Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF
@ 2014-11-28  9:37 Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 1/5] android/handsfree-client: Add SCO to handsfree client Lukasz Rymanowski
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

Last missing piece to HFP HF implementation.

v2:
* Handled Szymon comments
* rebase and minor self review fixes in 2/5

Lukasz Rymanowski (5):
  android/handsfree-client: Add SCO to handsfree client
  android/handsfree-client: Add handle incoming SCO connection
  android/handsfree-client: Implement audio connect/disconnect
  android/handsfree-client: Send AT+BCC to start codec negotiation
  android/README: Update status of HAL HFP HF implementation

 android/README             |   2 +-
 android/handsfree-client.c | 191 ++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 180 insertions(+), 13 deletions(-)

-- 
1.8.4


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

* [PATCH v2 1/5] android/handsfree-client: Add SCO to handsfree client
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
@ 2014-11-28  9:37 ` Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 2/5] android/handsfree-client: Add handle incoming SCO connection Lukasz Rymanowski
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 283519f..9e67c7f 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -47,6 +47,7 @@
 #include "bluetooth.h"
 #include "hal-msg.h"
 #include "handsfree-client.h"
+#include "sco.h"
 
 #define HFP_HF_CHANNEL 7
 
@@ -139,6 +140,8 @@ static uint32_t hfp_hf_record_id = 0;
 static struct queue *devices = NULL;
 static GIOChannel *hfp_hf_server = NULL;
 
+static struct bt_sco *sco = NULL;
+
 static struct device *find_default_device(void)
 {
 	return queue_peek_head(devices);
@@ -1999,6 +2002,11 @@ static void cleanup_hfp_hf(void)
 		bt_adapter_remove_record(hfp_hf_record_id);
 		hfp_hf_record_id = 0;
 	}
+
+	if (sco) {
+		bt_sco_unref(sco);
+		sco = NULL;
+	}
 }
 
 bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
@@ -2016,6 +2024,12 @@ bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
 	if (!enable_hf_client())
 		goto failed;
 
+	sco = bt_sco_new(addr);
+	if (!sco) {
+		error("hf-client: Cannot create SCO. HFP AG is in use ?");
+		goto failed;
+	}
+
 	hal_ipc = ipc;
 	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
@@ -2023,6 +2037,7 @@ bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
 	return true;
 
 failed:
+	cleanup_hfp_hf();
 	queue_destroy(devices, free);
 	devices = NULL;
 
-- 
1.8.4


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

* [PATCH v2 2/5] android/handsfree-client: Add handle incoming SCO connection
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 1/5] android/handsfree-client: Add SCO to handsfree client Lukasz Rymanowski
@ 2014-11-28  9:37 ` Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 3/5] android/handsfree-client: Implement audio connect/disconnect Lukasz Rymanowski
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index 9e67c7f..be12d5e 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -116,6 +116,7 @@ struct device {
 	bdaddr_t bdaddr;
 	struct hfp_hf *hf;
 	uint8_t state;
+	uint8_t audio_state;
 
 	uint8_t negotiated_codec;
 	uint32_t features;
@@ -184,6 +185,7 @@ static struct device *device_create(const bdaddr_t *bdaddr)
 
 	bacpy(&dev->bdaddr, bdaddr);
 	dev->state = HAL_HF_CLIENT_CONN_STATE_DISCONNECTED;
+	dev->audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED;
 
 	init_codecs(dev);
 
@@ -290,6 +292,26 @@ done:
 			HAL_OP_HF_CLIENT_DISCONNECT, status);
 }
 
+static void set_audio_state(struct device *dev, uint8_t state)
+{
+	struct hal_ev_hf_client_audio_state ev;
+	char address[18];
+
+	if (dev->audio_state == state)
+		return;
+
+	dev->audio_state = state;
+
+	ba2str(&dev->bdaddr, address);
+	DBG("device %s audio state %u", address, state);
+
+	bdaddr2android(&dev->bdaddr, ev.bdaddr);
+	ev.state = state;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
+				HAL_EV_HF_CLIENT_AUDIO_STATE, sizeof(ev), &ev);
+}
+
 static void handle_connect_audio(const void *buf, uint16_t len)
 {
 	DBG("Not Implemented");
@@ -2009,6 +2031,72 @@ static void cleanup_hfp_hf(void)
 	}
 }
 
+static bool confirm_sco_cb(const bdaddr_t *addr, uint16_t *voice_settings)
+{
+	struct device *dev;
+
+	DBG("");
+
+	dev = find_device(addr);
+	if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED) {
+		error("hf-client: No device or SLC not ready");
+		return false;
+	}
+
+	set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING);
+
+	if (codec_negotiation_supported(dev) &&
+			dev->negotiated_codec != CODEC_ID_CVSD)
+		*voice_settings = BT_VOICE_TRANSPARENT;
+	else
+		*voice_settings = BT_VOICE_CVSD_16BIT;
+
+	return true;
+}
+
+static void connect_sco_cb(enum sco_status status, const bdaddr_t *addr)
+{
+	struct device *dev;
+	uint8_t audio_state;
+
+	DBG("SCO Status %u", status);
+
+	/* Device shall be there, just sanity check */
+	dev = find_device(addr);
+	if (!dev) {
+		error("hf-client: There is no device?");
+		return;
+	}
+
+	if (status != SCO_STATUS_OK) {
+		audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED;
+		goto done;
+	}
+
+	if (dev->negotiated_codec == CODEC_ID_MSBC)
+		audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC;
+	else
+		audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED;
+
+done:
+	set_audio_state(dev, audio_state);
+}
+
+static void disconnect_sco_cb(const bdaddr_t *addr)
+{
+	struct device *dev;
+
+	DBG("");
+
+	dev = find_device(addr);
+	if (!dev) {
+		error("hf-client: No device");
+		return;
+	}
+
+	set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED);
+}
+
 bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
 {
 	DBG("");
@@ -2030,6 +2118,10 @@ bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr)
 		goto failed;
 	}
 
+	bt_sco_set_confirm_cb(sco, confirm_sco_cb);
+	bt_sco_set_connect_cb(sco, connect_sco_cb);
+	bt_sco_set_disconnect_cb(sco, disconnect_sco_cb);
+
 	hal_ipc = ipc;
 	ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, cmd_handlers,
 						G_N_ELEMENTS(cmd_handlers));
-- 
1.8.4


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

* [PATCH v2 3/5] android/handsfree-client: Implement audio connect/disconnect
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 1/5] android/handsfree-client: Add SCO to handsfree client Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 2/5] android/handsfree-client: Add handle incoming SCO connection Lukasz Rymanowski
@ 2014-11-28  9:37 ` Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 4/5] android/handsfree-client: Send AT+BCC to start codec negotiation Lukasz Rymanowski
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/handsfree-client.c | 60 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index be12d5e..fd68d78 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -312,19 +312,69 @@ static void set_audio_state(struct device *dev, uint8_t state)
 				HAL_EV_HF_CLIENT_AUDIO_STATE, sizeof(ev), &ev);
 }
 
+static bool connect_sco(struct device *dev)
+{
+	/* TODO: handle codec negotiation */
+
+	return bt_sco_connect(sco, &dev->bdaddr, BT_VOICE_CVSD_16BIT);
+}
+
 static void handle_connect_audio(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_connect_audio *cmd = (void *) buf;
+	struct device *dev;
+	uint8_t status;
+	bdaddr_t bdaddr;
+
+	DBG("");
+
+	android2bdaddr(&cmd->bdaddr, &bdaddr);
+
+	dev = find_device(&bdaddr);
+	if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED ||
+		dev->audio_state != HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
+		error("hf-client: Cannot create SCO, check SLC or audio state");
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	if (connect_sco(dev)) {
+		status = HAL_STATUS_SUCCESS;
+		set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING);
+	} else {
+		status = HAL_STATUS_FAILED;
+	}
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-			HAL_OP_HF_CLIENT_CONNECT_AUDIO, HAL_STATUS_UNSUPPORTED);
+					HAL_OP_HF_CLIENT_CONNECT_AUDIO, status);
 }
 
 static void handle_disconnect_audio(const void *buf, uint16_t len)
 {
-	DBG("Not Implemented");
+	const struct hal_cmd_hf_client_disconnect_audio *cmd = (void *) buf;
+	struct device *dev;
+	uint8_t status;
+	bdaddr_t bdaddr;
+
+	DBG("");
+
+	android2bdaddr(&cmd->bdaddr, &bdaddr);
+
+	dev = find_device(&bdaddr);
+	if (!dev ||
+		dev->audio_state == HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) {
+		error("hf-client: Device not found or audio not connected");
+		status = HAL_STATUS_FAILED;
+		goto done;
+	}
+
+	bt_sco_disconnect(sco);
+	status = HAL_STATUS_SUCCESS;
+
+done:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT,
-					HAL_OP_HF_CLIENT_DISCONNECT_AUDIO,
-					HAL_STATUS_UNSUPPORTED);
+				HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, status);
 }
 
 static void cmd_complete_cb(enum hfp_result result, enum hfp_error cme_err,
-- 
1.8.4


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

* [PATCH v2 4/5] android/handsfree-client: Send AT+BCC to start codec negotiation
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
                   ` (2 preceding siblings ...)
  2014-11-28  9:37 ` [PATCH v2 3/5] android/handsfree-client: Implement audio connect/disconnect Lukasz Rymanowski
@ 2014-11-28  9:37 ` Lukasz Rymanowski
  2014-11-28  9:37 ` [PATCH v2 5/5] android/README: Update status of HAL HFP HF implementation Lukasz Rymanowski
  2014-12-01 16:14 ` [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

With this patch we start codec negotation on audio connect if both sides
does support it.

This patch also moves codec_negotiation_supported functions up in the
file
---
 android/handsfree-client.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/android/handsfree-client.c b/android/handsfree-client.c
index fd68d78..9818a47 100644
--- a/android/handsfree-client.c
+++ b/android/handsfree-client.c
@@ -312,9 +312,26 @@ static void set_audio_state(struct device *dev, uint8_t state)
 				HAL_EV_HF_CLIENT_AUDIO_STATE, sizeof(ev), &ev);
 }
 
+static void bcc_cb(enum hfp_result result, enum hfp_error cme_err,
+							void *user_data)
+{
+	struct device *dev = user_data;
+
+	if (result != HFP_RESULT_OK)
+		set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED);
+}
+
+static bool codec_negotiation_supported(struct device *dev)
+{
+	return (dev->features & HFP_AG_FEAT_CODEC) &&
+			(hfp_hf_features & HFP_HF_FEAT_CODEC);
+}
+
 static bool connect_sco(struct device *dev)
 {
-	/* TODO: handle codec negotiation */
+	if (codec_negotiation_supported(dev))
+		return hfp_hf_send_command(dev->hf, bcc_cb, dev,
+								"AT+BCC");
 
 	return bt_sco_connect(sco, &dev->bdaddr, BT_VOICE_CVSD_16BIT);
 }
@@ -383,7 +400,6 @@ static void cmd_complete_cb(enum hfp_result result, enum hfp_error cme_err,
 	struct hal_ev_hf_client_command_complete ev;
 
 	DBG("");
-
 	memset(&ev, 0, sizeof(ev));
 
 	switch (result) {
@@ -1653,12 +1669,6 @@ static void slc_brsf_cb(struct hfp_context *context, void *user_data)
 		dev->features = feat;
 }
 
-static bool codec_negotiation_supported(struct device *dev)
-{
-	return (dev->features & HFP_AG_FEAT_CODEC) &&
-			(hfp_hf_features & HFP_HF_FEAT_CODEC);
-}
-
 static void slc_brsf_resp(enum hfp_result result, enum hfp_error cme_err,
 							void *user_data)
 {
-- 
1.8.4


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

* [PATCH v2 5/5] android/README: Update status of HAL HFP HF implementation
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
                   ` (3 preceding siblings ...)
  2014-11-28  9:37 ` [PATCH v2 4/5] android/handsfree-client: Send AT+BCC to start codec negotiation Lukasz Rymanowski
@ 2014-11-28  9:37 ` Lukasz Rymanowski
  2014-12-01 16:14 ` [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Lukasz Rymanowski @ 2014-11-28  9:37 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lukasz Rymanowski

---
 android/README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/README b/android/README
index aa12e51..6e5c95a 100644
--- a/android/README
+++ b/android/README
@@ -289,7 +289,7 @@ health            bt_hl.h            complete      complete
 pan               bt_pan.h           complete      complete
 avrcp             bt_rc.h            complete      complete
 socket            bt_sock.h          complete      partial
-handsfree_client  bt_hf_client.h     N/A           partial
+handsfree_client  bt_hf_client.h     N/A           complete
 map_client        bt_mce.h           N/A           complete
 a2dp_sink         bt_av.h            N/A           partial
 avrcp_ctrl        bt_rc.h            N/A           partial
-- 
1.8.4


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

* Re: [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF
  2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
                   ` (4 preceding siblings ...)
  2014-11-28  9:37 ` [PATCH v2 5/5] android/README: Update status of HAL HFP HF implementation Lukasz Rymanowski
@ 2014-12-01 16:14 ` Szymon Janc
  5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-12-01 16:14 UTC (permalink / raw)
  To: Lukasz Rymanowski; +Cc: linux-bluetooth

Hi Łukasz,

On Friday 28 of November 2014 10:37:20 Lukasz Rymanowski wrote:
> Last missing piece to HFP HF implementation.
> 
> v2:
> * Handled Szymon comments
> * rebase and minor self review fixes in 2/5
> 
> Lukasz Rymanowski (5):
>   android/handsfree-client: Add SCO to handsfree client
>   android/handsfree-client: Add handle incoming SCO connection
>   android/handsfree-client: Implement audio connect/disconnect
>   android/handsfree-client: Send AT+BCC to start codec negotiation
>   android/README: Update status of HAL HFP HF implementation
> 
>  android/README             |   2 +-
>  android/handsfree-client.c | 191 ++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 180 insertions(+), 13 deletions(-)

All patches applied, thanks.

-- 
Best regards, 
Szymon Janc

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

end of thread, other threads:[~2014-12-01 16:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-28  9:37 [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Lukasz Rymanowski
2014-11-28  9:37 ` [PATCH v2 1/5] android/handsfree-client: Add SCO to handsfree client Lukasz Rymanowski
2014-11-28  9:37 ` [PATCH v2 2/5] android/handsfree-client: Add handle incoming SCO connection Lukasz Rymanowski
2014-11-28  9:37 ` [PATCH v2 3/5] android/handsfree-client: Implement audio connect/disconnect Lukasz Rymanowski
2014-11-28  9:37 ` [PATCH v2 4/5] android/handsfree-client: Send AT+BCC to start codec negotiation Lukasz Rymanowski
2014-11-28  9:37 ` [PATCH v2 5/5] android/README: Update status of HAL HFP HF implementation Lukasz Rymanowski
2014-12-01 16:14 ` [PATCH v2 0/5] android/handsfree-client: Add SCO to HFP HF Szymon Janc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox