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_segmented_pdu_flatten(btstack_linked_list_t * segments, uint8_t segment_len, uint8_t * buffer) { 924 // assemble payload 925 btstack_linked_list_iterator_t it; 926 btstack_linked_list_iterator_init(&it, segments); 927 while (btstack_linked_list_iterator_has_next(&it)) { 928 mesh_network_pdu_t *segment = (mesh_network_pdu_t *) btstack_linked_list_iterator_next(&it); 929 btstack_assert(segment->pdu_header.pdu_type == MESH_PDU_TYPE_NETWORK); 930 // get segment n 931 uint8_t *lower_transport_pdu = mesh_network_pdu_data(segment); 932 uint8_t seg_o = (big_endian_read_16(lower_transport_pdu, 2) >> 5) & 0x001f; 933 uint8_t *segment_data = &lower_transport_pdu[4]; 934 (void) memcpy(&buffer[seg_o * segment_len], segment_data, segment_len); 935 } 936 } 937 938 static void mesh_upper_transport_run(void){ 939 940 while(!btstack_linked_list_empty(&upper_transport_incoming)){ 941 942 if (crypto_active) return; 943 944 // peek at next message 945 mesh_pdu_t * pdu = (mesh_pdu_t *) btstack_linked_list_get_first_item(&upper_transport_incoming); 946 mesh_network_pdu_t * network_pdu; 947 mesh_segmented_pdu_t * message_pdu; 948 mesh_unsegmented_pdu_t * unsegmented_pdu; 949 switch (pdu->pdu_type){ 950 case MESH_PDU_TYPE_UNSEGMENTED: 951 unsegmented_pdu = (mesh_unsegmented_pdu_t *) pdu; 952 network_pdu = unsegmented_pdu->segment; 953 btstack_assert(network_pdu != NULL); 954 // control? 955 if (mesh_network_control(network_pdu)) { 956 incoming_unsegmented_pdu_raw = unsegmented_pdu; 957 (void) btstack_linked_list_pop(&upper_transport_incoming); 958 mesh_upper_unsegmented_control_message_received(unsegmented_pdu); 959 break; 960 } else { 961 962 incoming_access_pdu_encrypted = &incoming_access_pdu_encrypted_singleton; 963 incoming_access_pdu_encrypted->pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS; 964 incoming_access_pdu_decrypted = &incoming_access_pdu_decrypted_singleton; 965 966 incoming_access_pdu_encrypted->netkey_index = network_pdu->netkey_index; 967 incoming_access_pdu_encrypted->transmic_len = 4; 968 969 uint8_t * lower_transport_pdu = mesh_network_pdu_data(network_pdu); 970 971 incoming_access_pdu_encrypted->akf_aid_control = lower_transport_pdu[0]; 972 incoming_access_pdu_encrypted->len = network_pdu->len - 10; // 9 header + 1 AID 973 (void)memcpy(incoming_access_pdu_encrypted->data, &lower_transport_pdu[1], incoming_access_pdu_encrypted->len); 974 975 // copy meta data into encrypted pdu buffer 976 (void)memcpy(incoming_access_pdu_encrypted->network_header, network_pdu->data, 9); 977 978 mesh_print_hex("Assembled payload", incoming_access_pdu_encrypted->data, incoming_access_pdu_encrypted->len); 979 980 // free mesh message 981 mesh_lower_transport_message_processed_by_higher_layer(pdu); 982 983 // get encoded transport pdu and start processing 984 (void) btstack_linked_list_pop(&upper_transport_incoming); 985 mesh_upper_transport_process_segmented_message(); 986 } 987 break; 988 case MESH_PDU_TYPE_SEGMENTED: 989 message_pdu = (mesh_segmented_pdu_t *) pdu; 990 uint8_t ctl = mesh_message_ctl(message_pdu); 991 if (ctl){ 992 incoming_control_pdu= &incoming_control_pdu_singleton; 993 incoming_control_pdu->pdu_header.pdu_type = MESH_PDU_TYPE_CONTROL; 994 995 // flatten 996 mesh_segmented_pdu_flatten(&message_pdu->segments, 8, incoming_control_pdu->data); 997 998 // copy meta data into encrypted pdu buffer 999 incoming_control_pdu->len = message_pdu->len; 1000 incoming_control_pdu->netkey_index = message_pdu->netkey_index; 1001 incoming_control_pdu->akf_aid_control = message_pdu->akf_aid_control; 1002 incoming_control_pdu->flags = 0; 1003 (void)memcpy(incoming_control_pdu->network_header, message_pdu->network_header, 9); 1004 1005 mesh_print_hex("Assembled payload", incoming_control_pdu->data, incoming_control_pdu->len); 1006 1007 // free mesh message 1008 mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu); 1009 1010 btstack_assert(mesh_control_message_handler != NULL); 1011 mesh_pdu_t * pdu = (mesh_pdu_t*) incoming_control_pdu; 1012 mesh_access_message_handler(MESH_TRANSPORT_PDU_RECEIVED, MESH_TRANSPORT_STATUS_SUCCESS, pdu); 1013 1014 } else { 1015 1016 incoming_access_pdu_encrypted = &incoming_access_pdu_encrypted_singleton; 1017 incoming_access_pdu_encrypted->pdu_header.pdu_type = MESH_PDU_TYPE_ACCESS; 1018 incoming_access_pdu_decrypted = &incoming_access_pdu_decrypted_singleton; 1019 1020 // flatten 1021 mesh_segmented_pdu_flatten(&message_pdu->segments, 12, incoming_access_pdu_encrypted->data); 1022 1023 // copy meta data into encrypted pdu buffer 1024 incoming_access_pdu_encrypted->len = message_pdu->len; 1025 incoming_access_pdu_encrypted->netkey_index = message_pdu->netkey_index; 1026 incoming_access_pdu_encrypted->transmic_len = message_pdu->transmic_len; 1027 incoming_access_pdu_encrypted->akf_aid_control = message_pdu->akf_aid_control; 1028 (void)memcpy(incoming_access_pdu_encrypted->network_header, message_pdu->network_header, 9); 1029 1030 mesh_print_hex("Assembled payload", incoming_access_pdu_encrypted->data, incoming_access_pdu_encrypted->len); 1031 1032 // free mesh message 1033 mesh_lower_transport_message_processed_by_higher_layer((mesh_pdu_t *)message_pdu); 1034 1035 // get encoded transport pdu and start processing 1036 (void) btstack_linked_list_pop(&upper_transport_incoming); 1037 mesh_upper_transport_process_segmented_message(); 1038 } 1039 break; 1040 default: 1041 btstack_assert(0); 1042 break; 1043 } 1044 } 1045 1046 while (!btstack_linked_list_empty(&upper_transport_outgoing)){ 1047 1048 if (crypto_active) break; 1049 1050 if (outgoing_segmented_access_pdu != NULL) break; 1051 1052 mesh_pdu_t * pdu = (mesh_pdu_t *) btstack_linked_list_get_first_item(&upper_transport_outgoing); 1053 if (mesh_lower_transport_can_send_to_dest(mesh_pdu_dst(pdu)) == 0) break; 1054 1055 (void) btstack_linked_list_pop(&upper_transport_outgoing); 1056 1057 mesh_unsegmented_pdu_t * unsegmented_pdu; 1058 1059 switch (pdu->pdu_type){ 1060 case MESH_PDU_TYPE_NETWORK: 1061 btstack_assert(mesh_pdu_ctl(pdu) != 0); 1062 mesh_upper_transport_send_unsegmented_control_pdu((mesh_network_pdu_t *) pdu); 1063 break; 1064 case MESH_PDU_TYPE_UNSEGMENTED: 1065 unsegmented_pdu = ( mesh_unsegmented_pdu_t *) pdu; 1066 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); 1067 mesh_upper_transport_send_unsegmented_access_pdu(unsegmented_pdu); 1068 break; 1069 case MESH_PDU_TYPE_ACCESS: 1070 if (mesh_pdu_ctl(pdu) != 0){ 1071 btstack_assert(false); 1072 } else { 1073 mesh_upper_transport_send_segmented_access_pdu((mesh_access_pdu_t *) pdu); 1074 } 1075 break; 1076 default: 1077 btstack_assert(false); 1078 break; 1079 } 1080 } 1081 } 1082 1083 1084 1085 static void mesh_upper_transport_pdu_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){ 1086 mesh_pdu_t * pdu_to_report; 1087 mesh_unsegmented_pdu_t * unsegmented_pdu; 1088 switch (callback_type){ 1089 case MESH_TRANSPORT_PDU_RECEIVED: 1090 mesh_upper_transport_message_received(pdu); 1091 break; 1092 case MESH_TRANSPORT_PDU_SENT: 1093 switch (pdu->pdu_type){ 1094 case MESH_PDU_TYPE_SEGMENTED: 1095 // free chunks 1096 while (!btstack_linked_list_empty(&outgoing_segmented_message_singleton.segments)){ 1097 mesh_network_pdu_t * network_pdu = (mesh_network_pdu_t *) btstack_linked_list_pop(&outgoing_segmented_message_singleton.segments); 1098 mesh_network_pdu_free(network_pdu); 1099 } 1100 // notify upper layer but use transport pdu 1101 pdu_to_report = (mesh_pdu_t *) outgoing_segmented_access_pdu; 1102 outgoing_segmented_access_pdu = NULL; 1103 if (mesh_pdu_ctl(pdu_to_report)){ 1104 mesh_control_message_handler(callback_type, status, pdu_to_report); 1105 } else { 1106 mesh_access_message_handler(callback_type, status, pdu_to_report); 1107 } 1108 break; 1109 case MESH_PDU_TYPE_UNSEGMENTED: 1110 unsegmented_pdu = (mesh_unsegmented_pdu_t *) pdu; 1111 if (unsegmented_pdu == &outgoing_unsegmented_pdu){ 1112 // notify upper layer but use network pdu (control pdu) 1113 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) != 0); 1114 mesh_network_pdu_t * network_pdu = outgoing_unsegmented_pdu.segment; 1115 outgoing_unsegmented_pdu.segment = NULL; 1116 mesh_control_message_handler(callback_type, status, (mesh_pdu_t *) network_pdu); 1117 } else { 1118 btstack_assert((unsegmented_pdu->flags & MESH_TRANSPORT_FLAG_CONTROL) == 0); 1119 mesh_access_message_handler(callback_type, status, pdu); 1120 } 1121 break; 1122 default: 1123 btstack_assert(false); 1124 break; 1125 } 1126 mesh_upper_transport_run(); 1127 break; 1128 default: 1129 break; 1130 } 1131 } 1132 1133 void mesh_upper_transport_pdu_free(mesh_pdu_t * pdu){ 1134 mesh_network_pdu_t * network_pdu; 1135 mesh_segmented_pdu_t * message_pdu; 1136 switch (pdu->pdu_type) { 1137 case MESH_PDU_TYPE_NETWORK: 1138 network_pdu = (mesh_network_pdu_t *) pdu; 1139 mesh_network_pdu_free(network_pdu); 1140 break; 1141 case MESH_PDU_TYPE_SEGMENTED: 1142 message_pdu = (mesh_segmented_pdu_t *) pdu; 1143 mesh_message_pdu_free(message_pdu); 1144 default: 1145 btstack_assert(false); 1146 break; 1147 } 1148 } 1149 1150 void mesh_upper_transport_message_processed_by_higher_layer(mesh_pdu_t * pdu){ 1151 crypto_active = 0; 1152 switch (pdu->pdu_type){ 1153 case MESH_PDU_TYPE_ACCESS: 1154 mesh_upper_transport_process_segmented_access_message_done((mesh_access_pdu_t *) pdu); 1155 break; 1156 case MESH_PDU_TYPE_SEGMENTED: 1157 mesh_upper_transport_process_message_done((mesh_segmented_pdu_t *) pdu); 1158 break; 1159 case MESH_PDU_TYPE_UNSEGMENTED: 1160 mesh_upper_transport_process_unsegmented_message_done(pdu); 1161 break; 1162 default: 1163 btstack_assert(0); 1164 break; 1165 } 1166 } 1167 1168 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)) { 1169 mesh_access_message_handler = callback; 1170 } 1171 1172 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)){ 1173 mesh_control_message_handler = callback; 1174 } 1175 1176 void mesh_upper_transport_init(){ 1177 mesh_lower_transport_set_higher_layer_handler(&mesh_upper_transport_pdu_handler); 1178 } 1179