Linux bluetooth development
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox