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_upper_transport.c" 39 40 #include "mesh/mesh_upper_transport.h" 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 46 #include "btstack_util.h" 47 #include "btstack_memory.h" 48 #include "btstack_debug.h" 49 50 #include "mesh/beacon.h" 51 #include "mesh/mesh_iv_index_seq_number.h" 52 #include "mesh/mesh_keys.h" 53 #include "mesh/mesh_lower_transport.h" 54 #include "mesh/mesh_peer.h" 55 #include "mesh/mesh_virtual_addresses.h" 56 57 // TODO: extract mesh_pdu functions into lower transport or network 58 #include "mesh/mesh_access.h" 59 60 // combined key x address iterator for upper transport decryption 61 62 typedef struct { 63 // state 64 mesh_transport_key_iterator_t key_it; 65 mesh_virtual_address_iterator_t address_it; 66 // elements 67 const mesh_transport_key_t * key; 68 const mesh_virtual_address_t * address; 69 // address - might be virtual 70 uint16_t dst; 71 // key info 72 } mesh_transport_key_and_virtual_address_iterator_t; 73 74 static void mesh_upper_transport_validate_segmented_message(void); 75 static void mesh_upper_transport_run(void); 76 77 static int crypto_active; 78 79 static mesh_unsegmented_pdu_t * incoming_unsegmented_pdu_raw; 80 81 static mesh_segmented_pdu_t incoming_message_pdu_singleton; 82 83 static mesh_access_pdu_t * incoming_access_pdu_encrypted; 84 static mesh_access_pdu_t * incoming_access_pdu_decrypted; 85 86 static mesh_access_pdu_t incoming_access_pdu_encrypted_singleton; 87 static mesh_access_pdu_t incoming_access_pdu_decrypted_singleton; 88 89 static mesh_control_pdu_t incoming_control_pdu_singleton; 90 static mesh_control_pdu_t * incoming_control_pdu; 91 92 static mesh_segmented_pdu_t outgoing_segmented_message_singleton; 93 static mesh_access_pdu_t * outgoing_segmented_access_pdu; 94 95 static mesh_unsegmented_pdu_t outgoing_unsegmented_pdu; 96 97 98 static uint8_t application_nonce[13]; 99 static btstack_crypto_ccm_t ccm; 100 static mesh_transport_key_and_virtual_address_iterator_t mesh_transport_key_it; 101 102 // upper transport callbacks - in access layer 103 static void (*mesh_access_message_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu); 104 static void (*mesh_control_message_handler)( mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu); 105 106 // incoming unsegmented (network) and segmented (transport) control and access messages 107 static btstack_linked_list_t upper_transport_incoming; 108 109 // outgoing unsegmented (network) and segmented (uppert_transport_outgoing) control and access messages 110 static btstack_linked_list_t upper_transport_outgoing; 111 112 113 // TODO: higher layer define used for assert 114 #define MESH_ACCESS_OPCODE_NOT_SET 0xFFFFFFFEu 115 116 void mesh_upper_transport_send_access_pdu(mesh_pdu_t *pdu){ 117 switch (pdu->pdu_type){ 118 case MESH_PDU_TYPE_UNSEGMENTED: 119 case MESH_PDU_TYPE_ACCESS: 120 break; 121 default: 122 btstack_assert(false); 123 break; 124 } 125 126 btstack_linked_list_add_tail(&upper_transport_outgoing, (btstack_linked_item_t*) pdu); 127 mesh_upper_transport_run(); 128 } 129 130 void mesh_upper_transport_send_control_pdu(mesh_pdu_t * pdu){ 131 if (pdu->pdu_type == MESH_PDU_TYPE_NETWORK){ 132 btstack_assert( ((mesh_network_pdu_t *) pdu)->len >= 9); 133 } 134 135 btstack_linked_list_add_tail(&upper_transport_outgoing, (btstack_linked_item_t*) pdu); 136 mesh_upper_transport_run(); 137 } 138 139 static void mesh_print_hex(const char * name, const uint8_t * data, uint16_t len){ 140 printf("%-20s ", name); 141 printf_hexdump(data, len); 142 } 143 // static void mesh_print_x(const char * name, uint32_t value){ 144 // printf("%20s: 0x%x", name, (int) value); 145 // } 146 147 static void mesh_transport_key_and_virtual_address_iterator_init(mesh_transport_key_and_virtual_address_iterator_t *it, 148 uint16_t dst, uint16_t netkey_index, uint8_t akf, 149 uint8_t aid) { 150 printf("KEY_INIT: dst %04x, akf %x, aid %x\n", dst, akf, aid); 151 // config 152 it->dst = dst; 153 // init elements 154 it->key = NULL; 155 it->address = NULL; 156 // init element iterators 157 mesh_transport_key_aid_iterator_init(&it->key_it, netkey_index, akf, aid); 158 // init address iterator 159 if (mesh_network_address_virtual(it->dst)){ 160 mesh_virtual_address_iterator_init(&it->address_it, dst); 161 // get first key 162 if (mesh_transport_key_aid_iterator_has_more(&it->key_it)) { 163 it->key = mesh_transport_key_aid_iterator_get_next(&it->key_it); 164 } 165 } 166 } 167 168 // cartesian product: keys x addressses 169 static int mesh_transport_key_and_virtual_address_iterator_has_more(mesh_transport_key_and_virtual_address_iterator_t * it){ 170 if (mesh_network_address_virtual(it->dst)) { 171 // find next valid entry 172 while (true){ 173 if (mesh_virtual_address_iterator_has_more(&it->address_it)) return 1; 174 if (!mesh_transport_key_aid_iterator_has_more(&it->key_it)) return 0; 175 // get next key 176 it->key = mesh_transport_key_aid_iterator_get_next(&it->key_it); 177 mesh_virtual_address_iterator_init(&it->address_it, it->dst); 178 } 179 } else { 180 return mesh_transport_key_aid_iterator_has_more(&it->key_it); 181 } 182 } 183 184 static void mesh_transport_key_and_virtual_address_iterator_next(mesh_transport_key_and_virtual_address_iterator_t * it){ 185 if (mesh_network_address_virtual(it->dst)) { 186 it->address = mesh_virtual_address_iterator_get_next(&it->address_it); 187 } else { 188 it->key = mesh_transport_key_aid_iterator_get_next(&it->key_it); 189 } 190 } 191 192 // UPPER TRANSPORT 193 194 uint16_t mesh_access_dst(mesh_access_pdu_t * access_pdu){ 195 return big_endian_read_16(access_pdu->network_header, 7); 196 } 197 198 uint16_t mesh_access_ctl(mesh_access_pdu_t * access_pdu){ 199 return access_pdu->network_header[1] >> 7; 200 } 201 202 uint32_t mesh_access_seq(mesh_access_pdu_t * access_pdu){ 203 return big_endian_read_24(access_pdu->network_header, 2); 204 } 205 206 void mesh_access_set_nid_ivi(mesh_access_pdu_t * access_pdu, uint8_t nid_ivi){ 207 access_pdu->network_header[0] = nid_ivi; 208 } 209 void mesh_access_set_ctl_ttl(mesh_access_pdu_t * access_pdu, uint8_t ctl_ttl){ 210 access_pdu->network_header[1] = ctl_ttl; 211 } 212 void mesh_access_set_seq(mesh_access_pdu_t * access_pdu, uint32_t seq){ 213 big_endian_store_24(access_pdu->network_header, 2, seq); 214 } 215 void mesh_access_set_src(mesh_access_pdu_t * access_pdu, uint16_t src){ 216 big_endian_store_16(access_pdu->network_header, 5, src); 217 } 218 void mesh_access_set_dest(mesh_access_pdu_t * access_pdu, uint16_t dest){ 219 big_endian_store_16(access_pdu->network_header, 7, dest); 220 } 221 222 // stub lower transport 223 224 static void mesh_upper_transport_dump_pdus(const char *name, btstack_linked_list_t *list){ 225 printf("List: %s:\n", name); 226 btstack_linked_list_iterator_t it; 227 btstack_linked_list_iterator_init(&it, list); 228 while (btstack_linked_list_iterator_has_next(&it)){ 229 mesh_pdu_t * pdu = (mesh_pdu_t*) btstack_linked_list_iterator_next(&it); 230 printf("- %p\n", pdu); 231 // printf_hexdump( mesh_pdu_data(pdu), mesh_pdu_len(pdu)); 232 } 233 } 234 235 static void mesh_upper_transport_reset_pdus(btstack_linked_list_t *list){ 236 while (!btstack_linked_list_empty(list)){ 237 mesh_upper_transport_pdu_free((mesh_pdu_t *) btstack_linked_list_pop(list)); 238 } 239 } 240 241 void mesh_upper_transport_dump(void){ 242 printf("incoming_unsegmented_pdu_raw: %p\n", incoming_unsegmented_pdu_raw); 243 mesh_upper_transport_dump_pdus("upper_transport_incoming", &upper_transport_incoming); 244 } 245 246 void mesh_upper_transport_reset(void){ 247 crypto_active = 0; 248 if (incoming_unsegmented_pdu_raw){ 249 mesh_network_pdu_t * network_pdu = incoming_unsegmented_pdu_raw->segment; 250 btstack_assert(network_pdu != NULL); 251 incoming_unsegmented_pdu_raw->segment = NULL; 252 mesh_network_pdu_free(network_pdu); 253 incoming_unsegmented_pdu_raw = NULL; 254 } 255 outgoing_segmented_access_pdu = NULL; 256 mesh_upper_transport_reset_pdus(&upper_transport_incoming); 257 } 258 259 static uint32_t iv_index_for_ivi_nid(uint8_t ivi_nid){ 260 // get IV Index and IVI 261 uint32_t iv_index = mesh_get_iv_index(); 262 int ivi = ivi_nid >> 7; 263 264 // if least significant bit differs, use previous IV Index 265 if ((iv_index & 1 ) ^ ivi){ 266 iv_index--; 267 } 268 return iv_index; 269 } 270 271 static void transport_unsegmented_setup_nonce(uint8_t * nonce, const mesh_network_pdu_t * network_pdu){ 272 nonce[1] = 0x00; // SZMIC if a Segmented Access message or 0 for all other message formats 273 (void)memcpy(&nonce[2], &network_pdu->data[2], 7); 274 big_endian_store_32(nonce, 9, iv_index_for_ivi_nid(network_pdu->data[0])); 275 } 276 277 static void transport_segmented_setup_nonce(uint8_t * nonce, const mesh_pdu_t * pdu){ 278 mesh_access_pdu_t * access_pdu; 279 switch (pdu->pdu_type){ 280 case MESH_PDU_TYPE_ACCESS: 281 access_pdu = (mesh_access_pdu_t *) pdu; 282 nonce[1] = access_pdu->transmic_len == 8 ? 0x80 : 0x00; 283 (void)memcpy(&nonce[2], &access_pdu->network_header[2], 7); 284 big_endian_store_32(nonce, 9, iv_index_for_ivi_nid(access_pdu->network_header[0])); 285 break; 286 default: 287 btstack_assert(0); 288 break; 289 } 290 } 291 292 static void transport_unsegmented_setup_application_nonce(uint8_t * nonce, const mesh_network_pdu_t * network_pdu){ 293 nonce[0] = 0x01; 294 transport_unsegmented_setup_nonce(nonce, network_pdu); 295 mesh_print_hex("AppNonce", nonce, 13); 296 } 297 298 static void transport_unsegmented_setup_device_nonce(uint8_t * nonce, const mesh_network_pdu_t * network_pdu){ 299 nonce[0] = 0x02; 300 transport_unsegmented_setup_nonce(nonce, network_pdu); 301 mesh_print_hex("DeviceNonce", nonce, 13); 302 } 303 304 static void transport_segmented_setup_application_nonce(uint8_t * nonce, const mesh_pdu_t * pdu){ 305 nonce[0] = 0x01; 306 transport_segmented_setup_nonce(nonce, pdu); 307 mesh_print_hex("AppNonce", nonce, 13); 308 } 309 310 static void transport_segmented_setup_device_nonce(uint8_t * nonce, const mesh_pdu_t * pdu){ 311 nonce[0] = 0x02; 312 transport_segmented_setup_nonce(nonce, pdu); 313 mesh_print_hex("DeviceNonce", nonce, 13); 314 } 315 316 static void mesh_upper_unsegmented_control_message_received(mesh_unsegmented_pdu_t * unsegmented_incoming_pdu){ 317 if (mesh_control_message_handler){ 318 mesh_control_message_handler(MESH_TRANSPORT_PDU_RECEIVED, MESH_TRANSPORT_STATUS_SUCCESS, (mesh_pdu_t*) unsegmented_incoming_pdu); 319 } else { 320 mesh_network_pdu_t * network_pdu =unsegmented_incoming_pdu->segment; 321 uint8_t * lower_transport_pdu = mesh_network_pdu_data(network_pdu); 322 uint8_t opcode = lower_transport_pdu[0]; 323 printf("[!] Unhandled Control message with opcode %02x\n", opcode); 324 // done 325 mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t*) unsegmented_incoming_pdu); 326 } 327 } 328 329 static void mesh_upper_transport_process_message_done(mesh_segmented_pdu_t *message_pdu){ 330 crypto_active = 0; 331 btstack_assert(message_pdu == &incoming_message_pdu_singleton); 332 mesh_network_pdu_t * network_pdu = (mesh_network_pdu_t *) btstack_linked_list_pop(&incoming_message_pdu_singleton.segments); 333 if (mesh_network_control(network_pdu)) { 334 btstack_assert(0); 335 } else { 336 btstack_assert(network_pdu != NULL); 337 mesh_network_pdu_free(network_pdu); 338 mesh_pdu_t * pdu = (mesh_pdu_t *) incoming_unsegmented_pdu_raw; 339 incoming_unsegmented_pdu_raw = NULL; 340 mesh_lower_transport_message_processed_by_higher_layer(pdu); 341 } 342 mesh_upper_transport_run(); 343 } 344 345 static void mesh_upper_transport_process_unsegmented_message_done(mesh_pdu_t * pdu){ 346 btstack_assert(pdu != NULL); 347 btstack_assert(pdu->pdu_type == MESH_PDU_TYPE_UNSEGMENTED); 348 349 mesh_unsegmented_pdu_t * unsegmented_incoming_pdu = (mesh_unsegmented_pdu_t *) pdu; 350 btstack_assert(unsegmented_incoming_pdu == incoming_unsegmented_pdu_raw); 351 352 crypto_active = 0; 353 incoming_unsegmented_pdu_raw = NULL; 354 mesh_network_pdu_t * network_pdu = unsegmented_incoming_pdu->segment; 355 if (!mesh_network_control(network_pdu)) { 356 mesh_network_pdu_free(network_pdu); 357 } 358 359 mesh_lower_transport_message_processed_by_higher_layer(pdu); 360 mesh_upper_transport_run(); 361 } 362 363 static void mesh_upper_transport_process_segmented_access_message_done(mesh_access_pdu_t *access_pdu){ 364 crypto_active = 0; 365 btstack_assert(mesh_access_ctl(access_pdu) == 0); 366 incoming_access_pdu_encrypted = NULL; 367 mesh_upper_transport_run(); 368 } 369 370 static void mesh_upper_transport_validate_segmented_message_ccm(void * arg){ 371 UNUSED(arg); 372 373 uint8_t * upper_transport_pdu = incoming_access_pdu_decrypted->data; 374 uint8_t upper_transport_pdu_len = incoming_access_pdu_decrypted->len - incoming_access_pdu_decrypted->transmic_len; 375 376 mesh_print_hex("Decrypted PDU", upper_transport_pdu, upper_transport_pdu_len); 377 378 // store TransMIC 379 uint8_t trans_mic[8]; 380 btstack_crypto_ccm_get_authentication_value(&ccm, trans_mic); 381 mesh_print_hex("TransMIC", trans_mic, incoming_access_pdu_decrypted->transmic_len); 382 383 if (memcmp(trans_mic, &upper_transport_pdu[upper_transport_pdu_len], incoming_access_pdu_decrypted->transmic_len) == 0){ 384 printf("TransMIC matches\n"); 385 386 // remove TransMIC from payload 387 incoming_access_pdu_decrypted->len -= incoming_access_pdu_decrypted->transmic_len; 388 389 // if virtual address, update dst to pseudo_dst 390 if (mesh_network_address_virtual(mesh_access_dst(incoming_access_pdu_decrypted))){ 391 big_endian_store_16(incoming_access_pdu_decrypted->network_header, 7, mesh_transport_key_it.address->pseudo_dst); 392 } 393 394 // pass to upper layer 395 btstack_assert(mesh_access_message_handler != NULL); 396 mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_access_pdu_decrypted; 397 mesh_access_message_handler(MESH_TRANSPORT_PDU_RECEIVED, MESH_TRANSPORT_STATUS_SUCCESS, pdu); 398 399 printf("\n"); 400 401 } else { 402 uint8_t akf = incoming_access_pdu_decrypted->akf_aid_control & 0x40; 403 if (akf){ 404 printf("TransMIC does not match, try next key\n"); 405 mesh_upper_transport_validate_segmented_message(); 406 } else { 407 printf("TransMIC does not match device key, done\n"); 408 // done 409 mesh_upper_transport_process_segmented_access_message_done(incoming_access_pdu_decrypted); 410 } 411 } 412 } 413 414 static void mesh_upper_transport_validate_segmented_message_digest(void * arg){ 415 UNUSED(arg); 416 uint8_t upper_transport_pdu_len = incoming_access_pdu_encrypted->len - incoming_access_pdu_encrypted->transmic_len; 417 uint8_t * upper_transport_pdu_data_in = incoming_access_pdu_encrypted->data; 418 uint8_t * upper_transport_pdu_data_out = incoming_access_pdu_decrypted->data; 419 btstack_crypto_ccm_decrypt_block(&ccm, upper_transport_pdu_len, upper_transport_pdu_data_in, upper_transport_pdu_data_out, &mesh_upper_transport_validate_segmented_message_ccm, NULL); 420 } 421 422 static void mesh_upper_transport_validate_segmented_message(void){ 423 uint8_t * upper_transport_pdu_data = incoming_access_pdu_decrypted->data; 424 uint8_t upper_transport_pdu_len = incoming_access_pdu_decrypted->len - incoming_access_pdu_decrypted->transmic_len; 425 426 if (!mesh_transport_key_and_virtual_address_iterator_has_more(&mesh_transport_key_it)){ 427 printf("No valid transport key found\n"); 428 mesh_upper_transport_process_segmented_access_message_done(incoming_access_pdu_decrypted); 429 return; 430 } 431 mesh_transport_key_and_virtual_address_iterator_next(&mesh_transport_key_it); 432 const mesh_transport_key_t * message_key = mesh_transport_key_it.key; 433 434 if (message_key->akf){ 435 transport_segmented_setup_application_nonce(application_nonce, (mesh_pdu_t *) incoming_access_pdu_encrypted); 436 } else { 437 transport_segmented_setup_device_nonce(application_nonce, (mesh_pdu_t *) incoming_access_pdu_encrypted); 438 } 439 440 // store application / device key index 441 mesh_print_hex("AppOrDevKey", message_key->key, 16); 442 incoming_access_pdu_decrypted->appkey_index = message_key->appkey_index; 443 444 mesh_print_hex("EncAccessPayload", upper_transport_pdu_data, upper_transport_pdu_len); 445 446 // decrypt ccm 447 crypto_active = 1; 448 uint16_t aad_len = 0; 449 if (mesh_network_address_virtual(mesh_access_dst(incoming_access_pdu_decrypted))){ 450 aad_len = 16; 451 } 452 btstack_crypto_ccm_init(&ccm, message_key->key, application_nonce, upper_transport_pdu_len, aad_len, incoming_access_pdu_decrypted->transmic_len); 453 454 if (aad_len){ 455 btstack_crypto_ccm_digest(&ccm, (uint8_t *) mesh_transport_key_it.address->label_uuid, aad_len, &mesh_upper_transport_validate_segmented_message_digest, NULL); 456 } else { 457 mesh_upper_transport_validate_segmented_message_digest(NULL); 458 } 459 } 460 461 static void mesh_upper_transport_process_segmented_message(void){ 462 // copy original pdu 463 (void)memcpy(incoming_access_pdu_decrypted, incoming_access_pdu_encrypted, 464 sizeof(mesh_access_pdu_t)); 465 466 // 467 uint8_t * upper_transport_pdu = incoming_access_pdu_decrypted->data; 468 uint8_t upper_transport_pdu_len = incoming_access_pdu_decrypted->len - incoming_access_pdu_decrypted->transmic_len; 469 mesh_print_hex("Upper Transport pdu", upper_transport_pdu, upper_transport_pdu_len); 470 471 uint8_t aid = incoming_access_pdu_decrypted->akf_aid_control & 0x3f; 472 uint8_t akf = (incoming_access_pdu_decrypted->akf_aid_control & 0x40) >> 6; 473 474 printf("AKF: %u\n", akf); 475 printf("AID: %02x\n", aid); 476 477 mesh_transport_key_and_virtual_address_iterator_init(&mesh_transport_key_it, mesh_access_dst(incoming_access_pdu_decrypted), 478 incoming_access_pdu_decrypted->netkey_index, akf, aid); 479 mesh_upper_transport_validate_segmented_message(); 480 } 481 482 static void mesh_upper_transport_message_received(mesh_pdu_t * pdu){ 483 btstack_linked_list_add_tail(&upper_transport_incoming, (btstack_linked_item_t*) pdu); 484 mesh_upper_transport_run(); 485 } 486 487 static void mesh_upper_transport_send_unsegmented_access_pdu_ccm(void * arg){ 488 crypto_active = 0; 489 490 mesh_unsegmented_pdu_t * unsegmented_pdu = (mesh_unsegmented_pdu_t *) arg; 491 mesh_network_pdu_t * network_pdu = unsegmented_pdu->segment; 492 493 uint8_t * upper_transport_pdu = mesh_network_pdu_data(network_pdu) + 1; 494 uint8_t upper_transport_pdu_len = mesh_network_pdu_len(network_pdu) - 1; 495 mesh_print_hex("EncAccessPayload", upper_transport_pdu, upper_transport_pdu_len); 496 // store TransMIC 497 btstack_crypto_ccm_get_authentication_value(&ccm, &upper_transport_pdu[upper_transport_pdu_len]); 498 mesh_print_hex("TransMIC", &upper_transport_pdu[upper_transport_pdu_len], 4); 499 network_pdu->len += 4; 500 upper_transport_pdu_len += 4; 501 mesh_print_hex("UpperTransportPDU", upper_transport_pdu, upper_transport_pdu_len); 502 // send network pdu 503 mesh_lower_transport_send_pdu((mesh_pdu_t*) unsegmented_pdu); 504 } 505 506 static void mesh_upper_transport_send_segmented_pdu(mesh_access_pdu_t * access_pdu){ 507 outgoing_segmented_access_pdu = access_pdu; 508 mesh_segmented_pdu_t * message_pdu = &outgoing_segmented_message_singleton; 509 message_pdu->pdu_header.pdu_type = MESH_PDU_TYPE_SEGMENTED; 510 511 // convert mesh_access_pdu_t into mesh_segmented_pdu_t 512 uint16_t message_offset = 0; 513 uint16_t bytes_current_segment = 0; 514 mesh_network_pdu_t * network_pdu = NULL; 515 while (message_offset < access_pdu->len){ 516 if (bytes_current_segment == 0){ 517 network_pdu = mesh_network_pdu_get(); 518 btstack_assert(network_pdu != NULL); 519 btstack_linked_list_add_tail(&message_pdu->segments, (btstack_linked_item_t *) network_pdu); 520 bytes_current_segment = MESH_NETWORK_PAYLOAD_MAX; 521 } 522 uint16_t bytes_to_copy = btstack_max(bytes_current_segment, access_pdu->len - message_offset); 523 (void) memcpy(&network_pdu->data[network_pdu->len], &access_pdu->data[message_offset], bytes_to_copy); 524 bytes_current_segment -= bytes_to_copy; 525 network_pdu->len += bytes_to_copy; 526 message_offset += bytes_to_copy; 527 } 528 // copy meta 529 message_pdu->len = access_pdu->len; 530 message_pdu->netkey_index = access_pdu->netkey_index; 531 message_pdu->transmic_len = access_pdu->transmic_len; 532 message_pdu->akf_aid_control = access_pdu->akf_aid_control; 533 message_pdu->flags = access_pdu->flags; 534 (void)memcpy(message_pdu->network_header, access_pdu->network_header, 9); 535 536 mesh_lower_transport_send_pdu((mesh_pdu_t*) message_pdu); 537 } 538 539 static void mesh_upper_transport_send_segmented_access_pdu_ccm(void * arg){ 540 crypto_active = 0; 541 542 mesh_access_pdu_t * access_pdu = (mesh_access_pdu_t *) arg; 543 mesh_print_hex("EncAccessPayload", access_pdu->data, access_pdu->len); 544 // store TransMIC 545 btstack_crypto_ccm_get_authentication_value(&ccm, &access_pdu->data[access_pdu->len]); 546 mesh_print_hex("TransMIC", &access_pdu->data[access_pdu->len], access_pdu->transmic_len); 547 access_pdu->len += access_pdu->transmic_len; 548 mesh_print_hex("UpperTransportPDU", access_pdu->data, access_pdu->len); 549 mesh_upper_transport_send_segmented_pdu(access_pdu); 550 } 551 552 static uint8_t mesh_upper_transport_setup_unsegmented_control_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode, 553 const uint8_t * control_pdu_data, uint16_t control_pdu_len){ 554 555 if (control_pdu_len > 11) return 1; 556 557 const mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index); 558 if (!network_key) return 1; 559 560 uint8_t transport_pdu_data[12]; 561 transport_pdu_data[0] = opcode; 562 (void)memcpy(&transport_pdu_data[1], control_pdu_data, control_pdu_len); 563 uint16_t transport_pdu_len = control_pdu_len + 1; 564 565 // setup network_pdu 566 mesh_network_setup_pdu(network_pdu, netkey_index, network_key->nid, 1, ttl, 0, src, dest, transport_pdu_data, transport_pdu_len); 567 568 return 0; 569 } 570 571 #if 0 572 static uint8_t mesh_upper_transport_setup_segmented_control_pdu(mesh_transport_pdu_t * transport_pdu, uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode, 573 const uint8_t * control_pdu_data, uint16_t control_pdu_len){ 574 575 if (control_pdu_len > 256) return 1; 576 577 const mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index); 578 if (!network_key) return 1; 579 580 (void)memcpy(transport_pdu->data, control_pdu_data, control_pdu_len); 581 transport_pdu->len = control_pdu_len; 582 transport_pdu->netkey_index = netkey_index; 583 transport_pdu->akf_aid_control = opcode; 584 transport_pdu->transmic_len = 0; // no TransMIC for control 585 mesh_transport_set_nid_ivi(transport_pdu, network_key->nid); 586 mesh_transport_set_src(transport_pdu, src); 587 mesh_transport_set_dest(transport_pdu, dest); 588 mesh_transport_set_ctl_ttl(transport_pdu, 0x80 | ttl); 589 590 return 0; 591 } 592 #endif 593 594 uint8_t mesh_upper_transport_setup_control_pdu(mesh_pdu_t * pdu, uint16_t netkey_index, 595 uint8_t ttl, uint16_t src, uint16_t dest, uint8_t opcode, const uint8_t * control_pdu_data, uint16_t control_pdu_len){ 596 switch (pdu->pdu_type){ 597 case MESH_PDU_TYPE_NETWORK: 598 return mesh_upper_transport_setup_unsegmented_control_pdu((mesh_network_pdu_t *) pdu, netkey_index, ttl, src, dest, opcode, control_pdu_data, control_pdu_len); 599 default: 600 btstack_assert(0); 601 return 1; 602 } 603 } 604 605 static uint8_t mesh_upper_transport_setup_unsegmented_access_pdu_header(mesh_unsegmented_pdu_t * unsegmented_pdu, uint16_t netkey_index, 606 uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest){ 607 608 mesh_network_pdu_t * network_pdu = unsegmented_pdu->segment; 609 610 // get app or device key 611 const mesh_transport_key_t * appkey; 612 appkey = mesh_transport_key_get(appkey_index); 613 if (appkey == NULL){ 614 printf("appkey_index %x unknown\n", appkey_index); 615 return 1; 616 } 617 uint8_t akf_aid = (appkey->akf << 6) | appkey->aid; 618 619 // lookup network by netkey_index 620 const mesh_network_key_t * network_key = mesh_network_key_list_get(netkey_index); 621 if (!network_key) return 1; 622 623 unsegmented_pdu->appkey_index = appkey_index; 624 625 network_pdu->data[9] = akf_aid; 626 // setup network_pdu 627 mesh_network_setup_pdu_header(network_pdu, netkey_index, network_key->nid, 0, ttl, 0, src, dest); 628 return 0; 629 } 630 631 static uint8_t mesh_upper_transport_setup_unsegmented_access_pdu(mesh_unsegmented_pdu_t * unsegmented_pdu, uint16_t netkey_index, uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest, 632 const uint8_t * access_pdu_data, uint8_t access_pdu_len){ 633 634 int status = mesh_upper_transport_setup_unsegmented_access_pdu_header(unsegmented_pdu, netkey_index, appkey_index, ttl, src, dest); 635 if (status) return status; 636 637 // store in unsegmented pdu 638 mesh_network_pdu_t * network_pdu = unsegmented_pdu->segment; 639 (void)memcpy(&network_pdu->data[10], access_pdu_data, access_pdu_len); 640 network_pdu->len = 10 + access_pdu_len; 641 return 0; 642 } 643 644 static uint8_t mesh_upper_transport_setup_segmented_access_pdu_header(mesh_access_pdu_t * access_pdu, uint16_t netkey_index, 645 uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic){ 646 647 // get app or device key 648 const mesh_transport_key_t *appkey; 649 appkey = mesh_transport_key_get(appkey_index); 650 if (appkey == NULL) { 651 printf("[!] Upper transport, setup segmented Access PDU - appkey_index %x unknown\n", appkey_index); 652 return 1; 653 } 654 uint8_t akf_aid = (appkey->akf << 6) | appkey->aid; 655 656 // lookup network by netkey_index 657 const mesh_network_key_t *network_key = mesh_network_key_list_get(netkey_index); 658 if (!network_key) return 1; 659 if (network_key == NULL) { 660 printf("[!] Upper transport, setup segmented Access PDU - netkey_index %x unknown\n", appkey_index); 661 return 1; 662 } 663 664 const uint8_t trans_mic_len = szmic ? 8 : 4; 665 666 // store in transport pdu 667 access_pdu->transmic_len = trans_mic_len; 668 access_pdu->netkey_index = netkey_index; 669 access_pdu->appkey_index = appkey_index; 670 access_pdu->akf_aid_control = akf_aid; 671 mesh_access_set_nid_ivi(access_pdu, network_key->nid | ((mesh_get_iv_index_for_tx() & 1) << 7)); 672 mesh_access_set_src(access_pdu, src); 673 mesh_access_set_dest(access_pdu, dest); 674 mesh_access_set_ctl_ttl(access_pdu, ttl); 675 return 0; 676 } 677 678 679 static uint8_t mesh_upper_transport_setup_segmented_access_pdu(mesh_access_pdu_t * access_pdu, uint16_t netkey_index, uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest, 680 uint8_t szmic, const uint8_t * access_pdu_data, uint8_t access_pdu_len){ 681 int status = mesh_upper_transport_setup_segmented_access_pdu_header(access_pdu, netkey_index, appkey_index, ttl, src, dest, szmic); 682 if (status) return status; 683 684 // store in transport pdu 685 (void)memcpy(access_pdu->data, access_pdu_data, access_pdu_len); 686 access_pdu->len = access_pdu_len; 687 return 0; 688 } 689 uint8_t mesh_upper_transport_setup_access_pdu_header(mesh_pdu_t * pdu, uint16_t netkey_index, uint16_t appkey_index, 690 uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic){ 691 switch (pdu->pdu_type){ 692 case MESH_PDU_TYPE_ACCESS: 693 return mesh_upper_transport_setup_segmented_access_pdu_header((mesh_access_pdu_t *) pdu, netkey_index, appkey_index, ttl, src, dest, szmic); 694 case MESH_PDU_TYPE_UNSEGMENTED: 695 return mesh_upper_transport_setup_unsegmented_access_pdu_header((mesh_unsegmented_pdu_t *) pdu, netkey_index, appkey_index, ttl, src, dest); 696 default: 697 btstack_assert(false); 698 return 1; 699 } 700 } 701 702 uint8_t mesh_upper_transport_setup_access_pdu(mesh_pdu_t * pdu, uint16_t netkey_index, uint16_t appkey_index, 703 uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic, 704 const uint8_t * access_pdu_data, uint8_t access_pdu_len){ 705 switch (pdu->pdu_type){ 706 case MESH_PDU_TYPE_UNSEGMENTED: 707 return mesh_upper_transport_setup_unsegmented_access_pdu((mesh_unsegmented_pdu_t *) pdu, netkey_index, appkey_index, ttl, src, dest, access_pdu_data, access_pdu_len); 708 case MESH_PDU_TYPE_ACCESS: 709 return mesh_upper_transport_setup_segmented_access_pdu((mesh_access_pdu_t *) pdu, netkey_index, appkey_index, ttl, src, dest, szmic, access_pdu_data, access_pdu_len); 710 default: 711 btstack_assert(false); 712 return 1; 713 } 714 } 715 716 static void mesh_upper_transport_send_unsegmented_access_pdu_digest(void * arg){ 717 mesh_unsegmented_pdu_t * unsegmented_pdu = (mesh_unsegmented_pdu_t *) arg; 718 mesh_network_pdu_t * network_pdu = unsegmented_pdu->segment; 719 uint8_t * access_pdu_data = mesh_network_pdu_data(network_pdu) + 1; 720 uint16_t access_pdu_len = mesh_network_pdu_len(network_pdu) - 1; 721 btstack_crypto_ccm_encrypt_block(&ccm, access_pdu_len, access_pdu_data, access_pdu_data, &mesh_upper_transport_send_unsegmented_access_pdu_ccm, unsegmented_pdu); 722 } 723 724 static mesh_transport_key_t * mesh_upper_transport_get_outgoing_appkey(uint16_t netkey_index, uint16_t appkey_index){ 725 // Device Key is fixed 726 if (appkey_index == MESH_DEVICE_KEY_INDEX) { 727 return mesh_transport_key_get(appkey_index); 728 } 729 730 // Get key refresh state from subnet 731 mesh_subnet_t * subnet = mesh_subnet_get_by_netkey_index(netkey_index); 732 if (subnet == NULL) return NULL; 733 734 // identify old and new app keys for given appkey_index 735 mesh_transport_key_t * old_key = NULL; 736 mesh_transport_key_t * new_key = NULL; 737 mesh_transport_key_iterator_t it; 738 mesh_transport_key_iterator_init(&it, netkey_index); 739 while (mesh_transport_key_iterator_has_more(&it)){ 740 mesh_transport_key_t * transport_key = mesh_transport_key_iterator_get_next(&it); 741 if (transport_key->appkey_index != appkey_index) continue; 742 if (transport_key->old_key == 0) { 743 new_key = transport_key; 744 } else { 745 old_key = transport_key; 746 } 747 } 748 749 // if no key is marked as old, just use the current one 750 if (old_key == NULL) return new_key; 751 752 // use new key if it exists in phase two 753 if ((subnet->key_refresh == MESH_KEY_REFRESH_SECOND_PHASE) && (new_key != NULL)){ 754 return new_key; 755 } else { 756 return old_key; 757 } 758 } 759 760 static void mesh_upper_transport_send_unsegmented_access_pdu(mesh_unsegmented_pdu_t * unsegmented_pdu){ 761 762 mesh_network_pdu_t * network_pdu = unsegmented_pdu->segment; 763 764 // if dst is virtual address, lookup label uuid and hash 765 uint16_t aad_len = 0; 766 mesh_virtual_address_t * virtual_address = NULL; 767 uint16_t dst = mesh_network_dst(network_pdu); 768 if (mesh_network_address_virtual(dst)){ 769 virtual_address = mesh_virtual_address_for_pseudo_dst(dst); 770 if (!virtual_address){ 771 printf("No virtual address register for pseudo dst %4x\n", dst); 772 btstack_memory_mesh_network_pdu_free(network_pdu); 773 return; 774 } 775 aad_len = 16; 776 big_endian_store_16(network_pdu->data, 7, virtual_address->hash); 777 } 778 779 // reserve slot 780 mesh_lower_transport_reserve_slot(); 781 782 // Nonce for Access Payload based on Network Sequence number: needs to be fixed now and lower layers need to send packet in right order 783 uint32_t seq = mesh_sequence_number_next(); 784 mesh_network_pdu_set_seq(network_pdu, seq); 785 786 // Dump PDU 787 printf("[+] Upper transport, send unsegmented Access PDU - dest %04x, seq %06x\n", dst, mesh_network_seq(network_pdu)); 788 mesh_print_hex("Access Payload", &network_pdu->data[10], network_pdu->len - 10); 789 790 // setup nonce 791 uint16_t appkey_index = unsegmented_pdu->appkey_index; 792 if (appkey_index == MESH_DEVICE_KEY_INDEX){ 793 transport_unsegmented_setup_device_nonce(application_nonce, network_pdu); 794 } else { 795 transport_unsegmented_setup_application_nonce(application_nonce, network_pdu); 796 } 797 798 // get app or device key 799 const mesh_transport_key_t * appkey = mesh_upper_transport_get_outgoing_appkey(network_pdu->netkey_index, appkey_index); 800 mesh_print_hex("AppOrDevKey", appkey->key, 16); 801 802 // encrypt ccm 803 uint8_t trans_mic_len = 4; 804 uint16_t access_pdu_len = mesh_network_pdu_len(network_pdu) - 1; 805 crypto_active = 1; 806 807 btstack_crypto_ccm_init(&ccm, appkey->key, application_nonce, access_pdu_len, aad_len, trans_mic_len); 808 if (virtual_address){ 809 mesh_print_hex("LabelUUID", virtual_address->label_uuid, 16); 810 btstack_crypto_ccm_digest(&ccm, virtual_address->label_uuid, 16, &mesh_upper_transport_send_unsegmented_access_pdu_digest, unsegmented_pdu); 811 } else { 812 mesh_upper_transport_send_unsegmented_access_pdu_digest(unsegmented_pdu); 813 } 814 } 815 816 static void mesh_upper_transport_send_segmented_access_pdu_digest(void *arg){ 817 mesh_access_pdu_t * access_pdu = (mesh_access_pdu_t *) arg; 818 uint16_t access_pdu_len = access_pdu->len; 819 uint8_t * access_pdu_data = access_pdu->data; 820 btstack_crypto_ccm_encrypt_block(&ccm, access_pdu_len,access_pdu_data, access_pdu_data, &mesh_upper_transport_send_segmented_access_pdu_ccm, access_pdu); 821 } 822 823 static void mesh_upper_transport_send_segmented_access_pdu(mesh_access_pdu_t * access_pdu){ 824 825 // if dst is virtual address, lookup label uuid and hash 826 uint16_t aad_len = 0; 827 mesh_virtual_address_t * virtual_address = NULL; 828 uint16_t dst = mesh_access_dst(access_pdu); 829 if (mesh_network_address_virtual(dst)){ 830 virtual_address = mesh_virtual_address_for_pseudo_dst(dst); 831 if (!virtual_address){ 832 printf("No virtual address register for pseudo dst %4x\n", dst); 833 mesh_access_message_handler(MESH_TRANSPORT_PDU_SENT, MESH_TRANSPORT_STATUS_SEND_FAILED, (mesh_pdu_t *) access_pdu); 834 return; 835 } 836 // printf("Using hash %4x with LabelUUID: ", virtual_address->hash); 837 // printf_hexdump(virtual_address->label_uuid, 16); 838 aad_len = 16; 839 big_endian_store_16(access_pdu->network_header, 7, virtual_address->hash); 840 } 841 842 // get app or device key 843 uint16_t appkey_index = access_pdu->appkey_index; 844 const mesh_transport_key_t * appkey = mesh_upper_transport_get_outgoing_appkey(access_pdu->netkey_index, appkey_index); 845 if (appkey == NULL){ 846 printf("AppKey %04x not found, drop message\n", appkey_index); 847 mesh_access_message_handler(MESH_TRANSPORT_PDU_SENT, MESH_TRANSPORT_STATUS_SEND_FAILED, (mesh_pdu_t *) access_pdu); 848 return; 849 } 850 851 // reserve slot 852 mesh_lower_transport_reserve_slot(); 853 854 // reserve one sequence number, which is also used to encrypt access payload 855 uint32_t seq = mesh_sequence_number_next(); 856 access_pdu->flags |= MESH_TRANSPORT_FLAG_SEQ_RESERVED; 857 mesh_access_set_seq(access_pdu, seq); 858 859 // Dump PDU 860 printf("[+] Upper transport, send segmented Access PDU - dest %04x, seq %06x\n", dst, mesh_access_seq(access_pdu)); 861 mesh_print_hex("Access Payload", access_pdu->data, access_pdu->len); 862 863 // setup nonce - uses dst, so after pseudo address translation 864 if (appkey_index == MESH_DEVICE_KEY_INDEX){ 865 transport_segmented_setup_device_nonce(application_nonce, (mesh_pdu_t *) access_pdu); 866 } else { 867 transport_segmented_setup_application_nonce(application_nonce, (mesh_pdu_t *) access_pdu); 868 } 869 870 // Dump key 871 mesh_print_hex("AppOrDevKey", appkey->key, 16); 872 873 // encrypt ccm 874 uint8_t transmic_len = access_pdu->transmic_len; 875 uint16_t access_pdu_len = access_pdu->len; 876 crypto_active = 1; 877 btstack_crypto_ccm_init(&ccm, appkey->key, application_nonce, access_pdu_len, aad_len, transmic_len); 878 if (virtual_address){ 879 mesh_print_hex("LabelUUID", virtual_address->label_uuid, 16); 880 btstack_crypto_ccm_digest(&ccm, virtual_address->label_uuid, 16, &mesh_upper_transport_send_segmented_access_pdu_digest, access_pdu); 881 } else { 882 mesh_upper_transport_send_segmented_access_pdu_digest(access_pdu); 883 } 884 } 885 886 static void mesh_upper_transport_send_unsegmented_control_pdu(mesh_network_pdu_t * network_pdu){ 887 // reserve slot 888 mesh_lower_transport_reserve_slot(); 889 // reserve sequence number 890 uint32_t seq = mesh_sequence_number_next(); 891 mesh_network_pdu_set_seq(network_pdu, seq); 892 // Dump PDU 893 uint8_t opcode = network_pdu->data[9]; 894 printf("[+] Upper transport, send unsegmented Control PDU %p - seq %06x opcode %02x\n", network_pdu, seq, opcode); 895 mesh_print_hex("Access Payload", &network_pdu->data[10], network_pdu->len - 10); 896 // wrap into mesh-unsegmented-pdu 897 outgoing_unsegmented_pdu.pdu_header.pdu_type = MESH_PDU_TYPE_UNSEGMENTED; 898 outgoing_unsegmented_pdu.segment = network_pdu; 899 outgoing_unsegmented_pdu.flags = MESH_TRANSPORT_FLAG_CONTROL; 900 901 // send 902 mesh_lower_transport_send_pdu((mesh_pdu_t *) &outgoing_unsegmented_pdu); 903 } 904 905 #if 0 906 static void mesh_upper_transport_send_segmented_control_pdu(mesh_transport_pdu_t * transport_pdu){ 907 // reserve slot 908 mesh_lower_transport_reserve_slot(); 909 // reserve sequence number 910 uint32_t seq = mesh_sequence_number_next(); 911 transport_pdu->flags |= MESH_TRANSPORT_FLAG_SEQ_RESERVED; 912 mesh_transport_set_seq(transport_pdu, seq); 913 // Dump PDU 914 uint8_t opcode = transport_pdu->data[0]; 915 printf("[+] Upper transport, send segmented Control PDU %p - seq %06x opcode %02x\n", transport_pdu, seq, opcode); 916 mesh_print_hex("Access Payload", &transport_pdu->data[1], transport_pdu->len - 1); 917 // send 918 btstack_assert(false); 919 // mesh_upper_transport_send_segmented_pdu(transport_pdu); 920 } 921 #endif 922 923 static void mesh_upper_transport_run(void){ 924 925 while(!btstack_linked_list_empty(&upper_transport_incoming)){ 926 927 if (crypto_active) return; 928 929 // peek at next message 930 mesh_pdu_t * pdu = (mesh_pdu_t *) btstack_linked_list_get_first_item(&upper_transport_incoming); 931 mesh_network_pdu_t * network_pdu; 932 mesh_segmented_pdu_t * message_pdu; 933 mesh_unsegmented_pdu_t * unsegmented_pdu; 934 switch (pdu->pdu_type){ 935 case MESH_PDU_TYPE_UNSEGMENTED: 936 unsegmented_pdu = (mesh_unsegmented_pdu_t *) pdu; 937 network_pdu = unsegmented_pdu->segment; 938 btstack_assert(network_pdu != NULL); 939 // control? 940 if (mesh_network_control(network_pdu)) { 941 incoming_unsegmented_pdu_raw = unsegmented_pdu; 942 (void) btstack_linked_list_pop(&upper_transport_incoming); 943 mesh_upper_unsegmented_control_message_received(unsegmented_pdu); 944 break; 945 } else { 946 947 incoming_access_pdu_encrypted = &incoming_access_pdu_encrypted_singleton; 948 incoming_access_pdu_encrypted->pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS; 949 incoming_access_pdu_decrypted = &incoming_access_pdu_decrypted_singleton; 950 951 incoming_access_pdu_encrypted->netkey_index = network_pdu->netkey_index; 952 incoming_access_pdu_encrypted->transmic_len = 4; 953 954 uint8_t * lower_transport_pdu = mesh_network_pdu_data(network_pdu); 955 956 incoming_access_pdu_encrypted->akf_aid_control = lower_transport_pdu[0]; 957 incoming_access_pdu_encrypted->len = network_pdu->len - 10; // 9 header + 1 AID 958 (void)memcpy(incoming_access_pdu_encrypted->data, &lower_transport_pdu[1], incoming_access_pdu_encrypted->len); 959 960 // copy meta data into encrypted pdu buffer 961 (void)memcpy(incoming_access_pdu_encrypted->network_header, network_pdu->data, 9); 962 963 mesh_print_hex("Assembled payload", incoming_access_pdu_encrypted->data, incoming_access_pdu_encrypted->len); 964 965 // free mesh message 966 mesh_lower_transport_message_processed_by_higher_layer(pdu); 967 968 // get encoded transport pdu and start processing 969 (void) btstack_linked_list_pop(&upper_transport_incoming); 970 mesh_upper_transport_process_segmented_message(); 971 } 972 break; 973 case MESH_PDU_TYPE_SEGMENTED: 974 message_pdu = (mesh_segmented_pdu_t *) pdu; 975 uint8_t ctl = mesh_message_ctl(message_pdu); 976 if (ctl){ 977 incoming_control_pdu= &incoming_control_pdu_singleton; 978 incoming_control_pdu->pdu_header.pdu_type = MESH_PDU_TYPE_CONTROL; 979 980 // assemble payload 981 while (message_pdu->segments){ 982 mesh_network_pdu_t * segment = (mesh_network_pdu_t *) btstack_linked_list_pop(&message_pdu->segments); 983 // get segment n 984 uint8_t * lower_transport_pdu = mesh_network_pdu_data(segment); 985 uint8_t seg_o = ( big_endian_read_16(lower_transport_pdu, 2) >> 5) & 0x001f; 986 uint8_t * segment_data = &lower_transport_pdu[4]; 987 (void)memcpy(&incoming_control_pdu->data[seg_o * 8], segment_data, 8); 988 } 989 990 // copy meta data into encrypted pdu buffer 991 incoming_control_pdu->len = message_pdu->len; 992 incoming_control_pdu->netkey_index = message_pdu->netkey_index; 993 incoming_control_pdu->akf_aid_control = message_pdu->akf_aid_control; 994 incoming_control_pdu->flags = 0; 995 (void)memcpy(incoming_control_pdu->network_header, message_pdu->network_header, 9); 996 997 mesh_print_hex("Assembled payload", incoming_control_pdu->data, incoming_control_pdu->len); 998 999 // free mesh message 1000 mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu); 1001 1002 btstack_assert(mesh_control_message_handler != NULL); 1003 mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_control_pdu; 1004 mesh_access_message_handler(MESH_TRANSPORT_PDU_RECEIVED, MESH_TRANSPORT_STATUS_SUCCESS, pdu); 1005 1006 } else { 1007 1008 incoming_access_pdu_encrypted = &incoming_access_pdu_encrypted_singleton; 1009 incoming_access_pdu_encrypted->pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS; 1010 incoming_access_pdu_decrypted = &incoming_access_pdu_decrypted_singleton; 1011 1012 // flatten segmented message into mesh_access_pdu_t 1013 1014 // assemble payload 1015 while (message_pdu->segments){ 1016 mesh_network_pdu_t * segment = (mesh_network_pdu_t *) btstack_linked_list_pop(&message_pdu->segments); 1017 // get segment n 1018 uint8_t * lower_transport_pdu = mesh_network_pdu_data(segment); 1019 uint8_t seg_o = ( big_endian_read_16(lower_transport_pdu, 2) >> 5) & 0x001f; 1020 uint8_t * segment_data = &lower_transport_pdu[4]; 1021 (void)memcpy(&incoming_access_pdu_encrypted->data[seg_o * 12], segment_data, 12); 1022 } 1023 1024 // copy meta data into encrypted pdu buffer 1025 incoming_access_pdu_encrypted->len = message_pdu->len; 1026 incoming_access_pdu_encrypted->netkey_index = message_pdu->netkey_index; 1027 incoming_access_pdu_encrypted->transmic_len = message_pdu->transmic_len; 1028 incoming_access_pdu_encrypted->akf_aid_control = message_pdu->akf_aid_control; 1029 (void)memcpy(incoming_access_pdu_encrypted->network_header, message_pdu->network_header, 9); 1030 1031 mesh_print_hex("Assembled payload", incoming_access_pdu_encrypted->data, incoming_access_pdu_encrypted->len); 1032 1033 // free mesh message 1034 mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu); 1035 1036 // get encoded transport pdu and start processing 1037 (void) btstack_linked_list_pop(&upper_transport_incoming); 1038 mesh_upper_transport_process_segmented_message(); 1039 } 1040 break; 1041 default: 1042 btstack_assert(0); 1043 break; 1044 } 1045 } 1046 1047 while (!btstack_linked_list_empty(&upper_transport_outgoing)){ 1048 1049 if (crypto_active) break; 1050 1051 if (outgoing_segmented_access_pdu != NULL) break; 1052 1053 mesh_pdu_t * pdu = (mesh_pdu_t *) btstack_linked_list_get_first_item(&upper_transport_outgoing); 1054 if (mesh_lower_transport_can_send_to_dest(mesh_pdu_dst(pdu)) == 0) break; 1055 1056 (void) btstack_linked_list_pop(&upper_transport_outgoing); 1057 1058 mesh_unsegmented_pdu_t * unsegmented_pdu; 1059 1060 switch (pdu->pdu_type){ 1061 case MESH_PDU_TYPE_NETWORK: 1062 btstack_assert(mesh_pdu_ctl(pdu) != 0); 1063 mesh_upper_transport_send_unsegmented_control_pdu((mesh_network_pdu_t *) pdu); 1064 break; 1065 case MESH_PDU_TYPE_UNSEGMENTED: 1066 unsegmented_pdu = ( mesh_unsegmented_pdu_t *) pdu; 1067 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); 1068 mesh_upper_transport_send_unsegmented_access_pdu(unsegmented_pdu); 1069 break; 1070 case MESH_PDU_TYPE_ACCESS: 1071 if (mesh_pdu_ctl(pdu) != 0){ 1072 btstack_assert(false); 1073 } else { 1074 mesh_upper_transport_send_segmented_access_pdu((mesh_access_pdu_t *) pdu); 1075 } 1076 break; 1077 default: 1078 btstack_assert(false); 1079 break; 1080 } 1081 } 1082 } 1083 1084 1085 1086 static void mesh_upper_transport_pdu_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ 1087 mesh_pdu_t * pdu_to_report; 1088 mesh_unsegmented_pdu_t * unsegmented_pdu; 1089 switch (callback_type){ 1090 case MESH_TRANSPORT_PDU_RECEIVED: 1091 mesh_upper_transport_message_received(pdu); 1092 break; 1093 case MESH_TRANSPORT_PDU_SENT: 1094 switch (pdu->pdu_type){ 1095 case MESH_PDU_TYPE_SEGMENTED: 1096 // free chunks 1097 while (!btstack_linked_list_empty(&outgoing_segmented_message_singleton.segments)){ 1098 mesh_network_pdu_t * network_pdu = (mesh_network_pdu_t *) btstack_linked_list_pop(&outgoing_segmented_message_singleton.segments); 1099 mesh_network_pdu_free(network_pdu); 1100 } 1101 // notify upper layer but use transport pdu 1102 pdu_to_report = (mesh_pdu_t *) outgoing_segmented_access_pdu; 1103 outgoing_segmented_access_pdu = NULL; 1104 if (mesh_pdu_ctl(pdu_to_report)){ 1105 mesh_control_message_handler(callback_type, status, pdu_to_report); 1106 } else { 1107 mesh_access_message_handler(callback_type, status, pdu_to_report); 1108 } 1109 break; 1110 case MESH_PDU_TYPE_UNSEGMENTED: 1111 unsegmented_pdu = (mesh_unsegmented_pdu_t *) pdu; 1112 if (unsegmented_pdu == &outgoing_unsegmented_pdu){ 1113 // notify upper layer but use network pdu (control pdu) 1114 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) != 0); 1115 mesh_network_pdu_t * network_pdu = outgoing_unsegmented_pdu.segment; 1116 outgoing_unsegmented_pdu.segment = NULL; 1117 mesh_control_message_handler(callback_type, status, (mesh_pdu_t *) network_pdu); 1118 } else { 1119 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); 1120 mesh_access_message_handler(callback_type, status, pdu); 1121 } 1122 break; 1123 default: 1124 btstack_assert(false); 1125 break; 1126 } 1127 mesh_upper_transport_run(); 1128 break; 1129 default: 1130 break; 1131 } 1132 } 1133 1134 void mesh_upper_transport_pdu_free(mesh_pdu_t * pdu){ 1135 mesh_network_pdu_t * network_pdu; 1136 mesh_segmented_pdu_t * message_pdu; 1137 switch (pdu->pdu_type) { 1138 case MESH_PDU_TYPE_NETWORK: 1139 network_pdu = (mesh_network_pdu_t *) pdu; 1140 mesh_network_pdu_free(network_pdu); 1141 break; 1142 case MESH_PDU_TYPE_SEGMENTED: 1143 message_pdu = (mesh_segmented_pdu_t *) pdu; 1144 mesh_message_pdu_free(message_pdu); 1145 default: 1146 btstack_assert(false); 1147 break; 1148 } 1149 } 1150 1151 void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu){ 1152 crypto_active = 0; 1153 switch (pdu->pdu_type){ 1154 case MESH_PDU_TYPE_ACCESS: 1155 mesh_upper_transport_process_segmented_access_message_done((mesh_access_pdu_t *) pdu); 1156 break; 1157 case MESH_PDU_TYPE_SEGMENTED: 1158 mesh_upper_transport_process_message_done((mesh_segmented_pdu_t *) pdu); 1159 break; 1160 case MESH_PDU_TYPE_UNSEGMENTED: 1161 mesh_upper_transport_process_unsegmented_message_done(pdu); 1162 break; 1163 default: 1164 btstack_assert(0); 1165 break; 1166 } 1167 } 1168 1169 void mesh_upper_transport_register_access_message_handler(void (*callback)(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu)) { 1170 mesh_access_message_handler = callback; 1171 } 1172 1173 void mesh_upper_transport_register_control_message_handler(void (*callback)(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu)){ 1174 mesh_control_message_handler = callback; 1175 } 1176 1177 void mesh_upper_transport_init(){ 1178 mesh_lower_transport_set_higher_layer_handler(&mesh_upper_transport_pdu_handler); 1179 } 1180