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