@@ -163,24 +163,23 @@ unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
0x0064 /* 1s timeout */);
ret = asha_connect_socket(asha_dev, cb, user_data);
if (ret < 0)
return 0;
else
return (++asha_dev->resume_id);
}
-unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev,
- bt_asha_cb_t cb, void *user_data)
+unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev)
{
- bt_asha_stop(asha_dev->asha, cb, user_data);
+ bt_asha_stop(asha_dev->asha);
if (asha_dev->io) {
g_io_channel_shutdown(asha_dev->io, TRUE, NULL);
g_io_channel_unref(asha_dev->io);
asha_dev->io = NULL;
};
return asha_dev->resume_id;
}
@@ -12,22 +12,21 @@
#include <stdbool.h>
#include <stdint.h>
#include "src/shared/asha.h"
struct bt_asha_device;
unsigned int bt_asha_device_start(struct bt_asha_device *asha_dev,
bt_asha_cb_t cb, void *user_data);
-unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev,
- bt_asha_cb_t cb, void *user_data);
+unsigned int bt_asha_device_stop(struct bt_asha_device *asha_dev);
void bt_asha_device_state_reset(struct bt_asha_device *asha_dev);
unsigned int bt_asha_device_device_get_resume_id(
struct bt_asha_device *asha_dev);
uint16_t bt_asha_device_get_render_delay(struct bt_asha_device *asha_dev);
enum bt_asha_state_t bt_asha_device_get_state(
struct bt_asha_device *asha_dev);
int bt_asha_device_get_fd(struct bt_asha_device *asha_dev);
@@ -2240,23 +2240,20 @@ static void asha_transport_sync_state(struct media_transport *transport,
switch (bt_asha_device_get_state(asha_dev)) {
case ASHA_STOPPED:
transport_set_state(transport, TRANSPORT_STATE_IDLE);
break;
case ASHA_STARTING:
transport_set_state(transport, TRANSPORT_STATE_REQUESTING);
break;
case ASHA_STARTED:
transport_set_state(transport, TRANSPORT_STATE_ACTIVE);
break;
- case ASHA_STOPPING:
- transport_set_state(transport, TRANSPORT_STATE_SUSPENDING);
- break;
}
}
static void asha_transport_state_cb(int status, void *user_data)
{
struct media_owner *owner = user_data;
struct media_transport *transport = owner->transport;
struct bt_asha_device *asha_dev;
enum bt_asha_state_t state;
@@ -2317,53 +2314,48 @@ static guint transport_asha_resume(struct media_transport *transport,
return ret > 0 ? ret : 0;
}
static guint transport_asha_suspend(struct media_transport *transport,
struct media_owner *owner)
{
struct bt_asha_device *asha_dev = transport->data;
guint ret = 0;
if (owner) {
- ret = bt_asha_device_stop(asha_dev, asha_transport_state_cb,
- owner);
+ ret = bt_asha_device_stop(asha_dev);
asha_transport_sync_state(transport, asha_dev);
+ asha_transport_state_cb(-1, owner);
} else {
- ret = bt_asha_device_stop(asha_dev, NULL, NULL);
+ ret = bt_asha_device_stop(asha_dev);
/* We won't have a callback to set the final state */
transport_set_state(transport, TRANSPORT_STATE_IDLE);
}
return ret;
}
static void transport_asha_cancel(struct media_transport *transport, guint id)
{
struct bt_asha_device *asha_dev = transport->data;
enum bt_asha_state_t state = bt_asha_device_get_state(asha_dev);
if (id != bt_asha_device_device_get_resume_id(asha_dev)) {
/* Not current, ignore */
DBG("Ignoring cancel request for id %d", id);
return;
}
if (state == ASHA_STARTING || state == ASHA_STARTED) {
DBG("Cancel requested, stopping");
- bt_asha_device_stop(asha_dev, NULL, NULL);
+ bt_asha_device_stop(asha_dev);
/* We won't have a callback to set the final state */
transport_set_state(transport, TRANSPORT_STATE_IDLE);
- } else if (state == ASHA_STOPPING) {
- DBG("Cancel requested, resetting transport state");
- /* We already dispatched a stop, just reset our state */
- bt_asha_device_state_reset(asha_dev);
- transport_set_state(transport, TRANSPORT_STATE_IDLE);
}
}
static int transport_asha_get_volume(struct media_transport *transport)
{
struct bt_asha_device *asha_dev = transport->data;
int8_t volume;
int scaled_volume;
volume = bt_asha_device_get_volume(asha_dev);
@@ -265,37 +265,40 @@ unsigned int bt_asha_start(struct bt_asha *asha, bt_asha_cb_t cb,
ret = asha_send_acp(asha, acp_start_cmd, sizeof(acp_start_cmd), cb,
user_data);
if (ret < 0)
return ret;
asha->state = ASHA_STARTING;
return 0;
}
-unsigned int bt_asha_stop(struct bt_asha *asha, bt_asha_cb_t cb,
- void *user_data)
+unsigned int bt_asha_stop(struct bt_asha *asha)
{
uint8_t acp_stop_cmd[] = {
0x02, /* STOP */
};
int ret;
if (asha->state != ASHA_STARTED)
return 0;
- asha->state = ASHA_STOPPING;
+ asha->state = ASHA_STOPPED;
- ret = asha_send_acp(asha, acp_stop_cmd, sizeof(acp_stop_cmd),
- cb, user_data);
+ ret = asha_send_acp(asha, acp_stop_cmd, sizeof(acp_stop_cmd), NULL,
+ NULL);
asha_set_send_status(asha, false);
+ /* We reset our state without waiting for a response */
+ bt_asha_state_reset(asha);
+ DBG("ASHA stop done");
+
return ret;
}
static unsigned int bt_asha_status(struct bt_asha *asha, bool other_connected)
{
uint8_t status = other_connected ? 1 : 0;
uint8_t acp_status_cmd[] = {
0x03, /* STATUS */
status,
};
@@ -434,34 +437,32 @@ static void audio_status_register(uint16_t att_ecode, void *user_data)
static void audio_status_notify(uint16_t value_handle, const uint8_t *value,
uint16_t length, void *user_data)
{
struct bt_asha *asha = user_data;
uint8_t status = *value;
/* Back these up to survive the reset paths */
bt_asha_cb_t state_cb = asha->state_cb;
bt_asha_cb_t state_cb_data = asha->state_cb_data;
+ DBG("ASHA status %u", status);
+
if (asha->state == ASHA_STARTING) {
if (status == 0) {
asha->state = ASHA_STARTED;
DBG("ASHA start complete");
update_asha_set(asha, true);
asha_set_send_status(asha, true);
} else {
bt_asha_state_reset(asha);
DBG("ASHA start failed");
}
- } else if (asha->state == ASHA_STOPPING) {
- /* We reset our state, regardless */
- bt_asha_state_reset(asha);
- DBG("ASHA stop %s", status == 0 ? "complete" : "failed");
}
if (state_cb) {
state_cb(status, state_cb_data);
asha->state_cb = NULL;
asha->state_cb_data = NULL;
}
}
static void handle_characteristic(struct gatt_db_attribute *attr,
@@ -12,21 +12,20 @@
#
#include <stdbool.h>
#include <stdint.h>
enum bt_asha_state_t {
ASHA_STOPPED = 0,
ASHA_STARTING,
ASHA_STARTED,
- ASHA_STOPPING,
};
typedef void (*bt_asha_cb_t)(int status, void *data);
typedef void (*bt_asha_attach_cb_t)(void *data);
struct bt_asha {
struct bt_gatt_client *client;
struct gatt_db *db;
struct gatt_db_attribute *attr;
uint16_t acp_handle;
@@ -57,18 +56,17 @@ struct bt_asha_set {
struct bt_asha *right;
};
struct bt_asha *bt_asha_new(void);
void bt_asha_reset(struct bt_asha *asha);
void bt_asha_state_reset(struct bt_asha *asha);
void bt_asha_free(struct bt_asha *asha);
unsigned int bt_asha_start(struct bt_asha *asha, bt_asha_cb_t cb,
void *user_data);
-unsigned int bt_asha_stop(struct bt_asha *asha, bt_asha_cb_t cb,
- void *user_data);
+unsigned int bt_asha_stop(struct bt_asha *asha);
bool bt_asha_set_volume(struct bt_asha *asha, int8_t volume);
bool bt_asha_attach(struct bt_asha *asha, struct gatt_db *db,
struct bt_gatt_client *client, bt_asha_attach_cb_t probe_cb,
void *cb_user_data);
From: Arun Raghavan <arun@asymptotic.io> Not all devices respond with the status update, so let's just send it out and assume it worked. --- profiles/audio/asha.c | 5 ++--- profiles/audio/asha.h | 3 +-- profiles/audio/transport.c | 16 ++++------------ src/shared/asha.c | 19 ++++++++++--------- src/shared/asha.h | 4 +--- 5 files changed, 18 insertions(+), 29 deletions(-)