static void printUUID(uint8_t * uuid128, uint16_t uuid16){ if (uuid16){ printf("%04x",uuid16); } else { printf("%s", uuid128_to_str(uuid128)); } }
static void handle_gatt_client_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(packet_type); UNUSED(channel); UNUSED(size); gatt_client_service_t service; gatt_client_characteristic_t characteristic; switch(hci_event_packet_get_type(packet)){ case GATT_EVENT_SERVICE_QUERY_RESULT:\ gatt_event_service_query_result_get_service(packet, &service); dump_service(&service); services[service_count++] = service; break; case GATT_EVENT_CHARACTERISTIC_QUERY_RESULT: gatt_event_characteristic_query_result_get_characteristic(packet, &characteristic); dump_characteristic(&characteristic); break; case GATT_EVENT_QUERY_COMPLETE: if (search_services){ // GATT_EVENT_QUERY_COMPLETE of search services service_index = 0; printf("\nGATT browser - CHARACTERISTIC for SERVICE %s\n", uuid128_to_str(service.uuid128)); search_services = 0; gatt_client_discover_characteristics_for_service(handle_gatt_client_event, connection_handler, &services[service_index]); } else { // GATT_EVENT_QUERY_COMPLETE of search characteristics if (service_index < service_count) { service = services[service_index++]; printf("\nGATT browser - CHARACTERISTIC for SERVICE %s, [0x%04x-0x%04x]\n", uuid128_to_str(service.uuid128), service.start_group_handle, service.end_group_handle); gatt_client_discover_characteristics_for_service(handle_gatt_client_event, connection_handler, &service); break; } service_index = 0; gap_disconnect(connection_handler); } break; default: break; } }
void att_dump_attributes(void){ att_iterator_t it; att_iterator_init(&it); uint8_t uuid128[16]; while (att_iterator_has_next(&it)){ att_iterator_fetch_next(&it); if (it.handle == 0) { log_info("Handle: END"); return; } log_info("Handle: 0x%04x, flags: 0x%04x, uuid: ", it.handle, it.flags); if (it.flags & ATT_PROPERTY_UUID128){ swap128(it.uuid, uuid128); log_info("%s", uuid128_to_str(uuid128)); } else { log_info("%04x", READ_BT_16(it.uuid, 0)); } log_info(", value_len: %u, value: ", it.value_len); hexdump(it.value, it.value_len); } }
/* LISTING_START(GAPLEAdvDataParsing): Parsing advertising data */ static void dump_advertisement_data(const 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, (uint8_t *)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); const 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 ", little_endian_read_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("%04"PRIX32, little_endian_read_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 reverse_128(data, uuid_128); printf("%s", uuid128_to_str(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", little_endian_read_16(data, 0) * 5/4, little_endian_read_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 reverse_bd_addr(data, address); printf("%s", bd_addr_to_str(address)); break; case 0x19: // Appearance // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml printf("%02X", little_endian_read_16(data, 0) ); break; case 0x1A: // Advertising Interval printf("%u ms", little_endian_read_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"); }