@@ -229,7 +229,7 @@ static void thread_border_router_bb_ans_send(thread_pbbr_t *this, uint8_t *desti
229
229
return ;
230
230
}
231
231
232
- static void thread_border_router_bb_qry_send (thread_pbbr_t * this , uint8_t * target_eid_ptr , uint16_t * rloc_ptr )
232
+ static void thread_border_router_bb_qry_send (thread_pbbr_t * this , const uint8_t * target_eid_ptr , uint16_t * rloc_ptr )
233
233
{
234
234
uint8_t * ptr ;
235
235
uint8_t payload [22 ];
@@ -446,7 +446,7 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16],
446
446
if (!link_configuration_ptr || !cur ) {
447
447
return -1 ;
448
448
}
449
- if (addr_is_assigned_to_interface (cur ,source_address )) {
449
+ if (addr_interface_address_compare (cur , source_address ) == 0 ) {
450
450
// Received from own address no need to process
451
451
return 0 ;
452
452
}
@@ -473,15 +473,57 @@ static int thread_pbbr_bb_qry_cb(int8_t service_id, uint8_t source_address[16],
473
473
474
474
return 0 ;
475
475
}
476
+
477
+ static int thread_pbbr_dua_duplicate_address_detection (int8_t service_id , uint8_t * addr_data_ptr , uint8_t * ml_eid_ptr )
478
+ {
479
+ thread_pbbr_t * this = thread_border_router_find_by_service (service_id );
480
+
481
+ if (!this ) {
482
+ return -1 ;
483
+ }
484
+
485
+ protocol_interface_info_entry_t * cur = protocol_stack_interface_info_get_by_id (this -> interface_id );
486
+ duplicate_dua_tr_t * tr_ptr = thread_border_router_dup_tr_find (this -> interface_id ,addr_data_ptr );
487
+
488
+ if (!tr_ptr ) {
489
+ return -1 ;
490
+ }
491
+
492
+ ipv6_route_t * route = ipv6_route_choose_next_hop (addr_data_ptr , this -> interface_id , NULL );
493
+ if (!route || route -> prefix_len != 128 || !route -> on_link || route -> info .source != ROUTE_THREAD_PROXIED_HOST ) {
494
+ // Not found
495
+ tr_debug ("route not found" );
496
+ return 0 ;
497
+ }
498
+
499
+ // We have pending request and received answer
500
+ if (memcmp (ml_eid_ptr ,tr_ptr -> ml_eid , 8 ) != 0 ){
501
+ // Different ml_eid but same address means duplicate address detected
502
+ thread_resolution_client_address_error (this -> interface_id , tr_ptr -> source_address , tr_ptr -> target_eid , tr_ptr -> ml_eid );
503
+ ipv6_neighbour_t * neighbour_entry ;
504
+ neighbour_entry = ipv6_neighbour_lookup (& cur -> ipv6_neighbour_cache , tr_ptr -> target_eid );
505
+ if (neighbour_entry ) {
506
+ tr_debug ("Remove from neigh Cache: %s" , tr_ipv6 (tr_ptr -> target_eid ));
507
+ ipv6_neighbour_entry_remove (& cur -> ipv6_neighbour_cache , neighbour_entry );
508
+ }
509
+ ipv6_route_delete (route -> prefix , route -> prefix_len , this -> interface_id , route -> info .next_hop_addr , ROUTE_THREAD_PROXIED_HOST );
510
+ }
511
+ return 0 ;
512
+
513
+ // TODO check last transaction time for migrated device if this answer is newer delete entry
514
+ // ipv6_route_delete(route->prefix, route->prefix_len, this->interface_id, route->info.next_hop_addr, ROUTE_THREAD_PROXIED_HOST);
515
+ }
516
+
476
517
static int thread_pbbr_bb_ans_cb (int8_t service_id , uint8_t source_address [16 ], uint16_t source_port , sn_coap_hdr_s * request_ptr )
477
518
{
478
519
(void )service_id ;
479
520
(void )source_port ;
480
521
(void )request_ptr ;
481
- uint16_t addr_len , ml_eid_len , last_transaction_time_len , network_name_len ;
522
+ uint16_t addr_len , ml_eid_len , last_transaction_time_len ;
482
523
uint8_t * addr_data_ptr ;
524
+ uint16_t rloc16 ;
525
+ uint8_t destination_address [16 ] = {0 };
483
526
uint8_t * ml_eid_ptr ;
484
- uint8_t * network_name_ptr ;
485
527
uint32_t last_transaction_time ;
486
528
tr_info ("Thread BBR BB_ANS.ntf receive" );
487
529
thread_pbbr_t * this = thread_border_router_find_by_service (service_id );
@@ -495,54 +537,51 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16],
495
537
if (!link_configuration_ptr || !cur ) {
496
538
return -1 ;
497
539
}
498
- if (addr_is_assigned_to_interface (cur ,source_address )) {
540
+ if (addr_interface_address_compare (cur , source_address ) == 0 ) {
499
541
// Received from own address no need to process
500
542
return 0 ;
501
543
}
502
544
503
545
addr_len = thread_meshcop_tlv_find (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_TARGET_EID , & addr_data_ptr );
504
546
ml_eid_len = thread_meshcop_tlv_find (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_ML_EID , & ml_eid_ptr );
505
547
last_transaction_time_len = thread_meshcop_tlv_data_get_uint32 (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_LAST_TRANSACTION_TIME , & last_transaction_time );
506
- network_name_len = thread_meshcop_tlv_find (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_LAST_TRANSACTION_TIME , & network_name_ptr );
507
548
508
549
if ( addr_len < 16 || ml_eid_len < 8 || last_transaction_time_len < 4 ) {
509
550
tr_err ("Invalid message" );
510
551
return 0 ;
511
552
}
512
553
513
- // Network name must match
514
- if (stringlen ((char * )link_configuration_ptr -> name ,16 ) != network_name_len || memcmp (link_configuration_ptr -> name ,network_name_ptr ,network_name_len ) != 0 ) {
554
+ if ((thread_pbbr_dua_duplicate_address_detection (service_id , addr_data_ptr , ml_eid_ptr ) == 0 )) {
515
555
return 0 ;
516
556
}
517
557
518
- ipv6_route_t * route = ipv6_route_choose_next_hop (addr_data_ptr , this -> interface_id , NULL );
519
- if (!route || route -> prefix_len != 128 || !route -> on_link || route -> info .source != ROUTE_THREAD_PROXIED_HOST ) {
520
- // Not found
558
+ // If rloc16 is present then a/an is sent to the thread device with the rloc
559
+ if (thread_tmfcop_tlv_data_get_uint16 (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_RLOC16 , & rloc16 ) != 2 ) {
521
560
return 0 ;
522
561
}
523
562
524
- duplicate_dua_tr_t * tr_ptr = thread_border_router_dup_tr_find (this -> interface_id ,addr_data_ptr );
525
- if (tr_ptr ) {
526
- // We have pending request and received answer
527
- if (memcmp (ml_eid_ptr ,tr_ptr -> ml_eid , 8 ) != 0 ){
528
- // Different ml_eid but same address means duplicate address detected
529
- thread_resolution_client_address_error (this -> interface_id , tr_ptr -> source_address , tr_ptr -> target_eid , tr_ptr -> ml_eid );
530
- ipv6_neighbour_t * neighbour_entry ;
531
- neighbour_entry = ipv6_neighbour_lookup (& cur -> ipv6_neighbour_cache , tr_ptr -> target_eid );
532
- if (neighbour_entry ) {
533
- tr_debug ("Remove from neigh Cache: %s" , tr_ipv6 (tr_ptr -> target_eid ));
534
- ipv6_neighbour_entry_remove (& cur -> ipv6_neighbour_cache , neighbour_entry );
535
- }
536
- ipv6_route_delete (route -> prefix , route -> prefix_len , this -> interface_id , route -> info .next_hop_addr , ROUTE_THREAD_PROXIED_HOST );
537
- } else {
538
- // Roaming case lets inform other pbbr that we have newest
539
- thread_border_router_bb_ans_send (this , source_address , tr_ptr -> target_eid , tr_ptr -> ml_eid , 0 , link_configuration_ptr -> name , NULL );
540
- }
541
- } else {
542
- ipv6_route_delete (route -> prefix , route -> prefix_len , this -> interface_id , route -> info .next_hop_addr , ROUTE_THREAD_PROXIED_HOST );
543
- }
563
+ // form the destination address to which the a/an is sent
564
+ thread_addr_write_mesh_local_16 (destination_address , rloc16 , cur -> thread_info );
544
565
545
- // If delayed DUA registration entry is present send duplicate error code to DUA.response
566
+ // Address query pending send address notification, include tlvs: target eid, rloc16 tlv of bbr, mleid, and last transaction time
567
+ uint8_t payload [16 + 2 + 8 + 4 ]; // Target eid + Rloc16 + MLEID + transaction time
568
+ uint8_t * ptr ;
569
+ ptr = payload ;
570
+ ptr = thread_tmfcop_tlv_data_write (ptr , TMFCOP_TLV_TARGET_EID , 16 , addr_data_ptr );
571
+ ptr = thread_tmfcop_tlv_data_write_uint16 (ptr , TMFCOP_TLV_RLOC16 , cur -> thread_info -> routerShortAddress );
572
+ ptr = thread_tmfcop_tlv_data_write (ptr , TMFCOP_TLV_ML_EID , 8 , ml_eid_ptr );
573
+ ptr = thread_tmfcop_tlv_data_write_uint32 (ptr , TMFCOP_TLV_LAST_TRANSACTION_TIME , last_transaction_time );
574
+
575
+ // XXX "Accepted" response?
576
+
577
+ /* We don't require a response, so we don't specify a callback. Library
578
+ * should retry itself until it gets an ACK.
579
+ */
580
+ coap_service_request_send (this -> coap_service_id , COAP_REQUEST_OPTIONS_ADDRESS_SHORT ,
581
+ destination_address , THREAD_MANAGEMENT_PORT ,
582
+ COAP_MSG_TYPE_CONFIRMABLE , COAP_MSG_CODE_REQUEST_POST ,
583
+ THREAD_URI_ADDRESS_NOTIFICATION , COAP_CT_OCTET_STREAM ,
584
+ payload , ptr - payload , NULL );
546
585
return 0 ;
547
586
}
548
587
static int thread_extension_bbr_bmlr_req_send (int8_t service_id , const uint8_t br_addr [16 ], const uint8_t * address_ptr , uint8_t addr_len , uint32_t timeout )
@@ -997,7 +1036,7 @@ void thread_extension_bbr_delete(int8_t interface_id)
997
1036
ns_dyn_mem_free (this );
998
1037
}
999
1038
1000
- bool thread_extension_bbr_nd_query_process (protocol_interface_info_entry_t * cur , const uint8_t * target_addr )
1039
+ bool thread_extension_bbr_nd_query_process (protocol_interface_info_entry_t * cur , const uint8_t * target_addr , uint16_t rloc )
1001
1040
{
1002
1041
uint8_t domain_prefix [8 ];
1003
1042
if (thread_version < THREAD_VERSION_1_2 ) {
@@ -1010,12 +1049,17 @@ bool thread_extension_bbr_nd_query_process(protocol_interface_info_entry_t *cur,
1010
1049
if (!this -> pbbr_started ) {
1011
1050
return false;
1012
1051
}
1013
- // if we have DUA addressing enabled
1014
- if ( thread_extension_network_prefix_get (cur -> id , NULL , domain_prefix , NULL ) == 0 &&
1015
- bitsequal (domain_prefix ,target_addr ,64 ) ) {
1016
- return true;
1052
+ // if we do not have DUA addressing enabled
1053
+ if ( !thread_extension_network_prefix_get (cur -> id , NULL , domain_prefix , NULL ) == 0 ||
1054
+ !bitsequal (domain_prefix ,target_addr ,64 ) ) {
1055
+ return false;
1056
+
1017
1057
}
1018
- return false;
1058
+
1059
+ // SEND BB_QRY
1060
+ thread_border_router_bb_qry_send (this ,target_addr ,& rloc );
1061
+ return true;
1062
+
1019
1063
}
1020
1064
1021
1065
0 commit comments