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 hci_send_acl(u8* output, u16 osize) { u16 payload_size; u8 edr; payload_size = osize - 4; l2cap_output(output + 4, &payload_size, &edr); if (payload_size) { #if !DISABLE_BT_CLASSICAL if (edr) { bt_write_u16(output, hci.edr.hconn | 0x2000); } else #endif { bt_write_u16(output, hci.le.hconn | 0x2000); } bt_write_u16(output + 2, payload_size); hci_dumphex("ACLO", output, payload_size + 4); hci_write(BT_ACL_OUT_CHANNEL, payload_size + 4); } }
static void hci_send_command(u8* buffer, u16 size) { u8 cmdlen; u8 send_cmd = 0; if (hci.ncmds) { if (hci.tasks.reset) { cmdlen = hci.curr_reset_cmd[2] + 3; memcpy(buffer, hci.curr_reset_cmd, cmdlen); hci.curr_reset_cmd += cmdlen; send_cmd = 1; if ((hci.curr_reset_cmd[0] == 0) && (hci.curr_reset_cmd[1] == 0)) { hci_printf("radio initialized\n"); hci.tasks.reset = 0; } } else if (hci.tasks.set_adv_params) { static const u8 le_set_adv_params[] = { 6,0x20, // set adv params 0xF, // params len 0x20,0, // min int 0x20,0, // max int 0, // adv type 0, // own addr type 0, //direct addr type 0,0,0,0,0,0, //direct addr 7, // channel map 0 // filter }; hci.tasks.set_adv_params = 0; memcpy(buffer, le_set_adv_params, sizeof(le_set_adv_params)); send_cmd = 1; } else if (hci.tasks.set_adv_data) { hci.tasks.set_adv_data = 0; buffer[0] = 8; buffer[1] = 0x20; buffer[2] = 32; memset(buffer + 3, 0, 32); buffer[3] = sizeof(CFG_DEVICE_NAME) + 3; // adv data len buffer[4] = sizeof(CFG_DEVICE_NAME) + 2; // adv element len buffer[5] = 9; // type: complete name memcpy(buffer + 6, CFG_DEVICE_NAME, sizeof(CFG_DEVICE_NAME)); send_cmd = 1; } else if (hci.tasks.set_adv_en) { static const u8 le_set_adv_en[] = {0xA, 0x20, 1, 1}; hci.tasks.set_adv_en = 0; memcpy(buffer, le_set_adv_en, sizeof(le_set_adv_en)); if ((hci.le.hconn == 0) && (hci.state.visible == 1)) { buffer[3] = 1; } else { buffer[3] = 0; } send_cmd = 1; hci_printf("adv_en = %x\n", buffer[3]); } #if !DISABLE_BT_CLASSICAL else if (hci.tasks.write_local_name) { hci.tasks.write_local_name = 0; buffer[0] = 0x13; buffer[1] = 0xC; buffer[2] = 248; strncpy(buffer + 3, CFG_DEVICE_NAME, 248); send_cmd = 1; } else if (hci.tasks.write_eir) { hci.tasks.write_eir = 0; buffer[0] = 0x52; buffer[1] = 0xC; buffer[2] = 241; buffer[3] = 1; // FEC required memset(buffer + 4, 0, 240); // EIR Element: complete local name buffer[4] = sizeof(CFG_DEVICE_NAME) + 1; buffer[5] = 9; memcpy(buffer + 6, CFG_DEVICE_NAME, sizeof(CFG_DEVICE_NAME)); send_cmd = 1; } else if (hci.tasks.write_scan_en) { static const u8 hci_write_scan_en[] = {0x1A, 0xC, 1, 0}; hci.tasks.write_scan_en = 0; memcpy(buffer, hci_write_scan_en, sizeof(hci_write_scan_en)); if ((hci.edr.hconn == 0) && (hci.state.visible == 1)) { buffer[3] = 3; } else { buffer[3] = 0; } send_cmd = 1; hci_printf("scan enable = %x\n", buffer[3]); } else if (hci.tasks.accept_conn) { hci.tasks.accept_conn = 0; buffer[0] = 9; buffer[1] = 4; buffer[2] = 7; memcpy(buffer + 3, hci.edr.bdaddr, 6); buffer[9] = 1; send_cmd = 1; hci_printf("accept conn\n"); } else if (hci.tasks.io_cap_reply) { hci.tasks.io_cap_reply = 0; buffer[0] = 0x2B; buffer[1] = 4; buffer[2] = 9; memcpy(buffer + 3, hci.edr.bdaddr, 6); buffer[9] = 3; // No IO buffer[10] = 0; // No OOB data buffer[11] = 0; send_cmd = 1; } else if (hci.tasks.user_cfm_reply) { hci.tasks.user_cfm_reply = 0; buffer[0] = 0x2C; buffer[1] = 4; buffer[2] = 6; memcpy(buffer + 3, hci.edr.bdaddr, 6); send_cmd = 1; } #endif if (send_cmd) { cmdlen = buffer[2] + 3; hci_dumphex("CMD", buffer, cmdlen); hci_write(BT_COMMAND_CHANNEL, cmdlen); hci.ncmds--; } } }