diff options
-rw-r--r-- | audio/headset.c | 89 | ||||
-rw-r--r-- | audio/manager.c | 63 | ||||
-rw-r--r-- | audio/pcm_bluetooth.c | 28 | ||||
-rw-r--r-- | audio/unix.c | 2 |
4 files changed, 112 insertions, 70 deletions
diff --git a/audio/headset.c b/audio/headset.c index 109e7c5d..1e1f3271 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -160,7 +160,8 @@ static void hs_signal_gain_setting(audio_device_t *device, const char *buf) DBUS_TYPE_INVALID); } -static headset_event_t parse_headset_event(const char *buf, char *rsp, int rsp_len) +static headset_event_t parse_headset_event(const char *buf, char *rsp, + int rsp_len) { printf("Received: %s\n", buf); @@ -215,7 +216,8 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, if (cond & (G_IO_ERR | G_IO_HUP)) goto failed; - err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf) - 1, &bytes_read); + err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf) - 1, + &bytes_read); if (err != G_IO_ERROR_NONE) goto failed; @@ -244,7 +246,8 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, memset(rsp, 0, sizeof(rsp)); - switch (parse_headset_event(&hs->buf[hs->data_start], rsp, sizeof(rsp))) { + switch (parse_headset_event(&hs->buf[hs->data_start], rsp, + sizeof(rsp))) { case HEADSET_EVENT_GAIN: hs_signal_gain_setting(device, &hs->buf[hs->data_start] + 2); break; @@ -273,9 +276,10 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond, err = G_IO_ERROR_NONE; while (err == G_IO_ERROR_NONE && total_bytes_written < count) { - /* FIXME: make it async */ - err = g_io_channel_write(hs->rfcomm, rsp + total_bytes_written, - count - total_bytes_written, &bytes_written); + err = g_io_channel_write(hs->rfcomm, + rsp + total_bytes_written, + count - total_bytes_written, + &bytes_written); if (err != G_IO_ERROR_NONE) error("Error while writting to the audio output channel"); total_bytes_written += bytes_written; @@ -345,7 +349,8 @@ static void auth_callback(DBusPendingCall *call, void *data) } else { char hs_address[18]; - g_io_add_watch(hs->rfcomm, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + g_io_add_watch(hs->rfcomm, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc) rfcomm_io_cb, device); ba2str(&device->bda, hs_address); @@ -363,7 +368,8 @@ static void auth_callback(DBusPendingCall *call, void *data) dbus_message_unref(reply); } -static gboolean sco_cb(GIOChannel *chan, GIOCondition cond, audio_device_t *device) +static gboolean sco_cb(GIOChannel *chan, GIOCondition cond, + audio_device_t *device) { struct headset *hs; @@ -579,7 +585,8 @@ static int rfcomm_connect(audio_device_t *device, int *err) if (!(errno == EAGAIN || errno == EINPROGRESS)) { if (err) *err = errno; - error("connect() failed: %s (%d)", strerror(errno), errno); + error("connect() failed: %s (%d)", strerror(errno), + errno); goto failed; } @@ -604,7 +611,8 @@ failed: static int create_hsp_ag_record(sdp_buf_t *buf, uint8_t ch) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + 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; @@ -665,7 +673,8 @@ static int create_hsp_ag_record(sdp_buf_t *buf, uint8_t ch) static int create_hfp_ag_record(sdp_buf_t *buf, uint8_t ch) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + 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; @@ -753,7 +762,8 @@ static uint32_t headset_add_ag_record(uint8_t channel, sdp_buf_t *buf) dbus_message_unref(msg); - if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { + if (dbus_error_is_set(&derr) || + dbus_set_error_from_message(&derr, reply)) { error("Adding service record failed: %s", derr.message); dbus_error_free(&derr); return 0; @@ -763,7 +773,8 @@ static uint32_t headset_add_ag_record(uint8_t channel, sdp_buf_t *buf) DBUS_TYPE_INVALID); if (dbus_error_is_set(&derr)) { - error("Invalid arguments to AddServiceRecord reply: %s", derr.message); + error("Invalid arguments to AddServiceRecord reply: %s", + derr.message); dbus_message_unref(reply); dbus_error_free(&derr); return 0; @@ -782,7 +793,8 @@ int headset_remove_ag_record(uint32_t rec_id) DBusError derr; msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "RemoveServiceRecord"); + "org.bluez.Database", + "RemoveServiceRecord"); if (!msg) { error("Can't allocate new method call"); return 0; @@ -798,7 +810,8 @@ int headset_remove_ag_record(uint32_t rec_id) dbus_message_unref(msg); if (dbus_error_is_set(&derr)) { - error("Removing service record 0x%x failed: %s", rec_id, derr.message); + error("Removing service record 0x%x failed: %s", + rec_id, derr.message); dbus_error_free(&derr); return 0; } @@ -837,7 +850,8 @@ static void get_record_reply(DBusPendingCall *call, void *data) } if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &array, &array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &array, &array_len, DBUS_TYPE_INVALID)) { error("Unable to get args from GetRecordReply"); goto failed_not_supported; @@ -870,15 +884,18 @@ static void get_record_reply(DBusPendingCall *call, void *data) goto failed_not_supported; } - if ((uuid.type == SDP_UUID32 && uuid.value.uuid32 != HEADSET_SVCLASS_ID) || - (uuid.type == SDP_UUID16 && uuid.value.uuid16 != HEADSET_SVCLASS_ID)) { + if ((uuid.type == SDP_UUID32 && + uuid.value.uuid32 != HEADSET_SVCLASS_ID) || + (uuid.type == SDP_UUID16 && + uuid.value.uuid16 != HEADSET_SVCLASS_ID)) { error("Service classes did not contain the expected UUID"); goto failed_not_supported; } if (!sdp_get_access_protos(record, &protos)) { ch = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); + sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, + NULL); sdp_list_free(protos, NULL); protos = NULL; } @@ -937,7 +954,8 @@ static DBusHandlerResult hs_stop(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NEED_MEMORY; } - if (hs->state == HEADSET_STATE_PLAY_IN_PROGRESS && hs->pending_connect) { + if (hs->state == HEADSET_STATE_PLAY_IN_PROGRESS && + hs->pending_connect) { g_io_channel_close(hs->pending_connect->io); if (hs->pending_connect->msg) err_connect_failed(connection, hs->pending_connect->msg, @@ -1011,7 +1029,8 @@ static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg, if (hs->pending_connect->io) g_io_channel_close(hs->pending_connect->io); if (hs->pending_connect->msg) - err_connect_failed(connection, hs->pending_connect->msg, + err_connect_failed(connection, + hs->pending_connect->msg, EINTR); pending_connect_free(hs->pending_connect); hs->pending_connect = NULL; @@ -1035,7 +1054,8 @@ static DBusHandlerResult hs_disconnect(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult hs_is_connected(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult hs_is_connected(DBusConnection *conn, + DBusMessage *msg, void *data) { audio_device_t *device = data; @@ -1080,7 +1100,8 @@ static void get_handles_reply(DBusPendingCall *call, void *data) if (dbus_set_error_from_message(&derr, reply)) { error("GetRemoteServiceHandles failed: %s", derr.message); if (c->msg) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connect_failed(connection, c->msg, EHOSTDOWN); else err_not_supported(connection, c->msg); @@ -1090,7 +1111,8 @@ static void get_handles_reply(DBusPendingCall *call, void *data) } if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &array, &array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, + &array, &array_len, DBUS_TYPE_INVALID)) { error("Unable to get args from reply"); @@ -1173,7 +1195,7 @@ static DBusHandlerResult hs_connect(DBusConnection *conn, DBusMessage *msg, hs->pending_connect = g_try_new0(struct pending_connect, 1); if (!hs->pending_connect) { - error("Out of memory when allocating new struct pending_connect"); + error("Out of memory when allocating struct pending_connect"); return DBUS_HANDLER_RESULT_NEED_MEMORY; } @@ -1290,7 +1312,7 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg, } if (hs->ring_timer) { - debug("Got Ring method call while ringing already in progress"); + debug("IndicateCall received when already indicating"); goto done; } @@ -1308,7 +1330,8 @@ done: return DBUS_HANDLER_RESULT_HANDLED; } -static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult hs_cancel_ringing(DBusConnection *conn, + DBusMessage *msg, void *data) { audio_device_t *device = data; @@ -1350,7 +1373,7 @@ static DBusHandlerResult hs_play(DBusConnection *conn, DBusMessage *msg, int sk, err; if (hs->state < HEADSET_STATE_CONNECTED) - return err_not_connected(connection, msg); /* FIXME: in progress error? */ + return err_not_connected(connection, msg); if (hs->state >= HEADSET_STATE_PLAY_IN_PROGRESS || hs->pending_connect) return err_already_connected(connection, msg); @@ -1580,7 +1603,8 @@ void headset_free(const char *object_path) device->headset = NULL; } -static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, void *data) +static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, + void *data) { int srv_sk, cli_sk; struct sockaddr_rc addr; @@ -1640,10 +1664,11 @@ static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, void * uuid = HFP_AG_UUID; } - auth = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", + auth = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "RequestAuthorization"); if (!auth) { - error("Unable to allocat new RequestAuthorization method call"); + error("Unable to allocate RequestAuthorization method call"); goto failed; } @@ -1652,7 +1677,7 @@ static gboolean headset_server_io_cb(GIOChannel *chan, GIOCondition cond, void * dbus_message_append_args(auth, DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - if (dbus_connection_send_with_reply(connection, auth, &pending, -1) == FALSE) { + if (!dbus_connection_send_with_reply(connection, auth, &pending, -1)) { error("Sending of authorization request failed"); goto failed; } diff --git a/audio/manager.c b/audio/manager.c index 18a653da..c0b51976 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -162,7 +162,8 @@ static audio_device_t *find_device(bdaddr_t *bda) return NULL; } -static DBusHandlerResult device_get_address(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult device_get_address(DBusConnection *conn, + DBusMessage *msg, void *data) { audio_device_t *device = data; @@ -250,13 +251,15 @@ static void remove_device(audio_device_t *device) static gboolean add_device(audio_device_t *device) { - if (!dbus_connection_create_object_path(connection, device->object_path, + if (!dbus_connection_create_object_path(connection, + device->object_path, device, NULL)) { error("D-Bus failed to register %s path", device->object_path); return FALSE; } - if (!dbus_connection_register_interface(connection, device->object_path, + if (!dbus_connection_register_interface(connection, + device->object_path, AUDIO_DEVICE_INTERFACE, device_methods, NULL, NULL)) { error("Failed to register %s interface to %s", @@ -330,7 +333,8 @@ void finish_sdp_transaction(DBusConnection *conn, bdaddr_t *dba) dbus_message_unref(msg); - if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { + if (dbus_error_is_set(&derr) || + dbus_set_error_from_message(&derr, reply)) { error("FinishRemoteServiceTransaction(%s) failed: %s", address, derr.message); dbus_error_free(&derr); @@ -638,7 +642,8 @@ static void get_handles_reply(DBusPendingCall *call, } if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &array, &array_len, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, + &array, &array_len, DBUS_TYPE_INVALID)) { err_failed(connection, data->msg, @@ -830,7 +835,8 @@ static gboolean device_matches(audio_device_t *device, char **interfaces) return TRUE; } -static DBusHandlerResult am_create_device(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult am_create_device(DBusConnection *conn, + DBusMessage *msg, void *data) { const char *address, *path; @@ -966,16 +972,16 @@ static DBusHandlerResult am_create_headset(DBusConnection *conn, DBusMessage *ms "Unable to create new audio device"); } - created = TRUE; - if (!device->headset) { device->headset = headset_init(device->object_path, NULL, 0); - if (!device->headset) { - remove_device(device); - return error_reply(connection, msg, - "org.bluez.audio.Error.Failed", - "Unable to init Headset interface"); - } + created = TRUE; + } + + if (!device->headset) { + remove_device(device); + return error_reply(connection, msg, + "org.bluez.audio.Error.Failed", + "Unable to init Headset interface"); } done: @@ -1087,7 +1093,8 @@ static DBusHandlerResult am_remove_headset(DBusConnection *conn, return am_remove_device(conn, msg, data); } -static DBusHandlerResult am_list_headsets(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult am_list_headsets(DBusConnection *conn, + DBusMessage *msg, void *data) { DBusMessageIter iter; @@ -1122,7 +1129,8 @@ static DBusHandlerResult am_list_headsets(DBusConnection *conn, DBusMessage *msg return send_message_and_unref(connection, reply); } -static DBusHandlerResult am_find_by_addr(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult am_find_by_addr(DBusConnection *conn, + DBusMessage *msg, void *data) { const char *path, *address; @@ -1160,7 +1168,8 @@ static DBusHandlerResult am_find_by_addr(DBusConnection *conn, DBusMessage *msg, return send_message_and_unref(conn, reply); } -static DBusHandlerResult am_get_default_headset(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult am_get_default_headset(DBusConnection *conn, + DBusMessage *msg, void *data) { DBusMessage *reply; @@ -1183,7 +1192,8 @@ static DBusHandlerResult am_get_default_headset(DBusConnection *conn, DBusMessag return send_message_and_unref(connection, reply); } -static DBusHandlerResult am_change_default_headset(DBusConnection *conn, DBusMessage *msg, +static DBusHandlerResult am_change_default_headset(DBusConnection *conn, + DBusMessage *msg, void *data) { DBusError derr; @@ -1295,11 +1305,18 @@ void audio_exit(void) int manager_get_device(uint8_t role, struct ipc_data_cfg *cfg) { - if (default_hs == NULL || default_hs->headset == NULL) - return -1; + GSList *l; - if (!headset_is_connected(default_hs->headset)) - return -1; + if (default_hs && default_hs->headset && + headset_is_connected(default_hs->headset)) + return headset_get_config(default_hs->headset, cfg); + + for (l = devices; l != NULL; l = l->next) { + audio_device_t *dev = l->data; + + if (dev->headset && headset_is_connected(dev->headset)) + return headset_get_config(dev->headset, cfg); + } - return headset_get_config(default_hs->headset, cfg); + return -1; } diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c index f2d3c275..26b7ad2c 100644 --- a/audio/pcm_bluetooth.c +++ b/audio/pcm_bluetooth.c @@ -57,14 +57,14 @@ struct bluetooth_data { static int bluetooth_start(snd_pcm_ioplug_t *io) { - DBG("io %p", io); + DBG("bluetooth_start %p", io); return 0; } static int bluetooth_stop(snd_pcm_ioplug_t *io) { - DBG("io %p", io); + DBG("bluetooth_stop %p", io); return 0; } @@ -73,7 +73,7 @@ static snd_pcm_sframes_t bluetooth_pointer(snd_pcm_ioplug_t *io) { struct bluetooth_data *data = io->private_data; - DBG("io %p", io); + DBG("bluetooth_pointer %p", io); DBG("hw_ptr=%lu", data->hw_ptr); @@ -84,14 +84,13 @@ static int bluetooth_close(snd_pcm_ioplug_t *io) { struct bluetooth_data *data = io->private_data; - DBG("io %p", io); + DBG("bluetooth_close %p", io); free(data); return 0; } - static int bluetooth_prepare(snd_pcm_ioplug_t *io) { struct bluetooth_data *data = io->private_data; @@ -99,16 +98,15 @@ static int bluetooth_prepare(snd_pcm_ioplug_t *io) DBG("Preparing with io->period_size = %lu, io->buffer_size = %lu", io->period_size, io->buffer_size); - if (io->stream == SND_PCM_STREAM_PLAYBACK) { + if (io->stream == SND_PCM_STREAM_PLAYBACK) /* If not null for playback, xmms doesn't display time * correctly */ data->hw_ptr = 0; - } - else { + else /* ALSA library is really picky on the fact hw_ptr is not null. * If it is, capture won't start */ data->hw_ptr = io->period_size; - } + return 0; } @@ -118,22 +116,22 @@ static int bluetooth_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params struct ipc_data_cfg cfg = data->cfg; uint32_t period_count = io->buffer_size / io->period_size; int opt_name; + + DBG("fd = %d, period_count = %d", cfg.fd, period_count); opt_name = (io->stream == SND_PCM_STREAM_PLAYBACK) ? SCO_TXBUFS : SCO_RXBUFS; - DBG("fd = %d, period_count = %d", cfg.fd, period_count); - if (setsockopt(cfg.fd, SOL_SCO, opt_name, &period_count, - sizeof(period_count)) == 0) + sizeof(period_count)) == 0) return 0; - + opt_name = (io->stream == SND_PCM_STREAM_PLAYBACK) ? - SO_SNDBUF : SO_RCVBUF; + SO_SNDBUF : SO_RCVBUF; if (setsockopt(cfg.fd, SOL_SCO, opt_name, &period_count, sizeof(period_count)) == 0) - return 0; + return 0; /* backward compatible to the old patch */ diff --git a/audio/unix.c b/audio/unix.c index f2bf2271..76650b75 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -85,9 +85,11 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data) pkt->type = PKT_TYPE_CFG_RSP; pkt->length = sizeof(struct ipc_data_cfg); pkt->error = PKT_ERROR_NONE; + len = sendto(sk, pkt, len, 0, (struct sockaddr *) &addr, addrlen); if (len < 0) info("Error %s(%d)", strerror(errno), errno); + info("%d bytes sent", len); break; case PKT_TYPE_STATUS_REQ: |