1 #include <stdio.h>
2
3 #include "CppUTest/TestHarness.h"
4 #include "CppUTest/CommandLineTestRunner.h"
5
6 #include "btstack_debug.h"
7 #include "btstack_memory.h"
8 #include "btstack_util.h"
9 #include "mesh/adv_bearer.h"
10 #include "mesh/gatt_bearer.h"
11 #include "mesh/mesh_access.h"
12 #include "mesh/mesh_crypto.h"
13 #include "mesh/mesh_foundation.h"
14 #include "mesh/mesh_iv_index_seq_number.h"
15 #include "mesh/mesh_lower_transport.h"
16 #include "mesh/mesh_network.h"
17 #include "mesh/mesh_upper_transport.h"
18 #include "mesh/provisioning.h"
19 #include "mesh/mesh_peer.h"
20 #include "mock.h"
21
22
23 static mesh_network_pdu_t * received_network_pdu;
24 static mesh_network_pdu_t * received_proxy_pdu;
25
26 static uint8_t outgoing_gatt_network_pdu_data[29];
27 static uint8_t outgoing_gatt_network_pdu_len;
28
29 static uint8_t outgoing_adv_network_pdu_data[29];
30 static uint8_t outgoing_adv_network_pdu_len;
31
32 static uint8_t recv_upper_transport_pdu_data[100];
33 static uint16_t recv_upper_transport_pdu_len;
34
35 #ifdef ENABLE_MESH_ADV_BEARER
36 static btstack_packet_handler_t adv_packet_handler;
adv_bearer_register_for_network_pdu(btstack_packet_handler_t packet_handler)37 void adv_bearer_register_for_network_pdu(btstack_packet_handler_t packet_handler){
38 adv_packet_handler = packet_handler;
39 }
adv_bearer_request_can_send_now_for_network_pdu(void)40 void adv_bearer_request_can_send_now_for_network_pdu(void){
41 // simulate can send now
42 uint8_t event[3];
43 event[0] = HCI_EVENT_MESH_META;
44 event[1] = 1;
45 event[2] = MESH_SUBEVENT_CAN_SEND_NOW;
46 (*adv_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
47 }
adv_bearer_send_network_pdu(const uint8_t * network_pdu,uint16_t size,uint8_t count,uint16_t interval)48 void adv_bearer_send_network_pdu(const uint8_t * network_pdu, uint16_t size, uint8_t count, uint16_t interval){
49 (void) count;
50 (void) interval;
51 // printf("ADV Network PDU: ");
52 // printf_hexdump(network_pdu, size);
53 memcpy(outgoing_adv_network_pdu_data, network_pdu, size);
54 outgoing_adv_network_pdu_len = size;
55 }
adv_bearer_emit_sent(void)56 static void adv_bearer_emit_sent(void){
57 uint8_t event[3];
58 event[0] = HCI_EVENT_MESH_META;
59 event[1] = 1;
60 event[2] = MESH_SUBEVENT_MESSAGE_SENT;
61 (*adv_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
62 }
63 #endif
64
65 #ifdef ENABLE_MESH_GATT_BEARER
66 static btstack_packet_handler_t gatt_packet_handler;
gatt_bearer_register_for_network_pdu(btstack_packet_handler_t packet_handler)67 void gatt_bearer_register_for_network_pdu(btstack_packet_handler_t packet_handler){
68 gatt_packet_handler = packet_handler;
69 }
gatt_bearer_register_for_mesh_proxy_configuration(btstack_packet_handler_t packet_handler)70 void gatt_bearer_register_for_mesh_proxy_configuration(btstack_packet_handler_t packet_handler){
71 UNUSED(packet_handler);
72 }
gatt_bearer_request_can_send_now_for_network_pdu(void)73 void gatt_bearer_request_can_send_now_for_network_pdu(void){
74 // simulate can send now
75 uint8_t event[3];
76 event[0] = HCI_EVENT_MESH_META;
77 event[1] = 1;
78 event[2] = MESH_SUBEVENT_CAN_SEND_NOW;
79 (*gatt_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
80 }
gatt_bearer_send_network_pdu(const uint8_t * network_pdu,uint16_t size)81 void gatt_bearer_send_network_pdu(const uint8_t * network_pdu, uint16_t size){
82 // printf("ADV Network PDU: ");
83 // printf_hexdump(network_pdu, size);
84 memcpy(outgoing_gatt_network_pdu_data, network_pdu, size);
85 outgoing_gatt_network_pdu_len = size;
86 }
gatt_bearer_emit_sent(void)87 static void gatt_bearer_emit_sent(void){
88 uint8_t event[3];
89 event[0] = HCI_EVENT_MESH_META;
90 event[1] = 1;
91 event[2] = MESH_SUBEVENT_MESSAGE_SENT;
92 (*gatt_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
93 }
gatt_bearer_emit_connected(void)94 static void gatt_bearer_emit_connected(void){
95 uint8_t event[5];
96 event[0] = HCI_EVENT_MESH_META;
97 event[1] = 1;
98 event[2] = MESH_SUBEVENT_PROXY_CONNECTED;
99 little_endian_store_16(event, 3, 0x1234);
100 (*gatt_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
101 }
102 #endif
103
104 // copy from mesh_message.c for now
mesh_pdu_dst(mesh_pdu_t * pdu)105 uint16_t mesh_pdu_dst(mesh_pdu_t * pdu){
106 switch (pdu->pdu_type){
107 case MESH_PDU_TYPE_UNSEGMENTED:
108 case MESH_PDU_TYPE_NETWORK:
109 case MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL:
110 return mesh_network_dst((mesh_network_pdu_t *) pdu);
111 case MESH_PDU_TYPE_ACCESS: {
112 return ((mesh_access_pdu_t *) pdu)->dst;
113 }
114 case MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS:
115 case MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS:
116 return ((mesh_upper_transport_pdu_t *) pdu)->dst;
117 default:
118 btstack_assert(false);
119 return MESH_ADDRESS_UNSASSIGNED;
120 }
121 }
mesh_pdu_ctl(mesh_pdu_t * pdu)122 uint16_t mesh_pdu_ctl(mesh_pdu_t * pdu){
123 switch (pdu->pdu_type){
124 case MESH_PDU_TYPE_NETWORK:
125 case MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL:
126 return mesh_network_control((mesh_network_pdu_t *) pdu);
127 case MESH_PDU_TYPE_ACCESS: {
128 return ((mesh_access_pdu_t *) pdu)->ctl_ttl >> 7;
129 }
130 default:
131 btstack_assert(false);
132 return 0;
133 }
134 }
135
CHECK_EQUAL_ARRAY(uint8_t * expected,uint8_t * actual,int size)136 static void CHECK_EQUAL_ARRAY(uint8_t * expected, uint8_t * actual, int size){
137 int i;
138 for (i=0; i<size; i++){
139 if (expected[i] != actual[i]) {
140 printf("offset %u wrong\n", i);
141 printf("expected: "); printf_hexdump(expected, size);
142 printf("actual: "); printf_hexdump(actual, size);
143 }
144 BYTES_EQUAL(expected[i], actual[i]);
145 }
146 }
147
scan_hex_byte(const char * byte_string)148 static int scan_hex_byte(const char * byte_string){
149 uint8_t upper_nibble = nibble_for_char(*byte_string++);
150 if (upper_nibble < 0) return -1;
151 uint8_t lower_nibble = nibble_for_char(*byte_string);
152 if (lower_nibble < 0) return -1;
153 return (upper_nibble << 4) | lower_nibble;
154 }
155
btstack_parse_hex(const char * string,uint16_t len,uint8_t * buffer)156 static int btstack_parse_hex(const char * string, uint16_t len, uint8_t * buffer){
157 int i;
158 for (i = 0; i < len; i++) {
159 int single_byte = scan_hex_byte(string);
160 if (single_byte < 0) return 0;
161 string += 2;
162 buffer[i] = (uint8_t)single_byte;
163 // don't check separator after last byte
164 if (i == len - 1) {
165 return 1;
166 }
167 // optional seperator
168 char separator = *string;
169 if (separator == ':' || separator == '-' || separator == ' ') {
170 string++;
171 }
172 }
173 return 1;
174 }
175
176 #if 0
177 static void btstack_print_hex(const uint8_t * data, uint16_t len, char separator){
178 int i;
179 for (i=0;i<len;i++){
180 printf("%02x", data[i]);
181 if (separator){
182 printf("%c", separator);
183 }
184 }
185 printf("\n");
186 }
187 #endif
188
189 static mesh_transport_key_t test_application_key;
mesh_application_key_set(uint16_t netkey_index,uint16_t appkey_index,uint8_t aid,const uint8_t * application_key)190 static void mesh_application_key_set(uint16_t netkey_index, uint16_t appkey_index, uint8_t aid, const uint8_t *application_key) {
191 test_application_key.netkey_index = netkey_index;
192 test_application_key.appkey_index = appkey_index;
193 test_application_key.aid = aid;
194 test_application_key.akf = 1;
195 memcpy(test_application_key.key, application_key, 16);
196 mesh_transport_key_add(&test_application_key);
197 }
198
load_network_key_nid_68(void)199 static void load_network_key_nid_68(void){
200 mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
201 network_key->nid = 0x68;
202 btstack_parse_hex("0953fa93e7caac9638f58820220a398e", 16, network_key->encryption_key);
203 btstack_parse_hex("8b84eedec100067d670971dd2aa700cf", 16, network_key->privacy_key);
204 mesh_network_key_add(network_key);
205 mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
206 }
207
load_network_key_nid_5e(void)208 static void load_network_key_nid_5e(void){
209 mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
210 network_key->nid = 0x5e;
211 btstack_parse_hex("be635105434859f484fc798e043ce40e", 16, network_key->encryption_key);
212 btstack_parse_hex("5d396d4b54d3cbafe943e051fe9a4eb8", 16, network_key->privacy_key);
213 mesh_network_key_add(network_key);
214 mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
215 }
216
load_network_key_nid_10(void)217 static void load_network_key_nid_10(void){
218 mesh_network_key_t * network_key = btstack_memory_mesh_network_key_get();
219 network_key->nid = 0x10;
220 btstack_parse_hex("3a4fe84a6cc2c6a766ea93f1084d4039", 16, network_key->encryption_key);
221 btstack_parse_hex("f695fcce709ccface4d8b7a1e6e39d25", 16, network_key->privacy_key);
222 mesh_network_key_add(network_key);
223 mesh_subnet_setup_for_netkey_index(network_key->netkey_index);
224 }
225
load_provisioning_data_test_message(void)226 static void load_provisioning_data_test_message(void){
227 uint8_t application_key[16];
228 btstack_parse_hex("63964771734fbd76e3b40519d1d94a48", 16, application_key);
229 mesh_application_key_set( 0, 0, 0x26, application_key);
230
231 uint8_t device_key[16];
232 btstack_parse_hex("9d6dd0e96eb25dc19a40ed9914f8f03f", 16, device_key);
233 mesh_transport_set_device_key(device_key);
234 }
235
test_lower_transport_callback_handler(mesh_network_callback_type_t callback_type,mesh_network_pdu_t * network_pdu)236 static void test_lower_transport_callback_handler(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu){
237 switch (callback_type){
238 case MESH_NETWORK_PDU_RECEIVED:
239 printf("test MESH_NETWORK_PDU_RECEIVED\n");
240 received_network_pdu = network_pdu;
241 break;
242 case MESH_NETWORK_PDU_SENT:
243 printf("test MESH_NETWORK_PDU_SENT\n");
244 mesh_lower_transport_received_message(MESH_NETWORK_PDU_SENT, network_pdu);
245 break;
246 default:
247 break;
248 }
249 }
250
test_proxy_server_callback_handler(mesh_network_callback_type_t callback_type,mesh_network_pdu_t * network_pdu)251 static void test_proxy_server_callback_handler(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu){
252 switch (callback_type){
253 case MESH_NETWORK_PDU_RECEIVED:
254 printf("test MESH_PROXY_PDU_RECEIVED\n");
255 received_proxy_pdu = network_pdu;
256 break;
257 case MESH_NETWORK_PDU_SENT:
258 // printf("test MESH_PROXY_PDU_SENT\n");
259 // mesh_lower_transport_received_mesage(MESH_NETWORK_PDU_SENT, network_pdu);
260 break;
261 case MESH_NETWORK_PDU_ENCRYPTED:
262 printf("test MESH_NETWORK_PDU_ENCRYPTED\n");
263 received_proxy_pdu = network_pdu;
264 break;
265 default:
266 break;
267 }
268 }
269
test_upper_transport_access_message_handler(mesh_transport_callback_type_t callback_type,mesh_transport_status_t status,mesh_pdu_t * pdu)270 static void test_upper_transport_access_message_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){
271 UNUSED(status);
272
273 // free sent pdus
274 if (callback_type == MESH_TRANSPORT_PDU_SENT) {
275 mesh_upper_transport_pdu_free(pdu);
276 return;
277 }
278
279 // process pdu received
280 mesh_access_pdu_t * access_pdu;
281 mesh_network_pdu_t * network_pdu;
282 mesh_segmented_pdu_t * message_pdu;
283
284 switch(pdu->pdu_type){
285 case MESH_PDU_TYPE_ACCESS:
286 access_pdu = (mesh_access_pdu_t *) pdu;
287 printf("test access handler MESH_PDU_TYPE_ACCESS received\n");
288 recv_upper_transport_pdu_len = access_pdu->len;
289 memcpy(recv_upper_transport_pdu_data, access_pdu->data, recv_upper_transport_pdu_len);
290 mesh_upper_transport_message_processed_by_higher_layer(pdu);
291 break;
292 case MESH_PDU_TYPE_SEGMENTED:
293 message_pdu = (mesh_segmented_pdu_t *) pdu;
294 printf("test access handler MESH_PDU_TYPE_SEGMENTED received\n");
295 network_pdu = (mesh_network_pdu_t *) btstack_linked_list_get_first_item(&message_pdu->segments);
296 recv_upper_transport_pdu_len = mesh_network_pdu_len(network_pdu) - 1;
297 memcpy(recv_upper_transport_pdu_data, mesh_network_pdu_data(network_pdu) + 1, recv_upper_transport_pdu_len);
298 mesh_upper_transport_message_processed_by_higher_layer(pdu);
299 break;
300 default:
301 btstack_assert(0);
302 break;
303 }
304 }
305
test_upper_transport_control_message_handler(mesh_transport_callback_type_t callback_type,mesh_transport_status_t status,mesh_pdu_t * pdu)306 static void test_upper_transport_control_message_handler(mesh_transport_callback_type_t callback_type, mesh_transport_status_t status, mesh_pdu_t * pdu){
307 UNUSED(status);
308
309 // ignore pdu sent
310 if (callback_type == MESH_TRANSPORT_PDU_SENT) return;
311
312 // process pdu received
313 mesh_control_pdu_t * control_pdu;
314 switch(pdu->pdu_type){
315 case MESH_PDU_TYPE_CONTROL:
316 control_pdu = (mesh_control_pdu_t *) pdu;
317 printf("test MESH_PDU_TYPE_CONTROL\n");
318 recv_upper_transport_pdu_len = control_pdu->len + 1;
319 recv_upper_transport_pdu_data[0] = control_pdu->akf_aid_control;
320 memcpy(&recv_upper_transport_pdu_data[1], control_pdu->data, control_pdu->len);
321 mesh_upper_transport_message_processed_by_higher_layer(pdu);
322 break;
323 default:
324 btstack_assert(0);
325 break;
326 }
327 }
328
TEST_GROUP(MessageTest)329 TEST_GROUP(MessageTest){
330 void setup(void){
331 btstack_memory_init();
332 btstack_crypto_init();
333 load_provisioning_data_test_message();
334 mesh_network_init();
335 mesh_lower_transport_init();
336 mesh_upper_transport_init();
337 mesh_network_key_init();
338 // intercept messages between network and lower layer
339 mesh_network_set_higher_layer_handler(&test_lower_transport_callback_handler);
340 mesh_network_set_proxy_message_handler(&test_proxy_server_callback_handler);
341 // register to receive upper transport messages
342 mesh_upper_transport_register_access_message_handler(&test_upper_transport_access_message_handler);
343 mesh_upper_transport_register_control_message_handler(&test_upper_transport_control_message_handler);
344 mesh_seq_auth_reset();
345 #ifdef ENABLE_MESH_GATT_BEARER
346 mesh_foundation_gatt_proxy_set(1);
347 gatt_bearer_emit_connected();
348 #endif
349 outgoing_gatt_network_pdu_len = 0;
350 outgoing_adv_network_pdu_len = 0;
351 received_network_pdu = NULL;
352 recv_upper_transport_pdu_len =0;
353 }
354 void teardown(void){
355 // printf("-- teardown start --\n\n");
356 btstack_crypto_reset();
357 mesh_network_reset();
358 mesh_lower_transport_reset();
359 mesh_upper_transport_dump();
360 mesh_upper_transport_reset();
361 // mesh_network_dump();
362 // mesh_transport_dump();
363 printf("-- teardown complete --\n\n");
364 }
365 };
366
367 static uint8_t transport_pdu_data[64];
368 static uint16_t transport_pdu_len;
369
370 static uint8_t test_network_pdu_len;
371 static uint8_t test_network_pdu_data[29];
372
test_receive_network_pdus(int count,char ** network_pdus,char ** lower_transport_pdus,char * access_pdu)373 static void test_receive_network_pdus(int count, char ** network_pdus, char ** lower_transport_pdus, char * access_pdu){
374 int i;
375 for (i=0;i<count;i++){
376 test_network_pdu_len = strlen(network_pdus[i]) / 2;
377 btstack_parse_hex(network_pdus[i], test_network_pdu_len, test_network_pdu_data);
378
379 mesh_network_received_message(test_network_pdu_data, test_network_pdu_len, 0);
380
381 while (received_network_pdu == NULL) {
382 mock_process_hci_cmd();
383 }
384
385 transport_pdu_len = strlen(lower_transport_pdus[i]) / 2;
386 btstack_parse_hex(lower_transport_pdus[i], transport_pdu_len, transport_pdu_data);
387
388 uint8_t * lower_transport_pdu = mesh_network_pdu_data(received_network_pdu);
389 uint8_t lower_transport_pdu_len = mesh_network_pdu_len(received_network_pdu);
390
391 // printf_hexdump(lower_transport_pdu, lower_transport_pdu_len);
392
393 CHECK_EQUAL( transport_pdu_len, lower_transport_pdu_len);
394 CHECK_EQUAL_ARRAY(transport_pdu_data, lower_transport_pdu, transport_pdu_len);
395
396 // forward to mesh_transport
397 mesh_lower_transport_received_message(MESH_NETWORK_PDU_RECEIVED, received_network_pdu);
398
399 // done
400 received_network_pdu = NULL;
401 }
402
403 // wait for transport pdu
404 while (recv_upper_transport_pdu_len == 0) {
405 mock_process_hci_cmd();
406
407 // check for acks
408 if (outgoing_gatt_network_pdu_len != 0){
409 outgoing_gatt_network_pdu_len = 0;
410 gatt_bearer_emit_sent();
411 }
412 if (outgoing_adv_network_pdu_len != 0){
413 outgoing_adv_network_pdu_len = 0;
414 adv_bearer_emit_sent();
415 }
416 }
417
418 transport_pdu_len = strlen(access_pdu) / 2;
419 btstack_parse_hex(access_pdu, transport_pdu_len, transport_pdu_data);
420
421 printf("UpperTransportPDU: ");
422 printf_hexdump(recv_upper_transport_pdu_data, recv_upper_transport_pdu_len);
423 CHECK_EQUAL( transport_pdu_len, recv_upper_transport_pdu_len);
424 CHECK_EQUAL_ARRAY(transport_pdu_data, recv_upper_transport_pdu_data, transport_pdu_len);
425 }
426
expect_gatt_network_pdu(void)427 static void expect_gatt_network_pdu(void){
428
429 while (outgoing_gatt_network_pdu_len == 0) {
430 mock_process_hci_cmd();
431 }
432
433 if (outgoing_gatt_network_pdu_len != test_network_pdu_len){
434 printf("Test Network PDU (%u): ", outgoing_gatt_network_pdu_len); printf_hexdump(outgoing_gatt_network_pdu_data, outgoing_gatt_network_pdu_len);
435 printf("Expected PDU (%u): ", test_network_pdu_len); printf_hexdump(test_network_pdu_data, test_network_pdu_len);
436 }
437 CHECK_EQUAL( outgoing_gatt_network_pdu_len, test_network_pdu_len);
438 CHECK_EQUAL_ARRAY(test_network_pdu_data, outgoing_gatt_network_pdu_data, test_network_pdu_len);
439
440 outgoing_gatt_network_pdu_len = 0;
441 gatt_bearer_emit_sent();
442 }
443
expect_adv_network_pdu(void)444 static void expect_adv_network_pdu(void){
445 while (outgoing_adv_network_pdu_len == 0) {
446 mock_process_hci_cmd();
447 }
448
449 if (outgoing_adv_network_pdu_len != test_network_pdu_len){
450 printf("Test Network PDU (%u): ", outgoing_adv_network_pdu_len); printf_hexdump(outgoing_adv_network_pdu_data, outgoing_adv_network_pdu_len);
451 printf("Expected PDU (%u): ", test_network_pdu_len); printf_hexdump(test_network_pdu_data, test_network_pdu_len);
452 }
453 CHECK_EQUAL( outgoing_adv_network_pdu_len, test_network_pdu_len);
454 CHECK_EQUAL_ARRAY(test_network_pdu_data, outgoing_adv_network_pdu_data, test_network_pdu_len);
455
456 outgoing_adv_network_pdu_len = 0;
457 adv_bearer_emit_sent();
458 }
459
test_send_access_message(uint16_t netkey_index,uint16_t appkey_index,uint8_t ttl,uint16_t src,uint16_t dest,uint8_t szmic,char * control_pdu,int count,char ** lower_transport_pdus,char ** network_pdus)460 static void test_send_access_message(uint16_t netkey_index, uint16_t appkey_index, uint8_t ttl, uint16_t src, uint16_t dest, uint8_t szmic, char * control_pdu, int count, char ** lower_transport_pdus, char ** network_pdus){
461
462 UNUSED(lower_transport_pdus);
463
464 transport_pdu_len = strlen(control_pdu) / 2;
465 btstack_parse_hex(control_pdu, transport_pdu_len, transport_pdu_data);
466
467 mesh_pdu_type_t pdu_type;
468 if (count == 1 ){
469 // send as unsegmented access pdu
470 pdu_type = MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS;
471 } else {
472 // send as segmented access pdu
473 pdu_type = MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS;
474 }
475 #if 0
476 //
477 upper_pdu.lower_pdu = NULL;
478 upper_pdu.flags = 0;
479 upper_pdu.pdu_type = pdu_type;
480 mesh_pdu_t * pdu = (mesh_pdu_t *) &upper_pdu;
481 mesh_upper_transport_setup_access_pdu(pdu, netkey_index, appkey_index, ttl, src, dest, szmic, transport_pdu_data, transport_pdu_len);
482 #else
483 mesh_upper_transport_builder_t builder;
484 mesh_upper_transport_message_init(&builder, pdu_type);
485 mesh_upper_transport_message_add_data(&builder, transport_pdu_data, transport_pdu_len);
486 mesh_pdu_t * pdu = (mesh_pdu_t *) mesh_upper_transport_message_finalize(&builder);
487 mesh_upper_transport_setup_access_pdu_header(pdu, netkey_index, appkey_index, ttl, src, dest, szmic);
488 #endif
489 mesh_upper_transport_send_access_pdu(pdu);
490
491 // check for all network pdus
492 int i;
493 for (i=0;i<count;i++){
494 // parse expected network pdu
495 test_network_pdu_len = strlen(network_pdus[i]) / 2;
496 btstack_parse_hex(network_pdus[i], test_network_pdu_len, test_network_pdu_data);
497
498 #ifdef ENABLE_MESH_GATT_BEARER
499 expect_gatt_network_pdu();
500 #endif
501
502 #ifdef ENABLE_MESH_ADV_BEARER
503 expect_adv_network_pdu();
504 #endif
505 }
506 // mesh_upper_transport_pdu_free(pdu);
507 }
508
test_send_control_message(uint16_t netkey_index,uint8_t ttl,uint16_t src,uint16_t dest,char * control_pdu,int count,char ** lower_transport_pdus,char ** network_pdus)509 static void test_send_control_message(uint16_t netkey_index, uint8_t ttl, uint16_t src, uint16_t dest, char * control_pdu, int count, char ** lower_transport_pdus, char ** network_pdus){
510
511 UNUSED(lower_transport_pdus);
512
513 transport_pdu_len = strlen(control_pdu) / 2;
514 btstack_parse_hex(control_pdu, transport_pdu_len, transport_pdu_data);
515
516 uint8_t opcode = transport_pdu_data[0];
517
518 mesh_pdu_t * pdu;
519 if (transport_pdu_len < 12){
520 // send as unsegmented control pdu
521 mesh_network_pdu_t * network_pdu = mesh_network_pdu_get();
522 mesh_upper_transport_setup_unsegmented_control_pdu(network_pdu, netkey_index, ttl, src, dest, opcode, transport_pdu_data+1, transport_pdu_len-1);
523 pdu = (mesh_pdu_t *) network_pdu;
524 } else {
525 mesh_upper_transport_builder_t builder;
526 mesh_upper_transport_message_init(&builder, MESH_PDU_TYPE_UPPER_SEGMENTED_CONTROL);
527 mesh_upper_transport_message_add_data(&builder, transport_pdu_data+1, transport_pdu_len-1);
528 mesh_upper_transport_pdu_t * final_upper_pdu = (mesh_upper_transport_pdu_t *) mesh_upper_transport_message_finalize(&builder);
529 mesh_upper_transport_setup_segmented_control_pdu_header(final_upper_pdu, netkey_index, ttl, src, dest, opcode);
530 pdu = (mesh_pdu_t *) final_upper_pdu;
531 }
532 mesh_upper_transport_send_control_pdu(pdu);
533
534 // check for all network pdus
535 int i;
536 for (i=0;i<count;i++){
537 // expected network pdu
538 test_network_pdu_len = strlen(network_pdus[i]) / 2;
539 btstack_parse_hex(network_pdus[i], test_network_pdu_len, test_network_pdu_data);
540
541 #ifdef ENABLE_MESH_GATT_BEARER
542 expect_gatt_network_pdu();
543 #endif
544
545 #ifdef ENABLE_MESH_ADV_BEARER
546 expect_adv_network_pdu();
547 #endif
548
549 }
550 }
551 #if 1
552 // Message 1
553 char * message1_network_pdus[] = {
554 (char *) "68eca487516765b5e5bfdacbaf6cb7fb6bff871f035444ce83a670df"
555 };
556 char * message1_lower_transport_pdus[] = {
557 (char *) "034b50057e400000010000",
558 };
559 char * message1_upper_transport_pdu = (char *) "034b50057e400000010000";
TEST(MessageTest,Message1Receive)560 TEST(MessageTest, Message1Receive){
561 load_network_key_nid_68();
562 mesh_set_iv_index(0x12345678);
563 test_receive_network_pdus(1, message1_network_pdus, message1_lower_transport_pdus, message1_upper_transport_pdu);
564 }
TEST(MessageTest,Message1Send)565 TEST(MessageTest, Message1Send){
566 uint16_t netkey_index = 0;
567 uint8_t ttl = 0;
568 uint16_t src = 0x1201;
569 uint16_t dest = 0xfffd;
570 uint32_t seq = 1;
571 load_network_key_nid_68();
572 mesh_set_iv_index(0x12345678);
573 mesh_sequence_number_set(seq);
574 test_send_control_message(netkey_index, ttl, src, dest, message1_upper_transport_pdu, 1, message1_lower_transport_pdus, message1_network_pdus);
575 }
576
577 // Message 2
578 char * message2_network_pdus[] = {
579 (char *) "68d4c826296d7979d7dbc0c9b4d43eebec129d20a620d01e"
580 };
581 char * message2_lower_transport_pdus[] = {
582 (char *) "04320308ba072f",
583 };
584 char * message2_upper_transport_pdu = (char *) "04320308ba072f";
TEST(MessageTest,Message2Receive)585 TEST(MessageTest, Message2Receive){
586 load_network_key_nid_68();
587 mesh_set_iv_index(0x12345678);
588 test_receive_network_pdus(1, message2_network_pdus, message2_lower_transport_pdus, message2_upper_transport_pdu);
589 }
TEST(MessageTest,Message2Send)590 TEST(MessageTest, Message2Send){
591 uint16_t netkey_index = 0;
592 uint8_t ttl = 0;
593 uint16_t src = 0x2345;
594 uint16_t dest = 0x1201;
595 uint32_t seq = 0x014820;
596 load_network_key_nid_68();
597 mesh_set_iv_index(0x12345678);
598 mesh_sequence_number_set(seq);
599 test_send_control_message(netkey_index, ttl, src, dest, message2_upper_transport_pdu, 1, message2_lower_transport_pdus, message2_network_pdus);
600 }
601
602 // Message 3
603 char * message3_network_pdus[] = {
604 (char *) "68da062bc96df253273086b8c5ee00bdd9cfcc62a2ddf572"
605 };
606 char * message3_lower_transport_pdus[] = {
607 (char *) "04fa0205a6000a",
608 };
609 char * message3_upper_transport_pdu = (char *) "04fa0205a6000a";
TEST(MessageTest,Message3Receive)610 TEST(MessageTest, Message3Receive){
611 load_network_key_nid_68();
612 mesh_set_iv_index(0x12345678);
613 test_receive_network_pdus(1, message3_network_pdus, message3_lower_transport_pdus, message3_upper_transport_pdu);
614 }
TEST(MessageTest,Message3Send)615 TEST(MessageTest, Message3Send){
616 uint16_t netkey_index = 0;
617 uint8_t ttl = 0;
618 uint16_t src = 0x2fe3;
619 uint16_t dest = 0x1201;
620 uint32_t seq = 0x2b3832;
621 load_network_key_nid_68();
622 mesh_set_iv_index(0x12345678);
623 mesh_sequence_number_set(seq);
624 test_send_control_message(netkey_index, ttl, src, dest, message3_upper_transport_pdu, 1, message3_lower_transport_pdus, message3_network_pdus);
625 }
626
627 // Message 4
628 char * message4_network_pdus[] = {
629 (char *) "5e84eba092380fb0e5d0ad970d579a4e88051c"
630 };
631 char * message4_lower_transport_pdus[] = {
632 (char *) "0100",
633 };
634 char * message4_upper_transport_pdu = (char *) "0100";
TEST(MessageTest,Message4Receive)635 TEST(MessageTest, Message4Receive){
636 load_network_key_nid_5e();
637 mesh_set_iv_index(0x12345678);
638 test_receive_network_pdus(1, message4_network_pdus, message4_lower_transport_pdus, message4_upper_transport_pdu);
639 }
TEST(MessageTest,Message4Send)640 TEST(MessageTest, Message4Send){
641 uint16_t netkey_index = 0;
642 uint8_t ttl = 0;
643 uint16_t src = 0x1201;
644 uint16_t dest = 0x2345;
645 uint32_t seq = 0x000002;
646 load_network_key_nid_5e();
647 mesh_set_iv_index(0x12345678);
648 mesh_sequence_number_set(seq);
649 test_send_control_message(netkey_index, ttl, src, dest, message4_upper_transport_pdu, 1, message4_lower_transport_pdus, message4_network_pdus);
650 }
651
652 // Message 5
653 char * message5_network_pdus[] = {
654 (char *) "5eafd6f53c43db5c39da1792b1fee9ec74b786c56d3a9dee",
655 };
656 char * message5_lower_transport_pdus[] = {
657 (char *) "02001234567800",
658 };
659 char * message5_upper_transport_pdu = (char *) "02001234567800";
TEST(MessageTest,Message5Receive)660 TEST(MessageTest, Message5Receive){
661 load_network_key_nid_5e();
662 mesh_set_iv_index(0x12345678);
663 test_receive_network_pdus(1, message5_network_pdus, message5_lower_transport_pdus, message5_upper_transport_pdu);
664 }
TEST(MessageTest,Message5Send)665 TEST(MessageTest, Message5Send){
666 uint16_t netkey_index = 0;
667 uint8_t ttl = 0;
668 uint16_t src = 0x2345;
669 uint16_t dest = 0x1201;
670 uint32_t seq = 0x014834;
671 load_network_key_nid_5e();
672 mesh_set_iv_index(0x12345678);
673 mesh_sequence_number_set(seq);
674 test_send_control_message(netkey_index, ttl, src, dest, message5_upper_transport_pdu, 1, message5_lower_transport_pdus, message5_network_pdus);
675 }
676
677 // Message 6
678 char * message6_network_pdus[] = {
679 (char *) "68cab5c5348a230afba8c63d4e686364979deaf4fd40961145939cda0e",
680 (char *) "681615b5dd4a846cae0c032bf0746f44f1b8cc8ce5edc57e55beed49c0",
681 };
682 char * message6_lower_transport_pdus[] = {
683 (char *) "8026ac01ee9dddfd2169326d23f3afdf",
684 (char *) "8026ac21cfdc18c52fdef772e0e17308",
685 };
686 char * message6_upper_transport_pdu = (char *) "0056341263964771734fbd76e3b40519d1d94a48";
TEST(MessageTest,Message6Receive)687 TEST(MessageTest, Message6Receive){
688 load_network_key_nid_68();
689 mesh_set_iv_index(0x12345678);
690 test_receive_network_pdus(2, message6_network_pdus, message6_lower_transport_pdus, message6_upper_transport_pdu);
691 }
TEST(MessageTest,Message6Send)692 TEST(MessageTest, Message6Send){
693 uint16_t netkey_index = 0;
694 uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
695 uint8_t ttl = 4;
696 uint16_t src = 0x0003;
697 uint16_t dest = 0x1201;
698 uint32_t seq = 0x3129ab;
699 uint8_t szmic = 0;
700
701 load_network_key_nid_68();
702 mesh_set_iv_index(0x12345678);
703 mesh_sequence_number_set(seq);
704 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message6_upper_transport_pdu, 2, message6_lower_transport_pdus, message6_network_pdus);
705 }
706
707 // Message 7 - ACK
708 char * message7_network_pdus[] = {
709 (char *) "68e476b5579c980d0d730f94d7f3509df987bb417eb7c05f",
710 };
711 char * message7_lower_transport_pdus[] = {
712 (char *) "00a6ac00000002",
713 };
714 char * message7_upper_transport_pdu = (char *) "00a6ac00000002";
TEST(MessageTest,Message7Send)715 TEST(MessageTest, Message7Send){
716 uint16_t netkey_index = 0;
717 uint8_t ttl = 0x0b;
718 uint16_t src = 0x2345;
719 uint16_t dest = 0x0003;
720 uint32_t seq = 0x014835;
721
722 load_network_key_nid_68();
723 mesh_set_iv_index(0x12345678);
724 mesh_sequence_number_set(seq);
725 test_send_control_message(netkey_index, ttl, src, dest, message7_upper_transport_pdu, 1, message7_lower_transport_pdus, message7_network_pdus);
726 }
727 // ACK message, handled in mesh_transport - can be checked with test_control_receive_network_pdu
728 // TEST(MessageTest, Message7Receive){
729 // mesh_set_iv_index(0x12345678);
730 // test_receive_network_pdus(1, message7_network_pdus, message7_lower_transport_pdus, message7_upper_transport_pdu);
731 // }
732
733 // Message 8 - ACK
734 char * message8_network_pdus[] = {
735 (char *) "684daa6267c2cf0e2f91add6f06e66006844cec97f973105ae2534f958",
736 };
737 char * message8_lower_transport_pdus[] = {
738 (char *) "8026ac01ee9dddfd2169326d23f3afdf",
739 };
740 char * message8_upper_transport_pdu = (char *) "8026ac01ee9dddfd2169326d23f3afdf";
741 // ACK message, handled in mesh_transport - can be checked with test_control_receive_network_pdu
742 // TEST(MessageTest, Message8Receive){
743 // mesh_set_iv_index(0x12345678);
744 // test_receive_network_pdus(1, message8_network_pdus, message8_lower_transport_pdus, message8_upper_transport_pdu);
745 // }
746
747 // Message 9 - ACK
748
749 // Message 10
750 char * message10_network_pdus[] = {
751 (char *) "5e7b786568759f7777ed355afaf66d899c1e3d",
752 };
753 char * message10_lower_transport_pdus[] = {
754 (char *) "0101",
755 };
756 char * message10_upper_transport_pdu = (char *) "0101";
TEST(MessageTest,Message10Receive)757 TEST(MessageTest, Message10Receive){
758 load_network_key_nid_5e();
759 mesh_set_iv_index(0x12345678);
760 test_receive_network_pdus(1, message10_network_pdus, message10_lower_transport_pdus, message10_upper_transport_pdu);
761 }
TEST(MessageTest,Message10Send)762 TEST(MessageTest, Message10Send){
763 uint16_t netkey_index = 0;
764 uint8_t ttl = 0;
765 uint16_t src = 0x1201;
766 uint16_t dest = 0x2345;
767 uint32_t seq = 0x000003;
768
769 load_network_key_nid_5e();
770 mesh_set_iv_index(0x12345678);
771 mesh_sequence_number_set(seq);
772 test_send_control_message(netkey_index, ttl, src, dest, message10_upper_transport_pdu, 1, message10_lower_transport_pdus, message10_network_pdus);
773 }
774
775 // Message 11
776 // The Friend node responds to this poll with the first segment of the stored message. It also indicates that it has more data.
777
778 // Message 12
779 char * message12_network_pdus[] = {
780 (char *) "5e8a18fc6e4d05ae21466087599c2426ce9a35",
781 };
782 char * message12_lower_transport_pdus[] = {
783 (char *) "0101",
784 };
785 char * message12_upper_transport_pdu = (char *) "0101";
TEST(MessageTest,Message12Receive)786 TEST(MessageTest, Message12Receive){
787 load_network_key_nid_5e();
788 mesh_set_iv_index(0x12345678);
789 test_receive_network_pdus(1, message12_network_pdus, message12_lower_transport_pdus, message12_upper_transport_pdu);
790 }
TEST(MessageTest,Message12Send)791 TEST(MessageTest, Message12Send){
792 uint16_t netkey_index = 0;
793 uint8_t ttl = 0;
794 uint16_t src = 0x1201;
795 uint16_t dest = 0x2345;
796 uint32_t seq = 0x000004;
797
798 load_network_key_nid_5e();
799 mesh_set_iv_index(0x12345678);
800 mesh_sequence_number_set(seq);
801 test_send_control_message(netkey_index, ttl, src, dest, message12_upper_transport_pdu, 1, message12_lower_transport_pdus, message12_network_pdus);
802 }
803
804 // Message 13
805 // The Friend node responds with the same message as last time.
806 // Message 14
807 // The Low Power node received the retransmitted stored message. As that message has the MD bit set
808 // it sends another Friend Poll to obtain the next message.
809 char * message14_network_pdus[] = {
810 (char *) "5e0bbaf92b5c8f7d3ae62a3c75dff683dce24e",
811 };
812 char * message14_lower_transport_pdus[] = {
813 (char *) "0100",
814 };
815 char * message14_upper_transport_pdu = (char *) "0100";
TEST(MessageTest,Message14Receive)816 TEST(MessageTest, Message14Receive){
817 load_network_key_nid_5e();
818 mesh_set_iv_index(0x12345678);
819 test_receive_network_pdus(1, message14_network_pdus, message14_lower_transport_pdus, message14_upper_transport_pdu);
820 }
TEST(MessageTest,Message14Send)821 TEST(MessageTest, Message14Send){
822 uint16_t netkey_index = 0;
823 uint8_t ttl = 0;
824 uint16_t src = 0x1201;
825 uint16_t dest = 0x2345;
826 uint32_t seq = 0x000005;
827
828 load_network_key_nid_5e();
829 mesh_set_iv_index(0x12345678);
830 mesh_sequence_number_set(seq);
831 test_send_control_message(netkey_index, ttl, src, dest, message14_upper_transport_pdu, 1, message14_lower_transport_pdus, message14_network_pdus);
832 }
833
834 // Message 15
835 // The Friend node responds, with the next message in the friend queue. The Friend node has no more data, so it sets the MD to 0.
836 char * message15_network_pdus[] = {
837 (char *) "5ea8dab50e7ee7f1d29805664d235eacd707217dedfe78497fefec7391",
838 };
839 char * message15_lower_transport_pdus[] = {
840 (char *) "8026ac21cfdc18c52fdef772e0e17308",
841 };
842 char * message15_upper_transport_pdu = (char *) "0100";
843 // ACK message, handled in mesh_transport - can be checked with test_control_receive_network_pdu
844 // not sure - no upper access message
845 // TEST(MessageTest, Message15Receive){
846 // load_network_key_nid_5e();
847 // mesh_set_iv_index(0x12345678);
848 // test_receive_network_pdus(1, message15_network_pdus, message15_lower_transport_pdus, message15_upper_transport_pdu);
849 // }
850
851 // Message 16
852 char * message16_network_pdus[] = {
853 (char *) "68e80e5da5af0e6b9be7f5a642f2f98680e61c3a8b47f228",
854 };
855 char * message16_lower_transport_pdus[] = {
856 (char *) "0089511bf1d1a81c11dcef",
857 };
858 char * message16_upper_transport_pdu = (char *) "800300563412";
TEST(MessageTest,Message16Receive)859 TEST(MessageTest, Message16Receive){
860 load_network_key_nid_68();
861 mesh_set_iv_index(0x12345678);
862 test_receive_network_pdus(1, message16_network_pdus, message16_lower_transport_pdus, message16_upper_transport_pdu);
863 }
TEST(MessageTest,Message16Send)864 TEST(MessageTest, Message16Send){
865 uint16_t netkey_index = 0;
866 uint16_t appkey_index = MESH_DEVICE_KEY_INDEX;
867 uint8_t ttl = 0x0b;
868 uint16_t src = 0x1201;
869 uint16_t dest = 0x0003;
870 uint32_t seq = 0x000006;
871 uint8_t szmic = 0;
872
873 load_network_key_nid_68();
874 mesh_set_iv_index(0x12345678);
875 mesh_sequence_number_set(seq);
876 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message16_upper_transport_pdu, 1, message16_lower_transport_pdus, message16_network_pdus);
877 }
878
879 // Message 17
880 // A Relay node receives the message from the Low Power node and relays it, decrementing the TTL value.
881 // Message 18
882 char * message18_network_pdus[] = {
883 (char *) "6848cba437860e5673728a627fb938535508e21a6baf57",
884 };
885 char * message18_lower_transport_pdus[] = {
886 (char *) "665a8bde6d9106ea078a",
887 };
888 char * message18_upper_transport_pdu = (char *) "0400000000";
TEST(MessageTest,Message18Receive)889 TEST(MessageTest, Message18Receive){
890 load_network_key_nid_68();
891 mesh_set_iv_index(0x12345678);
892 test_receive_network_pdus(1, message18_network_pdus, message18_lower_transport_pdus, message18_upper_transport_pdu);
893 }
TEST(MessageTest,Message18Send)894 TEST(MessageTest, Message18Send){
895 uint16_t netkey_index = 0;
896 uint16_t appkey_index = 0;
897 uint8_t ttl = 3;
898 uint16_t src = 0x1201;
899 uint16_t dest = 0xffff;
900 uint32_t seq = 0x00007;
901 uint8_t szmic = 0;
902
903 load_network_key_nid_68();
904 mesh_set_iv_index(0x12345678);
905 mesh_sequence_number_set(seq);
906 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message18_upper_transport_pdu, 1, message18_lower_transport_pdus, message18_network_pdus);
907 }
908
909
910 // Message 19
911 // The Low Power node sends another Health Current Status message indicating that there are three faults:
912 // Battery Low Warning, Power Supply Interrupted Warning, and Supply Voltage Too Low Warning.
913 char * message19_network_pdus[] = {
914 (char *) "68110edeecd83c3010a05e1b23a926023da75d25ba91793736",
915 };
916 char * message19_lower_transport_pdus[] = {
917 (char *) "66ca6cd88e698d1265f43fc5",
918 };
919 char * message19_upper_transport_pdu = (char *) "04000000010703";
TEST(MessageTest,Message19Receive)920 TEST(MessageTest, Message19Receive){
921 load_network_key_nid_68();
922 mesh_set_iv_index(0x12345678);
923 test_receive_network_pdus(1, message19_network_pdus, message19_lower_transport_pdus, message19_upper_transport_pdu);
924 }
TEST(MessageTest,Message19Send)925 TEST(MessageTest, Message19Send){
926 uint16_t netkey_index = 0;
927 uint16_t appkey_index = 0;
928 uint8_t ttl = 3;
929 uint16_t src = 0x1201;
930 uint16_t dest = 0xffff;
931 uint32_t seq = 0x00009;
932 uint8_t szmic = 0;
933
934 load_network_key_nid_68();
935 mesh_set_iv_index(0x12345678);
936 mesh_sequence_number_set(seq);
937 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message19_upper_transport_pdu, 1, message19_lower_transport_pdus, message19_network_pdus);
938 }
939
940 // Message 20
941 char * message20_network_pdus[] = {
942 (char *) "e85cca51e2e8998c3dc87344a16c787f6b08cc897c941a5368",
943 };
944 char * message20_lower_transport_pdus[] = {
945 (char *) "669c9803e110fea929e9542d",
946 };
947 char * message20_upper_transport_pdu = (char *) "04000000010703";
TEST(MessageTest,Message20Receive)948 TEST(MessageTest, Message20Receive){
949 load_network_key_nid_68();
950 mesh_set_iv_index(0x12345677);
951 test_receive_network_pdus(1, message20_network_pdus, message20_lower_transport_pdus, message20_upper_transport_pdu);
952 }
TEST(MessageTest,Message20Send)953 TEST(MessageTest, Message20Send){
954 uint16_t netkey_index = 0;
955 uint16_t appkey_index = 0;
956 uint8_t ttl = 3;
957 uint16_t src = 0x1234;
958 uint16_t dest = 0xffff;
959 uint32_t seq = 0x070809;
960 uint8_t szmic = 0;
961
962 load_network_key_nid_68();
963 mesh_set_iv_index(0x12345677);
964 mesh_sequence_number_set(seq);
965 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message20_upper_transport_pdu, 1, message20_lower_transport_pdus, message20_network_pdus);
966 }
967
968 // Message 21
969 // The Low Power node sends a vendor command to a group address.
970 char * message21_network_pdus[] = {
971 (char *) "e84e8fbe003f58a4d61157bb76352ea6307eebfe0f30b83500e9",
972 };
973 char * message21_lower_transport_pdus[] = {
974 (char *) "664d92e9dfcf3ab85b6e8fcf03",
975 };
976 char * message21_upper_transport_pdu = (char *) "d50a0048656c6c6f";
TEST(MessageTest,Message21Receive)977 TEST(MessageTest, Message21Receive){
978 load_network_key_nid_68();
979 mesh_set_iv_index(0x12345677);
980 test_receive_network_pdus(1, message21_network_pdus, message21_lower_transport_pdus, message21_upper_transport_pdu);
981 }
TEST(MessageTest,Message21Send)982 TEST(MessageTest, Message21Send){
983 uint16_t netkey_index = 0;
984 uint16_t appkey_index = 0;
985 uint8_t ttl = 3;
986 uint16_t src = 0x1234;
987 uint16_t dest = 0xc105;
988 uint32_t seq = 0x07080a;
989 uint8_t szmic = 0;
990
991 load_network_key_nid_68();
992 mesh_set_iv_index(0x12345677);
993 mesh_sequence_number_set(seq);
994 test_send_access_message(netkey_index, appkey_index, ttl, src, dest, szmic, message21_upper_transport_pdu, 1, message21_lower_transport_pdus, message21_network_pdus);
995 }
996
997 // Message 22
998 char * message22_network_pdus[] = {
999 (char *) "e8d85caecef1e3ed31f3fdcf88a411135fea55df730b6b28e255",
1000 };
1001 char * message22_lower_transport_pdus[] = {
1002 (char *) "663871b904d431526316ca48a0",
1003 };
1004 char * message22_upper_transport_pdu = (char *) "d50a0048656c6c6f";
1005 char * message22_label_string = (char *) "0073e7e4d8b9440faf8415df4c56c0e1";
1006
TEST(MessageTest,Message22Receive)1007 TEST(MessageTest, Message22Receive){
1008 load_network_key_nid_68();
1009 mesh_set_iv_index(0x12345677);
1010 uint8_t label_uuid[16];
1011 btstack_parse_hex(message22_label_string, 16, label_uuid);
1012 mesh_virtual_address_register(label_uuid, 0xb529);
1013 test_receive_network_pdus(1, message22_network_pdus, message22_lower_transport_pdus, message22_upper_transport_pdu);
1014 }
1015
TEST(MessageTest,Message22Send)1016 TEST(MessageTest, Message22Send){
1017 uint16_t netkey_index = 0;
1018 uint16_t appkey_index = 0;
1019 uint8_t ttl = 3;
1020 uint16_t src = 0x1234;
1021 uint32_t seq = 0x07080b;
1022 uint8_t szmic = 0;
1023
1024 load_network_key_nid_68();
1025 mesh_set_iv_index(0x12345677);
1026 mesh_sequence_number_set(seq);
1027 uint8_t label_uuid[16];
1028 btstack_parse_hex(message22_label_string, 16, label_uuid);
1029 mesh_virtual_address_t * virtual_address = mesh_virtual_address_register(label_uuid, 0xb529);
1030 uint16_t pseudo_dst = virtual_address->pseudo_dst;
1031 test_send_access_message(netkey_index, appkey_index, ttl, src, pseudo_dst, szmic, message22_upper_transport_pdu, 1, message22_lower_transport_pdus, message22_network_pdus);
1032 }
1033
1034 // Message 23
1035 char * message23_network_pdus[] = {
1036 (char *) "e877a48dd5fe2d7a9d696d3dd16a75489696f0b70c711b881385",
1037 };
1038 char * message23_lower_transport_pdus[] = {
1039 (char *) "662456db5e3100eef65daa7a38",
1040 };
1041 char * message23_upper_transport_pdu = (char *) "d50a0048656c6c6f";
1042 char * message23_label_string = (char *) "f4a002c7fb1e4ca0a469a021de0db875";
1043
TEST(MessageTest,Message23Receive)1044 TEST(MessageTest, Message23Receive){
1045 load_network_key_nid_68();
1046 mesh_set_iv_index(0x12345677);
1047 uint8_t label_uuid[16];
1048 btstack_parse_hex(message23_label_string, 16, label_uuid);
1049 mesh_virtual_address_register(label_uuid, 0x9736);
1050 test_receive_network_pdus(1, message23_network_pdus, message23_lower_transport_pdus, message23_upper_transport_pdu);
1051 }
TEST(MessageTest,Message23Send)1052 TEST(MessageTest, Message23Send){
1053 uint16_t netkey_index = 0;
1054 uint16_t appkey_index = 0;
1055 uint8_t ttl = 3;
1056 uint16_t src = 0x1234;
1057 uint32_t seq = 0x07080c;
1058 uint8_t szmic = 0;
1059
1060 load_network_key_nid_68();
1061 mesh_set_iv_index(0x12345677);
1062 mesh_sequence_number_set(seq);
1063 uint8_t label_uuid[16];
1064 btstack_parse_hex(message23_label_string, 16, label_uuid);
1065 mesh_virtual_address_t * virtual_address = mesh_virtual_address_register(label_uuid, 0x9736);
1066 uint16_t pseudo_dst = virtual_address->pseudo_dst;
1067 test_send_access_message(netkey_index, appkey_index, ttl, src, pseudo_dst, szmic, message23_upper_transport_pdu, 1, message23_lower_transport_pdus, message23_network_pdus);
1068 }
1069 #endif
1070
1071 // Message 24
1072 char * message24_network_pdus[] = {
1073 (char *) "e8624e65bb8c1794e998b4081f47a35251fdd3896d99e4db489b918599",
1074 (char *) "e8a7d0f0a2ea42dc2f4dd6fb4db33a6c088d023b47",
1075 };
1076 char * message24_lower_transport_pdus[] = {
1077 (char *) "e6a03401c3c51d8e476b28e3aa5001f3",
1078 (char *) "e6a034211c01cea6",
1079 };
1080 char * message24_upper_transport_pdu = (char *) "ea0a00576f726c64";
1081 char * message24_label_string = (char *) "f4a002c7fb1e4ca0a469a021de0db875";
TEST(MessageTest,Message24Receive)1082 TEST(MessageTest, Message24Receive){
1083 load_network_key_nid_68();
1084 mesh_set_iv_index(0x12345677);
1085 uint8_t label_uuid[16];
1086 btstack_parse_hex(message24_label_string, 16, label_uuid);
1087 mesh_virtual_address_register(label_uuid, 0x9736);
1088 test_receive_network_pdus(2, message24_network_pdus, message24_lower_transport_pdus, message24_upper_transport_pdu);
1089 }
TEST(MessageTest,Message24Send)1090 TEST(MessageTest, Message24Send){
1091 uint16_t netkey_index = 0;
1092 uint16_t appkey_index = 0;
1093 uint8_t ttl = 3;
1094 uint16_t src = 0x1234;
1095 uint32_t seq = 0x07080d;
1096 uint8_t szmic = 1;
1097
1098 load_network_key_nid_68();
1099 mesh_set_iv_index(0x12345677);
1100 mesh_sequence_number_set(seq);
1101 uint8_t label_uuid[16];
1102 btstack_parse_hex(message24_label_string, 16, label_uuid);
1103 mesh_virtual_address_t * virtual_address = mesh_virtual_address_register(label_uuid, 0x9736);
1104 uint16_t pseudo_dst = virtual_address->pseudo_dst;
1105 test_send_access_message(netkey_index, appkey_index, ttl, src, pseudo_dst, szmic, message24_upper_transport_pdu, 2, message24_lower_transport_pdus, message24_network_pdus);
1106 }
1107
1108 // Proxy Configuration Test
1109 char * proxy_config_pdus[] = {
1110 (char *) "0210386bd60efbbb8b8c28512e792d3711f4b526",
1111 };
1112 char * proxy_config_lower_transport_pdus[] = {
1113 (char *) "0000",
1114 };
1115 char * proxy_config_upper_transport_pdu = (char *) "ea0a00576f726c64";
TEST(MessageTest,ProxyConfigReceive)1116 TEST(MessageTest, ProxyConfigReceive){
1117 mesh_set_iv_index(0x12345678);
1118 load_network_key_nid_10();
1119 int i = 0;
1120 char ** network_pdus = proxy_config_pdus;
1121 test_network_pdu_len = strlen(network_pdus[i]) / 2;
1122 btstack_parse_hex(network_pdus[i], test_network_pdu_len, test_network_pdu_data);
1123 mesh_network_process_proxy_configuration_message(&test_network_pdu_data[1], test_network_pdu_len-1);
1124 while (received_proxy_pdu == NULL) {
1125 mock_process_hci_cmd();
1126 }
1127 char ** lower_transport_pdus = proxy_config_lower_transport_pdus;
1128 transport_pdu_len = strlen(lower_transport_pdus[i]) / 2;
1129 btstack_parse_hex(lower_transport_pdus[i], transport_pdu_len, transport_pdu_data);
1130
1131 uint8_t * lower_transport_pdu = mesh_network_pdu_data(received_proxy_pdu);
1132 uint8_t lower_transport_pdu_len = mesh_network_pdu_len(received_proxy_pdu);
1133
1134 // printf_hexdump(lower_transport_pdu, lower_transport_pdu_len);
1135
1136 CHECK_EQUAL( transport_pdu_len, lower_transport_pdu_len);
1137 CHECK_EQUAL_ARRAY(transport_pdu_data, lower_transport_pdu, transport_pdu_len);
1138
1139 // done
1140 mesh_network_message_processed_by_higher_layer(received_proxy_pdu);
1141 received_proxy_pdu = NULL;
1142 }
1143
1144
TEST(MessageTest,ProxyConfigSend)1145 TEST(MessageTest, ProxyConfigSend){
1146 uint16_t netkey_index = 0;
1147 uint8_t ctl = 1;
1148 uint8_t ttl = 0;
1149 uint16_t src = 1;
1150 uint16_t dest = 0;
1151 uint32_t seq = 1;
1152 uint8_t nid = 0x10;
1153 mesh_set_iv_index(0x12345678);
1154 load_network_key_nid_10();
1155 mesh_network_pdu_t * network_pdu = mesh_network_pdu_get();
1156 uint8_t data[] = { 0 , 0 };
1157 mesh_network_setup_pdu(network_pdu, netkey_index, nid, ctl, ttl, seq, src, dest, data, sizeof(data));
1158 mesh_network_encrypt_proxy_configuration_message(network_pdu);
1159 while (received_proxy_pdu == NULL) {
1160 mock_process_hci_cmd();
1161 }
1162 uint8_t * proxy_pdu_data = received_proxy_pdu->data;
1163 uint8_t proxy_pdu_len = received_proxy_pdu->len;
1164
1165 int i = 0;
1166 char ** network_pdus = proxy_config_pdus;
1167 transport_pdu_len = strlen(network_pdus[i]) / 2;
1168 btstack_parse_hex(network_pdus[i], transport_pdu_len, transport_pdu_data);
1169
1170 CHECK_EQUAL( transport_pdu_len-1, proxy_pdu_len);
1171 CHECK_EQUAL_ARRAY(transport_pdu_data+1, proxy_pdu_data, transport_pdu_len-1);
1172
1173 received_proxy_pdu = NULL;
1174
1175 mesh_network_pdu_free(network_pdu);
1176 }
1177
1178 static btstack_crypto_aes128_t crypto_request_aes128;
1179 static uint8_t plaintext[16];
1180 static uint8_t identity_key[16];
1181 static uint8_t hash[16];
1182 static uint8_t random_value[8];
1183
mesh_proxy_handle_get_aes128(void * arg)1184 static void mesh_proxy_handle_get_aes128(void * arg){
1185 UNUSED(arg);
1186 uint8_t expected_hash[8];
1187 uint8_t expected_random_value[8];
1188
1189 btstack_parse_hex("00861765aefcc57b", 8, expected_hash);
1190 CHECK_EQUAL_ARRAY(&hash[8], expected_hash, 8);
1191
1192 btstack_parse_hex("34ae608fbbc1f2c6", 8, expected_random_value);
1193 CHECK_EQUAL_ARRAY(random_value, expected_random_value, 8);
1194 }
1195
TEST(MessageTest,ServiceDataUsingNodeIdentityTest)1196 TEST(MessageTest, ServiceDataUsingNodeIdentityTest){
1197 btstack_parse_hex("34ae608fbbc1f2c6", 8, random_value);
1198 memset(plaintext, 0, sizeof(plaintext));
1199 memcpy(&plaintext[6] , random_value, 8);
1200 big_endian_store_16(plaintext, 14, 0x1201);
1201 // 84396c435ac48560b5965385253e210c
1202 btstack_parse_hex("84396c435ac48560b5965385253e210c", 16, identity_key);
1203 btstack_crypto_aes128_encrypt(&crypto_request_aes128, identity_key, plaintext, hash, mesh_proxy_handle_get_aes128, NULL);
1204 }
1205
1206 // Mesh v1.0, 8.2.1
1207 static btstack_crypto_aes128_cmac_t aes_cmac_request;
1208 static uint8_t k4_result[1];
handle_k4_result(void * arg)1209 static void handle_k4_result(void *arg){
1210 UNUSED(arg);
1211 printf("ApplicationkeyIDTest: %02x\n", k4_result[0]);
1212 CHECK_EQUAL( 0x26, k4_result[0]);
1213 }
TEST(MessageTest,ApplicationkeyIDTest)1214 TEST(MessageTest, ApplicationkeyIDTest){
1215 static uint8_t application_key[16];
1216 btstack_parse_hex("63964771734fbd76e3b40519d1d94a48", 16, application_key);
1217 mesh_k4(&aes_cmac_request, application_key, &k4_result[0], &handle_k4_result, NULL);
1218 }
1219
main(int argc,const char * argv[])1220 int main (int argc, const char * argv[]){
1221 return CommandLineTestRunner::RunAllTests(argc, argv);
1222 }
1223