diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-11 11:05:24 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-11 11:05:24 +0000 |
commit | 6763ebb3c231740c66a235f94d56e8d8cc213d90 (patch) | |
tree | 527ad7a778289b70ac64b2d4e49512eae6d634e2 /audio/device.c | |
parent | 46e860574f3d6d70d961e38270522764191cea20 (diff) |
Integrate A2DP work from Johan's and Luiz's GIT trees
Diffstat (limited to 'audio/device.c')
-rw-r--r-- | audio/device.c | 207 |
1 files changed, 166 insertions, 41 deletions
diff --git a/audio/device.c b/audio/device.c index 785d0115..af7cca80 100644 --- a/audio/device.c +++ b/audio/device.c @@ -100,21 +100,24 @@ static DBusMethodVTable device_methods[] = { { NULL, NULL, NULL, NULL } }; -static void device_free(struct device *device) +static void device_free(struct device *dev) { - if (device->headset) - headset_free(device); + if (dev->headset) + headset_free(dev); - if (device->conn) - dbus_connection_unref(device->conn); + if (dev->sink) + sink_free(dev); - if (device->adapter_path) - g_free(device->adapter_path); + if (dev->conn) + dbus_connection_unref(dev->conn); - if (device->path) - g_free(device->path); + if (dev->adapter_path) + g_free(dev->adapter_path); - g_free(device); + if (dev->path) + g_free(dev->path); + + g_free(dev); } static void device_unregister(DBusConnection *conn, void *data) @@ -129,7 +132,7 @@ static void device_unregister(DBusConnection *conn, void *data) struct device *device_register(DBusConnection *conn, const char *path, bdaddr_t *bda) { - struct device *device; + struct device *dev; bdaddr_t src; int dev_id; @@ -141,12 +144,12 @@ struct device *device_register(DBusConnection *conn, if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) return NULL; - device = g_new0(struct device, 1); + dev = g_new0(struct device, 1); - if (!dbus_connection_create_object_path(conn, path, device, + if (!dbus_connection_create_object_path(conn, path, dev, device_unregister)) { error("D-Bus failed to register %s path", path); - device_free(device); + device_free(dev); return NULL; } @@ -158,58 +161,69 @@ struct device *device_register(DBusConnection *conn, return NULL; } - device->path = g_strdup(path); - bacpy(&device->dst, bda); - bacpy(&device->src, &src); - device->conn = dbus_connection_ref(conn); - device->adapter_path = g_malloc0(16); - snprintf(device->adapter_path, 16, "/org/bluez/hci%d", dev_id); + dev->path = g_strdup(path); + bacpy(&dev->dst, bda); + bacpy(&dev->src, &src); + dev->conn = dbus_connection_ref(conn); + dev->adapter_path = g_malloc0(16); + snprintf(dev->adapter_path, 16, "/org/bluez/hci%d", dev_id); - return device; + return dev; } -int device_store(struct device *device, gboolean is_default) +int device_store(struct device *dev, gboolean is_default) { char value[64]; char filename[PATH_MAX + 1]; char src_addr[18], dst_addr[18]; + int offset = 0; - if (!device->path) + if (!dev->path) return -EINVAL; - ba2str(&device->dst, dst_addr); - ba2str(&device->src, src_addr); + ba2str(&dev->dst, dst_addr); + ba2str(&dev->src, src_addr); create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio"); create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (is_default) textfile_put(filename, "default", dst_addr); - if (device->headset) - snprintf(value, 64, "headset"); - else if (device->gateway) - snprintf(value, 64, "gateway"); - else if (device->sink) - snprintf(value, 64, "sink"); - else if (device->source) - snprintf(value, 64, "source"); - else if (device->control) - snprintf(value, 64, "control"); - else - snprintf(value, 64, "target"); + if (dev->headset) { + snprintf(value, 64, "headset "); + offset += strlen("headset "); + } + if (dev->gateway) { + snprintf(value + offset, 64 - offset, "gateway "); + offset += strlen("gateway "); + } + if (dev->sink) { + snprintf(value + offset, 64 - offset, "sink "); + offset += strlen("sink "); + } + if (dev->source) { + snprintf(value + offset, 64 - offset, "source "); + offset += strlen("source "); + } + if (dev->control) { + snprintf(value + offset, 64 - offset, "control "); + offset += strlen("control "); + } + if (dev->target) + snprintf(value + offset, 64 - offset, "target"); return textfile_put(filename, dst_addr, value); } -void device_finish_sdp_transaction(struct device *device) +void device_finish_sdp_transaction(struct device *dev) { char address[18], *addr_ptr = address; DBusMessage *msg, *reply; DBusError derr; - ba2str(&device->dst, address); + ba2str(&dev->dst, address); - msg = dbus_message_new_method_call("org.bluez", device->adapter_path, + msg = dbus_message_new_method_call("org.bluez", dev->adapter_path, "org.bluez.Adapter", "FinishRemoteServiceTransaction"); if (!msg) { @@ -221,7 +235,7 @@ void device_finish_sdp_transaction(struct device *device) DBUS_TYPE_INVALID); dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(device->conn, + reply = dbus_connection_send_with_reply_and_block(dev->conn, msg, -1, &derr); dbus_message_unref(msg); @@ -236,3 +250,114 @@ void device_finish_sdp_transaction(struct device *device) dbus_message_unref(reply); } + +int device_get_config(struct device *dev, int sock, struct ipc_packet *req, + int pkt_len, struct ipc_data_cfg **rsp) +{ + if (dev->sink && sink_is_active(dev)) + return sink_get_config(dev, sock, req, pkt_len, rsp); + else if (dev->headset && headset_is_active(dev)) + return headset_get_config(dev, sock, req, pkt_len, rsp); + else if (dev->sink) + return sink_get_config(dev, sock, req, pkt_len, rsp); + else if (dev->headset) + return headset_get_config(dev, sock, req, pkt_len, rsp); + + return -EINVAL; +} + +static avdtp_state_t ipc_to_avdtp_state(uint8_t ipc_state) +{ + switch (ipc_state) { + case STATE_DISCONNECTED: + return AVDTP_STATE_IDLE; + case STATE_CONNECTING: + return AVDTP_STATE_CONFIGURED; + case STATE_CONNECTED: + return AVDTP_STATE_OPEN; + case STATE_STREAM_STARTING: + case STATE_STREAMING: + return AVDTP_STATE_STREAMING; + default: + error("Unknown ipc state"); + return AVDTP_STATE_IDLE; + } +} + +static headset_state_t ipc_to_hs_state(uint8_t ipc_state) +{ + switch (ipc_state) { + case STATE_DISCONNECTED: + return HEADSET_STATE_DISCONNECTED; + case STATE_CONNECTING: + return HEADSET_STATE_CONNECT_IN_PROGRESS; + case STATE_CONNECTED: + return HEADSET_STATE_CONNECTED; + case STATE_STREAM_STARTING: + return HEADSET_STATE_PLAY_IN_PROGRESS; + case STATE_STREAMING: + return HEADSET_STATE_PLAYING; + default: + error("Unknown ipc state"); + return HEADSET_STATE_DISCONNECTED; + } +} + +void device_set_state(struct device *dev, uint8_t state) +{ + if (dev->sink && sink_is_active(dev)) + sink_set_state(dev, ipc_to_avdtp_state(state)); + else if (dev->headset && headset_is_active(dev)) + headset_set_state(dev, ipc_to_hs_state(state)); +} + +static uint8_t avdtp_to_ipc_state(avdtp_state_t state) +{ + switch (state) { + case AVDTP_STATE_IDLE: + return STATE_DISCONNECTED; + case AVDTP_STATE_CONFIGURED: + return STATE_CONNECTING; + case AVDTP_STATE_OPEN: + return STATE_CONNECTED; + case AVDTP_STATE_STREAMING: + return STATE_STREAMING; + default: + error("Unknown avdt state"); + return AVDTP_STATE_IDLE; + } +} + +static uint8_t hs_to_ipc_state(headset_state_t state) +{ + switch (state) { + case HEADSET_STATE_DISCONNECTED: + return STATE_DISCONNECTED; + case HEADSET_STATE_CONNECT_IN_PROGRESS: + return STATE_CONNECTING; + case HEADSET_STATE_CONNECTED: + return STATE_CONNECTED; + case HEADSET_STATE_PLAY_IN_PROGRESS: + return STATE_STREAMING; + default: + error("Unknown headset state"); + return AVDTP_STATE_IDLE; + } +} + +uint8_t device_get_state(struct device *dev) +{ + avdtp_state_t sink_state; + headset_state_t hs_state; + + if (dev->sink && sink_is_active(dev)) { + sink_state = sink_get_state(dev); + return avdtp_to_ipc_state(sink_state); + } + else if (dev->headset && headset_is_active(dev)) { + hs_state = headset_get_state(dev); + return hs_to_ipc_state(hs_state); + } + + return STATE_DISCONNECTED; +} |