All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command
@ 2014-03-02 23:50 Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 2/8] android/hal: Update services register commands with mode parameter Szymon Janc
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This will allow to run daemon services in non-default mode.
---
 android/hal-ipc-api.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index 0518c2f..6bf9af3 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -124,12 +124,16 @@ Core Service (ID 0)
 	Opcode 0x01 - Register module command/response
 
 		Command parameters: Service id (1 octet)
+		                    Mode (1 octet)
 		Response parameters: <none>
 
 		In case a command is sent for an undeclared service ID, it will
 		be rejected. Also there will be no notifications for undeclared
 		service ID.
 
+		Valid Mode values: 0x00 = Default Mode
+		                   0xXX = as defined by service
+
 		In case of an error, the error response will be returned.
 
 	Opcode 0x02 - Unregister module command/response
@@ -749,6 +753,8 @@ Bluetooth Handsfree HAL (ID 5)
 
 Android HAL name: "handsfree" (BT_PROFILE_HANDSFREE_ID)
 
+	Service modes:               0x01 = Headset Profile only mode
+
 	Opcode 0x00 - Error response
 
 		Response parameters: Status (1 octet)
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/8] android/hal: Update services register commands with mode parameter
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 3/8] android: Pass mode parameter to registered services Szymon Janc
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/hal-a2dp.c      | 1 +
 android/hal-avrcp.c     | 1 +
 android/hal-bluetooth.c | 1 +
 android/hal-handsfree.c | 1 +
 android/hal-hidhost.c   | 1 +
 android/hal-msg.h       | 3 +++
 android/hal-pan.c       | 1 +
 7 files changed, 9 insertions(+)

diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c
index c898995..ac495a1 100644
--- a/android/hal-a2dp.c
+++ b/android/hal-a2dp.c
@@ -109,6 +109,7 @@ static bt_status_t init(btav_callbacks_t *callbacks)
 				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_A2DP;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 46e25a0..a720a1e 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -220,6 +220,7 @@ static bt_status_t init(btrc_callbacks_t *callbacks)
 				sizeof(ev_handlers) / sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_AVRCP;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 6871f5d..832183e 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -442,6 +442,7 @@ static int init(bt_callbacks_t *callbacks)
 	}
 
 	cmd.service_id = HAL_SERVICE_ID_SOCKET;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	status = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, NULL, NULL, NULL);
diff --git a/android/hal-handsfree.c b/android/hal-handsfree.c
index 1b150c3..7a28e0f 100644
--- a/android/hal-handsfree.c
+++ b/android/hal-handsfree.c
@@ -212,6 +212,7 @@ static bt_status_t init(bthf_callbacks_t *callbacks)
 				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_HANDSFREE;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index c758d2a..16253e3 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -354,6 +354,7 @@ static bt_status_t init(bthh_callbacks_t *callbacks)
 				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_HIDHOST;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 7b6e46d..8eb97c3 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -54,9 +54,12 @@ static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket";
 
 #define HAL_OP_STATUS			IPC_OP_STATUS
 
+#define HAL_MODE_DEFAULT		0x00
+
 #define HAL_OP_REGISTER_MODULE		0x01
 struct hal_cmd_register_module {
 	uint8_t service_id;
+	uint8_t mode;
 } __attribute__((packed));
 
 #define HAL_OP_UNREGISTER_MODULE	0x02
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 5ee49ef..f383081 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -157,6 +157,7 @@ static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
 				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_PAN;
+	cmd.mode = HAL_MODE_DEFAULT;
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/8] android: Pass mode parameter to registered services
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 2/8] android/hal: Update services register commands with mode parameter Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 4/8] android/handsfree: Factor out HFP AG enable code Szymon Janc
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/a2dp.c      |  2 +-
 android/a2dp.h      |  2 +-
 android/avrcp.c     |  2 +-
 android/avrcp.h     |  2 +-
 android/bluetooth.c |  2 +-
 android/bluetooth.h |  2 +-
 android/handsfree.c |  2 +-
 android/handsfree.h |  2 +-
 android/hidhost.c   |  2 +-
 android/hidhost.h   |  2 +-
 android/main.c      | 14 +++++++-------
 android/pan.c       |  2 +-
 android/pan.h       |  2 +-
 android/socket.c    |  2 +-
 android/socket.h    |  2 +-
 15 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/android/a2dp.c b/android/a2dp.c
index 180d015..4ea16e2 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -1564,7 +1564,7 @@ retry:
 						audio_disconnected);
 }
 
-bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr)
+bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	GError *err = NULL;
 	sdp_record_t *rec;
diff --git a/android/a2dp.h b/android/a2dp.h
index b41a178..8a70407 100644
--- a/android/a2dp.h
+++ b/android/a2dp.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr);
+bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_a2dp_unregister(void);
diff --git a/android/avrcp.c b/android/avrcp.c
index 678c321..b65f35c 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -364,7 +364,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	DBG("%s connected", address);
 }
 
-bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr)
+bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	GError *err = NULL;
 	sdp_record_t *rec;
diff --git a/android/avrcp.h b/android/avrcp.h
index 3dcffeb..11e79b7 100644
--- a/android/avrcp.h
+++ b/android/avrcp.h
@@ -21,7 +21,7 @@
  *
  */
 
-bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr);
+bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_avrcp_unregister(void);
 
 void bt_avrcp_connect(const bdaddr_t *dst);
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 8ad7d5d..6d94904 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -3285,7 +3285,7 @@ static const struct ipc_handler cmd_handlers[] = {
 	{ handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) },
 };
 
-void bt_bluetooth_register(struct ipc *ipc)
+void bt_bluetooth_register(struct ipc *ipc, uint8_t mode)
 {
 	DBG("");
 
diff --git a/android/bluetooth.h b/android/bluetooth.h
index fbc850d..1c177be 100644
--- a/android/bluetooth.h
+++ b/android/bluetooth.h
@@ -31,7 +31,7 @@ void bt_bluetooth_cleanup(void);
 
 void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
 
-void bt_bluetooth_register(struct ipc *ipc);
+void bt_bluetooth_register(struct ipc *ipc, uint8_t mode);
 void bt_bluetooth_unregister(void);
 
 int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint);
diff --git a/android/handsfree.c b/android/handsfree.c
index 81ddcc7..cfdcc1a 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -532,7 +532,7 @@ static sdp_record_t *handsfree_ag_record(void)
 	return record;
 }
 
-bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr)
+bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	sdp_record_t *rec;
 	GError *err = NULL;
diff --git a/android/handsfree.h b/android/handsfree.h
index 3ede819..e5eff47 100644
--- a/android/handsfree.h
+++ b/android/handsfree.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr);
+bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_handsfree_unregister(void);
diff --git a/android/hidhost.c b/android/hidhost.c
index e469210..4226f69 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1330,7 +1330,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	}
 }
 
-bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr)
+bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	GError *err = NULL;
 
diff --git a/android/hidhost.h b/android/hidhost.h
index 1017195..e6b87ed 100644
--- a/android/hidhost.h
+++ b/android/hidhost.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr);
+bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_hid_unregister(void);
diff --git a/android/main.c b/android/main.c
index f7fe9c8..c6e08eb 100644
--- a/android/main.c
+++ b/android/main.c
@@ -84,43 +84,43 @@ static void service_register(const void *buf, uint16_t len)
 
 	switch (m->service_id) {
 	case HAL_SERVICE_ID_BLUETOOTH:
-		bt_bluetooth_register(hal_ipc);
+		bt_bluetooth_register(hal_ipc, m->mode);
 
 		break;
 	case HAL_SERVICE_ID_SOCKET:
-		bt_socket_register(hal_ipc, &adapter_bdaddr);
+		bt_socket_register(hal_ipc, &adapter_bdaddr, m->mode);
 
 		break;
 	case HAL_SERVICE_ID_HIDHOST:
-		if (!bt_hid_register(hal_ipc, &adapter_bdaddr)) {
+		if (!bt_hid_register(hal_ipc, &adapter_bdaddr, m->mode)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_A2DP:
-		if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr)) {
+		if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr, m->mode)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_PAN:
-		if (!bt_pan_register(hal_ipc, &adapter_bdaddr)) {
+		if (!bt_pan_register(hal_ipc, &adapter_bdaddr, m->mode)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_AVRCP:
-		if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr)) {
+		if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr, m->mode)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
 
 		break;
 	case HAL_SERVICE_ID_HANDSFREE:
-		if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr)) {
+		if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr, m->mode)) {
 			status = HAL_STATUS_FAILED;
 			goto failed;
 		}
diff --git a/android/pan.c b/android/pan.c
index 1e404ab..ce1f677 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -779,7 +779,7 @@ static sdp_record_t *pan_record(void)
 	return record;
 }
 
-bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr)
+bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	sdp_record_t *rec;
 	int err;
diff --git a/android/pan.h b/android/pan.h
index 2045ac5..cfbea96 100644
--- a/android/pan.h
+++ b/android/pan.h
@@ -21,5 +21,5 @@
  *
  */
 
-bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr);
+bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_pan_unregister(void);
diff --git a/android/socket.c b/android/socket.c
index afa2008..7bc77ed 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -1129,7 +1129,7 @@ static const struct ipc_handler cmd_handlers[] = {
 	{ handle_connect, false, sizeof(struct hal_cmd_socket_connect) },
 };
 
-void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr)
+void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
 	size_t i;
 
diff --git a/android/socket.h b/android/socket.h
index a1eca5a..b0e78c6 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -28,5 +28,5 @@ struct hal_sock_connect_signal {
 	int     status;
 } __attribute__((packed));
 
-void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr);
+void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode);
 void bt_socket_unregister(void);
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/8] android/handsfree: Factor out HFP AG enable code
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 2/8] android/hal: Update services register commands with mode parameter Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 3/8] android: Pass mode parameter to registered services Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 5/8] android/socket: Reserve channel for HSP AG Szymon Janc
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This is in preparation for support to not enable HFP AG when
initializing HAL.
---
 android/handsfree.c | 77 ++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index cfdcc1a..7a1d697 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -56,10 +56,10 @@ static struct {
 } device;
 
 static bdaddr_t adapter_addr;
-static uint32_t record_id = 0;
 static struct ipc *hal_ipc = NULL;
 
-static GIOChannel *server = NULL;
+static uint32_t hfp_record_id = 0;
+static GIOChannel *hfp_server = NULL;
 
 static void device_set_state(uint8_t state)
 {
@@ -460,7 +460,7 @@ static const struct ipc_handler cmd_handlers[] = {
 			sizeof(struct hal_cmd_handsfree_phone_state_change)},
 };
 
-static sdp_record_t *handsfree_ag_record(void)
+static sdp_record_t *hfp_ag_record(void)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
@@ -532,27 +532,28 @@ static sdp_record_t *handsfree_ag_record(void)
 	return record;
 }
 
-bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
+static bool enable_hfp_ag(void)
 {
 	sdp_record_t *rec;
 	GError *err = NULL;
 
 	DBG("");
 
-	bacpy(&adapter_addr, addr);
+	if (hfp_server)
+		return false;
 
-	server =  bt_io_listen( NULL, confirm_cb, NULL, NULL, &err,
-				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
-				BT_IO_OPT_CHANNEL, HFP_AG_CHANNEL,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-				BT_IO_OPT_INVALID);
-	if (!server) {
+	hfp_server =  bt_io_listen(NULL, confirm_cb, NULL, NULL, &err,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_CHANNEL, HFP_AG_CHANNEL,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_INVALID);
+	if (!hfp_server) {
 		error("Failed to listen on Handsfree rfcomm: %s", err->message);
 		g_error_free(err);
-		return false;
+		goto failed;
 	}
 
-	rec = handsfree_ag_record();
+	rec = hfp_ag_record();
 	if (!rec) {
 		error("Failed to allocate Handsfree record");
 		goto failed;
@@ -563,22 +564,49 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 		sdp_record_free(rec);
 		goto failed;
 	}
-	record_id = rec->handle;
 
-	hal_ipc = ipc;
-	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
-						G_N_ELEMENTS(cmd_handlers));
+	hfp_record_id = rec->handle;
 
 	return true;
 
 failed:
-	g_io_channel_shutdown(server, TRUE, NULL);
-	g_io_channel_unref(server);
-	server = NULL;
+	g_io_channel_shutdown(hfp_server, TRUE, NULL);
+	g_io_channel_unref(hfp_server);
+	hfp_server = NULL;
 
 	return false;
 }
 
+static void cleanup_hfp_ag(void)
+{
+	if (hfp_server) {
+		g_io_channel_shutdown(hfp_server, TRUE, NULL);
+		g_io_channel_unref(hfp_server);
+		hfp_server = NULL;
+	}
+
+	if (hfp_record_id > 0) {
+		bt_adapter_remove_record(hfp_record_id);
+		hfp_record_id = 0;
+	}
+}
+
+bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
+{
+	DBG("");
+
+	bacpy(&adapter_addr, addr);
+
+	if (!enable_hfp_ag())
+		return false;
+
+	hal_ipc = ipc;
+	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
+						G_N_ELEMENTS(cmd_handlers));
+
+	return true;
+}
+
 void bt_handsfree_unregister(void)
 {
 	DBG("");
@@ -586,12 +614,5 @@ void bt_handsfree_unregister(void)
 	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE);
 	hal_ipc = NULL;
 
-	if (server) {
-		g_io_channel_shutdown(server, TRUE, NULL);
-		g_io_channel_unref(server);
-		server = NULL;
-	}
-
-	bt_adapter_remove_record(record_id);
-	record_id = 0;
+	cleanup_hfp_ag();
 }
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 5/8] android/socket: Reserve channel for HSP AG
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
                   ` (2 preceding siblings ...)
  2014-03-02 23:50 ` [PATCH v3 4/8] android/handsfree: Factor out HFP AG enable code Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 6/8] android/handsfree: Add support " Szymon Janc
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/socket.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 7bc77ed..e9c7675 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -48,7 +48,8 @@
 #define RFCOMM_CHANNEL_MAX 30
 
 #define OPP_DEFAULT_CHANNEL	9
-#define HFAG_DEFAULT_CHANNEL	13
+#define HSP_AG_DEFAULT_CHANNEL	12
+#define HFP_AG_DEFAULT_CHANNEL	13
 #define PBAP_DEFAULT_CHANNEL	15
 #define MAP_MAS_DEFAULT_CHANNEL	16
 
@@ -376,10 +377,19 @@ static const struct profile_info {
 } profiles[] = {
 	{
 		.uuid = {
+			0x00, 0x00, 0x11, 0x08, 0x00, 0x00, 0x10, 0x00,
+			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+		},
+		.channel = HSP_AG_DEFAULT_CHANNEL,
+		.svc_hint = 0,
+		.sec_level = BT_IO_SEC_MEDIUM,
+		.create_record = NULL
+	}, {
+		.uuid = {
 			0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00,
 			0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
 		},
-		.channel = HFAG_DEFAULT_CHANNEL,
+		.channel = HFP_AG_DEFAULT_CHANNEL,
 		.svc_hint = 0,
 		.sec_level = BT_IO_SEC_MEDIUM,
 		.create_record = NULL
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 6/8] android/handsfree: Add support for HSP AG
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
                   ` (3 preceding siblings ...)
  2014-03-02 23:50 ` [PATCH v3 5/8] android/socket: Reserve channel for HSP AG Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 7/8] android/handsfree: Allow to connect to HSP or HFP handsfree unit Szymon Janc
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 android/handsfree.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 135 insertions(+), 1 deletion(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 7a1d697..0b97a5d 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -46,7 +46,9 @@
 #include "src/log.h"
 #include "utils.h"
 
+#define HSP_AG_CHANNEL 12
 #define HFP_AG_CHANNEL 13
+
 #define HFP_AG_FEATURES 0
 
 static struct {
@@ -61,6 +63,9 @@ static struct ipc *hal_ipc = NULL;
 static uint32_t hfp_record_id = 0;
 static GIOChannel *hfp_server = NULL;
 
+static uint32_t hsp_record_id = 0;
+static GIOChannel *hsp_server = NULL;
+
 static void device_set_state(uint8_t state)
 {
 	struct hal_ev_handsfree_conn_state ev;
@@ -460,6 +465,129 @@ static const struct ipc_handler cmd_handlers[] = {
 			sizeof(struct hal_cmd_handsfree_phone_state_change)},
 };
 
+static sdp_record_t *headset_ag_record(void)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_list_t *aproto, *proto[2];
+	sdp_record_t *record;
+	sdp_data_t *channel;
+	uint8_t netid = 0x01;
+	sdp_data_t *network;
+	uint8_t ch = HSP_AG_CHANNEL;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	network = sdp_data_alloc(SDP_UINT8, &netid);
+	if (!network) {
+		sdp_record_free(record);
+		return NULL;
+	}
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+
+	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
+	svclass_id = sdp_list_append(0, &svclass_uuid);
+	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
+	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
+	profile.version = 0x0102;
+	pfseq = sdp_list_append(0, &profile);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+	proto[0] = sdp_list_append(0, &l2cap_uuid);
+	apseq = sdp_list_append(0, proto[0]);
+
+	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
+	proto[1] = sdp_list_append(0, &rfcomm_uuid);
+	channel = sdp_data_alloc(SDP_UINT8, &ch);
+	proto[1] = sdp_list_append(proto[1], channel);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	sdp_set_info_attr(record, "Voice Gateway", 0, 0);
+
+	sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], NULL);
+	sdp_list_free(proto[1], NULL);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(pfseq, NULL);
+	sdp_list_free(aproto, NULL);
+	sdp_list_free(root, NULL);
+	sdp_list_free(svclass_id, NULL);
+
+	return record;
+}
+
+static bool enable_hsp_ag(void)
+{
+	sdp_record_t *rec;
+	GError *err = NULL;
+
+	DBG("");
+
+	hsp_server =  bt_io_listen(NULL, confirm_cb, NULL, NULL, &err,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_CHANNEL, HSP_AG_CHANNEL,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_INVALID);
+	if (!hsp_server) {
+		error("Failed to listen on Headset rfcomm: %s", err->message);
+		g_error_free(err);
+		return false;
+	}
+
+	rec = headset_ag_record();
+	if (!rec) {
+		error("Failed to allocate Headset record");
+		goto failed;
+	}
+
+	if (bt_adapter_add_record(rec, 0) < 0) {
+		error("Failed to register Headset record");
+		sdp_record_free(rec);
+		goto failed;
+	}
+
+	hsp_record_id = rec->handle;
+
+	return true;
+
+failed:
+	g_io_channel_shutdown(hsp_server, TRUE, NULL);
+	g_io_channel_unref(hsp_server);
+	hsp_server = NULL;
+
+	return false;
+}
+
+static void cleanup_hsp_ag(void)
+{
+	if (hsp_server) {
+		g_io_channel_shutdown(hsp_server, TRUE, NULL);
+		g_io_channel_unref(hsp_server);
+		hsp_server = NULL;
+	}
+
+	if (hsp_record_id > 0) {
+		bt_adapter_remove_record(hsp_record_id);
+		hsp_record_id = 0;
+	}
+}
+
 static sdp_record_t *hfp_ag_record(void)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
@@ -597,9 +725,14 @@ bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 
 	bacpy(&adapter_addr, addr);
 
-	if (!enable_hfp_ag())
+	if (!enable_hsp_ag())
 		return false;
 
+	if (!enable_hfp_ag()) {
+		cleanup_hsp_ag();
+		return false;
+	}
+
 	hal_ipc = ipc;
 	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
@@ -615,4 +748,5 @@ void bt_handsfree_unregister(void)
 	hal_ipc = NULL;
 
 	cleanup_hfp_ag();
+	cleanup_hsp_ag();
 }
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 7/8] android/handsfree: Allow to connect to HSP or HFP handsfree unit
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
                   ` (4 preceding siblings ...)
  2014-03-02 23:50 ` [PATCH v3 6/8] android/handsfree: Add support " Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-02 23:50 ` [PATCH v3 8/8] android/handsfree: Add support for disabling HSP or HFP AGs Szymon Janc
  2014-03-04  9:20 ` [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This allows to connect to HSP (it HFP is not enabled) or fallback to
HSP if HFP is not supported by remote device.
---
 android/handsfree.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 106 insertions(+), 7 deletions(-)

diff --git a/android/handsfree.c b/android/handsfree.c
index 0b97a5d..6149c62 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -184,7 +184,7 @@ drop:
 	g_io_channel_shutdown(chan, TRUE, NULL);
 }
 
-static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
 {
 	sdp_list_t *protos, *classes;
 	GError *gerr = NULL;
@@ -195,12 +195,13 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	DBG("");
 
 	if (err < 0) {
-		error("handsfree: unable to get SDP record: %s", strerror(-err));
+		error("handsfree: unable to get SDP record: %s",
+								strerror(-err));
 		goto fail;
 	}
 
 	if (!recs || !recs->data) {
-		error("handsfree: no SDP records found");
+		info("handsfree: no HSP SDP records found");
 		goto fail;
 	}
 
@@ -216,6 +217,94 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	}
 
 	/* TODO read remote version? */
+	/* TODO read volume control support */
+
+	memcpy(&uuid, classes->data, sizeof(uuid));
+	sdp_list_free(classes, free);
+
+	if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 ||
+			uuid.value.uuid16 != HEADSET_SVCLASS_ID) {
+		sdp_list_free(protos, NULL);
+		error("handsfree: invalid service record or not HSP");
+		goto fail;
+	}
+
+	channel = sdp_get_proto_port(protos, RFCOMM_UUID);
+	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
+	sdp_list_free(protos, NULL);
+	if (channel <= 0) {
+		error("handsfree: unable to get RFCOMM channel from record");
+		goto fail;
+	}
+
+	io = bt_io_connect(connect_cb, NULL, NULL, &gerr,
+				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+				BT_IO_OPT_DEST_BDADDR, &device.bdaddr,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+				BT_IO_OPT_CHANNEL, channel,
+				BT_IO_OPT_INVALID);
+	if (!io) {
+		error("handsfree: unable to connect: %s", gerr->message);
+		g_error_free(gerr);
+		goto fail;
+	}
+
+	g_io_channel_unref(io);
+	return;
+
+fail:
+	device_cleanup();
+}
+
+static int sdp_search_hsp(void)
+{
+	uuid_t uuid;
+
+	sdp_uuid16_create(&uuid, HEADSET_SVCLASS_ID);
+
+	return bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
+					sdp_hsp_search_cb, NULL, NULL, 0);
+}
+
+static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+	sdp_list_t *protos, *classes;
+	GError *gerr = NULL;
+	GIOChannel *io;
+	uuid_t uuid;
+	int channel;
+
+	DBG("");
+
+	if (err < 0) {
+		error("handsfree: unable to get SDP record: %s",
+								strerror(-err));
+		goto fail;
+	}
+
+	if (!recs || !recs->data) {
+		info("handsfree: no HFP SDP records found, trying HSP");
+
+		if (sdp_search_hsp() < 0) {
+			error("handsfree: HSP SDP search failed");
+			goto fail;
+		}
+
+		return;
+	}
+
+	if (sdp_get_service_classes(recs->data, &classes) < 0) {
+		error("handsfree: unable to get service classes from record");
+		goto fail;
+	}
+
+	if (sdp_get_access_protos(recs->data, &protos) < 0) {
+		error("handsfree: unable to get access protocols from record");
+		sdp_list_free(classes, free);
+		goto fail;
+	}
+
+	/* TODO read remote version? */
 
 	memcpy(&uuid, classes->data, sizeof(uuid));
 	sdp_list_free(classes, free);
@@ -254,13 +343,23 @@ fail:
 	device_cleanup();
 }
 
+static int sdp_search_hfp(void)
+{
+	uuid_t uuid;
+
+	sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID);
+
+	return bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
+					sdp_hfp_search_cb, NULL, NULL, 0);
+}
+
 static void handle_connect(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_handsfree_connect *cmd = buf;
 	char addr[18];
 	uint8_t status;
-	uuid_t uuid;
 	bdaddr_t bdaddr;
+	int ret;
 
 	DBG("");
 
@@ -276,9 +375,9 @@ static void handle_connect(const void *buf, uint16_t len)
 
 	device_init(&bdaddr);
 
-	sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID);
-	if (bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
-					sdp_search_cb, NULL, NULL, 0) < 0) {
+	/* prefer HFP over HSP */
+	ret = hfp_server ? sdp_search_hfp() : sdp_search_hsp();
+	if (ret < 0) {
 		error("handsfree: SDP search failed");
 		device_cleanup();
 		status = HAL_STATUS_FAILED;
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 8/8] android/handsfree: Add support for disabling HSP or HFP AGs
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
                   ` (5 preceding siblings ...)
  2014-03-02 23:50 ` [PATCH v3 7/8] android/handsfree: Allow to connect to HSP or HFP handsfree unit Szymon Janc
@ 2014-03-02 23:50 ` Szymon Janc
  2014-03-04  9:20 ` [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-02 23:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This allows to tune what profiles are supported by handsfree HAL.
---
 android/cutils/properties.h |  8 ++++++++
 android/hal-handsfree.c     | 15 ++++++++++++++-
 android/hal-msg.h           |  2 ++
 android/handsfree.c         |  4 ++--
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/android/cutils/properties.h b/android/cutils/properties.h
index dff812f..66a4a84 100644
--- a/android/cutils/properties.h
+++ b/android/cutils/properties.h
@@ -27,6 +27,14 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#define PROPERTY_VALUE_MAX 32
+
+static inline int property_get(const char *key, char *value,
+						const char *default_value)
+{
+	return 0;
+}
+
 /* property_set: returns 0 on success, < 0 on failure
 */
 static inline int property_set(const char *key, const char *value)
diff --git a/android/hal-handsfree.c b/android/hal-handsfree.c
index 7a28e0f..4117ed0 100644
--- a/android/hal-handsfree.c
+++ b/android/hal-handsfree.c
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <stdlib.h>
 
+#include <cutils/properties.h>
+
 #include "hal-log.h"
 #include "hal.h"
 #include "hal-msg.h"
@@ -196,6 +198,17 @@ static const struct hal_ipc_handler ev_handlers[] = {
 	{handle_hsp_key_press, false, 0},
 };
 
+static uint8_t get_mode(void)
+{
+	char value[PROPERTY_VALUE_MAX];
+
+	if (property_get("bluetooth.handsfree_mode", value, "") > 0 &&
+					(!strcasecmp(value, "hsp_only")))
+		return HAL_MODE_HANDSFREE_HSP_ONLY;
+
+	return HAL_MODE_DEFAULT;
+}
+
 static bt_status_t init(bthf_callbacks_t *callbacks)
 {
 	struct hal_cmd_register_module cmd;
@@ -212,7 +225,7 @@ static bt_status_t init(bthf_callbacks_t *callbacks)
 				sizeof(ev_handlers)/sizeof(ev_handlers[0]));
 
 	cmd.service_id = HAL_SERVICE_ID_HANDSFREE;
-	cmd.mode = HAL_MODE_DEFAULT;
+	cmd.mode = get_mode();
 
 	ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
 					sizeof(cmd), &cmd, 0, NULL, NULL);
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 8eb97c3..dd25f6e 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -385,6 +385,8 @@ struct hal_cmd_pan_disconnect {
 
 /* Handsfree HAL API */
 
+#define HAL_MODE_HANDSFREE_HSP_ONLY		0x01
+
 #define HAL_OP_HANDSFREE_CONNECT		0x01
 struct hal_cmd_handsfree_connect {
 	uint8_t bdaddr[6];
diff --git a/android/handsfree.c b/android/handsfree.c
index 6149c62..4f69e68 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -820,14 +820,14 @@ static void cleanup_hfp_ag(void)
 
 bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
 {
-	DBG("");
+	DBG("mode 0x%x", mode);
 
 	bacpy(&adapter_addr, addr);
 
 	if (!enable_hsp_ag())
 		return false;
 
-	if (!enable_hfp_ag()) {
+	if (mode != HAL_MODE_HANDSFREE_HSP_ONLY && !enable_hfp_ag()) {
 		cleanup_hsp_ag();
 		return false;
 	}
-- 
1.8.5.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command
  2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
                   ` (6 preceding siblings ...)
  2014-03-02 23:50 ` [PATCH v3 8/8] android/handsfree: Add support for disabling HSP or HFP AGs Szymon Janc
@ 2014-03-04  9:20 ` Szymon Janc
  7 siblings, 0 replies; 9+ messages in thread
From: Szymon Janc @ 2014-03-04  9:20 UTC (permalink / raw)
  To: linux-bluetooth

On Monday 03 of March 2014 00:50:42 Szymon Janc wrote:
> This will allow to run daemon services in non-default mode.
> ---
>  android/hal-ipc-api.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
> index 0518c2f..6bf9af3 100644
> --- a/android/hal-ipc-api.txt
> +++ b/android/hal-ipc-api.txt
> @@ -124,12 +124,16 @@ Core Service (ID 0)
>  	Opcode 0x01 - Register module command/response
>  
>  		Command parameters: Service id (1 octet)
> +		                    Mode (1 octet)
>  		Response parameters: <none>
>  
>  		In case a command is sent for an undeclared service ID, it will
>  		be rejected. Also there will be no notifications for undeclared
>  		service ID.
>  
> +		Valid Mode values: 0x00 = Default Mode
> +		                   0xXX = as defined by service
> +
>  		In case of an error, the error response will be returned.
>  
>  	Opcode 0x02 - Unregister module command/response
> @@ -749,6 +753,8 @@ Bluetooth Handsfree HAL (ID 5)
>  
>  Android HAL name: "handsfree" (BT_PROFILE_HANDSFREE_ID)
>  
> +	Service modes:               0x01 = Headset Profile only mode
> +
>  	Opcode 0x00 - Error response
>  
>  		Response parameters: Status (1 octet)
> 

Pushed.

-- 
Best regards, 
Szymon Janc

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-03-04  9:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-02 23:50 [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc
2014-03-02 23:50 ` [PATCH v3 2/8] android/hal: Update services register commands with mode parameter Szymon Janc
2014-03-02 23:50 ` [PATCH v3 3/8] android: Pass mode parameter to registered services Szymon Janc
2014-03-02 23:50 ` [PATCH v3 4/8] android/handsfree: Factor out HFP AG enable code Szymon Janc
2014-03-02 23:50 ` [PATCH v3 5/8] android/socket: Reserve channel for HSP AG Szymon Janc
2014-03-02 23:50 ` [PATCH v3 6/8] android/handsfree: Add support " Szymon Janc
2014-03-02 23:50 ` [PATCH v3 7/8] android/handsfree: Allow to connect to HSP or HFP handsfree unit Szymon Janc
2014-03-02 23:50 ` [PATCH v3 8/8] android/handsfree: Add support for disabling HSP or HFP AGs Szymon Janc
2014-03-04  9:20 ` [PATCH v3 1/8] android/ipc: Add Mode parameter to register service command Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.