int hci_connected(uint8_t *packet, uint16_t size) { bd_addr_t event_addr; // inform about new l2cap connection bt_flip_addr(event_addr, &packet[3]); uint16_t psm = READ_BT_16(packet, 11); bt_accessor(0)->connflags.source_cid = READ_BT_16(packet, 13); bt_accessor(0)->connflags.con_handle = READ_BT_16(packet, 9); if (packet[2] == 0) { printf("Channel successfully opened: "); print_bd_addr(event_addr); printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n", bt_accessor(0)->connflags.con_handle, psm, bt_accessor(0)->connflags.source_cid, READ_BT_16(packet, 15)); // send SABM command on dlci 0 printf("Sending SABM #0\n"); _bt_rfcomm_send_sabm(bt_accessor(0)->connflags.source_cid, 1, 0); } else { printf("L2CAP connection to device "); print_bd_addr(event_addr); printf(" failed. status code %u\n", packet[2]); return (1); } return (0); }
int hci_inquiry_result(uint8_t *packet, uint16_t size) { int numResponses; bd_addr_t addr; t_device res; int i; numResponses = packet[2]; for (i=0; i< numResponses && btscan_count_node(bt_accessor(0)->root) < MAX_DEVICES;i++) { bt_flip_addr(addr, &packet[3+i*6]); if (btscan_find_node(bt_accessor(0)->root, addr)) continue; memset(&res, 0, sizeof(res)); memcpy(res.address, addr, 6); res.pageScanRepetitionMode = packet [3 + numResponses*(6) + i*1]; res.classOfDevice = READ_BT_24(packet, 3 + numResponses*(packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ? (6+1+1) : (6+1+1+1))+ i*3); res.clockOffset = READ_BT_16(packet, 3 + numResponses*(packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ? (6+1+1+3) : (6+1+1+1+3)) + i*2) & 0x7fff; res.rssi = (packet[0] == HCI_EVENT_INQUIRY_RESULT_WITH_RSSI ? packet [3 + numResponses*(6+1+1+3+2) + i*1] : 0); res.state = 1; printf("Device found: "); print_bd_addr(addr); printf(" with COD: 0x%06x, pageScan %u, clock offset 0x%04x\n", res.classOfDevice, res.pageScanRepetitionMode, res.clockOffset); bt_accessor(0)->root = btscan_add_node(bt_accessor(0)->root, &res); } return (0); }
int main (int argc, const char * argv[]){ // parse addr of Bob uint8_t ok = 0; if (argc >= 2) { ok = sscan_bd_addr((uint8_t *) argv[1], bob_addr); } if (!ok) { printf("Usage: mitm 12:34:56:78:9A:BC\n"); exit(0); } // start stack run_loop_init(RUN_LOOP_POSIX); int err = bt_open(); if (err) { printf("Failed to open connection to BTdaemon\n"); return err; } printf("BTstack-in-the-Middle started, will pretend to be BOB ("); print_bd_addr(bob_addr); printf(")\n"); bt_register_packet_handler(packet_handler); bt_send_cmd(&btstack_set_power_mode, HCI_POWER_ON ); run_loop_execute(); bt_close(); }
void comm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; static uint8_t msc_resp_send = 0; static uint8_t msc_resp_received = 0; static uint8_t credits_used = 0; static uint8_t credits_free = 0; uint8_t packet_processed = 0; switch (packet_type) { case L2CAP_DATA_PACKET: // rfcomm: data[8] = addr // rfcomm: data[9] = command // received 1. message BT_RF_COMM_UA if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == 0x03){ packet_processed++; printf("Received RFCOMM unnumbered acknowledgement for channel 0 - multiplexer working\n"); printf("Sending UIH Parameter Negotiation Command\n"); _bt_rfcomm_send_uih_pn_command(source_cid, 1, RFCOMM_CHANNEL_ID, 100); } // received UIH Parameter Negotiation Response if (size == 14 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_PN_RSP){ packet_processed++; printf("UIH Parameter Negotiation Response\n"); printf("Sending SABM #%u\n", RFCOMM_CHANNEL_ID); _bt_rfcomm_send_sabm(source_cid, 1, RFCOMM_CHANNEL_ID); } // received 2. message BT_RF_COMM_UA if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){ packet_processed++; printf("Received RFCOMM unnumbered acknowledgement for channel %u - channel opened\n", RFCOMM_CHANNEL_ID); printf("Sending MSC 'I'm ready'\n"); _bt_rfcomm_send_uih_msc_cmd(source_cid, 1, RFCOMM_CHANNEL_ID, 0x8d); // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1 } // received BT_RFCOMM_MSC_CMD if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_CMD){ packet_processed++; printf("Received BT_RFCOMM_MSC_CMD\n"); printf("Responding to 'I'm ready'\n"); // fine with this uint8_t address = packet[0] | 2; // set response packet[3] = BT_RFCOMM_MSC_RSP; // " " rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0x30, (uint8_t*)&packet[3], 4); msc_resp_send = 1; } // received BT_RFCOMM_MSC_RSP if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_RSP){ packet_processed++; msc_resp_received = 1; } if (packet[1] == BT_RFCOMM_UIH && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){ packet_processed++; credits_used++; if(DEBUG){ printf("RX: address %02x, control %02x: ", packet[0], packet[1]); hexdump( (uint8_t*) &packet[3], size-4); } int written = 0; int length = size-4; int start_of_data = 3; //write data to fifo while (length) { if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) { printf("Error writing to FIFO\n"); } else { length -= written; } } } if (packet[1] == BT_RFCOMM_UIH_PF && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){ packet_processed++; credits_used++; if (!credits_free) { printf("Got %u credits, can send!\n", packet[2]); } credits_free = packet[2]; if(DEBUG){ printf("RX: address %02x, control %02x: ", packet[0], packet[1]); hexdump( (uint8_t *) &packet[4], size-5); } int written = 0; int length = size-5; int start_of_data = 4; //write data to fifo while (length) { if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) { printf("Error writing to FIFO\n"); } else { length -= written; } } } uint8_t send_credits_packet = 0; if (credits_used >= NR_CREDITS ) { send_credits_packet = 1; credits_used -= NR_CREDITS; } if (msc_resp_send && msc_resp_received) { send_credits_packet = 1; msc_resp_send = msc_resp_received = 0; printf("RFCOMM up and running!\n"); } if (send_credits_packet) { // send 0x30 credits uint8_t initiator = 1; uint8_t address = (1 << 0) | (initiator << 1) | (initiator << 1) | (RFCOMM_CHANNEL_ID << 3); rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, NR_CREDITS, NULL, 0); } if (!packet_processed){ // just dump data for now printf("??: address %02x, control %02x: ", packet[0], packet[1]); hexdump( packet, size ); } break; case HCI_EVENT_PACKET: switch (packet[0]) { case BTSTACK_EVENT_POWERON_FAILED: // handle HCI init failure printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n"); exit(1); break; case BTSTACK_EVENT_STATE: // bt stack activated, get started - use authentication yes/no if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_authentication_enable, 1); } break; case HCI_EVENT_LINK_KEY_REQUEST: // link key request bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, PIN); printf("Please enter PIN %s on remote device\n", PIN); break; case L2CAP_EVENT_CHANNEL_OPENED: // inform about new l2cap connection bt_flip_addr(event_addr, &packet[3]); uint16_t psm = READ_BT_16(packet, 11); source_cid = READ_BT_16(packet, 13); con_handle = READ_BT_16(packet, 9); if (packet[2] == 0) { printf("Channel successfully opened: "); print_bd_addr(event_addr); printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n", con_handle, psm, source_cid, READ_BT_16(packet, 15)); // send SABM command on dlci 0 printf("Sending SABM #0\n"); _bt_rfcomm_send_sabm(source_cid, 1, 0); } else { printf("L2CAP connection to device "); print_bd_addr(event_addr); printf(" failed. status code %u\n", packet[2]); exit(1); } break; case HCI_EVENT_DISCONNECTION_COMPLETE: // connection closed -> quit test app printf("Basebank connection closed, exit.\n"); exit(0); break; case HCI_EVENT_COMMAND_COMPLETE: // connect to RFCOMM device (PSM 0x03) at addr if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&l2cap_create_channel, addr, 0x03); } break; default: // unhandled event if(DEBUG) printf("unhandled event : %02x\n", packet[0]); break; } break; default: // unhandled packet type if(DEBUG) printf("unhandled packet type : %02x\n", packet_type); break; } }
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; switch (packet_type) { case L2CAP_DATA_PACKET: // just dump data for now printf("source cid %x -- ", channel); hexdump( packet, size ); // HOME => disconnect if (packet[0] == 0xA1) { // Status report if (packet[1] == 0x30 || packet[1] == 0x31) { // type 0x30 or 0x31 if (packet[3] & 0x080) { // homne button pressed printf("Disconnect baseband\n"); bt_send_cmd(&hci_disconnect, con_handle, 0x13); // remote closed connection } } } break; case HCI_EVENT_PACKET: switch (packet[0]) { case BTSTACK_EVENT_POWERON_FAILED: printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n"); exit(1); break; case BTSTACK_EVENT_STATE: // bt stack activated, get started - disable pairing if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_authentication_enable, 0); } break; case HCI_EVENT_LINK_KEY_REQUEST: printf("HCI_EVENT_LINK_KEY_REQUEST \n"); // link key request bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request printf("Please enter PIN 0000 on remote device\n"); bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); break; case L2CAP_EVENT_CHANNEL_OPENED: // inform about new l2cap connection // inform about new l2cap connection bt_flip_addr(event_addr, &packet[3]); uint16_t psm = READ_BT_16(packet, 11); uint16_t source_cid = READ_BT_16(packet, 13); con_handle = READ_BT_16(packet, 9); if (packet[2] == 0) { printf("Channel successfully opened: "); print_bd_addr(event_addr); printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n", con_handle, psm, source_cid, READ_BT_16(packet, 15)); if (psm == 0x13) { source_cid_interrupt = source_cid; // interupt channel openedn succesfully, now open control channel, too. bt_send_cmd(&l2cap_create_channel, event_addr, 0x11); } else { source_cid_control = source_cid; // request acceleration data.. // uint8_t setMode31[] = { 0x52, 0x12, 0x00, 0x31 }; // bt_send_l2cap( source_cid, setMode31, sizeof(setMode31)); // stop blinking // uint8_t setLEDs[] = { 0x52, 0x11, 0x10 }; // bt_send_l2cap( source_cid, setLEDs, sizeof(setLEDs)); } } else { printf("L2CAP connection to device "); print_bd_addr(event_addr); printf(" failed. status code %u\n", packet[2]); exit(1); } break; case HCI_EVENT_DISCONNECTION_COMPLETE: // connection closed -> quit tes app printf("Basebank connection closed, exit.\n"); exit(0); break; case HCI_EVENT_COMMAND_COMPLETE: // connect to HID device (PSM 0x13) at addr if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&l2cap_create_channel, addr, 0x13); printf("Press 1+2 on WiiMote to make it discoverable - Press HOME to disconnect later :)\n"); } break; default: // other event break; } break; default: // other packet type break; } }
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; uint16_t handle; uint16_t psm; uint16_t local_cid; uint16_t remote_cid; char pin[20]; int i; switch (packet_type) { case L2CAP_DATA_PACKET: // just dump data for now printf("source cid %x -- ", channel); hexdump( packet, size ); break; case HCI_EVENT_PACKET: switch (packet[0]) { case BTSTACK_EVENT_POWERON_FAILED: printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n"); exit(1); break; case BTSTACK_EVENT_STATE: // bt stack activated, get started - set local name if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_authentication_enable, 0); } break; case L2CAP_EVENT_INCOMING_CONNECTION: // data: event(8), len(8), address(48), handle (16), psm (16), source cid(16) dest cid(16) bt_flip_addr(event_addr, &packet[2]); handle = READ_BT_16(packet, 8); psm = READ_BT_16(packet, 10); local_cid = READ_BT_16(packet, 12); remote_cid = READ_BT_16(packet, 14); printf("L2CAP_EVENT_INCOMING_CONNECTION "); print_bd_addr(event_addr); printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n", handle, psm, local_cid, remote_cid); // accept bt_send_cmd(&l2cap_accept_connection, local_cid); break; case HCI_EVENT_LINK_KEY_REQUEST: // link key request bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request printf("Please enter PIN here: "); fgets(pin, 20, stdin); i = strlen(pin)-1; if( pin[i] == '\n') { pin[i] = '\0'; } printf("PIN = '%s'\n", pin); bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_pin_code_request_reply, &event_addr, strlen(pin), pin); break; case L2CAP_EVENT_CHANNEL_OPENED: // inform about new l2cap connection bt_flip_addr(event_addr, &packet[3]); psm = READ_BT_16(packet, 11); local_cid = READ_BT_16(packet, 13); handle = READ_BT_16(packet, 9); if (packet[2] == 0) { printf("Channel successfully opened: "); print_bd_addr(event_addr); printf(", handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n", handle, psm, local_cid, READ_BT_16(packet, 15)); if (psm == PSM_HID_CONTROL){ hid_control = local_cid; } if (psm == PSM_HID_INTERRUPT){ hid_interrupt = local_cid; } if (hid_control && hid_interrupt){ bt_send_cmd(&hci_switch_role_command, &event_addr, 0); } } else { printf("L2CAP connection to device "); print_bd_addr(event_addr); printf(" failed. status code %u\n", packet[2]); exit(1); } break; case HCI_EVENT_ROLE_CHANGE: { //HID Control: 0x06 bytes - SET_FEATURE_REPORT [ 53 F4 42 03 00 00 ] uint8_t set_feature_report[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00}; bt_send_l2cap(hid_control, (uint8_t*) &set_feature_report, sizeof(set_feature_report)); break; } case HCI_EVENT_DISCONNECTION_COMPLETE: // connection closed -> quit tes app printf("Basebank connection closed\n"); // exit(0); break; case HCI_EVENT_COMMAND_COMPLETE: if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&hci_write_class_of_device, 0x2540); } default: // other event break; } break; default: // other packet type break; } }
/* LISTING_START(GAPLEAdvDataParsing): Parsing advertising data */ static void dump_advertisement_data(uint8_t * adv_data, uint8_t adv_size){ ad_context_t context; bd_addr_t address; uint8_t uuid_128[16]; for (ad_iterator_init(&context, adv_size, adv_data) ; ad_iterator_has_more(&context) ; ad_iterator_next(&context)){ uint8_t data_type = ad_iterator_get_data_type(&context); uint8_t size = ad_iterator_get_data_len(&context); uint8_t * data = ad_iterator_get_data(&context); if (data_type > 0 && data_type < 0x1B){ printf(" %s: ", ad_types[data_type]); } int i; // Assigned Numbers GAP switch (data_type){ case 0x01: // Flags // show only first octet, ignore rest for (i=0; i<8;i++){ if (data[0] & (1<<i)){ printf("%s; ", flags[i]); } } break; case 0x02: // Incomplete List of 16-bit Service Class UUIDs case 0x03: // Complete List of 16-bit Service Class UUIDs case 0x14: // List of 16-bit Service Solicitation UUIDs for (i=0; i<size;i+=2){ printf("%02X ", READ_BT_16(data, i)); } break; case 0x04: // Incomplete List of 32-bit Service Class UUIDs case 0x05: // Complete List of 32-bit Service Class UUIDs for (i=0; i<size;i+=4){ printf("%04X ", READ_BT_32(data, i)); } break; case 0x06: // Incomplete List of 128-bit Service Class UUIDs case 0x07: // Complete List of 128-bit Service Class UUIDs case 0x15: // List of 128-bit Service Solicitation UUIDs swap128(data, uuid_128); printUUID128(uuid_128); break; case 0x08: // Shortened Local Name case 0x09: // Complete Local Name for (i=0; i<size;i++){ printf("%c", (char)(data[i])); } break; case 0x0A: // Tx Power Level printf("%d dBm", *(int8_t*)data); break; case 0x12: // Slave Connection Interval Range printf("Connection Interval Min = %u ms, Max = %u ms", READ_BT_16(data, 0) * 5/4, READ_BT_16(data, 2) * 5/4); break; case 0x16: // Service Data printf_hexdump(data, size); break; case 0x17: // Public Target Address case 0x18: // Random Target Address bt_flip_addr(address, data); print_bd_addr(address); break; case 0x19: // Appearance // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml printf("%02X", READ_BT_16(data, 0) ); break; case 0x1A: // Advertising Interval printf("%u ms", READ_BT_16(data, 0) * 5/8 ); break; case 0x3D: // 3D Information Data printf_hexdump(data, size); break; case 0xFF: // Manufacturer Specific Data break; case 0x0D: // Class of Device (3B) case 0x0E: // Simple Pairing Hash C (16B) case 0x0F: // Simple Pairing Randomizer R (16B) case 0x10: // Device ID case 0x11: // Security Manager TK Value (16B) default: printf("Unknown Advertising Data Type"); break; } printf("\n"); } printf("\n"); }
void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ hci_con_handle_t acl_in; hci_con_handle_t acl_out; switch (packet_type){ case HCI_ACL_DATA_PACKET: acl_in = READ_ACL_CONNECTION_HANDLE(packet); acl_out = 0; if (acl_in == alice_handle) { printf("Alice: "); hexdump( packet, size ); printf("\n\n"); acl_out = bob_handle; } if (acl_in == bob_handle) { printf("Bob: "); hexdump( packet, size ); printf("\n\n"); acl_out = alice_handle; } if (acl_out){ bt_store_16( packet, 0, (READ_BT_16(packet, 0) & 0xf000) | acl_out); bt_send_acl(packet, size); } break; case HCI_EVENT_PACKET: switch(packet[0]){ case BTSTACK_EVENT_STATE: // bt stack activated, get started - set COD if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_class_of_device, 0x7A020C); // used on iPhone } break; case HCI_EVENT_EXTENDED_INQUIRY_RESPONSE: // process EIR responses if (packet[17]) { bt_flip_addr(temp_addr, &packet[3]); if (BD_ADDR_CMP(temp_addr, bob_addr)) { printf("2. Got BOB's EIR. "); int i, k; bzero(bob_EIR, EIR_LEN); for (i=17, k=0;i<EIR_LEN && packet[i]; i += packet[i] + 1, k += bob_EIR[k] + 1){ if (packet[i+1] == 0x09) { // complete name id -- use own bob_EIR[k+0] = 1 + strlen(NAME); bob_EIR[k+1] = 0x09; memcpy(&bob_EIR[k+2], NAME, strlen(NAME)); } else { // vendor specific if (packet[i+1] == 0x0ff ) { bob_got_EIR = 1; } memcpy(&bob_EIR[k], &packet[i], packet[i]+1); } } hexdump(&bob_EIR, k); printf("\n\n"); bob_clock_offset = READ_BT_16(packet, 14); bob_page_scan_repetition_mode = packet[9]; } // stop inquiry // bt_send_cmd(&hci_inquiry_cancel); } break; case HCI_EVENT_CONNECTION_REQUEST: // accept incoming connections bt_flip_addr(temp_addr, &packet[2]); if (BD_ADDR_CMP(temp_addr, bob_addr) ){ printf("-> Connection request from BOB. Denying\n"); // bt_send_cmd(&hci_accept_connection_request, &temp_addr, 1); } else { printf("-> Connection request from Alice. Sending Accept\n"); bt_send_cmd(&hci_accept_connection_request, &temp_addr, 1); } break; case HCI_EVENT_CONNECTION_COMPLETE: // handle connections bt_flip_addr(temp_addr, &packet[5]); if (packet[2] == 0){ hci_con_handle_t incoming_handle = READ_BT_16(packet, 3); if (BD_ADDR_CMP(temp_addr, bob_addr)){ bob_handle = incoming_handle; printf("7. Connected to BOB (handle %u). Relaying data!\n", bob_handle); } else { alice_handle = incoming_handle; printf("6. Alice connected (handle %u). Connecting to BOB.\n", alice_handle); bt_send_cmd(&hci_create_connection, &bob_addr, 0x18, bob_page_scan_repetition_mode, 0, 0x8000 || bob_clock_offset, 0); } } else { printf("Connection complete status %u for connection", packet[2]); print_bd_addr(temp_addr); printf("\n"); } break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request printf("Please enter PIN 1234 on remote device\n"); break; case HCI_EVENT_DISCONNECTION_COMPLETE: // connection closed -> quit test app printf("Basebank connection closed, exit.\n"); exit(0); break; case HCI_EVENT_COMMAND_COMPLETE: // use pairing yes/no if ( COMMAND_COMPLETE_EVENT(packet, hci_write_class_of_device) ) { bt_send_cmd(&hci_write_authentication_enable, 0); } // allow Extended Inquiry responses if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&hci_write_inquiry_mode, 2); } // get all events, including EIRs if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { bt_send_cmd(&hci_set_event_mask, 0xffffffff, 0x1fffffff); } // fine with us, too if ( COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask) ) { bt_send_cmd(&hci_write_simple_pairing_mode, 1); } // start inquiry if ( COMMAND_COMPLETE_EVENT(packet, hci_write_simple_pairing_mode) ) { // enable capure bt_send_cmd(&btstack_set_acl_capture_mode, 1); printf("1. Started inquiry.\n"); bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, 15, 0); } // Connect to BOB if ( COMMAND_COMPLETE_EVENT(packet, hci_write_extended_inquiry_response) ) { printf("5. Waiting for Alice!...\n"); // bt_send_cmd(&hci_write_scan_enable, 3); // 3 inq scan + page scan // bt_send_cmd(&hci_create_connection, &addr, 0x18, page_scan_repetition_mode, 0, 0x8000 || clock_offset, 0); } break; default: // Inquiry done, set EIR if (packet[0] == HCI_EVENT_INQUIRY_COMPLETE || COMMAND_COMPLETE_EVENT(packet, hci_inquiry_cancel)){ if (!inquiry_done){ inquiry_done = 1; printf("3. Inquiry Complete\n"); if (bob_got_EIR){ printf("4. Set EIR to Bob's.\n"); bt_send_cmd(&hci_write_extended_inquiry_response, 0, bob_EIR); } else { // failed to get BOB's EIR } } } break; } default: break; } }