From 1979df89758a177e919027f7e519e98ecc82d9a8 Mon Sep 17 00:00:00 2001 From: Deepak Venugopal Date: Tue, 28 Nov 2017 15:54:39 +0200 Subject: [PATCH] added status to MLR response and implemeted BMLR.ntf multicast. (#1492) --- source/6LoWPAN/Thread/thread_extension.c | 12 ++-- source/6LoWPAN/Thread/thread_extension_bbr.c | 62 ++++++++++++++++++- .../Thread/thread_extension_constants.h | 1 + 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/source/6LoWPAN/Thread/thread_extension.c b/source/6LoWPAN/Thread/thread_extension.c index 3eb57485617..38584769226 100644 --- a/source/6LoWPAN/Thread/thread_extension.c +++ b/source/6LoWPAN/Thread/thread_extension.c @@ -329,7 +329,7 @@ void thread_extension_init(int8_t interface_id, int8_t coap_service_id) cur->thread_info->extension_info->coap_service_id = coap_service_id; } -static int thread_extension_multicast_listener_report(protocol_interface_info_entry_t *cur, const uint8_t br_addr[16], const uint8_t address[16], uint32_t timeout, const uint8_t ml_eid[8]) +static int thread_extension_mlr_req_send(protocol_interface_info_entry_t *cur, const uint8_t br_addr[16], const uint8_t address[16]) { uint8_t payload[2 + 16 + 2 + 4 + 2 + 8]; uint8_t *ptr; @@ -340,12 +340,8 @@ static int thread_extension_multicast_listener_report(protocol_interface_info_en ptr = payload; ptr = thread_meshcop_tlv_data_write(ptr, TMFCOP_TLV_IPV6_ADDRESS, 16, address); - ptr = thread_meshcop_tlv_data_write_uint32(ptr, TMFCOP_TLV_TIMEOUT, timeout); - if (ml_eid) { - ptr = thread_tmfcop_tlv_data_write(ptr, TMFCOP_TLV_ML_EID, 8, ml_eid); - } - tr_debug("thread multicast listener report; timeout: %"PRIu32, timeout); + tr_debug("thread MLR.req send"); coap_service_request_send(thread_management_client_service_id_get(cur->id), COAP_REQUEST_OPTIONS_NONE, br_addr, THREAD_MANAGEMENT_PORT, COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_BBR_MCAST_LISTENER_REPORT, COAP_CT_OCTET_STREAM, payload, ptr - payload, thread_comercial_mlr_cb); @@ -510,7 +506,7 @@ void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t * // follow the Primary BBR set timeout + Small jitter added group->mld_timer = added ? mlr_timer: 0; // MLR is sent only for primary BBR for now, but this might change - thread_extension_multicast_listener_report(interface, br_ml_addr, group->group, group->mld_timer, interface->iid_slaac); + thread_extension_mlr_req_send(interface, br_ml_addr, group->group); #if 0 ns_list_foreach(thread_network_data_prefix_cache_entry_t, cur, &interface->thread_info->networkDataStorage.localPrefixList) { @@ -520,7 +516,7 @@ void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t * } thread_addr_write_mesh_local_16(br_ml_addr, br->routerID, interface->thread_info); tr_debug("Sending MLR.ntf to border router: %s", trace_ipv6(br_ml_addr)); - thread_extension_multicast_listener_report(interface, br_ml_addr, group->group, group->mld_timer, interface->iid_slaac); + thread_extension_mlr_req_send(interface, br_ml_addr, group->group, group->mld_timer, interface->iid_slaac); } } #endif diff --git a/source/6LoWPAN/Thread/thread_extension_bbr.c b/source/6LoWPAN/Thread/thread_extension_bbr.c index 2d44d6ee77d..d52bc96969e 100644 --- a/source/6LoWPAN/Thread/thread_extension_bbr.c +++ b/source/6LoWPAN/Thread/thread_extension_bbr.c @@ -528,6 +528,26 @@ static int thread_pbbr_bb_ans_cb(int8_t service_id, uint8_t source_address[16], // If delayed DUA registration entry is present send duplicate error code to DUA.response return 0; } +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) +{ + uint8_t payload[2 + 16 + 2 + 4 + 2]; + uint8_t *ptr; + + if (!br_addr || !address) { + return -1; + } + + ptr = payload; + ptr = thread_meshcop_tlv_data_write(ptr, TMFCOP_TLV_IPV6_ADDRESS, 16, address); + ptr = thread_meshcop_tlv_data_write_uint32(ptr, TMFCOP_TLV_TIMEOUT, timeout); + + tr_debug("thread BMLR.ntf send; timeout: %"PRIu32, timeout); + + coap_service_request_send(service_id, COAP_REQUEST_OPTIONS_NONE, br_addr, THREAD_MANAGEMENT_PORT, + COAP_MSG_TYPE_CONFIRMABLE, COAP_MSG_CODE_REQUEST_POST, THREAD_URI_BBR_BMLR_NTF, COAP_CT_OCTET_STREAM, payload, ptr - payload, NULL); + return 0; +} + static 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) { (void)source_address; @@ -536,22 +556,38 @@ static int thread_extension_bbr_mlr_cb(int8_t service_id, uint8_t source_address uint16_t addr_len; uint8_t *addr_data_ptr; uint32_t timeout_value; + uint8_t bbr_rloc_addr[16]; + uint8_t bbr_status = THREAD_BBR_STATUS_SUCCESS; + uint8_t payload[4]; + uint8_t *ptr; tr_info("Thread BBR MLR.ntf receive"); thread_pbbr_t *this = thread_border_router_find_by_service(service_id); + protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); sn_coap_msg_code_e response_code = COAP_MSG_CODE_RESPONSE_CHANGED; if (!this) { return -1; } + ptr = payload; // Set default value if not specified in message. timeout_value = this->mlr_timeout; addr_len = thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_IPV6_ADDRESS, &addr_data_ptr); - thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_TIMEOUT, &timeout_value); + //TODO in future check if commissioner + //thread_meshcop_tlv_data_get_uint32(request_ptr->payload_ptr, request_ptr->payload_len, TMFCOP_TLV_TIMEOUT, &timeout_value); + + // check if we are not primary bbr respond status 5 + if (0 != thread_extension_primary_bbr_get(cur, bbr_rloc_addr, NULL, NULL, NULL) || + !addr_get_entry(cur,bbr_rloc_addr)) { + // Primary BBR not present or I am not BBR + bbr_status = THREAD_BBR_STATUS_NOT_PRIMARY_BBR; + goto send_response; + } + // TODO this can have multiple address please process all if ( addr_len != 16) { tr_err("Invalid /n/mr message"); 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 tr_debug("Multicast address: %s Timeout value: %"PRIu32, trace_ipv6(addr_data_ptr),timeout_value); + // TODO do not decrease the timeout value, but only applies if commissioner support added multicast_fwd_add(this->interface_id, addr_data_ptr, timeout_value); + // send BMLR.ntf message to backend + thread_extension_bbr_bmlr_req_send(this->br_service_id, this->pbbr_multicast_address, addr_data_ptr, timeout_value); + send_response: + if (request_ptr->msg_type == COAP_MSG_TYPE_CONFIRMABLE) { - coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, NULL, 0); + ptr = thread_tmfcop_tlv_data_write_uint8(ptr, TMFCOP_TLV_STATUS, bbr_status); + coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr -payload); return 0; } return -1; } +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) +{ + (void)source_address; + (void)source_port; + (void)service_id; + (void)request_ptr; + + tr_info("Thread BBR BMLR.ntf receive"); + + return -1; +} static 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) { @@ -776,6 +829,7 @@ static int thread_extension_bbr_pbbr_start(thread_pbbr_t *this) // Register Mesh address registration URI coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_MCAST_LISTENER_REPORT, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_mlr_cb); + coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_BMLR_NTF, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_bmlr_cb); coap_service_register_uri(this->coap_service_id, THREAD_URI_BBR_DOMAIN_ADDRESS_REGISTRATION, COAP_SERVICE_ACCESS_POST_ALLOWED, thread_extension_bbr_dua_cb); // Register Mesh side relay URI 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) if (!cur) { return; } + if (thread_attach_ready(cur) != 0) { + //not yet attached + return; + } // Check if there is already pbbr if present dont enable if ( 0 == thread_extension_primary_bbr_get(cur, NULL, NULL, NULL, NULL) ) { // Primary bbr present in network I am secondary diff --git a/source/6LoWPAN/Thread/thread_extension_constants.h b/source/6LoWPAN/Thread/thread_extension_constants.h index e66fdc41ff7..031fb756c01 100644 --- a/source/6LoWPAN/Thread/thread_extension_constants.h +++ b/source/6LoWPAN/Thread/thread_extension_constants.h @@ -49,6 +49,7 @@ typedef struct discovery_additional_info { #define THREAD_DEFAULT_NMKP_PORT 49193 #define THREAD_URI_BBR_MCAST_LISTENER_REPORT "n/mr" //<* 1.2 feature +#define THREAD_URI_BBR_BMLR_NTF "n/bmr" //<* 1.2 feature #define THREAD_URI_BBR_DOMAIN_ADDRESS_REGISTRATION "n/dr" //<* 1.2 feature #define THREAD_URI_BBR_TRI_RX_NTF "c/rxr" //<* Backbone border router #define THREAD_URI_BBR_NMK_RX_NTF "c/rxb" //<* Backbone border router