diff --git a/example/sm_pairing_central.c b/example/sm_pairing_central.c index 9e64489a8..0129fab8c 100644 --- a/example/sm_pairing_central.c +++ b/example/sm_pairing_central.c @@ -64,6 +64,9 @@ // LightBlue assigns 0x1111 as the UUID for a Blank service. #define REMOTE_SERVICE 0x1111 +// Fixed passkey - used with sm_pairing_peripheral. Passkey is random in general +#define FIXED_PASSKEY 12346 + static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_packet_callback_registration_t sm_event_callback_registration; @@ -76,7 +79,8 @@ static btstack_packet_callback_registration_t sm_event_callback_registration; */ /* LISTING_START(GAPLEAdvSetup): Setting up GAP LE client for receiving advertisements */ -static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); +static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void sm_pairing_central_setup(void){ l2cap_init(); @@ -92,25 +96,24 @@ static void sm_pairing_central_setup(void){ /** * Choose ONE of the following configurations + * Bonding is disabled to allow for repeated testing. It can be enabled with SM_AUTHREQ_BONDING */ // register handler - hci_event_callback_registration.callback = &packet_handler; + hci_event_callback_registration.callback = &hci_packet_handler; hci_add_event_handler(&hci_event_callback_registration); - sm_event_callback_registration.callback = &packet_handler; + sm_event_callback_registration.callback = &sm_packet_handler; sm_add_event_handler(&sm_event_callback_registration); - att_server_register_packet_handler(packet_handler); - // LE Legacy Pairing, Just Works - sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); - sm_set_authentication_requirements(SM_AUTHREQ_NO_BONDING); + // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); + // sm_set_authentication_requirements(SM_AUTHREQ_ NO_BONDING); // LE Legacy Pairing, Passkey entry initiator enter, responder (us) displays // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); // sm_set_authentication_requirements(SM_AUTHREQ_MITM_PROTECTION); - // sm_use_fixed_passkey_in_display_role(123456); + // sm_use_fixed_passkey_in_display_role(FIXED_PASSKEY); #ifdef ENABLE_LE_SECURE_CONNECTIONS // LE Secure Connetions, Just Works @@ -118,13 +121,14 @@ static void sm_pairing_central_setup(void){ // sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION); // LE Secure Connections, Numeric Comparison - // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); - // sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); + // sm_set_io_capabilities(IO_CAPABILITY_KEYBOARD_ONLY); + sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_YES_NO); + sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); // LE Legacy Pairing, Passkey entry initiator enter, responder (us) displays // sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); // sm_set_authentication_requirements(SM_AUTHREQ_SECURE_CONNECTION|SM_AUTHREQ_MITM_PROTECTION); - // sm_use_fixed_passkey_in_display_role(123456); + // sm_use_fixed_passkey_in_display_role(FIXED_PASSKEY); #endif } @@ -135,12 +139,12 @@ static void sm_pairing_central_setup(void){ * @text The HCI packet handler has to start the scanning, * and to handle received advertisements. Advertisements are received * as HCI event packets of the GAP_EVENT_ADVERTISING_REPORT type, - * see Listing GAPLEAdvPacketHandler. + * see Listing HCIPacketHandler. */ -/* LISTING_START(GAPLEAdvPacketHandler): Scanning and receiving advertisements */ +/* LISTING_START(HCIPacketHandler): Scanning and receiving advertisements */ -static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ +static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(channel); UNUSED(size); @@ -162,15 +166,48 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe uint8_t address_type = gap_event_advertising_report_get_address_type(packet); uint8_t length = gap_event_advertising_report_get_data_length(packet); const uint8_t * data = gap_event_advertising_report_get_data(packet); - printf("Advertisement event: addr-type %u, addr %s, data[%u] ", - address_type, bd_addr_to_str(address), length); - printf_hexdump(data, length); + // printf("Advertisement event: addr-type %u, addr %s, data[%u] ", + // address_type, bd_addr_to_str(address), length); + // printf_hexdump(data, length); if (!ad_data_contains_uuid16(length, (uint8_t *) data, REMOTE_SERVICE)) break; printf("Found remote with UUID %04x, connecting...\n", REMOTE_SERVICE); gap_stop_scan(); gap_connect(address,address_type); break; } + case HCI_EVENT_LE_META: + // wait for connection complete + if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break; + con_handle = hci_subevent_le_connection_complete_get_connection_handle(packet); + printf("Connection complete\n"); + // start pairing + sm_request_pairing(con_handle); + break; + case HCI_EVENT_ENCRYPTION_CHANGE: + con_handle = hci_event_encryption_change_get_connection_handle(packet); + printf("Connection encrypted: %u\n", hci_event_encryption_change_get_encryption_enabled(packet)); + break; + default: + break; + } +} + +/* @section HCI packet handler + * + * @text The SM packet handler receives Security Manager Events required for pairing. + * It also receives events generated during Identity Resolving + * see Listing SMPacketHandler. + */ + +/* LISTING_START(SMPacketHandler): Scanning and receiving advertisements */ + +static void sm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + UNUSED(channel); + UNUSED(size); + + if (packet_type != HCI_EVENT_PACKET) return; + + switch (hci_event_packet_get_type(packet)) { case SM_EVENT_JUST_WORKS_REQUEST: printf("Just works requested\n"); sm_just_works_confirm(sm_event_just_works_request_get_handle(packet)); @@ -182,6 +219,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case SM_EVENT_PASSKEY_DISPLAY_NUMBER: printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet)); break; + case SM_EVENT_PASSKEY_INPUT_NUMBER: + printf("Passkey Input requested\n"); + printf("Sending fixed passkey %"PRIu32"\n", FIXED_PASSKEY); + sm_passkey_input(sm_event_passkey_input_number_get_handle(packet), FIXED_PASSKEY); + break; case SM_EVENT_PAIRING_COMPLETE: switch (sm_event_pairing_complete_get_status(packet)){ case ERROR_CODE_SUCCESS: @@ -200,17 +242,6 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe break; } break; - case HCI_EVENT_LE_META: - // wait for connection complete - if (hci_event_le_meta_get_subevent_code(packet) != HCI_SUBEVENT_LE_CONNECTION_COMPLETE) break; - con_handle = hci_subevent_le_connection_complete_get_connection_handle(packet); - // start pairing - sm_request_pairing(con_handle); - break; - case HCI_EVENT_ENCRYPTION_CHANGE: - con_handle = hci_event_encryption_change_get_connection_handle(packet); - printf("Connection encrypted: %u\n", hci_event_encryption_change_get_encryption_enabled(packet)); - break; default: break; }