@@ -528,6 +528,26 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16],
528528 // If delayed DUA registration entry is present send duplicate error code to DUA.response
529529 return 0 ;
530530}
531+ static int thread_extension_bbr_bmlr_req_send (int8_t service_id , const uint8_t br_addr [16 ], const uint8_t address [16 ], uint32_t timeout )
532+ {
533+ uint8_t payload [2 + 16 + 2 + 4 + 2 ];
534+ uint8_t * ptr ;
535+
536+ if (!br_addr || !address ) {
537+ return -1 ;
538+ }
539+
540+ ptr = payload ;
541+ ptr = thread_meshcop_tlv_data_write (ptr , TMFCOP_TLV_IPV6_ADDRESS , 16 , address );
542+ ptr = thread_meshcop_tlv_data_write_uint32 (ptr , TMFCOP_TLV_TIMEOUT , timeout );
543+
544+ tr_debug ("thread BMLR.ntf send; timeout: %" PRIu32 , timeout );
545+
546+ coap_service_request_send (service_id , COAP_REQUEST_OPTIONS_NONE , br_addr , THREAD_MANAGEMENT_PORT ,
547+ COAP_MSG_TYPE_CONFIRMABLE , COAP_MSG_CODE_REQUEST_POST , THREAD_URI_BBR_BMLR_NTF , COAP_CT_OCTET_STREAM , payload , ptr - payload , NULL );
548+ return 0 ;
549+ }
550+
531551static int thread_extension_bbr_mlr_cb (int8_t service_id , uint8_t source_address [16 ], uint16_t source_port , sn_coap_hdr_s * request_ptr )
532552{
533553 (void )source_address ;
@@ -536,22 +556,38 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address
536556 uint16_t addr_len ;
537557 uint8_t * addr_data_ptr ;
538558 uint32_t timeout_value ;
559+ uint8_t bbr_rloc_addr [16 ];
560+ uint8_t bbr_status = THREAD_BBR_STATUS_SUCCESS ;
561+ uint8_t payload [4 ];
562+ uint8_t * ptr ;
539563
540564 tr_info ("Thread BBR MLR.ntf receive" );
541565
542566 thread_pbbr_t * this = thread_border_router_find_by_service (service_id );
567+ protocol_interface_info_entry_t * cur = protocol_stack_interface_info_get_by_id (this -> interface_id );
543568 sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED ;
544569
545570 if (!this ) {
546571 return -1 ;
547572 }
573+ ptr = payload ;
548574
549575 // Set default value if not specified in message.
550576 timeout_value = this -> mlr_timeout ;
551577
552578 addr_len = thread_meshcop_tlv_find (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_IPV6_ADDRESS , & addr_data_ptr );
553- thread_meshcop_tlv_data_get_uint32 (request_ptr -> payload_ptr , request_ptr -> payload_len , TMFCOP_TLV_TIMEOUT , & timeout_value );
579+ //TODO in future check if commissioner
580+ //thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_TIMEOUT, &timeout_value);
581+
582+ // check if we are not primary bbr respond status 5
583+ if (0 != thread_extension_primary_bbr_get (cur , bbr_rloc_addr , NULL , NULL , NULL ) ||
584+ !addr_get_entry (cur ,bbr_rloc_addr )) {
585+ // Primary BBR not present or I am not BBR
586+ bbr_status = THREAD_BBR_STATUS_NOT_PRIMARY_BBR ;
587+ goto send_response ;
588+ }
554589
590+ // TODO this can have multiple address please process all
555591 if ( addr_len != 16 ) {
556592 tr_err ("Invalid /n/mr message" );
557593 response_code = COAP_MSG_CODE_RESPONSE_BAD_REQUEST ;
@@ -560,16 +596,33 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address
560596
561597 tr_debug ("Multicast address: %s Timeout value: %" PRIu32 , trace_ipv6 (addr_data_ptr ),timeout_value );
562598
599+ // TODO do not decrease the timeout value, but only applies if commissioner support added
563600 multicast_fwd_add (this -> interface_id , addr_data_ptr , timeout_value );
564601
602+ // send BMLR.ntf message to backend
603+ thread_extension_bbr_bmlr_req_send (this -> br_service_id , this -> pbbr_multicast_address , addr_data_ptr , timeout_value );
604+
565605send_response :
606+
566607 if (request_ptr -> msg_type == COAP_MSG_TYPE_CONFIRMABLE ) {
567- coap_service_response_send (this -> coap_service_id , COAP_REQUEST_OPTIONS_NONE , request_ptr , response_code , COAP_CT_OCTET_STREAM , NULL , 0 );
608+ ptr = thread_tmfcop_tlv_data_write_uint8 (ptr , TMFCOP_TLV_STATUS , bbr_status );
609+ coap_service_response_send (this -> coap_service_id , COAP_REQUEST_OPTIONS_NONE , request_ptr , response_code , COAP_CT_OCTET_STREAM , payload , ptr - payload );
568610 return 0 ;
569611 }
570612
571613 return -1 ;
572614}
615+ static int thread_extension_bbr_bmlr_cb (int8_t service_id , uint8_t source_address [16 ], uint16_t source_port , sn_coap_hdr_s * request_ptr )
616+ {
617+ (void )source_address ;
618+ (void )source_port ;
619+ (void )service_id ;
620+ (void )request_ptr ;
621+
622+ tr_info ("Thread BBR BMLR.ntf receive" );
623+
624+ return -1 ;
625+ }
573626
574627static int thread_extension_bbr_dua_cb (int8_t service_id , uint8_t source_address [16 ], uint16_t source_port , sn_coap_hdr_s * request_ptr )
575628{
@@ -776,6 +829,7 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this)
776829
777830 // Register Mesh address registration URI
778831 coap_service_register_uri (this -> coap_service_id , THREAD_URI_BBR_MCAST_LISTENER_REPORT , COAP_SERVICE_ACCESS_POST_ALLOWED , thread_extension_bbr_mlr_cb );
832+ coap_service_register_uri (this -> coap_service_id , THREAD_URI_BBR_BMLR_NTF , COAP_SERVICE_ACCESS_POST_ALLOWED , thread_extension_bbr_bmlr_cb );
779833 coap_service_register_uri (this -> coap_service_id , THREAD_URI_BBR_DOMAIN_ADDRESS_REGISTRATION , COAP_SERVICE_ACCESS_POST_ALLOWED , thread_extension_bbr_dua_cb );
780834 // Register Mesh side relay URI
781835 coap_service_register_uri (this -> coap_service_id , THREAD_URI_BBR_TRI_RX_NTF , COAP_SERVICE_ACCESS_POST_ALLOWED , thread_pbbr_relay_to_tri_cb );
@@ -890,6 +944,10 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds)
890944 if (!cur ) {
891945 return ;
892946 }
947+ if (thread_attach_ready (cur ) != 0 ) {
948+ //not yet attached
949+ return ;
950+ }
893951 // Check if there is already pbbr if present dont enable
894952 if ( 0 == thread_extension_primary_bbr_get (cur , NULL , NULL , NULL , NULL ) ) {
895953 // Primary bbr present in network I am secondary
0 commit comments