static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { unsigned char key[16]; char sa[18], da[18]; int err; ba2str(sba, sa); ba2str(dba, da); syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)", sa, da); err = read_link_key(sba, dba, key); if (err < 0) { struct link_key *linkkey = get_link_key(sba, dba); if (linkkey) { memcpy(key, linkkey->key, 16); linkkey->time = time(0); err = 0; } } if (err < 0) { /* Link key not found */ hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); } else { /* Link key found */ link_key_reply_cp lr; memcpy(lr.link_key, key, 16); bacpy(&lr.bdaddr, dba); hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, LINK_KEY_REPLY_CP_SIZE, &lr); } }
static void gap_run(){ if (!hci_can_send_command_packet_now()) return; if (todos & SET_ADVERTISEMENT_DATA){ printf("GAP_RUN: set advertisement data\n"); todos &= ~SET_ADVERTISEMENT_DATA; hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data); return; } if (todos & SET_ADVERTISEMENT_PARAMS){ todos &= ~SET_ADVERTISEMENT_PARAMS; uint8_t adv_type = 0; // default bd_addr_t null_addr; memset(null_addr, 0, 6); uint16_t adv_int_min = 0x0030; uint16_t adv_int_max = 0x0030; hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, 0, 0, &null_addr, 0x07, 0x00); return; } if (todos & ENABLE_ADVERTISEMENTS){ printf("GAP_RUN: enable advertisements\n"); todos &= ~ENABLE_ADVERTISEMENTS; hci_send_cmd(&hci_le_set_advertise_enable, 1); return; } }
static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_auth_complete *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { if (!ev->status) { conn->link_mode |= HCI_LM_AUTH; conn->sec_level = conn->pending_sec_level; } else conn->sec_level = BT_SECURITY_LOW; clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); if (conn->state == BT_CONFIG) { if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); } } else { hci_auth_cfm(conn, ev->status); hci_conn_hold(conn); conn->disc_timeout = HCI_DISCONN_TIMEOUT; hci_conn_put(conn); } if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { if (!ev->status) { struct hci_cp_set_conn_encrypt cp; cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); hci_encrypt_cfm(conn, ev->status, 0x00); } } } hci_dev_unlock(hdev); }
uint8_t test_codec(uint8_t ev, uint16_t lparam, void* rparam) { switch(ev) { case EVENT_WINDOW_CREATED: codec_wakeup(); hci_send_cmd(&hci_vs_set_pcm_loopback_enable, 1); break; case EVENT_WINDOW_PAINT: { tContext *pContext = (tContext*)rparam; GrContextForegroundSet(pContext, ClrBlack); GrRectFill(pContext, &client_clip); GrContextForegroundSet(pContext, ClrWhite); GrContextFontSet(pContext, (tFont*)&g_sFontGothic18); GrStringDraw(pContext, "Speaker is looping back to mic", -1, 0, 50, 0); window_volume(pContext, 30, 125, 8, codec_getvolume()); window_button(pContext, KEY_UP, "+"); window_button(pContext, KEY_DOWN, "-"); break; } case EVENT_KEY_PRESSED: switch(lparam) { case KEY_UP: { codec_changevolume(+1); break; } case KEY_DOWN: { // decrease voice codec_changevolume(-1); break; } } window_invalid(NULL); break; case EVENT_EXIT_PRESSED: hci_send_cmd(&hci_vs_set_pcm_loopback_enable, 1); codec_suspend(); return 0; // return 0 to close the window default: return 0; } return 1; }
void proc_scopcm() { hci_send_cmd(hci_write_sco_pcm_int, sizeof(hci_write_sco_pcm_int)); read_event(uart_fd, buffer); hci_send_cmd(hci_write_pcm_data_format, sizeof(hci_write_pcm_data_format)); read_event(uart_fd, buffer); }
static void passkey_agent_free(struct passkey_agent *agent) { GSList *l; if (!agent) return; for (l = agent->pending_requests; l != NULL; l = l->next) { struct pending_agent_request *req = l->data; hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); send_cancel_request(req); } if (agent->timeout) g_source_remove(agent->timeout); if (!agent->exited) release_agent(agent); g_free(agent->name); g_free(agent->path); g_free(agent->addr); if (agent->conn) dbus_connection_unref(agent->conn); g_slist_free(agent->pending_requests); g_free(agent); }
static int write_inquiry_mode(int dev_id, int sock) { struct hci_filter flt; write_inquiry_mode_cp cp; hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); if (setsockopt(sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("Can't set HCI filter"); return 1; } memset(&cp, 0, sizeof(cp)); cp.mode = 0x01; //cp.mode = 0x00; if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE,WRITE_INQUIRY_MODE_RP_SIZE, &cp) < 0) { perror("Can't set write inquiry mode"); return 1; } return 0; }
static int hfp_ag_run_for_audio_connection(hfp_connection_t * context){ if (context->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED || context->state > HFP_W2_DISCONNECT_SCO) return 0; if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED && context->release_audio_connection){ context->state = HFP_W4_SCO_DISCONNECTED; context->release_audio_connection = 0; gap_disconnect(context->sco_handle); return 1; } if (context->state == HFP_AUDIO_CONNECTION_ESTABLISHED) return 0; // run codecs exchange int done = codecs_exchange_state_machine(context); if (done) return done; // printf(" -> State machine: Audio Connection\n"); if (context->codecs_state != HFP_CODECS_EXCHANGED) return done; if (context->establish_audio_connection){ context->state = HFP_W4_SCO_CONNECTED; context->establish_audio_connection = 0; hci_send_cmd(&hci_setup_synchronous_connection, context->con_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F); return 1; } return 0; }
/* Authentication Complete */ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { if (!ev->status) conn->link_mode |= HCI_LM_AUTH; clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); hci_auth_cfm(conn, ev->status); if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { if (!ev->status) { struct hci_cp_set_conn_encrypt cp; cp.handle = __cpu_to_le16(conn->handle); cp.encrypt = 1; hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); hci_encrypt_cfm(conn, ev->status, 0x00); } } } hci_dev_unlock(hdev); }
static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) { struct hci_cp_remote_name_req *cp; struct hci_conn *conn; BT_DBG("%s status 0x%x", hdev->name, status); /* If successful wait for the name req complete event before * checking for the need to do authentication */ if (!status) return; cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ); if (!cp) return; hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); if (conn && hci_outgoing_auth_needed(hdev, conn)) { struct hci_cp_auth_requested cp; cp.handle = __cpu_to_le16(conn->handle); hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); } hci_dev_unlock(hdev); }
void proc_enable_lpm() { hci_send_cmd(hci_write_sleep_mode, sizeof(hci_write_sleep_mode)); read_event(uart_fd, buffer); }
static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { if (!ev->status) memcpy(conn->features, ev->features, 8); if (conn->state == BT_CONFIG) { if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { struct hci_cp_read_remote_ext_features cp; cp.handle = ev->handle; cp.page = 0x01; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); } } } hci_dev_unlock(hdev); }
void proc_bdaddr() { hci_send_cmd(hci_write_bd_addr, sizeof(hci_write_bd_addr)); read_event(uart_fd, buffer); }
/* * sco_connect(pcb, sockaddr) * * Initiate a SCO connection to the destination address. */ int sco_connect(struct sco_pcb *pcb, struct sockaddr_bt *dest) { hci_add_sco_con_cp cp; struct hci_unit *unit; struct hci_link *acl, *sco; int err; if (pcb->sp_flags & SP_LISTENING) return EINVAL; bdaddr_copy(&pcb->sp_raddr, &dest->bt_bdaddr); if (bdaddr_any(&pcb->sp_raddr)) return EDESTADDRREQ; if (bdaddr_any(&pcb->sp_laddr)) { err = hci_route_lookup(&pcb->sp_laddr, &pcb->sp_raddr); if (err) return err; } unit = hci_unit_lookup(&pcb->sp_laddr); if (unit == NULL) return ENETDOWN; /* * We must have an already open ACL connection before we open the SCO * connection, and since SCO connections dont happen on their own we * will not open one, the application wanting this should have opened * it previously. */ acl = hci_link_lookup_bdaddr(unit, &pcb->sp_raddr, HCI_LINK_ACL); if (acl == NULL || acl->hl_state != HCI_LINK_OPEN) return EHOSTUNREACH; sco = hci_link_alloc(unit); if (sco == NULL) return ENOMEM; sco->hl_type = HCI_LINK_SCO; bdaddr_copy(&sco->hl_bdaddr, &pcb->sp_raddr); sco->hl_link = hci_acl_open(unit, &pcb->sp_raddr); KKASSERT(sco->hl_link == acl); cp.con_handle = htole16(acl->hl_handle); cp.pkt_type = htole16(0x00e0); /* HV1, HV2, HV3 */ err = hci_send_cmd(unit, HCI_CMD_ADD_SCO_CON, &cp, sizeof(cp)); if (err) { hci_link_free(sco, err); return err; } sco->hl_sco = pcb; pcb->sp_link = sco; pcb->sp_mtu = unit->hci_max_sco_size; return 0; }
irqreturn_t mt_bt_eirq_handler(int i, void *arg) { struct hci_dev *hdev = NULL; //printk(KERN_ALERT "mt_bt_eirq_handler\n"); mt_bt_disable_irq(); if(eint_handle_method == 0) { //#ifdef CONFIG_BT_HCIUART /* BlueZ stack, hci_uart driver */ hdev = hci_dev_get(0); if(hdev == NULL){ /* Avoid the early interrupt before hci0 registered */ //BT_HWCTL_ALERT("hdev is NULL\n"); }else{ //BT_HWCTL_ALERT("EINT arrives! notify host wakeup\n"); printk("Send host wakeup command\n"); hci_send_cmd(hdev, 0xFCC1, 0, NULL); /* enable irq after receiving host wakeup command's event */ } mt_bt_enable_irq(); } else { //#else /* Maybe handle the interrupt in user space? */ eint_gen = 1; wake_up_interruptible(&eint_wait); /* Send host wakeup command in user space, enable irq then */ //#endif } return IRQ_HANDLED; }
int hci_disable_device_under_test_mode() { int ret = -1; int dev_id = -1; dev_id = init_smd("/dev/smd3"); if (dev_id < 0) { ALOGE("Can not open file /dev/smd3,maybe file is not exist or no permission to access \n"); return ret; } ret = hci_send_cmd(dev_id, 0x03, 0x0003, 0, NULL); if (ret < 0) { ALOGE("Disable Device Under Test Mode Command failure"); fprintf(stderr, "Disable Device Under Test Mode Command failure hci%d: %s (%d)\n", dev_id, strerror(errno), errno); goto failed; } goto done; failed: close(dev_id); ALOGE("hci_Disable_device_under_test_mode Failed\n"); return ret ; done: close(dev_id); ALOGV("hci_Disable_device_under_test_mode OUT\n"); return ret ; }
/* Authentication Complete */ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { evt_auth_complete *ac = (evt_auth_complete *) skb->data; struct hci_conn *conn = NULL; __u16 handle = __le16_to_cpu(ac->handle); BT_DBG("%s status %d", hdev->name, ac->status); hci_dev_lock(hdev); conn = conn_hash_lookup_handle(hdev, handle); if (conn) { if (!ac->status) conn->link_mode |= HCI_LM_AUTH; clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); hci_proto_auth_cfm(conn, ac->status); if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { if (!ac->status) { set_conn_encrypt_cp ce; ce.handle = __cpu_to_le16(conn->handle); ce.encrypt = 1; hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, SET_CONN_ENCRYPT_CP_SIZE, &ce); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); hci_proto_encrypt_cfm(conn, ac->status); } } } hci_dev_unlock(hdev); }
/* Connect Request */ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data; int mask = hdev->link_mode; BT_DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&ev->bdaddr), ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct hci_conn *conn; struct hci_cp_accept_conn_req cp; hci_dev_lock(hdev); conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) { BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } } memcpy(conn->dev_class, ev->dev_class, 3); conn->state = BT_CONNECT; hci_dev_unlock(hdev); bacpy(&cp.bdaddr, &ev->bdaddr); if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) cp.role = 0x00; /* Become master */ else cp.role = 0x01; /* Remain slave */ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp); } else { /* Connection rejected */ struct hci_cp_reject_conn_req cp; bacpy(&cp.bdaddr, &ev->bdaddr); cp.reason = 0x0f; hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, sizeof(cp), &cp); } }
static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cp[254], rp[254]; struct hci_request rq; uint8_t cmd[10]; uint16_t size; size = (length < 8) ? 9 : ((length + 1) / 2) + 5; cmd[0] = command & 0xff; cmd[1] = command >> 8; cmd[2] = size & 0xff; cmd[3] = size >> 8; cmd[4] = seqnum & 0xff; cmd[5] = seqnum >> 8; cmd[6] = varid & 0xff; cmd[7] = varid >> 8; cmd[8] = 0x00; cmd[9] = 0x00; memset(cp, 0, sizeof(cp)); cp[0] = 0xc2; memcpy(cp + 1, cmd, sizeof(cmd)); memcpy(cp + 11, value, length); switch (varid) { case CSR_VARID_COLD_RESET: case CSR_VARID_WARM_RESET: case CSR_VARID_COLD_HALT: case CSR_VARID_WARM_HALT: return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, (size * 2) + 1, cp); } memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; rq.clen = (size * 2) + 1; rq.rparam = rp; rq.rlen = sizeof(rp); if (hci_send_req(dd, &rq, 2000) < 0) return -1; if (rp[0] != 0xc2) { errno = EIO; return -1; } if ((rp[9] + (rp[10] << 8)) != 0) { errno = ENXIO; return -1; } memcpy(value, rp + 11, length); return 0; }
/* Connect Request */ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { evt_conn_request *cr = (evt_conn_request *) skb->data; int mask = hdev->link_mode; BT_DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type); mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type); if (mask & HCI_LM_ACCEPT) { /* Connection accepted */ struct hci_conn *conn; accept_conn_req_cp ac; hci_dev_lock(hdev); conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr); if (!conn) { if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) { BT_ERR("No memmory for new connection"); hci_dev_unlock(hdev); return; } } conn->state = BT_CONNECT; hci_dev_unlock(hdev); bacpy(&ac.bdaddr, &cr->bdaddr); if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) ac.role = 0x00; /* Become master */ else ac.role = 0x01; /* Remain slave */ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac); } else { /* Connection rejected */ reject_conn_req_cp rc; bacpy(&rc.bdaddr, &cr->bdaddr); rc.reason = 0x0f; hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ, REJECT_CONN_REQ_CP_SIZE, &rc); } }
void proc_i2s() { hci_send_cmd(hci_write_i2spcm_interface_param, sizeof(hci_write_i2spcm_interface_param)); read_event(uart_fd, buffer); }
// enable LE, setup ADV data static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ if (packet_type != HCI_EVENT_PACKET) return; bd_addr_t addr; uint8_t adv_data[] = { 02, 01, 05, 03, 02, 0xf0, 0xff }; switch (packet[0]) { case BTSTACK_EVENT_STATE: // bt stack activated, get started - set local name if (packet[2] == HCI_STATE_WORKING) { printf("Working!\n"); hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data); } break; case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED: if (packet[2]) { printf("CONNECTED"); } else { printf("DISCONNECTED"); } break; case HCI_EVENT_DISCONNECTION_COMPLETE: // restart advertising hci_send_cmd(&hci_le_set_advertise_enable, 1); break; case HCI_EVENT_COMMAND_COMPLETE: if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){ bt_flip_addr(addr, &packet[6]); printf("BD ADDR: %s\n", bd_addr_to_str(addr)); break; } if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){ hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data); break; } if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){ hci_send_cmd(&hci_le_set_advertise_enable, 1); break; } default: break; } }
static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; BT_DBG("%s status %d", hdev->name, ev->status); hci_dev_lock(hdev); conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (!conn) goto unlock; if (!ev->status) memcpy(conn->features, ev->features, 8); if (conn->state != BT_CONFIG) goto unlock; if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) { struct hci_cp_read_remote_ext_features cp; cp.handle = ev->handle; cp.page = 0x01; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, sizeof(cp), &cp); goto unlock; } if (!ev->status) { struct hci_cp_remote_name_req cp; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, &conn->dst); cp.pscan_rep_mode = 0x02; hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp); } if (!hci_outgoing_auth_needed(hdev, conn)) { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); hci_conn_put(conn); } unlock: hci_dev_unlock(hdev); }
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 generic_reset_device(int dd) { bdaddr_t bdaddr; int err; err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL); if (err < 0) return err; return hci_read_bd_addr(dd, &bdaddr, 10000); }
/** send_hciCmd Function * This function takes the hci commands for the BT chip configurations, creates * a hci channel to send the commadns through UART to configure BT chip * * Parameters : * @ dev_id : HCI device ID * @ command_length : Number of arguments of the command * @ command : Pointer to command list * Returns 0 upon success * , different error messages depending upon the error. */ static void send_hciCmd(int dev_id, int command_length, char **command) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; int i, opt, len, dd; uint16_t ocf; uint8_t ogf; if (dev_id < 0) dev_id = hci_get_route(NULL); errno = 0; ogf = strtol(command[0], NULL, 16); ocf = strtol(command[1], NULL, 16); for (i = 2, len = 0; i < command_length && len < sizeof(buf); i++, len++) *ptr++ = (uint8_t) strtol(command[i], NULL, 16); dd = hci_open_dev(dev_id); if (dd < 0) { perror("Device open failed"); return; } /* Setup filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_all_events(&flt); if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { perror("HCI filter setup failed"); return; } /* Send the BT chip configuration commands */ if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); return; } /* Wait for the command completion event */ len = read(dd, buf, sizeof(buf)); if (len < 0) { perror("Read failed"); return; } hdr = (void *)(buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); hci_close_dev(dd); }
static void do_next_remote_name_request(void){ int i; for (i=0;i<deviceCount;i++) { // remote name request if (devices[i].state == REMOTE_NAME_REQUEST){ devices[i].state = REMOTE_NAME_INQUIRED; printf("Get remote name of %s...\n", bd_addr_to_str(devices[i].address)); hci_send_cmd(&hci_remote_name_request, devices[i].address, devices[i].pageScanRepetitionMode, 0, devices[i].clockOffset | 0x8000); return; } } }
void proc_reset() { signal(SIGALRM, expired); hci_send_cmd(hci_reset, sizeof(hci_reset)); alarm(4); read_event(uart_fd, buffer); alarm(0); }
void proc_baudrate() { if (baudrate > 3000000) { hci_send_cmd(hci_write_uart_clock_setting_48Mhz, sizeof(hci_write_uart_clock_setting_48Mhz)); read_event(uart_fd, buffer); } hci_send_cmd(hci_update_baud_rate, sizeof(hci_update_baud_rate)); read_event(uart_fd, buffer); cfsetospeed(&termios, termios_baudrate); cfsetispeed(&termios, termios_baudrate); tcsetattr(uart_fd, TCSANOW, &termios); if (debug) { fprintf(stderr, "Done setting baudrate\n"); } }
static void gap_run(){ if (!hci_can_send_command_packet_now()) return; if (todos & DISABLE_ADVERTISEMENTS){ todos &= ~DISABLE_ADVERTISEMENTS; printf("GAP_RUN: disable advertisements\n"); advertisements_enabled = 0; hci_send_cmd(&hci_le_set_advertise_enable, 0); return; } if (todos & SET_ADVERTISEMENT_DATA){ printf("GAP_RUN: set advertisement data\n"); todos &= ~SET_ADVERTISEMENT_DATA; hci_send_cmd(&hci_le_set_advertising_data, adv_data_len, adv_data); return; } if (todos & SET_ADVERTISEMENT_PARAMS){ todos &= ~SET_ADVERTISEMENT_PARAMS; uint8_t adv_type = gap_adv_type(); bd_addr_t null_addr; memset(null_addr, 0, 6); uint16_t adv_int_min = 0x800; uint16_t adv_int_max = 0x800; switch (adv_type){ case 0: case 2: case 3: hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, 0, &null_addr, 0x07, 0x00); break; case 1: case 4: hci_send_cmd(&hci_le_set_advertising_parameters, adv_int_min, adv_int_max, adv_type, gap_random, tester_address_type, &tester_address, 0x07, 0x00); break; } return; } if (todos & SET_SCAN_RESPONSE_DATA){ printf("GAP_RUN: set scan response data\n"); todos &= ~SET_SCAN_RESPONSE_DATA; hci_send_cmd(&hci_le_set_scan_response_data, adv_data_len, adv_data); // hack for menu if ((todos & ENABLE_ADVERTISEMENTS) == 0) show_usage(); return; } if (todos & ENABLE_ADVERTISEMENTS){ printf("GAP_RUN: enable advertisements\n"); todos &= ~ENABLE_ADVERTISEMENTS; advertisements_enabled = 1; hci_send_cmd(&hci_le_set_advertise_enable, 1); show_usage(); return; } }