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__ "pb_adv.c" 39 40 #include "pb_adv.h" 41 42 #include <stdint.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 47 #include "btstack_debug.h" 48 #include "btstack_event.h" 49 #include "btstack_util.h" 50 51 #include "mesh/adv_bearer.h" 52 #include "mesh/beacon.h" 53 #include "mesh/mesh_node.h" 54 #include "mesh/provisioning.h" 55 56 #define PB_ADV_LINK_OPEN_RETRANSMIT_MS 1000 57 58 static void pb_adv_run(void); 59 60 /* taps: 32 31 29 1; characteristic polynomial: x^32 + x^31 + x^29 + x + 1 */ 61 #define LFSR(a) ((a >> 1) ^ (uint32_t)((0 - (a & 1u)) & 0xd0000001u)) 62 63 // PB-ADV - Provisioning Bearer using Advertisement Bearer 64 65 #define MESH_GENERIC_PROVISIONING_LINK_OPEN 0x00 66 #define MESH_GENERIC_PROVISIONING_LINK_ACK 0x01 67 #define MESH_GENERIC_PROVISIONING_LINK_CLOSE 0x02 68 69 #define MESH_GENERIC_PROVISIONING_TRANSACTION_TIMEOUT_MS 30000 70 71 #define MESH_PB_ADV_MAX_PDU_SIZE 100 72 #define MESH_PB_ADV_MAX_SEGMENTS 8 73 #define MESH_PB_ADV_START_PAYLOAD 20 74 #define MESH_PB_ADV_CONT_PAYLOAD 23 75 76 typedef enum mesh_gpcf_format { 77 MESH_GPCF_TRANSACTION_START = 0, 78 MESH_GPCF_TRANSACTION_ACK, 79 MESH_GPCF_TRANSACTION_CONT, 80 MESH_GPCF_PROV_BEARER_CONTROL, 81 } mesh_gpcf_format_t; 82 83 typedef enum { 84 LINK_STATE_W4_OPEN, 85 LINK_STATE_W2_SEND_ACK, 86 LINK_STATE_W4_ACK, 87 LINK_STATE_OPEN, 88 LINK_STATE_CLOSING, 89 } link_state_t; 90 static link_state_t link_state; 91 92 #ifdef ENABLE_MESH_PROVISIONER 93 static const uint8_t * pb_adv_peer_device_uuid; 94 #endif 95 96 static uint8_t pb_adv_msg_in_buffer[MESH_PB_ADV_MAX_PDU_SIZE]; // TODO: how large are prov messages? 97 98 // single adv link 99 static uint16_t pb_adv_cid = 1; 100 static uint8_t pb_adv_provisioner_role; 101 102 // link state 103 static uint32_t pb_adv_link_id; 104 static uint8_t pb_adv_link_close_reason; 105 static uint8_t pb_adv_link_close_countdown; 106 107 // random delay for outgoing packets 108 static uint32_t pb_adv_lfsr; 109 static uint8_t pb_adv_random_delay_active; 110 static btstack_timer_source_t pb_adv_random_delay_timer; 111 112 // incoming message 113 static uint8_t pb_adv_msg_in_transaction_nr_prev; 114 static uint16_t pb_adv_msg_in_len; // 115 static uint8_t pb_adv_msg_in_fcs; 116 static uint8_t pb_adv_msg_in_last_segment; 117 static uint8_t pb_adv_msg_in_segments_missing; // bitfield for segmentes 1-n 118 static uint8_t pb_adv_msg_in_transaction_nr; 119 static uint8_t pb_adv_msg_in_send_ack; 120 121 // oputgoing message 122 static uint8_t pb_adv_msg_out_active; 123 static uint8_t pb_adv_msg_out_transaction_nr; 124 static uint8_t pb_adv_msg_out_completed_transaction_nr; 125 static uint16_t pb_adv_msg_out_len; 126 static uint16_t pb_adv_msg_out_pos; 127 static uint8_t pb_adv_msg_out_seg; 128 static uint32_t pb_adv_msg_out_start; 129 static const uint8_t * pb_adv_msg_out_buffer; 130 131 static btstack_packet_handler_t pb_adv_packet_handler; 132 133 // poor man's random number generator 134 static uint32_t pb_adv_random(void){ 135 pb_adv_lfsr = LFSR(pb_adv_lfsr); 136 return pb_adv_lfsr; 137 } 138 139 static void pb_adv_emit_pdu_sent(uint8_t status){ 140 uint8_t event[] = { HCI_EVENT_MESH_META, 2, MESH_SUBEVENT_PB_TRANSPORT_PDU_SENT, status}; 141 pb_adv_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event)); 142 } 143 144 static void pb_adv_emit_link_open(uint8_t status, uint16_t pb_transport_cid){ 145 uint8_t event[7] = { HCI_EVENT_MESH_META, 5, MESH_SUBEVENT_PB_TRANSPORT_LINK_OPEN, status}; 146 little_endian_store_16(event, 4, pb_transport_cid); 147 event[6] = MESH_PB_TYPE_ADV; 148 pb_adv_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event)); 149 } 150 151 static void pb_adv_emit_link_close(uint16_t pb_transport_cid, uint8_t reason){ 152 uint8_t event[6] = { HCI_EVENT_MESH_META, 3, MESH_SUBEVENT_PB_TRANSPORT_LINK_CLOSED}; 153 little_endian_store_16(event, 3, pb_transport_cid); 154 event[5] = reason; 155 pb_adv_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event)); 156 } 157 158 static void pb_adv_handle_bearer_control(uint32_t link_id, uint8_t transaction_nr, const uint8_t * pdu, uint16_t size){ 159 UNUSED(transaction_nr); 160 UNUSED(size); 161 162 uint8_t bearer_opcode = pdu[0] >> 2; 163 uint8_t reason; 164 const uint8_t * own_device_uuid; 165 switch (bearer_opcode){ 166 case MESH_GENERIC_PROVISIONING_LINK_OPEN: // Open a session on a bearer with a device 167 // does it match our device_uuid? 168 own_device_uuid = mesh_node_get_device_uuid(); 169 if (!own_device_uuid) break; 170 if (memcmp(&pdu[1], own_device_uuid, 16) != 0) break; 171 switch(link_state){ 172 case LINK_STATE_W4_OPEN: 173 pb_adv_link_id = link_id; 174 pb_adv_provisioner_role = 0; 175 pb_adv_msg_in_transaction_nr = 0xff; // first transaction nr will be 0x00 176 pb_adv_msg_in_transaction_nr_prev = 0xff; 177 log_info("link open, id %08x", pb_adv_link_id); 178 printf("PB-ADV: Link Open %08x\n", pb_adv_link_id); 179 link_state = LINK_STATE_W2_SEND_ACK; 180 adv_bearer_request_can_send_now_for_provisioning_pdu(); 181 pb_adv_emit_link_open(0, pb_adv_cid); 182 break; 183 case LINK_STATE_OPEN: 184 if (pb_adv_link_id != link_id) break; 185 log_info("link open, resend ACK"); 186 link_state = LINK_STATE_W2_SEND_ACK; 187 adv_bearer_request_can_send_now_for_provisioning_pdu(); 188 break; 189 default: 190 break; 191 } 192 break; 193 #ifdef ENABLE_MESH_PROVISIONER 194 case MESH_GENERIC_PROVISIONING_LINK_ACK: // Acknowledge a session on a bearer 195 if (link_state != LINK_STATE_W4_ACK) break; 196 link_state = LINK_STATE_OPEN; 197 pb_adv_msg_out_transaction_nr = 0; 198 pb_adv_msg_in_transaction_nr = 0x7f; // first transaction nr will be 0x80 199 pb_adv_msg_in_transaction_nr_prev = 0x7f; 200 btstack_run_loop_remove_timer(&pb_adv_random_delay_timer); 201 log_info("link open, id %08x", pb_adv_link_id); 202 printf("PB-ADV: Link Open %08x\n", pb_adv_link_id); 203 pb_adv_emit_link_open(0, pb_adv_cid); 204 break; 205 #endif 206 case MESH_GENERIC_PROVISIONING_LINK_CLOSE: // Close a session on a bearer 207 // does it match link id 208 if (link_id != pb_adv_link_id) break; 209 if (link_state == LINK_STATE_W4_OPEN) break; 210 reason = pdu[1]; 211 link_state = LINK_STATE_W4_OPEN; 212 log_info("link close, reason %x", reason); 213 pb_adv_emit_link_close(pb_adv_cid, reason); 214 break; 215 default: 216 log_info("BearerOpcode %x reserved for future use\n", bearer_opcode); 217 break; 218 } 219 } 220 221 static void pb_adv_pdu_complete(void){ 222 223 // Verify FCS 224 uint8_t pdu_crc = btstack_crc8_calc((uint8_t*)pb_adv_msg_in_buffer, pb_adv_msg_in_len); 225 if (pdu_crc != pb_adv_msg_in_fcs){ 226 printf("Incoming PDU: fcs %02x, calculated %02x -> drop packet\n", pb_adv_msg_in_fcs, btstack_crc8_calc(pb_adv_msg_in_buffer, pb_adv_msg_in_len)); 227 return; 228 } 229 230 printf("PB-ADV: %02x complete\n", pb_adv_msg_in_transaction_nr); 231 232 // transaction complete 233 pb_adv_msg_in_transaction_nr_prev = pb_adv_msg_in_transaction_nr; 234 if (pb_adv_provisioner_role){ 235 pb_adv_msg_in_transaction_nr = 0x7f; // invalid 236 } else { 237 pb_adv_msg_in_transaction_nr = 0xff; // invalid 238 } 239 240 // Ack Transaction 241 pb_adv_msg_in_send_ack = 1; 242 pb_adv_run(); 243 244 // Forward to Provisioning 245 pb_adv_packet_handler(PROVISIONING_DATA_PACKET, 0, pb_adv_msg_in_buffer, pb_adv_msg_in_len); 246 } 247 248 static void pb_adv_handle_transaction_start(uint8_t transaction_nr, const uint8_t * pdu, uint16_t size){ 249 250 // resend ack if packet from previous transaction received 251 if (transaction_nr != 0xff && transaction_nr == pb_adv_msg_in_transaction_nr_prev){ 252 printf("PB_ADV: %02x transaction complete, resending ack \n", transaction_nr); 253 pb_adv_msg_in_send_ack = 1; 254 return; 255 } 256 257 // new transaction? 258 if (transaction_nr != pb_adv_msg_in_transaction_nr){ 259 260 // check len 261 uint16_t msg_len = big_endian_read_16(pdu, 1); 262 if (msg_len > MESH_PB_ADV_MAX_PDU_SIZE){ 263 // abort transaction 264 return; 265 } 266 267 // check num segments 268 uint8_t last_segment = pdu[0] >> 2; 269 if (last_segment >= MESH_PB_ADV_MAX_SEGMENTS){ 270 // abort transaction 271 return; 272 } 273 274 printf("PB-ADV: %02x started\n", transaction_nr); 275 276 pb_adv_msg_in_transaction_nr = transaction_nr; 277 pb_adv_msg_in_len = msg_len; 278 pb_adv_msg_in_fcs = pdu[3]; 279 pb_adv_msg_in_last_segment = last_segment; 280 281 // set bits for segments 1..n (segment 0 already received in this message) 282 pb_adv_msg_in_segments_missing = (1 << last_segment) - 1; 283 284 // store payload 285 uint16_t payload_len = size - 4; 286 (void)memcpy(pb_adv_msg_in_buffer, &pdu[4], payload_len); 287 288 // complete? 289 if (pb_adv_msg_in_segments_missing == 0){ 290 pb_adv_pdu_complete(); 291 } 292 } 293 } 294 295 static void pb_adv_handle_transaction_cont(uint8_t transaction_nr, const uint8_t * pdu, uint16_t size){ 296 297 // check transaction nr 298 if (transaction_nr != 0xff && transaction_nr == pb_adv_msg_in_transaction_nr_prev){ 299 printf("PB_ADV: %02x transaction complete, resending resending ack\n", transaction_nr); 300 pb_adv_msg_in_send_ack = 1; 301 return; 302 } 303 304 if (transaction_nr != pb_adv_msg_in_transaction_nr){ 305 printf("PB-ADV: %02x received msg for transaction nr %x\n", pb_adv_msg_in_transaction_nr, transaction_nr); 306 return; 307 } 308 309 // validate seg nr 310 uint8_t seg = pdu[0] >> 2; 311 if (seg >= MESH_PB_ADV_MAX_SEGMENTS || seg == 0){ 312 return; 313 } 314 315 // check if segment already received 316 uint8_t seg_mask = 1 << (seg-1); 317 if ((pb_adv_msg_in_segments_missing & seg_mask) == 0){ 318 printf("PB-ADV: %02x, segment %u already received\n", transaction_nr, seg); 319 return; 320 } 321 printf("PB-ADV: %02x, segment %u stored\n", transaction_nr, seg); 322 323 // calculate offset and fragment size 324 uint16_t msg_pos = MESH_PB_ADV_START_PAYLOAD + (seg-1) * MESH_PB_ADV_CONT_PAYLOAD; 325 uint16_t fragment_size = size - 1; 326 327 // check size if last segment 328 if (seg == pb_adv_msg_in_last_segment && (msg_pos + fragment_size) != pb_adv_msg_in_len){ 329 // last segment has invalid size 330 return; 331 } 332 333 // store segment and mark as received 334 (void)memcpy(&pb_adv_msg_in_buffer[msg_pos], &pdu[1], fragment_size); 335 pb_adv_msg_in_segments_missing &= ~seg_mask; 336 337 // last segment 338 if (pb_adv_msg_in_segments_missing == 0){ 339 pb_adv_pdu_complete(); 340 } 341 } 342 343 static void pb_adv_outgoing_transation_complete(uint8_t status){ 344 // stop sending 345 pb_adv_msg_out_active = 0; 346 // emit done 347 pb_adv_emit_pdu_sent(status); 348 // keep track of ack'ed transactions 349 pb_adv_msg_out_completed_transaction_nr = pb_adv_msg_out_transaction_nr; 350 // increment outgoing transaction nr 351 pb_adv_msg_out_transaction_nr++; 352 if (pb_adv_msg_out_transaction_nr == 0x00){ 353 // Device role 354 pb_adv_msg_out_transaction_nr = 0x80; 355 } 356 if (pb_adv_msg_out_transaction_nr == 0x80){ 357 // Provisioner role 358 pb_adv_msg_out_transaction_nr = 0x00; 359 } 360 } 361 362 static void pb_adv_handle_transaction_ack(uint8_t transaction_nr, const uint8_t * pdu, uint16_t size){ 363 UNUSED(pdu); 364 UNUSED(size); 365 if (transaction_nr == pb_adv_msg_out_transaction_nr){ 366 printf("PB-ADV: %02x ACK received\n", transaction_nr); 367 pb_adv_outgoing_transation_complete(ERROR_CODE_SUCCESS); 368 } else if (transaction_nr == pb_adv_msg_out_completed_transaction_nr){ 369 // Transaction ack received again 370 } else { 371 printf("PB-ADV: %02x unexpected Transaction ACK %x recevied\n", pb_adv_msg_out_transaction_nr, transaction_nr); 372 } 373 } 374 375 static int pb_adv_packet_to_send(void){ 376 return pb_adv_msg_in_send_ack || pb_adv_msg_out_active || (link_state == LINK_STATE_W4_ACK); 377 } 378 379 static void pb_adv_timer_handler(btstack_timer_source_t * ts){ 380 UNUSED(ts); 381 pb_adv_random_delay_active = 0; 382 if (!pb_adv_packet_to_send()) return; 383 adv_bearer_request_can_send_now_for_provisioning_pdu(); 384 } 385 386 static void pb_adv_run(void){ 387 if (!pb_adv_packet_to_send()) return; 388 if (pb_adv_random_delay_active) return; 389 390 // spec recommends 20-50 ms, we use 20-51 ms 391 pb_adv_random_delay_active = 1; 392 uint16_t random_delay_ms = 20 + (pb_adv_random() & 0x1f); 393 log_info("random delay %u ms", random_delay_ms); 394 btstack_run_loop_set_timer_handler(&pb_adv_random_delay_timer, &pb_adv_timer_handler); 395 btstack_run_loop_set_timer(&pb_adv_random_delay_timer, random_delay_ms); 396 btstack_run_loop_add_timer(&pb_adv_random_delay_timer); 397 } 398 399 static void pb_adv_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 400 UNUSED(channel); 401 402 if (packet_type != HCI_EVENT_PACKET) return; 403 const uint8_t * data; 404 uint8_t length; 405 uint32_t link_id; 406 uint8_t transaction_nr; 407 uint8_t generic_provisioning_control; 408 switch(packet[0]){ 409 case GAP_EVENT_ADVERTISING_REPORT: 410 // data starts at offset 12 411 data = &packet[12]; 412 // PDB ADV PDU 413 length = data[0]; 414 415 // validate length field 416 if ((12 + length) > size) return; 417 418 link_id = big_endian_read_32(data, 2); 419 transaction_nr = data[6]; 420 // generic provision PDU 421 generic_provisioning_control = data[7]; 422 mesh_gpcf_format_t generic_provisioning_control_format = (mesh_gpcf_format_t) generic_provisioning_control & 3; 423 424 // unless, we're waiting for LINK_OPEN, check link_id 425 if (link_state != LINK_STATE_W4_OPEN){ 426 if (link_id != pb_adv_link_id) break; 427 } 428 429 if (generic_provisioning_control_format == MESH_GPCF_PROV_BEARER_CONTROL){ 430 pb_adv_handle_bearer_control(link_id, transaction_nr, &data[7], length-6); 431 break; 432 } 433 434 // verify link id and link state 435 if (link_state != LINK_STATE_OPEN) break; 436 437 switch (generic_provisioning_control_format){ 438 case MESH_GPCF_TRANSACTION_START: 439 pb_adv_handle_transaction_start(transaction_nr, &data[7], length-6); 440 break; 441 case MESH_GPCF_TRANSACTION_CONT: 442 pb_adv_handle_transaction_cont(transaction_nr, &data[7], length-6); 443 break; 444 case MESH_GPCF_TRANSACTION_ACK: 445 pb_adv_handle_transaction_ack(transaction_nr, &data[7], length-6); 446 break; 447 default: 448 break; 449 } 450 pb_adv_run(); 451 break; 452 case HCI_EVENT_MESH_META: 453 switch(packet[2]){ 454 case MESH_SUBEVENT_CAN_SEND_NOW: 455 #ifdef ENABLE_MESH_PROVISIONER 456 if (link_state == LINK_STATE_W4_ACK){ 457 // build packet 458 uint8_t buffer[22]; 459 big_endian_store_32(buffer, 0, pb_adv_link_id); 460 buffer[4] = 0; // Transaction ID = 0 461 buffer[5] = (0 << 2) | 3; // Link Open | Provisioning Bearer Control 462 (void)memcpy(&buffer[6], pb_adv_peer_device_uuid, 16); 463 adv_bearer_send_provisioning_pdu(buffer, sizeof(buffer)); 464 log_info("link open %08x", pb_adv_link_id); 465 printf("PB-ADV: Sending Link Open for device uuid: "); 466 printf_hexdump(pb_adv_peer_device_uuid, 16); 467 btstack_run_loop_set_timer_handler(&pb_adv_random_delay_timer, &pb_adv_timer_handler); 468 btstack_run_loop_set_timer(&pb_adv_random_delay_timer, PB_ADV_LINK_OPEN_RETRANSMIT_MS); 469 btstack_run_loop_add_timer(&pb_adv_random_delay_timer); 470 break; 471 } 472 #endif 473 if (link_state == LINK_STATE_CLOSING){ 474 log_info("link close %08x", pb_adv_link_id); 475 printf("PB-ADV: Sending Link Close\n"); 476 // build packet 477 uint8_t buffer[7]; 478 big_endian_store_32(buffer, 0, pb_adv_link_id); 479 buffer[4] = 0; // Transaction ID = 0 480 buffer[5] = (2 << 2) | 3; // Link Close | Provisioning Bearer Control 481 buffer[6] = pb_adv_link_close_reason; 482 adv_bearer_send_provisioning_pdu(buffer, sizeof(buffer)); 483 pb_adv_link_close_countdown--; 484 if (pb_adv_link_close_countdown) { 485 adv_bearer_request_can_send_now_for_provisioning_pdu(); 486 } else { 487 link_state = LINK_STATE_W4_OPEN; 488 } 489 break; 490 } 491 if (link_state == LINK_STATE_W2_SEND_ACK){ 492 link_state = LINK_STATE_OPEN; 493 pb_adv_msg_out_transaction_nr = 0x80; 494 // build packet 495 uint8_t buffer[6]; 496 big_endian_store_32(buffer, 0, pb_adv_link_id); 497 buffer[4] = 0; 498 buffer[5] = (1 << 2) | 3; // Link Ack | Provisioning Bearer Control 499 adv_bearer_send_provisioning_pdu(buffer, sizeof(buffer)); 500 log_info("link ack %08x", pb_adv_link_id); 501 printf("PB-ADV: Sending Link Open Ack\n"); 502 break; 503 } 504 if (pb_adv_msg_in_send_ack){ 505 pb_adv_msg_in_send_ack = 0; 506 uint8_t buffer[6]; 507 big_endian_store_32(buffer, 0, pb_adv_link_id); 508 buffer[4] = pb_adv_msg_in_transaction_nr_prev; 509 buffer[5] = MESH_GPCF_TRANSACTION_ACK; 510 adv_bearer_send_provisioning_pdu(buffer, sizeof(buffer)); 511 log_info("transaction ack %08x", pb_adv_link_id); 512 printf("PB-ADV: %02x sending ACK\n", pb_adv_msg_in_transaction_nr_prev); 513 pb_adv_run(); 514 break; 515 } 516 if (pb_adv_msg_out_active){ 517 518 // check timeout for outgoing message 519 // since uint32_t is used and time now must be greater than pb_adv_msg_out_start, 520 // this claculation is correct even when the run loop time overruns 521 uint32_t transaction_time_ms = btstack_run_loop_get_time_ms() - pb_adv_msg_out_start; 522 if (transaction_time_ms >= MESH_GENERIC_PROVISIONING_TRANSACTION_TIMEOUT_MS){ 523 pb_adv_outgoing_transation_complete(ERROR_CODE_CONNECTION_TIMEOUT); 524 return; 525 } 526 527 uint8_t buffer[29]; // ADV MTU 528 big_endian_store_32(buffer, 0, pb_adv_link_id); 529 buffer[4] = pb_adv_msg_out_transaction_nr; 530 uint16_t bytes_left; 531 uint16_t pos; 532 if (pb_adv_msg_out_pos == 0){ 533 // Transaction start 534 int seg_n = pb_adv_msg_out_len / 24; 535 pb_adv_msg_out_seg = 0; 536 buffer[5] = seg_n << 2 | MESH_GPCF_TRANSACTION_START; 537 big_endian_store_16(buffer, 6, pb_adv_msg_out_len); 538 buffer[8] = btstack_crc8_calc((uint8_t*)pb_adv_msg_out_buffer, pb_adv_msg_out_len); 539 pos = 9; 540 bytes_left = 24 - 4; 541 printf("PB-ADV: %02x Sending Start: ", pb_adv_msg_out_transaction_nr); 542 } else { 543 // Transaction continue 544 buffer[5] = pb_adv_msg_out_seg << 2 | MESH_GPCF_TRANSACTION_CONT; 545 pos = 6; 546 bytes_left = 24 - 1; 547 printf("PB-ADV: %02x Sending Cont: ", pb_adv_msg_out_transaction_nr); 548 } 549 pb_adv_msg_out_seg++; 550 uint16_t bytes_to_copy = btstack_min(bytes_left, pb_adv_msg_out_len - pb_adv_msg_out_pos); 551 (void)memcpy(&buffer[pos], 552 &pb_adv_msg_out_buffer[pb_adv_msg_out_pos], 553 bytes_to_copy); 554 pos += bytes_to_copy; 555 printf("bytes %02u, pos %02u, len %02u: ", bytes_to_copy, pb_adv_msg_out_pos, pb_adv_msg_out_len); 556 printf_hexdump(buffer, pos); 557 pb_adv_msg_out_pos += bytes_to_copy; 558 559 if (pb_adv_msg_out_pos == pb_adv_msg_out_len){ 560 // done 561 pb_adv_msg_out_pos = 0; 562 } 563 adv_bearer_send_provisioning_pdu(buffer, pos); 564 pb_adv_run(); 565 break; 566 } 567 break; 568 default: 569 break; 570 } 571 default: 572 break; 573 } 574 } 575 576 void pb_adv_init(void){ 577 adv_bearer_register_for_provisioning_pdu(&pb_adv_handler); 578 pb_adv_lfsr = 0x12345678; 579 pb_adv_random(); 580 } 581 582 void pb_adv_register_packet_handler(btstack_packet_handler_t packet_handler){ 583 pb_adv_packet_handler = packet_handler; 584 } 585 586 void pb_adv_send_pdu(uint16_t pb_transport_cid, const uint8_t * pdu, uint16_t size){ 587 UNUSED(pb_transport_cid); 588 printf("PB-ADV: Send packet "); 589 printf_hexdump(pdu, size); 590 pb_adv_msg_out_buffer = pdu; 591 pb_adv_msg_out_len = size; 592 pb_adv_msg_out_pos = 0; 593 pb_adv_msg_out_start = btstack_run_loop_get_time_ms(); 594 pb_adv_msg_out_active = 1; 595 pb_adv_run(); 596 } 597 598 /** 599 * Close Link 600 * @param pb_transport_cid 601 */ 602 void pb_adv_close_link(uint16_t pb_transport_cid, uint8_t reason){ 603 switch (link_state){ 604 case LINK_STATE_W4_ACK: 605 case LINK_STATE_OPEN: 606 case LINK_STATE_W2_SEND_ACK: 607 pb_adv_emit_link_close(pb_transport_cid, 0); 608 link_state = LINK_STATE_CLOSING; 609 pb_adv_link_close_countdown = 3; 610 pb_adv_link_close_reason = reason; 611 adv_bearer_request_can_send_now_for_provisioning_pdu(); 612 break; 613 case LINK_STATE_W4_OPEN: 614 case LINK_STATE_CLOSING: 615 // nothing to do 616 break; 617 } 618 } 619 620 #ifdef ENABLE_MESH_PROVISIONER 621 uint16_t pb_adv_create_link(const uint8_t * device_uuid){ 622 if (link_state != LINK_STATE_W4_OPEN) return 0; 623 624 pb_adv_peer_device_uuid = device_uuid; 625 pb_adv_provisioner_role = 1; 626 627 // create new 32-bit link id 628 pb_adv_link_id = pb_adv_random(); 629 630 // after sending OPEN, we wait for an ACK 631 link_state = LINK_STATE_W4_ACK; 632 633 // request outgoing 634 adv_bearer_request_can_send_now_for_provisioning_pdu(); 635 636 // dummy pb_adv_cid 637 return pb_adv_cid; 638 } 639 #endif 640 641