aboutsummaryrefslogtreecommitdiff
path: root/proto/blueberry/a2dp.proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto/blueberry/a2dp.proto')
-rw-r--r--proto/blueberry/a2dp.proto179
1 files changed, 169 insertions, 10 deletions
diff --git a/proto/blueberry/a2dp.proto b/proto/blueberry/a2dp.proto
index 803ab0a..a5e1b1a 100644
--- a/proto/blueberry/a2dp.proto
+++ b/proto/blueberry/a2dp.proto
@@ -3,76 +3,235 @@ syntax = "proto3";
package blueberry;
import "blueberry/host.proto";
-
+import "google/protobuf/wrappers.proto";
+
+// Service to trigger A2DP (Advanced Audio Distribution Profile) procedures.
+//
+// Requirement for the implementor:
+// - Streams must not be automaticaly opened, even if discovered.
+// - The `Host` service should be implemented
+//
+// References:
+// - [A2DP] Bluetooth SIG, Specification of the Bluetooth System,
+// Advanced Audio Distribution, Version 1.3 or Later
+// - [AVDTP] Bluetooth SIG, Specification of the Bluetooth System,
+// Audio/Video Distribution Transport Protocol, Version 1.3 or Later
service A2DP {
+ // Open a stream from a local **Source** endpoint to a remote **Sink**
+ // endpoint.
+ //
+ // The returned source should be in the AVDTP_OPEN state (see [AVDTP] 9.1).
+ // The function must block until the stream has reached this state
+ //
+ // A cancellation of this call must result in aborting the current
+ // AVDTP procedure (see [AVDTP] 9.9)
rpc OpenSource(OpenSourceRequest) returns (OpenSourceResponse);
+ // Open a stream from a local **Sink** endpoint to a remote **Source**
+ // endpoint.
+ //
+ // The returned sink must be in the AVDTP_OPEN state (see [AVDTP] 9.1).
+ // The function must block until the stream has reached this state
+ //
+ // A cancellation of this call must result in aborting the current
+ // AVDTP procedure (see [AVDTP] 9.9)
rpc OpenSink(OpenSinkRequest) returns (OpenSinkResponse);
+ // Wait for a stream from a local **Source** endpoint to
+ // a remote **Sink** endpoint to open.
+ //
+ // If the peer has opened a source prior to this call, the server will
+ // return it. The server must return the same source only once.
+ rpc WaitSource(WaitSourceRequest) returns (WaitSourceResponse);
+ // Wait for a stream from a local **Sink** endpoint to
+ // a remote **Source** endpoint to open.
+ //
+ // If the peer has opened a sink prior to this call, the server will
+ // return it. The server must return the same sink only once.
+ rpc WaitSink(WaitSinkRequest) returns (WaitSinkResponse);
+ // Get if the stream is suspended
+ rpc IsSuspended(IsSuspendedRequest) returns (google.protobuf.BoolValue);
+ // Start a suspended stream.
rpc Start(StartRequest) returns (StartResponse);
+ // Suspend a started stream.
rpc Suspend(SuspendRequest) returns (SuspendResponse);
+ // Close a stream, the source or sink tokens must not be reused afterwards.
rpc Close(CloseRequest) returns (CloseResponse);
- rpc Abort(AbortRequest) returns (AbortResponse);
+ // Get the `AudioEncoding` value of a stream
+ rpc GetAudioEncoding(GetAudioEncodingRequest) returns (GetAudioEncodingResponse);
+ // Playback audio by a `Source`
+ rpc PlaybackAudio(stream PlaybackAudioRequest) returns (PlaybackAudioResponse);
+ // Capture audio from a `Sink`
+ rpc CaptureAudio(CaptureAudioRequest)returns (stream CaptureAudioResponse);
+}
+
+// Audio encoding formats.
+enum AudioEncoding {
+ // Interleaved stereo frames with 16-bit signed little-endian linear PCM
+ // samples at 44100Hz sample rate
+ PCM_S16_LE_44K1_STEREO = 0;
+ // Interleaved stereo frames with 16-bit signed little-endian linear PCM
+ // samples at 48000Hz sample rate
+ PCM_S16_LE_48K_STEREO = 1;
}
+// A Token representing a Source stream (see [A2DP] 2.2).
+// It's acquired via an OpenSource on the A2DP service.
message Source {
+ // Opaque value filled by the GRPC server, must not
+ // be modified nor crafted.
bytes cookie = 1;
}
+// A Token representing a Sink stream (see [A2DP] 2.2).
+// It's acquired via an OpenSink on the A2DP service.
message Sink {
+ // Opaque value filled by the GRPC server, must not
+ // be modified nor crafted.
bytes cookie = 1;
}
+// Request for the `OpenSource` method.
message OpenSourceRequest {
+ // The connection that will open the stream.
Connection connection = 1;
}
+// Response for the `OpenSource` method.
message OpenSourceResponse {
- oneof response {
+ // Result of the `OpenSource` call:
+ // - If successfull: a Source
+ oneof result {
Source source = 1;
}
}
+// Request for the `OpenSink` method.
message OpenSinkRequest {
+ // The connection that will open the stream.
Connection connection = 1;
}
+// Response for the `OpenSink` method.
message OpenSinkResponse {
- oneof response {
+ // Result of the `OpenSink` call:
+ // - If successfull: a Sink
+ oneof result {
+ Sink sink = 1;
+ }
+}
+
+// Request for the `WaitSource` method.
+message WaitSourceRequest {
+ // The connection that is awaiting the stream.
+ Connection connection = 1;
+}
+
+// Response for the `WaitSource` method.
+message WaitSourceResponse {
+ // Result of the `WaitSource` call:
+ // - If successfull: a Source
+ oneof result {
+ Source source = 1;
+ }
+}
+
+// Request for the `WaitSink` method.
+message WaitSinkRequest {
+ // The connection that is awaiting the stream.
+ Connection connection = 1;
+}
+
+// Response for the `WaitSink` method.
+message WaitSinkResponse {
+ // Result of the `WaitSink` call:
+ // - If successfull: a Sink
+ oneof result {
+ Sink sink = 1;
+ }
+}
+
+// Request for the `IsSuspended` method.
+message IsSuspendedRequest {
+ // The stream on which the function will check if it's suspended
+ oneof target {
Sink sink = 1;
+ Source source = 2;
}
}
+// Request for the `Start` method.
message StartRequest {
- oneof response {
+ // Target of the start, either a Sink or a Source.
+ oneof target {
Sink sink = 1;
Source source = 2;
}
}
+// Response for the `Start` method.
message StartResponse {}
+// Request for the `Suspend` method.
message SuspendRequest {
- oneof response {
+ // Target of the suspend, either a Sink or a Source.
+ oneof target {
Sink sink = 1;
Source source = 2;
}
}
+// Response for the `Suspend` method.
message SuspendResponse {}
+// Request for the `Close` method.
message CloseRequest {
- oneof response {
+ // Target of the close, either a Sink or a Source.
+ oneof target {
Sink sink = 1;
Source source = 2;
}
}
+// Response for the `Close` method.
message CloseResponse {}
-message AbortRequest {
- oneof response {
+// Request for the `GetAudioEncoding` method.
+message GetAudioEncodingRequest {
+ // The stream on which the function will read the `AudioEncoding`.
+ oneof target {
Sink sink = 1;
Source source = 2;
}
}
-message AbortResponse {} \ No newline at end of file
+// Response for the `GetAudioEncoding` method.
+message GetAudioEncodingResponse {
+ // Audio encoding of the stream.
+ AudioEncoding encoding = 1;
+}
+
+// Request for the `PlaybackAudio` method.
+message PlaybackAudioRequest {
+ // Source that will playback audio.
+ Source source = 1;
+ // Audio data to playback.
+ // The audio data must be encoded in the specified `AudioEncoding` value
+ // obtained in response of a `GetAudioEncoding` method call.
+ bytes data = 2;
+}
+
+// Response for the `PlaybackAudio` method.
+message PlaybackAudioResponse {}
+
+// Request for the `CaptureAudio` method.
+message CaptureAudioRequest {
+ // Sink that will capture audio
+ Sink sink = 1;
+}
+
+// Response for the `CaptureAudio` method.
+message CaptureAudioResponse {
+ // Captured audio data.
+ // The audio data is encoded in the specified `AudioEncoding` value
+ // obained in response of a `GetAudioEncoding` method call.
+ bytes data = 1;
+}