static bt_status_t get_adapter_property(const struct pdu* cmd) { uint8_t type; struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->get_adapter_property); if (read_pdu_at(cmd, 0, "C", &type) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->get_adapter_property(type); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_get_adapter_property; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_get_adapter_property: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_set_volume(const struct pdu* cmd) { uint8_t volume; struct pdu_wbuf* wbuf; bt_status_t status; if (read_pdu_at(cmd, 0, "C", &volume) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; assert(btrc_interface); assert(btrc_interface->set_volume); status = btrc_interface->set_volume(volume); if (status != BT_STATUS_SUCCESS) goto err_btrc_interface_set_volume; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_btrc_interface_set_volume: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t cancel_discovery(const struct pdu* cmd) { struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->cancel_discovery); wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->cancel_discovery(); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_cancel_discovery; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_cancel_discovery: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t set_adapter_property(const struct pdu* cmd) { bt_property_t property; int status; struct pdu_wbuf* wbuf; assert(bt_interface); assert(bt_interface->set_adapter_property); if (read_bt_property_t(cmd, 0, &property) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) { status = BT_STATUS_NOMEM; goto err_create_pdu_wbuf; } status = bt_interface->set_adapter_property(&property); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_set_adapter_property; free(property.val); init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_set_adapter_property: cleanup_pdu_wbuf(wbuf); err_create_pdu_wbuf: free(property.val); return status; }
static bt_status_t register_module(const struct pdu* cmd) { uint8_t service; uint8_t mode; struct pdu_wbuf* wbuf; if (read_pdu_at(cmd, 0, "CC", &service, &mode) < 0) return BT_STATUS_FAIL; wbuf = create_pdu_wbuf(0, sizeof(*wbuf->msg.msg_iov)); if (!wbuf) return BT_STATUS_FAIL; if (core_register_module(service, mode) < 0) goto err_core_register_module; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(build_pdu_wbuf_msg(wbuf)); return BT_STATUS_SUCCESS; err_core_register_module: cleanup_pdu_wbuf(wbuf); return BT_STATUS_FAIL; }
static bt_status_t opcode_listen(const struct pdu* cmd) { uint8_t type; int8_t service_name[256]; uint8_t uuid[16]; uint16_t channel; uint8_t flags; int sock_fd; struct pdu_wbuf* wbuf; bt_status_t status; if (read_pdu_at(cmd, 0, "CmmSC", &type, service_name, (size_t)sizeof(service_name), uuid, (size_t)uuid, &channel, &flags) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, sizeof(*wbuf->msg.msg_iov)); if (!wbuf) return BT_STATUS_NOMEM; status = bt_sock_listen(type, (char*)service_name, uuid, channel, &sock_fd, flags); if (status != BT_STATUS_SUCCESS) goto err_bt_sock_listen; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(build_pdu_wbuf_msg_with_fd(wbuf, sock_fd)); return BT_STATUS_SUCCESS; err_bt_sock_listen: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t get_remote_device_property(const struct pdu* cmd) { long off; bt_bdaddr_t remote_addr; uint8_t type; struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->get_remote_device_property); off = read_bt_bdaddr_t(cmd, 0, &remote_addr); if (off < 0) return BT_STATUS_PARM_INVALID; if (read_pdu_at(cmd, off, "C", &type) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->get_remote_device_property(&remote_addr, type); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_get_remote_device_property; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_get_remote_device_property: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_get_play_status_rsp(const struct pdu* cmd) { uint8_t play_status; uint32_t duration, position; struct pdu_wbuf* wbuf; bt_status_t status; assert(btrc_interface); assert(btrc_interface->get_play_status_rsp); if (read_pdu_at(cmd, 0, "CII", &play_status, &duration, &position) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = btrc_interface->get_play_status_rsp(play_status, duration, position); if (status != BT_STATUS_SUCCESS) goto err_btrc_interface_get_play_status_rsp; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_btrc_interface_get_play_status_rsp: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_list_player_app_value_rsp(const struct pdu* cmd) { long off; uint8_t num_attr; uint8_t p_vals[256]; struct pdu_wbuf* wbuf; bt_status_t status; assert(btrc_interface); assert(btrc_interface->list_player_app_value_rsp); off = read_pdu_at(cmd, 0, "C", &num_attr); if (off < 0) return BT_STATUS_PARM_INVALID; if (read_pdu_at(cmd, off, "m", p_vals, num_attr) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = btrc_interface->list_player_app_value_rsp(num_attr, p_vals); if (status != BT_STATUS_SUCCESS) goto err_btrc_interface_list_player_app_value_rsp; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_btrc_interface_list_player_app_value_rsp: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t cancel_bond(const struct pdu* cmd) { bt_bdaddr_t bd_addr; struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->cancel_bond); if (read_bt_bdaddr_t(cmd, 0, &bd_addr) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->cancel_bond(&bd_addr); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_cancel_bond; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_cancel_bond: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t get_adapter_properties(const struct pdu* cmd) { struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->get_adapter_properties); wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->get_adapter_properties(); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_get_adapter_properties; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_get_adapter_properties: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_get_player_app_value_rsp(const struct pdu* cmd) { btrc_player_settings_t p_vals; struct pdu_wbuf* wbuf; bt_status_t status; assert(btrc_interface); assert(btrc_interface->get_player_app_value_rsp); if (read_btrc_player_settings_t(cmd, 0, &p_vals) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = btrc_interface->get_player_app_value_rsp(&p_vals); if (status != BT_STATUS_SUCCESS) goto err_btrc_interface_get_player_app_value_rsp; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_btrc_interface_get_player_app_value_rsp: cleanup_pdu_wbuf(wbuf); return status; }
static void ssp_request_cb(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(6 + /* remote address */ 249 + /* remote name */ 4 + /* class of device */ 1 + /* paring variant */ 4, /* passkey */ 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_CORE, OPCODE_SSP_REQUEST_NTF); if (append_bt_bdaddr_t(&wbuf->buf.pdu, remote_bd_addr) < 0) goto cleanup; if (append_bt_bdname_t(&wbuf->buf.pdu, bd_name) < 0) goto cleanup; if (append_to_pdu(&wbuf->buf.pdu, "ICI", cod, (uint8_t)pairing_variant, pass_key) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static void acl_state_changed_cb(bt_status_t status, bt_bdaddr_t* remote_bd_addr, bt_acl_state_t state) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(1 + /* status */ 6 + /* remote address */ 1, /* ACL state */ 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_CORE, OPCODE_ACL_STATE_CHANGED_NTF); if (append_to_pdu(&wbuf->buf.pdu, "C", (uint8_t)status) < 0) goto cleanup; if (append_bt_bdaddr_t(&wbuf->buf.pdu, remote_bd_addr) < 0) goto cleanup; if (append_to_pdu(&wbuf->buf.pdu, "C", (uint8_t)state) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static void device_found_cb(int num_properties, bt_property_t* properties) { bt_property_t* aligned_properties; struct pdu_wbuf* wbuf; properties = align_properties(properties, num_properties, &aligned_properties); if (!properties) return; wbuf = create_pdu_wbuf(1 + /* number of properties */ properties_length(num_properties, properties), 0, NULL); if (!wbuf) goto cleanup_properties; init_pdu(&wbuf->buf.pdu, SERVICE_BT_CORE, OPCODE_DEVICE_FOUND_NTF); if (append_bt_property_t_array(&wbuf->buf.pdu, properties, num_properties) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; free(aligned_properties); return; cleanup: cleanup_pdu_wbuf(wbuf); cleanup_properties: free(aligned_properties); }
static void pin_request_cb(bt_bdaddr_t* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(6 + /* remote address */ 249 + /* remote name */ 4, /* class of device */ 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_CORE, OPCODE_PIN_REQUEST_NTF); if (append_bt_bdaddr_t(&wbuf->buf.pdu, remote_bd_addr) < 0) goto cleanup; if (append_bt_bdname_t(&wbuf->buf.pdu, bd_name) < 0) goto cleanup; if (append_to_pdu(&wbuf->buf.pdu, "I", cod) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static bt_status_t le_test_mode(const struct pdu* cmd) { long off; uint16_t opcode; uint8_t len; uint8_t buf[256]; struct pdu_wbuf* wbuf; int status; off = read_pdu_at(cmd, 0, "SC", &opcode, &len); if (off < 0) return BT_STATUS_PARM_INVALID; if (read_pdu_at(cmd, off, "m", buf, len) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->le_test_mode(opcode, buf, len); if (status != BT_STATUS_SUCCESS) goto err_bt_core_le_test_mode; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_core_le_test_mode: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t dut_mode_configure(const struct pdu* cmd) { uint8_t enable; struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->dut_mode_configure); if (read_pdu_at(cmd, 0, "C", &enable) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->dut_mode_configure(enable); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_dut_mode_configure; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_dut_mode_configure: cleanup_pdu_wbuf(wbuf); return status; }
static void set_player_app_value_cb(btrc_player_settings_t* p_vals) { struct pdu_wbuf* wbuf; assert(p_vals); wbuf = create_pdu_wbuf(1 + /* number of attribute-value pairs */ p_vals->num_attr + /* one byte per attribute */ p_vals->num_attr, /* one byte per value */ 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_RC, OPCODE_SET_PLAYER_APP_VALUE_NTF); if (append_btrc_player_settings_t(&wbuf->buf.pdu, p_vals) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static bt_status_t get_remote_device_properties(const struct pdu* cmd) { bt_bdaddr_t remote_addr; struct pdu_wbuf* wbuf; int status; assert(bt_interface); assert(bt_interface->get_remote_device_properties); if (read_bt_bdaddr_t(cmd, 0, &remote_addr) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; status = bt_interface->get_remote_device_properties(&remote_addr); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_get_remote_device_properties; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_get_remote_device_properties: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_get_element_attr_rsp(const struct pdu* cmd) { long off; uint8_t num_attr; btrc_element_attr_val_t* p_attrs; struct pdu_wbuf* wbuf; bt_status_t status; assert(btrc_interface); assert(btrc_interface->get_element_attr_rsp); off = read_pdu_at(cmd, 0, "C", &num_attr); if (off < 0) return BT_STATUS_PARM_INVALID; p_attrs = malloc(num_attr * sizeof(*p_attrs)); if (!p_attrs) { ALOGE_ERRNO("malloc"); return BT_STATUS_NOMEM; } off = read_btrc_element_attr_val_t_array(cmd, off, p_attrs, num_attr); if (off < 0) { status = BT_STATUS_PARM_INVALID; goto err_read_btrc_element_attr_val_t_array; } wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) { status = BT_STATUS_NOMEM; goto err_create_pdu_wbuf; } status = btrc_interface->get_element_attr_rsp(num_attr, p_attrs); if (status != BT_STATUS_SUCCESS) goto err_btrc_interface_get_element_attr_rsp; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); free(p_attrs); return BT_STATUS_SUCCESS; err_btrc_interface_get_element_attr_rsp: cleanup_pdu_wbuf(wbuf); err_create_pdu_wbuf: err_read_btrc_element_attr_val_t_array: free(p_attrs); return status; }
static int register_module(const struct pdu* cmd) { uint8_t service; struct pdu_wbuf* wbuf; int (*handler)(const struct pdu*); if (read_pdu_at(cmd, 0, "C", &service) < 0) { return ERROR_PARM_INVALID; } if (g_service_handler[service]) { ALOGE("service 0x%x already registered", service); return ERROR_FAIL; } if (!g_register_service[service]) { ALOGE("invalid service id 0x%x", service); return ERROR_FAIL; } wbuf = create_pdu_wbuf(OPCODE_REGISTER_MODULE_RSP_SIZE, 0, NULL); if (!wbuf) { return ERROR_NOMEM; } handler = g_register_service[service](g_send_pdu); if (!handler) { goto err_register_service; } g_service_handler[service] = handler; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); if (append_to_pdu(&wbuf->buf.pdu, "I", (uint32_t)PROTOCOL_VERSION) < 0) { goto err_append_to_pdu; } send_pdu(wbuf); return ERROR_NONE; err_append_to_pdu: err_register_service: destroy_pdu_wbuf(wbuf); return ERROR_FAIL; }
static void remote_device_properties_cb(bt_status_t status, bt_bdaddr_t* bd_addr, int num_properties, bt_property_t* properties) { bt_property_t* aligned_properties; struct pdu_wbuf* wbuf; properties = align_properties(properties, num_properties, &aligned_properties); if (!properties) return; fix_properties(bd_addr, num_properties, properties); wbuf = create_pdu_wbuf(1 + /* status */ 6 + /* address */ 1 + /* number of properties */ properties_length(num_properties, properties), 0, NULL); if (!wbuf) goto cleanup_properties; init_pdu(&wbuf->buf.pdu, SERVICE_BT_CORE, OPCODE_REMOTE_DEVICE_PROPERTIES_NTF); if (append_to_pdu(&wbuf->buf.pdu, "C", (uint8_t)status) < 0) goto cleanup; if (append_bt_bdaddr_t(&wbuf->buf.pdu, bd_addr) < 0) goto cleanup; if (append_bt_property_t_array(&wbuf->buf.pdu, properties, num_properties) < 0) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; free(aligned_properties); return; cleanup: cleanup_pdu_wbuf(wbuf); cleanup_properties: free(aligned_properties); }
static void get_play_status_cb(void) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_RC, OPCODE_GET_PLAY_STATUS_NTF); if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static void list_player_app_attr_cb(void) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_RC, OPCODE_LIST_PLAYER_APP_ATTR_NTF); if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }
static bt_status_t create_bond(const struct pdu* cmd) { long off; bt_bdaddr_t bd_addr; struct pdu_wbuf* wbuf; int status; #if ANDROID_VERSION >= 21 uint8_t transport; #endif assert(bt_interface); assert(bt_interface->create_bond); off = read_bt_bdaddr_t(cmd, 0, &bd_addr); if (off < 0) return BT_STATUS_PARM_INVALID; #if ANDROID_VERSION >= 21 if (read_pdu_at(cmd, off, "C", &transport) < 0) return BT_STATUS_PARM_INVALID; #endif wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; #if ANDROID_VERSION >= 21 status = bt_interface->create_bond(&bd_addr, transport); #else status = bt_interface->create_bond(&bd_addr); #endif if (status != BT_STATUS_SUCCESS) goto err_bt_interface_create_bond; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_create_bond: cleanup_pdu_wbuf(wbuf); return status; }
static int unregister_module(const struct pdu* cmd) { uint8_t service; struct pdu_wbuf* wbuf; if (read_pdu_at(cmd, 0, "C", &service) < 0) { return ERROR_PARM_INVALID; } wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) { return ERROR_NOMEM; } if (service == SERVICE_REGISTRY) { ALOGE("service REGISTRY cannot be unregistered"); goto err_service_registry; } if (!g_unregister_service[service]) { ALOGE("service 0x%x not registered", service); goto err_not_unregister_service; } if (g_unregister_service[service]() < 0) { goto err_unregister_service; } g_service_handler[service] = NULL; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return ERROR_NONE; err_unregister_service: err_not_unregister_service: err_service_registry: destroy_pdu_wbuf(wbuf); return ERROR_FAIL; }
static bt_status_t get_remote_service_record(const struct pdu* cmd) { long off; bt_bdaddr_t remote_addr; bt_uuid_t uuid; struct pdu_wbuf* wbuf; struct get_remote_service_record_params* params; int status; assert(bt_interface); assert(bt_interface->get_remote_service_record); off = read_bt_bdaddr_t(cmd, 0, &remote_addr); if (off < 0) return BT_STATUS_PARM_INVALID; if (read_bt_uuid_t(cmd, off, &uuid) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, 0, NULL); if (!wbuf) return BT_STATUS_NOMEM; params = store_get_remote_service_record_params(&remote_addr, &uuid); if (!params) { status = BT_STATUS_NOMEM; goto err_store_get_remote_service_record_params; } status = bt_interface->get_remote_service_record(&remote_addr, &uuid); if (status != BT_STATUS_SUCCESS) goto err_bt_interface_get_remote_service_record; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_interface_get_remote_service_record: remove_get_remote_service_record_params(params); err_store_get_remote_service_record_params: cleanup_pdu_wbuf(wbuf); return status; }
static bt_status_t opcode_connect(const struct pdu* cmd) { long off; bt_bdaddr_t bd_addr; uint8_t type; uint8_t uuid[16]; uint16_t channel; uint8_t flags; struct pdu_wbuf* wbuf; struct ancillary_data* data; bt_status_t status; off = read_bt_bdaddr_t(cmd, 0, &bd_addr); if (off < 0) return BT_STATUS_PARM_INVALID; if (read_pdu_at(cmd, off, "CmsC", &type, uuid, sizeof(uuid), &channel, &flags) < 0) return BT_STATUS_PARM_INVALID; wbuf = create_pdu_wbuf(0, ALIGNMENT_PADDING + sizeof(*data), build_ancillary_data); if (!wbuf) return BT_STATUS_NOMEM; data = ceil_align(pdu_wbuf_tail(wbuf), ALIGNMENT_PADDING); status = bt_sock_connect(&bd_addr, type, uuid, channel, &data->sock_fd, flags); if (status != BT_STATUS_SUCCESS) goto err_bt_sock_listen; init_pdu(&wbuf->buf.pdu, cmd->service, cmd->opcode); send_pdu(wbuf); return BT_STATUS_SUCCESS; err_bt_sock_listen: cleanup_pdu_wbuf(wbuf); return status; }
static void list_player_app_values_cb(btrc_player_attr_t attr_id) { struct pdu_wbuf* wbuf; wbuf = create_pdu_wbuf(1, /* player attribute */ 0, NULL); if (!wbuf) return; init_pdu(&wbuf->buf.pdu, SERVICE_BT_RC, OPCODE_LIST_PLAYER_APP_VALUES_NTF); if ((append_to_pdu(&wbuf->buf.pdu, "C", (uint8_t)attr_id) < 0)) goto cleanup; if (run_task(send_ntf_pdu, wbuf) < 0) goto cleanup; return; cleanup: cleanup_pdu_wbuf(wbuf); }