1 /* 2 * Copyright (C) 2014 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "mesh_pts.c" 39 40 #include <stdint.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <mesh/mesh_iv_index_seq_number.h> 45 46 #include "btstack.h" 47 #include "mesh_pts.h" 48 49 // general 50 static void show_usage(void); 51 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 52 static void mesh_pts_dump_mesh_options(void); 53 54 #define MESH_BLUEKITCHEN_MODEL_ID_TEST_SERVER 0x0000u 55 56 static btstack_packet_callback_registration_t hci_event_callback_registration; 57 static int provisioned; 58 59 static mesh_model_t mesh_vendor_model; 60 61 static mesh_model_t mesh_generic_on_off_server_model; 62 static mesh_generic_on_off_state_t mesh_generic_on_off_state; 63 static mesh_publication_model_t generic_on_off_server_publication; 64 65 static mesh_model_t mesh_generic_level_server_model; 66 static mesh_generic_level_state_t mesh_generic_level_state; 67 static mesh_publication_model_t generic_level_server_publication; 68 69 static mesh_model_t mesh_configuration_client_model; 70 71 static char gap_name_buffer[30]; 72 static char gap_name_prefix[] = "Mesh "; 73 74 // pts add-on 75 #define PTS_DEFAULT_TTL 10 76 77 static int pts_type; 78 79 static mesh_virtual_address_t * pts_virtual_addresss; 80 81 static uint16_t test_destination = 0x0001; 82 83 const char * pts_device_uuid_string = "001BDC0810210B0E0A0C000B0E0A0C00"; 84 85 static uint8_t prov_static_oob_data[16]; 86 static const char * prov_static_oob_string = "00000000000000000102030405060708"; 87 88 static uint8_t prov_public_key_data[64]; 89 static const char * prov_public_key_string = "F465E43FF23D3F1B9DC7DFC04DA8758184DBC966204796ECCF0D6CF5E16500CC0201D048BCBBD899EEEFC424164E33C201C2B010CA6B4D43A8A155CAD8ECB279"; 90 static uint8_t prov_private_key_data[32]; 91 static const char * prov_private_key_string = "529AA0670D72CD6497502ED473502B037E8803B5C60829A5A3CAA219505530BA"; 92 93 // pin entry (pts) 94 static int ui_chars_for_pin; 95 static uint8_t ui_pin[17]; 96 static int ui_pin_offset; 97 98 99 static mesh_health_fault_t health_fault; 100 101 static void mesh_provisioning_dump(const mesh_provisioning_data_t * data){ 102 mesh_network_key_t * key = data->network_key; 103 printf("UnicastAddr: 0x%02x\n", data->unicast_address); 104 printf("DevKey: "); printf_hexdump(data->device_key, 16); 105 printf("IV Index: 0x%08x\n", data->iv_index); 106 printf("Flags: 0x%02x\n", data->flags); 107 printf("NetKey: "); printf_hexdump(key->net_key, 16); 108 printf("-- Derived from NetKey --\n"); 109 printf("NID: 0x%02x\n", key->nid); 110 printf("NetworkID: "); printf_hexdump(key->network_id, 8); 111 printf("BeaconKey: "); printf_hexdump(key->beacon_key, 16); 112 printf("EncryptionKey: "); printf_hexdump(key->encryption_key, 16); 113 printf("PrivacyKey: "); printf_hexdump(key->privacy_key, 16); 114 printf("IdentityKey: "); printf_hexdump(key->identity_key, 16); 115 } 116 117 118 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 119 UNUSED(channel); 120 UNUSED(size); 121 bd_addr_t addr; 122 int i; 123 124 switch (packet_type) { 125 case HCI_EVENT_PACKET: 126 switch (hci_event_packet_get_type(packet)) { 127 case BTSTACK_EVENT_STATE: 128 if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) break; 129 // dump bd_addr in pts format 130 gap_local_bd_addr(addr); 131 printf("Local addr: %s - ", bd_addr_to_str(addr)); 132 for (i=0;i<6;i++) { 133 printf("%02x", addr[i]); 134 } 135 printf("\n"); 136 137 // setup gap name 138 strcpy(gap_name_buffer, gap_name_prefix); 139 strcat(gap_name_buffer, bd_addr_to_str(addr)); 140 141 // stop publication for testing 142 mesh_model_publication_stop(mesh_node_get_health_server()); 143 144 // dump PTS MeshOptions.ini 145 mesh_pts_dump_mesh_options(); 146 break; 147 default: 148 break; 149 } 150 break; 151 } 152 } 153 154 static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 155 UNUSED(packet_type); 156 UNUSED(channel); 157 UNUSED(size); 158 159 mesh_provisioning_data_t provisioning_data; 160 161 switch(packet[0]){ 162 case HCI_EVENT_MESH_META: 163 switch(packet[2]){ 164 case MESH_SUBEVENT_PB_TRANSPORT_LINK_OPEN: 165 switch (mesh_subevent_pb_transport_link_open_get_status(packet)){ 166 case ERROR_CODE_SUCCESS: 167 printf("Provisioner link opened\n"); 168 break; 169 default: 170 printf("Provisioner link open failed, status 0x%02x\n", mesh_subevent_pb_transport_link_open_get_status(packet)); 171 break; 172 } 173 break; 174 case MESH_SUBEVENT_PB_TRANSPORT_LINK_CLOSED: 175 printf("Provisioner link close"); 176 break; 177 #ifdef ENABLE_MESH_PROVISIONER 178 case MESH_SUBEVENT_PB_PROV_CAPABILITIES: 179 printf("Provisioner, select authentication method\n"); 180 provisioning_provisioner_select_authentication_method(1, 0, 0, 0, 0, 0); 181 break; 182 #endif 183 case MESH_SUBEVENT_ATTENTION_TIMER: 184 printf("Attention Timer: %u\n", mesh_subevent_attention_timer_get_attention_time(packet)); 185 break; 186 case MESH_SUBEVENT_PB_PROV_INPUT_OOB_REQUEST: 187 printf("Enter passphrase: "); 188 fflush(stdout); 189 ui_chars_for_pin = 1; 190 ui_pin_offset = 0; 191 break; 192 case MESH_SUBEVENT_PB_PROV_COMPLETE: 193 printf("Provisioning complete\n"); 194 // dump provisioning data 195 provisioning_device_data_get(&provisioning_data); 196 mesh_provisioning_dump(&provisioning_data); 197 provisioned = 1; 198 break; 199 default: 200 break; 201 } 202 break; 203 default: 204 break; 205 } 206 } 207 208 static void mesh_state_update_message_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 209 UNUSED(channel); 210 UNUSED(size); 211 212 if (packet_type != HCI_EVENT_PACKET) return; 213 214 switch(packet[0]){ 215 case HCI_EVENT_MESH_META: 216 switch(packet[2]){ 217 case MESH_SUBEVENT_STATE_UPDATE_BOOL: 218 printf("State update: model identifier 0x%08x, state identifier 0x%08x, reason %u, state %u\n", 219 mesh_subevent_state_update_bool_get_model_identifier(packet), 220 mesh_subevent_state_update_bool_get_state_identifier(packet), 221 mesh_subevent_state_update_bool_get_reason(packet), 222 mesh_subevent_state_update_bool_get_value(packet)); 223 break; 224 default: 225 printf("mesh_state_update_message_handler: event not parsed"); 226 break; 227 } 228 break; 229 default: 230 break; 231 } 232 } 233 234 static void mesh_configuration_message_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 235 UNUSED(channel); 236 UNUSED(size); 237 238 if (packet_type != HCI_EVENT_PACKET) return; 239 240 switch(packet[0]){ 241 case HCI_EVENT_MESH_META: 242 switch(packet[2]){ 243 default: 244 printf("mesh_configuration_message_handler: event not parsed"); 245 break; 246 } 247 break; 248 default: 249 break; 250 } 251 } 252 // PTS 253 254 static void printf_hex(const uint8_t * data, uint16_t len){ 255 while (len){ 256 printf("%02x", *data); 257 data++; 258 len--; 259 } 260 printf("\n"); 261 } 262 263 static void mesh_pts_dump_mesh_options(void){ 264 printf("\nMeshOptions.ini - into 'My Decoders' of Bluetooth Protocol Viewer\n"); 265 266 printf("[mesh]\n"); 267 268 printf("{IVindex}\n"); 269 printf("%08x\n", mesh_get_iv_index()); 270 271 mesh_network_key_t * network_key = mesh_network_key_list_get(0); 272 if (network_key){ 273 printf("{NetKey}\n"); 274 printf_hex(network_key->net_key, 16); 275 } 276 277 mesh_transport_key_t * transport_key = mesh_transport_key_get(0); 278 if (transport_key){ 279 printf("{AppKey}\n"); 280 printf_hex(transport_key->key, 16); 281 } 282 283 mesh_transport_key_t * device_key = mesh_transport_key_get(MESH_DEVICE_KEY_INDEX); 284 if (device_key){ 285 printf("{DevKey}\n"); 286 printf_hex(device_key->key, 16); 287 } 288 printf("\n"); 289 } 290 291 static void mesh_unprovisioned_beacon_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 292 UNUSED(channel); 293 UNUSED(size); 294 295 if (packet_type != MESH_BEACON_PACKET) return; 296 static uint8_t device_uuid[16]; 297 uint16_t oob; 298 memcpy(device_uuid, &packet[1], 16); 299 oob = big_endian_read_16(packet, 17); 300 printf("received unprovisioned device beacon, oob data %x, device uuid: ", oob); 301 printf_hexdump(device_uuid, 16); 302 provisioning_provisioner_start_provisioning(device_uuid); 303 } 304 305 static int scan_hex_byte(const char * byte_string){ 306 int upper_nibble = nibble_for_char(*byte_string++); 307 if (upper_nibble < 0) return -1; 308 int lower_nibble = nibble_for_char(*byte_string); 309 if (lower_nibble < 0) return -1; 310 return (upper_nibble << 4) | lower_nibble; 311 } 312 313 static int btstack_parse_hex(const char * string, uint16_t len, uint8_t * buffer){ 314 int i; 315 for (i = 0; i < len; i++) { 316 int single_byte = scan_hex_byte(string); 317 if (single_byte < 0) return 0; 318 string += 2; 319 buffer[i] = (uint8_t)single_byte; 320 // don't check seperator after last byte 321 if (i == len - 1) { 322 return 1; 323 } 324 // optional seperator 325 char separator = *string; 326 if (separator == ':' && separator == '-' && separator == ' ') { 327 string++; 328 } 329 } 330 return 1; 331 } 332 333 static void btstack_print_hex(const uint8_t * data, uint16_t len, char separator){ 334 int i; 335 for (i=0;i<len;i++){ 336 printf("%02x", data[i]); 337 if (separator){ 338 printf("%c", separator); 339 } 340 } 341 printf("\n"); 342 } 343 344 static void send_pts_network_messsage(uint16_t dst_addr, uint8_t ttl){ 345 uint8_t access_pdu_data[16]; 346 347 printf("Send Network message dst %04x, ttl %u\n", dst_addr, ttl); 348 349 int access_pdu_len = 1; 350 memset(access_pdu_data, 0x55, access_pdu_len); 351 uint16_t netkey_index = 0; 352 uint16_t appkey_index = MESH_DEVICE_KEY_INDEX; 353 uint16_t src = mesh_node_get_primary_element_address(); 354 355 // send as unsegmented access pdu 356 mesh_upper_transport_builder_t builder; 357 mesh_upper_transport_message_init(&builder, MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS); 358 mesh_upper_transport_message_add_data(&builder, access_pdu_data, access_pdu_len); 359 mesh_pdu_t * pdu = (mesh_pdu_t *) mesh_upper_transport_message_finalize(&builder); 360 int status = mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dst_addr, 0); 361 if (status) return; 362 mesh_access_send_unacknowledged_pdu(pdu); 363 } 364 365 static void send_pts_unsegmented_access_messsage(uint16_t dst_addr, uint8_t ttl){ 366 367 printf("Send Unsegmented Access message dst %04x, ttl %u\n", dst_addr, ttl); 368 369 // load_pts_app_key(); 370 371 uint8_t access_pdu_data[16]; 372 uint16_t src = mesh_node_get_primary_element_address(); 373 374 int access_pdu_len = 1; 375 memset(access_pdu_data, 0x55, access_pdu_len); 376 uint16_t netkey_index = 0; 377 uint16_t appkey_index = 0; // MESH_DEVICE_KEY_INDEX; 378 379 // send as unsegmented access pdu 380 mesh_upper_transport_builder_t builder; 381 mesh_upper_transport_message_init(&builder, MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS); 382 mesh_upper_transport_message_add_data(&builder, access_pdu_data, access_pdu_len); 383 mesh_pdu_t * pdu = (mesh_pdu_t *) mesh_upper_transport_message_finalize(&builder); 384 int status = mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dst_addr, 0); 385 if (status) return; 386 mesh_access_send_unacknowledged_pdu(pdu); 387 } 388 389 static void send_pts_segmented_access_messsage_unicast(uint16_t dst_addr, uint8_t ttl){ 390 391 printf("Send Segmented Access message dst %04x, ttl %u\n", dst_addr, ttl); 392 393 // load_pts_app_key(); 394 395 uint8_t access_pdu_data[20]; 396 397 uint16_t src = mesh_node_get_primary_element_address(); 398 399 int access_pdu_len = 20; 400 memset(access_pdu_data, 0x55, access_pdu_len); 401 uint16_t netkey_index = 0; 402 uint16_t appkey_index = 0; // MESH_DEVICE_KEY_INDEX; 403 404 // send as segmented access pdu 405 mesh_upper_transport_builder_t builder; 406 mesh_upper_transport_message_init(&builder, MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS); 407 mesh_upper_transport_message_add_data(&builder, access_pdu_data, access_pdu_len); 408 mesh_pdu_t * pdu = (mesh_pdu_t *) mesh_upper_transport_message_finalize(&builder); 409 int status = mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dst_addr, 0); 410 if (status) return; 411 mesh_access_send_unacknowledged_pdu(pdu); 412 } 413 414 static void show_usage(void){ 415 bd_addr_t iut_address; 416 gap_local_bd_addr(iut_address); 417 printf("\n--- Bluetooth Mesh Console at %s ---\n", bd_addr_to_str(iut_address)); 418 printf("Destination: %04x\n", test_destination); 419 printf("\n"); 420 printf("0 - Destination: Unicast\n"); 421 printf("1 - Destination: Virtual 9779\n"); 422 printf("2 - Destination: Group D000\n"); 423 printf("3 - Destination: All Proxies FFFC\n"); 424 printf("4 - Destination: All Friends FFFD\n"); 425 printf("5 - Destination: All Relays FFFE\n"); 426 printf("6 - Destination: Nodes FFFF\n"); 427 428 printf("7 - Send Network Message\n"); 429 printf("8 - Send Unsegmented Access Message\n"); 430 printf("9 - Send Segmented Access Message\n"); 431 432 printf("? - Clear Replay Protection List\n"); 433 printf("? - Load PTS App key\n"); 434 printf("R - Delete provisioning data\n"); 435 printf("p - Enable Public Key OOB \n"); 436 printf("o - Enable Output OOB \n"); 437 printf("i - Input Output OOB \n"); 438 printf("s - Static Output OOB \n"); 439 printf("b - Set Secure Network Beacon %s\n", mesh_foundation_beacon_get() ? "Off" : "On"); 440 #ifdef ENABLE_MESH_PROXY_SERVER 441 printf("n - Start Advertising with Node Identity\n"); 442 printf("N - Stop Advertising with Node Identity\n"); 443 #endif 444 printf("g - Generic ON/OFF Server Toggle Value\n"); 445 printf("f - Register Battery Low warning\n"); 446 printf("\n"); 447 } 448 449 static void stdin_process(char cmd){ 450 if (ui_chars_for_pin){ 451 printf("%c", cmd); 452 fflush(stdout); 453 if (cmd == '\n'){ 454 printf("\nSending Pin '%s'\n", ui_pin); 455 provisioning_device_input_oob_complete_alphanumeric(1, ui_pin, ui_pin_offset); 456 ui_chars_for_pin = 0; 457 } else { 458 ui_pin[ui_pin_offset++] = cmd; 459 } 460 return; 461 } 462 463 uint8_t ttl; 464 switch (pts_type){ 465 case 0: 466 ttl = 0; 467 break; 468 case 1: 469 ttl = PTS_DEFAULT_TTL; 470 break; 471 default: 472 ttl = 0x7f; 473 break; 474 } 475 476 switch (cmd){ 477 case '0': 478 test_destination = 0x0001; 479 break; 480 case '1': 481 test_destination = pts_virtual_addresss->pseudo_dst; 482 break; 483 case '2': 484 test_destination = 0xd000; 485 break; 486 case '3': 487 test_destination = MESH_ADDRESS_ALL_PROXIES; 488 break; 489 case '4': 490 test_destination = MESH_ADDRESS_ALL_FRIENDS; 491 break; 492 case '5': 493 test_destination = MESH_ADDRESS_ALL_RELAYS; 494 break; 495 case '6': 496 test_destination = MESH_ADDRESS_ALL_NODES; 497 break; 498 case '7': 499 send_pts_network_messsage(test_destination, ttl); 500 pts_type++; 501 break; 502 case '8': 503 send_pts_unsegmented_access_messsage(test_destination, ttl); 504 pts_type++; 505 break; 506 case '9': 507 send_pts_segmented_access_messsage_unicast(test_destination, ttl); 508 pts_type++; 509 break; 510 511 case 'R': 512 mesh_node_reset(); 513 printf("Mesh Node Reset!\n"); 514 #ifdef ENABLE_MESH_PROXY_SERVER 515 mesh_proxy_start_advertising_unprovisioned_device(); 516 #endif 517 break; 518 case 'p': 519 printf("+ Public Key OOB Enabled\n"); 520 btstack_parse_hex(prov_public_key_string, 64, prov_public_key_data); 521 btstack_parse_hex(prov_private_key_string, 32, prov_private_key_data); 522 provisioning_device_set_public_key_oob(prov_public_key_data, prov_private_key_data); 523 break; 524 case 'o': 525 printf("+ Output OOB Enabled\n"); 526 provisioning_device_set_output_oob_actions(0x08, 0x08); 527 break; 528 case 'i': 529 printf("+ Input OOB Enabled\n"); 530 provisioning_device_set_input_oob_actions(0x08, 0x08); 531 break; 532 case 's': 533 printf("+ Static OOB Enabled\n"); 534 btstack_parse_hex(prov_static_oob_string, 16, prov_static_oob_data); 535 provisioning_device_set_static_oob(16, prov_static_oob_data); 536 break; 537 case 'g': 538 printf("Generic ON/OFF Server Toggle Value\n"); 539 mesh_generic_on_off_server_set(&mesh_generic_on_off_server_model, 1-mesh_generic_on_off_server_get(&mesh_generic_on_off_server_model), 0, 0); 540 break; 541 case 'b': 542 printf("Turn Secure Network Beacon %s\n", mesh_foundation_beacon_get() ? "Off" : "On"); 543 mesh_foundation_beacon_set(1 - mesh_foundation_beacon_get()); 544 mesh_foundation_state_store(); 545 break; 546 #ifdef ENABLE_MESH_PROXY_SERVER 547 case 'n': 548 printf("Start Advertising with Node ID\n"); 549 mesh_proxy_start_advertising_with_node_id(); 550 break; 551 case 'N': 552 printf("Stop Advertising with Node ID\n"); 553 mesh_proxy_start_advertising_with_node_id(); 554 break; 555 #endif 556 case 'f': 557 // 0x01 = Battery Low 558 mesh_health_server_set_fault(mesh_node_get_health_server(), BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, 1); 559 case ' ': 560 show_usage(); 561 break; 562 default: 563 printf("Command: '%c' not implemented\n", cmd); 564 show_usage(); 565 break; 566 } 567 } 568 569 static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ 570 UNUSED(connection_handle); 571 if (att_handle == ATT_CHARACTERISTIC_GAP_DEVICE_NAME_01_VALUE_HANDLE){ 572 return att_read_callback_handle_blob((const uint8_t *)gap_name_buffer, strlen(gap_name_buffer), offset, buffer, buffer_size); 573 } 574 return 0; 575 } 576 577 static void pts_lower_transport_callback_handler(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu){ 578 switch (callback_type){ 579 case MESH_NETWORK_PDU_RECEIVED: 580 printf("PTS: network pdu received. TTL %02x CTL %02x SRC %04x DST %04x\n", 581 mesh_network_ttl(network_pdu), mesh_network_control(network_pdu), 582 mesh_network_src(network_pdu), mesh_network_dst(network_pdu)); 583 printf("PTS: payload "); 584 printf_hexdump(mesh_network_pdu_data(network_pdu), mesh_network_pdu_len(network_pdu)); 585 break; 586 case MESH_NETWORK_PDU_SENT: 587 break; 588 default: 589 break; 590 } 591 // forward to mesh_transport 592 mesh_lower_transport_received_message(callback_type, network_pdu); 593 } 594 595 int btstack_main(void); 596 int btstack_main(void) 597 { 598 // console 599 btstack_stdin_setup(stdin_process); 600 601 // crypto 602 btstack_crypto_init(); 603 604 // l2cap 605 l2cap_init(); 606 607 // setup le device db 608 le_device_db_init(); 609 610 // setup ATT server 611 att_server_init(profile_data, &att_read_callback, NULL); 612 613 // 614 sm_init(); 615 616 617 // mesh 618 mesh_init(); 619 620 // setup connectable advertisments 621 bd_addr_t null_addr; 622 memset(null_addr, 0, 6); 623 uint8_t adv_type = 0; // AFV_IND 624 uint16_t adv_int_min = 0x0030; 625 uint16_t adv_int_max = 0x0030; 626 adv_bearer_advertisements_set_params(adv_int_min, adv_int_max, adv_type, 0, null_addr, 0x07, 0x00); 627 628 // Provisioning in device role 629 mesh_register_provisioning_device_packet_handler(&mesh_provisioning_message_handler); 630 631 // Loc - bottom - https://www.bluetooth.com/specifications/assigned-numbers/gatt-namespace-descriptors 632 mesh_node_set_element_location(mesh_node_get_primary_element(), 0x103); 633 634 // Setup node info 635 mesh_node_set_info(BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, 0, 0); 636 637 // setup health server 638 mesh_health_server_add_fault_state(mesh_node_get_health_server(), BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, &health_fault); 639 640 // Setup Generic On/Off model 641 mesh_generic_on_off_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_GENERIC_ON_OFF_SERVER); 642 mesh_generic_on_off_server_model.operations = mesh_generic_on_off_server_get_operations(); 643 mesh_generic_on_off_server_model.model_data = (void *) &mesh_generic_on_off_state; 644 mesh_generic_on_off_server_register_packet_handler(&mesh_generic_on_off_server_model, &mesh_state_update_message_handler); 645 mesh_generic_on_off_server_set_publication_model(&mesh_generic_on_off_server_model, &generic_on_off_server_publication); 646 mesh_element_add_model(mesh_node_get_primary_element(), &mesh_generic_on_off_server_model); 647 648 // Setup Generic On/Off model 649 mesh_generic_level_server_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_GENERIC_LEVEL_SERVER); 650 mesh_generic_level_server_model.operations = mesh_generic_level_server_get_operations(); 651 mesh_generic_level_server_model.model_data = (void *) &mesh_generic_level_state; 652 mesh_generic_level_server_register_packet_handler(&mesh_generic_level_server_model, &mesh_state_update_message_handler); 653 mesh_generic_level_server_set_publication_model(&mesh_generic_level_server_model, &generic_level_server_publication); 654 mesh_element_add_model(mesh_node_get_primary_element(), &mesh_generic_level_server_model); 655 656 // Setup our custom model 657 mesh_vendor_model.model_identifier = mesh_model_get_model_identifier(BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, MESH_BLUEKITCHEN_MODEL_ID_TEST_SERVER); 658 mesh_element_add_model(mesh_node_get_primary_element(), &mesh_vendor_model); 659 660 // Setup Configuration Client model 661 mesh_configuration_client_model.model_identifier = mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_GENERIC_LEVEL_SERVER); 662 mesh_configuration_client_register_packet_handler(&mesh_configuration_client_model, &mesh_configuration_message_handler); 663 mesh_element_add_model(mesh_node_get_primary_element(), &mesh_configuration_client_model); 664 665 // Enable PROXY 666 mesh_foundation_gatt_proxy_set(1); 667 668 // register for HCI events 669 hci_event_callback_registration.callback = &packet_handler; 670 hci_add_event_handler(&hci_event_callback_registration); 671 672 #if defined(ENABLE_MESH_ADV_BEARER) 673 // setup scanning when supporting ADV Bearer 674 gap_set_scan_parameters(0, 0x300, 0x300); 675 gap_start_scan(); 676 #endif 677 678 // intercept messages between network and lower layer 679 mesh_network_set_higher_layer_handler(&pts_lower_transport_callback_handler); 680 681 // PTS add-on 682 683 #ifdef ENABLE_MESH_ADV_BEARER 684 // Register for Unprovisioned Device Beacons provisioner 685 beacon_register_for_unprovisioned_device_beacons(&mesh_unprovisioned_beacon_handler); 686 #endif 687 688 // Set PTS Device UUID 689 uint8_t pts_device_uuid[16]; 690 btstack_parse_hex(pts_device_uuid_string, 16, pts_device_uuid); 691 mesh_node_set_device_uuid(pts_device_uuid); 692 btstack_print_hex(pts_device_uuid, 16, 0); 693 694 // PTS Virtual Address Label UUID - without Config Model, PTS uses our device uuid 695 uint8_t label_uuid[16]; 696 btstack_parse_hex("001BDC0810210B0E0A0C000B0E0A0C00", 16, label_uuid); 697 pts_virtual_addresss = mesh_virtual_address_register(label_uuid, 0x9779); 698 699 printf("TSPX_iut_model_id 0x1000 (Generic OnOff Server)\n"); 700 printf("TSPX_vendor_model_id 0x%08x\n", mesh_vendor_model.model_identifier); 701 // turn on! 702 hci_power_control(HCI_POWER_ON); 703 704 return 0; 705 } 706 /* EXAMPLE_END */ 707