void process_hci_event(uint8_t* packet) { uint16_t local_cid; //char pin[20]; //int i; //CFDataRef cfData; switch (packet[0]) { case BTSTACK_EVENT_POWERON_FAILED: printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n"); changeState(iSAP_state_error); break; case BTSTACK_EVENT_STATE: if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_local_name, device_name); changeState(iSAP_state_ready); } break; case L2CAP_EVENT_INCOMING_CONNECTION: local_cid = READ_BT_16(packet, 12); // accept bt_send_cmd(&l2cap_accept_connection, local_cid); changeState(iSAP_state_starting_l2cap); break; case HCI_EVENT_LINK_KEY_NOTIFICATION: //implement link key saving break; case HCI_EVENT_LINK_KEY_REQUEST: // link key request bt_flip_addr(event_addr, &packet[2]); //unsigned char lk[16] = {0x88, 0xf2, 0x5a, 0x92, 0x5a, 0x9e, 0x00, 0x4b, 0x05, 0xf9, 0xf7, 0x02, 0xd9, 0x1a, 0x43, 0xbb}; //bt_send_cmd(&hci_link_key_request_reply, &event_addr, lk); bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request sendMessageToGUI(CFMSG_setPIN, 0, NULL, NULL, CFSTR(_messagePortName_client)); //while (!allowPin) { // sleep(1); //} //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 source_cid = READ_BT_16(packet, 13); con_handle = READ_BT_16(packet, 9); break; case HCI_EVENT_CONNECTION_REQUEST: { // accept incoming connections bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_accept_connection_request, &event_addr, 1); changeState(iSAP_state_starting_hci); break; } case HCI_EVENT_CONNECTION_COMPLETE: // handle connections break; case HCI_EVENT_DISCONNECTION_COMPLETE: printf("Basebank connection closed\n"); changeState(iSAP_state_ready); break; case HCI_EVENT_COMMAND_COMPLETE: // use pairing yes/no if ( COMMAND_COMPLETE_EVENT(packet, hci_write_local_name) ) { bt_send_cmd(&hci_write_authentication_enable, 0); } else if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&hci_write_class_of_device, 0x5a020C); } break; default: // other event if (DEBUG) { printf("Unknown packet %02x\n", packet[0]); } break; } }
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ //static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t addr; int i; int numResponses; // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = packet[0]; switch(state){ case INIT: if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI state = W4_INQUIRY_MODE_COMPLETE; } break; case W4_INQUIRY_MODE_COMPLETE: switch(event){ case HCI_EVENT_COMMAND_COMPLETE: if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { start_scan(); state = ACTIVE; } break; case HCI_EVENT_COMMAND_STATUS: if ( COMMAND_STATUS_EVENT(packet, hci_write_inquiry_mode) ) { printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]); start_scan(); state = ACTIVE; } break; default: break; } break; case ACTIVE: switch(event){ case HCI_EVENT_INQUIRY_RESULT: case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: numResponses = packet[2]; for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ bt_flip_addr(addr, &packet[3+i*6]); int index = getDeviceIndexForAddress(addr); if (index >= 0) continue; memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = packet [3 + numResponses*(6) + i*1]; if (event == HCI_EVENT_INQUIRY_RESULT){ devices[deviceCount].classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1+1) + i*3); devices[deviceCount].clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff; devices[deviceCount].rssi = 0; } else { devices[deviceCount].classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1) + i*3); devices[deviceCount].clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+3) + i*2) & 0x7fff; devices[deviceCount].rssi = packet [3 + numResponses*(6+1+1+3+2) + i*1]; } devices[deviceCount].state = REMOTE_NAME_REQUEST; printf("Device found: %s with COD: 0x%06x, pageScan %u, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, devices[deviceCount].clockOffset, devices[deviceCount].rssi); deviceCount++; } break; case HCI_EVENT_INQUIRY_COMPLETE: for (i=0;i<deviceCount;i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; case BTSTACK_EVENT_REMOTE_NAME_CACHED: bt_flip_addr(addr, &packet[3]); printf("Cached remote name for %s: '%s'\n", bd_addr_to_str(addr), &packet[9]); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: bt_flip_addr(addr, &packet[3]); int index = getDeviceIndexForAddress(addr); if (index >= 0) { if (packet[2] == 0) { printf("Name: '%s'\n", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; } else { printf("Failed to get name: page timeout\n"); } } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; default: break; } break; default: break; } }
void start_scan(void){ printf("Starting inquiry scan..\n"); bt_send_cmd(&hci_inquiry, HCI_INQUIRY_LAP, INQUIRY_INTERVAL, 0); }
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; switch (packet_type) { case RFCOMM_DATA_PACKET: printf("Received RFCOMM data on channel id %u, size %u\n", channel, size); hexdump(packet, size); bt_send_rfcomm(channel, 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 if (packet[2] == HCI_STATE_WORKING) { // get persistent RFCOMM channel printf("HCI_STATE_WORKING\n"); bt_send_cmd(&rfcomm_persistent_channel_for_service, "ch.ringwald.btstack.rfcomm-echo2"); } break; case RFCOMM_EVENT_PERSISTENT_CHANNEL: rfcomm_channel_nr = packet[3]; printf("RFCOMM channel %u was assigned by BTdaemon\n", rfcomm_channel_nr); bt_send_cmd(&rfcomm_register_service, rfcomm_channel_nr, 100); // reserved channel, mtu=100 break; case RFCOMM_EVENT_SERVICE_REGISTERED: printf("RFCOMM_EVENT_SERVICE_REGISTERED channel: %u, status: 0x%02x\n", packet[3], packet[2]); // register SDP for our SPP create_spp_service(service_buffer, rfcomm_channel_nr); bt_send_cmd(&sdp_register_service_record, service_buffer); bt_send_cmd(&btstack_set_discoverable, 1); break; case HCI_EVENT_PIN_CODE_REQUEST: // inform about pin code request printf("Using PIN 0000\n"); bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); break; case RFCOMM_EVENT_INCOMING_CONNECTION: // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) bt_flip_addr(event_addr, &packet[2]); rfcomm_channel_nr = packet[8]; rfcomm_channel_id = READ_BT_16(packet, 9); printf("RFCOMM channel %u requested for %s\n", rfcomm_channel_nr, bd_addr_to_str(event_addr)); bt_send_cmd(&rfcomm_accept_connection, rfcomm_channel_id); break; case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16) if (packet[2]) { printf("RFCOMM channel open failed, status %u\n", packet[2]); } else { rfcomm_channel_id = READ_BT_16(packet, 12); mtu = READ_BT_16(packet, 14); printf("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n", rfcomm_channel_id, mtu); } break; case HCI_EVENT_DISCONNECTION_COMPLETE: // connection closed -> quit test app printf("Basebank connection closed\n"); break; default: break; } break; default: 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; char pin[20]; int i; switch (packet_type) { case L2CAP_DATA_PACKET: // measure data rate 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 if (packet[2] == HCI_STATE_WORKING) { if (serverMode) { printf("Waiting for incoming L2CAP connection on PSM %04x...\n", PSM_TEST); timer.process = timer_handler; run_loop_set_timer(&timer, 3000); // run_loop_add_timer(&timer); } else { bt_send_cmd(&hci_write_authentication_enable, 0); } } break; case HCI_EVENT_COMMAND_COMPLETE: // use pairing yes/no if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) { bt_send_cmd(&hci_write_class_of_device, 0x38010c); } if ( COMMAND_COMPLETE_EVENT(packet, hci_write_class_of_device) ) { bt_send_cmd(&l2cap_create_channel_mtu, addr, PSM_TEST, PACKET_SIZE); } 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 %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x\n", bd_addr_to_str(event_addr), handle, psm, local_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); if( pin[i-1] == '\n' || pin[i-1] == '\r') { pin[i-1] = '\0'; i--; } printf("PIN (%u)= '%s'\n", i, pin); bt_flip_addr(event_addr, &packet[2]); bt_send_cmd(&hci_pin_code_request_reply, &event_addr, i, 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: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n", bd_addr_to_str(event_addr), handle, psm, local_cid, READ_BT_16(packet, 15)); } else { printf("L2CAP connection to device %s failed. status code %u\n", bd_addr_to_str(event_addr), packet[2]); } break; case HCI_EVENT_DISCONNECTION_COMPLETE: printf("Basebank connection closed\n"); break; case L2CAP_EVENT_CREDITS: if (!serverMode) { // can send! (assuming single credits are handet out) update_packet(); local_cid = READ_BT_16(packet, 2); bt_send_l2cap( local_cid, packet, PACKET_SIZE); } break; default: // other event break; } break; default: // other packet type break; } }
void timer_handler(struct timer *ts){ bt_send_cmd(&hci_read_bd_addr); run_loop_set_timer(&timer, 3000); run_loop_add_timer(&timer); };
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; } }
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; } }
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ //static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t addr; int i; int index; int numResponses; // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = hci_event_packet_get_type(packet); switch(state){ case INIT: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI state = W4_INQUIRY_MODE_COMPLETE; } break; case W4_INQUIRY_MODE_COMPLETE: switch(event){ case HCI_EVENT_COMMAND_COMPLETE: if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_write_inquiry_mode)) { start_scan(); state = ACTIVE; } break; case HCI_EVENT_COMMAND_STATUS: if (HCI_EVENT_IS_COMMAND_STATUS(packet, hci_write_inquiry_mode)) { printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]); start_scan(); state = ACTIVE; } break; default: break; } break; case ACTIVE: switch(event){ case HCI_EVENT_INQUIRY_RESULT: case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{ numResponses = hci_event_inquiry_result_get_num_responses(packet); int offset = 3; for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ reverse_bd_addr(&packet[offset], addr); offset += 6; index = getDeviceIndexForAddress(addr); if (index >= 0) continue; // already in our list memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = packet[offset]; offset += 1; if (event == HCI_EVENT_INQUIRY_RESULT){ offset += 2; // Reserved + Reserved devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = 0; } else { offset += 1; // Reserved devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = packet[offset]; offset += 1; } devices[deviceCount].state = REMOTE_NAME_REQUEST; printf("Device found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, devices[deviceCount].clockOffset, devices[deviceCount].rssi); deviceCount++; } break; } case HCI_EVENT_INQUIRY_COMPLETE: for (i=0;i<deviceCount;i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; case DAEMON_EVENT_REMOTE_NAME_CACHED: reverse_bd_addr(&packet[3], addr); printf("Cached remote name for %s: '%s'\n", bd_addr_to_str(addr), &packet[9]); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: reverse_bd_addr(&packet[3], addr); index = getDeviceIndexForAddress(addr); if (index >= 0) { if (packet[2] == 0) { printf("Name: '%s'\n", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; } else { printf("Failed to get name: page timeout\n"); } } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; default: break; } break; default: break; } }