]> code.delx.au - pulseaudio/commitdiff
Update ipc to match new message headers introduced on BlueZ 4.34.
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>
Wed, 25 Mar 2009 20:57:19 +0000 (17:57 -0300)
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>
Thu, 26 Mar 2009 18:40:04 +0000 (15:40 -0300)
src/modules/bluetooth/ipc.c
src/modules/bluetooth/ipc.h
src/modules/bluetooth/module-bluetooth-device.c

index f14c92c47e164c4e0ecd7ad12e5e998961e37133..dcecad8aee287967a1cbc9ee21d2ad183f9b80d9 100644 (file)
@@ -35,6 +35,7 @@ static const char *strtypes[] = {
 /* This table contains the string representation for messages names */
 static const char *strnames[] = {
        "BT_GET_CAPABILITIES",
+       "BT_OPEN",
        "BT_SET_CONFIGURATION",
        "BT_NEW_STREAM",
        "BT_START_STREAM",
index f030acfa24370ce0667708653e7468499326db39..2e170f5043b4fd89d61a6315a5261b4e3aaee670 100644 (file)
@@ -71,7 +71,7 @@ extern "C" {
 #include <sys/un.h>
 #include <errno.h>
 
-#define BT_SUGGESTED_BUFFER_SIZE   128
+#define BT_SUGGESTED_BUFFER_SIZE   512
 #define BT_IPC_SOCKET_NAME "\0/org/bluez/audio"
 
 /* Generic message header definition, except for RESPONSE messages */
@@ -94,10 +94,12 @@ typedef struct {
 
 /* Messages names */
 #define BT_GET_CAPABILITIES            0
-#define BT_SET_CONFIGURATION           1
-#define BT_NEW_STREAM                  2
-#define BT_START_STREAM                        3
-#define BT_STOP_STREAM                 4
+#define BT_OPEN                                1
+#define BT_SET_CONFIGURATION           2
+#define BT_NEW_STREAM                  3
+#define BT_START_STREAM                        4
+#define BT_STOP_STREAM                 5
+#define BT_CLOSE                       6
 #define BT_CONTROL                     7
 
 #define BT_CAPABILITIES_TRANSPORT_A2DP 0
@@ -112,19 +114,31 @@ typedef struct {
 
 struct bt_get_capabilities_req {
        bt_audio_msg_header_t   h;
-       char                    device[18];     /* Address of the remote Device */
+       char                    source[18];     /* Address of the local Device */
+       char                    destination[18];/* Address of the remote Device */
+       char                    object[128];    /* DBus object path */
        uint8_t                 transport;      /* Requested transport */
        uint8_t                 flags;          /* Requested flags */
+       uint8_t                 seid;           /* Requested capability configuration */
 } __attribute__ ((packed));
 
 /**
- * SBC Codec parameters as per A2DP profile 1.0 Â§ 4.3
+ * SBC Codec parameters as per A2DP profile 1.0 § 4.3
  */
 
-#define BT_A2DP_CODEC_SBC                      0x00
-#define BT_A2DP_CODEC_MPEG12                   0x01
-#define BT_A2DP_CODEC_MPEG24                   0x02
-#define BT_A2DP_CODEC_ATRAC                    0x03
+/* A2DP seid are 6 bytes long so HSP/HFP are assigned to 7-8 bits */
+#define BT_A2DP_SEID_RANGE                     (1 << 6) - 1
+
+#define BT_A2DP_SBC_SOURCE                     0x00
+#define BT_A2DP_SBC_SINK                       0x01
+#define BT_A2DP_MPEG12_SOURCE                  0x02
+#define BT_A2DP_MPEG12_SINK                    0x03
+#define BT_A2DP_MPEG24_SOURCE                  0x04
+#define BT_A2DP_MPEG24_SINK                    0x05
+#define BT_A2DP_ATRAC_SOURCE                   0x06
+#define BT_A2DP_ATRAC_SINK                     0x07
+#define BT_A2DP_UNKNOWN_SOURCE                 0x08
+#define BT_A2DP_UNKNOWN_SINK                   0x09
 
 #define BT_SBC_SAMPLING_FREQ_16000             (1 << 3)
 #define BT_SBC_SAMPLING_FREQ_32000             (1 << 2)
@@ -163,10 +177,16 @@ struct bt_get_capabilities_req {
 #define BT_PCM_FLAG_NREC                       0x01
 #define BT_PCM_FLAG_PCM_ROUTING                        0x02
 
+#define BT_WRITE_LOCK                          (1 << 1)
+#define BT_READ_LOCK                           1
+
 typedef struct {
+       uint8_t seid;
        uint8_t transport;
        uint8_t type;
        uint8_t length;
+       uint8_t configured;
+       uint8_t lock;
        uint8_t data[0];
 } __attribute__ ((packed)) codec_capabilities_t;
 
@@ -199,20 +219,35 @@ typedef struct {
 
 struct bt_get_capabilities_rsp {
        bt_audio_msg_header_t   h;
+       char                    source[18];     /* Address of the local Device */
+       char                    destination[18];/* Address of the remote Device */
+       char                    object[128];    /* DBus object path */
        uint8_t                 data[0];        /* First codec_capabilities_t */
 } __attribute__ ((packed));
 
+struct bt_open_req {
+       bt_audio_msg_header_t   h;
+       char                    source[18];     /* Address of the local Device */
+       char                    destination[18];/* Address of the remote Device */
+       char                    object[128];    /* DBus object path */
+       uint8_t                 seid;           /* Requested capability configuration to lock */
+       uint8_t                 lock;           /* Requested lock */
+} __attribute__ ((packed));
+
+struct bt_open_rsp {
+       bt_audio_msg_header_t   h;
+       char                    source[18];     /* Address of the local Device */
+       char                    destination[18];/* Address of the remote Device */
+       char                    object[128];    /* DBus object path */
+} __attribute__ ((packed));
+
 struct bt_set_configuration_req {
        bt_audio_msg_header_t   h;
-       char                    device[18];     /* Address of the remote Device */
-       uint8_t                 access_mode;    /* Requested access mode */
        codec_capabilities_t    codec;          /* Requested codec */
 } __attribute__ ((packed));
 
 struct bt_set_configuration_rsp {
        bt_audio_msg_header_t   h;
-       uint8_t                 transport;      /* Granted transport */
-       uint8_t                 access_mode;    /* Granted access mode */
        uint16_t                link_mtu;       /* Max length that transport supports */
 } __attribute__ ((packed));
 
@@ -241,6 +276,14 @@ struct bt_stop_stream_rsp {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
+struct bt_close_req {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+struct bt_close_rsp {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
 struct bt_suspend_stream_ind {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
index 2500fb094aee137ad555430cd4e86663a9bbcc27..d09dc2c9e262fe76ce4a686b4a5f6524e1c3eea2 100644 (file)
@@ -311,7 +311,7 @@ static int parse_caps(struct userdata *u, const struct bt_get_capabilities_rsp *
     } else if (u->profile == PROFILE_A2DP) {
 
         while (bytes_left > 0) {
-            if (codec->type == BT_A2DP_CODEC_SBC)
+            if ((codec->type == BT_A2DP_SBC_SINK) && !codec->lock)
                 break;
 
             bytes_left -= codec->length;
@@ -321,7 +321,7 @@ static int parse_caps(struct userdata *u, const struct bt_get_capabilities_rsp *
         if (bytes_left <= 0 || codec->length != sizeof(u->a2dp.sbc_capabilities))
             return -1;
 
-        pa_assert(codec->type == BT_A2DP_CODEC_SBC);
+        pa_assert(codec->type == BT_A2DP_SBC_SINK);
 
         memcpy(&u->a2dp.sbc_capabilities, codec, sizeof(u->a2dp.sbc_capabilities));
     }
@@ -344,7 +344,7 @@ static int get_caps(struct userdata *u) {
     msg.getcaps_req.h.name = BT_GET_CAPABILITIES;
     msg.getcaps_req.h.length = sizeof(msg.getcaps_req);
 
-    pa_strlcpy(msg.getcaps_req.device, u->address, sizeof(msg.getcaps_req.device));
+    pa_strlcpy(msg.getcaps_req.object, u->path, sizeof(msg.getcaps_req.object));
     if (u->profile == PROFILE_A2DP)
         msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
     else {
@@ -602,12 +602,29 @@ static void setup_sbc(struct a2dp_info *a2dp) {
 
 static int set_conf(struct userdata *u) {
     union {
+        struct bt_open_req open_req;
+        struct bt_open_rsp open_rsp;
         struct bt_set_configuration_req setconf_req;
         struct bt_set_configuration_rsp setconf_rsp;
         bt_audio_error_t error;
         uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
     } msg;
 
+    memset(&msg, 0, sizeof(msg));
+    msg.open_req.h.type = BT_REQUEST;
+    msg.open_req.h.name = BT_OPEN;
+    msg.open_req.h.length = sizeof(msg.open_req);
+
+    pa_strlcpy(msg.open_req.object, u->path, sizeof(msg.open_req.object));
+    msg.open_req.seid = u->profile == PROFILE_A2DP ? u->a2dp.sbc_capabilities.capability.seid : BT_A2DP_SEID_RANGE + 1;
+    msg.open_req.lock = u->profile == PROFILE_A2DP ? BT_WRITE_LOCK : BT_READ_LOCK | BT_WRITE_LOCK;
+
+    if (service_send(u, &msg.open_req.h) < 0)
+        return -1;
+
+    if (service_expect(u, &msg.open_rsp.h, sizeof(msg), BT_OPEN, sizeof(msg.open_rsp)) < 0)
+        return -1;
+
     if (u->profile == PROFILE_A2DP ) {
         u->sample_spec.format = PA_SAMPLE_S16LE;
 
@@ -626,15 +643,14 @@ static int set_conf(struct userdata *u) {
     msg.setconf_req.h.name = BT_SET_CONFIGURATION;
     msg.setconf_req.h.length = sizeof(msg.setconf_req);
 
-    pa_strlcpy(msg.setconf_req.device, u->address, sizeof(msg.setconf_req.device));
-    msg.setconf_req.access_mode = u->profile == PROFILE_A2DP ? BT_CAPABILITIES_ACCESS_MODE_WRITE : BT_CAPABILITIES_ACCESS_MODE_READWRITE;
-
-    msg.setconf_req.codec.transport = u->profile == PROFILE_A2DP ? BT_CAPABILITIES_TRANSPORT_A2DP : BT_CAPABILITIES_TRANSPORT_SCO;
-
     if (u->profile == PROFILE_A2DP) {
         memcpy(&msg.setconf_req.codec, &u->a2dp.sbc_capabilities, sizeof(u->a2dp.sbc_capabilities));
-        msg.setconf_req.h.length += msg.setconf_req.codec.length - sizeof(msg.setconf_req.codec);
+    } else {
+        msg.setconf_req.codec.transport = BT_CAPABILITIES_TRANSPORT_SCO;
+        msg.setconf_req.codec.seid = BT_A2DP_SEID_RANGE + 1;
+        msg.setconf_req.codec.length = sizeof(pcm_capabilities_t);
     }
+    msg.setconf_req.h.length += msg.setconf_req.codec.length - sizeof(msg.setconf_req.codec);
 
     if (service_send(u, &msg.setconf_req.h) < 0)
         return -1;
@@ -642,18 +658,6 @@ static int set_conf(struct userdata *u) {
     if (service_expect(u, &msg.setconf_rsp.h, sizeof(msg), BT_SET_CONFIGURATION, sizeof(msg.setconf_rsp)) < 0)
         return -1;
 
-    if ((u->profile == PROFILE_A2DP && msg.setconf_rsp.transport != BT_CAPABILITIES_TRANSPORT_A2DP) ||
-        (u->profile == PROFILE_HSP && msg.setconf_rsp.transport != BT_CAPABILITIES_TRANSPORT_SCO)) {
-        pa_log("Transport doesn't match what we requested.");
-        return -1;
-    }
-
-    if ((u->profile == PROFILE_A2DP && msg.setconf_rsp.access_mode != BT_CAPABILITIES_ACCESS_MODE_WRITE) ||
-        (u->profile == PROFILE_HSP && msg.setconf_rsp.access_mode != BT_CAPABILITIES_ACCESS_MODE_READWRITE)) {
-        pa_log("Access mode doesn't match what we requested.");
-        return -1;
-    }
-
     u->link_mtu = msg.setconf_rsp.link_mtu;
 
     /* setup SBC encoder now we agree on parameters */