static void bt_health_unregister_app(const void *buf, uint16_t len) { const struct hal_cmd_health_unreg_app *cmd = buf; struct health_app *app; DBG(""); app = queue_remove_if(apps, match_app_by_id, INT_TO_PTR(cmd->app_id)); if (!app) { ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_INVALID); return; } send_app_reg_notify(app, HAL_HEALTH_APP_DEREG_SUCCESS); if (record_id > 0) { bt_adapter_remove_record(record_id); record_id = 0; } free_health_app(app); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_SUCCESS); }
static void bt_stream_suspend(const void *buf, uint16_t len) { const struct audio_cmd_suspend_stream *cmd = buf; struct a2dp_setup *setup; int err; DBG(""); setup = find_setup(cmd->id); if (!setup) { error("Unable to find stream for endpoint %u", cmd->id); goto failed; } err = avdtp_suspend(setup->dev->session, setup->stream); if (err < 0) { error("avdtp_suspend: %s", strerror(-err)); goto failed; } ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_SUCCESS); return; failed: ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM, AUDIO_STATUS_FAILED); }
static void handle_set_volume(const void *buf, uint16_t len) { struct hal_cmd_avrcp_set_volume *cmd = (void *) buf; struct avrcp_device *dev; uint8_t status; int ret; DBG(""); if (!devices) { error("AVRCP: No device found to set volume"); status = HAL_STATUS_FAILED; goto done; } /* Peek the first device since the HAL cannot really address a specific * device it might mean there could only be one connected. */ dev = devices->data; ret = avrcp_set_volume(dev->session, cmd->value & 0x7f, set_volume_rsp, dev); if (ret < 0) { status = HAL_STATUS_FAILED; goto done; } status = HAL_STATUS_SUCCESS; done: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME, status); }
static void bt_pan_disconnect(const void *buf, uint16_t len) { const struct hal_cmd_pan_disconnect *cmd = buf; struct pan_device *dev; uint8_t status; GSList *l; bdaddr_t dst; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) { status = HAL_STATUS_FAILED; goto failed; } dev = l->data; if (dev->conn_state == HAL_PAN_STATE_CONNECTED && dev->session) bnep_disconnect(dev->session); bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, status); }
static void bt_a2dp_disconnect(const void *buf, uint16_t len) { const struct hal_cmd_a2dp_connect *cmd = buf; uint8_t status; struct a2dp_device *dev; GSList *l; bdaddr_t dst; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) { status = HAL_STATUS_FAILED; goto failed; } dev = l->data; status = HAL_STATUS_SUCCESS; if (dev->io) { bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); goto failed; } /* Wait AVDTP session to shutdown */ avdtp_shutdown(dev->session); bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING); failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, status); }
static void handle_get_play_status(const void *buf, uint16_t len) { const struct hal_cmd_avrcp_get_play_status *cmd = buf; uint8_t status; struct avrcp_request *req; int ret; DBG(""); req = pop_request(AVRCP_GET_PLAY_STATUS, 0, false); if (!req) { status = HAL_STATUS_FAILED; goto done; } ret = avrcp_get_play_status_rsp(req->dev->session, req->transaction, cmd->position, cmd->duration, cmd->status); if (ret < 0) { status = HAL_STATUS_FAILED; g_free(req); goto done; } status = HAL_STATUS_SUCCESS; g_free(req); done: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS, status); }
static void handle_list_player_values(const void *buf, uint16_t len) { DBG(""); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES, HAL_STATUS_FAILED); }
static void bt_hid_disconnect(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_disconnect *cmd = buf; struct hid_device *dev; uint8_t status; GSList *l; bdaddr_t dst; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) { status = HAL_STATUS_FAILED; goto failed; } dev = l->data; /* Wait either channels to HUP */ if (dev->intr_io) g_io_channel_shutdown(dev->intr_io, TRUE, NULL); if (dev->ctrl_io) g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT, status); }
static void handle_get_player_values_text(const void *buf, uint16_t len) { DBG(""); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, HAL_STATUS_FAILED); }
static void handle_set_player_attrs_value(const void *buf, uint16_t len) { DBG(""); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE, HAL_STATUS_FAILED); }
static void bt_health_destroy_channel(const void *buf, uint16_t len) { DBG("Not implemented"); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_UNSUPPORTED); }
static void bt_health_unregister_app(const void *buf, uint16_t len) { DBG("Not implemented"); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_UNSUPPORTED); }
static void service_unregister(const void *buf, uint16_t len) { const struct hal_cmd_unregister_module *m = buf; uint8_t status; if (m->service_id > HAL_SERVICE_ID_MAX || !services[m->service_id]) { status = HAL_STATUS_FAILED; goto failed; } switch (m->service_id) { case HAL_SERVICE_ID_BLUETOOTH: bt_bluetooth_unregister(); break; case HAL_SERVICE_ID_SOCKET: bt_socket_unregister(); break; case HAL_SERVICE_ID_HIDHOST: bt_hid_unregister(); break; case HAL_SERVICE_ID_A2DP: bt_a2dp_unregister(); break; case HAL_SERVICE_ID_PAN: bt_pan_unregister(); break; case HAL_SERVICE_ID_AVRCP: bt_avrcp_unregister(); break; case HAL_SERVICE_ID_HANDSFREE: bt_handsfree_unregister(); break; case HAL_SERVICE_ID_GATT: bt_gatt_unregister(); break; case HAL_SERVICE_ID_HEALTH: bt_health_unregister(); break; default: /* * This would indicate bug in HAL, as unregister should not be * called in init failed */ DBG("service %u not supported", m->service_id); status = HAL_STATUS_FAILED; goto failed; } services[m->service_id] = false; status = HAL_STATUS_SUCCESS; info("Service ID=%u unregistered", m->service_id); failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, status); }
static void bt_a2dp_sink_disconnect(const void *buf, uint16_t len) { /* TODO */ DBG(""); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_DISCONNECT, HAL_STATUS_UNSUPPORTED); }
static void bt_health_register_app(const void *buf, uint16_t len) { const struct hal_cmd_health_reg_app *cmd = buf; struct hal_rsp_health_reg_app rsp; struct health_app *app; uint16_t off; uint16_t app_name_len, provider_len, srv_name_len, srv_descr_len; char *app_name, *provider = NULL, *srv_name = NULL, *srv_descr = NULL; DBG(""); if (len != sizeof(*cmd) + cmd->len || cmd->app_name_off > cmd->provider_name_off || cmd->provider_name_off > cmd->service_name_off || cmd->service_name_off > cmd->service_descr_off || cmd->service_descr_off > cmd->len) { error("health: Invalid register app command, terminating"); raise(SIGTERM); return; } app_name = (char *) cmd->data; app_name_len = cmd->provider_name_off - cmd->app_name_off; off = app_name_len; provider_len = cmd->service_name_off - off; if (provider_len > 0) provider = (char *) cmd->data + off; off += provider_len; srv_name_len = cmd->service_descr_off - off; if (srv_name_len > 0) srv_name = (char *) cmd->data + off; off += srv_name_len; srv_descr_len = cmd->len - off; if (srv_descr_len > 0) srv_descr = (char *) cmd->data + off; app = create_health_app(app_name, provider, srv_name, srv_descr, cmd->num_of_mdep); if (!app) goto fail; if (!queue_push_tail(apps, app)) goto fail; rsp.app_id = app->id; ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_REG_APP, sizeof(rsp), &rsp, -1); return; fail: free_health_app(app); ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, HAL_STATUS_FAILED); }
static void service_register(const void *buf, uint16_t len) { const struct hal_cmd_register_module *m = buf; uint8_t status; if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id]) { status = HAL_STATUS_FAILED; goto failed; } switch (m->service_id) { case HAL_SERVICE_ID_BLUETOOTH: bt_bluetooth_register(); break; case HAL_SERVICE_ID_SOCK: bt_socket_register(&adapter_bdaddr); break; case HAL_SERVICE_ID_HIDHOST: if (!bt_hid_register(&adapter_bdaddr)) { status = HAL_STATUS_FAILED; goto failed; } break; case HAL_SERVICE_ID_A2DP: if (!bt_a2dp_register(&adapter_bdaddr)) { status = HAL_STATUS_FAILED; goto failed; } break; case HAL_SERVICE_ID_PAN: if (!bt_pan_register(&adapter_bdaddr)) { status = HAL_STATUS_FAILED; goto failed; } break; default: DBG("service %u not supported", m->service_id); status = HAL_STATUS_FAILED; goto failed; } services[m->service_id] = true; status = HAL_STATUS_SUCCESS; info("Service ID=%u registered", m->service_id); failed: ipc_send_rsp(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, status); }
static void bt_stream_open(const void *buf, uint16_t len) { const struct audio_cmd_open_stream *cmd = buf; struct audio_rsp_open_stream *rsp; struct a2dp_setup *setup; int fd; uint16_t omtu; DBG(""); if (cmd->id) setup = find_setup(cmd->id); else setup = setups ? setups->data : NULL; if (!setup) { error("Unable to find stream for endpoint %u", cmd->id); ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED); return; } if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu, NULL)) { error("avdtp_stream_get_transport: failed"); ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, AUDIO_STATUS_FAILED); return; } len = sizeof(struct audio_rsp_open_stream) + sizeof(struct audio_preset) + setup->preset->len; rsp = g_malloc0(len); rsp->id = setup->endpoint->id; rsp->mtu = omtu; rsp->preset->len = setup->preset->len; memcpy(rsp->preset->data, setup->preset->data, setup->preset->len); ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, len, rsp, fd); g_free(rsp); }
static void bt_hid_info(const void *buf, uint16_t len) { /* Data from hal_cmd_hidhost_set_info is usefull only when we create * UHID device. Once device is created all the transactions will be * done through the fd. There is no way to use this information * once device is created with HID internals. */ DBG("Not supported"); ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO, HAL_STATUS_UNSUPPORTED); }
static void bt_hid_connect(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_connect *cmd = buf; struct hid_device *dev; uint8_t status; char addr[18]; bdaddr_t dst; GSList *l; uuid_t uuid; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (l) { status = HAL_STATUS_FAILED; goto failed; } dev = hid_device_new(&dst); ba2str(&dev->dst, addr); DBG("connecting to %s", addr); if (bt_is_device_le(&dst)) { if (!hog_connect(dev)) { status = HAL_STATUS_FAILED; hid_device_remove(dev); goto failed; } goto done; } sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_did_search_cb, dev, NULL, 0) < 0) { error("hidhost: Failed to search DeviceID SDP details"); hid_device_remove(dev); status = HAL_STATUS_FAILED; goto failed; } done: if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED) bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status); }
static void bt_hid_virtual_unplug(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_virtual_unplug *cmd = buf; struct hid_device *dev; GSList *l; uint8_t status; bdaddr_t dst; uint8_t hdr; int fd; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) { status = HAL_STATUS_FAILED; goto failed; } dev = l->data; if (!(dev->ctrl_io)) { status = HAL_STATUS_FAILED; goto failed; } hdr = HID_MSG_CONTROL | HID_VIRTUAL_CABLE_UNPLUG; fd = g_io_channel_unix_get_fd(dev->ctrl_io); if (write(fd, &hdr, sizeof(hdr)) < 0) { error("hidhost: Error writing virtual unplug command: %s (%d)", strerror(errno), errno); status = HAL_STATUS_FAILED; goto failed; } /* Wait either channels to HUP */ if (dev->intr_io) g_io_channel_shutdown(dev->intr_io, TRUE, NULL); if (dev->ctrl_io) g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_VIRTUAL_UNPLUG, status); }
static void bt_audio_close(const void *buf, uint16_t len) { const struct audio_cmd_close *cmd = buf; struct a2dp_endpoint *endpoint; DBG(""); endpoint = find_endpoint(cmd->id); if (!endpoint) { error("Unable to find endpoint %u", cmd->id); ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE, AUDIO_STATUS_FAILED); return; } endpoints = g_slist_remove(endpoints, endpoint); unregister_endpoint(endpoint); ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE, AUDIO_STATUS_SUCCESS); }
static void bt_hid_set_protocol(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_set_protocol *cmd = buf; struct hid_device *dev; GSList *l; bdaddr_t dst; int fd; uint8_t hdr; uint8_t status; DBG(""); switch (cmd->mode) { case HAL_HIDHOST_REPORT_PROTOCOL: case HAL_HIDHOST_BOOT_PROTOCOL: break; default: status = HAL_STATUS_INVALID; goto failed; } android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (!l) { status = HAL_STATUS_FAILED; goto failed; } dev = l->data; hdr = HID_MSG_SET_PROTOCOL | cmd->mode; fd = g_io_channel_unix_get_fd(dev->ctrl_io); if (write(fd, &hdr, sizeof(hdr)) < 0) { error("hidhost: error writing device_set_protocol: %s (%d)", strerror(errno), errno); status = HAL_STATUS_FAILED; goto failed; } dev->last_hid_msg = HID_MSG_SET_PROTOCOL; status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_PROTOCOL, status); }
void gpe1_nop(ipc_msg_t* cmd, void* arg) { int rc; ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)cmd; nop_t *args = (nop_t*)async_cmd->cmd_data; // send back a response, IPC success even if ffdc/rc are non zeros rc = ipc_send_rsp(cmd, IPC_RC_SUCCESS); if(rc) { PK_TRACE("gpe1_nop: Failed to send response back. Halting GPE1", rc); gpe_set_ffdc(&(args->error), 0x00, GPE_RC_IPC_SEND_FAILED, rc); pk_halt(); } }
static void bt_pan_enable(const void *buf, uint16_t len) { const struct hal_cmd_pan_enable *cmd = buf; uint8_t status, state; int err; DBG(""); if (local_role == cmd->local_role) { status = HAL_STATUS_SUCCESS; goto reply; } /* destroy existing server */ destroy_nap_device(); switch (cmd->local_role) { case HAL_PAN_ROLE_NAP: break; case HAL_PAN_ROLE_NONE: local_role = HAL_PAN_ROLE_NONE; status = HAL_STATUS_SUCCESS; state = HAL_PAN_CTRL_DISABLED; goto notify; default: status = HAL_STATUS_UNSUPPORTED; goto reply; } local_role = cmd->local_role; err = register_nap_server(); if (err < 0) { status = HAL_STATUS_FAILED; destroy_nap_device(); goto reply; } status = HAL_STATUS_SUCCESS; state = HAL_PAN_CTRL_ENABLED; notify: bt_pan_notify_ctrl_state(NULL, state, status); reply: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status); }
static void service_unregister(const void *buf, uint16_t len) { const struct hal_cmd_unregister_module *m = buf; uint8_t status; if (!unregister_service(m->service_id)) { status = HAL_STATUS_FAILED; goto failed; } status = HAL_STATUS_SUCCESS; info("Service ID=%u unregistered", m->service_id); failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, status); }
static void bt_hid_connect(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_connect *cmd = buf; struct hid_device *dev; uint8_t status; char addr[18]; bdaddr_t dst; GSList *l; uuid_t uuid; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (l) { status = HAL_STATUS_FAILED; goto failed; } dev = g_new0(struct hid_device, 1); bacpy(&dev->dst, &dst); dev->uhid_fd = -1; ba2str(&dev->dst, addr); DBG("connecting to %s", addr); bt_string2uuid(&uuid, HID_UUID); if (bt_search_service(&adapter_addr, &dev->dst, &uuid, hid_sdp_search_cb, dev, NULL, 0) < 0) { error("Failed to search sdp details"); hid_device_free(dev); status = HAL_STATUS_FAILED; goto failed; } devices = g_slist_append(devices, dev); bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, status); }
static void bt_hid_info(const void *buf, uint16_t len) { const struct hal_cmd_hidhost_set_info *cmd = buf; if (len != sizeof(*cmd) + cmd->descr_len) { error("Invalid hid set info size (%u bytes), terminating", len); raise(SIGTERM); return; } /* Data from hal_cmd_hidhost_set_info is usefull only when we create * UHID device. Once device is created all the transactions will be * done through the fd. There is no way to use this information * once device is created with HID internals. */ DBG("Not supported"); ipc_send_rsp(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO, HAL_STATUS_UNSUPPORTED); }
static void bt_audio_open(const void *buf, uint16_t len) { const struct audio_cmd_open *cmd = buf; struct audio_rsp_open rsp; GSList *presets; DBG(""); audio_retrying = false; if (cmd->presets == 0) { error("No audio presets found"); goto failed; } presets = parse_presets(cmd->preset, cmd->presets, len - sizeof(*cmd)); if (!presets) { error("No audio presets found"); goto failed; } rsp.id = register_endpoint(cmd->uuid, cmd->codec, presets); if (rsp.id == 0) { g_slist_free_full(presets, preset_free); error("Unable to register endpoint"); goto failed; } g_slist_free(presets); ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN, sizeof(rsp), &rsp, -1); return; failed: ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN, AUDIO_STATUS_FAILED); }
static void handle_get_element_attrs_text(const void *buf, uint16_t len) { struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf; uint8_t status; struct avrcp_request *req; uint8_t pdu[IPC_MTU]; uint8_t *ptr; size_t pdu_len; int ret; DBG(""); req = pop_request(AVRCP_GET_ELEMENT_ATTRIBUTES, 0, false); if (!req) { status = HAL_STATUS_FAILED; goto done; } ptr = (uint8_t *) &cmd->values[0]; pdu_len = 0; write_element_attrs(ptr, cmd->number, pdu, &pdu_len); ret = avrcp_get_element_attrs_rsp(req->dev->session, req->transaction, pdu, pdu_len); if (ret < 0) { status = HAL_STATUS_FAILED; g_free(req); goto done; } status = HAL_STATUS_SUCCESS; g_free(req); done: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, status); }
static void bt_a2dp_connect(const void *buf, uint16_t len) { const struct hal_cmd_a2dp_connect *cmd = buf; struct a2dp_device *dev; uint8_t status; char addr[18]; bdaddr_t dst; GSList *l; DBG(""); android2bdaddr(&cmd->bdaddr, &dst); l = g_slist_find_custom(devices, &dst, device_cmp); if (l) { status = HAL_STATUS_FAILED; goto failed; } dev = a2dp_device_new(&dst); if (!a2dp_device_connect(dev, signaling_connect_cb)) { a2dp_device_remove(dev); status = HAL_STATUS_FAILED; goto failed; } ba2str(&dev->dst, addr); DBG("connecting to %s", addr); bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTING); status = HAL_STATUS_SUCCESS; failed: ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status); }