static void hci_le_control(uint16_t ocf, int plen, uint8_t *data) { le_read_buffer_size_rp bs; const uint16_t ogf = OGF_LE_CTL; switch (ocf) { case OCF_LE_READ_BUFFER_SIZE: bs.status = 0; bs.pkt_len = htobs(VHCI_ACL_MTU); bs.max_pkt = htobs(VHCI_ACL_MAX_PKT); command_complete(ogf, ocf, sizeof(bs), &bs); break; default: command_status(ogf, ocf, 0x01); break; } }
static struct mgmt_request *create_request(uint16_t opcode, uint16_t index, uint16_t length, const void *param, mgmt_request_func_t callback, void *user_data, mgmt_destroy_func_t destroy) { struct mgmt_request *request; struct mgmt_hdr *hdr; if (!opcode) return NULL; if (length > 0 && !param) return NULL; request = new0(struct mgmt_request, 1); if (!request) return NULL; request->len = length + MGMT_HDR_SIZE; request->buf = malloc(request->len); if (!request->buf) { free(request); return NULL; } if (length > 0) memcpy(request->buf + MGMT_HDR_SIZE, param, length); hdr = request->buf; hdr->opcode = htobs(opcode); hdr->index = htobs(index); hdr->len = htobs(length); request->opcode = opcode; request->index = index; request->callback = callback; request->destroy = destroy; request->user_data = user_data; return request; }
static void device_devup_setup(int index) { struct hci_dev_info di; uint16_t policy; int dd, err; if (hci_devinfo(index, &di) < 0) return; if (hci_test_bit(HCI_RAW, &di.flags)) return; dd = hci_open_dev(index); if (dd < 0) { err = errno; error("Can't open device hci%d: %s (%d)", index, strerror(err), err); return; } /* Set page timeout */ if ((main_opts.flags & (1 << HCID_SET_PAGETO))) { write_page_timeout_cp cp; cp.timeout = htobs(main_opts.pageto); hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); } /* Set default link policy */ policy = htobs(main_opts.link_policy); hci_send_cmd(dd, OGF_LINK_POLICY, OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy); hci_close_dev(dd); start_security_manager(index); /* Return value 1 means ioctl(DEVDOWN) was performed */ if (manager_start_adapter(index) == 1) stop_security_manager(index); }
static int mgmt_set_name(int index, const char *name) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)]; DBG("index %d, name %s", index, name); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME); hdr->len = htobs(sizeof(*cp)); hdr->index = htobs(index); strncpy((char *) cp->name, name, sizeof(cp->name) - 1); if (write(mgmt_sock, buf, sizeof(buf)) < 0) return -errno; return 0; }
int main(int argc, char** argv) { // Add BLE address here char BLEDestinationAddress[18] = "C5:2A:45:36:E3:A2"; // Allocate a socket (from btio/btio.c: line 1532) int fileDescriptor = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (fileDescriptor < 0) { ExitOnError(__FUNCTION__, "socket", errno, __FILE__, __LINE__); } printf("File Descriptor = %d\n"); // Set connection parameters (from btio/btio.c: l2cap_connect line 346) struct sockaddr_l2 SocketAddr = { 0 }; str2ba(BLEDestinationAddress, &SocketAddr.l2_bdaddr); SocketAddr.l2_bdaddr_type = BDADDR_LE_RANDOM; SocketAddr.l2_family = AF_BLUETOOTH; SocketAddr.l2_cid = htobs(ATT_CID); // Connect to server (from btio/btio.c: line 362) printf("Connecting...\n"); int status = connect(fileDescriptor, (struct sockaddr*)&SocketAddr, sizeof(SocketAddr)); if (status < 0) { close(fileDescriptor); ExitOnError(__FUNCTION__, "connect", errno, __FILE__, __LINE__); } else { printf("Connected\n"); } // Test.. compile pas voir README.md reverse engineering #### char-read-uuid #### //epoll_ctl(epoll_fd, EPOLL_CTL_MOD, data->fd, &ev); // Send a message status = write(fileDescriptor, "hello!", 6); if( status < 0 ) { close(fileDescriptor); ExitOnError(__FUNCTION__, "write", errno, __FILE__, __LINE__); } else { printf("write ok \n"); } close(fileDescriptor); return 0; }
static int mgmt_set_io_capability(int index, uint8_t io_capability) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_io_capability)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_set_io_capability *cp = (void *) &buf[sizeof(*hdr)]; DBG("hci%d io_capability 0x%02x", index, io_capability); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_SET_IO_CAPABILITY); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); cp->io_capability = io_capability; if (write(mgmt_sock, buf, sizeof(buf)) < 0) return -errno; return 0; }
void bthost_le_start_encrypt(struct bthost *bthost, uint16_t handle, const uint8_t ltk[16]) { struct bt_hci_cmd_le_start_encrypt cmd; memset(&cmd, 0, sizeof(cmd)); cmd.handle = htobs(handle); memcpy(cmd.ltk, ltk, 16); send_command(bthost, BT_HCI_CMD_LE_START_ENCRYPT, &cmd, sizeof(cmd)); }
static int ble_scan_enable(int device_desc) { uint16_t interval = htobs(DISCOV_LE_SCAN_INT); uint16_t window = htobs(DISCOV_LE_SCAN_WIN); uint8_t own_address_type = 0x00; uint8_t filter_policy = 0x00; int ret = hci_le_set_scan_parameters(device_desc, LE_SCAN_ACTIVE, interval, window, own_address_type, filter_policy, 10000); if (ret < 0) { fprintf(stderr, "ERROR: Set scan parameters failed (are you root?).\n"); return 1; } ret = hci_le_set_scan_enable(device_desc, 0x01, 1, 10000); if (ret < 0) { fprintf(stderr, "ERROR: Enable scan failed.\n"); return 1; } return 0; }
static void evt_disconn_logic_link_complete(struct bt_amp *amp, uint8_t reason) { struct bt_hci_evt_disconn_logic_link_complete evt; evt.status = BT_HCI_ERR_SUCCESS; evt.handle = htobs(amp->logic_handle); evt.reason = reason; send_event(amp, BT_HCI_EVT_DISCONN_LOGIC_LINK_COMPLETE, &evt, sizeof(evt)); }
static void evt_logic_link_complete(struct bt_amp *amp) { struct bt_hci_evt_logic_link_complete evt; evt.status = BT_HCI_ERR_SUCCESS; evt.handle = htobs(amp->logic_handle); evt.phy_handle = amp->phy_handle; evt.flow_spec = 0x00; send_event(amp, BT_HCI_EVT_LOGIC_LINK_COMPLETE, &evt, sizeof(evt)); }
int8_t hci_resolve_interruption(hci_socket_t *hci_socket, hci_controller_t *hci_controller) { CHECK_HCI_CONTROLLER_PTR(hci_controller, "hci_resolve_interruption"); if (!hci_controller->interrupted) { print_trace(TRACE_WARNING, "hci_resolve_interruption : nothing to resolve.\n"); return 0; } char new_socket = 0; char socket_err = 0; check_hci_socket_ptr(&hci_socket, hci_controller, &new_socket, &socket_err); if (socket_err) { return -1; } pthread_mutex_lock(&hci_controller_mutex); switch (hci_controller->state) { case HCI_STATE_SCANNING : print_trace(TRACE_INFO, "The controller was previsouly blocking on the scanning state\n"); if (hci_le_set_scan_enable(hci_socket->sock, htobs(0x00), htobs(0x00), 0) < 0) { perror("set_scan_disable"); } else { hci_controller->interrupted = 0; hci_change_state(hci_controller, HCI_STATE_OPEN); } break; default: print_trace(TRACE_ERROR, "hci_resolve_interruption : unrecognized state.\n"); break; } pthread_mutex_unlock(&hci_controller_mutex); if (!hci_controller->interrupted) { print_trace(TRACE_INFO, "hci_resolve_interruption : interruption resolved.\n"); return 0; } else { print_trace(TRACE_INFO, "hci_resolve_interruption : unable to resolve the interruption.\n"); return -1; } }
static int mgmt_set_mode(int sk, uint16_t index, uint16_t opcode, uint8_t val) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_mode *cp = (void *) &buf[sizeof(*hdr)]; memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(opcode); hdr->index = htobs(index); hdr->len = htobs(sizeof(*cp)); cp->val = val; if (write(sk, buf, sizeof(buf)) < 0) { perror("write"); return -1; } return 0; }
static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)]; DBG("index %d major %u minor %u", index, major, minor); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); cp->major = major; cp->minor = minor; if (write(mgmt_sock, buf, sizeof(buf)) < 0) return -errno; return 0; }
/* * Function btobex_prepare_connect (self, service) * * Prepare for Bluetooth RFCOMM connect * */ void btobex_prepare_connect(obex_t *self, bdaddr_t *src, bdaddr_t *dst, uint8_t channel) { #ifndef _WIN32 self->trans.self.rfcomm.rc_family = AF_BLUETOOTH; bacpy(&self->trans.self.rfcomm.rc_bdaddr, src); self->trans.self.rfcomm.rc_channel = 0; self->trans.peer.rfcomm.rc_family = AF_BLUETOOTH; bacpy(&self->trans.peer.rfcomm.rc_bdaddr, dst); self->trans.peer.rfcomm.rc_channel = htobs(channel); #endif /* _WIN32 */ }
int do_lescan() { int dev_id, sock; int ret; if (!strncmp(g_src, "hci", 3)) dev_id = atoi(g_src + 3); else dev_id = hci_get_route(NULL); sock = hci_open_dev(dev_id); if (dev_id < 0 || sock < 0) { perror("opening socket"); exit(1); } uint8_t own_type = 0x00; uint16_t interval = htobs(0x0012); uint16_t window = htobs(0x0012); uint8_t scan_type = 0x01; uint8_t filter_dup = 1; uint8_t filter_type = 0; ret = hci_le_set_scan_parameters(sock, scan_type, interval, window, own_type, 0x00, 1000); if (ret) { perror("hci_le_set_scan_parameters"); exit(1); } ret = hci_le_set_scan_enable(sock, 0x01, filter_dup, 1000); if (ret) { perror("hci_le_set_scan_enable"); exit(1); } print_advertising_devices(sock, filter_type); ret = hci_le_set_scan_enable(sock, 0x00, filter_dup, 1000); close(sock); return 0; }
static int init_server(uint16_t mtu) { struct l2cap_options opts; struct sockaddr_l2 l2addr; socklen_t optlen; int l2cap_sock; /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (l2cap_sock < 0) { printf("opening L2CAP socket: %s", strerror(errno)); return -1; } memset(&l2addr, 0, sizeof(l2addr)); l2addr.l2_family = AF_BLUETOOTH; bacpy(&l2addr.l2_bdaddr, BDADDR_ANY); l2addr.l2_psm = htobs(SDP_PSM); if (bind(l2cap_sock, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) { printf("binding L2CAP socket: %s", strerror(errno)); return -1; } int opt = L2CAP_LM_MASTER; if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { printf("setsockopt: %s", strerror(errno)); return -1; } memset(&opts, 0, sizeof(opts)); optlen = sizeof(opts); if (getsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { printf("getsockopt: %s", strerror(errno)); return -1; } opts.omtu = mtu; opts.imtu = mtu; if (setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { printf("setsockopt: %s", strerror(errno)); return -1; } if (listen(l2cap_sock, 5) < 0) { printf("listen: %s", strerror(errno)); return -1; } return l2cap_sock; }
tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, uint8_t value_len, uint8_t *attr_value) { struct hci_request rq; uint8_t status; uint8_t buffer[HCI_MAX_PACKET_SIZE]; uint8_t indx = 0; if ((value_len+5) > HCI_MAX_PACKET_SIZE) return BLE_STATUS_INVALID_PARAMS; conn_handle = htobs(conn_handle); memcpy(buffer + indx, &conn_handle, 2); indx += 2; attr_handle = htobs(attr_handle); memcpy(buffer + indx, &attr_handle, 2); indx += 2; buffer[indx] = value_len; indx++; memcpy(buffer + indx, attr_value, value_len); indx += value_len; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; rq.cparam = (void *)buffer; rq.clen = indx; rq.event = EVT_CMD_STATUS; rq.rparam = &status; rq.rlen = 1; if (hci_send_req(&rq) < 0) return -1; return status; }
tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, const uint8_t *addr_array) { struct hci_request rq; gap_set_broadcast_mode_cp cp; uint8_t status; uint8_t indx = 0; uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; if (variable_size > sizeof(cp.var_len_data) ) return BLE_STATUS_INVALID_PARAMS; cp.adv_interv_min = htobs(adv_interv_min); cp.adv_interv_max = htobs(adv_interv_max); cp.adv_type = adv_type; cp.own_addr_type = own_addr_type; cp.var_len_data[indx] = adv_data_length; indx++; Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); indx += adv_data_length; cp.var_len_data[indx] = num_whitelist_entries; indx ++; Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); Osal_MemSet(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = OCF_GAP_SET_BROADCAST_MODE; rq.cparam = &cp; rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; rq.rparam = &status; rq.rlen = 1; if (hci_send_req(&rq, FALSE) < 0) return BLE_STATUS_TIMEOUT; return status; }
tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, uint8_t value_len, uint8_t *attr_value) { struct hci_request rq; uint8_t status; uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; uint8_t indx = 0; if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) return BLE_STATUS_INVALID_PARAMS; conn_handle = htobs(conn_handle); Osal_MemCpy(buffer + indx, &conn_handle, 2); indx += 2; attr_handle = htobs(attr_handle); Osal_MemCpy(buffer + indx, &attr_handle, 2); indx += 2; buffer[indx] = value_len; indx++; Osal_MemCpy(buffer + indx, attr_value, value_len); indx += value_len; Osal_MemSet(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; rq.cparam = (void *)buffer; rq.clen = indx; rq.event = EVT_CMD_STATUS; rq.rparam = &status; rq.rlen = 1; if (hci_send_req(&rq, FALSE) < 0) return BLE_STATUS_TIMEOUT; return status; }
tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) { struct hci_request rq; uint8_t status; gatt_del_inc_serv_cp cp; cp.service_handle = htobs(servHandle); cp.inc_serv_handle = htobs(includeServHandle); Osal_MemSet(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = OCF_GATT_DEL_INC_SERV; rq.cparam = &cp; rq.clen = GATT_DEL_INC_SERV_CP_SIZE; rq.rparam = &status; rq.rlen = 1; if (hci_send_req(&rq, FALSE) < 0) return BLE_STATUS_TIMEOUT; return status; }
static int mgmt_disconnect(int index, bdaddr_t *bdaddr) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_disconnect)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_disconnect *cp = (void *) &buf[sizeof(*hdr)]; char addr[18]; ba2str(bdaddr, addr); DBG("index %d %s", index, addr); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_DISCONNECT); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); bacpy(&cp->bdaddr, bdaddr); if (write(mgmt_sock, buf, sizeof(buf)) < 0) error("write: %s (%d)", strerror(errno), errno); return 0; }
int get_rssi(bdaddr_t *bdaddr, struct hci_state current_hci_state) { struct hci_dev_info di; if (hci_devinfo(current_hci_state.device_id, &di) < 0) { perror("Can't get device info"); return(-1); } uint16_t handle; // int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to); // HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5 if (hci_create_connection(current_hci_state.device_handle, bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); // TODO close(dd); return(-1); } sleep(1); struct hci_conn_info_req *cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); bacpy(&cr->bdaddr, bdaddr); cr->type = ACL_LINK; if(ioctl(current_hci_state.device_handle, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); return(-1); } int8_t rssi; if(hci_read_rssi(current_hci_state.device_handle, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("Read RSSI failed"); return(-1); } printf("RSSI return value: %d\n", rssi); free(cr); usleep(10000); hci_disconnect(current_hci_state.device_handle, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); }
void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) { hci_command_hdr hc; hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); hc.plen= plen; uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; header[0] = HCI_COMMAND_PKT; Osal_MemCpy(header+1, &hc, sizeof(hc)); hci_write(header, param, sizeof(header), plen); }
static void read_version_complete(int sk, void *buf, size_t len) { struct mgmt_hdr hdr; struct mgmt_rp_read_version *rp = buf; if (len < sizeof(*rp)) { error("Too small read version complete event"); return; } mgmt_revision = btohs(bt_get_unaligned(&rp->revision)); mgmt_version = rp->version; DBG("version %u revision %u", mgmt_version, mgmt_revision); memset(&hdr, 0, sizeof(hdr)); hdr.opcode = htobs(MGMT_OP_READ_INDEX_LIST); hdr.index = htobs(MGMT_INDEX_NONE); if (write(sk, &hdr, sizeof(hdr)) < 0) error("Unable to read controller index list: %s (%d)", strerror(errno), errno); }
static int mgmt_remove_uuid(int index, uuid_t *uuid) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_uuid)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_remove_uuid *cp = (void *) &buf[sizeof(*hdr)]; uuid_t uuid128; DBG("index %d", index); uuid_to_uuid128(&uuid128, uuid); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_REMOVE_UUID); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); memcpy(cp->uuid, uuid128.value.uuid128.data, 16); if (write(mgmt_sock, buf, sizeof(buf)) < 0) return -errno; return 0; }
static int mgmt_remove_bonding(int index, bdaddr_t *bdaddr) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_key)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_remove_key *cp = (void *) &buf[sizeof(*hdr)]; char addr[18]; ba2str(bdaddr, addr); DBG("index %d addr %s", index, addr); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_REMOVE_KEY); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); bacpy(&cp->bdaddr, bdaddr); cp->disconnect = 1; if (write(mgmt_sock, buf, sizeof(buf)) < 0) return -errno; return 0; }
static int mgmt_create_bonding(int index, bdaddr_t *bdaddr, uint8_t io_cap) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pair_device)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_pair_device *cp = (void *) &buf[sizeof(*hdr)]; char addr[18]; ba2str(bdaddr, addr); DBG("hci%d bdaddr %s io_cap 0x%02x", index, addr, io_cap); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_PAIR_DEVICE); hdr->len = htobs(sizeof(*cp)); hdr->index = htobs(index); bacpy(&cp->bdaddr, bdaddr); cp->io_cap = io_cap; if (write(mgmt_sock, &buf, sizeof(buf)) < 0) return -errno; return 0; }
static int mgmt_set_local_name(int sk, uint16_t index) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)]; memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME); hdr->index = htobs(index); hdr->len = htobs(sizeof(*cp)); char name[] = "Wireless Controller"; memcpy(cp->name, name, sizeof(name)); if (write(sk, buf, sizeof(buf)) < 0) { perror("write"); return -1; } return 0; }
static int mgmt_remove_remote_oob_data(int index, bdaddr_t *bdaddr) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_remote_oob_data)]; struct mgmt_hdr *hdr = (void *) buf; struct mgmt_cp_remove_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)]; char addr[18]; ba2str(bdaddr, addr); DBG("hci%d bdaddr %s", index, addr); memset(buf, 0, sizeof(buf)); hdr->opcode = htobs(MGMT_OP_REMOVE_REMOTE_OOB_DATA); hdr->index = htobs(index); hdr->len = htobs(sizeof(*cp)); bacpy(&cp->bdaddr, bdaddr); if (write(mgmt_sock, &buf, sizeof(buf)) < 0) return -errno; return 0; }
tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) { struct hci_request rq; uint8_t status; gatt_read_charac_val_cp cp; cp.conn_handle = htobs(conn_handle); cp.attr_handle = htobs(attr_handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = OCF_GATT_READ_CHARAC_VAL; rq.cparam = &cp; rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; rq.event = EVT_CMD_STATUS; rq.rparam = &status; rq.rlen = 1; if (hci_send_req(&rq) < 0) return -1; return status; }