static void avctp_confirm_cb(GIOChannel *chan, gpointer data) { struct avctp *session; struct audio_device *dev; char address[18]; bdaddr_t src, dst; GError *err = NULL; uint16_t psm; struct btd_device *device; bt_io_get(chan, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_DEST, address, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID); if (err) { error("%s", err->message); g_error_free(err); g_io_channel_shutdown(chan, TRUE, NULL); return; } DBG("AVCTP: incoming connect from %s", address); device = adapter_find_device(adapter_find(&src), &dst); if (!device) return; session = avctp_get_internal(device); if (session == NULL) return; dev = manager_get_audio_device(device, TRUE); if (!dev) { error("Unable to get audio device object for %s", address); goto drop; } if (dev->control == NULL) { btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID); if (dev->control == NULL) goto drop; } switch (psm) { case AVCTP_CONTROL_PSM: avctp_control_confirm(session, chan, dev); break; case AVCTP_BROWSING_PSM: avctp_browsing_confirm(session, chan, dev); break; } return; drop: if (psm == AVCTP_CONTROL_PSM) avctp_set_state(session, AVCTP_STATE_DISCONNECTED); }
static void avctp_set_state(struct avctp *session, avctp_state_t new_state) { GSList *l; struct audio_device *dev; avctp_state_t old_state = session->state; dev = manager_get_audio_device(session->device, FALSE); if (dev == NULL) { error("%s(): No matching audio device", __func__); return; } session->state = new_state; for (l = callbacks; l != NULL; l = l->next) { struct avctp_state_callback *cb = l->data; cb->cb(dev, old_state, new_state, cb->user_data); } switch (new_state) { case AVCTP_STATE_DISCONNECTED: DBG("AVCTP Disconnected"); avctp_disconnected(session); break; case AVCTP_STATE_CONNECTING: DBG("AVCTP Connecting"); break; case AVCTP_STATE_CONNECTED: DBG("AVCTP Connected"); break; case AVCTP_STATE_BROWSING_CONNECTING: DBG("AVCTP Browsing Connecting"); break; case AVCTP_STATE_BROWSING_CONNECTED: DBG("AVCTP Browsing Connected"); break; default: error("Invalid AVCTP state %d", new_state); return; } }
static void init_uinput(struct avctp *session) { struct audio_device *dev; char address[18], name[248 + 1]; dev = manager_get_audio_device(session->device, FALSE); device_get_name(dev->btd_dev, name, sizeof(name)); if (g_str_equal(name, "Nokia CK-20W")) { session->key_quirks[AVC_FORWARD] |= QUIRK_NO_RELEASE; session->key_quirks[AVC_BACKWARD] |= QUIRK_NO_RELEASE; session->key_quirks[AVC_PLAY] |= QUIRK_NO_RELEASE; session->key_quirks[AVC_PAUSE] |= QUIRK_NO_RELEASE; } ba2str(device_get_address(session->device), address); session->uinput = uinput_create(address); if (session->uinput < 0) error("AVRCP: failed to init uinput for %s", address); else DBG("AVRCP: uinput initialized for %s", address); }
static struct audio_device *a2dp_get_dev(struct avdtp *session) { return manager_get_audio_device(avdtp_get_device(session), FALSE); }