Merge pull request #7737 from deepakvenugopal/master

Nanostack release for Mbed OS 5.10
pull/7780/head
Cruz Monrreal 2018-08-13 09:13:58 -05:00 committed by GitHub
commit 70c3bdfffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
180 changed files with 8568 additions and 4933 deletions

View File

@ -353,6 +353,19 @@ extern int8_t coap_service_set_duplicate_message_buffer(int8_t service_id, uint8
*/ */
extern int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert, uint16_t cert_len, const unsigned char *priv_key, uint8_t priv_key_len); extern int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert, uint16_t cert_len, const unsigned char *priv_key, uint8_t priv_key_len);
/**
* \brief Set CoAP blockwise payload size
*
* Set CoAP blockwise payload limit. If payload is bigger than configured limit, CoAP message will use blockwise option when sending.
*
* \param service_id Id number of the current service.
* \param size Blockwise size. Valid sizes are 16, 32, 64, 128, 256, 512 and 1024 bytes
*
* \return -1 For failure
*- 0 For success
*/
extern int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -175,6 +175,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const
} }
} }
if(!to_be_removed){ if(!to_be_removed){
tr_err("max session count exceeded");
return NULL; return NULL;
} }
@ -188,6 +189,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const
} }
} }
if(handshakes >= max_handshakes) { if(handshakes >= max_handshakes) {
tr_err("ongoing handshakes exceeded");
return NULL; return NULL;
} }
@ -215,6 +217,7 @@ static secure_session_t *secure_session_create(internal_socket_t *parent, const
this->sec_handler = coap_security_create(parent->socket, this->timer.id, this, secure_mode, this->sec_handler = coap_security_create(parent->socket, this->timer.id, this, secure_mode,
&secure_session_sendto, &secure_session_recvfrom, &start_timer, &timer_status); &secure_session_sendto, &secure_session_recvfrom, &start_timer, &timer_status);
if( !this->sec_handler ){ if( !this->sec_handler ){
tr_err("security create failed");
ns_dyn_mem_free(this); ns_dyn_mem_free(this);
return NULL; return NULL;
} }
@ -401,7 +404,6 @@ static int send_to_real_socket(int8_t socket_id, const ns_address_t *address, co
ns_cmsghdr_t *cmsg; ns_cmsghdr_t *cmsg;
ns_in6_pktinfo_t *pktinfo; ns_in6_pktinfo_t *pktinfo;
tr_debug("send from source address %s", trace_array(source_address, 16));
msghdr.msg_control = ancillary_databuffer; msghdr.msg_control = ancillary_databuffer;
msghdr.msg_controllen = sizeof(ancillary_databuffer); msghdr.msg_controllen = sizeof(ancillary_databuffer);
@ -647,9 +649,11 @@ static void secure_recv_sckt_msg(void *cb_res)
session->last_contact_time = coap_service_get_internal_timer_ticks(); session->last_contact_time = coap_service_get_internal_timer_ticks();
// Start handshake // Start handshake
if (!coap_security_handler_is_started(session->sec_handler)) { if (!coap_security_handler_is_started(session->sec_handler)) {
coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, sock->timeout_min, sock->timeout_max); if(-1 == coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, sock->timeout_min, sock->timeout_max)) {
tr_err("Connection start failed");
secure_session_delete(session);
}
ns_dyn_mem_free(keys._key); ns_dyn_mem_free(keys._key);
} }
} else { } else {
//Continue handshake //Continue handshake
@ -742,11 +746,16 @@ int coap_connection_handler_virtual_recv(coap_conn_handler_t *handler, uint8_t a
if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, address, port, &keys)) { if (sock->parent->_get_password_cb && 0 == sock->parent->_get_password_cb(sock->socket, address, port, &keys)) {
session = secure_session_create(sock, address, port, keys.mode); session = secure_session_create(sock, address, port, keys.mode);
if (!session) { if (!session) {
tr_err("coap_connection_handler_virtual_recv session creation failed - OOM"); tr_err("coap_connection_handler_virtual_recv session creation failed");
ns_dyn_mem_free(keys._key); ns_dyn_mem_free(keys._key);
return -1; return -1;
} }
coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max); if (-1 == coap_security_handler_connect_non_blocking(session->sec_handler, true, DTLS, keys, handler->socket->timeout_min, handler->socket->timeout_max)) {
tr_err("Connection start failed");
ns_dyn_mem_free(keys._key);
secure_session_delete(session);
return -1;
}
ns_dyn_mem_free(keys._key); ns_dyn_mem_free(keys._key);
return 0; return 0;
} else { } else {

View File

@ -20,6 +20,7 @@
#include "coap_service_api_internal.h" #include "coap_service_api_internal.h"
#include "coap_message_handler.h" #include "coap_message_handler.h"
#include "mbed-coap/sn_coap_protocol.h" #include "mbed-coap/sn_coap_protocol.h"
#include "source/include/sn_coap_protocol_internal.h"
#include "socket_api.h" #include "socket_api.h"
#include "ns_types.h" #include "ns_types.h"
#include "ns_list.h" #include "ns_list.h"
@ -138,7 +139,6 @@ void transaction_delete(coap_transaction_t *this)
if (!coap_message_handler_transaction_valid(this)) { if (!coap_message_handler_transaction_valid(this)) {
return; return;
} }
ns_list_remove(&request_list, this); ns_list_remove(&request_list, this);
transaction_free(this); transaction_free(this);
@ -163,11 +163,14 @@ void transactions_delete_all(uint8_t *address_ptr, uint16_t port)
static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param) static int8_t coap_rx_function(sn_coap_hdr_s *resp_ptr, sn_nsdl_addr_s *address_ptr, void *param)
{ {
coap_transaction_t *this = NULL; coap_transaction_t *this = NULL;
(void)address_ptr;
(void)param; (void)param;
if (resp_ptr->coap_status == COAP_STATUS_BUILDER_BLOCK_SENDING_DONE) {
return 0;
}
tr_warn("transaction was not handled %d", resp_ptr->msg_id); tr_warn("transaction was not handled %d", resp_ptr->msg_id);
if (!resp_ptr) { if (!resp_ptr || !address_ptr) {
return -1; return -1;
} }
if(resp_ptr->token_ptr){ if(resp_ptr->token_ptr){
@ -193,7 +196,7 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint
} }
coap_msg_handler_t *handle; coap_msg_handler_t *handle;
handle = used_malloc_func_ptr(sizeof(coap_msg_handler_t)); handle = ns_dyn_mem_alloc(sizeof(coap_msg_handler_t));
if (handle == NULL) { if (handle == NULL) {
return NULL; return NULL;
} }
@ -207,13 +210,16 @@ coap_msg_handler_t *coap_message_handler_init(void *(*used_malloc_func_ptr)(uint
handle->coap = sn_coap_protocol_init(used_malloc_func_ptr, used_free_func_ptr, used_tx_callback_ptr, &coap_rx_function); handle->coap = sn_coap_protocol_init(used_malloc_func_ptr, used_free_func_ptr, used_tx_callback_ptr, &coap_rx_function);
if( !handle->coap ){ if( !handle->coap ){
used_free_func_ptr(handle); ns_dyn_mem_free(handle);
return NULL; return NULL;
} }
/* Set default buffer size for CoAP duplicate message detection */ /* Set default buffer size for CoAP duplicate message detection */
sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE); sn_coap_protocol_set_duplicate_buffer_size(handle->coap, DUPLICATE_MESSAGE_BUFFER_SIZE);
/* Set default blockwise message size. */
sn_coap_protocol_set_block_size(handle->coap, DEFAULT_BLOCKWISE_DATA_SIZE);
/* Set default CoAP retransmission paramters */ /* Set default CoAP retransmission paramters */
sn_coap_protocol_set_retransmission_parameters(handle->coap, COAP_RESENDING_COUNT, COAP_RESENDING_INTERVAL); sn_coap_protocol_set_retransmission_parameters(handle->coap, COAP_RESENDING_COUNT, COAP_RESENDING_INTERVAL);
@ -263,6 +269,7 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
sn_nsdl_addr_s src_addr; sn_nsdl_addr_s src_addr;
sn_coap_hdr_s *coap_message; sn_coap_hdr_s *coap_message;
int16_t ret_val = 0; int16_t ret_val = 0;
coap_transaction_t *this = NULL;
if (!cb || !handle) { if (!cb || !handle) {
return -1; return -1;
@ -273,8 +280,19 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; src_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
src_addr.port = port; src_addr.port = port;
coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, NULL); coap_transaction_t *transaction_ptr = transaction_create();
if (!transaction_ptr) {
return -1;
}
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id);
transaction_ptr->client_request = false;// this is server transaction
memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16);
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
transaction_ptr->remote_port = port;
coap_message = sn_coap_protocol_parse(handle->coap, &src_addr, data_len, data_ptr, transaction_ptr);
if (coap_message == NULL) { if (coap_message == NULL) {
transaction_delete(transaction_ptr);
tr_err("CoAP Parsing failed"); tr_err("CoAP Parsing failed");
return -1; return -1;
} }
@ -284,36 +302,26 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
/* Check, if coap itself sends response, or block receiving is ongoing... */ /* Check, if coap itself sends response, or block receiving is ongoing... */
if (coap_message->coap_status != COAP_STATUS_OK && coap_message->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) { if (coap_message->coap_status != COAP_STATUS_OK && coap_message->coap_status != COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) {
tr_debug("CoAP library responds"); tr_debug("CoAP library responds");
transaction_delete(transaction_ptr);
ret_val = -1; ret_val = -1;
goto exit; goto exit;
} }
/* Request received */ /* Request received */
if (coap_message->msg_code > 0 && coap_message->msg_code < 32) { if (coap_message->msg_code > 0 && coap_message->msg_code < 32) {
coap_transaction_t *transaction_ptr = transaction_create(); transaction_ptr->msg_id = coap_message->msg_id;
if (transaction_ptr) { transaction_ptr->req_msg_type = coap_message->msg_type;
transaction_ptr->service_id = coap_service_id_find_by_socket(socket_id); if (coap_message->token_len) {
transaction_ptr->msg_id = coap_message->msg_id; memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len);
transaction_ptr->client_request = false;// this is server transaction transaction_ptr->token_len = coap_message->token_len;
transaction_ptr->req_msg_type = coap_message->msg_type;
memcpy(transaction_ptr->local_address, *(dst_addr_ptr) == 0xFF ? ns_in6addr_any : dst_addr_ptr, 16);
memcpy(transaction_ptr->remote_address, source_addr_ptr, 16);
if (coap_message->token_len) {
memcpy(transaction_ptr->token, coap_message->token_ptr, coap_message->token_len);
transaction_ptr->token_len = coap_message->token_len;
}
transaction_ptr->remote_port = port;
if (cb(socket_id, coap_message, transaction_ptr) < 0) {
// negative return value = message ignored -> delete transaction
transaction_delete(transaction_ptr);
}
goto exit;
} else {
ret_val = -1;
} }
if (cb(socket_id, coap_message, transaction_ptr) < 0) {
// negative return value = message ignored -> delete transaction
transaction_delete(transaction_ptr);
}
goto exit;
/* Response received */ /* Response received */
} else { } else {
coap_transaction_t *this = NULL;
if (coap_message->token_ptr) { if (coap_message->token_ptr) {
this = transaction_find_client_by_token(coap_message->token_ptr, coap_message->token_len, source_addr_ptr, port); this = transaction_find_client_by_token(coap_message->token_ptr, coap_message->token_len, source_addr_ptr, port);
} }
@ -331,6 +339,10 @@ int16_t coap_message_handler_coap_msg_process(coap_msg_handler_t *handle, int8_t
} }
exit: exit:
if (coap_message->coap_status == COAP_STATUS_PARSER_BLOCKWISE_MSG_RECEIVED) {
handle->sn_coap_service_free(coap_message->payload_ptr);
}
sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message); sn_coap_parser_release_allocated_coap_msg_mem(handle->coap, coap_message);
return ret_val; return ret_val;
@ -350,7 +362,7 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
tr_debug("Service %d, send CoAP request payload_len %d", service_id, payload_len); tr_debug("Service %d, send CoAP request payload_len %d", service_id, payload_len);
transaction_ptr = transaction_create(); transaction_ptr = transaction_create();
if (!uri || !transaction_ptr) { if (!uri || !transaction_ptr || !handle) {
return 0; return 0;
} }
@ -383,7 +395,10 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
request.payload_len = payload_len; request.payload_len = payload_len;
request.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify... request.payload_ptr = (uint8_t *) payload_ptr; // Cast away const and trust that nsdl doesn't modify...
data_len = sn_coap_builder_calc_needed_packet_data_size(&request);
prepare_blockwise_message(handle->coap, &request);
data_len = sn_coap_builder_calc_needed_packet_data_size_2(&request, sn_coap_protocol_get_configured_blockwise_size(handle->coap));
data_ptr = own_alloc(data_len); data_ptr = own_alloc(data_len);
if(data_len > 0 && !data_ptr){ if(data_len > 0 && !data_ptr){
transaction_delete(transaction_ptr); transaction_delete(transaction_ptr);
@ -408,6 +423,10 @@ uint16_t coap_message_handler_request_send(coap_msg_handler_t *handle, int8_t se
// Free allocated data // Free allocated data
own_free(data_ptr); own_free(data_ptr);
if(request.options_list_ptr) {
own_free(request.options_list_ptr);
}
if(request_response_cb == NULL){ if(request_response_cb == NULL){
//No response expected //No response expected
return 0; return 0;
@ -426,8 +445,10 @@ static int8_t coap_message_handler_resp_build_and_send(coap_msg_handler_t *handl
dst_addr.addr_len = 16; dst_addr.addr_len = 16;
dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6; dst_addr.type = SN_NSDL_ADDRESS_TYPE_IPV6;
dst_addr.port = transaction_ptr->remote_port; dst_addr.port = transaction_ptr->remote_port;
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
data_len = sn_coap_builder_calc_needed_packet_data_size(coap_msg_ptr); prepare_blockwise_message(handle->coap, coap_msg_ptr);
#endif
data_len = sn_coap_builder_calc_needed_packet_data_size_2(coap_msg_ptr, sn_coap_protocol_get_configured_blockwise_size(handle->coap));
data_ptr = own_alloc(data_len); data_ptr = own_alloc(data_len);
if (data_len > 0 && !data_ptr) { if (data_len > 0 && !data_ptr) {
return -1; return -1;

View File

@ -606,3 +606,14 @@ int8_t coap_service_certificate_set(int8_t service_id, const unsigned char *cert
return 0; return 0;
} }
int8_t coap_service_blockwise_size_set(int8_t service_id, uint16_t size)
{
(void) service_id;
if (!coap_service_handle) {
return -1;
}
return sn_coap_protocol_set_block_size(coap_service_handle->coap, size);
}

View File

@ -23,9 +23,13 @@
#include "ns_list.h" #include "ns_list.h"
#define TRANSACTION_LIFETIME 180 #define TRANSACTION_LIFETIME 180
/* Default value for CoAP duplicate message buffer (0 = disabled) */ /* Default value for CoAP duplicate message buffer (0 = disabled) */
#define DUPLICATE_MESSAGE_BUFFER_SIZE 0 #define DUPLICATE_MESSAGE_BUFFER_SIZE 0
/* Default value for CoAP blockwise data size (0 = disabled) */
#define DEFAULT_BLOCKWISE_DATA_SIZE 0
/* Default values for CoAP resendings */ /* Default values for CoAP resendings */
#define COAP_RESENDING_COUNT 3 #define COAP_RESENDING_COUNT 3
#define COAP_RESENDING_INTERVAL 10 #define COAP_RESENDING_INTERVAL 10

View File

@ -81,6 +81,7 @@ bool test_coap_message_handler_init()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
if( NULL == handle ) if( NULL == handle )
return false; return false;
@ -97,6 +98,7 @@ bool test_coap_message_handler_destroy()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
if( 0 != coap_message_handler_destroy(handle) ) if( 0 != coap_message_handler_destroy(handle) )
@ -113,6 +115,7 @@ bool test_coap_message_handler_find_transaction()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
uint8_t buf[16]; uint8_t buf[16];
@ -140,26 +143,29 @@ bool test_coap_message_handler_coap_msg_process()
{ {
uint8_t buf[16]; uint8_t buf[16];
memset(&buf, 1, 16); memset(&buf, 1, 16);
bool ret_val = false;
/*Handler is null*/ /*Handler is null*/
if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL)) if( -1 != coap_message_handler_coap_msg_process(NULL, 0, buf, 22, ns_in6addr_any, NULL, 0, NULL))
return false; goto exit;
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
sn_coap_protocol_stub.expectedHeader = NULL; sn_coap_protocol_stub.expectedHeader = NULL;
/* Coap parse returns null */ /* Coap parse returns null */
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
sn_coap_protocol_stub.expectedHeader->coap_status = 66; sn_coap_protocol_stub.expectedHeader->coap_status = 66;
nsdynmemlib_stub.returnCounter = 1;
/* Coap library responds */ /* Coap library responds */
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
@ -167,8 +173,9 @@ bool test_coap_message_handler_coap_msg_process()
sn_coap_protocol_stub.expectedHeader->msg_code = 1; sn_coap_protocol_stub.expectedHeader->msg_code = 1;
retValue = 0; retValue = 0;
/* request received */ /* request received */
nsdynmemlib_stub.returnCounter = 1;
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
@ -177,15 +184,16 @@ bool test_coap_message_handler_coap_msg_process()
nsdynmemlib_stub.returnCounter = 1; nsdynmemlib_stub.returnCounter = 1;
retValue = -1; retValue = -1;
if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( 0 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK; sn_coap_protocol_stub.expectedHeader->coap_status = COAP_STATUS_OK;
sn_coap_protocol_stub.expectedHeader->msg_code = 333; sn_coap_protocol_stub.expectedHeader->msg_code = 333;
nsdynmemlib_stub.returnCounter = 1;
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_protocol_stub.expectedHeader = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s)); memset(sn_coap_protocol_stub.expectedHeader, 0, sizeof(sn_coap_hdr_s));
@ -200,20 +208,19 @@ bool test_coap_message_handler_coap_msg_process()
sn_coap_builder_stub.expectedUint16 = 1; sn_coap_builder_stub.expectedUint16 = 1;
nsdynmemlib_stub.returnCounter = 3; nsdynmemlib_stub.returnCounter = 3;
if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv)) if( 2 != coap_message_handler_request_send(handle, 3, 0, buf, 24, 1, 2, &uri, 4, NULL, 0, &resp_recv))
return false; goto exit;
sn_coap_protocol_stub.expectedHeader->msg_id = 2; sn_coap_protocol_stub.expectedHeader->msg_id = 2;
// sn_coap_protocol_stub.expectedHeader->token_ptr = (uint8_t*)malloc(4);
// memset(sn_coap_protocol_stub.expectedHeader->token_ptr, 1, 4);
if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb)) if( -1 != coap_message_handler_coap_msg_process(handle, 0, buf, 22, ns_in6addr_any, NULL, 0, process_cb))
return false; goto exit;
// free(sn_coap_protocol_stub.expectedHeader->token_ptr);
ret_val = true;
exit:
free(sn_coap_protocol_stub.expectedCoap); free(sn_coap_protocol_stub.expectedCoap);
sn_coap_protocol_stub.expectedCoap = NULL; sn_coap_protocol_stub.expectedCoap = NULL;
coap_message_handler_destroy(handle); coap_message_handler_destroy(handle);
return true; return ret_val;
} }
bool test_coap_message_handler_request_send() bool test_coap_message_handler_request_send()
@ -221,6 +228,7 @@ bool test_coap_message_handler_request_send()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
uint8_t buf[16]; uint8_t buf[16];
@ -293,6 +301,7 @@ bool test_coap_message_handler_request_delete()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
uint8_t buf[16]; uint8_t buf[16];
@ -329,6 +338,7 @@ bool test_coap_message_handler_response_send()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
sn_coap_hdr_s *header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s)); sn_coap_hdr_s *header = (sn_coap_hdr_s *)malloc(sizeof(sn_coap_hdr_s));
memset(header, 0, sizeof(sn_coap_hdr_s)); memset(header, 0, sizeof(sn_coap_hdr_s));
@ -385,6 +395,7 @@ bool test_coap_message_handler_exec()
retCounter = 1; retCounter = 1;
sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s)); sn_coap_protocol_stub.expectedCoap = (struct coap_s*)malloc(sizeof(struct coap_s));
memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s)); memset(sn_coap_protocol_stub.expectedCoap, 0, sizeof(struct coap_s));
nsdynmemlib_stub.returnCounter = 1;
coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function); coap_msg_handler_t *handle = coap_message_handler_init(&test_own_alloc, &test_own_free, &coap_tx_function);
if( 0 != coap_message_handler_exec(handle, 0)) if( 0 != coap_message_handler_exec(handle, 0))

View File

@ -30,7 +30,7 @@ void ns_dyn_mem_init(uint8_t *heap, uint16_t h_size, void (*passed_fptr)(heap_fa
{ {
} }
#else #else
void ns_dyn_mem_init(void *heap, uint16_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr) void ns_dyn_mem_init(void *heap, ns_mem_heap_size_t h_size, void (*passed_fptr)(heap_fail_t), mem_stat_t *info_ptr)
{ {
} }
#endif #endif

View File

@ -49,6 +49,11 @@ uint16_t sn_coap_builder_calc_needed_packet_data_size(sn_coap_hdr_s *src_coap_ms
return sn_coap_builder_stub.expectedUint16; return sn_coap_builder_stub.expectedUint16;
} }
uint16_t sn_coap_builder_calc_needed_packet_data_size_2(sn_coap_hdr_s *src_coap_msg_ptr, uint16_t blockwise_payload_size)
{
return sn_coap_builder_stub.expectedUint16;
}
int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number) int16_t sn_coap_builder_options_build_add_zero_length_option(uint8_t **dst_packet_data_pptr, uint8_t option_length, uint8_t option_exist, sn_coap_option_numbers_e option_number)
{ {
return sn_coap_builder_stub.expectedInt16; return sn_coap_builder_stub.expectedInt16;

View File

@ -110,3 +110,13 @@ int8_t sn_coap_protocol_delete_retransmission(struct coap_s *handle, uint16_t ms
{ {
return 0; return 0;
} }
uint16_t sn_coap_protocol_get_configured_blockwise_size(struct coap_s *handle)
{
return 0;
}
int8_t prepare_blockwise_message(struct coap_s *handle, sn_coap_hdr_s *src_coap_msg_ptr)
{
return 0;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -18,6 +18,7 @@
#define CCMLIB_H_ #define CCMLIB_H_
#include "ns_types.h" #include "ns_types.h"
#include "platform/arm_hal_aes.h"
/** /**
* *
@ -25,11 +26,11 @@
* \brief CCM Library API. * \brief CCM Library API.
* *
* \section ccm-api CCM Library API: * \section ccm-api CCM Library API:
* - ccm_sec_init(), A function to init CCM library. * - ccm_sec_init(), A function to init CCM context.
* - ccm_process_run(), A function to run configured CCM process. * - ccm_process_run(), A function to run configured CCM process.
* *
* \section ccm-instruction CCM process sequence: * \section ccm-instruction CCM process sequence:
* 1. Init CCM library by, ccm key, ccm_sec_init() * 1. Init CCM context by, ccm key, ccm_sec_init()
* - security level * - security level
* - 128-bit CCM key * - 128-bit CCM key
* - mode: AES_CCM_ENCRYPT or AES_CCM_DECRYPT * - mode: AES_CCM_ENCRYPT or AES_CCM_DECRYPT
@ -41,11 +42,6 @@
* -If 0 Process ok * -If 0 Process ok
* -< 0 MIC fail or parameter fail * -< 0 MIC fail or parameter fail
* *
* \section ccm-mutex CCM Mutex for Multi Thread System
* If you are running a multi thread system and the CCM library will be used for multiple thread, do the following:
* 1. Add compiler flag to library build process CCM_USE_MUTEX.
* 2. Define OS-specific mutex at the application.
* 3. Implement arm_ccm_mutex_lock() arm_ccm_mutex_unlock() function for using the generated and initialized mutex.
*/ */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -63,41 +59,39 @@ extern "C" {
#define AES_CCM_DECRYPT 0x01 /**< Decryption mode */ #define AES_CCM_DECRYPT 0x01 /**< Decryption mode */
/**
* \brief A function for locking CCM mutex if the OS is multi thread. If you are using single thread create an empty function.
*/
extern void arm_ccm_mutex_lock(void);
/**
* \brief A function for unlocking CCM mutex if the OS is multi thread. If you are using single thread create an empty function
*/
extern void arm_ccm_mutex_unlock(void);
/*! /*!
* \struct ccm_globals_t * \struct ccm_globals_t
* \brief CCM global structure. * \brief CCM global structure.
* The structure is used for configuring NONCE, adata and data before calling ccm_process_run(). * The structure is used for configuring NONCE, adata and data before calling ccm_process_run().
*/ */
typedef struct { typedef struct {
uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */ uint8_t exp_nonce[15]; /**< CCM NONCE buffer Nonce. */
uint8_t *data_ptr; /**< Pointer to data IN. */ uint8_t *data_ptr; /**< Pointer to data IN. */
uint16_t data_len; /**< Length of data IN. */ uint16_t data_len; /**< Length of data IN. */
const uint8_t *adata_ptr; /**< Pointer to authentication data. */ const uint8_t *adata_ptr; /**< Pointer to authentication data. */
uint16_t adata_len; /**< Length of authentication data. */ uint16_t adata_len; /**< Length of authentication data. */
uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */ unsigned ccm_encode_mode:1; /**< Encryption modeAES_CCM_ENCRYPT or AES_CCM_DECRYPT. */
uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */ unsigned ccm_sec_level:3; /**< Encryption operation security level 0-7. */
unsigned ccm_l_param:4; /**< Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12*/
uint8_t mic_len; /**< ccm_sec_init() sets here the length of MIC. */
uint8_t *mic; /**< Encrypt process writes MIC. Decrypt reads it and compares it with the MIC obtained from data. */
const uint8_t *key_ptr; /**< Encyption key pointer to 128-bit key. */
arm_aes_context_t *aes_context; /**< Allocated AES context. */
} ccm_globals_t; } ccm_globals_t;
/** /**
* \brief A function to initialize the CCM library. * \brief A function to initialize the CCM context.
* \param ccm_context pointer to initialized XXM context
* \param sec_level Used CCM security level (0-7). * \param sec_level Used CCM security level (0-7).
* \param ccm_key Pointer to 128-key. * \param ccm_key Pointer to 128-key.
* \param mode AES_CCM_ENCRYPT or AES_CCM_DECRYPT. * \param mode AES_CCM_ENCRYPT or AES_CCM_DECRYPT.
* \param ccm_l Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12. (NONCE length = (15-ccm_l)) * \param ccm_l Can be 2 or 3. 2 when NONCE length is 13 and 3 when 12. (NONCE length = (15-ccm_l))
* *
* \return Pointer to Global CCM parameter buffer. * \return true when AES context allocation is OK and given parameters.
* \return 0 When parameter fails or CCM is busy. * \return false CCM parameters or AES context allocation fail.
*/ */
extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l); extern bool ccm_sec_init(ccm_globals_t *ccm_context, uint8_t sec_level, const uint8_t *ccm_key, uint8_t mode, uint8_t ccm_l);
/** /**
* \brief A function to run the configured CCM process. * \brief A function to run the configured CCM process.
@ -109,6 +103,14 @@ extern ccm_globals_t *ccm_sec_init(uint8_t sec_level, const uint8_t *ccm_key, ui
* \return -2 Null pointer given to function. * \return -2 Null pointer given to function.
*/ */
extern int8_t ccm_process_run(ccm_globals_t *ccm_params); extern int8_t ccm_process_run(ccm_globals_t *ccm_params);
/**
* \brief A function to free aes context. Call only if ccm_process_run() is not called
* \param ccm_params CCM parameters
*
*/
extern void ccm_free(ccm_globals_t *ccm_params);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -74,17 +74,16 @@ typedef bool fhss_use_broadcast_queue(const fhss_api_t *api, bool is_broadcast_a
* @param is_broadcast_addr Destination address type of packet (true if broadcast address). * @param is_broadcast_addr Destination address type of packet (true if broadcast address).
* @param destination_address Destination MAC address. * @param destination_address Destination MAC address.
* @param frame_type Frame type of packet (Frames types are defined by FHSS api). * @param frame_type Frame type of packet (Frames types are defined by FHSS api).
* @param synch_info Pointer to where FHSS synchronization info is written (if synch frame).
* @param frame_length MSDU length of the frame. * @param frame_length MSDU length of the frame.
* @param phy_header_length PHY header length. * @param phy_header_length PHY header length.
* @param phy_tail_length PHY tail length. * @param phy_tail_length PHY tail length.
* @param tx_time TX time.
* @return 0 Success. * @return 0 Success.
* @return -1 Transmission of the packet is currently not allowed, try again. * @return -1 Transmission of the packet is currently not allowed, try again.
* @return -2 Invalid api. * @return -2 Invalid api.
* @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue. * @return -3 Broadcast packet on Unicast channel (not allowed), push packet back to queue.
* @return -4 Synchronization info missing.
*/ */
typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint8_t *synch_info, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length); typedef int fhss_tx_handle(const fhss_api_t *api, bool is_broadcast_addr, uint8_t *destination_address, int frame_type, uint16_t frame_length, uint8_t phy_header_length, uint8_t phy_tail_length, uint32_t tx_time);
/** /**
* @brief Check TX permission. * @brief Check TX permission.
@ -152,6 +151,17 @@ typedef uint32_t fhss_read_timestamp(const fhss_api_t *api);
*/ */
typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu); typedef uint16_t fhss_get_retry_period(const fhss_api_t *api, uint8_t *destination_address, uint16_t phy_mtu);
/**
* @brief Write synchronization info to given pointer.
* @param api FHSS instance.
* @param ptr Pointer to data. Start of written data for Synch frame. Start of IE header for Data frame.
* @param length Length of IE header. Ignored when Synch frame.
* @param frame_type Frame type of packet (Frames types are defined by FHSS api).
* @param tx_time TX time must be referenced to the first symbol following the SFD of the transmitted frame.
* @return -1 on fail, write length otherwise.
*/
typedef int16_t fhss_write_synch_info(const fhss_api_t *api, uint8_t *ptr, uint8_t length, int frame_type, uint32_t tx_time);
/** /**
* @brief Initialize MAC functions. * @brief Initialize MAC functions.
* @param api FHSS instance. * @param api FHSS instance.
@ -177,6 +187,7 @@ struct fhss_api {
fhss_synch_state_set *synch_state_set; /**< Change synchronization state. */ fhss_synch_state_set *synch_state_set; /**< Change synchronization state. */
fhss_read_timestamp *read_timestamp; /**< Read timestamp. */ fhss_read_timestamp *read_timestamp; /**< Read timestamp. */
fhss_get_retry_period *get_retry_period; /**< Get retransmission period. */ fhss_get_retry_period *get_retry_period; /**< Get retransmission period. */
fhss_write_synch_info *write_synch_info; /**< Write synchronization info to TX frame*/
fhss_init_callbacks *init_callbacks; /**< Initialize MAC functions. */ fhss_init_callbacks *init_callbacks; /**< Initialize MAC functions. */
}; };
@ -256,6 +267,18 @@ typedef int mac_broadcast_notify(const fhss_api_t *fhss_api, uint32_t broadcast_
*/ */
typedef int mac_read_coordinator_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address); typedef int mac_read_coordinator_mac_address(const fhss_api_t *fhss_api, uint8_t *mac_address);
/**
* @brief Read synchronization info for a specific peer.
* @param fhss_api FHSS instance.
* @param info_ptr Pointer to info data.
* @param mac_address MAC address pointer.
* @param info_type Type of the read info (UTT-IE, BT-IE, US-IE, BS-IE).
* @param rx_timestamp Time of reception of the element.
* @return >=0 Length of the info.
* @return -1 Fail.
*/
typedef int mac_read_synch_info(const fhss_api_t *fhss_api, uint8_t *info_ptr, uint8_t *mac_address, int info_type, uint32_t rx_timestamp);
/** /**
* \brief Struct fhss_callback defines functions that software MAC needs to implement. * \brief Struct fhss_callback defines functions that software MAC needs to implement.
* Function pointers are passed to FHSS using fhss_init_callbacks function. * Function pointers are passed to FHSS using fhss_init_callbacks function.
@ -270,6 +293,7 @@ struct fhss_callback {
mac_tx_poll *tx_poll; /**< Poll TX queue. */ mac_tx_poll *tx_poll; /**< Poll TX queue. */
mac_broadcast_notify *broadcast_notify; /**< Broadcast channel notification from FHSS. */ mac_broadcast_notify *broadcast_notify; /**< Broadcast channel notification from FHSS. */
mac_read_coordinator_mac_address *read_coord_mac_address; /**< Read coordinator MAC address. */ mac_read_coordinator_mac_address *read_coord_mac_address; /**< Read coordinator MAC address. */
mac_read_synch_info *read_synch_info; /**< Read information element for a specific MAC address. */
}; };
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -28,6 +28,23 @@
extern "C" { extern "C" {
#endif #endif
#include "fhss_ws_extension.h"
/**
* @brief WS channel functions.
*/
typedef enum
{
/** Fixed channel. */
WS_FIXED_CHANNEL,
/** TR51 channel function. */
WS_TR51CF,
/** Direct Hash channel function. */
WS_DH1CF,
/** Vendor Defined channel function. */
WS_VENDOR_DEF_CF
} fhss_ws_channel_functions;
/** /**
* \brief Struct fhss_tuning_parameter defines FHSS tuning parameters. * \brief Struct fhss_tuning_parameter defines FHSS tuning parameters.
* All delays are given in microseconds. * All delays are given in microseconds.
@ -63,20 +80,59 @@ typedef struct fhss_configuration
} fhss_configuration_t; } fhss_configuration_t;
/**
* @brief Get channel using vendor defined channel function.
* @param api FHSS instance.
* @param slot Slot number in channel schedule.
* @param eui64 EUI-64 address of node for which the (unicast) schedule is calculated. NULL for broadcast schedule.
* @param bsi Broadcast schedule identifier used in (broadcast) schedule calculation.
* @param number_of_channels Number of channels in schedule.
* @return Channel.
*/
typedef int32_t fhss_vendor_defined_cf(const fhss_api_t *api, uint16_t slot, uint8_t eui64[8], uint16_t bsi, uint16_t number_of_channels);
/**
* \brief Struct fhss_ws_configuration defines configuration of WS FHSS.
*/
typedef struct fhss_ws_configuration
{
/** WS channel function. */
fhss_ws_channel_functions ws_channel_function;
/** Broadcast schedule identifier. */
uint16_t bsi;
/** Unicast dwell interval. Range: 15-250 milliseconds. */
uint8_t fhss_uc_dwell_interval;
/** Broadcast interval. Duration between broadcast dwell intervals. Range: 0-16777216 milliseconds. */
uint32_t fhss_broadcast_interval;
/** Broadcast dwell interval. Range: 15-250 milliseconds. */
uint8_t fhss_bc_dwell_interval;
/** Channel mask. */
uint32_t channel_mask[8];
/** Vendor defined channel function. */
fhss_vendor_defined_cf *vendor_defined_cf;
} fhss_ws_configuration_t;
/** /**
* \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer. * \brief Struct fhss_timer defines interface between FHSS and FHSS platform timer.
* Application must implement FHSS timer driver which is then used by FHSS with this interface. * Application must implement FHSS timer driver which is then used by FHSS with this interface.
*/ */
typedef struct fhss_timer typedef struct fhss_timer
{ {
/** Start timeout (1us) */ /** Start timeout (1us). Timer must support multiple simultaneous timeouts */
int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api); int (*fhss_timer_start)(uint32_t, void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
/** Stop timeout */ /** Stop timeout */
int (*fhss_timer_stop)(const fhss_api_t *fhss_api); int (*fhss_timer_stop)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
/** Get remaining time of started timeout*/ /** Get remaining time of started timeout*/
uint32_t (*fhss_get_remaining_slots)(const fhss_api_t *fhss_api); uint32_t (*fhss_get_remaining_slots)(void (*fhss_timer_callback)(const fhss_api_t *fhss_api, uint16_t), const fhss_api_t *fhss_api);
/** Get timestamp since initialization of driver. Overflow of 32-bit counter is allowed (1us) */ /** Get timestamp since initialization of driver. Overflow of 32-bit counter is allowed (1us) */
uint32_t (*fhss_get_timestamp)(const fhss_api_t *fhss_api); uint32_t (*fhss_get_timestamp)(const fhss_api_t *fhss_api);

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* \file fhss_ws_extension.h
* \brief
*/
#ifndef FHSS_WS_EXT_H
#define FHSS_WS_EXT_H
#include "ns_types.h"
#include "fhss_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief unicast_timing_info Unicast timing/hopping schedule information structure.
*/
typedef struct unicast_timing_info {
unsigned unicast_channel_function:3; /**< Unicast schedule channel function */
uint8_t unicast_dwell_interval; /**< Unicast dwell interval */
uint16_t unicast_number_of_channels; /**< Unicast number of channels */
uint_fast24_t ufsi; /**< Unicast fractional sequence interval */
uint32_t utt_rx_timestamp; /**< UTT-IE reception timestamp */
} unicast_timing_info_t;
/**
* @brief broadcast_timing_info Broadcast timing/hopping schedule information structure.
*/
typedef struct broadcast_timing_info {
unsigned broadcast_channel_function:3; /**< Broadcast schedule channel function */
uint8_t broadcast_dwell_interval; /**< Broadcast dwell interval */
uint16_t broadcast_slot; /**< Broadcast slot number */
uint16_t broadcast_schedule_id; /**< Broadcast schedule identifier */
uint_fast24_t broadcast_interval_offset; /**< Broadcast interval offset */
uint32_t broadcast_interval; /**< Broadcast interval */
uint32_t bt_rx_timestamp; /**< BT-IE reception timestamp */
} broadcast_timing_info_t;
/**
* @brief fhss_ws_neighbor_timing_info Neighbor timing/hopping schedule information structure.
*/
typedef struct fhss_ws_neighbor_timing_info {
uint8_t clock_drift; /**< Neighbor clock drift */
uint8_t timing_accuracy; /**< Neighbor timing accuracy */
unicast_timing_info_t uc_timing_info; /**< Neighbor unicast timing info */
broadcast_timing_info_t bc_timing_info; /**< Neighbor broadcast timing info */
uint32_t *excluded_channels; /**< Neighbor excluded channels (bit mask) */
} fhss_ws_neighbor_timing_info_t;
/**
* @brief Get neighbor timing/hopping schedule.
* @param api FHSS instance.
* @param eui64 EUI-64 address of node for which the info is requested.
* @return Neighbor timing/hopping schedule.
*/
typedef fhss_ws_neighbor_timing_info_t *fhss_get_neighbor_info(const fhss_api_t *api, uint8_t eui64[8]);
/**
* @brief Set parent which broadcast channels must be listened by FHSS.
* @param fhss_api FHSS instance.
* @param eui64 EUI-64 address of parent.
* @param bc_timing_info Pointer to parent broadcast timing/hopping schedule info.
* @return 0 on success, -1 on fail.
*/
extern int ns_fhss_ws_set_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8], const broadcast_timing_info_t *bc_timing_info);
/**
* @brief Remove parent which was set by ns_fhss_ws_set_parent function.
* @param fhss_api FHSS instance.
* @param eui64 EUI-64 address of parent.
* @return 0 on success, -1 on fail.
*/
extern int ns_fhss_ws_remove_parent(const fhss_api_t *fhss_api, const uint8_t eui64[8]);
/**
* @brief Set neighbor timing/hopping schedule request function.
* @param fhss_api FHSS instance.
* @param get_neighbor_info Neighbor info function pointer.
* @return 0 on success, -1 on fail.
*/
extern int ns_fhss_set_neighbor_info_fp(const fhss_api_t *fhss_api, fhss_get_neighbor_info *get_neighbor_info);
/**
* @brief Set node hop count. Hop count is used to specify TX/RX slot. When hop count is set to 0xFF, TX/RX slots are ignored.
* @param fhss_api FHSS instance.
* @param hop_count Hop count to be set.
* @return 0 on success, -1 on fail.
*/
extern int ns_fhss_ws_set_hop_count(const fhss_api_t *fhss_api, const uint8_t hop_count);
#ifdef __cplusplus
}
#endif
#endif // FHSS_WS_EXT_H

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -32,6 +32,8 @@
extern "C" { extern "C" {
#endif #endif
struct channel_list_s;
typedef struct mac_api_s mac_api_t; typedef struct mac_api_s mac_api_t;
/** /**
@ -120,6 +122,17 @@ typedef void mlme_request(const mac_api_t* api, mlme_primitive id, const void *d
*/ */
typedef void mcps_data_request(const mac_api_t* api, const mcps_data_req_t *data); typedef void mcps_data_request(const mac_api_t* api, const mcps_data_req_t *data);
/**
* @brief mcps_request MCPS_DATA with IE extions request call
* @param api API to handle the request
* @param data MCPS-DATA.request specific values
* @param ie_ext Information element list to MCPS-DATA.request
* @param asynch_channel_list Optional channel list to asynch data request. Give NULL when normal data request.
*
* Asynch data request is mac standard extension. asynch_channel_list include channel mask which channel message is requested to send.
*/
typedef void mcps_data_request_ext(const mac_api_t* api, const mcps_data_req_t *data, const mcps_data_req_ie_list_t *ie_ext, const struct channel_list_s *asynch_channel_list);
/** /**
* @brief mcps_purge_request MCPS_PURGE request call * @brief mcps_purge_request MCPS_PURGE request call
* @param api API to handle the request * @param api API to handle the request
@ -136,6 +149,14 @@ typedef void mcps_purge_request(const mac_api_t* api, const mcps_purge_t *data);
*/ */
typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *data); typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *data);
/**
* @brief mcps_data_confirm_ext MCPS-DATA confirm with Enhanced ACK payload is called as a response to MCPS-DATA request
* @param api The API which handled the response
* @param data MCPS-DATA.confirm specific values
* @param conf_data Possible Confirmation Data
*/
typedef void mcps_data_confirm_ext(const mac_api_t* api, const mcps_data_conf_t *data, const mcps_data_conf_payload_t *conf_data);
/** /**
* @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data * @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data
* @param api The API which handled the response * @param api The API which handled the response
@ -143,6 +164,24 @@ typedef void mcps_data_confirm(const mac_api_t* api, const mcps_data_conf_t *dat
*/ */
typedef void mcps_data_indication(const mac_api_t* api, const mcps_data_ind_t *data); typedef void mcps_data_indication(const mac_api_t* api, const mcps_data_ind_t *data);
/**
* @brief mcps_data_indication MCPS-DATA indication is called when MAC layer has received data
* @param api The API which handled the response
* @param data MCPS-DATA.indication specific values
* @param ie_ext Information element list
*/
typedef void mcps_data_indication_ext(const mac_api_t* api, const mcps_data_ind_t *data, const mcps_data_ie_list_t *ie_ext);
/**
* @brief mcps_ack_data_req_ext Callback for request IE elements and payload to enhanced ACK
* @param api The API which handled the response
* @param data Pointer where MAC user set Payload and IE element pointers and length
* @param rssi Signal strength for received packet
* @param lqi Link quality to neighbor
*/
typedef void mcps_ack_data_req_ext(const mac_api_t* api, mcps_ack_data_payload_t *data, int8_t rssi, uint8_t lqi);
/** /**
* @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request * @brief mcps_purge_confirm MCPS-PURGE confirm is called as a response to MCPS-PURGE request
* @param api The API which handled the request * @param api The API which handled the request
@ -201,6 +240,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c
mcps_data_indication *data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_cb, mcps_data_indication *data_ind_cb, mcps_purge_confirm *purge_conf_cb, mlme_confirm *mlme_conf_cb,
mlme_indication *mlme_ind_cb, int8_t parent_id); mlme_indication *mlme_ind_cb, int8_t parent_id);
/**
* @brief mac_api_enable_mcps_ext Initialises MAC 2015 extension for MCPS layer into use, callbacks must be non-NULL.
* @param api mac_api_t pointer, which is created by application.
* @param data_ind_cb Upper layer function to handle MCPS indications
* @param data_cnf_cb Upper layer function to handle MCPS confirmation
* @param ack_data_req_cb Upper layer function for set Enhanced ACK payload
* @return -1 if error, -2 if OOM, 0 otherwise
*/
typedef int8_t mac_api_enable_mcps_ext(mac_api_t *api,
mcps_data_indication_ext *data_ind_cb,
mcps_data_confirm_ext *data_cnf_cb,
mcps_ack_data_req_ext *ack_data_req_cb);
/** /**
* \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer. * \brief Struct mac_api_s defines functions for two-way communications between external MAC and Upper layer.
* Application creates mac_api_t object by calling external MAC's creator function. * Application creates mac_api_t object by calling external MAC's creator function.
@ -209,14 +261,19 @@ typedef int8_t mac_api_initialize(mac_api_t *api, mcps_data_confirm *data_conf_c
*/ */
struct mac_api_s { struct mac_api_s {
mac_api_initialize *mac_initialize; /**< MAC initialize function to use */ mac_api_initialize *mac_initialize; /**< MAC initialize function to use */
mac_api_enable_mcps_ext *mac_mcps_extension_enable; /**< MAC MCPS IE extension enable function, optional feature */
//External MAC callbacks //External MAC callbacks
mlme_request *mlme_req; /**< MAC MLME request function to use */ mlme_request *mlme_req; /**< MAC MLME request function to use */
mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */ mcps_data_request *mcps_data_req; /**< MAC MCPS data request function to use */
mcps_data_request_ext *mcps_data_req_ext; /**< MAC MCPS data request with Information element extension function to use */
mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */ mcps_purge_request *mcps_purge_req; /**< MAC MCPS purge request function to use */
//Upper layer callbacksMLME_ASSOCIATE //Upper layer callbacksMLME_ASSOCIATE
mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */ mcps_data_confirm *data_conf_cb; /**< MAC MCPS data confirm callback function */
mcps_data_confirm_ext *data_conf_ext_cb; /**< MAC MCPS data confirm with payload callback function */
mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */ mcps_data_indication *data_ind_cb; /**< MAC MCPS data indication callback function */
mcps_data_indication_ext *data_ind_ext_cb; /**< MAC MCPS data indication with IE extension's callback function */
mcps_ack_data_req_ext *enhanced_ack_data_req_cb; /**< Enhanced ACK IE element and payload request from MAC user */
mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */ mcps_purge_confirm *purge_conf_cb; /**< MAC MCPS purge confirm callback function */
mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */ mlme_confirm *mlme_conf_cb; /**< MAC MLME confirm callback function */
mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */ mlme_indication *mlme_ind_cb; /**< MAC MLME indication callback function */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -30,6 +30,7 @@
#define MAC_FRAME_VERSION_2003 0 /**< FCF - IEEE 802.15.4-2003 compatible */ #define MAC_FRAME_VERSION_2003 0 /**< FCF - IEEE 802.15.4-2003 compatible */
#define MAC_FRAME_VERSION_2006 1 /**< FCF - IEEE 802.15.4-2006 (big payload or new security) */ #define MAC_FRAME_VERSION_2006 1 /**< FCF - IEEE 802.15.4-2006 (big payload or new security) */
#define MAC_FRAME_VERSION_2015 2 /**< FCF - IEEE 802.15.4-2015 (IE element support) */
//See IEEE standard 802.15.4-2006 (table 96) for more details about identifiers //See IEEE standard 802.15.4-2006 (table 96) for more details about identifiers
#define MAC_KEY_ID_MODE_IMPLICIT 0 /**< Key identifier mode implicit */ #define MAC_KEY_ID_MODE_IMPLICIT 0 /**< Key identifier mode implicit */
@ -66,4 +67,36 @@ typedef struct mlme_security_s {
uint8_t Keysource[8]; /**< Key source */ uint8_t Keysource[8]; /**< Key source */
} mlme_security_t; } mlme_security_t;
#define MAC_HEADER_VENDOR_SPESIFIC_IE_ID 0x00 /**< Vendor specific Header IE element */
#define MAC_HEADER_ASSIGNED_EXTERNAL_ORG_IE_ID 0x2a /**< External organisation defined Header IE element */
#define MAC_HEADER_TERMINATION1_IE_ID 0x7e /**< Header IE element termination when Payload element is following Header IE */
#define MAC_HEADER_TERMINATION2_IE_ID 0x7f /**< Header IE element termination when no Payload element is following Header IE but normal payload is */
/**
* @brief struct mac_header_IE_t Mac Header information element structure for parsing or write operation
* This structure encapsulates security related variables,
*/
typedef struct mac_header_IE_s {
uint8_t *content_ptr; /**< Content data */
unsigned length:7; /**< Element length 0- 127 */
uint8_t id; /**< Element ID */
} mac_header_IE_t;
#define MAC_PAYLOAD_IE_ESDU_GROUP_ID 0x00 /**< Encapsulated Service Data Unit (ESDU) Payload IE element's */
#define MAC_PAYLOAD_MLME_IE_GROUP_ID 0x01 /**< MLME nested Payload IE element's */
#define MAC_PAYLOAD_VENDOR_IE_GROUP_ID 0x02 /**< Vendor specific nested Payload IE element's */
#define MAC_PAYLOAD_MPX_IE_GROUP_ID 0x03 /**< MPX Payload IE element, IEEE 802.15.9 defined */
#define MAC_PAYLOAD_TERMINATION_IE_GROUP_ID 0x0f /**< Payload IE element terminator. Mandatory when normal payload is coming after IE element part */
/**
* @brief struct mac_header_IE_t Mac Payload information element structure for parsing or write operation
* This structure encapsulates security related variables,
*/
typedef struct mac_payload_IE_s {
uint8_t *content_ptr; /**< Content data */
unsigned length:11; /**< Element length 0- 2047 */
unsigned id:4; /**< Group ID */
} mac_payload_IE_t;
#endif /* MAC_COMMON_DEFINES_H_ */ #endif /* MAC_COMMON_DEFINES_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,6 +25,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "mac_common_defines.h" #include "mac_common_defines.h"
/** /**
* @brief struct mcps_data_req_t Data request structure * @brief struct mcps_data_req_t Data request structure
* *
@ -41,6 +42,8 @@ typedef struct mcps_data_req_s {
bool TxAckReq: 1; /**< Specifies whether ACK is needed or not */ bool TxAckReq: 1; /**< Specifies whether ACK is needed or not */
bool InDirectTx:1; /**< Specifies whether indirect or direct transmission is used */ bool InDirectTx:1; /**< Specifies whether indirect or direct transmission is used */
bool PendingBit: 1; /**< Specifies whether more fragments are to be sent or not */ bool PendingBit: 1; /**< Specifies whether more fragments are to be sent or not */
bool SeqNumSuppressed:1; /**< True suppress sequence number from frame. This will be only checked when 2015 extension is enabled */
bool PanIdSuppressed:1; /**< True suppress PAN-id is done when possible from frame. This will be only checked when 2015 extension is enabled */
mlme_security_t Key; /**< Security key */ mlme_security_t Key; /**< Security key */
} mcps_data_req_t; } mcps_data_req_t;
@ -58,6 +61,21 @@ typedef struct mcps_data_conf_s {
uint8_t tx_retries; /**< Number of retries done during sending, 0 means no retries */ uint8_t tx_retries; /**< Number of retries done during sending, 0 means no retries */
} mcps_data_conf_t; } mcps_data_conf_t;
/**
* @brief struct mcps_data_conf_payload_t Data confirmatio IE extension list and payload from enhanced ACK
*
*/
typedef struct mcps_data_conf_payload_s {
uint8_t *headerIeList; /**< Header information IE's list without terminator*/
uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/
uint8_t *payloadPtr; /**< Ack payload pointer */
uint16_t headerIeListLength; /**< Header information IE's list length in bytes */
uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */
uint16_t payloadLength; /**< Payload length in bytes */
} mcps_data_conf_payload_t;
/** /**
* @brief struct mcps_data_ind_t Data indication structure * @brief struct mcps_data_ind_t Data indication structure
* *
@ -79,6 +97,54 @@ typedef struct mcps_data_ind_s {
uint8_t *msdu_ptr; /**< Data unit */ uint8_t *msdu_ptr; /**< Data unit */
} mcps_data_ind_t; } mcps_data_ind_t;
/**
* @brief struct mcps_data_ie_list_t MCPS data Information element list stucture
*
* Structure for IEEE 802.15.4-2015 MCPS data extension to Indication
*/
typedef struct mcps_data_ie_list {
uint8_t *headerIeList; /**< Header information IE's list without terminator*/
uint8_t *payloadIeList; /**< Payload information IE's list without terminator*/
uint16_t headerIeListLength; /**< Header information IE's list length in bytes */
uint16_t payloadIeListLength; /**< Payload information IE's list length in bytes */
} mcps_data_ie_list_t;
/** \brief Scatter-gather descriptor for MCPS request IE Element list
*
* Slightly optimised for small platforms - we assume we won't need any
* element bigger than 64K.
*/
typedef struct ns_ie_iovec {
void *ieBase; /**< IE element pointer */
uint_fast16_t iovLen; /**< IE element length */
} ns_ie_iovec_t;
/**
* @brief struct mcps_data_req_ie_list MCPS data Information element list stuctrure
*
* Structure for IEEE 802.15.4-2015 MCPS data extension to Request
*
* IE element could be divided to multiple vector which MAC just write to message direct.
*/
typedef struct mcps_data_req_ie_list {
ns_ie_iovec_t *headerIeVectorList; /**< Header IE element list */
ns_ie_iovec_t *payloadIeVectorList; /**< Payload IE element list */
uint16_t headerIovLength; /**< Header IE element list size, set 0 when no elements */
uint16_t payloadIovLength; /**< Payload IE element list size, set 0 when no elements */
} mcps_data_req_ie_list_t;
/**
* @brief struct mcps_ack_data_payload_t IE extension list and payload for enhanced ACK
*
*/
typedef struct mcps_ack_data_payload {
struct mcps_data_req_ie_list ie_elements; /**< IE hader and payload's elements */
uint8_t *payloadPtr; /**< Ack payload pointer */
uint16_t payloadLength; /**< Payload length in bytes */
} mcps_ack_data_payload_t;
/** /**
* @brief struct mcps_purge_t Purge request structure * @brief struct mcps_purge_t Purge request structure
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -264,6 +264,7 @@ typedef enum {
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/ macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
macDefaultKeySource = 0x7c, /*<Default key source*/ macDefaultKeySource = 0x7c, /*<Default key source*/
//NON standard extension //NON standard extension
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */ macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/ macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
macThreadForceLongAddressForBeacon = 0xff /*<Thread standard force beacon source address for extended 64-bit*/ macThreadForceLongAddressForBeacon = 0xff /*<Thread standard force beacon source address for extended 64-bit*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -38,6 +38,15 @@ extern "C" {
*/ */
extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics); extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer, fhss_statistics_t *fhss_statistics);
/**
* @brief TODO: description.
* @param fhss_configuration Basic FHSS configuration.
* @param fhss_timer FHSS platform timer interface and configuration.
* @param fhss_statistics FHSS statistics storage.
* @return New FHSS instance if successful, NULL otherwise.
*/
extern fhss_api_t *ns_fhss_ws_create(const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer);
/** /**
* @brief Set synchronization time configuration for FHSS network. Should be only called from Border router. * @brief Set synchronization time configuration for FHSS network. Should be only called from Border router.
* @param fhss_api FHSS instance. * @param fhss_api FHSS instance.
@ -46,6 +55,21 @@ extern fhss_api_t *ns_fhss_create(const fhss_configuration_t *fhss_configuration
*/ */
extern int ns_fhss_configuration_set(fhss_api_t *fhss_api, const fhss_synch_configuration_t *fhss_synch_configuration); extern int ns_fhss_configuration_set(fhss_api_t *fhss_api, const fhss_synch_configuration_t *fhss_synch_configuration);
/**
* @brief Get WS configuration.
* @param fhss_api FHSS instance.
* @return WS configuration.
*/
extern const fhss_ws_configuration_t *ns_fhss_ws_configuration_get(const fhss_api_t *fhss_api);
/**
* @brief Set WS configuration.
* @param fhss_api FHSS instance.
* @param fhss_configuration Basic FHSS configuration.
* @return 0 on success, -1 on fail.
*/
extern int ns_fhss_ws_configuration_set(const fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration);
/** /**
* @brief Deletes a FHSS API instance and removes it from software MAC. * @brief Deletes a FHSS API instance and removes it from software MAC.
* @param fhss_api FHSS instance. * @param fhss_api FHSS instance.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -166,6 +166,7 @@ typedef enum {
NET_6LOWPAN_ND_WITHOUT_MLE, /**< **UNSUPPORTED** */ NET_6LOWPAN_ND_WITHOUT_MLE, /**< **UNSUPPORTED** */
NET_6LOWPAN_ND_WITH_MLE, /**< 6LoWPAN ND with MLE. */ NET_6LOWPAN_ND_WITH_MLE, /**< 6LoWPAN ND with MLE. */
NET_6LOWPAN_THREAD, /**< 6LoWPAN Thread with MLE attached. */ NET_6LOWPAN_THREAD, /**< 6LoWPAN Thread with MLE attached. */
NET_6LOWPAN_WS , /**< WS. */
NET_6LOWPAN_ZIGBEE_IP /**< **UNSUPPORTED** */ NET_6LOWPAN_ZIGBEE_IP /**< **UNSUPPORTED** */
} net_6lowpan_mode_extension_e; } net_6lowpan_mode_extension_e;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -36,19 +36,33 @@
#include "ns_types.h" #include "ns_types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* This API must be able to provide this many simultaneous contexts */
#if 1 /* config option for 802.15.4-2015? */
#define ARM_AES_MBEDTLS_CONTEXT_MIN 2 /**</ event loop and driver rx callback context */
#else
#define ARM_AES_MBEDTLS_CONTEXT_MIN 1 /**</ event loop use only */
#endif
typedef struct arm_aes_context arm_aes_context_t;
/** /**
* \brief Set the AES key * \brief Set the AES key
* *
* This function sets the 128-bit AES key that will be used for future * This function sets the 128-bit AES key that will be used for future
* calls to arm_aes_encrypt(). The key must be copied by the function. * calls to arm_aes_encrypt(). The key must be copied by the function.
* Function must return unique pointer for every started AES context.
* *
* \param key pointer to 128-bit AES key * \param key pointer to 128-bit AES key
*
* \return Pointer to aes context
* \return NULL if aes context allocation fail
*/ */
void arm_aes_start(const uint8_t key[__static 16]); arm_aes_context_t *arm_aes_start(const uint8_t key[__static 16]);
/** /**
* \brief This function performs dst=E[preset key,src] (Simple ECB block). * \brief This function performs dst=E[preset key,src] (Simple ECB block).
@ -57,10 +71,12 @@ void arm_aes_start(const uint8_t key[__static 16]);
* It is called between arm_aes_start() and arm_aes_finish(). * It is called between arm_aes_start() and arm_aes_finish().
* Note that src and dst pointers may be equal. * Note that src and dst pointers may be equal.
* *
* \param aes_context Pointer for allocated
* \param src pointer to 128-bit plaintext in * \param src pointer to 128-bit plaintext in
* \param dst pointer for 128-bit ciphertext out * \param dst pointer for 128-bit ciphertext out
*/ */
extern void arm_aes_encrypt( extern void arm_aes_encrypt(
arm_aes_context_t *aes_context,
const uint8_t src[__static 16], const uint8_t src[__static 16],
uint8_t dst[__static 16]); uint8_t dst[__static 16]);
@ -69,9 +85,9 @@ extern void arm_aes_encrypt(
* *
* This function is called to terminate a series of AES operations. * This function is called to terminate a series of AES operations.
* It may be a no-op, or it may disable AES hardware. Use of the preset key is * It may be a no-op, or it may disable AES hardware. Use of the preset key is
* no longer valid after this call. * no longer valid after this call and aes context will be freed.
*/ */
void arm_aes_finish(void); void arm_aes_finish(arm_aes_context_t *aes_context);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -45,6 +45,7 @@ typedef enum {
PHY_LINK_TX_SUCCESS, /**< MAC TX complete. MAC will a make decision to enter wait ACK or TX done state. */ PHY_LINK_TX_SUCCESS, /**< MAC TX complete. MAC will a make decision to enter wait ACK or TX done state. */
PHY_LINK_TX_FAIL, /**< Link TX process fail. */ PHY_LINK_TX_FAIL, /**< Link TX process fail. */
PHY_LINK_CCA_FAIL, /**< RF link CCA process fail. */ PHY_LINK_CCA_FAIL, /**< RF link CCA process fail. */
PHY_LINK_CCA_PREPARE, /**< RX Tx timeout prepare operation like channel switch to Tx channel from Receive one If operation fail must return not zero*/
} phy_link_tx_status_e; } phy_link_tx_status_e;
/** Extension types */ /** Extension types */
@ -56,6 +57,13 @@ typedef enum {
PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */ PHY_EXTENSION_READ_LINK_STATUS, /**< Net library could read link status. */
PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */ PHY_EXTENSION_CONVERT_SIGNAL_INFO, /**< Convert signal info. */
PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */ PHY_EXTENSION_ACCEPT_ANY_BEACON, /**< Set boolean true or false for accept beacon from other Pan-ID than configured. Default value should be false */
PHY_EXTENSION_SET_TX_TIME, /**< Net library sets transmission time based on global time stamp. Max. 65ms from setting to TX. If TX time is set to zero, it should be ignored.*/
PHY_EXTENSION_READ_RX_TIME, /**< Read the time of last reception based on global micro seconds time stamp. */
PHY_EXTENSION_READ_TX_FINNISH_TIME, /**< Read the time of last finished TX micro seconds based on global time stamp. */
PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, /**< Read status for support Radio driver support for set TX time, CCA and Timestamp read. Also PHY_LINK_CCA_PREPARE tx status must be supported also*/
PHY_EXTENSION_GET_TIMESTAMP, /**< Read 32-bit constant monotonic time stamp in us */
PHY_EXTENSION_SET_CSMA_PARAMETERS, /**< CSMA parameter's are given by phy_csma_params_t structure remember type cast uint8_t pointer to structure type*/
PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, /**< Read Symbols per seconds which will help to convert symbol time to real time */
} phy_extension_type_e; } phy_extension_type_e;
/** Address types */ /** Address types */
@ -110,6 +118,12 @@ typedef struct phy_signal_info_s {
uint16_t result; /**< Resulting signal information. */ uint16_t result; /**< Resulting signal information. */
} phy_signal_info_s; } phy_signal_info_s;
/** CSMA-CA parameters */
typedef struct phy_csma_params {
uint32_t backoff_time; /**< CSMA Backoff us time before start CCA & TX. 0 should disable current backoff*/
bool cca_enabled; /**< True will affect CCA check false start TX direct after backoff */
} phy_csma_params_t;
/** PHY modulation scheme */ /** PHY modulation scheme */
typedef enum phy_modulation_e typedef enum phy_modulation_e
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -66,6 +66,13 @@ extern int8_t ns_sw_mac_virtual_client_unregister(struct mac_api_s *api);
*/ */
extern int ns_sw_mac_fhss_register(struct mac_api_s *mac_api, struct fhss_api *fhss_api); extern int ns_sw_mac_fhss_register(struct mac_api_s *mac_api, struct fhss_api *fhss_api);
/**
* @brief Request registered FHSS API instance from software MAC instance.
* @param mac_api MAC instance.
* @return FHSS api.
*/
extern struct fhss_api *ns_sw_mac_get_fhss_api(struct mac_api_s *mac_api);
/** /**
* @brief Start collecting statistics from software MAC. * @brief Start collecting statistics from software MAC.
* @param mac_api MAC instance. * @param mac_api MAC instance.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -75,6 +75,19 @@ int thread_bbr_start(int8_t interface_id, int8_t backbone_interface_id);
* *
*/ */
int thread_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay); int thread_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
/**
* Set prefix to be used as combining multiple thread networks on backbone.
*
* update prefix value
*
* \param interface_id interface ID of the Thread network.
* \param prefix value must be buffer at the size of 8 bytes
*
* \return 0 on success
* \return <0 in case of errors
*
*/
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
/** /**
* Set the Thread validation interface destination address. * Set the Thread validation interface destination address.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -54,6 +54,7 @@ typedef struct thread_border_router_info_t {
bool P_default_route: 1; /**< This device provides the default route. */ bool P_default_route: 1; /**< This device provides the default route. */
bool P_on_mesh: 1; /**< This prefix is considered to be on-mesh */ bool P_on_mesh: 1; /**< This prefix is considered to be on-mesh */
bool P_nd_dns: 1; /**< this border router is able to provide DNS information */ bool P_nd_dns: 1; /**< this border router is able to provide DNS information */
bool P_res1: 1; /**< First reserved bit */
bool stableData: 1; /**< This data is stable and expected to be available at least 48h. */ bool stableData: 1; /**< This data is stable and expected to be available at least 48h. */
} thread_border_router_info_t; } thread_border_router_info_t;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -96,7 +96,7 @@ typedef struct link_configuration {
#define SECURITY_POLICY_EXTERNAL_COMMISSIONER_ALLOWED 0x10 /**< This indicates that external Commissioner authentication is allowed using PSKc. */ #define SECURITY_POLICY_EXTERNAL_COMMISSIONER_ALLOWED 0x10 /**< This indicates that external Commissioner authentication is allowed using PSKc. */
#define SECURITY_POLICY_BEACON_PAYLOAD_ENABLED 0x08 /**< Thread 1.x Beacons are enabled when this is set. */ #define SECURITY_POLICY_BEACON_PAYLOAD_ENABLED 0x08 /**< Thread 1.x Beacons are enabled when this is set. */
/* /**
* Mandatory device information * Mandatory device information
* *
* This information is required if commissioning is enabled for this device. * This information is required if commissioning is enabled for this device.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -69,8 +69,11 @@
#endif #endif
#include "sw_mac.h" #include "sw_mac.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "6LoWPAN/MAC/mpx_api.h"
#include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/lowpan_adaptation_interface.h"
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
#include "Service_Libs/etx/etx.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP_LOWPAN "6lo" #define TRACE_GROUP_LOWPAN "6lo"
@ -164,7 +167,7 @@ void protocol_6lowpan_stack(buffer_t *b)
case B_TO_PHY: case B_TO_PHY:
b = lowpan_adaptation_data_process_tx_preprocess(cur, b); b = lowpan_adaptation_data_process_tx_preprocess(cur, b);
if (lowpan_adaptation_interface_tx(cur, b) != 0) { if (lowpan_adaptation_interface_tx(cur, b) != 0) {
tr_error("Adaptaion Layer Data req fail"); tr_error("Adaptation Layer Data req fail");
} }
b = NULL; b = NULL;
break; break;
@ -347,7 +350,6 @@ void protocol_6lowpan_host_init(protocol_interface_info_entry_t *cur, bool sleep
} }
//Clear always INTERFACE_NWK_ROUTER_DEVICE, INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE //Clear always INTERFACE_NWK_ROUTER_DEVICE, INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE
cur->lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE); cur->lowpan_info &= ~(INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE);
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
mac_data_poll_init(cur); mac_data_poll_init(cur);
arm_nwk_6lowpan_borderrouter_data_free(cur); arm_nwk_6lowpan_borderrouter_data_free(cur);
@ -358,7 +360,6 @@ void protocol_6lowpan_router_init(protocol_interface_info_entry_t *cur)
cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER; cur->bootsrap_mode = ARM_NWK_BOOTSRAP_MODE_6LoWPAN_ROUTER;
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
mac_data_poll_init(cur); mac_data_poll_init(cur);
arm_nwk_6lowpan_borderrouter_data_free(cur); arm_nwk_6lowpan_borderrouter_data_free(cur);
} }
@ -398,6 +399,7 @@ void protocol_6lowpan_register_handlers(protocol_interface_info_entry_t *cur)
* for routers, as RPL doesn't deal with it) */ * for routers, as RPL doesn't deal with it) */
cur->ipv6_neighbour_cache.send_addr_reg = true; cur->ipv6_neighbour_cache.send_addr_reg = true;
cur->ipv6_neighbour_cache.recv_na_aro = true; cur->ipv6_neighbour_cache.recv_na_aro = true;
cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro = false;
} }
void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress) void protocol_6lowpan_release_short_link_address_from_neighcache(protocol_interface_info_entry_t *cur, uint16_t shortAddress)
{ {
@ -430,28 +432,27 @@ void protocol_6lowpan_release_long_link_address_from_neighcache(protocol_interfa
} }
#ifdef HAVE_6LOWPAN_ND #ifdef HAVE_6LOWPAN_ND
static int8_t mle_set_link_priority(int8_t interface_id, const uint8_t *address, bool priority) static int8_t mle_set_link_priority(protocol_interface_info_entry_t *cur, const uint8_t *address, bool priority)
{ {
uint8_t mac64[8]; uint8_t mac64[8];
mle_neigh_table_entry_t *mle_entry; mac_neighbor_table_entry_t *entry;
if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) { if (!memcmp(address, ADDR_SHORT_ADR_SUFFIC, 6)) {
mle_entry = mle_class_get_by_link_address(interface_id, address + 6, ADDR_802_15_4_SHORT); entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address + 6, ADDR_802_15_4_SHORT);
} else { } else {
memcpy(mac64, address, 8); memcpy(mac64, address, 8);
mac64[0] ^= 2; mac64[0] ^= 2;
mle_entry = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG); entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG);
} }
if (!mle_entry) { if (!entry) {
return -1; return -1;
} }
if (priority) { if (priority) {
mle_entry->priorityFlag = 1; entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
} else { } else {
mle_entry->priorityFlag = 0; entry->link_role = NORMAL_NEIGHBOUR;
} }
return 0; return 0;
} }
@ -461,11 +462,11 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
#ifndef NO_MLE #ifndef NO_MLE
if (removed_priority) { if (removed_priority) {
mle_set_link_priority(cur->id,removed_priority, false); mle_set_link_priority(cur,removed_priority, false);
} }
if (updated_priority) { if (updated_priority) {
mle_set_link_priority(cur->id, updated_priority, true); mle_set_link_priority(cur, updated_priority, true);
} }
#endif #endif
} }
@ -476,30 +477,30 @@ void protocol_6lowpan_neighbor_priority_update(protocol_interface_info_entry_t *
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
{ {
mle_neigh_table_entry_t *neigh_table_ptr; protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!addr_ptr) { if (!cur || !addr_ptr) {
return 0; return 0;
} }
neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type);
if (neigh_table_ptr) { if (entry) {
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
// If primary parent has changed clears priority from previous parent // If primary parent has changed clears priority from previous parent
if (!neigh_table_ptr->priorityFlag) { if (entry->link_role != PRIORITY_PARENT_NEIGHBOUR) {
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST); protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_1ST);
} }
neigh_table_ptr->priorityFlag = 1; entry->link_role = PRIORITY_PARENT_NEIGHBOUR;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (cur) { uint8_t temp[2];
uint8_t temp[2]; common_write_16_bit(entry->mac16, temp);
common_write_16_bit(neigh_table_ptr->short_adr, temp); mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp);
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, temp); mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, entry->mac64);
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_LONG, neigh_table_ptr->mac64); if (etx_entry) {
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
} }
protocol_stats_update(STATS_ETX_1ST_PARENT, neigh_table_ptr->etx >> 4);
return 1; return 1;
} else { } else {
return 0; return 0;
@ -508,21 +509,26 @@ uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr) uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr)
{ {
mle_neigh_table_entry_t *neigh_table_ptr;
if (!addr_ptr) { protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !addr_ptr) {
return 0; return 0;
} }
neigh_table_ptr = mle_class_get_by_link_address(interface_id, addr_ptr + PAN_ID_LEN, addr_type); mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr_ptr + PAN_ID_LEN, addr_type);
if (neigh_table_ptr) { if (entry) {
etx_storage_t *etx_entry = etx_storage_entry_get(interface_id, entry->index);
// If secondary parent has changed clears priority from previous parent // If secondary parent has changed clears priority from previous parent
if (neigh_table_ptr->second_priority_flag == 0) { if (entry->link_role != SECONDARY_PARENT_NEIGHBOUR) {
protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND); protocol_6lowpan_neighbor_priority_clear_all(interface_id, PRIORITY_2ND);
} }
neigh_table_ptr->second_priority_flag = 1; entry->link_role = SECONDARY_PARENT_NEIGHBOUR;
protocol_stats_update(STATS_ETX_2ND_PARENT, neigh_table_ptr->etx >> 4);
if (etx_entry) {
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
}
return 1; return 1;
} else { } else {
return 0; return 0;
@ -531,21 +537,22 @@ uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addr
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority) void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority)
{ {
mle_neigh_table_list_t *mle_neigh_table; protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
mle_neigh_table = mle_class_active_list_get(interface_id); if (!cur) {
if (!mle_neigh_table) {
return; return;
} }
mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_table_list) {
if (priority == PRIORITY_1ST) { if (priority == PRIORITY_1ST && entry->link_role == PRIORITY_PARENT_NEIGHBOUR) {
entry->priorityFlag = 0; entry->link_role = NORMAL_NEIGHBOUR;
} else { } else {
if (entry->second_priority_flag) { if (entry->link_role == SECONDARY_PARENT_NEIGHBOUR) {
protocol_stats_update(STATS_ETX_2ND_PARENT, 0); protocol_stats_update(STATS_ETX_2ND_PARENT, 0);
entry->link_role = NORMAL_NEIGHBOUR;
} }
entry->second_priority_flag = 0;
} }
} }
} }
@ -558,43 +565,33 @@ void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_
int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8]) int8_t protocol_6lowpan_neighbor_address_state_synch(protocol_interface_info_entry_t *cur, const uint8_t eui64[8], const uint8_t iid[8])
{ {
int8_t ret_val = -1; int8_t ret_val = -1;
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
#ifndef NO_MLE mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), eui64, ADDR_802_15_4_LONG);
mle_neigh_table_entry_t *mle_entry = 0; if (entry) {
mle_entry = mle_class_get_by_link_address(cur->id, eui64, ADDR_802_15_4_LONG); if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) {
if (mle_entry && !mle_entry->threadNeighbor) { iid += 6;
if (memcmp(iid, ADDR_SHORT_ADR_SUFFIC, 6) == 0) { //Set Short Address to MLE
iid += 6; entry->mac16 = common_read_16_bit(iid);
//Set Short Address to MLE }
mle_entry->short_adr = common_read_16_bit(iid); if (!entry->ffd_device) {
} if (entry->connected_device) {
if ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry, entry->link_lifetime);
if (mle_entry->handshakeReady) { }
mle_entry_timeout_refresh(mle_entry); ret_val = 1;
} } else {
ret_val = 1; ret_val = 0;
} else {
ret_val = 0;
}
} }
#endif
} else {
ret_val = 0;
} }
return ret_val; return ret_val;
} }
int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type) int8_t protocol_6lowpan_neighbor_remove(protocol_interface_info_entry_t *cur, uint8_t *address_ptr, addrtype_t type)
{ {
int8_t ret_val = 0; mac_neighbor_table_entry_t * entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address_ptr, type);
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { if (entry) {
#ifndef NO_MLE mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry);
mle_class_remove_neighbour(cur->id, address_ptr, type);
#endif
} else {
//REMOVE Something else
} }
return ret_val; return 0;
} }
void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur) void protocol_6lowpan_allocate_mac16(protocol_interface_info_entry_t *cur)
@ -739,7 +736,7 @@ uint8_t protocol_6lowpan_beacon_join_priority_tx(int8_t interface_id)
mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get(); mle_6lowpan_data_t *mle_6lowpan_data = protocol_6lowpan_mle_data_get();
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur);
if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) { if (mle_neigh_cnt > mle_6lowpan_data->nbr_of_neigh_lower_threshold) {
uint16_t mle_neigh_limit; uint16_t mle_neigh_limit;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -69,7 +69,9 @@
#include "mac_api.h" #include "mac_api.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "libNET/src/net_load_balance_internal.h" #include "libNET/src/net_load_balance_internal.h"
#include "6LoWPAN/lowpan_adaptation_interface.h"
#include "6LoWPAN/NVM/nwk_nvm.h" #include "6LoWPAN/NVM/nwk_nvm.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
/* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315 /* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315
@ -90,15 +92,16 @@ static void protocol_6lowpan_bootstrap_rpl_callback(rpl_event_t event, void *han
#endif #endif
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority); static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority);
static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count); static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id,mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count);
static uint8_t protocol_6lowpan_mle_data_allocate(void); static uint8_t protocol_6lowpan_mle_data_allocate(void);
static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries); static bool mle_accept_request_cb(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status); static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status);
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur); static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur);
static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64); static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64); static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur_interface, const uint8_t *mac64);
static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64);
static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface); static void protocol_6lowpan_address_reg_ready(protocol_interface_info_entry_t *cur_interface);
static void coordinator_black_list(protocol_interface_info_entry_t *cur); static void coordinator_black_list(protocol_interface_info_entry_t *cur);
@ -158,9 +161,9 @@ uint8_t *mle_general_write_timeout(uint8_t *ptr, protocol_interface_info_entry_t
} }
static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mle_neigh_table_entry_t *cur) static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *cur)
{ {
if (!cur->priorityFlag || if (cur->link_role != PRIORITY_PARENT_NEIGHBOUR ||
!(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur_interface->lowpan_info & INTERFACE_NWK_ACTIVE) ||
cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
return; return;
@ -176,9 +179,9 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en
} }
} else { } else {
//Call Priority parent loose //Call Priority parent loose
if (cur->short_adr != 0xffff) { if (cur->mac16 != 0xffff) {
memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6); memcpy(mac64, ADDR_SHORT_ADR_SUFFIC, 6);
common_write_16_bit(cur->short_adr, &mac64[6]); common_write_16_bit(cur->mac16, &mac64[6]);
} else { } else {
memcpy(mac64,cur->mac64 , 8); memcpy(mac64,cur->mac64 , 8);
mac64[0] ^= 2; mac64[0] ^= 2;
@ -192,64 +195,42 @@ static void protocol_6lowpan_priority_neighbor_remove(protocol_interface_info_en
} }
} }
static void protocol_6lowpan_neighbor_information_remove(int8_t interface_id, mle_neigh_table_entry_t *cur) static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
{ {
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur_interface) { if (!cur_interface) {
return; return false;
} }
// Sleepy host
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
mac_data_poll_protocol_poll_mode_decrement(cur_interface);
}
protocol_6lowpan_priority_neighbor_remove(cur_interface, cur);
if (cur->mode & MLE_FFD_DEV) {
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, cur->short_adr);
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, cur->mac64);
}
mac_helper_devicetable_remove(cur_interface->mac_api, cur->attribute_index);
}
static bool protocol_6lowpan_challenge_callback(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
{
uint8_t mac64[8]; uint8_t mac64[8];
uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId); uint8_t *ll64_ptr = mle_service_get_msg_destination_address_pointer(msgId);
memcpy(mac64, ll64_ptr + 8, 8); memcpy(mac64, ll64_ptr + 8, 8);
mac64[0] ^= 2; mac64[0] ^= 2;
mle_neigh_table_entry_t *neig_info = mle_class_get_by_link_address(interface_id, mac64, ADDR_802_15_4_LONG); mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), mac64, ADDR_802_15_4_LONG);
if (!neig_info) { if (!neig_info) {
return false;//Why entry is removed before timeout?? return false;//Why entry is removed before timeout??
} }
if (neig_info->ttl > MLE_TABLE_CHALLENGE_TIMER) { if (!neig_info->nud_active) {
return false; return false;
} }
if (usedAllRetries) { if (usedAllRetries) {
//GET entry //GET entry
mle_class_remove_entry(interface_id, neig_info); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), neig_info);
return false; return false;
} }
return true; return true;
} }
static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t *mac64) static bool protocol_6lowpan_host_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur) {
return false;
}
uint16_t bufId; uint16_t bufId;
mle_message_timeout_params_t timeout; mle_message_timeout_params_t timeout;
uint8_t ll64[16]; uint8_t ll64[16];
@ -261,7 +242,7 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t
tr_debug("Link REQUEST"); tr_debug("Link REQUEST");
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
if (bufId == 0) { if (bufId == 0) {
return -1; return false;
} }
uint8_t *ptr = mle_service_get_data_pointer(bufId); uint8_t *ptr = mle_service_get_data_pointer(bufId);
@ -293,16 +274,11 @@ static int8_t protocol_6lowpan_host_challenge(int8_t interface_id, const uint8_t
mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_set_msg_timeout_parameters(bufId, &timeout);
mle_service_send_message(bufId); mle_service_send_message(bufId);
return 0; return true;
} }
static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8_t *mac64) static bool protocol_6lowpan_router_challenge(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur) {
return false;
}
uint16_t bufId; uint16_t bufId;
mle_message_timeout_params_t timeout; mle_message_timeout_params_t timeout;
@ -315,7 +291,7 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8
tr_debug("Link REQUEST"); tr_debug("Link REQUEST");
bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST); bufId = mle_service_msg_allocate(cur->id, 32, true,MLE_COMMAND_REQUEST);
if (bufId == 0) { if (bufId == 0) {
return -1; return false;
} }
uint8_t *ptr = mle_service_get_data_pointer(bufId); uint8_t *ptr = mle_service_get_data_pointer(bufId);
@ -342,16 +318,16 @@ static int8_t protocol_6lowpan_router_challenge(int8_t interface_id, const uint8
mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_set_msg_timeout_parameters(bufId, &timeout);
mle_service_send_message(bufId); mle_service_send_message(bufId);
return 0; return true;
} }
static uint8_t mle_advert_neigh_cnt(int8_t interface_id, bool short_adr) { static uint8_t mle_advert_neigh_cnt(protocol_interface_info_entry_t *cur_interface, bool short_adr) {
uint8_t advert_neigh_cnt; uint8_t advert_neigh_cnt;
uint8_t neighb_max; uint8_t neighb_max;
uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); uint8_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface);
if (short_adr == true) { if (short_adr == true) {
neighb_max = 16; neighb_max = 16;
@ -413,88 +389,94 @@ static uint8_t mle_link_quality_tlv_parse(uint8_t *mac64, uint16_t short_address
return 0; return 0;
} }
static uint8_t *mle_table_set_neighbours(int8_t interface_id, uint8_t *ptr) static bool neighbor_list_short_address_available(mac_neighbor_table_t *table_class)
{
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, &table_class->neighbour_list) {
if (cur_entry->connected_device && cur_entry->mac16 == 0xffff) {
return false;
}
}
return true;
}
static uint8_t *mle_table_set_neighbours(protocol_interface_info_entry_t *cur, uint8_t *ptr)
{ {
uint8_t *len_ptr = 0; uint8_t *len_ptr = 0;
uint8_t short_temp[2] = {0xff,0xff};
uint8_t neigh_count = 0; uint8_t neigh_count = 0;
uint8_t neigh_count_max = 0; uint8_t neigh_count_max = 0;
uint8_t *link_flags_ptr; uint8_t *link_flags_ptr;
mle_neigh_table_entry_t *first_entry_ptr = NULL; mac_neighbor_table_entry_t *first_entry_ptr = NULL;
bool loop_list = false;
mle_neigh_table_list_t * neigh_list = mle_class_active_list_get(interface_id); mac_neighbor_table_list_t * neigh_list = &cur->mac_parameters->mac_neighbor_table->neighbour_list;
if (!neigh_list) {
return ptr;
}
*ptr++ = MLE_TYPE_LINK_QUALITY; *ptr++ = MLE_TYPE_LINK_QUALITY;
len_ptr = ptr++; len_ptr = ptr++;
*len_ptr = 1; *len_ptr = 1;
// defaults: complete, 2 bytes long link-layer address
link_flags_ptr = ptr++;
*link_flags_ptr = 0x81;
if (mle_class_get_by_link_address(interface_id, short_temp,ADDR_802_15_4_SHORT)) { link_flags_ptr = ptr++;
*link_flags_ptr |= 0x07; //*link_flags_ptr = 0x81;
neigh_count_max = mle_advert_neigh_cnt(interface_id, false); bool use_short_address_compression = neighbor_list_short_address_available(mac_neighbor_info(cur));
if (use_short_address_compression) {
//complete, 2 bytes long link-layer address
*link_flags_ptr = 0x81;
} else { } else {
neigh_count_max = mle_advert_neigh_cnt(interface_id, true); //complete, 8 bytes long link-layer address
*link_flags_ptr = 0x87;
}
neigh_count_max = mle_advert_neigh_cnt(cur, use_short_address_compression);
bool clean_entries = false;
ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, neigh_list)
{
if ((cur_entry->connected_device) && (cur_entry->advertisment == false)) {
// If looping list, stops adding entries when at first sent entry again
if (first_entry_ptr == cur_entry) {
break;
} else if (first_entry_ptr == NULL) {
first_entry_ptr = cur_entry;
}
// Limits the number of entries that are sent
if (++neigh_count > neigh_count_max) {
*link_flags_ptr &= 0x7f;
break;
}
if (cur_entry->link_role == PRIORITY_PARENT_NEIGHBOUR) {
*ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
} else {
*ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
}
*ptr++ = etx_local_incoming_idr_read(cur->id, cur_entry->index) >> 3;
if (use_short_address_compression) {
ptr = common_write_16_bit(cur_entry->mac16, ptr);
*len_ptr += 4;
} else {
memcpy(ptr, cur_entry->mac64, 8);
ptr += 8;
*len_ptr += 10;
}
// If end of the neighbor list, Mark a clean advertisment from the list
if (cur_entry->link.next == 0) {
clean_entries = true;
}
cur_entry->advertisment = true;
}
} }
do { if (clean_entries) {
ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) ns_list_foreach(mac_neighbor_table_entry_t, temp, neigh_list) {
{ // Marks entries not sent
temp->advertisment = false;
loop_list = false;
if ((cur->handshakeReady) && (cur->link_q_adv_sent == false)) {
// If looping list, stops adding entries when at first sent entry again
if (first_entry_ptr == cur) {
break;
} else if (first_entry_ptr == NULL) {
first_entry_ptr = cur;
}
// Limits the number of entries that are sent
if (++neigh_count > neigh_count_max) {
*link_flags_ptr &= 0x7f;
break;
}
if (cur->priorityFlag) {
*ptr++ = MLE_NEIGHBOR_PRIORITY_LINK | MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
} else {
*ptr++ = MLE_NEIGHBOR_INCOMING_LINK | MLE_NEIGHBOR_OUTGOING_LINK;
}
*ptr++ = etx_local_incoming_idr_read(interface_id, cur) >> 3;
if ((*link_flags_ptr & 0x07) == 1) {
ptr = common_write_16_bit(cur->short_adr, ptr);
*len_ptr += 4;
} else {
memcpy(ptr, cur->mac64, 8);
ptr += 8;
*len_ptr += 10;
}
// If end of the neighbor list, start adding entries from start again
if (cur->link.next == 0) {
loop_list = true;
mle_neigh_table_list_t * neigh_temp = mle_class_active_list_get(interface_id);
ns_list_foreach(mle_neigh_table_entry_t, temp, neigh_temp)
{
// Marks entries not sent
temp->link_q_adv_sent = false;
}
} else {
cur->link_q_adv_sent = true;
}
}
} }
} while (loop_list); }
return ptr; return ptr;
} }
@ -515,10 +497,10 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
return 0; return 0;
} }
if (mle_class_get_by_link_address(cur->id, short_temp,ADDR_802_15_4_SHORT)) { if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), short_temp,ADDR_802_15_4_SHORT)) {
neig_cache_size += mle_advert_neigh_cnt(cur->id, false) * 10; neig_cache_size += mle_advert_neigh_cnt(cur, false) * 10;
} else { } else {
neig_cache_size += mle_advert_neigh_cnt(cur->id, true) << 2; neig_cache_size += mle_advert_neigh_cnt(cur, true) << 2;
} }
uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT); uint16_t bufId = mle_service_msg_allocate(cur->id, neig_cache_size, false, MLE_COMMAND_ADVERTISEMENT);
@ -539,7 +521,7 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
ptr = mle_service_get_data_pointer(bufId); ptr = mle_service_get_data_pointer(bufId);
ptr = mle_general_write_source_address(ptr, cur); ptr = mle_general_write_source_address(ptr, cur);
ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur)); ptr = mle_tlv_write_mode(ptr, lowpan_mode_get_by_interface_ptr(cur));
ptr = mle_table_set_neighbours(cur->id, ptr); ptr = mle_table_set_neighbours(cur, ptr);
if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) { if (mle_service_update_length_by_ptr(bufId,ptr)!= 0) {
tr_debug("Buffer overflow at message write"); tr_debug("Buffer overflow at message write");
@ -549,15 +531,6 @@ static int protocol_6lowpan_mle_neigh_advertise(protocol_interface_info_entry_t
} }
#endif #endif
static uint8_t compute_link_margin(int8_t rssi)
{
if (rssi < -94) {
return 0;
}
return (rssi + 94);
}
static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info) static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data_len, mle_tlv_info_t *tlv_info)
{ {
/** /**
@ -571,8 +544,11 @@ static int mle_validate_6lowpan_link_request_message(uint8_t *ptr, uint16_t data
return 0; return 0;
} }
static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length) static void mle_neigh_time_and_mode_update(mac_neighbor_table_entry_t *entry_temp, mle_message_t *mle_msg)
{ {
uint8_t *tlv_ptr = mle_msg->data_ptr;
uint16_t tlv_length = mle_msg->data_length;
mle_tlv_info_t mle_tlv_info; mle_tlv_info_t mle_tlv_info;
uint32_t timeout_tlv; uint32_t timeout_tlv;
@ -580,42 +556,44 @@ static void mle_neigh_time_and_mode_update(mle_neigh_table_entry_t *entry_temp,
return; return;
} }
protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) { if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_MODE, &mle_tlv_info) > 0) {
uint8_t *t_ptr = mle_tlv_info.dataPtr; uint8_t *t_ptr = mle_tlv_info.dataPtr;
entry_temp->mode = *t_ptr; mle_mode_parse_to_mac_entry(entry_temp, *t_ptr);
} }
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) { if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr); timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
} else { } else {
if (entry_temp->mode & MLE_FFD_DEV) { if (entry_temp->ffd_device) {
timeout_tlv = mle_6lowpan_data->router_lifetime; timeout_tlv = mle_6lowpan_data->router_lifetime;
} else { } else {
timeout_tlv = mle_6lowpan_data->host_lifetime; timeout_tlv = mle_6lowpan_data->host_lifetime;
} }
} }
mle_entry_timeout_update(entry_temp, timeout_tlv); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv);
} }
static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mle_neigh_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address) static void mle_neigh_entry_update_by_mle_tlv_list(int8_t interface_id, mac_neighbor_table_entry_t *entry_temp, uint8_t *tlv_ptr, uint16_t tlv_length, uint8_t *mac64, uint16_t short_address)
{ {
mle_tlv_info_t mle_tlv_info; mle_tlv_info_t mle_tlv_info;
if (tlv_length) { if (tlv_length) {
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) { if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_SRC_ADDRESS, &mle_tlv_info) > 0) {
entry_temp->short_adr = common_read_16_bit(mle_tlv_info.dataPtr); entry_temp->mac16 = common_read_16_bit(mle_tlv_info.dataPtr);
} }
if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) { if (mle_tlv_option_discover(tlv_ptr, tlv_length, MLE_TYPE_LINK_QUALITY, &mle_tlv_info) > 0) {
uint8_t link_idr; uint8_t link_idr;
uint8_t iop_flags; uint8_t iop_flags;
if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) { if (mle_link_quality_tlv_parse(mac64, short_address, mle_tlv_info.dataPtr, mle_tlv_info.tlvLen, &iop_flags, &link_idr)) {
etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp); etx_remote_incoming_idr_update(interface_id, link_idr, entry_temp->index);
if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) { if ((iop_flags & MLE_NEIGHBOR_PRIORITY_LINK) == MLE_NEIGHBOR_PRIORITY_LINK) {
entry_temp->priority_child_flag = true; entry_temp->link_role = CHILD_NEIGHBOUR;
} else { } else if (entry_temp->link_role == CHILD_NEIGHBOUR) {
entry_temp->priority_child_flag = false; entry_temp->link_role = NORMAL_NEIGHBOUR;
} }
} }
} }
@ -758,10 +736,10 @@ static int mle_router_accept_request_build(protocol_interface_info_entry_t *cur,
static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64) static void protocol_6lowpan_link_reject_handler(protocol_interface_info_entry_t *cur, uint8_t *ll64)
{ {
mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, 0, ll64, false, NULL); mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, false, NULL);
tr_debug("MLE link reject"); tr_debug("MLE link reject");
if (entry_temp) { if (mac_entry) {
mle_class_remove_entry(cur->id, entry_temp); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), mac_entry);
} }
} }
@ -984,14 +962,16 @@ int protocol_6lowpan_router_synch_to_new_router(protocol_interface_info_entry_t
} }
static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mle_neigh_table_entry_t *entry_temp) static uint8_t mle_calculate_idr(int8_t interface_id, mle_message_t *mle_msg, mac_neighbor_table_entry_t *entry_temp)
{ {
if (!entry_temp) {
return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp) >> 3; return etx_lqi_dbm_update(-2, mle_msg->lqi, mle_msg->dbm, 0) >> 3;
}
return etx_lqi_dbm_update(interface_id, mle_msg->lqi, mle_msg->dbm, entry_temp->index) >> 3;
} }
static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t *mle_msg, uint8_t only_max_limit_chk) static bool mle_6lowpan_neighbor_limit_check(mle_message_t *mle_msg, uint8_t only_max_limit_chk)
{ {
uint16_t mle_neigh_cnt; uint16_t mle_neigh_cnt;
bool link_quality = false; bool link_quality = false;
@ -1000,7 +980,7 @@ static bool mle_6lowpan_neighbor_limit_check(int8_t interface_id, mle_message_t
return true; return true;
} }
mle_neigh_cnt = mle_class_active_neigh_counter(interface_id); mle_neigh_cnt = mle_class_active_neigh_counter(mle_msg->interface_ptr);
// Neighbor max limit // Neighbor max limit
if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) { if (mle_neigh_cnt >= mle_6lowpan_data->nbr_of_neigh_max) {
@ -1048,17 +1028,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
uint8_t mode = 0x0a; uint8_t mode = 0x0a;
mle_tlv_info_t mle_tlv_info; mle_tlv_info_t mle_tlv_info;
mle_tlv_info_t mle_challenge; mle_tlv_info_t mle_challenge;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
uint8_t linkMargin;
uint8_t incoming_idr; uint8_t incoming_idr;
uint16_t responseId, own_mac16; uint16_t responseId, own_mac16;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (!cur) {
return;
}
//Calculate link margin
linkMargin = compute_link_margin(mle_msg->dbm);
own_mac16 = mac_helper_mac16_address_get(cur); own_mac16 = mac_helper_mac16_address_get(cur);
@ -1081,13 +1055,13 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
mle_6lowpan_data->link_req_token_bucket--; mle_6lowpan_data->link_req_token_bucket--;
} else { } else {
//Update only old information based on link request //Update only old information based on link request
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) { if (entry_temp) {
mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); mle_neigh_time_and_mode_update(entry_temp,mle_msg);
mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_update_by_mle_tlv_list(interface_id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
} else { } else {
if (!mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { if (!mle_6lowpan_neighbor_limit_check(mle_msg, false)) {
return; return;
} }
} }
@ -1095,7 +1069,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp); incoming_idr = mle_calculate_idr(interface_id, mle_msg, entry_temp);
if (entry_temp && entry_temp->handshakeReady) { if (entry_temp && entry_temp->connected_device) {
response_type = MLE_COMMAND_ACCEPT; response_type = MLE_COMMAND_ACCEPT;
} else { } else {
response_type = MLE_COMMAND_ACCEPT_AND_REQUEST; response_type = MLE_COMMAND_ACCEPT_AND_REQUEST;
@ -1117,13 +1091,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
} }
tr_debug("Accept & Request"); tr_debug("Accept & Request");
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL);
if (!entry_temp) { if (!entry_temp) {
// If there is space for neighbors try to allocate new entry // If there is space for neighbors try to allocate new entry
if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, true)) { if (mle_6lowpan_neighbor_limit_check(mle_msg, true)) {
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, true, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, NULL);
} }
} }
@ -1137,23 +1109,22 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
//Response state set now timeout know positive state //Response state set now timeout know positive state
mle_service_set_msg_response_true(responseId); mle_service_set_msg_response_true(responseId);
entry_temp->connected_device = 1;
entry_temp->threadNeighbor = false;
entry_temp->handshakeReady = 1;
mac_data_poll_protocol_poll_mode_decrement(cur); mac_data_poll_protocol_poll_mode_decrement(cur);
//Read Source address and Challenge //Read Source address and Challenge
mle_neigh_time_and_mode_update(entry_temp,mle_msg->data_ptr, mle_msg->data_length); mle_neigh_time_and_mode_update(entry_temp,mle_msg);
if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) { if (mle_msg->message_type == MLE_COMMAND_ACCEPT_AND_REQUEST) {
// If no global address set priority (bootstrap ongoing) // If no global address set priority (bootstrap ongoing)
if (!cur->global_address_available) { if (!cur->global_address_available) {
entry_temp->priorityFlag = true; entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
} }
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, entry_temp->priorityFlag); uint8_t priority = (entry_temp->link_role == PRIORITY_PARENT_NEIGHBOUR);
mle_router_accept_request_build(cur, mle_msg, mle_challenge.dataPtr, mle_challenge.tlvLen, MLE_COMMAND_ACCEPT, incoming_idr, priority);
} else { } else {
mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_update_by_mle_tlv_list(cur->id, entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp); incoming_idr = mle_calculate_idr(cur->id, mle_msg, entry_temp);
@ -1161,7 +1132,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
// If MLE frame counter was invalid update its value since three way handshake is complete // If MLE frame counter was invalid update its value since three way handshake is complete
if (security_headers->invalid_frame_counter) { if (security_headers->invalid_frame_counter) {
entry_temp->mle_frame_counter = security_headers->frameCounter; mle_service_frame_counter_entry_add(interface_id, entry_temp->index, security_headers->frameCounter);
} }
break; break;
@ -1184,12 +1155,11 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
t_ptr = mle_tlv_info.dataPtr; t_ptr = mle_tlv_info.dataPtr;
mode = *t_ptr; mode = *t_ptr;
} }
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
entry_temp = mle_class_get_entry_by_ll64(interface_id, linkMargin, mle_msg->packet_src_address, false, NULL);
if (!entry_temp) { if (!entry_temp) {
if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) { if ((mode & MLE_DEV_MASK) == MLE_FFD_DEV) {
// If there is space for neighbors synchronizes to new router // If there is space for neighbors synchronizes to new router
if (mle_6lowpan_neighbor_limit_check(interface_id, mle_msg, false)) { if (mle_6lowpan_neighbor_limit_check(mle_msg, false)) {
// Checks blacklist // Checks blacklist
if (blacklist_reject(mle_msg->packet_src_address)) { if (blacklist_reject(mle_msg->packet_src_address)) {
return; return;
@ -1220,7 +1190,7 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
//Possible remove //Possible remove
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) { if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV) {
//Remove Entry //Remove Entry
mle_class_remove_entry(cur->id, entry_temp); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
tr_error("MLE adv: Own address not found"); tr_error("MLE adv: Own address not found");
return; return;
} }
@ -1232,8 +1202,8 @@ void mle_6lowpan_message_handler(int8_t interface_id, mle_message_t *mle_msg, ml
//UPDATE //UPDATE
mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16); mle_neigh_entry_update_by_mle_tlv_list(cur->id,entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur->mac, own_mac16);
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
if (entry_temp->handshakeReady) { if (entry_temp->connected_device) {
mle_entry_timeout_refresh(entry_temp); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
} }
} }
break; break;
@ -1250,7 +1220,7 @@ int8_t arm_6lowpan_mle_service_ready_for_security_init(protocol_interface_info_e
//validate MLE service //validate MLE service
if (!mle_service_interface_registeration_validate(cur->id)) { if (!mle_service_interface_registeration_validate(cur->id)) {
//Register //Register
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { if (mle_service_interface_register(cur->id,cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
tr_error("Mle Service init Fail"); tr_error("Mle Service init Fail");
return -1; return -1;
} }
@ -1301,29 +1271,24 @@ mle_6lowpan_data_t *protocol_6lowpan_mle_data_get(void)
static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority) static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_entry *cur_interface, uint8_t entry_count, uint8_t force_priority)
{ {
mle_neigh_table_list_t *mle_neigh_table;
uint8_t count = 0; uint8_t count = 0;
uint8_t ll64[16]; uint8_t ll64[16];
if (!cur_interface) { if (!cur_interface) {
return; return;
} }
mac_neighbor_table_list_t *mac_table_list = &cur_interface->mac_parameters->mac_neighbor_table->neighbour_list;
mle_neigh_table = mle_class_active_list_get(cur_interface->id); entry_count = protocol_6lowpan_mle_order_last_entries(cur_interface->id, mac_table_list, entry_count);
if (!mle_neigh_table) { ns_list_foreach_reverse_safe(mac_neighbor_table_entry_t, entry, mac_table_list) {
return;
}
entry_count = protocol_6lowpan_mle_order_last_entries(mle_neigh_table, entry_count);
ns_list_foreach_reverse_safe(mle_neigh_table_entry_t, entry, mle_neigh_table) {
if (++count > entry_count) { if (++count > entry_count) {
break; break;
} }
if (!force_priority) { if (!force_priority) {
if (entry->priorityFlag || entry->priority_child_flag) { if (entry->link_role == PRIORITY_PARENT_NEIGHBOUR || entry->link_role == CHILD_NEIGHBOUR) {
break; break;
} }
} }
@ -1336,23 +1301,23 @@ static void protocol_6lowpan_mle_purge_neighbors(struct protocol_interface_info_
// Sends REJECT // Sends REJECT
mle_service_reject_message_build(cur_interface->id, ll64, false); mle_service_reject_message_build(cur_interface->id, ll64, false);
mle_class_remove_entry(cur_interface->id, entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur_interface), entry);
// Adds purged neighbor to blacklist so that it is not added right away back from advertisement // Adds purged neighbor to blacklist so that it is not added right away back from advertisement
blacklist_update(ll64, false); blacklist_update(ll64, false);
} }
} }
static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *mle_neigh_table, uint8_t entry_count) static uint8_t protocol_6lowpan_mle_order_last_entries(int8_t interface_id, mac_neighbor_table_list_t *mac_neigh_table, uint8_t entry_count)
{ {
mle_neigh_table_entry_t *last; mac_neighbor_table_entry_t *last;
mle_neigh_table_entry_t *first_ordered = NULL; mac_neighbor_table_entry_t *first_ordered = NULL;
etx_storage_t * etx_last, *etx_cur;
uint8_t count = 0; uint8_t count = 0;
do { do {
last = NULL; last = NULL;
ns_list_foreach(mle_neigh_table_entry_t, entry, mle_neigh_table) { ns_list_foreach(mac_neighbor_table_entry_t, entry, mac_neigh_table) {
if (entry == first_ordered) { if (entry == first_ordered) {
break; break;
@ -1363,37 +1328,27 @@ static uint8_t protocol_6lowpan_mle_order_last_entries(mle_neigh_table_list_t *m
continue; continue;
} }
// Primary parent (parent selected for bootstrap or RPL primary parent) if (entry->link_role > last->link_role) { //Bigger link role is allways better
if (entry->priorityFlag && !last->priorityFlag) {
continue; continue;
} else if (entry->link_role == last->link_role) {
// Compare ETX when Link role is same
etx_cur = etx_storage_entry_get(interface_id, entry->index);
etx_last = etx_storage_entry_get(interface_id, last->index);
if (etx_cur && etx_last && etx_cur->etx <= etx_last->etx) {
continue;
}
} }
// Secondary parent (RPL secondary parent)
if (entry->second_priority_flag && !last->second_priority_flag) {
continue;
}
// Uses this node as parent
if (entry->priority_child_flag && !last->priority_child_flag) {
continue;
}
// Better ETX
if (entry->etx <= last->etx) {
continue;
}
last = entry; last = entry;
} }
// Sets last to end of list // Sets last to end of list
if (last) { if (last) {
ns_list_remove(mle_neigh_table, last); ns_list_remove(mac_neigh_table, last);
if (first_ordered) { if (first_ordered) {
ns_list_add_before(mle_neigh_table, first_ordered, last); ns_list_add_before(mac_neigh_table, first_ordered, last);
} else { } else {
ns_list_add_to_end(mle_neigh_table, last); ns_list_add_to_end(mac_neigh_table, last);
} }
first_ordered = last; first_ordered = last;
@ -1431,10 +1386,11 @@ static int8_t arm_6lowpan_bootstrap_down(protocol_interface_info_entry_t *cur)
static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg) static void lowpan_mle_receive_security_bypass_cb(int8_t interface_id, mle_message_t *mle_msg)
{ {
(void) interface_id;
#ifdef PANA #ifdef PANA
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *interface = mle_msg->interface_ptr;
//Accept Only Link Reject //Accept Only Link Reject
if (interface && mle_msg->message_type == MLE_COMMAND_REJECT) { if (mle_msg->message_type == MLE_COMMAND_REJECT) {
if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) { if ((interface->lowpan_info & (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) != (INTERFACE_NWK_BOOTSRAP_ACTIVE | INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION)) {
return; return;
@ -1508,7 +1464,7 @@ static int8_t arm_6lowpan_bootstrap_up(protocol_interface_info_entry_t *cur)
if (!mle_service_interface_registeration_validate(cur->id)) { if (!mle_service_interface_registeration_validate(cur->id)) {
//Register //Register
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
tr_error("Mle Service init Fail"); tr_error("Mle Service init Fail");
return -1; return -1;
} }
@ -1594,7 +1550,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur)
} else { } else {
protocol_6lowpan_register_handlers(cur); protocol_6lowpan_register_handlers(cur);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
mac_helper_default_security_level_set(cur, SEC_NONE); mac_helper_default_security_level_set(cur, SEC_NONE);
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) { if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_RF_SNIFFER) {
@ -1621,15 +1576,6 @@ int8_t arm_network_processor_up(protocol_interface_info_entry_t *cur)
return ret_val; return ret_val;
} }
static bool lowpan_interface_is_active(int8_t interface_id) {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
return false;
}
return true;
}
static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params) static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *cur, const mlme_security_t *security_params)
{ {
if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) { if (cur->mac_parameters->mac_next_key_index && (security_params->KeyIndex == cur->mac_parameters->mac_next_key_index)) {
@ -1641,6 +1587,66 @@ static void arm_6lowpan_security_key_update_cb(protocol_interface_info_entry_t *
} }
} }
} }
static void lowpan_neighbor_entry_remove_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
{
protocol_interface_info_entry_t *cur_interface = user_data;
lowpan_adaptation_remove_free_indirect_table(cur_interface, entry_ptr);
// Sleepy host
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
mac_data_poll_protocol_poll_mode_decrement(cur_interface);
}
protocol_6lowpan_priority_neighbor_remove(cur_interface, entry_ptr);
if (entry_ptr->ffd_device) {
protocol_6lowpan_release_short_link_address_from_neighcache(cur_interface, entry_ptr->mac16);
protocol_6lowpan_release_long_link_address_from_neighcache(cur_interface, entry_ptr->mac64);
}
mac_helper_devicetable_remove(cur_interface->mac_api, entry_ptr->index);
//Removes ETX neighbor
etx_neighbor_remove(cur_interface->id, entry_ptr->index);
//Remove MLE frame counter info
mle_service_frame_counter_entry_delete(cur_interface->id, entry_ptr->index);
}
static bool lowpan_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
{
// Sleepy host
protocol_interface_info_entry_t *cur_interface = user_data;
if (cur_interface->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
//Trig middle way challenge if Broadcast message have been missed
if (!entry_ptr->ffd_device) {
return false; //End device must do this
}
if (entry_ptr->lifetime > (entry_ptr->link_lifetime / 2)) {
return false; //Trig only when midway is overed
}
return protocol_6lowpan_router_challenge(cur_interface, entry_ptr->mac64);
}
if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) {
return false; //Do not never challenge than priority parent
}
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
return false; //Sleepy end device should not never challenge
}
if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
return false;
}
return protocol_6lowpan_host_challenge(cur_interface, entry_ptr->mac64);
}
int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension) int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode, net_6lowpan_mode_extension_e net_6lowpan_mode_extension)
{ {
int8_t ret_val = -1; int8_t ret_val = -1;
@ -1665,20 +1671,29 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode
cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb; cur->mac_security_key_usage_update_cb = arm_6lowpan_security_key_update_cb;
//Allocate MLE class here //Allocate MLE class here
//Deallocate old here //Deallocate old here
mac_neighbor_table_delete(mac_neighbor_info(cur));
mac_description_storage_size_t buffer;
//Read MAC device table sizes
if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) {
return -1;
}
mle_class_deallocate(interface_id); mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size, lowpan_neighbor_entry_remove_notify
, lowpan_neighbor_entry_nud_notify, cur);
if (!mac_neighbor_info(cur)) {
return -1;
}
if (enable_mle_protocol) { if (enable_mle_protocol) {
if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size)) {
return -1;
}
mac_description_storage_size_t buffer; if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) {
//Read MAC device table sizes
if (cur->mac_api->mac_storage_sizes_get(cur->mac_api, &buffer) != 0) {
return -1; return -1;
} }
if (mle_class_init(interface_id, buffer.device_decription_table_size, &protocol_6lowpan_neighbor_information_remove, &protocol_6lowpan_host_challenge, &lowpan_interface_is_active) != 0) {
return -1; lowpan_adaptation_interface_etx_update_enable(cur->id);
}
mle_class_router_challenge(interface_id, protocol_6lowpan_router_challenge);
} }
mle_service_interface_unregister(cur->id); mle_service_interface_unregister(cur->id);
@ -1704,7 +1719,7 @@ int8_t arm_6lowpan_bootstarp_bootstrap_set(int8_t interface_id, net_6lowpan_mode
return -2; return -2;
#else #else
cur->comm_status_ind_cb = lowpan_comm_status_indication_cb; cur->comm_status_ind_cb = lowpan_comm_status_indication_cb;
if (mle_service_interface_register(cur->id,mle_6lowpan_message_handler, cur->mac,8) != 0) { if (mle_service_interface_register(cur->id, cur, mle_6lowpan_message_handler, cur->mac,8) != 0) {
tr_error("Mle Service init Fail"); tr_error("Mle Service init Fail");
return -1; return -1;
} }
@ -1906,7 +1921,7 @@ void protocol_6lowpan_link_advertise_handle(nd_router_t *cur, protocol_interface
cur->mle_purge_timer -= 1; cur->mle_purge_timer -= 1;
} else { } else {
if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) { if (mle_6lowpan_data && mle_6lowpan_data->nbr_of_neigh_max != 0) {
uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface->id); uint16_t mle_neigh_cnt = mle_class_active_neigh_counter(cur_interface);
if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) { if (mle_neigh_cnt > (mle_6lowpan_data->nbr_of_neigh_max - MLE_NEIGHBOR_PURGE_NBR)) {
protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true); protocol_6lowpan_mle_purge_neighbors(cur_interface, MLE_NEIGHBOR_PURGE_NBR, true);
} }
@ -1946,15 +1961,15 @@ static void protocol_6lowpan_nd_ready(protocol_interface_info_entry_t *cur)
if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) { if ((cur->lowpan_info & (INTERFACE_NWK_ROUTER_DEVICE | INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE | INTERFACE_NWK_BOOTSRAP_MLE)) == INTERFACE_NWK_BOOTSRAP_MLE) {
//TRIG Only Normal Host //TRIG Only Normal Host
#ifndef NO_MLE #ifndef NO_MLE
//GET Cordinaotor MLE Entry //GET Cordinator MLE Entry
addrtype_t addrType; addrtype_t addrType;
uint8_t tempAddr[8]; uint8_t tempAddr[8];
addrType = mac_helper_coordinator_address_get(cur, tempAddr); addrType = mac_helper_coordinator_address_get(cur, tempAddr);
mac_neighbor_table_entry_t * neig_info = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tempAddr, addrType);
mle_neigh_table_entry_t *entry_t = mle_class_get_by_link_address(cur->id, tempAddr, addrType); if (neig_info) {
if (entry_t) { if (neig_info->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
if (entry_t->ttl > MLE_TABLE_CHALLENGE_TIMER) { neig_info->lifetime = (MLE_TABLE_CHALLENGE_TIMER + 1);
entry_t->ttl = (MLE_TABLE_CHALLENGE_TIMER + 1);
} }
} }
#endif #endif
@ -2175,7 +2190,6 @@ void nwk_6lowpan_nd_address_registartion_ready(protocol_interface_info_entry_t *
if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) { if (cur->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_SLEEPY_HOST) {
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
tr_debug("Enable Poll state"); tr_debug("Enable Poll state");
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
mac_data_poll_init(cur); mac_data_poll_init(cur);
mac_data_poll_init_protocol_poll(cur); mac_data_poll_init_protocol_poll(cur);
@ -2753,12 +2767,13 @@ static void protocol_6lowpan_generate_link_reject(protocol_interface_info_entry_
static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
{ {
#ifndef NO_MLE
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
if (!cur) { if (!cur) {
return; return;
} }
mac_neighbor_table_entry_t * entry_ptr;
switch (status->status) { switch (status->status) {
case MLME_UNSUPPORTED_SECURITY: case MLME_UNSUPPORTED_SECURITY:
case MLME_UNAVAILABLE_KEY: case MLME_UNAVAILABLE_KEY:
@ -2775,29 +2790,33 @@ static void lowpan_comm_status_indication_cb(int8_t if_id, const mlme_comm_statu
break; break;
case MLME_DATA_POLL_NOTIFICATION: case MLME_DATA_POLL_NOTIFICATION:
mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false); entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), status->SrcAddr, status->SrcAddrMode);
if (entry_ptr) {
// Refresh Timeout
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_ptr, entry_ptr->link_lifetime);
}
break; break;
default: default:
break; break;
} }
#endif
} }
bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address) bool lowpan_neighbour_data_clean(int8_t interface_id, const uint8_t *link_local_address)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur) {
return false;
}
bool return_value = false; bool return_value = false;
#ifndef NO_MLE mac_neighbor_table_entry_t *neigh_entry = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), link_local_address, false, NULL);
mle_neigh_table_entry_t * neigh_entry = mle_class_get_entry_by_ll64(interface_id, 0, link_local_address, false, NULL);
if (neigh_entry) { if (neigh_entry) {
//Remove entry //Remove entry
if (neigh_entry->priorityFlag) { if (neigh_entry->link_role == PRIORITY_PARENT_NEIGHBOUR || neigh_entry->link_role == SECONDARY_PARENT_NEIGHBOUR) {
return_value = true;
} else if (neigh_entry->second_priority_flag) {
return_value = true; return_value = true;
} }
mle_class_remove_entry(interface_id, neigh_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neigh_entry);
} }
#endif
return return_value; return return_value;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -37,6 +37,7 @@
#include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h"
#include "Service_Libs/blacklist/blacklist.h" #include "Service_Libs/blacklist/blacklist.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "mac_api.h" #include "mac_api.h"
#ifdef HAVE_RPL #ifdef HAVE_RPL
@ -66,6 +67,7 @@
#include "platform/arm_hal_interrupt.h" #include "platform/arm_hal_interrupt.h"
#include "common_functions.h" #include "common_functions.h"
#include "mac_api.h" #include "mac_api.h"
#include "6LoWPAN/MAC/mpx_api.h"
#include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/lowpan_adaptation_interface.h"
#include "6LoWPAN/Fragmentation/cipv6_fragmenter.h" #include "6LoWPAN/Fragmentation/cipv6_fragmenter.h"
#include "libNET/src/net_load_balance_internal.h" #include "libNET/src/net_load_balance_internal.h"
@ -80,12 +82,14 @@ static int8_t set_6lowpan_nwk_down(protocol_interface_info_entry_t *cur)
/* Change Active -> Idle */ /* Change Active -> Idle */
/* Disable Protocols Timers */ /* Disable Protocols Timers */
if (!thread_info(cur)) { if (!thread_info(cur)) {
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) { mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
#ifndef NO_MLE #ifndef NO_MLE
mle_class_list_clean(cur->id); if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
blacklist_clear(); blacklist_clear();
#endif
} }
#endif
} }
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) { if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION) {
pana_reset_values(cur->mac_parameters->pan_id); pana_reset_values(cur->mac_parameters->pan_id);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -35,13 +35,11 @@ extern struct rpl_domain *protocol_6lowpan_rpl_domain;
extern struct rpl_dodag *protocol_6lowpan_rpl_root_dodag; extern struct rpl_dodag *protocol_6lowpan_rpl_root_dodag;
#ifdef HAVE_RPL #ifdef HAVE_RPL
#ifndef NO_MLE
typedef enum { typedef enum {
PRIORITY_1ST, PRIORITY_1ST,
PRIORITY_2ND, PRIORITY_2ND,
} neighbor_priority; } neighbor_priority;
#endif #endif
#endif
void protocol_6lowpan_interface_common_init(struct protocol_interface_info_entry *cur); void protocol_6lowpan_interface_common_init(struct protocol_interface_info_entry *cur);
void protocol_6lowpan_host_init(struct protocol_interface_info_entry *cur, bool sleepy_host); void protocol_6lowpan_host_init(struct protocol_interface_info_entry *cur, bool sleepy_host);
@ -53,12 +51,10 @@ int protocol_6lowpan_child_update(struct protocol_interface_info_entry *cur);
void protocol_6lowpan_neighbor_priority_update(struct protocol_interface_info_entry *cur, uint8_t *removed_priority, uint8_t *updated_priority); void protocol_6lowpan_neighbor_priority_update(struct protocol_interface_info_entry *cur, uint8_t *removed_priority, uint8_t *updated_priority);
#ifdef HAVE_RPL #ifdef HAVE_RPL
#ifndef NO_MLE
uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr); uint16_t protocol_6lowpan_neighbor_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr); uint16_t protocol_6lowpan_neighbor_second_priority_set(int8_t interface_id, addrtype_t addr_type, const uint8_t *addr_ptr);
void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority); void protocol_6lowpan_neighbor_priority_clear_all(int8_t interface_id, neighbor_priority priority);
#endif #endif
#endif
#else #else
#define protocol_6lowpan_child_update(cur) (-1) #define protocol_6lowpan_child_update(cur) (-1)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -27,7 +27,6 @@
struct protocol_interface_info_entry; struct protocol_interface_info_entry;
struct nd_router; struct nd_router;
struct mle_neigh_table_entry_t;
#define MLE_NEIGHBOR_PURGE_NBR 3 #define MLE_NEIGHBOR_PURGE_NBR 3
#define MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT 4 // Times advertisement timeout #define MLE_NEIGHBOR_PURGE_TIMER_TIMEOUT 4 // Times advertisement timeout

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -77,12 +77,7 @@ buffer_t *lowpan_down(buffer_t *buf)
return NULL; return NULL;
} }
if (thread_info(cur)) { if (thread_info(cur)) {
mle_neigh_table_entry_t *mle_entry; stable_only = thread_stable_context_check(cur, buf);
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type);
if (mle_entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), mle_entry->short_adr)) {
/* Check if the child can handle only stable network data (e.g. sleepy device) */
stable_only = !(mle_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET);
}
} }
} }
@ -169,7 +164,7 @@ buffer_t *lowpan_down(buffer_t *buf)
/* RFC 6282+4944 require that we limit compression to the first fragment. /* RFC 6282+4944 require that we limit compression to the first fragment.
* This check is slightly conservative - always allow 4 for first-fragment header * This check is slightly conservative - always allow 4 for first-fragment header
*/ */
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4; uint_fast16_t max_iphc_size = mac_helper_max_payload_size(cur, overhead) - mesh_size - 4;
buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only); buf = iphc_compress(&cur->lowpan_contexts, buf, max_iphc_size, stable_only);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -45,6 +45,7 @@
#endif #endif
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP "mPol" #define TRACE_GROUP "mPol"
@ -281,6 +282,23 @@ void mac_poll_timer_trig(uint32_t poll_time, protocol_interface_info_entry_t *cu
} }
} }
} }
static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, uint8_t *address, addrtype_t type)
{
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type);
if (!entry) {
return NULL;
}
if (!entry->connected_device) {
return NULL;
}
if (!entry->nud_active) {
entry->lifetime = entry->link_lifetime;
}
return entry;
}
void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm) void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll_conf_t *confirm)
{ {
@ -295,20 +313,21 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll
} }
rf_ptr->pollActive = false; rf_ptr->pollActive = false;
mac_neighbor_table_entry_t *entry = NULL;
switch (confirm->status) { switch (confirm->status) {
case MLME_SUCCESS: case MLME_SUCCESS:
//tr_debug("Poll Confirm: Data with Data"); //tr_debug("Poll Confirm: Data with Data");
rf_ptr->nwk_parent_poll_fail = 0; rf_ptr->nwk_parent_poll_fail = 0;
//Trig new Data Poll immediately //Trig new Data Poll immediately
mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true); entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode);
poll_time = 1; poll_time = 1;
break; break;
case MLME_NO_DATA: case MLME_NO_DATA:
//Start next case timer //Start next case timer
rf_ptr->nwk_parent_poll_fail = 0; rf_ptr->nwk_parent_poll_fail = 0;
mle_refresh_entry_timeout(cur->id, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode, true); entry = neighbor_data_poll_referesh(cur, rf_ptr->poll_req.CoordAddress, (addrtype_t)rf_ptr->poll_req.CoordAddrMode);
//tr_debug("Poll Confirm: No Data"); //tr_debug("Poll Confirm: No Data");
if (rf_ptr->protocol_poll == 0) { if (rf_ptr->protocol_poll == 0) {
@ -333,6 +352,9 @@ void mac_mlme_poll_confirm(protocol_interface_info_entry_t *cur, const mlme_poll
} }
break; break;
} }
if (thread_info(cur) && entry) {
thread_neighbor_communication_update(cur, entry->index);
}
mac_poll_timer_trig(poll_time, cur); mac_poll_timer_trig(poll_time, cur);
@ -423,7 +445,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne
new_poll_time = (poll_time * 1000); new_poll_time = (poll_time * 1000);
if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) { if (rf_ptr->host_mode == NET_HOST_RX_ON_IDLE) {
tr_debug("Init Poll timer and period"); tr_debug("Init Poll timer and period");
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
} }
rf_ptr->nwk_app_poll_time = new_poll_time; rf_ptr->nwk_app_poll_time = new_poll_time;
@ -449,7 +470,6 @@ int8_t mac_data_poll_host_mode_set(struct protocol_interface_info_entry *cur, ne
} }
} }
tr_debug("Enable Poll By APP"); tr_debug("Enable Poll By APP");
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
mac_poll_timer_trig(1, cur); mac_poll_timer_trig(1, cur);
rf_ptr->nwk_app_poll_time = 300; rf_ptr->nwk_app_poll_time = 300;
@ -525,14 +545,12 @@ void mac_data_poll_init(struct protocol_interface_info_entry *cur)
if (cur->mac_parameters->RxOnWhenIdle) { if (cur->mac_parameters->RxOnWhenIdle) {
tr_debug("Set Non-Sleepy HOST"); tr_debug("Set Non-Sleepy HOST");
rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE; rfd_ptr->host_mode = NET_HOST_RX_ON_IDLE;
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
} else { } else {
rfd_ptr->protocol_poll = 1; rfd_ptr->protocol_poll = 1;
mac_poll_timer_trig(200, cur); mac_poll_timer_trig(200, cur);
tr_debug("Set Sleepy HOST configure"); tr_debug("Set Sleepy HOST configure");
rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE; rfd_ptr->host_mode = NET_HOST_FAST_POLL_MODE;
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
rfd_ptr->slow_poll_rate_seconds = 3; rfd_ptr->slow_poll_rate_seconds = 3;
rfd_ptr->timeOutInSeconds = 32; rfd_ptr->timeOutInSeconds = 32;
rfd_ptr->nwk_app_poll_time = 300; rfd_ptr->nwk_app_poll_time = 300;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -25,7 +25,6 @@
#include "net_nwk_scan.h" #include "net_nwk_scan.h"
#include "ns_trace.h" #include "ns_trace.h"
#include "common_functions.h" #include "common_functions.h"
#include "MLE/mle_tlv.h"
#include "mac_api.h" #include "mac_api.h"
#define TRACE_GROUP "MACh" #define TRACE_GROUP "MACh"
@ -685,7 +684,7 @@ int8_t mac_helper_mac64_set(protocol_interface_info_entry_t *interface, const ui
* Given a buffer, with address and security flags set, compute the maximum * Given a buffer, with address and security flags set, compute the maximum
* MAC payload that could be put in that buffer. * MAC payload that could be put in that buffer.
*/ */
uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast8_t frame_overhead) uint_fast16_t mac_helper_max_payload_size(protocol_interface_info_entry_t *cur, uint_fast16_t frame_overhead)
{ {
uint16_t max; uint16_t max;
@ -833,7 +832,17 @@ void mac_helper_devicetable_remove(mac_api_t *mac_api, uint8_t attribute_index)
mac_api->mlme_req(mac_api,MLME_SET , &set_req); mac_api->mlme_req(mac_api,MLME_SET , &set_req);
} }
void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_interface_info_entry_t *cur, uint32_t frame_counter, uint8_t keyID, bool force_set) void mac_helper_device_description_write(protocol_interface_info_entry_t *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt)
{
memcpy(device_desc->ExtAddress, mac64, 8);
device_desc->ShortAddress = mac16;
device_desc->PANId = mac_helper_panid_get(cur);
device_desc->Exempt = exempt;
device_desc->FrameCounter = frame_counter;
}
void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_desc, protocol_interface_info_entry_t *cur, uint8_t attribute_index, uint8_t keyID, bool force_set)
{ {
if (!cur->mac_api) { if (!cur->mac_api) {
return; return;
@ -844,18 +853,10 @@ void mac_helper_devicetable_set(mle_neigh_table_entry_t *entry_temp, protocol_in
return; return;
} }
mlme_device_descriptor_t device_desc;
mlme_set_t set_req; mlme_set_t set_req;
device_desc.FrameCounter = frame_counter;
device_desc.Exempt = false;
device_desc.ShortAddress = entry_temp->short_adr;
memcpy(device_desc.ExtAddress, entry_temp->mac64, 8);
device_desc.PANId = mac_helper_panid_get(cur);
set_req.attr = macDeviceTable; set_req.attr = macDeviceTable;
set_req.attr_index = entry_temp->attribute_index; set_req.attr_index = attribute_index;
set_req.value_pointer = (void*)&device_desc; set_req.value_pointer = (void*)device_desc;
set_req.value_size = sizeof(mlme_device_descriptor_t); set_req.value_size = sizeof(mlme_device_descriptor_t);
tr_debug("Register Device"); tr_debug("Register Device");
cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req); cur->mac_api->mlme_req(cur->mac_api,MLME_SET , &set_req);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -29,7 +29,6 @@ struct protocol_interface_info_entry;
struct ns_sockaddr; struct ns_sockaddr;
struct buffer; struct buffer;
struct mac_api_s; struct mac_api_s;
struct mle_neigh_table_entry_t;
void mac_create_scan_request(mac_scan_type_t type, struct channel_list_s *chanlist, uint8_t scan_duration, struct mlme_scan_s *request); void mac_create_scan_request(mac_scan_type_t type, struct channel_list_s *chanlist, uint8_t scan_duration, struct mlme_scan_s *request);
@ -100,7 +99,7 @@ bool mac_helper_write_our_addr(struct protocol_interface_info_entry *interface,
int8_t mac_helper_mac64_set(struct protocol_interface_info_entry *interface, const uint8_t *mac64); int8_t mac_helper_mac64_set(struct protocol_interface_info_entry *interface, const uint8_t *mac64);
uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast8_t frame_overhead); uint_fast16_t mac_helper_max_payload_size(struct protocol_interface_info_entry *cur, uint_fast16_t frame_overhead);
uint_fast8_t mac_helper_frame_overhead(struct protocol_interface_info_entry *cur, const struct buffer *buf); uint_fast8_t mac_helper_frame_overhead(struct protocol_interface_info_entry *cur, const struct buffer *buf);
@ -110,8 +109,9 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr);
void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index); void mac_helper_devicetable_remove(struct mac_api_s *mac_api, uint8_t attribute_index);
void mac_helper_devicetable_set(struct mle_neigh_table_entry_t *entry_temp, struct protocol_interface_info_entry *cur, uint32_t frame_counter, uint8_t keyID, bool force_set); void mac_helper_device_description_write(struct protocol_interface_info_entry *cur, mlme_device_descriptor_t *device_desc, uint8_t *mac64, uint16_t mac16, uint32_t frame_counter, bool exempt);
void mac_helper_devicetable_set(const mlme_device_descriptor_t *device_dec, struct protocol_interface_info_entry *cur, uint8_t attribute_index, uint8_t keyID, bool force_set);
int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set); int8_t mac_helper_mac_mlme_max_retry_set(int8_t interface_id, uint8_t mac_retry_set);
#endif // MAC_HELPER_H #endif // MAC_HELPER_H

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nsconfig.h"
#include "ns_types.h"
#include "string.h"
#include "common_functions.h"
#include "mac_common_defines.h"
#include "mac_ie_lib.h"
#define MAC_IE_HEADER_LENGTH_MASK 0x007f
#define MAC_IE_HEADER_ID_MASK 0x7f80
#define MAC_IE_PAYLOAD_LENGTH_MASK 0x07ff
#define MAC_IE_PAYLOAD_ID_MASK 0x7800
#define MAC_IE_TYPE_PAYLOAD_MASK 0x8000
#define MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK 0x07ff
#define MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK 0x7800
#define MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK 0x00ff
#define MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK 0x7f00
#define MAC_NESTED_IE_TYPE_LONG_MASK 0x8000
static void mac_ie_header_parse(mac_header_IE_t *header_element, uint8_t *ptr)
{
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
header_element->length = (ie_dummy & MAC_IE_HEADER_LENGTH_MASK);
header_element->id = ((ie_dummy & MAC_IE_HEADER_ID_MASK ) >> 7 );
header_element->content_ptr = ptr + 2;
}
static void mac_ie_payload_parse(mac_payload_IE_t *payload_element, uint8_t *ptr)
{
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
payload_element->length = (ie_dummy & MAC_IE_PAYLOAD_LENGTH_MASK);
payload_element->id = ((ie_dummy & MAC_IE_PAYLOAD_ID_MASK ) >> 11);
payload_element->content_ptr = ptr + 2;
}
static void mac_ie_nested_id_parse(mac_nested_payload_IE_t *element, uint8_t *ptr)
{
uint16_t ie_dummy = common_read_16_bit_inverse(ptr);
if (ie_dummy & MAC_NESTED_IE_TYPE_LONG_MASK) {
element->type_long = true;
element->length = (ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK);
element->id = ((ie_dummy & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK ) >> 11);
} else {
element->type_long = false;
element->length = (ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK);
element->id = ((ie_dummy & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK ) >> 8);
}
element->content_ptr = ptr + 2;
}
uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length)
{
uint16_t ie_dummy = 0; //Header Type
ie_dummy |= (length & MAC_IE_HEADER_LENGTH_MASK);
ie_dummy |= ((type << 7 ) & MAC_IE_HEADER_ID_MASK);
return common_write_16_bit_inverse(ie_dummy, ptr);
}
uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length)
{
uint16_t ie_dummy = MAC_IE_TYPE_PAYLOAD_MASK; //Payload type
ie_dummy |= (length & MAC_IE_PAYLOAD_LENGTH_MASK);
ie_dummy |= ((type << 11 ) & MAC_IE_PAYLOAD_ID_MASK);
return common_write_16_bit_inverse(ie_dummy, ptr);
}
uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length)
{
uint16_t ie_dummy = MAC_NESTED_IE_TYPE_LONG_MASK;
ie_dummy |= (length & MAC_NESTED_LONG_IE_PAYLOAD_LENGTH_MASK);
ie_dummy |= ((sub_id << 11 ) & MAC_NESTED_LONG_IE_PAYLOAD_ID_MASK);
return common_write_16_bit_inverse(ie_dummy, ptr);
}
uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length)
{
uint16_t ie_dummy = 0;
ie_dummy |= (length & MAC_NESTED_SHORT_IE_PAYLOAD_LENGTH_MASK);
ie_dummy |= ((sub_id << 8 ) & MAC_NESTED_SHORT_IE_PAYLOAD_ID_MASK);
return common_write_16_bit_inverse(ie_dummy, ptr);
}
uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, mac_payload_IE_t * payload_ie)
{
mac_payload_IE_t ie_element;
while (length >= 2) {
mac_ie_payload_parse(&ie_element, payload_ptr);
if (payload_ie->id == ie_element.id) {
payload_ie->content_ptr = ie_element.content_ptr;
payload_ie->length = ie_element.length;
return ie_element.length;
}
length -= ie_element.length + 2;
payload_ptr += ie_element.length + 2;
}
return 0;
}
uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie)
{
mac_nested_payload_IE_t ie_element;
while (length >= 2) {
mac_ie_nested_id_parse(&ie_element, payload_ptr);
if (length < ie_element.length + 2) {
return 0;
}
if (nested_ie->id == ie_element.id && nested_ie->type_long == ie_element.type_long) {
nested_ie->content_ptr = ie_element.content_ptr;
nested_ie->length = ie_element.length;
return ie_element.length;
}
length -= ie_element.length + 2;
payload_ptr += ie_element.length + 2;
}
return 0;
}
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie)
{
mac_header_IE_t ie_element;
while (length >= 2) {
mac_ie_header_parse(&ie_element, header_ptr);
if (header_ie->id == ie_element.id) {
header_ie->content_ptr = ie_element.content_ptr;
header_ie->length = ie_element.length;
return ie_element.length;
}
length -= ie_element.length + 2;
header_ptr += ie_element.length + 2;
}
return 0;
}
uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id)
{
mac_header_IE_t ie_element;
uint8_t *sub_id_ptr;
while (length > 2) {
mac_ie_header_parse(&ie_element, header_ptr);
sub_id_ptr = ie_element.content_ptr;
if (ie_element.length && header_ie->id == ie_element.id && *sub_id_ptr == sub_id) {
sub_id_ptr++;
ie_element.length--;
header_ie->content_ptr = sub_id_ptr;
header_ie->length = ie_element.length;
return ie_element.length;
}
length -= ie_element.length + 2;
header_ptr += ie_element.length + 2;
}
return 0;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MAC_IE_LIB_H_
#define MAC_IE_LIB_H_
struct mac_payload_IE_s;
struct mac_payload_IE_s;
/**
* @brief struct mac_nested_payload_IE_t Mac Nested IE Payload information element structure for parsing or write operation
*/
typedef struct mac_nested_payload_IE_s {
uint8_t *content_ptr; /**< Content data */
uint16_t length; /**< Element length 0- 2047 when type_long true and for short 0- 255*/
unsigned id:7; /**< Group ID 4-bit for long and 7 bit for short type */
bool type_long:1; /**< True when Nested IE long format and false for short */
} mac_nested_payload_IE_t;
/** IE header element generic header write */
uint8_t *mac_ie_header_base_write(uint8_t *ptr, uint8_t type, uint16_t length);
/** IE payload element generic header write */
uint8_t *mac_ie_payload_base_write(uint8_t *ptr, uint8_t type, uint16_t length);
/** Nested IE long header write */
uint8_t *mac_ie_nested_ie_long_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length);
/** Nested IE short header write */
uint8_t *mac_ie_nested_ie_short_base_write(uint8_t *ptr, uint8_t sub_id, uint16_t length);
/** Payload IE discover for spesific group ID */
uint16_t mac_ie_payload_discover(uint8_t *payload_ptr, uint16_t length, struct mac_payload_IE_s * payload_ie);
/** Nested IE element discover inside parsed payload element */
uint16_t mac_ie_nested_discover(uint8_t *payload_ptr, uint16_t length, mac_nested_payload_IE_t * nested_ie);
/** Header IE elemnt discover */
uint8_t mac_ie_header_discover(uint8_t *header_ptr, uint16_t length, struct mac_header_IE_s * header_ie);
/** Header IE elemnt discover with sub id */
uint8_t mac_ie_header_sub_id_discover(uint8_t *header_ptr, uint16_t length, mac_header_IE_t * header_ie, uint8_t sub_id);
#endif /* MAC_IE_LIB_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -29,6 +29,7 @@
#include "6LoWPAN/MAC/mac_pairwise_key.h" #include "6LoWPAN/MAC/mac_pairwise_key.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "NWK_INTERFACE/Include/protocol.h" #include "NWK_INTERFACE/Include/protocol.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP "mPKe" #define TRACE_GROUP "mPKe"
@ -171,12 +172,12 @@ static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_l
static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) { static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) {
//Delete mle entries & Keys //Delete mle entries & Keys
mle_neigh_table_entry_t *cur_entry; mac_neighbor_table_entry_t *cur_entry;
mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table;
for (uint8_t i = 0; i< main_list->key_table_size; i++) { for (uint8_t i = 0; i< main_list->key_table_size; i++) {
cur_entry = mle_class_get_by_device_attribute_id(interface->id, cur->device_descriptor_attribute); cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute);
if (cur_entry) { if (cur_entry) {
mle_class_remove_entry(interface->id, cur_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry);
} }
mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute); mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute);
} }
@ -266,30 +267,31 @@ int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const ui
} }
//Allocate mle entry //Allocate mle entry
mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, &new_entry_created); mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created);
if (!mle_entry) { if (!mac_entry) {
return -1; return -1;
} }
mle_entry->thread_commission = true;
mle_entry->short_adr = 0xffff; mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true);
mle_entry->ttl = 20; mac_entry->mac16 = 0xffff;
//Allocate key description //Allocate key description
mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mle_entry->attribute_index); mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index);
if (!key_desc) { if (!key_desc) {
mle_class_remove_entry(interface_id, mle_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
return -1; return -1;
} }
//Set device descriptor mlme_device_descriptor_t device_desc;
mac_helper_devicetable_set(mle_entry, interface, 0, interface->mac_parameters->mac_default_key_index, new_entry_created); mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false);
mac_helper_devicetable_set(&device_desc, interface,mac_entry->index, interface->mac_parameters->mac_default_key_index, new_entry_created);
//set key descriptor //set key descriptor
if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) { if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) {
main_list->key_table_size--; main_list->key_table_size--;
mle_class_remove_entry(interface_id, mle_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
return -1; return -1;
} }
@ -309,23 +311,23 @@ int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8])
if (!main_list) { if (!main_list) {
return -1; return -1;
} }
//Get from mle //Get from mac
mle_neigh_table_entry_t *mle_entry = mle_class_get_entry_by_mac64(interface_id, 0, eui64, true, NULL); mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL);
if (!mle_entry) { if (!mac_entry) {
return -1; return -1;
} }
//discover by mle entry attribute //discover by mle entry attribute
uint8_t key_attribute; uint8_t key_attribute;
if (!mac_pairwise_key_info_delete(main_list, mle_entry->attribute_index, &key_attribute)) { if (!mac_pairwise_key_info_delete(main_list, mac_entry->index, &key_attribute)) {
return -1; return -1;
} }
//kill Entry & overwrite key //kill Entry & overwrite key
mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute); mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute);
mle_class_remove_entry(interface_id, mle_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -31,9 +31,9 @@
#include "mac_mcps.h" #include "mac_mcps.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "6LoWPAN/MAC/mac_response_handler.h" #include "6LoWPAN/MAC/mac_response_handler.h"
#include "6LoWPAN/MAC/mpx_api.h"
#include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/lowpan_adaptation_interface.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
static bool mac_data_is_broadcast_addr(const sockaddr_t *addr);
#define TRACE_GROUP "MRsH" #define TRACE_GROUP "MRsH"
@ -49,15 +49,16 @@ static void mac_mlme_device_table_confirmation_handle(protocol_interface_info_en
if (confirmation->status == MLME_SUCCESS) { if (confirmation->status == MLME_SUCCESS) {
//GET ME table by extended mac64 address //GET ME table by extended mac64 address
mle_neigh_table_entry_t * entry = mle_class_get_by_link_address(info_entry->id, descpription->ExtAddress, ADDR_802_15_4_LONG); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(info_entry), descpription->ExtAddress, ADDR_802_15_4_LONG);
if (!entry) { if (!entry) {
return; return;
} }
if (entry->short_adr != descpription->ShortAddress) { if (entry->mac16 != descpription->ShortAddress) {
//Refresh Short ADDRESS //Refresh Short ADDRESS
mlme_set_t set_request; mlme_set_t set_request;
descpription->ShortAddress = entry->short_adr; descpription->ShortAddress = entry->mac16;
//CALL MLME-SET //CALL MLME-SET
set_request.attr = macDeviceTable; set_request.attr = macDeviceTable;
@ -107,62 +108,10 @@ void mcps_data_confirm_handler( const mac_api_t* api, const mcps_data_conf_t *da
lowpan_adaptation_interface_tx_confirm(info_entry, data); lowpan_adaptation_interface_tx_confirm(info_entry, data);
} }
static bool mcps_data_indication_neighbor_validate(int8_t interface_id, const sockaddr_t *addr)
{
/* If MLE is enabled, we will talk if we have an MLE association */
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(interface_id, addr->address + 2, addr->addr_type);
if (mle_entry && (mle_entry->handshakeReady || mle_entry->thread_commission)) {
return true;
}
/* Otherwise, we don't know them */
return false;
}
void mcps_data_indication_handler( const mac_api_t* api, const mcps_data_ind_t *data_ind ) void mcps_data_indication_handler( const mac_api_t* api, const mcps_data_ind_t *data_ind )
{ {
protocol_interface_info_entry_t *info_entry = protocol_stack_interface_info_get_by_id(api->parent_id); protocol_interface_info_entry_t *info_entry = protocol_stack_interface_info_get_by_id(api->parent_id);
buffer_t *buf = buffer_get(data_ind->msduLength); lowpan_adaptation_interface_data_ind(info_entry, data_ind);
if (!buf || !info_entry) {
return;
}
uint8_t *ptr;
buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength);
//tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8));
buf->options.lqi = data_ind->mpduLinkQuality;
buf->options.dbm = data_ind->signal_dbm;
buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode;
ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address);
memcpy(ptr, data_ind->SrcAddr, 8);
buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode;
ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address);
memcpy(ptr, data_ind->DstAddr, 8);
//Set Link spesific stuff to seperately
buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId;
buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId;
if (mac_data_is_broadcast_addr(&buf->dst_sa)) {
buf->options.ll_broadcast_rx = true;
}
buf->interface = info_entry;
if (data_ind->Key.SecurityLevel) {
buf->link_specific.ieee802_15_4.fc_security = true;
if (info_entry->mac_security_key_usage_update_cb) {
info_entry->mac_security_key_usage_update_cb(info_entry, &data_ind->Key);
}
} else {
buf->link_specific.ieee802_15_4.fc_security = false;
if (mac_helper_default_security_level_get(info_entry) ||
!mcps_data_indication_neighbor_validate(info_entry->id, &buf->src_sa)) {
//SET By Pass
buf->options.ll_security_bypass_rx = true;
}
}
buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP);
protocol_push(buf);
} }
void mcps_purge_confirm_handler( const mac_api_t* api, mcps_purge_conf_t *data ) void mcps_purge_confirm_handler( const mac_api_t* api, mcps_purge_conf_t *data )
@ -306,9 +255,3 @@ void mlme_indication_handler( const mac_api_t* api, mlme_primitive id, const voi
} }
} }
bool mac_data_is_broadcast_addr(const sockaddr_t *addr)
{
return (addr->addr_type == ADDR_802_15_4_SHORT) &&
(addr->address[2] == 0xFF && addr->address[3] == 0xFF);
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MPX_API_H_
#define MPX_API_H_
struct mcps_data_req_s;
struct mcps_data_conf_s;
struct mcps_data_ind_s;
struct mcps_purge_s;
typedef struct mpx_api_s mpx_api_t;
/**
* @brief mpx_data_request MPX_DATA request with user ID
* @param api API to handle the request
* @param data MCPS-DATA.request specific values
* @param user_id MPX user ID
*
*/
typedef void mpx_data_request(const mpx_api_t *api, const struct mcps_data_req_s *data, uint16_t user_id);
/**
* @brief mpx_data_queue_clean clean MPX user data
* @param api API to handle the request
* @param purge MCPS-purge request
* @param user_id MPX user ID
*
*/
typedef void mpx_data_purge_request(const mpx_api_t *api, struct mcps_purge_s *purge, uint16_t user_id);
/**
* @brief mpx_data_confirm MPX-DATA confirm is called as a response to MPX-DATA request
* @param api The API which handled the response
* @param data MCPS-DATA.confirm specific values
* @param user_id MPX user ID
*/
typedef void mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data);
/**
* @brief mpx_data_indication MPX-DATA confirm is called as a response to MPX-DATA request
* @param api The API which handled the response
* @param data MCPS-DATA.indication specific values
* @param user_id MPX user ID
*/
typedef void mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data);
/**
* @brief mpx_header_size_get Function for request MPX user head room size
* @param api The API which handled the response
* @param user_id MPX user ID
*
* @return >0 Head room size in bytes
* @return 0 When Unknown User Id
*/
typedef uint16_t mpx_header_size_get(const mpx_api_t * api, uint16_t user_id);
/**
* @brief mpx_data_cb_register MPX-DATA confirm cb register by user
* @param api The API which handled the response
* @param confirm_cb MPX Data Confirm call back
* @param indication_cb MPX Data indication
* @param user_id MPX user ID
*
* @return 0 register OK
* @return -1 Unknown User ID
*/
typedef int8_t mpx_data_cb_register(const mpx_api_t* api, mpx_data_confirm *confirm_cb, mpx_data_indication *indication_cb, uint16_t user_id);
/**
* \brief Struct mpx_api_s defines functions for MPX user for register call backs and send data.
*/
struct mpx_api_s {
mpx_data_request * mpx_data_request; /**< MPX data request. */
mpx_data_purge_request *mpx_data_purge; /**< MPX data Purge. */
mpx_header_size_get * mpx_headroom_size_get; /**< MPX headroom size get in bytes. */
mpx_data_cb_register * mpx_user_registration; /**< MPX User cb registration must be call before enable to send or RX data*/
};
#endif /* MPX_API_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -41,6 +41,8 @@
#include "BorderRouter/border_router.h" #include "BorderRouter/border_router.h"
#include "Service_Libs/pan_blacklist/pan_blacklist_api.h" #include "Service_Libs/pan_blacklist/pan_blacklist_api.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "6LoWPAN/ws/ws_common.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP "loND" #define TRACE_GROUP "loND"
@ -845,17 +847,18 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
/* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */ /* Register with 2 seconds off the lifetime - don't want the NCE to expire before the route */
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0); ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, neigh->lifetime - 2, 0);
#ifndef NO_MLE
/* We need to know peer is a host before publishing - this needs MLE. Not yet established /* We need to know peer is a host before publishing - this needs MLE. Not yet established
* what to do without MLE - might need special external/non-external prioritisation at root. * what to do without MLE - might need special external/non-external prioritisation at root.
* This "publish for RFD" rule comes from ZigBee IP. * This "publish for RFD" rule comes from ZigBee IP.
*/ */
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur_interface->id, ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur_interface), ipv6_neighbour_eui64(&cur_interface->ipv6_neighbour_cache, neigh), ADDR_802_15_4_LONG);
if (mle_entry && ((mle_entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV)) {
if (entry && !entry->ffd_device) {
rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime); rpl_control_publish_host_address(protocol_6lowpan_rpl_domain, neigh->ip_address, neigh->lifetime);
} }
protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8); protocol_6lowpan_neighbor_address_state_synch(cur_interface, aro->eui64, neigh->ip_address + 8);
#endif
} else { } else {
/* Um, no - can't transmit response if we remove NCE now! */ /* Um, no - can't transmit response if we remove NCE now! */
//ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache, neigh); //ipv6_neighbour_entry_remove(&cur_interface->ipv6_neighbour_cache, neigh);
@ -863,9 +866,7 @@ static void nd_update_registration(protocol_interface_info_entry_t *cur_interfac
neigh->lifetime = 2; neigh->lifetime = 2;
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0); ipv6_route_add(neigh->ip_address, 128, cur_interface->id, NULL, ROUTE_ARO, 4, 0);
#ifndef NO_MLE
rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address); rpl_control_unpublish_address(protocol_6lowpan_rpl_domain, neigh->ip_address);
#endif
} }
} }
@ -967,7 +968,13 @@ bool nd_ns_aro_handler(protocol_interface_info_entry_t *cur_interface, const uin
/* Set the LL address, ensure it's marked STALE */ /* Set the LL address, ensure it's marked STALE */
ipv6_neighbour_entry_update_unsolicited(&cur_interface->ipv6_neighbour_cache, neigh, ll_addr.addr_type, ll_addr.address); ipv6_neighbour_entry_update_unsolicited(&cur_interface->ipv6_neighbour_cache, neigh, ll_addr.addr_type, ll_addr.address);
ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); ipv6_neighbour_set_state(&cur_interface->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
if (ws_info(cur_interface)) {
aro_out->status = ARO_SUCCESS;
aro_out->present = true;
// Todo: this might not be needed...
nd_update_registration(cur_interface, neigh, aro_out);
return true;
}
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || nd_params.multihop_dad == false) { if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER || nd_params.multihop_dad == false) {
if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) { if (cur_interface->bootsrap_mode == ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER) {
whiteboard_entry_t *wb; whiteboard_entry_t *wb;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -30,10 +30,23 @@
#ifndef THREAD_ADDRESS_REGISTRATION_CLIENT_H_ #ifndef THREAD_ADDRESS_REGISTRATION_CLIENT_H_
#define THREAD_ADDRESS_REGISTRATION_CLIENT_H_ #define THREAD_ADDRESS_REGISTRATION_CLIENT_H_
#ifdef HAVE_THREAD_V2
void thread_address_registration_init(void);
void thread_address_registration_deinit(void);
void thread_address_registration_timer_set(protocol_interface_info_entry_t *interface, uint16_t dua_delay_seconds, uint16_t mlr_refresh_seconds);
void thread_address_registration_timer(protocol_interface_info_entry_t *interface, uint16_t seconds);
#else
#define thread_address_registration_init(void) #define thread_address_registration_init(void)
#define thread_address_registration_deinit(void) #define thread_address_registration_deinit(void)
#define thread_address_registration_timer_set(interface, seconds); #define thread_address_registration_timer_set(interface, dua_delay_seconds, mlr_refresh_seconds);
#define thread_address_registration_timer(interface, seconds); #define thread_address_registration_timer(interface, seconds);
#endif
#endif /* THREAD_ADDRESS_REGISTRATION_CLIENT_H_ */ #endif /* THREAD_ADDRESS_REGISTRATION_CLIENT_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -943,7 +943,7 @@ void thread_bbr_seconds_timer(int8_t interface_id, uint32_t seconds)
#endif // HAVE_THREAD_ROUTER #endif // HAVE_THREAD_ROUTER
#ifdef HAVE_THREAD_BORDER_ROUTER #ifdef HAVE_THREAD_BORDER_ROUTER
static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]) int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16])
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur) { if (!cur) {
@ -955,18 +955,18 @@ static int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 1
return 0; return 0;
} }
int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr) {
(void) mleid_ptr; int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info)
{
thread_bbr_t *this = thread_bbr_find_by_interface(interface_id); thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
if (!this || this->backbone_interface_id < 0) { if (!this || this->backbone_interface_id < 0) {
tr_err("bbr not ready");
return -1; return -1;
} }
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0); ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_HOST, info, 0, lifetime, 0);
// We are using route info field to store sequence number // We are using route info field to store sequence number
if (!route) { if (!route) {
// Direct route to host allows ND proxying to work // Direct route to host allows ND proxying to work
tr_err("out of resources"); tr_err("bbr out of resources");
return -2; return -2;
} }
// send NA // send NA
@ -975,14 +975,44 @@ int thread_bbr_nd_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr,
return 0; return 0;
} }
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) { int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr)
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL); {
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_HOST ) { thread_bbr_t *this = thread_bbr_find_by_interface(interface_id);
//Not found if (!this || this->backbone_interface_id < 0) {
return -1; return -1;
} }
//TODO get information to route to parameters eq mleid, timeout thread_pbbr_dua_info_t *map = ns_dyn_mem_alloc(sizeof(thread_pbbr_dua_info_t));
if (!map) {
goto error;
}
memcpy(map->mleid_ptr, mleid_ptr, 8);
map->last_contact_time = protocol_core_monotonic_time;
// We are using route info field to store BBR MLEID map
ipv6_route_t *route = ipv6_route_add_with_info(addr_data_ptr, 128, interface_id, NULL, ROUTE_THREAD_PROXIED_DUA_HOST, map, 0, lifetime, 0);
if (!route) {
// Direct route to host allows ND proxying to work
ns_dyn_mem_free(map);
goto error;
}
// Route info autofreed
route->info_autofree = true;
// send NA
thread_bbr_na_send(this->backbone_interface_id, addr_data_ptr);
return 0; return 0;
error:
tr_err("out of resources");
return -2;
}
struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr) {
ipv6_route_t *route = ipv6_route_choose_next_hop(addr_data_ptr, interface_id, NULL);
if (!route || route->prefix_len < 128 || !route->on_link || route->info.source != ROUTE_THREAD_PROXIED_DUA_HOST ) {
//Not found
return NULL;
}
return route;
} }
int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status) int thread_bbr_proxy_state_update(int8_t caller_interface_id , int8_t handler_interface_id, bool status)
@ -1090,6 +1120,17 @@ return 0;
#endif // HAVE_THREAD_BORDER_ROUTER #endif // HAVE_THREAD_BORDER_ROUTER
} }
int thread_bbr_prefix_set(int8_t interface_id, uint8_t *prefix)
{
(void) interface_id;
(void) prefix;
#ifdef HAVE_THREAD_BORDER_ROUTER
return thread_extension_bbr_prefix_set(interface_id, prefix);
#else
return -1;
#endif // HAVE_THREAD_BORDER_ROUTER
}
int thread_bbr_validation_interface_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port) int thread_bbr_validation_interface_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port)
{ {
(void) interface_id; (void) interface_id;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,6 +36,8 @@
#include "net_interface.h" #include "net_interface.h"
#ifdef HAVE_THREAD_ROUTER #ifdef HAVE_THREAD_ROUTER
struct ipv6_route;
/** /**
* \brief Initialize Thread Commissioner relay for BBR and Routers * \brief Initialize Thread Commissioner relay for BBR and Routers
* *
@ -98,23 +100,39 @@ void thread_bbr_network_data_update_notify(protocol_interface_info_entry_t *cur)
/** /**
* \brief Add new nd entry to bbr * \brief Add new nd entry to bbr
* *
* \param interface_id addr_data_ptr lifetime info mleid_ptr * \param interface_id addr_data_ptr lifetime info
*/ */
int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info, const uint8_t *mleid_ptr); int thread_bbr_nd_entry_add(int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, void *info);
/** /**
* \brief Find if bbr has nd entry * \brief Add new dua entry to bbr
*
* \param interface_id addr_data_ptr lifetime info mleid_ptr
*/
int thread_bbr_dua_entry_add (int8_t interface_id, const uint8_t *addr_data_ptr, uint32_t lifetime, const uint8_t *mleid_ptr);
/**
* \brief Send na
*
* \param interface_id addr_data_ptr lifetime info mleid_ptr
*/
int thread_bbr_na_send(int8_t interface_id, const uint8_t target[static 16]);
/**
* \brief Find if bbr has dua entry
* *
* \param interface_id addr_data_ptr * \param interface_id addr_data_ptr
*/ */
int thread_bbr_nd_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr); struct ipv6_route *thread_bbr_dua_entry_find(int8_t interface_id, const uint8_t *addr_data_ptr);
#else #else
#define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL) #define thread_bbr_proxy_state_update(caller_interface_id , handler_interface_id, status) (NULL)
#define thread_bbr_routing_enabled(cur) false #define thread_bbr_routing_enabled(cur) false
#define thread_bbr_network_data_update_notify(cur) #define thread_bbr_network_data_update_notify(cur)
#define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info, mleid_ptr) (0) #define thread_bbr_nd_entry_add(interface_id, addr_data_ptr, lifetime, info) (0)
#define thread_bbr_nd_entry_find(interface_id, addr_data_ptr) (0) #define thread_bbr_dua_entry_add(interface_id, addr_data_ptr, lifetime, mleid_ptr) (0)
#define thread_bbr_dua_entry_find(interface_id, addr_data_ptr) (NULL)
#define thread_bbr_na_send(interface_id, target) (0)
#endif //HAVE_THREAD_BORDER_ROUTER #endif //HAVE_THREAD_BORDER_ROUTER

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -59,6 +59,7 @@
#include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h"
#include "6LoWPAN/Thread/thread_management_internal.h" #include "6LoWPAN/Thread/thread_management_internal.h"
#include "6LoWPAN/Thread/thread_management_server.h" #include "6LoWPAN/Thread/thread_management_server.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "6LoWPAN/Thread/thread_network_data_lib.h" #include "6LoWPAN/Thread/thread_network_data_lib.h"
#include "6LoWPAN/Thread/thread_network_synch.h" #include "6LoWPAN/Thread/thread_network_synch.h"
#include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_joiner_application.h"
@ -90,9 +91,14 @@
#include "thread_meshcop_lib.h" #include "thread_meshcop_lib.h"
#include "multicast_api.h" #include "multicast_api.h"
#include "mlme.h" #include "mlme.h"
#include "Service_Libs/etx/etx.h"
#include "Service_Libs/nd_proxy/nd_proxy.h" #include "Service_Libs/nd_proxy/nd_proxy.h"
#include "Service_Libs/blacklist/blacklist.h" #include "Service_Libs/blacklist/blacklist.h"
#include "Service_Libs/mle_service/mle_service_api.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "6LoWPAN/lowpan_adaptation_interface.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "platform/topo_trace.h"
#define TRACE_GROUP "thbs" #define TRACE_GROUP "thbs"
@ -111,27 +117,46 @@ static void thread_bootstrap_generate_leader_and_link(protocol_interface_info_en
static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_state_type_e state); static int thread_bootstrap_attach_start(int8_t interface_id, thread_bootsrap_state_type_e state);
static void thread_bootsrap_network_discovery_failure(int8_t interface_id); static void thread_bootsrap_network_discovery_failure(int8_t interface_id);
static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur); static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data);
static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info); static void thread_bootsrap_network_join_start(struct protocol_interface_info_entry *cur_interface, discovery_response_list_t *nwk_info);
static bool thread_interface_is_active(int8_t interface_id) { static void thread_neighbor_remove(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); {
if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { protocol_interface_info_entry_t *cur = user_data;
lowpan_adaptation_remove_free_indirect_table(cur, entry_ptr);
thread_reset_neighbour_info(cur, entry_ptr);
//Removes ETX neighbor
etx_neighbor_remove(cur->id, entry_ptr->index);
//Remove MLE frame counter info
mle_service_frame_counter_entry_delete(cur->id, entry_ptr->index);
}
static bool thread_neighbor_entry_nud_notify(mac_neighbor_table_entry_t *entry_ptr, void *user_data)
{
// Sleepy host
protocol_interface_info_entry_t *cur_interface = user_data;
if (thread_am_router(cur_interface)) {
return false; //Never do Keep alive with any one
}
if (entry_ptr->link_role != PRIORITY_PARENT_NEIGHBOUR) {
return false; //Do not never challenge than priority parent
}
if (cur_interface->lowpan_info & INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE) {
return false; //Sleepy end device should not never challenge
}
if (entry_ptr->lifetime > MLE_TABLE_CHALLENGE_TIMER) {
return false; return false;
} }
return true; return thread_host_bootstrap_child_update(cur_interface, entry_ptr->mac64);
}
static void thread_neighbor_remove(int8_t interface_id, mle_neigh_table_entry_t *cur)
{
protocol_interface_info_entry_t *cur_interface = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur_interface) {
return;
}
thread_reset_neighbour_info(cur_interface, cur);
} }
int8_t thread_mle_class_init(int8_t interface_id) int8_t thread_mle_class_init(int8_t interface_id)
@ -151,11 +176,29 @@ int8_t thread_mle_class_init(int8_t interface_id)
return -1; return -1;
} }
if (mle_class_init(interface_id, buffer.device_decription_table_size - 1, &thread_neighbor_remove, &thread_host_bootstrap_child_update, &thread_interface_is_active) != 0) { thread_neighbor_class_delete(&cur->thread_info->neighbor_class);
if (!thread_neighbor_class_create(&cur->thread_info->neighbor_class, buffer.device_decription_table_size - 1)) {
return -1; return -1;
} }
mle_class_router_challenge(interface_id, NULL); if (!mac_neighbor_info(cur) ) {
mac_neighbor_info(cur) = mac_neighbor_table_create(buffer.device_decription_table_size - 1, thread_neighbor_remove
, thread_neighbor_entry_nud_notify, cur);
if (!mac_neighbor_info(cur)) {
return -1;
}
}
if (mle_service_frame_counter_table_allocate(interface_id, buffer.device_decription_table_size - 1)) {
return -1;
}
if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size - 1)) {
return -1;
}
lowpan_adaptation_interface_etx_update_enable(cur->id);
//Defined well know neighbour for discovery //Defined well know neighbour for discovery
@ -232,7 +275,7 @@ uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParen
return newLqi; return newLqi;
} }
bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp) bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_temp)
{ {
if (entry_temp && thread_info(cur)->thread_endnode_parent) { if (entry_temp && thread_info(cur)->thread_endnode_parent) {
if(memcmp(entry_temp->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) == 0) { if(memcmp(entry_temp->mac64, thread_info(cur)->thread_endnode_parent->mac64, 8) == 0) {
@ -245,45 +288,31 @@ bool thread_check_is_this_my_parent(protocol_interface_info_entry_t *cur, mle_ne
bool thread_bootstrap_request_network_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, uint16_t short_address) bool thread_bootstrap_request_network_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, uint16_t short_address)
{ {
bool requestNetworkdata = false; bool requestNetworkdata = false;
thread_leader_data_t *leadeInfo = thread_info(cur)->thread_leader_data; thread_leader_data_t *leaderInfo = thread_info(cur)->thread_leader_data;
if (thread_info(cur)->thread_endnode_parent->shortAddress != short_address) { if (thread_info(cur)->thread_endnode_parent->shortAddress != short_address) {
return false; return false;
} }
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) { if (!thread_partition_match(cur, leaderData)) {
tr_debug("Learn new Network Data"); tr_debug("Learn new Network Data");
requestNetworkdata = true; requestNetworkdata = true;
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1; thread_partition_info_update(cur, leaderData);
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1;
} }
else if (common_serial_number_greater_8(leaderData->dataVersion, leadeInfo->dataVersion)) { else if (common_serial_number_greater_8(leaderData->dataVersion, leaderInfo->dataVersion)) {
requestNetworkdata = true; requestNetworkdata = true;
} else if (common_serial_number_greater_8(leaderData->stableDataVersion, leadeInfo->stableDataVersion)) { } else if (common_serial_number_greater_8(leaderData->stableDataVersion, leaderInfo->stableDataVersion)) {
requestNetworkdata = true; requestNetworkdata = true;
} }
// Version number is updated when new network data is learned to avoid synchronization problems
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
if (requestNetworkdata) { if (requestNetworkdata) {
thread_bootstrap_parent_network_data_request(cur, true); thread_bootstrap_parent_network_data_request(cur, true);
} }
return true; return true;
} }
bool thread_instance_id_matches(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
{
if (thread_info(cur)->thread_leader_data) {
if (thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) {
return true;
}
}
return false;
}
static int thread_router_check_previous_partition_info(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv) static int thread_router_check_previous_partition_info(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv)
{ {
if (!routeTlv || !routeTlv->dataPtr || !routeTlv->tlvLen || !leaderData) { if (!routeTlv || !routeTlv->dataPtr || !routeTlv->tlvLen || !leaderData) {
@ -386,8 +415,7 @@ int thread_leader_data_validation(protocol_interface_info_entry_t *cur, thread_l
if (!thread_info(cur)->thread_leader_data) { if (!thread_info(cur)->thread_leader_data) {
return -1; return -1;
} }
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) || if (!thread_partition_match(cur, leaderData)) {
(thread_info(cur)->thread_leader_data->weighting != leaderData->weighting)) {
uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv); uint8_t routers_in_route_tlv = thread_get_router_count_from_route_tlv(routeTlv);
//partition checks //partition checks
return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv); return thread_bootstrap_partition_process(cur,routers_in_route_tlv,leaderData, routeTlv);
@ -472,11 +500,9 @@ void thread_end_device_mode_set(protocol_interface_info_entry_t *cur, bool sleep
{ {
if (sleepy) { if (sleepy) {
cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; cur->lowpan_info |= INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
mle_class_mode_set(cur->id, MLE_CLASS_SLEEPY_END_DEVICE);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, false);
} else { } else {
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
} }
} }
@ -537,9 +563,6 @@ void thread_set_link_local_address(protocol_interface_info_entry_t *cur)
static int thread_configuration_security_activate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration) static int thread_configuration_security_activate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration)
{ {
uint8_t key_material[32];
uint8_t key_index;
tr_debug("MAC SET Security Mode"); tr_debug("MAC SET Security Mode");
if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) { if (!(cur->lowpan_info & INTERFACE_NWK_ACTIVE) || !(cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED)) {
@ -554,16 +577,11 @@ static int thread_configuration_security_activate(protocol_interface_info_entry_
cur->thread_info->masterSecretMaterial.historyKeyValid = false; cur->thread_info->masterSecretMaterial.historyKeyValid = false;
cur->thread_info->masterSecretMaterial.valid_Info = true; cur->thread_info->masterSecretMaterial.valid_Info = true;
// Update the guard timer value // Update the guard timer value
thread_calculate_key_guard_timer(cur, linkConfiguration, true); thread_key_guard_timer_calculate(cur, linkConfiguration, true);
//Define KEY's //Define KEY's
thread_key_get(linkConfiguration->master_key, key_material, linkConfiguration->key_sequence); thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
key_index = THREAD_KEY_INDEX(linkConfiguration->key_sequence); thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
//Set Keys thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
//Add Security to MLE service
mle_service_security_set_security_key(cur->id, key_material, key_index, true);
//Gen also Next Key
thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
return 0; return 0;
} }
@ -711,9 +729,9 @@ int thread_configuration_mle_disable(protocol_interface_info_entry_t *cur)
return 0; return 0;
} }
int thread_mle_service_register(int8_t interface_id, uint8_t *mac64 ) static int thread_mle_service_register(protocol_interface_info_entry_t *cur, uint8_t *mac64 )
{ {
if (mle_service_interface_register(interface_id,thread_mle_parent_discover_receive_cb, mac64,8) != 0) { if (mle_service_interface_register(cur->id, cur, thread_mle_parent_discover_receive_cb, mac64,8) != 0) {
tr_error("Mle Service init Fail"); tr_error("Mle Service init Fail");
return -1; return -1;
} }
@ -1052,7 +1070,7 @@ void thread_tasklet(arm_event_s *event)
case THREAD_CHILD_UPDATE: case THREAD_CHILD_UPDATE:
tr_debug_extra("Thread SM THREAD_CHILD_UPDATE"); tr_debug_extra("Thread SM THREAD_CHILD_UPDATE");
if (thread_info(cur)->thread_endnode_parent) { if (thread_info(cur)->thread_endnode_parent) {
thread_host_bootstrap_child_update(cur->id, cur->thread_info->thread_endnode_parent->mac64); thread_host_bootstrap_child_update(cur, cur->thread_info->thread_endnode_parent->mac64);
} }
break; break;
case THREAD_ANNOUNCE_ACTIVE: { case THREAD_ANNOUNCE_ACTIVE: {
@ -1166,12 +1184,12 @@ void thread_bootstrap_ready(protocol_interface_info_entry_t *cur)
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur) void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur)
{ {
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
ns_list_foreach_safe(mle_neigh_table_entry_t, cur_entry, neig_list) { ns_list_foreach_safe(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->short_adr)) { if (!thread_addr_is_equal_or_child(cur->thread_info->routerShortAddress, cur_entry->mac16)) {
tr_debug("Free ID %x", cur_entry->short_adr); tr_debug("Free ID %x", cur_entry->mac16);
mle_class_remove_entry(cur->id, cur_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), cur_entry);
} }
} }
} }
@ -1454,9 +1472,7 @@ int thread_bootstrap_reset(protocol_interface_info_entry_t *cur)
neighbor_cache_flush(&cur->neigh_cache); neighbor_cache_flush(&cur->neigh_cache);
thread_bootstrap_stop(cur); thread_bootstrap_stop(cur);
#ifndef NO_MLE mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
mle_class_list_clean(cur->id);
#endif
cur->bootsrap_state_machine_cnt = 0; cur->bootsrap_state_machine_cnt = 0;
mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params); mac_helper_free_scan_confirm(&cur->mac_parameters->nwk_scan_params);
//tr_debug( "--> idle"); //tr_debug( "--> idle");
@ -1600,6 +1616,7 @@ void thread_bootstrap_routing_activate(protocol_interface_info_entry_t *cur)
// FEDs and routers (REEDs) perform their own address resolution // FEDs and routers (REEDs) perform their own address resolution
thread_nd_service_activate(cur->id); thread_nd_service_activate(cur->id);
} else { } else {
thread_nd_client_service_activate(cur->id);
thread_child_set_default_route(cur); thread_child_set_default_route(cur);
} }
} }
@ -2177,7 +2194,7 @@ void thread_bootstrap_start_network_discovery(protocol_interface_info_entry_t *c
scan_request.channel_mask = cur->mac_parameters->nwk_scan_params.stack_chan_list.channel_mask[0]; scan_request.channel_mask = cur->mac_parameters->nwk_scan_params.stack_chan_list.channel_mask[0];
scan_request.filter_tlv_data = NULL; scan_request.filter_tlv_data = NULL;
scan_request.filter_tlv_length = 0; scan_request.filter_tlv_length = 0;
if (thread_discovery_network_scan(cur->id, &scan_request, discover_ready) != 0 ) { if (thread_discovery_network_scan(cur, &scan_request, discover_ready) != 0 ) {
tr_error("Discovery scan start fail"); tr_error("Discovery scan start fail");
} }
} }
@ -2198,7 +2215,7 @@ void thread_bootstrap_state_machine(protocol_interface_info_entry_t *cur)
//SET Link by Static configuration //SET Link by Static configuration
tr_info("thread network attach start"); tr_info("thread network attach start");
if (thread_mle_service_register(cur->id,thread_joiner_application_random_mac_get(cur->id)) != 0 || if (thread_mle_service_register(cur,thread_joiner_application_random_mac_get(cur->id)) != 0 ||
thread_link_configuration_activate(cur, linkConfiguration) != 0) { thread_link_configuration_activate(cur, linkConfiguration) != 0) {
tr_error("Network Bootsrap Start Fail"); tr_error("Network Bootsrap Start Fail");
bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, cur); bootsrap_next_state_kick(ER_BOOTSTRAP_SCAN_FAIL, cur);
@ -2257,6 +2274,7 @@ void thread_bootstrap_stop(protocol_interface_info_entry_t *cur)
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD, NULL);
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_BORDER_ROUTER, NULL);
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
thread_leader_service_leader_data_free(cur->thread_info); thread_leader_service_leader_data_free(cur->thread_info);
thread_bootstrap_all_nodes_multicast_unregister(cur); thread_bootstrap_all_nodes_multicast_unregister(cur);
thread_data_base_init(cur->thread_info, cur->id); thread_data_base_init(cur->thread_info, cur->id);
@ -2672,7 +2690,7 @@ int thread_bootstrap_network_data_activate(protocol_interface_info_entry_t *cur)
thread_router_bootstrap_anycast_address_register(cur); thread_router_bootstrap_anycast_address_register(cur);
// Update joiner router status // Update joiner router status
thread_management_server_joiner_router_init(cur->id); thread_management_server_joiner_router_init(cur->id);
thread_extension_joiner_router_init(cur->id); thread_extension_service_init(cur);
// Update border router relay // Update border router relay
thread_bbr_commissioner_proxy_service_update(cur->id); thread_bbr_commissioner_proxy_service_update(cur->id);
@ -2870,8 +2888,7 @@ void thread_bootstrap_clear_neighbor_entries(protocol_interface_info_entry_t *cu
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour); ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, neighbour);
} }
} }
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
mle_class_list_clean(cur->id);
} }
void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t *cur) void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t *cur)
@ -2883,10 +2900,10 @@ void thread_bootstrap_dynamic_configuration_save(protocol_interface_info_entry_t
if (thread_i_am_router(cur)) { if (thread_i_am_router(cur)) {
/* Store information of our children to the dynamic storage */ /* Store information of our children to the dynamic storage */
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
ns_list_foreach_safe(mle_neigh_table_entry_t, entry, neig_list) { ns_list_foreach_safe(mac_neighbor_table_entry_t, entry, mac_table_list) {
if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->short_adr)) { if (thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) {
thread_dynamic_storage_child_info_store(cur->id, entry); thread_dynamic_storage_child_info_store(cur, entry);
} }
} }
} }
@ -2910,7 +2927,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa
return false; return false;
} }
if(mle_class_free_entry_count_get(interface->id) < 1) { if(mle_class_free_entry_count_get(interface) < 1) {
// We dont have room for any new links // We dont have room for any new links
tr_warn("Link ignore no room for addr:%x", short_address); tr_warn("Link ignore no room for addr:%x", short_address);
return false; return false;
@ -2928,7 +2945,7 @@ bool thread_bootstrap_link_create_check(protocol_interface_info_entry_t *interfa
return false; return false;
} }
if (mle_class_active_neigh_counter(interface->id) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) { if (mle_class_active_neigh_counter(interface) < THREAD_REED_AND_END_DEVICE_NEIGHBOR_LINKS + 1) {
return true; return true;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -52,7 +52,7 @@ struct thread_info_s;
struct protocol_interface_info_entry; struct protocol_interface_info_entry;
struct thread_leader_data_s; struct thread_leader_data_s;
struct link_configuration; struct link_configuration;
struct mle_neigh_table_entry_t; struct mac_neighbor_table_entry;
struct mle_tlv_info_s; struct mle_tlv_info_s;
typedef enum { typedef enum {
@ -103,12 +103,11 @@ uint8_t thread_mode_get_by_interface_ptr(struct protocol_interface_info_entry *c
void thread_bootstrap_device_synch_finish(protocol_interface_info_entry_t *cur); void thread_bootstrap_device_synch_finish(protocol_interface_info_entry_t *cur);
int8_t thread_mle_class_init(int8_t interface_id); int8_t thread_mle_class_init(int8_t interface_id);
void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers); void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers);
int thread_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mle_neigh_table_entry_t *child);
void thread_bootstrap_ready(struct protocol_interface_info_entry *cur); void thread_bootstrap_ready(struct protocol_interface_info_entry *cur);
int thread_bootstrap_reset(struct protocol_interface_info_entry *cur); int thread_bootstrap_reset(struct protocol_interface_info_entry *cur);
void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur); void thread_neighbor_list_clean(struct protocol_interface_info_entry *cur);
bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address); bool thread_bootstrap_request_network_data(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, uint16_t short_address);
bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mle_neigh_table_entry_t *entry_temp); bool thread_check_is_this_my_parent(struct protocol_interface_info_entry *cur, struct mac_neighbor_table_entry *entry_temp);
void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur); void thread_clean_old_16_bit_address_based_addresses(struct protocol_interface_info_entry *cur);
int8_t thread_bootsrap_event_trig(thread_bootsrap_event_type_e event_type, int8_t Id, arm_library_event_priority_e priority); int8_t thread_bootsrap_event_trig(thread_bootsrap_event_type_e event_type, int8_t Id, arm_library_event_priority_e priority);
void thread_interface_init(struct protocol_interface_info_entry *cur); void thread_interface_init(struct protocol_interface_info_entry *cur);
@ -126,7 +125,6 @@ int thread_parent_discover_start(int8_t interface_id, uint8_t *mac64 );
bool thread_device_synch_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries); bool thread_device_synch_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
bool thread_link_request_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries); bool thread_link_request_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries);
bool thread_instance_id_matches(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData);
int thread_leader_data_validation(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, struct mle_tlv_info_s *routeTlv); int thread_leader_data_validation(struct protocol_interface_info_entry *cur, struct thread_leader_data_s *leaderData, struct mle_tlv_info_s *routeTlv);
uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParent); uint8_t thread_calculate_link_margin(int8_t dbm, uint8_t compLinkMarginFromParent);
uint8_t thread_compute_link_margin(int8_t rssi); uint8_t thread_compute_link_margin(int8_t rssi);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -297,19 +297,19 @@ static bool thread_border_router_local_network_data_prefix_match(thread_network_
return true; return true;
} }
static void thread_border_router_child_network_data_clean(uint8_t interface_id, uint16_t child_id) static void thread_border_router_child_network_data_clean(protocol_interface_info_entry_t *cur, uint16_t child_id)
{ {
uint8_t addr16_buf[2]; uint8_t addr16_buf[2];
common_write_16_bit(child_id, addr16_buf); common_write_16_bit(child_id, addr16_buf);
if (mle_class_get_by_link_address(interface_id, addr16_buf, ADDR_802_15_4_SHORT)) { if (mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr16_buf, ADDR_802_15_4_SHORT)) {
/* Child is available in mle, do nothing */ /* Child is available in mle, do nothing */
return; return;
} }
// Child is not our child => network data contains data from lost children, remove it // Child is not our child => network data contains data from lost children, remove it
tr_debug("Remove nwk data from lost child: %04x", child_id); tr_debug("Remove nwk data from lost child: %04x", child_id);
thread_management_client_network_data_unregister(interface_id, child_id); thread_management_client_network_data_unregister(cur->id, child_id);
} }
static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr) static void thread_border_router_lost_children_nwk_data_validate(protocol_interface_info_entry_t *cur, uint16_t router_short_addr)
@ -326,7 +326,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) { ns_list_foreach(thread_network_server_data_entry_t, curRoute, &curLP->routeList) {
if (thread_addr_is_child(router_short_addr, curRoute->routerID)) { if (thread_addr_is_child(router_short_addr, curRoute->routerID)) {
// Router children found // Router children found
thread_border_router_child_network_data_clean(cur->id, curRoute->routerID); thread_border_router_child_network_data_clean(cur, curRoute->routerID);
} }
} }
@ -334,7 +334,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) { ns_list_foreach(thread_network_server_data_entry_t, curBR, &curLP->borderRouterList) {
if (thread_addr_is_child(router_short_addr, curBR->routerID)) { if (thread_addr_is_child(router_short_addr, curBR->routerID)) {
// Router children found // Router children found
thread_border_router_child_network_data_clean(cur->id, curBR->routerID); thread_border_router_child_network_data_clean(cur, curBR->routerID);
} }
} }
} }
@ -344,7 +344,7 @@ static void thread_border_router_lost_children_nwk_data_validate(protocol_interf
ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) { ns_list_foreach(thread_network_data_service_server_entry_t, server, &service->server_list) {
if (thread_addr_is_child(router_short_addr, server->router_id)) { if (thread_addr_is_child(router_short_addr, server->router_id)) {
// Router children found // Router children found
thread_border_router_child_network_data_clean(cur->id, server->router_id); thread_border_router_child_network_data_clean(cur, server->router_id);
} }
} }
} }
@ -626,6 +626,7 @@ int thread_border_router_prefix_add(int8_t interface_id, uint8_t *prefix_ptr, ui
service.stableData = prefix_info_ptr->stableData; service.stableData = prefix_info_ptr->stableData;
service.P_on_mesh = prefix_info_ptr->P_on_mesh; service.P_on_mesh = prefix_info_ptr->P_on_mesh;
service.P_nd_dns = prefix_info_ptr->P_nd_dns; service.P_nd_dns = prefix_info_ptr->P_nd_dns;
service.P_res1 = prefix_info_ptr->P_res1;
return thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service); return thread_local_server_list_add_on_mesh_server(&cur->thread_info->localServerDataBase, &prefixTlv, &service);
#else #else

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2015, 2017, Arm Limited and affiliates. * Copyright (c) 2014-2015, 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -64,6 +64,7 @@
#include "6LoWPAN/Thread/thread_address_registration_client.h" #include "6LoWPAN/Thread/thread_address_registration_client.h"
#include "6LoWPAN/Thread/thread_resolution_client.h" #include "6LoWPAN/Thread/thread_resolution_client.h"
#include <6LoWPAN/Thread/thread_extension_bootstrap.h> #include <6LoWPAN/Thread/thread_extension_bootstrap.h>
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "Service_Libs/mle_service/mle_service_security.h" #include "Service_Libs/mle_service/mle_service_security.h"
#include "Service_Libs/blacklist/blacklist.h" #include "Service_Libs/blacklist/blacklist.h"
@ -79,6 +80,7 @@
#include "MLE/mle_tlv.h" #include "MLE/mle_tlv.h"
#include "Service_Libs/nd_proxy/nd_proxy.h" #include "Service_Libs/nd_proxy/nd_proxy.h"
#include "Service_Libs/mle_service/mle_service_api.h" #include "Service_Libs/mle_service/mle_service_api.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mac_pairwise_key.h" #include "6LoWPAN/MAC/mac_pairwise_key.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
@ -104,7 +106,7 @@ thread_leader_data_t *thread_leader_data_generate(void);
thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info); thread_parent_info_t *thread_parent_data_allocate(thread_info_t *info);
static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr); static uint8_t * thread_joining_port_tlv_write(uint16_t port, uint8_t *ptr);
static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr); static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr);
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor); static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index);
static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason); static void thread_address_notification_cb(struct protocol_interface_info_entry *interface, const struct if_address_entry *addr, if_address_callback_t reason);
/* Helper functions*/ /* Helper functions*/
@ -152,33 +154,37 @@ uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_
if (!linkConfiguration) { if (!linkConfiguration) {
return NULL; return NULL;
} }
//tr_debug("MLE key request by sequence id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
cur = protocol_stack_interface_info_get_by_id(interface_id); cur = protocol_stack_interface_info_get_by_id(interface_id);
if (cur && cur->thread_info) { if (!cur || !cur->thread_info) {
if (cur->thread_info->masterSecretMaterial.valid_Info) { return NULL;
if (keySequnce == linkConfiguration->key_sequence) { }
if (mle_service_security_default_key_id_get(interface_id) == keyId) { if (!cur->thread_info->masterSecretMaterial.valid_Info) {
keyPtr = mle_service_security_default_key_get(interface_id); return NULL;
} }
} else if (keySequnce == (linkConfiguration->key_sequence + 1)) { if (keySequnce == linkConfiguration->key_sequence) {
if (mle_service_security_next_key_id_get(interface_id) == keyId) { if (mle_service_security_default_key_id_get(interface_id) == keyId) {
keyPtr = mle_service_security_next_key_get(interface_id); keyPtr = mle_service_security_default_key_get(interface_id);
}
}
if (!keyPtr) {
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce);
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
}
} }
} else if (keySequnce == (linkConfiguration->key_sequence + 1)) {
if (mle_service_security_next_key_id_get(interface_id) == keyId) {
keyPtr = mle_service_security_next_key_get(interface_id);
}
}
if (!keyPtr) {
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, keySequnce);
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, keySequnce);
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
cur->thread_info->masterSecretMaterial.historyKeyValid = false;
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
} }
return keyPtr; return keyPtr;
} }
uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId) uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_security_event_t event, uint8_t keyId)
{ {
(void)keyId;
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
if (!interface) { if (!interface) {
return NULL; return NULL;
@ -197,7 +203,7 @@ uint8_t * thread_mle_service_security_notify_cb(int8_t interface_id, mle_securit
break; break;
case MLE_SEC_UNKNOWN_KEY: case MLE_SEC_UNKNOWN_KEY:
return thread_management_key_request(interface_id,keyId); return NULL;
} }
return NULL; return NULL;
} }
@ -360,23 +366,31 @@ bool thread_connectivity_tlv_parse(uint8_t *ptr, uint16_t dataLength, thread_con
return false; return false;
} }
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init) void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init)
{ {
uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0; uint32_t key_rotation = linkConfiguration ? linkConfiguration->key_rotation : 0;
if (is_init && key_rotation < 3600) { if (is_init && key_rotation < 1) {
tr_warn("Attempted to set key rotation time smaller than 1 hour."); tr_warn("Attempted to set key rotation time smaller than 1 hour.");
key_rotation = 3600; key_rotation = 1;
} }
cur->thread_info->masterSecretMaterial.keyRotation = key_rotation; cur->thread_info->masterSecretMaterial.keyRotation = key_rotation * 3600; // setting value is hours converting to seconds
cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 0.93); cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = is_init ? 0 : (key_rotation * 3600 * 0.93);
}
void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur)
{
cur->thread_info->masterSecretMaterial.keySwitchGuardTimer = 0;
} }
thread_leader_data_t *thread_leader_data_generate(void) thread_leader_data_t *thread_leader_data_generate(void)
{ {
thread_leader_data_t *leader_data; thread_leader_data_t *leader_data;
leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t)); leader_data = ns_dyn_mem_alloc(sizeof(thread_leader_data_t));
if (leader_data) {
memset(leader_data,0,sizeof(thread_leader_data_t));
}
return leader_data; return leader_data;
} }
@ -663,16 +677,27 @@ thread_mcast_child_t *thread_child_mcast_entry_find(thread_mcast_children_list_t
return NULL; return NULL;
} }
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf)
{
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur),buf->dst_sa.address + 2 , buf->dst_sa.addr_type);
if (entry && thread_addr_is_child(mac_helper_mac16_address_get(cur), entry->mac16)) {
/* Check if the child can handle only stable network data (e.g. sleepy device) */
return !(thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, entry->index));
}
return false;
}
thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64) thread_mcast_child_t *thread_child_mcast_entry_get(protocol_interface_info_entry_t *cur, const uint8_t *mcast_addr, const uint8_t *mac64)
{ {
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, mac64, ADDR_802_15_4_LONG); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), mac64, ADDR_802_15_4_LONG);
if (!mle_entry) { if (!entry) {
tr_error("No MLE entry."); tr_error("No MLE entry.");
return NULL; return NULL;
} }
if (mle_entry->mode & MLE_RX_ON_IDLE) { if (entry->rx_on_idle) {
/* Not a sleepy child */ /* Not a sleepy child */
tr_debug("Not a sleepy child"); tr_debug("Not a sleepy child");
return NULL; return NULL;
@ -791,8 +816,6 @@ int thread_init(protocol_interface_info_entry_t *cur)
return -1; return -1;
} }
mle_class_router_challenge(cur->id, NULL);
if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) { if (etx_accum_failures_callback_register(cur->nwk_id, cur->id, 1, thread_tx_failure_handler) != 1) {
return -1; return -1;
} }
@ -803,7 +826,6 @@ int thread_init(protocol_interface_info_entry_t *cur)
thread_data_base_init(cur->thread_info, cur->id); thread_data_base_init(cur->thread_info, cur->id);
mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true); mac_helper_pib_boolean_set(cur,macThreadForceLongAddressForBeacon , true);
mac_helper_mac16_address_set(cur, 0xffff); mac_helper_mac16_address_set(cur, 0xffff);
mle_class_mode_set(cur->id, MLE_CLASS_END_DEVICE);
return 0; return 0;
} }
@ -817,7 +839,7 @@ int thread_attach_ready(protocol_interface_info_entry_t *cur)
case THREAD_STATE_CONNECTED: case THREAD_STATE_CONNECTED:
case THREAD_STATE_CONNECTED_ROUTER: case THREAD_STATE_CONNECTED_ROUTER:
return 0; return 0;
break; /* break; */
default: default:
break; break;
} }
@ -919,7 +941,7 @@ static void thread_key_switch_timer(protocol_interface_info_entry_t *cur, uint16
tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1); tr_debug("thrKeyRotation == 0: sync key material by %"PRIu32, linkConfiguration->key_sequence + 1);
thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1); thread_management_key_sets_calc(cur, linkConfiguration, linkConfiguration->key_sequence + 1);
thread_calculate_key_guard_timer(cur, linkConfiguration, false); thread_key_guard_timer_calculate(cur, linkConfiguration, false);
} }
} }
@ -1019,14 +1041,15 @@ void thread_timer(protocol_interface_info_entry_t *cur, uint8_t ticks)
return; return;
} }
if (thread_i_am_router(cur)) { if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) {
/* Own attach is ongoing, do not send advertisements */
return;
}
if (thread_i_am_router(cur)) {
if (thread_routing_timer(thread_info, ticks)) { if (thread_routing_timer(thread_info, ticks)) {
thread_router_bootstrap_mle_advertise(cur); thread_router_bootstrap_mle_advertise(cur);
} }
} else {
} }
} }
@ -1121,14 +1144,20 @@ uint8_t thread_beacon_indication(uint8_t *ptr, uint8_t len, protocol_interface_i
static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer) static uint8_t *thread_linkquality_write(int8_t interface_id, uint8_t *buffer)
{ {
protocol_interface_info_entry_t *interface_ptr = protocol_stack_interface_info_get_by_id(interface_id);
if (!interface_ptr && !interface_ptr->thread_info) {
return buffer;
}
uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0; uint8_t lqi1 = 0, lqi2 = 0, lqi3 = 0;
thread_link_quality_e thread_link_quality; thread_link_quality_e thread_link_quality;
mle_neigh_table_list_t *neigh_list = mle_class_active_list_get(interface_id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(interface_ptr)->neighbour_list;
ns_list_foreach(mle_neigh_table_entry_t, cur, neigh_list) { ns_list_foreach(mac_neighbor_table_entry_t, cur, mac_table_list) {
if (thread_is_router_addr(cur->short_adr)) { if (thread_is_router_addr(cur->mac16)) {
// Only count routers to link quality // Only count routers to link quality
thread_link_quality = thread_link_margin_to_quality(cur->link_margin); uint16_t link_margin = thread_neighbor_entry_linkmargin_get(&interface_ptr->thread_info->neighbor_class, cur->index);
thread_link_quality = thread_link_margin_to_quality(link_margin);
switch (thread_link_quality) { switch (thread_link_quality) {
case QUALITY_20dB: case QUALITY_20dB:
lqi3++; lqi3++;
@ -1193,14 +1222,14 @@ uint8_t *thread_connectivity_tlv_write(uint8_t *ptr, protocol_interface_info_ent
*ptr++ = 10; *ptr++ = 10;
// determine parent priority // determine parent priority
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur->id) > 2*THREAD_MAX_MTD_CHILDREN)) { if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && (3*mle_class_rfd_entry_count_get(cur) > 2*THREAD_MAX_MTD_CHILDREN)) {
*ptr++ = CONNECTIVITY_PP_LOW; *ptr++ = CONNECTIVITY_PP_LOW;
} else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur->id) > 2*THREAD_MAX_SED_CHILDREN)) { } else if (!(mode & MLE_RX_ON_IDLE) && (3*mle_class_sleepy_entry_count_get(cur) > 2*THREAD_MAX_SED_CHILDREN)) {
*ptr++ = CONNECTIVITY_PP_LOW; *ptr++ = CONNECTIVITY_PP_LOW;
} else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) { } else if (3*thread_router_bootstrap_child_count_get(cur) > 2*thread->maxChildCount) {
// 1/3 of the child capacity remaining, PP=low // 1/3 of the child capacity remaining, PP=low
*ptr++ = CONNECTIVITY_PP_LOW; *ptr++ = CONNECTIVITY_PP_LOW;
} else if (mle_class_free_entry_count_get(cur->id) < THREAD_FREE_MLE_ENTRY_THRESHOLD) { } else if (mle_class_free_entry_count_get(cur) < THREAD_FREE_MLE_ENTRY_THRESHOLD) {
// If only few entries available in the MLE table, change priority to low // If only few entries available in the MLE table, change priority to low
*ptr++ = CONNECTIVITY_PP_LOW; *ptr++ = CONNECTIVITY_PP_LOW;
} else { } else {
@ -1829,7 +1858,7 @@ static uint8_t * thread_commissioner_port_tlv_write(uint16_t port, uint8_t *ptr)
return common_write_16_bit(port, ptr); return common_write_16_bit(port, ptr);
} }
static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, mle_neigh_table_entry_t *neighbor) static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failures, uint8_t attribute_index)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(nwk_id);
@ -1839,27 +1868,33 @@ static void thread_tx_failure_handler(int8_t nwk_id, uint8_t accumulated_failure
return; return;
} }
mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_attribute_discover(mac_neighbor_info(cur), attribute_index);
if (!neighbor) {
return;
}
if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) { if (accumulated_failures >= THREAD_MAC_TRANSMISSIONS*THREAD_FAILED_CHILD_TRANSMISSIONS) {
mle_class_remove_entry(cur->id, neighbor); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor);
} }
} }
/* Called when MLE link to neighbour lost, or ETX callback says link is bad */ /* Called when MLE link to neighbour lost, or ETX callback says link is bad */
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour) void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *neighbour)
{ {
thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent; thread_parent_info_t *thread_endnode_parent = thread_info(cur)->thread_endnode_parent;
if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->short_adr) { if (!thread_i_am_router(cur) && thread_endnode_parent && thread_endnode_parent->shortAddress == neighbour->mac16) {
if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) { if(cur->nwk_bootstrap_state != ER_CHILD_ID_REQ) {
tr_warn("End device lost parent, reset!\n"); tr_warn("End device lost parent, reset!\n");
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
} }
} }
thread_routing_remove_link(cur, neighbour->short_adr); thread_routing_remove_link(cur, neighbour->mac16);
thread_router_bootstrap_reset_child_info(cur, neighbour); thread_router_bootstrap_reset_child_info(cur, neighbour);
protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64); protocol_6lowpan_release_long_link_address_from_neighcache(cur, neighbour->mac64);
mac_helper_devicetable_remove(cur->mac_api, neighbour->attribute_index); mac_helper_devicetable_remove(cur->mac_api, neighbour->index);
thread_neighbor_class_entry_remove(&cur->thread_info->neighbor_class, neighbour->index);
} }
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv) uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv)
@ -1894,7 +1929,7 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry
} else { } else {
if (reason == ADDR_CALLBACK_DAD_COMPLETE) { if (reason == ADDR_CALLBACK_DAD_COMPLETE) {
/* Send address notification (our parent doesn't do that for us) */ /* Send address notification (our parent doesn't do that for us) */
thread_extension_address_registration(interface, addr->address, NULL); thread_extension_address_registration(interface, addr->address, NULL, false, false);
} }
} }
} }
@ -1902,9 +1937,6 @@ static void thread_address_notification_cb(struct protocol_interface_info_entry
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added) void thread_mcast_group_change(struct protocol_interface_info_entry *interface, if_group_entry_t *group, bool addr_added)
{ {
(void) addr_added;
group->mld_timer = 0;
if (thread_attach_ready(interface) != 0) { if (thread_attach_ready(interface) != 0) {
return; return;
@ -1918,11 +1950,13 @@ void thread_mcast_group_change(struct protocol_interface_info_entry *interface,
interface->thread_info->childUpdateReqTimer = 1; interface->thread_info->childUpdateReqTimer = 1;
} }
} else { } else {
thread_extension_mcast_subscrition_change(interface, group, addr_added); if (addr_added) {
thread_address_registration_timer_set(interface, 0, 1);
}
} }
} }
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur) void thread_partition_data_purge(protocol_interface_info_entry_t *cur)
{ {
/* Partition has been changed. Wipe out data related to old partition */ /* Partition has been changed. Wipe out data related to old partition */
thread_management_client_pending_coap_request_kill(cur->id); thread_management_client_pending_coap_request_kill(cur->id);
@ -1935,5 +1969,33 @@ void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur)
} }
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
{
if (thread_info(cur)->thread_leader_data) {
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData->partitionId) &&
(thread_info(cur)->thread_leader_data->weighting == leaderData->weighting)) {
return true;
}
}
return false;
}
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData)
{
/* Force network data update later when processing network data TLV */
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1;
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1;
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
thread_info(cur)->thread_leader_data->weighting = leaderData->weighting;
/* New network data learned, get rid of old partition data */
thread_partition_data_purge(cur);
}
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index)
{
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, neighbor_attribute_index);
}
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -40,6 +40,8 @@
#include "eventOS_event_timer.h" #include "eventOS_event_timer.h"
#include "MLE/mle_tlv.h" #include "MLE/mle_tlv.h"
struct mac_neighbor_table_entry;
#define MAX_MLE_CHALLENGE_LENGTH 32 #define MAX_MLE_CHALLENGE_LENGTH 32
/* /*
@ -55,8 +57,8 @@
#define NETWORK_ID_TIMEOUT 120 //seconds #define NETWORK_ID_TIMEOUT 120 //seconds
// Values when adverticements are made faster when leader connection is restored // Values when adverticements are made faster when leader connection is restored
#define NETWORK_ID_SPEEDUP 60 //seconds #define NETWORK_ID_SPEEDUP 55 //seconds
#define NETWORK_ID_SPEEDUP_MAX 100 //seconds #define NETWORK_ID_SPEEDUP_MAX 80 //seconds
#define DHCPV6_ENTERPRISE_THREAD 0x0000AFAA #define DHCPV6_ENTERPRISE_THREAD 0x0000AFAA
#define DHCPV6_OPTION_VENDOR_SPESIFIC_INFO_LEN 0x0011 #define DHCPV6_OPTION_VENDOR_SPESIFIC_INFO_LEN 0x0011
@ -92,6 +94,22 @@ typedef enum {
THREAD_COMMISSIONER_REGISTERED THREAD_COMMISSIONER_REGISTERED
} thread_commissioner_register_status_e; } thread_commissioner_register_status_e;
typedef struct thread_neigh_table_entry_s {
uint8_t mlEid[8];
uint32_t last_contact_time; /*!< monotonic time - hard to define "contact"; used for Thread Leasequery replies */
uint16_t link_margin;
bool secured_data_request:1;
bool request_full_data_set:1;
} thread_neigh_table_entry_t ;
/**
* Neighbor info data base
*/
typedef struct thread_neighbor_class_s {
thread_neigh_table_entry_t *neigh_info_list; /*!< Allocated Neighbour info array*/
uint8_t list_size; /*!< List size*/
} thread_neighbor_class_t;
typedef struct thread_mcast_child { typedef struct thread_mcast_child {
uint8_t mac64[8]; uint8_t mac64[8];
ns_list_link_t link; ns_list_link_t link;
@ -261,6 +279,7 @@ typedef struct thread_previous_partition_info_s {
typedef struct thread_info_s { typedef struct thread_info_s {
thread_routing_info_t routing; thread_routing_info_t routing;
thread_neighbor_class_t neighbor_class;
thread_master_secret_material_t masterSecretMaterial; thread_master_secret_material_t masterSecretMaterial;
thread_network_data_cache_entry_t networkDataStorage; thread_network_data_cache_entry_t networkDataStorage;
thread_network_local_data_cache_entry_t localServerDataBase; thread_network_local_data_cache_entry_t localServerDataBase;
@ -363,7 +382,7 @@ uint16_t thread_network_data_generate_stable_set(protocol_interface_info_entry_t
void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId); void thread_set_active_router(protocol_interface_info_entry_t *cur, if_address_entry_t *address_entry, uint8_t *routerId);
uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv); uint8_t thread_get_router_count_from_route_tlv(mle_tlv_info_t *routeTlv);
void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *neighbour); void thread_reset_neighbour_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *neighbour);
void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur); void thread_child_id_request_entry_clean(protocol_interface_info_entry_t *cur);
thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64); thread_pending_child_id_req_t *thread_child_id_request_entry_get(protocol_interface_info_entry_t *cur, uint8_t *euid64);
@ -413,15 +432,19 @@ uint8_t *thread_pending_operational_dataset_write(protocol_interface_info_entry_
bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len); bool thread_pending_operational_dataset_process(protocol_interface_info_entry_t *cur, uint64_t mle_pending_timestamp, uint8_t *ptr, uint16_t len);
/*Write optional thread leader data TLV if leader data is known*/ /*Write optional thread leader data TLV if leader data is known*/
uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur); uint8_t thread_pending_timestamp_tlv_size(protocol_interface_info_entry_t *cur);
void thread_calculate_key_guard_timer(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init); void thread_key_guard_timer_calculate(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, bool is_init);
void thread_key_guard_timer_reset(protocol_interface_info_entry_t *cur);
void thread_set_link_local_address(protocol_interface_info_entry_t *cur); void thread_set_link_local_address(protocol_interface_info_entry_t *cur);
void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added); void thread_mcast_group_change(struct protocol_interface_info_entry *interface, struct if_group_entry *group, bool group_added);
void thread_old_partition_data_purge(protocol_interface_info_entry_t *cur); void thread_partition_data_purge(protocol_interface_info_entry_t *cur);
bool thread_partition_match(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
void thread_partition_info_update(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
void thread_neighbor_communication_update(protocol_interface_info_entry_t *cur, uint8_t neighbor_attribute_index);
bool thread_stable_context_check(protocol_interface_info_entry_t *cur, buffer_t *buf);
#else // HAVE_THREAD #else // HAVE_THREAD
NS_DUMMY_DEFINITIONS_OK NS_DUMMY_DEFINITIONS_OK
#define thread_stable_context_check(cur, buf) (false)
#define thread_info(cur) ((thread_info_t *) NULL) #define thread_info(cur) ((thread_info_t *) NULL)
#define thread_am_router(cur) (false) #define thread_am_router(cur) (false)
#define thread_am_host(cur) (false) #define thread_am_host(cur) (false)
@ -438,6 +461,7 @@ NS_DUMMY_DEFINITIONS_OK
#define thread_link_reject_send(interface, ll64) 0 #define thread_link_reject_send(interface, ll64) 0
#define thread_addr_is_mesh_local_16(addr, cur) false #define thread_addr_is_mesh_local_16(addr, cur) false
#define thread_mcast_group_change(interface, group, group_added) ((void)0) #define thread_mcast_group_change(interface, group, group_added) ((void)0)
#define thread_neighbor_communication_update(cur, neighbor_attribute_index) ((void)0)
#endif // HAVE_THREAD #endif // HAVE_THREAD
#endif /* LOWPAN_THREAD_H_ */ #endif /* LOWPAN_THREAD_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -39,6 +39,7 @@
#include "thread_joiner_application.h" #include "thread_joiner_application.h"
#include "thread_leader_service.h" #include "thread_leader_service.h"
#include "thread_router_bootstrap.h" #include "thread_router_bootstrap.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h"
#include "thread_config.h" #include "thread_config.h"
@ -47,6 +48,7 @@
#include "thread_diagcop_lib.h" #include "thread_diagcop_lib.h"
#include "common_functions.h" #include "common_functions.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "mac_api.h" #include "mac_api.h"
@ -93,31 +95,31 @@ static uint8_t *thread_diagnostic_child_table_tlv_build(uint8_t *data_ptr, proto
uint8_t child_count = 0; uint8_t child_count = 0;
uint8_t calculated_timeout; uint8_t calculated_timeout;
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_table) {
return data_ptr;
}
child_count = thread_router_bootstrap_child_count_get(cur); child_count = thread_router_bootstrap_child_count_get(cur);
*data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type *data_ptr++ = DIAGCOP_TLV_CHILD_TABLE; // Type
*data_ptr++ = (3 * child_count); // Length *data_ptr++ = (3 * child_count); // Length
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == mac_helper_mac16_address_get(cur)){ if (thread_router_addr_from_addr(cur_entry->mac16) == mac_helper_mac16_address_get(cur)){
/* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */ /* |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3| */
/* |Timeout |Rsv| Child ID | Mode | */ /* |Timeout |Rsv| Child ID | Mode | */
calculated_timeout = thread_log2_aprx((cur_entry->timeout_rx-1)*MLE_TIMER_TICKS_SECONDS) + 4; calculated_timeout = thread_log2_aprx(cur_entry->link_lifetime - 1) + 4;
tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->short_adr, cur_entry->mode); uint8_t mode = 0;
mode |= mle_mode_write_from_mac_entry(cur_entry);
mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, cur_entry->index);
tr_debug("Write child table TLV entry: %d - %d - %d", calculated_timeout, cur_entry->mac16, mode);
*data_ptr = 0x00; //reserved bytes to zero *data_ptr = 0x00; //reserved bytes to zero
*data_ptr = calculated_timeout << 3; *data_ptr = calculated_timeout << 3;
if(cur_entry->short_adr & 0x0100){ if(cur_entry->mac16 & 0x0100){
*data_ptr = *data_ptr | 0x01; *data_ptr = *data_ptr | 0x01;
} }
data_ptr++; data_ptr++;
*data_ptr++ = (uint8_t)(cur_entry->short_adr & 0x00ff); *data_ptr++ = (uint8_t)(cur_entry->mac16 & 0x00ff);
*data_ptr++ = cur_entry->mode; *data_ptr++ = mode;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -818,7 +818,7 @@ static void thread_discovery_request_msg_handler(thread_discovery_class_t * disc
tr_debug("Thread discovery request message RX"); tr_debug("Thread discovery request message RX");
// Check if we have room for new neighbor // Check if we have room for new neighbor
if (mle_class_free_entry_count_get(discovery_class->interface_id) < 1) { if (mle_class_free_entry_count_get(discovery_class->interface) < 1) {
tr_debug("MLE table full, skip request"); tr_debug("MLE table full, skip request");
return; return;
} }
@ -1281,10 +1281,10 @@ static void thread_discovery_normal_receive_cb(int8_t interface_id, mle_message_
/** /**
* Start Thread network discovery * Start Thread network discovery
*/ */
int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb) int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb)
{ {
thread_discovery_class_t * discovery_class = thread_discovery_class_get(interface_id); thread_discovery_class_t * discovery_class = thread_discovery_class_get(cur_interface->id);
if (!discovery_class || !ready_cb || !scan_request) { if (!discovery_class || !ready_cb || !scan_request) {
return -1; return -1;
} }
@ -1304,12 +1304,12 @@ int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t
return -3; return -3;
} }
if (mle_service_interface_register(interface_id, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) { if (mle_service_interface_register(cur_interface->id, cur_interface, thread_discovery_normal_receive_cb, discovery_class->discovery_request->temporary_mac64,8) != 0) {
thread_discovery_request_free(discovery_class); thread_discovery_request_free(discovery_class);
return -1; return -1;
} }
if (mle_service_interface_receiver_bypass_handler_update(interface_id, thread_discovery_message_receiver_cb) != 0) { if (mle_service_interface_receiver_bypass_handler_update(cur_interface->id, thread_discovery_message_receiver_cb) != 0) {
thread_discovery_request_free(discovery_class); thread_discovery_request_free(discovery_class);
return -1; return -1;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -122,7 +122,7 @@ int thread_discovery_responser_enable(int8_t interface_id, bool enable_service);
/** /**
* Start Thread network discovery * Start Thread network discovery
*/ */
int thread_discovery_network_scan(int8_t interface_id, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb); int thread_discovery_network_scan(struct protocol_interface_info_entry *cur_interface, thread_discover_reques_t *scan_request, thread_discovery_ready_cb *ready_cb);
/** /**
* Start device orphan scan * Start device orphan scan

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -40,27 +40,66 @@ extern "C" {
struct discovery_response_list; struct discovery_response_list;
#ifdef HAVE_THREAD_V2
void thread_extension_allocate(protocol_interface_info_entry_t *cur);
void thread_extension_free(protocol_interface_info_entry_t *cur);
void thread_extension_init(int8_t interface_id, int8_t coap_service_id);
void thread_extension_mtd_service_register(protocol_interface_info_entry_t *cur);
int thread_extension_network_prefix_get(int8_t interface_id, uint8_t *options_ptr, uint8_t *prefix_ptr, uint8_t *prefix_len);
void thread_extension_network_data_process(struct protocol_interface_info_entry *cur);
int thread_extension_primary_bbr_get(struct protocol_interface_info_entry *cur, uint8_t *addr_ptr, uint8_t *seq_ptr, uint32_t *timer1_ptr, uint32_t *timer2_ptr);
void thread_extension_address_registration(struct protocol_interface_info_entry *interface, const uint8_t *addr, const uint8_t *child_mac64, bool refresh_child_entry, bool duplicate_child_detected);
void thread_extension_address_generate(protocol_interface_info_entry_t *cur);
void thread_extension_aloc_generate(struct protocol_interface_info_entry *cur);
bool thread_extension_aloc_map(protocol_interface_info_entry_t *cur, uint16_t *addr16);
void thread_extension_mcast_subscrition_change(protocol_interface_info_entry_t *interface);
void thread_extension_address_registration_trigger(protocol_interface_info_entry_t *interface);
void thread_extension_route_set(protocol_interface_info_entry_t *cur);
void thread_extension_activate(protocol_interface_info_entry_t *cur);
bool thread_extension_enabled(protocol_interface_info_entry_t *cur);
bool thread_extension_context_can_delete(int8_t id, uint8_t servicesPrefix[16], uint8_t context_prefix_length);
bool thread_extension_version_check(uint8_t version);
void thread_extension_discover_response_read(struct discovery_response_list *nwk_info, uint16_t discover_response_tlv, uint8_t *data_ptr, uint16_t data_len);
void thread_extension_discover_response_tlv_write(uint16_t *data, uint8_t version, uint16_t securityPolicy);
int thread_extension_service_init(protocol_interface_info_entry_t *cur);
void thread_extension_addr_ntf_send(struct protocol_interface_info_entry *cur, uint8_t *destination_address, const uint8_t *addr_data_ptr, uint8_t bbr_status);
#ifdef HAVE_THREAD_ROUTER
bool thread_extension_joining_enabled(int8_t interface_id);
uint8_t thread_extension_discover_response_len(protocol_interface_info_entry_t *cur);
uint8_t *thread_extension_discover_response_write(protocol_interface_info_entry_t *cur, uint8_t *ptr);
#else
#define thread_extension_joining_enabled(interface_id) false
#define thread_extension_discover_response_len(cur) 0
#define thread_extension_discover_response_write(cur, ptr) (ptr)
#endif //HAVE_THREAD_ROUTER
#else
#define thread_extension_allocate(cur) #define thread_extension_allocate(cur)
#define thread_extension_free(cur) #define thread_extension_free(cur)
#define thread_extension_init(interface_id,coap_service_id) #define thread_extension_init(interface_id,coap_service_id)
#define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1) #define thread_extension_network_prefix_get(interface_id,options_ptr,prefix_ptr,prefix_len) (-1)
#define thread_extension_network_data_process(cur) #define thread_extension_network_data_process(cur)
#define thread_extension_primary_bbr_get(cur,addr_ptr,seq_ptr,timer1_ptr, timer2_ptr) (-1) #define thread_extension_primary_bbr_get(cur,addr_ptr,seq_ptr,timer1_ptr, timer2_ptr) (-1)
#define thread_extension_address_registration(interface,addr,child_mac64) #define thread_extension_address_registration(interface,addr,child_mac64,refresh_child_entry,duplicate_child_detected)
#define thread_extension_address_generate(cur) #define thread_extension_address_generate(cur)
#define thread_extension_aloc_generate(cur) #define thread_extension_aloc_generate(cur)
#define thread_extension_aloc_map(cur, addr16) false #define thread_extension_aloc_map(cur, addr16) false
#define thread_extension_mcast_subscrition_change(interface, group, added) #define thread_extension_mcast_subscrition_change(interface)
#define thread_extension_route_set(cur) #define thread_extension_route_set(cur)
#define thread_extension_activate(cur) #define thread_extension_activate(cur)
#define thread_extension_enabled(cur) (false) #define thread_extension_enabled(cur) (false)
#define thread_extension_version_check(version) (false) #define thread_extension_version_check(version) (false)
#define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len) #define thread_extension_discover_response_read(nwk_info, discover_response_tlv, data_ptr, data_len)
#define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data) #define thread_extension_discover_response_tlv_write(data, version, extension_bit) (data)
#define thread_extension_joiner_router_init(interface_id) #define thread_extension_service_init(cur) 0
#define thread_extension_joining_enabled(interface_id) false #define thread_extension_joining_enabled(interface_id) false
#define thread_extension_discover_response_len(cur) 0 #define thread_extension_discover_response_len(cur) 0
#define thread_extension_discover_response_write(cur, ptr) (ptr) #define thread_extension_discover_response_write(cur, ptr) (ptr)
#define thread_extension_addr_ntf_send(cur,destination_address,addr_data_ptr,bbr_status)
#define thread_extension_context_can_delete(id, servicesPrefix, context_prefix_length) false
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,6 +38,14 @@
extern "C" { extern "C" {
#endif #endif
/*
* Thread PBBR ML-EID map structure
*/
typedef struct thread_pbbr_dua_info {
uint8_t mleid_ptr[8];
uint32_t last_contact_time;
} thread_pbbr_dua_info_t;
#if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER) #if defined(HAVE_THREAD_V2) && defined(HAVE_THREAD_BORDER_ROUTER)
int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id); int8_t thread_extension_bbr_init(int8_t interface_id, int8_t backbone_interface_id);
@ -47,6 +55,7 @@ void thread_extension_bbr_seconds_timer(int8_t interface_id, uint32_t seconds);
int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay); int thread_extension_bbr_timeout_set(int8_t interface_id, uint32_t timeout_a, uint32_t timeout_b, uint32_t delay);
int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port); int thread_extension_bbr_address_set(int8_t interface_id, const uint8_t *addr_ptr, uint16_t port);
void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur); void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur);
int thread_extension_bbr_prefix_set(int8_t interface_id, uint8_t *prefix);
#else #else
@ -58,6 +67,7 @@ void thread_extension_bbr_route_update(protocol_interface_info_entry_t *cur);
#define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay) #define thread_extension_bbr_timeout_set(interface_id, timeout_a, timeout_b, delay)
#define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1) #define thread_extension_bbr_address_set(interface_id, addr_ptr, port) (-1)
#define thread_extension_bbr_route_update(cur) #define thread_extension_bbr_route_update(cur)
#define thread_extension_bbr_prefix_set(interface_id, prefix) 0
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -63,6 +63,7 @@
#include "6LoWPAN/Thread/thread_management_client.h" #include "6LoWPAN/Thread/thread_management_client.h"
#include "6LoWPAN/Thread/thread_network_data_lib.h" #include "6LoWPAN/Thread/thread_network_data_lib.h"
#include "6LoWPAN/Thread/thread_tmfcop_lib.h" #include "6LoWPAN/Thread/thread_tmfcop_lib.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "thread_management_if.h" #include "thread_management_if.h"
#include "Common_Protocols/ipv6.h" #include "Common_Protocols/ipv6.h"
#include "MPL/mpl.h" #include "MPL/mpl.h"
@ -73,6 +74,7 @@
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "Core/include/address.h" #include "Core/include/address.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP "tebs" #define TRACE_GROUP "tebs"
@ -122,7 +124,8 @@ static void thread_merge_prepare(protocol_interface_info_entry_t *cur)
thread_clean_old_16_bit_address_based_addresses(cur); thread_clean_old_16_bit_address_based_addresses(cur);
mpl_clear_realm_scope_seeds(cur); mpl_clear_realm_scope_seeds(cur);
ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_HOST, NULL);
thread_old_partition_data_purge(cur); ipv6_route_table_remove_info(cur->id, ROUTE_THREAD_PROXIED_DUA_HOST, NULL);
thread_partition_data_purge(cur);
thread_network_data_clean(cur); thread_network_data_clean(cur);
cur->nwk_mode = ARM_NWK_GP_IP_MODE; cur->nwk_mode = ARM_NWK_GP_IP_MODE;
} }
@ -145,7 +148,7 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI
uint8_t ll64[16]; uint8_t ll64[16];
thread_scanned_parent_t *parent = cur->thread_info->thread_attach_scanned_parent; thread_scanned_parent_t *parent = cur->thread_info->thread_attach_scanned_parent;
link_configuration_s *linkConfiguration; link_configuration_s *linkConfiguration;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
linkConfiguration = thread_joiner_application_get_config(interface_id); linkConfiguration = thread_joiner_application_get_config(interface_id);
if (!linkConfiguration) { if (!linkConfiguration) {
@ -156,22 +159,25 @@ static bool thread_parent_discover_timeout_cb(int8_t interface_id, uint16_t msgI
memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8); memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8);
memcpy(&ll64[8], parent->mac64 , 8); memcpy(&ll64[8], parent->mac64 , 8);
ll64[8] ^= 2; ll64[8] ^= 2;
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_entry_created);
entry_temp = mle_class_get_entry_by_ll64(interface_id, parent->linkMarginToParent,ll64, true, &new_entry_created);
if (entry_temp == NULL) { if (entry_temp == NULL) {
return false; return false;
} }
entry_temp->threadNeighbor = true; thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, parent->linkMarginToParent, new_entry_created);
entry_temp->short_adr = parent->shortAddress; thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
entry_temp->priorityFlag = true;
entry_temp->holdTime = 90; entry_temp->mac16 = parent->shortAddress;
entry_temp->mle_frame_counter = parent->mleFrameCounter; entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
mle_service_frame_counter_entry_add(interface_id, entry_temp->index, parent->mleFrameCounter);
thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence); thread_management_key_sets_calc(cur, linkConfiguration, cur->thread_info->thread_attach_scanned_parent->keySequence);
thread_calculate_key_guard_timer(cur, linkConfiguration, true); thread_key_guard_timer_calculate(cur, linkConfiguration, true);
mac_helper_devicetable_set(entry_temp, cur, parent->linLayerFrameCounter, mac_helper_default_key_index_get(cur), new_entry_created); mlme_device_descriptor_t device_desc;
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,parent->linLayerFrameCounter, false);
mac_helper_devicetable_set(&device_desc, cur,entry_temp->index, mac_helper_default_key_index_get(cur), new_entry_created);
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, THREAD_DEFAULT_LINK_LIFETIME);
if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) { if (cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_SLEEPY_END_DEVICE) {
nwk_thread_host_control(cur, NET_HOST_FAST_POLL_MODE, 50); nwk_thread_host_control(cur, NET_HOST_FAST_POLL_MODE, 50);
@ -284,6 +290,8 @@ void thread_network_attach_start(protocol_interface_info_entry_t *cur)
tr_debug("MLE Parent request"); tr_debug("MLE Parent request");
cur->nwk_bootstrap_state = ER_MLE_SCAN; cur->nwk_bootstrap_state = ER_MLE_SCAN;
cur->bootsrap_state_machine_cnt = 0; cur->bootsrap_state_machine_cnt = 0;
/* advance trickle timer by 6 (in 100ms ticks) seconds if needed */
thread_routing_trickle_advance(&cur->thread_info->routing, 6*10);
} else { } else {
cur->bootsrap_state_machine_cnt = 5; cur->bootsrap_state_machine_cnt = 5;
} }
@ -297,7 +305,7 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
uint16_t address16; uint16_t address16;
uint32_t llFrameCounter; uint32_t llFrameCounter;
thread_leader_data_t leaderData; thread_leader_data_t leaderData;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
bool new_entry_created; bool new_entry_created;
tr_debug("Validate Link Synch Response"); tr_debug("Validate Link Synch Response");
@ -323,31 +331,36 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
thread_management_key_synch_req(cur->id, common_read_32_bit(securityHeader->Keysource)); thread_management_key_synch_req(cur->id, common_read_32_bit(securityHeader->Keysource));
// if learning key sequence from link sync actual guard timer value is not known
thread_key_guard_timer_reset(cur);
} else { } else {
tr_debug("Key ID Mode 2 not used; dropped."); tr_debug("Key ID Mode 2 not used; dropped.");
return -3; return -3;
} }
//Update parent link information //Update parent link information
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, src_address, true, &new_entry_created); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), src_address, true, &new_entry_created);
if (!entry_temp) { if (!entry_temp) {
tr_debug("Neighbor allocate fail"); tr_debug("Neighbor allocate fail");
return -2; return -2;
} }
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
/* /*
*/ */
entry_temp->threadNeighbor = true; entry_temp->mac16 = srcAddress;
entry_temp->short_adr = srcAddress; entry_temp->connected_device = 1;
entry_temp->handshakeReady = 1; entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR; // Make this our parent
entry_temp->holdTime = 90; common_write_16_bit(entry_temp->mac16, shortAddress);
entry_temp->priorityFlag = true; // Make this our parent
common_write_16_bit(entry_temp->short_adr, shortAddress);
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout);
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, securityHeader->KeyIndex, new_entry_created);
mlme_device_descriptor_t device_desc;
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, securityHeader->KeyIndex, new_entry_created);
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
thread_bootstrap_update_ml16_address(cur, address16); thread_bootstrap_update_ml16_address(cur, address16);
@ -377,12 +390,10 @@ static int thread_end_device_synch_response_validate(protocol_interface_info_ent
static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) static void thread_child_synch_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
{ {
(void) interface_id;
tr_debug("Thread MLE message child_synch handler"); tr_debug("Thread MLE message child_synch handler");
//State machine What packet shuold accept in this case //State machine What packet shuold accept in this case
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (!cur) {
return;
}
/* Check that message is from link-local scope */ /* Check that message is from link-local scope */
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
@ -466,10 +477,8 @@ static bool thread_host_prefer_parent_response(protocol_interface_info_entry_t *
*/ */
void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); (void) interface_id;
if (!cur) { protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
return;
}
/* Check that message is from link-local scope */ /* Check that message is from link-local scope */
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
@ -538,8 +547,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) { if (thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH || thread_info(cur)->thread_attached_state == THREAD_STATE_REATTACH_RETRY) {
tr_debug("Reattach"); tr_debug("Reattach");
if (thread_info(cur)->thread_leader_data) { if (thread_info(cur)->thread_leader_data) {
if ((thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) || if (!thread_partition_match(cur, &leaderData)) {
(thread_info(cur)->thread_leader_data->weighting != leaderData.weighting)) {
//accept only same ID at reattach phase //accept only same ID at reattach phase
return; return;
} }
@ -557,8 +565,7 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED || thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED ||
thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) { thread_info(cur)->thread_attached_state == THREAD_STATE_CONNECTED_ROUTER) {
if (thread_info(cur)->thread_leader_data) { if (thread_info(cur)->thread_leader_data) {
if ((thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) && if (thread_partition_match(cur, &leaderData)) {
(thread_info(cur)->thread_leader_data->weighting == leaderData.weighting)) {
//accept only different ID at anyattach phase //accept only different ID at anyattach phase
tr_debug("Drop old partition"); tr_debug("Drop old partition");
return; return;
@ -736,12 +743,9 @@ void thread_mle_parent_discover_receive_cb(int8_t interface_id, mle_message_t *m
static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
{ {
thread_leader_data_t leaderData; thread_leader_data_t leaderData;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
link_configuration_s *link_configuration; link_configuration_s *link_configuration;
if (!cur) {
return;
}
link_configuration = thread_joiner_application_get_config(cur->id); link_configuration = thread_joiner_application_get_config(cur->id);
if (!link_configuration) { if (!link_configuration) {
return; return;
@ -790,17 +794,19 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
thread_merge_prepare(cur); thread_merge_prepare(cur);
// Create entry for new parent // Create entry for new parent
entry_temp = mle_class_get_entry_by_ll64(cur->id, thread_compute_link_margin(mle_msg->dbm), mle_msg->packet_src_address, true, &new_entry_created); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_entry_created);
if (entry_temp == NULL) { if (entry_temp == NULL) {
// todo: what to do here? // todo: what to do here?
return; return;
} }
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, thread_compute_link_margin(mle_msg->dbm), new_entry_created);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
//Parse mandatory TLV's //Parse mandatory TLV's
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) { if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData)) {
return; return;
} }
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->short_adr)) { if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &entry_temp->mac16)) {
return; return;
} }
@ -836,25 +842,24 @@ static void thread_mle_child_request_receive_cb(int8_t interface_id, mle_message
return; return;
} }
common_write_16_bit(entry_temp->short_adr, shortAddress); common_write_16_bit(entry_temp->mac16, shortAddress);
//Update possible reed address by real router address //Update possible reed address by real router address
scan_result->shortAddress = entry_temp->short_adr; scan_result->shortAddress = entry_temp->mac16;
entry_temp->holdTime = 90; entry_temp->connected_device = 1;
entry_temp->handshakeReady = 1; entry_temp->link_role = PRIORITY_PARENT_NEIGHBOUR;
entry_temp->priorityFlag = true;
entry_temp->threadNeighbor = true;
mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress); mac_helper_coordinator_address_set(cur, ADDR_802_15_4_SHORT, shortAddress);
mle_entry_timeout_update(entry_temp, thread_info(cur)->host_link_timeout); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, thread_info(cur)->host_link_timeout);
if (scan_result->security_key_index != security_headers->KeyIndex) { if (scan_result->security_key_index != security_headers->KeyIndex) {
// KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter // KeyIndex has been changed between parent_response and child_id_response, reset link layer frame counter
scan_result->linLayerFrameCounter = 0; scan_result->linLayerFrameCounter = 0;
scan_result->security_key_index = security_headers->KeyIndex; scan_result->security_key_index = security_headers->KeyIndex;
} }
mlme_device_descriptor_t device_desc;
mac_helper_devicetable_set(entry_temp, cur, scan_result->linLayerFrameCounter, security_headers->KeyIndex, new_entry_created); mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,scan_result->linLayerFrameCounter, false);
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created);
thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED; thread_info(cur)->thread_attached_state = THREAD_STATE_CONNECTED;
@ -948,23 +953,26 @@ static int8_t thread_end_device_synch_start(protocol_interface_info_entry_t *cur
void thread_endevice_synch_start(protocol_interface_info_entry_t *cur) void thread_endevice_synch_start(protocol_interface_info_entry_t *cur)
{ {
if (cur->thread_info->thread_endnode_parent) { if (cur->thread_info->thread_endnode_parent) {
mle_neigh_table_entry_t *entry_temp;
bool new_entry_created; bool new_entry_created;
// Add the parent to the MLE neighbor table // Add the parent to the MLE neighbor table
entry_temp = mle_class_get_entry_by_mac64(cur->id, 64, cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created); mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), cur->thread_info->thread_endnode_parent->mac64, true, &new_entry_created);
if (mac_entry) {
//Add link margin 64
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index);
if (entry_temp) { mac_entry->mac16 = cur->thread_info->thread_endnode_parent->shortAddress;
entry_temp->short_adr = cur->thread_info->thread_endnode_parent->shortAddress; mac_entry->connected_device = 1;
entry_temp->handshakeReady = 1;
entry_temp->threadNeighbor = true;
// In case we don't get response to sync; use temporary timeout here, // In case we don't get response to sync; use temporary timeout here,
// Child ID Response handler will set correct value later // Child ID Response handler will set correct value later
mle_entry_timeout_update(entry_temp, 20); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), mac_entry, mac_entry->link_lifetime);
// Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response) // Add the parent to the MAC table (for e.g. secured/fragmented Child Update Response)
mac_helper_devicetable_set(entry_temp, cur, 0, cur->mac_parameters->mac_default_key_index, new_entry_created); mlme_device_descriptor_t device_desc;
mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,0, false);
mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created);
} }
} }
@ -978,10 +986,9 @@ void thread_endevice_synch_start(protocol_interface_info_entry_t *cur)
static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries) static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, bool usedAllRetries)
{ {
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
thread_scanned_parent_t *scanned_parent; thread_scanned_parent_t *scanned_parent;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
uint8_t ll64[16];
(void)msgId; (void)msgId;
@ -1017,15 +1024,17 @@ static bool thread_child_id_req_timeout(int8_t interface_id, uint16_t msgId, boo
tr_debug("Back to old partition"); tr_debug("Back to old partition");
/* If scanned parent is from other partition, delete from MLE table */ /* If scanned parent is from other partition, delete from MLE table */
if (scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) { if ((scanned_parent->leader_data.partitionId != thread_info(cur)->thread_leader_data->partitionId) ||
memcpy(ll64, ADDR_LINK_LOCAL_PREFIX , 8); (scanned_parent->leader_data.weighting != thread_info(cur)->thread_leader_data->weighting)) {
memcpy(&ll64[8], scanned_parent->mac64 , 8); entry_temp = mac_neighbor_table_address_discover(mac_neighbor_info(cur), scanned_parent->mac64, ADDR_802_15_4_LONG);
ll64[8] ^= 2; if (entry_temp) {
bool my_parent = thread_check_is_this_my_parent(cur, entry_temp);
entry_temp = mle_class_get_entry_by_ll64(cur->id, scanned_parent->linkMarginToParent, ll64, false, NULL); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
if (entry_temp && !thread_check_is_this_my_parent(cur, entry_temp)) { if (my_parent) {
// remove scanned_parent entry only if it is not my parent tr_debug("No parent resp - any-attach");
mle_class_remove_entry(cur->id, entry_temp); thread_bootstrap_connection_error(interface_id, CON_ERROR_NETWORK_ATTACH_FAIL, NULL);
goto exit;
}
} }
} }
@ -1159,22 +1168,22 @@ static bool thread_child_update_timeout_cb(int8_t interface_id, uint16_t msgId,
} }
int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64) bool thread_host_bootstrap_child_update(protocol_interface_info_entry_t *cur, const uint8_t *mac64)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
mle_message_timeout_params_t timeout; mle_message_timeout_params_t timeout;
uint8_t mode; uint8_t mode;
uint32_t keySequence; uint32_t keySequence;
if (!cur->thread_info->thread_endnode_parent) { if (!cur->thread_info->thread_endnode_parent) {
return -1; tr_debug("Not end device parent info for NUD");
return false;
} }
if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) { if (cur->thread_info->thread_endnode_parent->childUpdateProcessActive) {
//Set Pending if earlier process is already started //Set Pending if earlier process is already started
cur->thread_info->thread_endnode_parent->childUpdatePending = true; cur->thread_info->thread_endnode_parent->childUpdatePending = true;
return -1; return false;
} }
//Trig event //Trig event
cur->thread_info->thread_endnode_parent->childUpdatePending = false; cur->thread_info->thread_endnode_parent->childUpdatePending = false;
@ -1189,7 +1198,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma
uint16_t bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false, MLE_COMMAND_CHILD_UPDATE_REQUEST); uint16_t bufId = mle_service_msg_allocate(cur->id, 150 + 3 + 6 + 10, false, MLE_COMMAND_CHILD_UPDATE_REQUEST);
if (bufId == 0) { if (bufId == 0) {
return -1; return false;
} }
thread_management_get_current_keysequence(cur->id, &keySequence); thread_management_get_current_keysequence(cur->id, &keySequence);
@ -1228,7 +1237,7 @@ int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *ma
mle_service_set_msg_timeout_parameters(bufId, &timeout); mle_service_set_msg_timeout_parameters(bufId, &timeout);
mle_service_send_message(bufId); mle_service_send_message(bufId);
return 0; return true;
} }
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge) int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge)
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -42,7 +42,7 @@ struct protocol_interface_info_entry;
struct mle_security_header; struct mle_security_header;
void thread_network_attach_start(struct protocol_interface_info_entry *cur); void thread_network_attach_start(struct protocol_interface_info_entry *cur);
int8_t thread_host_bootstrap_child_update(int8_t interface_id, const uint8_t *mac64); bool thread_host_bootstrap_child_update(struct protocol_interface_info_entry *cur, const uint8_t *mac64);
int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge); int thread_host_bootstrap_child_update_negative_response(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, mle_tlv_info_t *challenge);
void thread_child_set_default_route(struct protocol_interface_info_entry *cur); void thread_child_set_default_route(struct protocol_interface_info_entry *cur);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -778,8 +778,8 @@ static bool thread_joiner_application_validate_settings(thread_joiner_t *this)
new_value_generated = 1; new_value_generated = 1;
tr_info("Generating Random ML-EID"); tr_info("Generating Random ML-EID");
} }
if (this->configuration_ptr->key_rotation < 3600) { if (this->configuration_ptr->key_rotation < 1) {
this->configuration_ptr->key_rotation = 3600; this->configuration_ptr->key_rotation = 1;
} }
return new_value_generated; return new_value_generated;
} }
@ -967,17 +967,12 @@ static int thread_joiner_application_nvm_link_config_read(thread_joiner_t *this)
this->configuration_valid = true; this->configuration_valid = true;
link_configuration_trace(this->configuration_ptr); link_configuration_trace(this->configuration_ptr);
//Add Security to MLE service
uint8_t key_material[32];
uint8_t key_index;
//Define KEY's
thread_key_get(this->configuration_ptr->master_key, key_material, this->configuration_ptr->key_sequence);
key_index = THREAD_KEY_INDEX(this->configuration_ptr->key_sequence);
//Set Keys
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(this->interface_id);
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); //Add Security to MLE service
mle_service_security_set_security_key(this->interface_id, key_material, key_index, true); thread_security_prev_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
thread_security_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
thread_security_next_key_generate(cur,this->configuration_ptr->master_key,this->configuration_ptr->key_sequence);
// update counters // update counters
mle_service_security_set_frame_counter(this->interface_id, fast_data.mle_frame_counter); mle_service_security_set_frame_counter(this->interface_id, fast_data.mle_frame_counter);
mac_helper_link_frame_counter_set(this->interface_id, fast_data.mac_frame_counter); mac_helper_link_frame_counter_set(this->interface_id, fast_data.mac_frame_counter);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -414,7 +414,7 @@ static int thread_leader_service_active_set_cb(int8_t service_id, uint8_t source
} }
} }
if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) { if (3 <= thread_meshcop_tlv_find(request_ptr->payload_ptr, request_ptr->payload_len, MESHCOP_TLV_SECURITY_POLICY, &ptr)) {
if (common_read_16_bit(ptr) < 3600) { if (common_read_16_bit(ptr) < 1) {
tr_warn("invalid security policy"); tr_warn("invalid security policy");
ret = -1; ret = -1;
goto send_response; goto send_response;
@ -1090,7 +1090,7 @@ static int thread_leader_service_petition_cb(int8_t service_id, uint8_t source_a
ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff); ptr = thread_meshcop_tlv_data_write_uint8(ptr, MESHCOP_TLV_STATE, 0xff);
} }
tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr, session_id, ret); tr_debug("Petition req recv id %s, RESP session id: %d ret %d", commissioner_id_ptr ? commissioner_id_ptr : "(none)", session_id, ret);
send_error_response: send_error_response:
coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload); coap_service_response_send(this->coap_service_id, COAP_REQUEST_OPTIONS_NONE, request_ptr, response_code, COAP_CT_OCTET_STREAM, payload, ptr - payload);
@ -1346,7 +1346,7 @@ static void thread_leader_service_interface_setup_activate(protocol_interface_in
thread_leader_service_private_routemask_init(private); thread_leader_service_private_routemask_init(private);
//SET Router ID //SET Router ID
thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac); thread_leader_allocate_router_id_by_allocated_id(private, routerId, cur->mac);
thread_old_partition_data_purge(cur); thread_partition_data_purge(cur);
// remove any existing rloc mapping in nvm // remove any existing rloc mapping in nvm
thread_nvm_store_mleid_rloc_map_remove(); thread_nvm_store_mleid_rloc_map_remove();
cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS; cur->lowpan_address_mode = NET_6LOWPAN_GP16_ADDRESS;
@ -1526,7 +1526,7 @@ void thread_leader_service_timer(protocol_interface_info_entry_t *cur, uint32_t
cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD; cur->thread_info->leader_private_data->leader_id_seq_timer = ID_SEQUENCE_PERIOD;
thread_leader_service_update_id_set(cur); thread_leader_service_update_id_set(cur);
thread_network_data_context_re_use_timer_update(&cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts); thread_network_data_context_re_use_timer_update(cur->id, &cur->thread_info->networkDataStorage, 10, &cur->lowpan_contexts);
// Send update to network data if needed // Send update to network data if needed
thread_leader_service_network_data_changed(cur, false, false); thread_leader_service_network_data_changed(cur, false, false);
} }
@ -1621,7 +1621,6 @@ void thread_leader_service_thread_partitition_generate(int8_t interface_id, bool
//memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8); //memset(cur->thread_info->lastValidRouteMask, 0, (N_THREAD_ROUTERS+7)/8);
//SET SHort Address & PAN-ID //SET SHort Address & PAN-ID
cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE; cur->lowpan_info &= ~INTERFACE_NWK_CONF_MAC_RX_OFF_IDLE;
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true); mac_helper_pib_boolean_set(cur, macRxOnWhenIdle, true);
cur->interface_mode = INTERFACE_UP; cur->interface_mode = INTERFACE_UP;
cur->nwk_mode = ARM_NWK_GP_IP_MODE; cur->nwk_mode = ARM_NWK_GP_IP_MODE;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -146,6 +146,8 @@ void thread_management_client_init(int8_t interface_id)
if (this) { if (this) {
this->network_data_set_cb_ptr = NULL; this->network_data_set_cb_ptr = NULL;
this->router_id_release_cb_ptr = NULL;
this->neighbor_discovery_cb_ptr = NULL;
this->router_id_cb_ptr = NULL; this->router_id_cb_ptr = NULL;
this->interface_id = interface_id; this->interface_id = interface_id;
this->coap_asd_msg_id = 0; this->coap_asd_msg_id = 0;
@ -333,6 +335,15 @@ static int thread_management_client_neighbor_discovery_data_cb(int8_t service_id
return 0; return 0;
} }
int thread_management_client_get_interface_id_by_service_id(int8_t service_id)
{
thread_management_t *this = thread_management_find_by_service(service_id);
if (!this) {
return -1;
}
return this->interface_id;
}
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb) int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb)
{ {
thread_management_t *this = thread_management_find(interface_id); thread_management_t *this = thread_management_find(interface_id);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -148,6 +148,15 @@ int thread_management_client_network_data_unregister(int8_t interface_id, uint16
*/ */
int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb); int thread_management_client_neighbor_discovery_data_request(int8_t interface_id, const uint8_t destination[16], const uint8_t *options, uint8_t options_len, thread_management_client_network_data_set_cb *set_cb);
/** Get interface_id of based on coap service_id
*
*
* /param service_id coap service id.
*
*return interface_id of thread instance if successful and -1 for failure
*/
int thread_management_client_get_interface_id_by_service_id(int8_t service_id);
/** send active configuration dataset get for parent /** send active configuration dataset get for parent
* *
* /param interface_id interface id of this thread instance. * /param interface_id interface id of this thread instance.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -62,6 +62,7 @@
#include "6LoWPAN/Thread/thread_tmfcop_lib.h" #include "6LoWPAN/Thread/thread_tmfcop_lib.h"
#include "6LoWPAN/Thread/thread_constants.h" #include "6LoWPAN/Thread/thread_constants.h"
#include "6LoWPAN/Thread/thread_extension_bootstrap.h" #include "6LoWPAN/Thread/thread_extension_bootstrap.h"
#include "6LoWPAN/Thread/thread_extension.h"
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
#include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up #include "RPL/rpl_control.h" // insanity - bootstraps shouldn't be doing each others' clean-up
#include "MLE/mle.h" #include "MLE/mle.h"
@ -77,7 +78,9 @@
#include "Service_Libs/blacklist/blacklist.h" #include "Service_Libs/blacklist/blacklist.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mac_pairwise_key.h" #include "6LoWPAN/MAC/mac_pairwise_key.h"
#include "6LoWPAN/MAC/mpx_api.h"
#include "6LoWPAN/lowpan_adaptation_interface.h" #include "6LoWPAN/lowpan_adaptation_interface.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "mac_common_defines.h" #include "mac_common_defines.h"
#include "mlme.h" #include "mlme.h"
#include "mac_api.h" #include "mac_api.h"
@ -307,68 +310,6 @@ void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_seque
SHALIB_finish_HMAC(key_material_buf, 8); SHALIB_finish_HMAC(key_material_buf, 8);
} }
/**
* Increment Thread key sequence counter
*
* \param interface_id Network Interface
*
* return 0, ADD OK
* return <0 Add Not OK
*/
uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId)
{
protocol_interface_info_entry_t *cur;
uint8_t *keyPtr = NULL;
link_configuration_s *linkConfiguration;
linkConfiguration = thread_joiner_application_get_config(interface_id);
if (!linkConfiguration) {
return NULL;
}
cur = protocol_stack_interface_info_get_by_id(interface_id);
if (cur && cur->thread_info) {
if (cur->thread_info->masterSecretMaterial.valid_Info) {
if (cur->thread_info->masterSecretMaterial.historyKeyValid && (cur->thread_info->masterSecretMaterial.historyKeyId == keyId)) {
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
} else {
uint32_t thrSequenceCounter;
uint8_t compId = 0xff, keyIdDiff;
thrSequenceCounter = linkConfiguration->key_sequence + 1;
//Calculate Current Next key ID
compId = THREAD_KEY_INDEX(thrSequenceCounter);
if (keyId > compId) {
keyIdDiff = (keyId - compId);
} else {
keyIdDiff = (128 - (compId - keyId));
}
if (keyIdDiff > 64) {
//Calc Temp Key
thrSequenceCounter -= (128 - keyIdDiff);
tr_debug("Gen temporary key id %"PRIu8" seq %"PRIu32, keyId, thrSequenceCounter);
thread_key_get(linkConfiguration->master_key, cur->thread_info->masterSecretMaterial.historyKey, thrSequenceCounter);
cur->thread_info->masterSecretMaterial.historyKeyId = keyId;
cur->thread_info->masterSecretMaterial.historyKeyValid = true;
keyPtr = cur->thread_info->masterSecretMaterial.historyKey;
} else {
tr_debug("Gen new key id %"PRIu8" %"PRIu8" diff", keyId, keyIdDiff);
thrSequenceCounter += keyIdDiff;
//Generate
tr_debug("Missed n key Update...generated missed key %"PRIu8" update by seq %"PRIu32, keyIdDiff, thrSequenceCounter);
thread_management_key_sets_calc(cur, linkConfiguration, thrSequenceCounter);
//Get Default key
keyPtr = mle_service_security_default_key_get(interface_id);
}
thread_nvm_store_seq_counter_write(linkConfiguration->key_sequence);
}
}
}
return keyPtr;
}
/** /**
* Thread key sequence & key synch * Thread key sequence & key synch
* *
@ -381,22 +322,32 @@ void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce)
if (!linkConfiguration) { if (!linkConfiguration) {
return; return;
} }
cur = protocol_stack_interface_info_get_by_id(interface_id); cur = protocol_stack_interface_info_get_by_id(interface_id);
if (cur && cur->thread_info) { if (!cur || !cur->thread_info) {
if (cur->thread_info->masterSecretMaterial.valid_Info) { return;
if (keySequnce != linkConfiguration->key_sequence) {
if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer == 0 && keySequnce > linkConfiguration->key_sequence)) {
tr_debug("Sync key material by %"PRIu32, keySequnce);
thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
thread_calculate_key_guard_timer(cur, linkConfiguration, false);
}
}
}
} }
if (!cur->thread_info->masterSecretMaterial.valid_Info) {
return;
}
//tr_debug("Sync key material by %"PRIu32, keySequnce);
if (keySequnce <= linkConfiguration->key_sequence) {
// Smaller or equal request ignored
//tr_debug("Sync key material no change");
return;
}
if ((cur->thread_info->masterSecretMaterial.keySwitchGuardTimer > 0)) {
// Guard time prevent the change
//tr_debug("Sync key material guard blocked");
return;
}
// Calculate new keys
tr_debug("Sync key material by %"PRIu32, keySequnce);
thread_management_key_sets_calc(cur, linkConfiguration, keySequnce);
thread_key_guard_timer_calculate(cur, linkConfiguration, false);
} }
void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId) static void thread_history_key_material_push(thread_info_t *thread_info, uint8_t *mleKeyPtr, uint8_t keyId)
{ {
thread_info->masterSecretMaterial.historyKeyValid = true; thread_info->masterSecretMaterial.historyKeyValid = true;
thread_info->masterSecretMaterial.historyKeyId = keyId; thread_info->masterSecretMaterial.historyKeyId = keyId;
@ -424,7 +375,7 @@ void thread_security_update_from_mac(protocol_interface_info_entry_t *cur)
linkConfiguration->key_sequence++; linkConfiguration->key_sequence++;
mac_helper_link_frame_counter_set(cur->id, 0); mac_helper_link_frame_counter_set(cur->id, 0);
thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence); thread_security_next_key_generate(cur, linkConfiguration->master_key, linkConfiguration->key_sequence);
thread_calculate_key_guard_timer(cur, linkConfiguration, false); thread_key_guard_timer_calculate(cur, linkConfiguration, false);
} }
void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
@ -437,11 +388,33 @@ void thread_security_key_generate(protocol_interface_info_entry_t *cur, uint8_t
thread_key_get(masterKey, key_material, thrKeySequenceCounter); thread_key_get(masterKey, key_material, thrKeySequenceCounter);
/* Update keys as primary keys */ /* Update keys as primary keys */
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter); key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
tr_debug("Set key Id: %u", key_index); tr_debug("Set current key Id: %u", key_index);
mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); mac_helper_security_default_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
mle_service_security_set_security_key(cur->id, key_material, key_index, true); mle_service_security_set_security_key(cur->id, key_material, key_index, true);
} }
void thread_security_prev_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
{
uint8_t key_material[32];
uint8_t key_index;
uint32_t thrKeySequenceCounter;
if (keySequence == 0) {
// in initial value there is no prev available
return;
}
thrKeySequenceCounter = keySequence - 1;
/* Produced keys from Thread security material: MAC key | MLE key */
thread_key_get(masterKey, key_material, thrKeySequenceCounter);
/* Update keys as primary keys */
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
tr_debug("Set previous key Id: %u", key_index);
mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX);
mle_service_security_set_security_key(cur->id, key_material, key_index, false);
//copy master secret material to history
thread_history_key_material_push(cur->thread_info, key_material, key_index);
}
void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence) void thread_security_next_key_generate(protocol_interface_info_entry_t *cur, uint8_t *masterKey, uint32_t keySequence)
{ {
uint8_t key_material[32]; uint8_t key_material[32];
@ -471,31 +444,17 @@ int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_c
ret_val = 0; ret_val = 0;
} else { } else {
/* Generate new key set */ /* Generate new key set */
uint8_t key_material[32];
uint8_t key_index;
thread_nvm_fast_data_t fast_data;
//SET History key, Current Key & Next Key
//Generate History Key
//Clean All Keys //Clean All Keys
mac_helper_security_key_clean(cur); mac_helper_security_key_clean(cur);
thrKeySequenceCounter--;
/* Update keys as non-primary keys */
thread_key_get(linkConfiguration->master_key, key_material, thrKeySequenceCounter);
key_index = THREAD_KEY_INDEX(thrKeySequenceCounter);
//copy master secret material to history
memcpy(cur->thread_info->masterSecretMaterial.historyKey, key_material, 32);
cur->thread_info->masterSecretMaterial.historyKeyId = key_index;
cur->thread_info->masterSecretMaterial.historyKeyValid = true;
mac_helper_security_prev_key_set(cur, &key_material[16], key_index, MAC_KEY_ID_MODE_IDX); // Update key sequence
//Set New Active Key
thrKeySequenceCounter++;
linkConfiguration->key_sequence = thrKeySequenceCounter; linkConfiguration->key_sequence = thrKeySequenceCounter;
fast_data.seq_counter = thrKeySequenceCounter; // Zero all frame counters. MLE does it automatically
fast_data.mac_frame_counter = 0;
fast_data.mle_frame_counter = mle_service_security_get_frame_counter(cur->interface_mode);
thread_nvm_store_fast_data_write(&fast_data);
mac_helper_link_frame_counter_set(cur->id, 0); mac_helper_link_frame_counter_set(cur->id, 0);
// Store all frame counters as zero and update the sequence counter
thread_nvm_store_fast_data_write_all(0, 0, thrKeySequenceCounter);
thread_security_prev_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); thread_security_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence); thread_security_next_key_generate(cur,linkConfiguration->master_key,linkConfiguration->key_sequence);
ret_val = 0; ret_val = 0;
@ -790,12 +749,23 @@ int thread_dhcpv6_server_delete(int8_t interface_id, uint8_t *prefix_ptr)
} }
#ifdef HAVE_THREAD #ifdef HAVE_THREAD
static mac_neighbor_table_entry_t *neighbor_data_poll_referesh(protocol_interface_info_entry_t *cur, const uint8_t *address, addrtype_t type)
{
mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), address, type);
if (!entry || !entry->connected_device) {
return NULL;
}
entry->lifetime = entry->link_lifetime;
return entry;
}
void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status) void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* status)
{ {
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id); protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(if_id);
if (!cur) { if (!cur) {
return; return;
} }
mac_neighbor_table_entry_t *entry;
switch (status->status) { switch (status->status) {
@ -808,7 +778,10 @@ void thread_comm_status_indication_cb(int8_t if_id, const mlme_comm_status_t* st
break; break;
case MLME_DATA_POLL_NOTIFICATION: case MLME_DATA_POLL_NOTIFICATION:
mle_refresh_entry_timeout(if_id, status->SrcAddr, (addrtype_t)status->SrcAddrMode, false); entry = neighbor_data_poll_referesh(cur, status->SrcAddr, (addrtype_t)status->SrcAddrMode);
if (entry) {
thread_neighbor_communication_update(cur, entry->index);
}
break; break;
default: default:
break; break;
@ -908,7 +881,7 @@ int thread_management_node_init(
scan_params->scan_duration = 5; scan_params->scan_duration = 5;
cur->thread_info->masterSecretMaterial.valid_Info = false; cur->thread_info->masterSecretMaterial.valid_Info = false;
thread_calculate_key_guard_timer(cur, static_configuration, true); thread_key_guard_timer_calculate(cur, static_configuration, true);
cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT; cur->thread_info->maxChildCount = THREAD_MAX_CHILD_COUNT;
cur->thread_info->rfc6775 = false; cur->thread_info->rfc6775 = false;
@ -1439,10 +1412,21 @@ int thread_management_partition_weighting_set(int8_t interface_id, uint8_t parti
return 0; return 0;
} }
bool trig_network_scan = false;
if (cur->thread_info->thread_leader_data) {
if (cur->thread_info->thread_leader_data->weighting < partition_weighting) {
trig_network_scan = true;
}
}
cur->thread_info->partition_weighting = partition_weighting; cur->thread_info->partition_weighting = partition_weighting;
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
// bootstrap active and weighting has changed if (trig_network_scan && thread_extension_enabled(cur)) {
thread_bootstrap_reset_restart(interface_id); thread_nvm_store_link_info_clear();
// bootstrap active and weighting has changed
thread_bootstrap_reset_restart(interface_id);
}
} }
return 0; return 0;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -77,15 +77,13 @@ int thread_management_increment_key_sequence_counter(int8_t interface_id);
int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter); int thread_management_key_sets_calc(protocol_interface_info_entry_t *cur, link_configuration_s *linkConfiguration, uint32_t thrKeySequenceCounter);
uint8_t *thread_management_key_request(int8_t interface_id, uint8_t keyId);
void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce); void thread_management_key_synch_req(int8_t interface_id, uint32_t keySequnce);
uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce); uint8_t *thread_management_key_request_with_sequence(int8_t interface_id, uint8_t keyId, uint32_t keySequnce);
void thread_security_update_from_mac(struct protocol_interface_info_entry *cur); void thread_security_update_from_mac(struct protocol_interface_info_entry *cur);
void thread_history_key_material_push(struct thread_info_s *thread_info, uint8_t *mleKeyPtr, uint8_t keyId); void thread_security_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
void thread_security_prev_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
void thread_security_next_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence); void thread_security_next_key_generate(struct protocol_interface_info_entry *cur, uint8_t *masterKey, uint32_t keySequence);
void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter); void thread_key_get(uint8_t *key, uint8_t *key_material_buf, uint32_t key_sequence_counter);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -1159,7 +1159,6 @@ int thread_management_server_init(int8_t interface_id)
} }
#endif #endif
thread_extension_init(interface_id, this->coap_service_id); thread_extension_init(interface_id, this->coap_service_id);
// All thread devices // All thread devices
coap_service_register_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_management_server_get_command_cb); coap_service_register_uri(this->coap_service_id, THREAD_URI_MANAGEMENT_GET, COAP_SERVICE_ACCESS_GET_ALLOWED, thread_management_server_get_command_cb);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,6 +38,7 @@
#include "6LoWPAN/Thread/thread_config.h" #include "6LoWPAN/Thread/thread_config.h"
#include "6LoWPAN/Thread/thread_common.h" #include "6LoWPAN/Thread/thread_common.h"
#include "6LoWPAN/Thread/thread_lowpower_private_api.h" #include "6LoWPAN/Thread/thread_lowpower_private_api.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "6LoWPAN/Thread/thread_mle_message_handler.h" #include "6LoWPAN/Thread/thread_mle_message_handler.h"
#include "6LoWPAN/Thread/thread_bootstrap.h" #include "6LoWPAN/Thread/thread_bootstrap.h"
#include "6LoWPAN/Thread/thread_management_internal.h" #include "6LoWPAN/Thread/thread_management_internal.h"
@ -48,13 +49,15 @@
#include "6LoWPAN/Thread/thread_extension.h" #include "6LoWPAN/Thread/thread_extension.h"
#include "6LoWPAN/Thread/thread_router_bootstrap.h" #include "6LoWPAN/Thread/thread_router_bootstrap.h"
#include "6LoWPAN/Thread/thread_network_synch.h" #include "6LoWPAN/Thread/thread_network_synch.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "mac_api.h" #include "mac_api.h"
#define TRACE_GROUP "thmh" #define TRACE_GROUP "thmh"
static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, uint8_t *router_ll64); static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, uint8_t *router_ll64);
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor); static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor);
static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin); static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData); static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread_leader_data_t *leaderData);
static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin); static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, uint8_t linkMargin);
@ -72,11 +75,7 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
* and MUST be discarded. * and MUST be discarded.
*/ */
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (!cur) {
return;
}
/* Check that message is from link-local scope */ /* Check that message is from link-local scope */
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
@ -100,11 +99,11 @@ void thread_general_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg,
} }
case MLE_COMMAND_REJECT: { case MLE_COMMAND_REJECT: {
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
tr_warn("Reject Link"); tr_warn("Reject Link");
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) { if (entry_temp) {
mle_class_remove_entry(cur->id, entry_temp); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
} }
break; break;
} }
@ -159,16 +158,11 @@ static void thread_save_leader_data(protocol_interface_info_entry_t *cur, thread
requestNetworkdata = true; requestNetworkdata = true;
} }
if (thread_info(cur)->thread_leader_data->partitionId != leaderData->partitionId) { if (!thread_partition_match(cur, leaderData)) {
requestNetworkdata = true; requestNetworkdata = true;
thread_info(cur)->thread_leader_data->stableDataVersion = leaderData->stableDataVersion - 1; thread_partition_info_update(cur, leaderData);
thread_info(cur)->thread_leader_data->dataVersion = leaderData->dataVersion - 1;
} }
thread_info(cur)->thread_leader_data->partitionId = leaderData->partitionId;
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData->leaderRouterId;
thread_info(cur)->thread_leader_data->weighting = leaderData->weighting;
if (requestNetworkdata) { if (requestNetworkdata) {
thread_bootstrap_parent_network_data_request(cur, false); thread_bootstrap_parent_network_data_request(cur, false);
} else { } else {
@ -215,12 +209,12 @@ static int8_t thread_link_request_start(protocol_interface_info_entry_t *cur, ui
return 0; return 0;
} }
static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mle_neigh_table_entry_t *neighbor) static bool thread_router_leader_data_process(protocol_interface_info_entry_t *cur, uint8_t *src_address, thread_leader_data_t *leaderData, mle_tlv_info_t *routeTlv, mac_neighbor_table_entry_t *neighbor)
{ {
int leaderDataUpdate = thread_leader_data_validation(cur, leaderData, routeTlv); int leaderDataUpdate = thread_leader_data_validation(cur, leaderData, routeTlv);
if (leaderDataUpdate == 1) { if (leaderDataUpdate == 1) {
if (neighbor && neighbor->handshakeReady == 1) { if (neighbor && neighbor->connected_device == 1) {
// Request network data if we have a 2-way link // Request network data if we have a 2-way link
tr_debug("Request New Network Data from %s", trace_ipv6(src_address)); tr_debug("Request New Network Data from %s", trace_ipv6(src_address));
thread_network_data_request_send(cur, src_address, true); thread_network_data_request_send(cur, src_address, true);
@ -272,30 +266,32 @@ static bool thread_router_advertiment_tlv_analyze(uint8_t *ptr, uint16_t data_le
return true; return true;
} }
static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mle_neigh_table_entry_t *entry_temp, uint16_t short_address) static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg, mle_security_header_t *security_headers, mac_neighbor_table_entry_t *entry_temp, uint16_t short_address)
{ {
if (!entry_temp) { if (!entry_temp) {
return; return;
} }
uint8_t linkMargin = thread_compute_link_margin(mle_msg->dbm);
mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex); mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex);
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
if (!thread_attach_active_router(cur) && !thread_check_is_this_my_parent(cur, entry_temp)) { if (!thread_attach_active_router(cur) && !thread_check_is_this_my_parent(cur, entry_temp)) {
mle_entry_timeout_refresh(entry_temp); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
} else {
entry_temp->last_contact_time = protocol_core_monotonic_time;
} }
if (short_address != entry_temp->short_adr) { if (short_address != entry_temp->mac16) {
if (thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) { if (thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) {
thread_dynamic_storage_child_info_clear(cur->id, entry_temp); thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
} }
entry_temp->short_adr = short_address; entry_temp->mac16 = short_address;
/* throw MLME_GET request, short address is changed automatically in get request callback */ /* throw MLME_GET request, short address is changed automatically in get request callback */
mlme_get_t get_req; mlme_get_t get_req;
get_req.attr = macDeviceTable; get_req.attr = macDeviceTable;
get_req.attr_index = entry_temp->attribute_index; get_req.attr_index = entry_temp->index;
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
} }
@ -304,11 +300,6 @@ static void thread_update_mle_entry(protocol_interface_info_entry_t *cur, mle_me
static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address) static bool thread_parse_advertisement_from_parent(protocol_interface_info_entry_t *cur, thread_leader_data_t *leader_data, uint16_t short_address)
{ {
if ((thread_info(cur)->thread_leader_data->partitionId != leader_data->partitionId) ||
(thread_info(cur)->thread_leader_data->weighting != leader_data->weighting)) {
//parent changed partition/weight - reset own routing information
thread_old_partition_data_purge(cur);
}
//check if network data needs to be requested //check if network data needs to be requested
if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) { if (!thread_bootstrap_request_network_data(cur, leader_data, short_address)) {
tr_debug("Parent short address changed - re-attach"); tr_debug("Parent short address changed - re-attach");
@ -323,7 +314,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
{ {
mle_tlv_info_t routeTlv; mle_tlv_info_t routeTlv;
thread_leader_data_t leaderData; thread_leader_data_t leaderData;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
uint16_t shortAddress; uint16_t shortAddress;
bool adv_from_my_partition; bool adv_from_my_partition;
bool my_parent; bool my_parent;
@ -342,12 +333,16 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
} }
// Get MLE entry // Get MLE entry
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) {
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
}
// Check if this is from my parent // Check if this is from my parent
my_parent = thread_check_is_this_my_parent(cur, entry_temp); my_parent = thread_check_is_this_my_parent(cur, entry_temp);
adv_from_my_partition = thread_instance_id_matches(cur, &leaderData); adv_from_my_partition = thread_partition_match(cur, &leaderData);
if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) { if ((security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) && adv_from_my_partition) {
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
@ -355,13 +350,14 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
if (entry_temp && !adv_from_my_partition && !my_parent ) { if (entry_temp && !adv_from_my_partition && !my_parent ) {
// Remove MLE entry that are located in other partition and is not my parent // Remove MLE entry that are located in other partition and is not my parent
mle_class_remove_entry(cur->id, entry_temp); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
entry_temp = NULL; entry_temp = NULL;
} }
/* Check parent status */ /* Check parent status */
if (!thread_attach_active_router(cur) && my_parent) { if (!thread_attach_active_router(cur) && my_parent) {
if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) { if (!thread_parse_advertisement_from_parent(cur, &leaderData, shortAddress)) {
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
return; return;
} }
} }
@ -374,7 +370,7 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
/* REED and FED */ /* REED and FED */
if (!thread_attach_active_router(cur)) { if (!thread_attach_active_router(cur)) {
/* Check if advertisement is from same partition */ /* Check if advertisement is from same partition */
if (thread_info(cur)->thread_leader_data->weighting == leaderData.weighting && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId ) { if (thread_partition_match(cur, &leaderData)) {
if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) { if (!entry_temp && thread_bootstrap_link_create_check(cur, shortAddress) && thread_bootstrap_link_create_allowed(cur, shortAddress, mle_msg->packet_src_address)) {
// Create link to new neighbor no other processing allowed // Create link to new neighbor no other processing allowed
thread_link_request_start(cur, mle_msg->packet_src_address); thread_link_request_start(cur, mle_msg->packet_src_address);
@ -404,9 +400,8 @@ static void thread_parse_advertisement(protocol_interface_info_entry_t *cur, mle
} }
// Process route TLV // Process route TLV
if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) && if ((entry_temp && routeTlv.dataPtr && routeTlv.tlvLen) && thread_partition_match(cur, &leaderData)){
(thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId)){ tr_debug("Update Route TLV %x", entry_temp->mac16);
tr_debug("Update Route TLV %x", entry_temp->short_adr);
thread_router_bootstrap_route_tlv_push(cur, routeTlv.dataPtr, routeTlv.tlvLen , linkMargin, entry_temp); thread_router_bootstrap_route_tlv_push(cur, routeTlv.dataPtr, routeTlv.tlvLen , linkMargin, entry_temp);
} }
} }
@ -417,7 +412,7 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
uint16_t version, shortAddress; uint16_t version, shortAddress;
uint16_t messageId; uint16_t messageId;
uint8_t linkMarginfronNeigh; uint8_t linkMarginfronNeigh;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
bool createNew, new_entry_created; bool createNew, new_entry_created;
tr_info("MLE LINK ACCEPT"); tr_info("MLE LINK ACCEPT");
@ -444,12 +439,14 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
/* Call to determine whether or not we should create a new link */ /* Call to determine whether or not we should create a new link */
createNew = thread_bootstrap_link_create_check(cur, shortAddress); createNew = thread_bootstrap_link_create_check(cur, shortAddress);
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry_created); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry_created);
if (!entry_temp) { if (!entry_temp) {
thread_link_reject_send(cur, mle_msg->packet_src_address); thread_link_reject_send(cur, mle_msg->packet_src_address);
return; return;
} }
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_entry_created);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
@ -460,32 +457,35 @@ static void thread_parse_accept(protocol_interface_info_entry_t *cur, mle_messag
mleFrameCounter = llFrameCounter; mleFrameCounter = llFrameCounter;
} }
entry_temp->threadNeighbor = true; entry_temp->mac16 = shortAddress;
entry_temp->short_adr = shortAddress; mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter);
entry_temp->mle_frame_counter = mleFrameCounter;
// Set full data as REED needs full data and SED will not make links // Set full data as REED needs full data and SED will not make links
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
mlme_device_descriptor_t device_desc;
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry_created);
uint32_t timeout;
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry_created); if (new_entry_created) {
timeout = THREAD_DEFAULT_LINK_LIFETIME;
if (entry_temp->timeout_rx) {
mle_entry_timeout_refresh(entry_temp);
} else { } else {
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); timeout = entry_temp->link_lifetime;
} }
if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->short_adr)) { mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
if (thread_i_am_router(cur) && thread_is_router_addr(entry_temp->mac16)) {
// If we both are routers, mark the link as 2-way // If we both are routers, mark the link as 2-way
entry_temp->handshakeReady = 1; entry_temp->connected_device = 1;
tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->handshakeReady); tr_debug("Marked link as 2-way, handshakeReady=%d", entry_temp->connected_device);
} else { } else {
tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->handshakeReady); tr_debug("Marked link as 1-way, handshakeReady=%d", entry_temp->connected_device);
} }
blacklist_update(mle_msg->packet_src_address, true); blacklist_update(mle_msg->packet_src_address, true);
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) { if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
} }
} }
static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg) static void thread_parse_annoucement(protocol_interface_info_entry_t *cur, mle_message_t *mle_msg)
@ -544,7 +544,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
mle_tlv_info_t ConfigurationTlv; mle_tlv_info_t ConfigurationTlv;
uint64_t active_timestamp = 0; uint64_t active_timestamp = 0;
uint64_t pending_timestamp = 0;// means no pending timestamp uint64_t pending_timestamp = 0;// means no pending timestamp
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
bool accept_new_data = false; bool accept_new_data = false;
bool leaderDataReceived; bool leaderDataReceived;
@ -560,7 +560,12 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
return; return;
} }
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) {
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
}
if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER || if(cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER ||
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) { cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_FULL_END_DEVICE) {
@ -570,7 +575,7 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
return; return;
} }
} else { } else {
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { if (!thread_partition_match(cur, &leaderData)) {
// if receiving data response from different partition it is dropped // if receiving data response from different partition it is dropped
return; return;
} }
@ -583,10 +588,8 @@ static void thread_parse_data_response(protocol_interface_info_entry_t *cur, mle
} }
} }
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { if (!thread_partition_match(cur, &leaderData)) {
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId; thread_partition_info_update(cur, &leaderData);
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
thread_old_partition_data_purge(cur);
accept_new_data = true; accept_new_data = true;
} }
@ -705,11 +708,11 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
mle_tlv_info_t tlv_req; mle_tlv_info_t tlv_req;
uint64_t active_timestamp = 0; uint64_t active_timestamp = 0;
uint64_t pending_timestamp = 0;// means no pending timestamp uint64_t pending_timestamp = 0;// means no pending timestamp
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
bool data_request_needed = false; bool data_request_needed = false;
tr_debug("Child update request"); tr_debug("Child update request");
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) || if (!thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData) ||
!entry_temp || !entry_temp ||
@ -718,14 +721,16 @@ static void thread_host_child_update_request_process(protocol_interface_info_ent
tr_warn("invalid message"); tr_warn("invalid message");
return; return;
} }
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv); mle_tlv_read_tlv(MLE_TYPE_CHALLENGE, mle_msg->data_ptr, mle_msg->data_length, &challengeTlv);
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req); mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
// Check if partition changed // Check if partition changed
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { if (!thread_partition_match(cur, &leaderData)) {
thread_info(cur)->thread_leader_data->leaderRouterId = leaderData.leaderRouterId; thread_partition_info_update(cur, &leaderData);
thread_info(cur)->thread_leader_data->partitionId = leaderData.partitionId;
thread_old_partition_data_purge(cur);
} }
//Check Network Data TLV //Check Network Data TLV
if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) { if (mle_tlv_read_tlv(MLE_TYPE_NETWORK_DATA, mle_msg->data_ptr, mle_msg->data_length, &networkDataTlv)) {
@ -767,7 +772,7 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
{ {
uint8_t mode; uint8_t mode;
uint32_t timeout; uint32_t timeout;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
thread_leader_data_t leaderData = {0}; thread_leader_data_t leaderData = {0};
uint8_t status; uint8_t status;
bool leader_data_received; bool leader_data_received;
@ -780,11 +785,12 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
//mle_service_buffer_find //mle_service_buffer_find
leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData); leader_data_received = thread_leader_data_parse(mle_msg->data_ptr, mle_msg->data_length, &leaderData);
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) && if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status) &&
status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) { status == 1 && thread_check_is_this_my_parent(cur, entry_temp)) {
tr_debug("parent has connection error"); tr_debug("parent has connection error");
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
return; return;
} }
@ -798,6 +804,8 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
} }
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
} else { } else {
tr_debug("Key ID Mode 2 not used; dropped."); tr_debug("Key ID Mode 2 not used; dropped.");
@ -811,13 +819,11 @@ static void thread_parse_child_update_response(protocol_interface_info_entry_t *
timeout = cur->thread_info->host_link_timeout; timeout = cur->thread_info->host_link_timeout;
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
entry_temp->holdTime = 90;
tr_debug("Setting child timeout, value=%"PRIu32, timeout); tr_debug("Setting child timeout, value=%"PRIu32, timeout);
mle_entry_timeout_update(entry_temp, timeout);
} }
tr_debug("Keep-Alive -->Respond from Parent"); tr_debug("Keep-Alive -->Respond from Parent");
mle_entry_timeout_refresh(entry_temp); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
//Save possible new Leader Data //Save possible new Leader Data
if (leader_data_received) { if (leader_data_received) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -50,6 +50,7 @@
#include "ns_trace.h" #include "ns_trace.h"
#include "6LoWPAN/Thread/thread_common.h" #include "6LoWPAN/Thread/thread_common.h"
#include "6LoWPAN/Thread/thread_routing.h" #include "6LoWPAN/Thread/thread_routing.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "6LoWPAN/Thread/thread_nd.h" #include "6LoWPAN/Thread/thread_nd.h"
#include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_joiner_application.h"
#include "6LoWPAN/Thread/thread_extension.h" #include "6LoWPAN/Thread/thread_extension.h"
@ -57,6 +58,7 @@
#include "6LoWPAN/Thread/thread_resolution_server.h" #include "6LoWPAN/Thread/thread_resolution_server.h"
#include "6LoWPAN/Thread/thread_bbr_api_internal.h" #include "6LoWPAN/Thread/thread_bbr_api_internal.h"
#include "6LoWPAN/Thread/thread_extension_bbr.h" #include "6LoWPAN/Thread/thread_extension_bbr.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "Common_Protocols/icmpv6.h" #include "Common_Protocols/icmpv6.h"
#include "MLE/mle.h" #include "MLE/mle.h"
@ -196,14 +198,14 @@ bool thread_nd_ns_transmit(protocol_interface_info_entry_t *cur, ipv6_neighbour_
} }
} }
static mle_neigh_table_entry_t *thread_nd_child_mleid_get(int8_t interface_id, uint8_t *childAddress, uint8_t *mlmeid_ptr) static mac_neighbor_table_entry_t *thread_nd_child_mleid_get(protocol_interface_info_entry_t *cur, uint8_t *childAddress, uint8_t *mlmeid_ptr)
{ {
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), childAddress, ADDR_802_15_4_SHORT);
entry_temp = mle_class_get_by_link_address(interface_id, childAddress, ADDR_802_15_4_SHORT); if (entry && !entry->ffd_device) {
if (entry_temp) { uint8_t *ptr = thread_neighbor_class_get_mleid(&cur->thread_info->neighbor_class, entry->index);
if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { if (ptr) {
memcpy(mlmeid_ptr,entry_temp->mlEid,8); memcpy(mlmeid_ptr, ptr, 8);
return entry_temp; return entry;
} }
} }
return NULL; return NULL;
@ -228,12 +230,13 @@ static int thread_nd_address_query_lookup(int8_t interface_id, const uint8_t tar
/* Scan IPv6 neighbour cache for registered entries of children */ /* Scan IPv6 neighbour cache for registered entries of children */
ns_list_foreach(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) { ns_list_foreach(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, target_addr)) { if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, target_addr)) {
mle_neigh_table_entry_t *mle_entry; mac_neighbor_table_entry_t *mle_entry;
*addr_out = mac16; *addr_out = mac16;
mle_entry = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], mleid_ptr); mle_entry = thread_nd_child_mleid_get(cur, &n->ll_address[2], mleid_ptr);
if (mle_entry) { if (mle_entry) {
//Get MLEID from Child //Get MLEID from Child
*last_transaction_time = (protocol_core_monotonic_time - mle_entry->last_contact_time) / 10; /* Both variables are count of 100ms ticks. */ uint32_t last_contact = thread_neighbor_last_communication_time_get(&cur->thread_info->neighbor_class, mle_entry->index);
*last_transaction_time = (protocol_core_monotonic_time - last_contact) / 10; /* Both variables are count of 100ms ticks. */
*proxy = true; *proxy = true;
return 0; return 0;
} }
@ -291,17 +294,18 @@ static void thread_nd_address_error(int8_t interface_id, const uint8_t ip_addr[1
if_address_entry_t *addr_entry = addr_get_entry(cur, ip_addr); if_address_entry_t *addr_entry = addr_get_entry(cur, ip_addr);
if (addr_entry && memcmp(ml_eid, cur->iid_slaac, 8)) { if (addr_entry && memcmp(ml_eid, cur->iid_slaac, 8)) {
addr_duplicate_detected(cur, ip_addr); addr_duplicate_detected(cur, ip_addr);
thread_extension_address_generate(cur);
} }
/* Scan IPv6 neighbour cache for registered entries of children */ /* Scan IPv6 neighbour cache for registered entries of children */
ns_list_foreach_safe(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) { ns_list_foreach_safe(ipv6_neighbour_t, n, &cur->ipv6_neighbour_cache.list) {
if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, ip_addr)) { if (n->type == IP_NEIGHBOUR_REGISTERED && addr_ipv6_equal(n->ip_address, ip_addr)) {
uint8_t child_mleid[8]; uint8_t child_mleid[8];
mle_neigh_table_entry_t *child = thread_nd_child_mleid_get(interface_id, &n->ll_address[2], child_mleid); mac_neighbor_table_entry_t *child = thread_nd_child_mleid_get(cur, &n->ll_address[2], child_mleid);
/* If this address belongs to an RFD child, with a different ML-EID, we must send it a duplicate message, and remove the EID */ /* If this address belongs to an RFD child, with a different ML-EID, we must send it a duplicate message, and remove the EID */
if (child && memcmp(child_mleid, ml_eid, 8)) { if (child && memcmp(child_mleid, ml_eid, 8)) {
uint8_t child_ml_addr[16]; uint8_t child_ml_addr[16];
thread_addr_write_mesh_local_16(child_ml_addr, child->short_adr, cur->thread_info); thread_addr_write_mesh_local_16(child_ml_addr, child->mac16, cur->thread_info);
tr_warn("Forwarding address error to child %04x", common_read_16_bit(&n->ll_address[2])); tr_warn("Forwarding address error to child %04x", common_read_16_bit(&n->ll_address[2]));
thread_resolution_client_address_error(interface_id, child_ml_addr, ip_addr, ml_eid); thread_resolution_client_address_error(interface_id, child_ml_addr, ip_addr, ml_eid);
ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, n); ipv6_neighbour_entry_remove(&cur->ipv6_neighbour_cache, n);
@ -367,7 +371,7 @@ buffer_t *thread_nd_snoop(protocol_interface_info_entry_t *cur, buffer_t *buf, c
return buffer_free(buf); return buffer_free(buf);
} }
if (!mle_class_get_by_link_address(cur->id, &ll_dst->address[2], ADDR_802_15_4_SHORT)) { if (!mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_dst->address[2], ADDR_802_15_4_SHORT)) {
/* We now know this was a packet for a non-existent child */ /* We now know this was a packet for a non-existent child */
goto bounce; goto bounce;
} }
@ -433,7 +437,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf
return buf; return buf;
} }
mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, &ll_src->address[2], ADDR_802_15_4_SHORT); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), &ll_src->address[2], ADDR_802_15_4_SHORT);
/* Due to note 1 and 1b above, full-function children / neighbor routers /* Due to note 1 and 1b above, full-function children / neighbor routers
* who did resolve to an RLOC16 may have optimised out the mesh header. * who did resolve to an RLOC16 may have optimised out the mesh header.
@ -446,7 +450,7 @@ buffer_t *thread_nd_special_forwarding(protocol_interface_info_entry_t *cur, buf
* is not in our neighbour cache, we need to send the child an error * is not in our neighbour cache, we need to send the child an error
* to clear its cache.) * to clear its cache.)
*/ */
if (!(buf->options.lowpan_mesh_rx || (entry && (entry->mode & MLE_DEV_MASK) == MLE_FFD_DEV))) { if (!(buf->options.lowpan_mesh_rx || (entry && entry->ffd_device))) {
return buf; return buf;
} }
@ -530,10 +534,11 @@ buffer_t *thread_nd_icmp_handler(protocol_interface_info_entry_t *cur, buffer_t
return buf; return buf;
} }
int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64) int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created)
{ {
ipv6_neighbour_t *neigh; ipv6_neighbour_t *neigh;
uint8_t ll_address[4]; uint8_t ll_address[4];
bool neighbor_created = false;
common_write_16_bit(panId, ll_address + 0); common_write_16_bit(panId, ll_address + 0);
common_write_16_bit(mac16, ll_address + 2); common_write_16_bit(mac16, ll_address + 2);
neigh = ipv6_neighbour_lookup_or_create(&cur->ipv6_neighbour_cache, ipv6Address); neigh = ipv6_neighbour_lookup_or_create(&cur->ipv6_neighbour_cache, ipv6Address);
@ -542,21 +547,24 @@ int thread_nd_address_registration(protocol_interface_info_entry_t *cur, const u
} }
uint8_t *nce_eui64 = ipv6_neighbour_eui64(&cur->ipv6_neighbour_cache, neigh); uint8_t *nce_eui64 = ipv6_neighbour_eui64(&cur->ipv6_neighbour_cache, neigh);
/*if (neigh->state != IP_NEIGHBOUR_NEW) if (neigh->state != IP_NEIGHBOUR_NEW && memcmp(nce_eui64, mac64, 8) != 0)
{
// Worry about this later
// Compare mac64 to nce_eui64 to spot duplicates
}
else*/
{ {
/* New entry */ return -2;
memcpy(nce_eui64, mac64, 8);
} }
/* New entry */
if (neigh->state == IP_NEIGHBOUR_NEW) {
neighbor_created = true;
}
memcpy(nce_eui64, mac64, 8);
/* Set the LL address, ensure it's marked STALE */ /* Set the LL address, ensure it's marked STALE */
ipv6_neighbour_entry_update_unsolicited(&cur->ipv6_neighbour_cache, neigh, ADDR_802_15_4_SHORT, ll_address); ipv6_neighbour_entry_update_unsolicited(&cur->ipv6_neighbour_cache, neigh, ADDR_802_15_4_SHORT, ll_address);
neigh->type = IP_NEIGHBOUR_REGISTERED; neigh->type = IP_NEIGHBOUR_REGISTERED;
neigh->lifetime = 0xffffffff; //Set Infinite neigh->lifetime = 0xffffffff; //Set Infinite
ipv6_neighbour_set_state(&cur->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE); ipv6_neighbour_set_state(&cur->ipv6_neighbour_cache, neigh, IP_NEIGHBOUR_STALE);
if (new_neighbour_created) {
*new_neighbour_created = neighbor_created;
}
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -55,7 +55,7 @@ int thread_nd_map_anycast_address(protocol_interface_info_entry_t *cur, uint16_t
void thread_nd_address_remove(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address); void thread_nd_address_remove(protocol_interface_info_entry_t *cur_interface, addrtype_t ll_type, const uint8_t *ll_address);
void thread_nd_flush_neighbour_cache_for_short_addr(struct protocol_interface_info_entry *cur, uint16_t flushee, bool children); void thread_nd_flush_neighbour_cache_for_short_addr(struct protocol_interface_info_entry *cur, uint16_t flushee, bool children);
int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64); int thread_nd_address_registration(struct protocol_interface_info_entry *cur, const uint8_t *ipv6Address, uint16_t mac16, uint16_t panId, const uint8_t *mac64, bool *new_neighbour_created);
#else //HAVE_THREAD_NEIGHBOR_DISCOVERY #else //HAVE_THREAD_NEIGHBOR_DISCOVERY

View File

@ -0,0 +1,209 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "nsconfig.h"
#include <string.h>
#include "ns_types.h"
#include "ns_trace.h"
#include "nsdynmemLIB.h"
#include "common_functions.h"
#include "NWK_INTERFACE/Include/protocol.h"
#include "6LoWPAN/Thread/thread_common.h"
#include "6LoWPAN/Thread/thread_routing.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
static thread_neigh_table_entry_t * thread_neighbor_class_table_entry_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
if (!class_ptr->neigh_info_list || attribute_index >= class_ptr->list_size) {
return NULL;
}
thread_neigh_table_entry_t *entry = class_ptr->neigh_info_list + attribute_index;
return entry;
}
bool thread_neighbor_class_create(thread_neighbor_class_t *class_ptr, uint8_t neigh_table_size)
{
class_ptr->neigh_info_list = ns_dyn_mem_alloc(sizeof(thread_neigh_table_entry_t) * neigh_table_size);
if (!class_ptr->neigh_info_list) {
return false;
}
class_ptr->list_size = neigh_table_size;
thread_neigh_table_entry_t * list_ptr = class_ptr->neigh_info_list;
for (uint8_t i = 0; i< neigh_table_size; i++) {
memset(list_ptr, 0, sizeof(thread_neigh_table_entry_t));
list_ptr++;
}
return true;
}
void thread_neighbor_class_delete(thread_neighbor_class_t *class_ptr)
{
ns_dyn_mem_free(class_ptr->neigh_info_list);
class_ptr->neigh_info_list = NULL;
class_ptr->list_size = 0;
}
void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return;
}
memcpy(entry->mlEid, mleid, 8);
}
uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return NULL;
}
return entry->mlEid;
}
void thread_neighbor_last_communication_time_update(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return;
}
entry->last_contact_time = protocol_core_monotonic_time;
}
void thread_neighbor_class_update_link(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return;
}
if (new_link) {
entry->link_margin = entry->link_margin + linkmargin - (entry->link_margin >> THREAD_LINK_MARGIN_SCALING);
} else {
entry->link_margin = linkmargin << THREAD_LINK_MARGIN_SCALING;
}
}
uint16_t thread_neighbor_entry_linkmargin_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return 0;
}
return entry->link_margin;
}
uint32_t thread_neighbor_last_communication_time_get(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return 0;
}
return entry->last_contact_time;
}
bool thread_neighbor_class_mleid_compare(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, const uint8_t *mleid)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry || memcmp(entry->mlEid, mleid, 8)) {
return false;
}
return true;
}
bool thread_neighbor_class_request_full_data_setup(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return false;
}
return entry->request_full_data_set;
}
bool thread_neighbor_class_secured_data_request(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (!entry) {
return false;
}
return entry->secured_data_request;
}
void thread_neighbor_class_request_full_data_setup_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (entry) {
entry->request_full_data_set = value;
}
}
void thread_neighbor_class_secured_data_request_set(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, bool value)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (entry) {
entry->secured_data_request = value;
}
}
void thread_neighbor_class_mode_parse_to_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index, uint8_t mode)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (entry) {
entry->request_full_data_set = mode & MLE_THREAD_REQ_FULL_DATA_SET;
entry->secured_data_request = mode & MLE_THREAD_SECURED_DATA_REQUEST;
}
}
uint8_t thread_neighbor_class_mode_write_from_entry(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
uint8_t mode = 0;
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (entry) {
if (entry->request_full_data_set) {
mode |= MLE_THREAD_REQ_FULL_DATA_SET;
}
if (entry->secured_data_request) {
mode |= MLE_THREAD_SECURED_DATA_REQUEST;
}
}
return mode;
}
void thread_neighbor_class_entry_remove(thread_neighbor_class_t *class_ptr, uint8_t attribute_index)
{
thread_neigh_table_entry_t *entry = thread_neighbor_class_table_entry_get(class_ptr,attribute_index);
if (entry) {
memset(entry, 0, sizeof(thread_neigh_table_entry_t));
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THREAD_NEIGHBOR_CLASS_H_
#define THREAD_NEIGHBOR_CLASS_H_
struct thread_neighbor_class_s;
/** Thead Spesific ModeFlags */
#define MLE_THREAD_SECURED_DATA_REQUEST 0x04
#define MLE_THREAD_REQ_FULL_DATA_SET 0x01
bool thread_neighbor_class_create(struct thread_neighbor_class_s *class_ptr, uint8_t neigh_table_size);
void thread_neighbor_class_delete(struct thread_neighbor_class_s *class_ptr);
void thread_neighbor_class_add_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin);
void thread_neighbor_class_add_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid);
uint8_t * thread_neighbor_class_get_mleid(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
void thread_neighbor_class_update_link(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t linkmargin, bool new_link);
void thread_neighbor_last_communication_time_update(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
uint16_t thread_neighbor_entry_linkmargin_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
uint32_t thread_neighbor_last_communication_time_get(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
bool thread_neighbor_class_mleid_compare(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, const uint8_t *mleid);
bool thread_neighbor_class_request_full_data_setup(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
bool thread_neighbor_class_secured_data_request(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
void thread_neighbor_class_mode_parse_to_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, uint8_t mode);
uint8_t thread_neighbor_class_mode_write_from_entry(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
void thread_neighbor_class_request_full_data_setup_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value);
void thread_neighbor_class_secured_data_request_set(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index, bool value);
void thread_neighbor_class_entry_remove(struct thread_neighbor_class_s *class_ptr, uint8_t attribute_index);
#endif /* THREAD_NEIGHBOR_CLASS_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -60,6 +60,7 @@
#define THREAD_P_DEF_ROUTE_BIT_MOVE 9 /* R-bit */ #define THREAD_P_DEF_ROUTE_BIT_MOVE 9 /* R-bit */
#define THREAD_P_ON_MESH_BIT_MOVE 8 /* O-bit */ #define THREAD_P_ON_MESH_BIT_MOVE 8 /* O-bit */
#define THREAD_P_ND_DNS_BIT_MOVE 7 /* N-bit */ #define THREAD_P_ND_DNS_BIT_MOVE 7 /* N-bit */
#define THREAD_P_ND_RES_BIT_MOVE 6 /* First reserved bit */
/* Bit shift for HasRouteTLV preference bit */ /* Bit shift for HasRouteTLV preference bit */
#define THREAD_HAS_ROUTE_PRF_BIT_MOVE 6 /* Prf-bits */ #define THREAD_HAS_ROUTE_PRF_BIT_MOVE 6 /* Prf-bits */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -328,9 +328,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre
newEntry->servicesPrefixLen = prefixTlv->PrefixLen; newEntry->servicesPrefixLen = prefixTlv->PrefixLen;
newEntry->domainId = prefixTlv->domainId; newEntry->domainId = prefixTlv->domainId;
newEntry->dhcpv6ServerActive = false; newEntry->dhcpv6ServerActive = false;
newEntry->dhcpv6ServerDataStable = false; newEntry->brDataStable = false;
newEntry->slaacServerActive = false; newEntry->slaacServerActive = false;
newEntry->slaacServerDataStable = false;
newEntry->slaacPreferred = false; newEntry->slaacPreferred = false;
newEntry->routeActive = false; newEntry->routeActive = false;
newEntry->routeDataStable = false; newEntry->routeDataStable = false;
@ -339,6 +338,8 @@ thread_network_local_data_entry_t *thread_local_service_list_allocate(thread_pre
newEntry->defaultRoute = false; newEntry->defaultRoute = false;
newEntry->onMesh = false; newEntry->onMesh = false;
newEntry->ndDns = false; newEntry->ndDns = false;
newEntry->brActive = false;
newEntry->res1 = false;
} }
return newEntry; return newEntry;
} }
@ -373,6 +374,7 @@ thread_network_server_data_entry_t *thread_server_entry_allocate(thread_border_r
newEntry->Prf = service->Prf; newEntry->Prf = service->Prf;
newEntry->P_on_mesh = service->P_on_mesh; newEntry->P_on_mesh = service->P_on_mesh;
newEntry->P_nd_dns = service->P_nd_dns; newEntry->P_nd_dns = service->P_nd_dns;
newEntry->P_res1 = service->P_res1;
newEntry->canDelete = false; newEntry->canDelete = false;
} }
@ -868,7 +870,7 @@ static int thread_service_data_delete_mark_by_router_id(thread_network_data_serv
return retVal; return retVal;
} }
static int thread_server_context_clean(thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list) static int thread_server_context_clean(int8_t id, thread_network_data_cache_entry_t *cachePtr, thread_data_context_list_t *listPtr, thread_network_data_prefix_cache_entry_t *prefixEntry, lowpan_context_list_t *context_list)
{ {
int retVal = -1; int retVal = -1;
(void) prefixEntry; (void) prefixEntry;
@ -879,7 +881,9 @@ static int thread_server_context_clean(thread_network_data_cache_entry_t *cacheP
cachePtr->stableUpdatePushed = true; cachePtr->stableUpdatePushed = true;
} }
// Set context lifetime to 0 to delete // Set context lifetime to 0 to delete
lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true); if (thread_extension_context_can_delete(id, prefixEntry->servicesPrefix, cur->contextPrefixLength)) {
lowpan_context_update(context_list, cur->cid, 0, NULL, 0, true);
}
ns_list_remove(listPtr, cur); ns_list_remove(listPtr, cur);
ns_dyn_mem_free(cur); ns_dyn_mem_free(cur);
retVal = 0; retVal = 0;
@ -1019,7 +1023,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
} }
thread_server_data_clean_by_router_id(cachePtr, &cur->routeList, cur, true, curInterface); thread_server_data_clean_by_router_id(cachePtr, &cur->routeList, cur, true, curInterface);
if (!is_leader) { if (!is_leader) {
thread_server_context_clean(cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts); thread_server_context_clean(curInterface->id, cachePtr, &cur->contextList, cur, &curInterface->lowpan_contexts);
} }
if (ns_list_is_empty(&cur->borderRouterList)) { if (ns_list_is_empty(&cur->borderRouterList)) {
@ -1071,7 +1075,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
return address_removed; return address_removed;
} }
void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list) void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list)
{ {
ns_list_foreach_safe(thread_network_data_prefix_cache_entry_t, cur, &cachePtr->localPrefixList) { ns_list_foreach_safe(thread_network_data_prefix_cache_entry_t, cur, &cachePtr->localPrefixList) {
ns_list_foreach_safe(thread_network_data_context_entry_t, curContext, &cur->contextList) { ns_list_foreach_safe(thread_network_data_context_entry_t, curContext, &cur->contextList) {
@ -1086,7 +1090,9 @@ void thread_network_data_context_re_use_timer_update(thread_network_data_cache_e
cachePtr->temporaryUpdatePushed = true; cachePtr->temporaryUpdatePushed = true;
} }
// Set context lifetime to 0 to delete // Set context lifetime to 0 to delete
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true); if (thread_extension_context_can_delete(id, cur->servicesPrefix,curContext->contextPrefixLength)) {
lowpan_context_update(context_list, curContext->cid, 0, NULL, 0, true);
}
ns_dyn_mem_free(curContext); ns_dyn_mem_free(curContext);
} }
} }
@ -1708,21 +1714,21 @@ int thread_local_server_list_add_on_mesh_server(thread_network_local_data_cache_
if (networkDataList) { if (networkDataList) {
thread_network_local_data_entry_t *prefix_entry = thread_local_prefix_entry_get(&networkDataList->prefix_list, prefixTlv); thread_network_local_data_entry_t *prefix_entry = thread_local_prefix_entry_get(&networkDataList->prefix_list, prefixTlv);
if (prefix_entry) { if (prefix_entry) {
prefix_entry->brDataStable = service->stableData;
prefix_entry->preference = service->Prf; prefix_entry->preference = service->Prf;
prefix_entry->configure = service->P_configure; prefix_entry->configure = service->P_configure;
prefix_entry->defaultRoute = service->P_default_route; prefix_entry->defaultRoute = service->P_default_route;
prefix_entry->onMesh = service->P_on_mesh; prefix_entry->onMesh = service->P_on_mesh;
prefix_entry->ndDns = service->P_nd_dns; prefix_entry->ndDns = service->P_nd_dns;
prefix_entry->res1 = service->P_res1;
prefix_entry->dhcpv6ServerActive = service->P_dhcp;
prefix_entry->slaacServerActive = service->P_slaac;
prefix_entry->slaacPreferred = service->P_preferred;
if (service->P_dhcp) { if (service->P_dhcp ||
prefix_entry->dhcpv6ServerActive = true; service->P_slaac ||
prefix_entry->dhcpv6ServerDataStable = service->stableData; service->P_res1) {
} prefix_entry->brActive = true;
if (service->P_slaac) {
prefix_entry->slaacServerActive = true;
prefix_entry->slaacServerDataStable = service->stableData;
prefix_entry->slaacPreferred = service->P_preferred;
} }
if (prefixTlv->PrefixLen == 0) { if (prefixTlv->PrefixLen == 0) {
@ -1891,9 +1897,7 @@ int thread_local_server_del_route(thread_network_local_data_cache_entry_t *netwo
} }
prefix_entry->routeActive = false; prefix_entry->routeActive = false;
if (prefix_entry->dhcpv6ServerActive) { if (prefix_entry->brActive) {
return 0;
} else if (prefix_entry->slaacServerActive) {
return 0; return 0;
} }
@ -2023,17 +2027,13 @@ uint8_t thread_server_prefix_length(thread_network_local_data_entry_t *cur)
if (cur->routeActive) { if (cur->routeActive) {
if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) { if (!(cur->brActive && cur->defaultRoute)) {
// HasRoute is added if BorderRouter TLV does not have default route bit // HasRoute is added if BorderRouter TLV does not have default route bit
tempLength += 5; tempLength += 5;
} }
} }
if (cur->dhcpv6ServerActive) { if (cur->brActive) {
tempLength += 6;
}
if (cur->slaacServerActive) {
tempLength += 6; tempLength += 6;
} }
@ -2091,14 +2091,9 @@ uint16_t thread_nd_own_service_list_data_size(thread_network_local_data_cache_en
static bool thread_check_local_data_prefix_stable_boolean(thread_network_local_data_entry_t *dataList) static bool thread_check_local_data_prefix_stable_boolean(thread_network_local_data_entry_t *dataList)
{ {
if (dataList->dhcpv6ServerActive && dataList->dhcpv6ServerDataStable) { if (dataList->brActive && dataList->brDataStable) {
return true; return true;
} }
if (dataList->slaacServerActive && dataList->slaacServerDataStable) {
return true;
}
return false; return false;
} }
@ -2269,7 +2264,7 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
if (servicesLen) { if (servicesLen) {
ptr = thread_nd_hosted_prefix_header_write(ptr,servicesLen, cur); ptr = thread_nd_hosted_prefix_header_write(ptr,servicesLen, cur);
if (cur->routeActive) { if (cur->routeActive) {
if (!((cur->slaacServerActive || cur->dhcpv6ServerActive) && cur->defaultRoute)) { if (!(cur->brActive && cur->defaultRoute)) {
// HasRoute is added if BorderRouter TLV does not have default route bit // HasRoute is added if BorderRouter TLV does not have default route bit
uint8_t preference = 0; uint8_t preference = 0;
tlvType = THREAD_NWK_DATA_TYPE_ROUTE; tlvType = THREAD_NWK_DATA_TYPE_ROUTE;
@ -2283,10 +2278,10 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
} }
} }
if (cur->slaacServerActive || cur->dhcpv6ServerActive) { if (cur->brActive) {
uint16_t flags = 0; uint16_t flags = 0;
tlvType = THREAD_NWK_DATA_TYPE_BORDER_ROUTER; tlvType = THREAD_NWK_DATA_TYPE_BORDER_ROUTER;
if (cur->slaacServerDataStable || cur->dhcpv6ServerDataStable) { if (cur->brDataStable) {
tlvType |= THREAD_NWK_STABLE_DATA; tlvType |= THREAD_NWK_STABLE_DATA;
} }
if (cur->slaacServerActive) { if (cur->slaacServerActive) {
@ -2313,6 +2308,9 @@ uint8_t * thread_nd_own_service_list_data_write(thread_network_local_data_cache_
if (cur->ndDns) { if (cur->ndDns) {
flags |= 1 << THREAD_P_ND_DNS_BIT_MOVE; flags |= 1 << THREAD_P_ND_DNS_BIT_MOVE;
} }
if (cur->res1) {
flags |= 1 << THREAD_P_ND_RES_BIT_MOVE;
}
ptr = thread_service_border_router_tlv_write(ptr, tlvType, routerID, flags); ptr = thread_service_border_router_tlv_write(ptr, tlvType, routerID, flags);
} // slaac or dhcp } // slaac or dhcp
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -72,6 +72,7 @@ typedef struct thread_network_data_temporary_route_or_dhcpv6_server_entry_s {
bool stableData: 1; bool stableData: 1;
bool P_on_mesh: 1; bool P_on_mesh: 1;
bool P_nd_dns: 1; bool P_nd_dns: 1;
bool P_res1: 1;
bool canDelete: 1; bool canDelete: 1;
ns_list_link_t link; /*!< List link entry */ ns_list_link_t link; /*!< List link entry */
} thread_network_server_data_entry_t; } thread_network_server_data_entry_t;
@ -87,6 +88,7 @@ typedef struct thread_border_router_tlv_entry_t {
bool stableData: 1; /* P_stable */ bool stableData: 1; /* P_stable */
bool P_on_mesh: 1; /* P_on_mesh */ bool P_on_mesh: 1; /* P_on_mesh */
bool P_nd_dns: 1; /* P_nd_dns */ bool P_nd_dns: 1; /* P_nd_dns */
bool P_res1: 1; /* P_res1 */
} thread_border_router_tlv_entry_t; } thread_border_router_tlv_entry_t;
typedef struct thread_prefix_tlv { typedef struct thread_prefix_tlv {
@ -136,16 +138,17 @@ typedef struct thread_network_local_data_entry_s {
uint8_t servicesPrefixLen; /*!< Prefix length in bits This Can Be 1-128 */ uint8_t servicesPrefixLen; /*!< Prefix length in bits This Can Be 1-128 */
bool routeActive: 1; bool routeActive: 1;
bool routeDataStable: 1; bool routeDataStable: 1;
bool brActive: 1;
bool dhcpv6ServerActive: 1; bool dhcpv6ServerActive: 1;
bool dhcpv6ServerDataStable: 1; bool brDataStable: 1;
bool slaacServerActive: 1; bool slaacServerActive: 1;
bool slaacServerDataStable: 1;
bool slaacPreferred: 1; bool slaacPreferred: 1;
unsigned preference: 2; unsigned preference: 2;
bool configure: 1; bool configure: 1;
bool defaultRoute: 1; bool defaultRoute: 1;
bool onMesh: 1; bool onMesh: 1;
bool ndDns: 1; bool ndDns: 1;
bool res1:1;
ns_list_link_t link; /*!< List link entry */ ns_list_link_t link; /*!< List link entry */
} thread_network_local_data_entry_t; } thread_network_local_data_entry_t;
@ -207,7 +210,7 @@ bool thread_network_data_router_id_free(thread_network_data_cache_entry_t *cache
void thread_network_local_data_free_and_clean(thread_network_local_data_cache_entry_t *cachePtr, int8_t interface_id); void thread_network_local_data_free_and_clean(thread_network_local_data_cache_entry_t *cachePtr, int8_t interface_id);
void thread_network_data_context_re_use_timer_update(thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list); void thread_network_data_context_re_use_timer_update(int8_t id, thread_network_data_cache_entry_t *cachePtr, uint32_t ticks, lowpan_context_list_t *context_list);
/** /**
* Add new route information to route List * Add new route information to route List

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -56,12 +56,14 @@
#include "6LoWPAN/Thread/thread_joiner_application.h" #include "6LoWPAN/Thread/thread_joiner_application.h"
#include "6LoWPAN/Thread/thread_management_client.h" #include "6LoWPAN/Thread/thread_management_client.h"
#include "6LoWPAN/Thread/thread_network_synch.h" #include "6LoWPAN/Thread/thread_network_synch.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "thread_management_if.h" #include "thread_management_if.h"
#include "thread_config.h" #include "thread_config.h"
#include "Common_Protocols/ipv6.h" #include "Common_Protocols/ipv6.h"
#include "Common_Protocols/icmpv6.h" #include "Common_Protocols/icmpv6.h"
#include "Common_Protocols/icmpv6_radv.h" #include "Common_Protocols/icmpv6_radv.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#define TRACE_GROUP "tsyn" #define TRACE_GROUP "tsyn"
@ -90,7 +92,7 @@ typedef struct thread_network_dynamic_data_entry {
} thread_network_dynamic_data_entry_t; } thread_network_dynamic_data_entry_t;
static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id); static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t interface_id);
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child); static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child);
static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link); static NS_LIST_DEFINE(thread_network_dynamic_data_info, thread_network_dynamic_data_entry_t, link);
thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId) thread_network_dynamic_data_entry_t *thread_network_synch_create(int8_t interfaceId)
@ -155,54 +157,53 @@ int thread_network_synch_data_free(int8_t interface_id)
* Dynamic network data storage. * Dynamic network data storage.
*/ */
void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child) void thread_dynamic_storage_child_info_store(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *child)
{ {
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(cur_interface->id);
if (!storeEntry) { if (!storeEntry) {
storeEntry = thread_network_synch_create(interface_id); storeEntry = thread_network_synch_create(cur_interface->id);
} }
if (!storeEntry) { if (!storeEntry) {
return; return;
} }
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); uint32_t mle_frame_counter = mle_service_neighbor_frame_counter_get(cur_interface->id, child->index);
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(cur_interface->id, child);
if (!child_info) {
child_info = thread_dynamic_storage_free_child_find(cur_interface->id);
}
if (child_info) { if (child_info) {
child_info->mode = child->mode; uint8_t mode = mle_mode_write_from_mac_entry(child);
child_info->short_addr = child->short_adr; mode |= thread_neighbor_class_mode_write_from_entry(&cur_interface->thread_info->neighbor_class, child->index);
child_info->mle_frame_counter = child->mle_frame_counter;
child_info->mode = mode;
child_info->short_addr = child->mac16;
child_info->mle_frame_counter = mle_frame_counter;
child_info->mac_frame_counter = 0; child_info->mac_frame_counter = 0;
memcpy(child_info->long_addr, child->mac64, 8); memcpy(child_info->long_addr, child->mac64, 8);
return; return;
} }
child_info = thread_dynamic_storage_free_child_find(interface_id);
if (child_info) {
child_info->mode = child->mode;
child_info->short_addr = child->short_adr;
child_info->mle_frame_counter = child->mle_frame_counter;
child_info->mac_frame_counter = 0;
memcpy(child_info->long_addr, child->mac64, 8);
}
return; return;
} }
void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child) void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child)
{ {
thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child); thread_sync_child_info_t *child_info = thread_dynamic_storage_child_info_find(interface_id, child);
if (child_info){ if (child_info){
// Clear child information // Clear child information
memset (child_info,0,sizeof(thread_sync_child_info_t)); memset (child_info,0,sizeof(thread_sync_child_info_t));
tr_debug("Dynamic storage: cleared child; mac16=%04x", child->short_adr); tr_debug("Dynamic storage: cleared child; mac16=%04x", child->mac16);
return; return;
} }
return; return;
} }
static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mle_neigh_table_entry_t *child) static thread_sync_child_info_t *thread_dynamic_storage_child_info_find(int8_t interface_id, mac_neighbor_table_entry_t *child)
{ {
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
@ -236,6 +237,10 @@ static thread_sync_child_info_t *thread_dynamic_storage_free_child_find(int8_t i
void thread_dynamic_storage_build_mle_table(int8_t interface_id) void thread_dynamic_storage_build_mle_table(int8_t interface_id)
{ {
tr_debug("Dynamic storage: building MLE table."); tr_debug("Dynamic storage: building MLE table.");
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !cur->mac_parameters) {
return;
}
thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id); thread_network_dynamic_data_entry_t *storeEntry = thread_network_synch_find(interface_id);
bool new_entry_created; bool new_entry_created;
@ -248,9 +253,9 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id)
return; return;
} }
mle_neigh_table_list_t *neig_list = mle_class_active_list_get(interface_id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!neig_list) { if (!mac_table_list) {
return; return;
} }
@ -262,19 +267,21 @@ void thread_dynamic_storage_build_mle_table(int8_t interface_id)
} }
uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr; uint8_t *mac64 = storeEntry->networ_dynamic_data_parameters.children[i].long_addr;
tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8)); tr_debug("Child: %04x, %s", storeEntry->networ_dynamic_data_parameters.children[i].short_addr, trace_array(mac64, 8));
mle_neigh_table_entry_t *entry = mle_class_get_entry_by_mac64(interface_id, 64, mac64, true, &new_entry_created);
if (entry) {
entry->short_adr = storeEntry->networ_dynamic_data_parameters.children[i].short_addr;
entry->mle_frame_counter = storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter;
entry->mode = storeEntry->networ_dynamic_data_parameters.children[i].mode;
entry->threadNeighbor = true;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(cur), mac64, true, &new_entry_created);
if (mac_entry) {
if (cur && cur->mac_parameters) { mac_entry->mac16 = storeEntry->networ_dynamic_data_parameters.children[i].short_addr;
// Set MAC layer frame counter for the child mle_service_frame_counter_entry_add(interface_id, mac_entry->index, storeEntry->networ_dynamic_data_parameters.children[i].mle_frame_counter);
mac_helper_devicetable_set(entry, cur, storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, cur->mac_parameters->mac_default_key_index, new_entry_created); mle_mode_parse_to_mac_entry(mac_entry, storeEntry->networ_dynamic_data_parameters.children[i].mode);
}
// Set MAC layer frame counter for the child
mlme_device_descriptor_t device_desc;
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, mac_entry->index,64, new_entry_created);
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, mac_entry->index,storeEntry->networ_dynamic_data_parameters.children[i].mode);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, mac_entry->index);
mac_helper_device_description_write(cur, &device_desc, mac_entry->mac64, mac_entry->mac16,storeEntry->networ_dynamic_data_parameters.children[i].mac_frame_counter, false);
mac_helper_devicetable_set(&device_desc, cur, mac_entry->index, cur->mac_parameters->mac_default_key_index, new_entry_created);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,6 +35,9 @@
#ifndef THREAD_NETWORK_SYNCH_H_ #ifndef THREAD_NETWORK_SYNCH_H_
#define THREAD_NETWORK_SYNCH_H_ #define THREAD_NETWORK_SYNCH_H_
struct protocol_interface_info_entry;
struct mac_neighbor_table_entry;
//Call This when clean synched networkdata //Call This when clean synched networkdata
int thread_network_synch_data_free(int8_t interface_id); int thread_network_synch_data_free(int8_t interface_id);
//Call This when want synch last network setup //Call This when want synch last network setup
@ -46,8 +49,8 @@ bool thread_dynamic_storage_pending_configuration_exists(int8_t interface_id);
void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size); void thread_dynamic_storage_pending_configuration_read(int8_t interface_id, void *data, uint16_t size);
void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size); void thread_dynamic_storage_pending_configuration_store(int8_t interface_id, void *data, uint16_t size);
void thread_dynamic_storage_child_info_store(int8_t interface_id, mle_neigh_table_entry_t *child); void thread_dynamic_storage_child_info_store(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *child);
void thread_dynamic_storage_child_info_clear(int8_t interface_id, mle_neigh_table_entry_t *child); void thread_dynamic_storage_child_info_clear(int8_t interface_id, struct mac_neighbor_table_entry *child);
void thread_dynamic_storage_build_mle_table(int8_t interface_id); void thread_dynamic_storage_build_mle_table(int8_t interface_id);
void thread_dynamic_storage_frame_counter_store(int8_t interface_id, uint32_t mle_frame_counter, uint32_t mac_frame_counter); void thread_dynamic_storage_frame_counter_store(int8_t interface_id, uint32_t mle_frame_counter, uint32_t mac_frame_counter);
uint32_t thread_dynamic_storage_mle_frame_counter_get(int8_t interfaceId); uint32_t thread_dynamic_storage_mle_frame_counter_get(int8_t interfaceId);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -84,7 +84,7 @@ static int thread_nvm_store_fast_data_save(thread_nvm_fast_data_t* fast_data_to_
static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter); static int thread_nvm_store_all_counters_store(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t seq_counter);
static void thread_nvm_store_link_info_delayed_write(uint32_t seconds); static void thread_nvm_store_link_info_delayed_write(uint32_t seconds);
#define MAX_ROOT_PATH_LEN 150 #define MAX_ROOT_PATH_LEN 200
#define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1) #define FAST_DATA_STRING_LEN (strlen(FAST_DATA_FILE)+strlen(thread_nvm_store_get_root_path())+1)
#define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1) #define ACTIVE_CONF_STRING_LEN (strlen(THREAD_NVM_ACTIVE_CONF_FILE)+strlen(thread_nvm_store_get_root_path())+1)
@ -330,6 +330,15 @@ int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint3
return ret; return ret;
} }
int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter)
{
int ret;
ret = thread_nvm_store_all_counters_store(mac_frame_counter, mle_frame_counter, network_seq_counter);
cached_fast_data.mac_frame_counter = mac_frame_counter;
cached_fast_data.mle_frame_counter = mle_frame_counter;
cached_fast_data.seq_counter=network_seq_counter;
return ret;
}
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter) int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter)
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Arm Limited and affiliates. * Copyright (c) 2017-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -84,6 +84,9 @@ int thread_nvm_store_fast_data_write(thread_nvm_fast_data_t* fast_data);
int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter); int thread_nvm_store_frame_counters_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter);
/* stores the frame counter and seq counter to nvm only if any threshold is passed*/ /* stores the frame counter and seq counter to nvm only if any threshold is passed*/
int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter); int thread_nvm_store_fast_data_check_and_write(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter);
/*Store all fast data values unconditionally*/
int thread_nvm_store_fast_data_write_all(uint32_t mac_frame_counter, uint32_t mle_frame_counter, uint32_t network_seq_counter);
/* stores the value to nvm only if it has changed */ /* stores the value to nvm only if it has changed */
int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter); int thread_nvm_store_seq_counter_write(uint32_t network_seq_counter);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -66,6 +66,7 @@
#include "6LoWPAN/Thread/thread_lowpower_private_api.h" #include "6LoWPAN/Thread/thread_lowpower_private_api.h"
#include "6LoWPAN/Thread/thread_tmfcop_lib.h" #include "6LoWPAN/Thread/thread_tmfcop_lib.h"
#include "6LoWPAN/Thread/thread_nvm_store.h" #include "6LoWPAN/Thread/thread_nvm_store.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "thread_management_if.h" #include "thread_management_if.h"
#include "Common_Protocols/ipv6.h" #include "Common_Protocols/ipv6.h"
#include "Common_Protocols/icmpv6.h" #include "Common_Protocols/icmpv6.h"
@ -83,12 +84,12 @@
#include "6LoWPAN/MAC/mac_data_poll.h" #include "6LoWPAN/MAC/mac_data_poll.h"
#include "thread_border_router_api.h" #include "thread_border_router_api.h"
#include "Core/include/address.h" #include "Core/include/address.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#ifdef HAVE_THREAD_ROUTER #ifdef HAVE_THREAD_ROUTER
#define TRACE_GROUP "trbs" #define TRACE_GROUP "trbs"
static bool thread_rfd_device(uint8_t mode);
static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode); static uint8_t *thread_tlv_add(protocol_interface_info_entry_t *cur, uint8_t *ptr, uint8_t tlv_type, uint8_t mode);
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf); static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf);
@ -103,18 +104,10 @@ static int thread_router_accept_request_build(protocol_interface_info_entry_t *c
static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv, uint64_t active_timestamp, uint64_t pending_timestamp); static int thread_child_update_response(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t mode, uint16_t short_address, uint32_t timeout, mle_tlv_info_t *addressRegisterTlv,mle_tlv_info_t *tlvReq, mle_tlv_info_t *challengeTlv, uint64_t active_timestamp, uint64_t pending_timestamp);
static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode); static int mle_build_and_send_data_response_msg(protocol_interface_info_entry_t *cur, uint8_t *dst_address, uint8_t *data_ptr, uint16_t data_len, mle_tlv_info_t *request_tlv, uint8_t mode);
static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode); static int thread_attach_parent_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress, uint8_t *challenge, uint16_t chalLen, uint8_t linkMargin, uint8_t scanMask, uint8_t mode);
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info); static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info);
static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur); static int8_t thread_router_bootstrap_synch_request_send(protocol_interface_info_entry_t *cur);
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp); static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp);
static bool thread_rfd_device(uint8_t mode)
{
if ((mode & MLE_DEV_MASK) != MLE_RFD_DEV) {
return false;
}
return true;
}
static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr) static bool thread_router_parent_address_check(protocol_interface_info_entry_t *cur, uint8_t *source_addr)
{ {
@ -209,7 +202,7 @@ int thread_router_bootstrap_mle_advertise(protocol_interface_info_entry_t *cur)
} }
static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *mle_entry, buffer_t *buf) static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry, buffer_t *buf)
{ {
link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id); link_configuration_s *linkConfiguration = thread_joiner_application_get_config(cur->id);
if (!linkConfiguration) { if (!linkConfiguration) {
@ -224,7 +217,7 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle
new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD); new_buf->info = (buffer_info_t) (B_DIR_DOWN | B_TO_IPV6_TXRX | B_FROM_IPV6_FWD);
uint8_t next_hop[16]; uint8_t next_hop[16];
memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8); memcpy(next_hop, ADDR_LINK_LOCAL_PREFIX, 8);
memcpy(&next_hop[8], mle_entry->mac64, 8); memcpy(&next_hop[8], entry->mac64, 8);
next_hop[8] ^= 2; next_hop[8] ^= 2;
ipv6_buffer_route_to(new_buf, next_hop, cur); ipv6_buffer_route_to(new_buf, next_hop, cur);
@ -234,15 +227,11 @@ static void clone_multicast_to_unicast(protocol_interface_info_entry_t *cur, mle
static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf) static void mle_multicast_push_to_sleep_child(protocol_interface_info_entry_t *cur, buffer_t *buf)
{ {
mle_neigh_table_list_t *mle_neigh_list = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_neigh_list) {
return; ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
} if (!cur_entry->rx_on_idle) {
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_neigh_list) { clone_multicast_to_unicast(cur, cur_entry, buf);
if (cur_entry->threadNeighbor) {
if (!(cur_entry->mode & MLE_RX_ON_IDLE)) {
clone_multicast_to_unicast(cur, cur_entry, buf);
}
} }
} }
} }
@ -260,9 +249,9 @@ static void thread_registered_mcast_forward_to_child(protocol_interface_info_ent
tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address)); tr_debug("Forwarding to registered multicast address: %s", trace_ipv6(addr->address));
ns_list_foreach(thread_mcast_child_t, child, &addr->children) { ns_list_foreach(thread_mcast_child_t, child, &addr->children) {
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, child->mac64, ADDR_802_15_4_LONG); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), child->mac64, ADDR_802_15_4_LONG);
if (mle_entry && mle_entry->threadNeighbor && !(mle_entry->mode & MLE_RX_ON_IDLE)) { if (entry && !entry->rx_on_idle) {
clone_multicast_to_unicast(cur, mle_entry, buffer); clone_multicast_to_unicast(cur, entry, buffer);
} }
} }
} }
@ -304,13 +293,10 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m
uint16_t version, shortAddress, address16; uint16_t version, shortAddress, address16;
uint32_t llFrameCounter; uint32_t llFrameCounter;
mle_tlv_info_t routing; mle_tlv_info_t routing;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
tr_debug("Thread MLE message router sync"); tr_debug("Thread MLE message router sync");
//State machine What packet shuold accept in this case //State machine What packet shuold accept in this case
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (!cur) {
return;
}
/* Check that message is from link-local scope */ /* Check that message is from link-local scope */
if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) { if(!addr_is_ipv6_link_local(mle_msg->packet_src_address)) {
@ -353,42 +339,56 @@ static void thread_router_synch_receive_cb(int8_t interface_id, mle_message_t *m
return; return;
} }
//Allocate neighbor entry //Allocate neighbor entry
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, true, &new_neigbour);
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, true, &new_neigbour);
if (!entry_temp) { if (!entry_temp) {
return; return;
} }
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
thread_key_guard_timer_reset(cur);
} else {
tr_error("Key ID Mode 2 not used; dropped.");
return;
}
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, new_neigbour);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
//Free Response //Free Response
mle_service_msg_free(messageId); mle_service_msg_free(messageId);
entry_temp->threadNeighbor = true; entry_temp->mac16 = shortAddress;
entry_temp->short_adr = shortAddress;
//when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour //when allocating neighbour entry, use MLE Frame counter if present to validate further advertisements from the neighbour
entry_temp->mle_frame_counter = mleFrameCounter; mle_service_frame_counter_entry_add(cur->id, entry_temp->index, mleFrameCounter);
if (entry_temp->timeout_rx) { uint32_t timeout_tlv;
mle_entry_timeout_refresh(entry_temp);
mle_tlv_info_t mle_tlv_info;
if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
} else { } else {
mle_tlv_info_t mle_tlv_info; if (new_neigbour) {
uint32_t timeout_tlv; timeout_tlv = THREAD_DEFAULT_LINK_LIFETIME;
if (mle_tlv_option_discover(mle_msg->data_ptr, mle_msg->data_length, MLE_TYPE_TIMEOUT, &mle_tlv_info) > 0) {
timeout_tlv = common_read_32_bit(mle_tlv_info.dataPtr);
mle_entry_timeout_update(entry_temp, timeout_tlv);
} else { } else {
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); timeout_tlv = entry_temp->link_lifetime;
} }
} }
if (thread_is_router_addr(shortAddress)) { mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout_tlv);
entry_temp->handshakeReady = 1;
}
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; if (thread_is_router_addr(shortAddress)) {
entry_temp->connected_device = 1;
}
thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) { if (mle_tlv_read_8_bit_tlv(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length, &linkMarginfronNeigh)) {
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
} }
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_neigbour); mlme_device_descriptor_t device_desc;
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_neigbour);
//Copy Leader Data //Copy Leader Data
*cur->thread_info->thread_leader_data = leaderData; *cur->thread_info->thread_leader_data = leaderData;
@ -949,17 +949,17 @@ static int thread_attach_parent_response_build(protocol_interface_info_entry_t *
return 0; return 0;
} }
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child) int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child)
{ {
/* Cleanup occurs for /any/ link we lose to something that looks like a child address, /* Cleanup occurs for /any/ link we lose to something that looks like a child address,
* not just links that are /now/ our children. * not just links that are /now/ our children.
* Due to REED/partition transitions the address may not look like a current child address; * Due to REED/partition transitions the address may not look like a current child address;
* we could be holding a child entry for future repromotion to router with same ID. * we could be holding a child entry for future repromotion to router with same ID.
*/ */
if (thread_is_router_addr(child->short_adr) || child->short_adr >= 0xfffe) { if (thread_is_router_addr(child->mac16) || child->mac16 >= 0xfffe) {
return -1; return -1;
} }
tr_debug("Child free %x", child->short_adr); tr_debug("Child free %x", child->mac16);
thread_dynamic_storage_child_info_clear(cur->id, child); thread_dynamic_storage_child_info_clear(cur->id, child);
/* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache /* As we are losing a link to a child address, we can assume that if we have an IP neighbour cache
@ -967,12 +967,12 @@ int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cu
* finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not * finding a new parent, and hence a new 16-bit address. (Losing a link to a router address would not
* invalidate our IP->16-bit mapping.) * invalidate our IP->16-bit mapping.)
*/ */
protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->short_adr); protocol_6lowpan_release_short_link_address_from_neighcache(cur, child->mac16);
// If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader // If Child's RLOC16 appears in the Network Data send the RLOC16 to the Leader
if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->short_adr)) { if (thread_network_data_services_registered(&cur->thread_info->networkDataStorage, child->mac16)) {
tr_debug("Remove references to Child's RLOC16 from the Network Data"); tr_debug("Remove references to Child's RLOC16 from the Network Data");
thread_management_client_network_data_unregister(cur->id, child->short_adr); thread_management_client_network_data_unregister(cur->id, child->mac16);
} }
// Clear all (sleepy) child registrations to multicast groups // Clear all (sleepy) child registrations to multicast groups
@ -991,13 +991,11 @@ void thread_router_bootstrap_child_information_clear(protocol_interface_info_ent
} }
// Remove mle neighbour entries for children in previous partition // Remove mle neighbour entries for children in previous partition
mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!entry_list) {
return; ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) {
} if (table_entry->mac16 < 0xfffe && !thread_is_router_addr(table_entry->mac16)) {
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) { mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry);
if (table_entry->short_adr < 0xfffe && !thread_is_router_addr(table_entry->short_adr)) {
mle_class_remove_entry(cur->id, table_entry);
} }
} }
} }
@ -1006,17 +1004,14 @@ static void thread_router_bootstrap_invalid_child_information_clear(protocol_int
tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc); tr_debug("Thread Short address changed old: %x new: %x", cur->thread_info->routerShortAddress, router_rloc);
mle_neigh_table_list_t *entry_list = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!entry_list) {
return;
}
// scrub neighbours with child addresses that are not ours // scrub neighbours with child addresses that are not ours
ns_list_foreach_safe(mle_neigh_table_entry_t, table_entry, entry_list) { ns_list_foreach_safe(mac_neighbor_table_entry_t, table_entry, mac_table_list) {
if (table_entry->short_adr < 0xfffe && if (table_entry->mac16 < 0xfffe &&
!thread_is_router_addr(table_entry->short_adr) && !thread_is_router_addr(table_entry->mac16) &&
thread_router_addr_from_addr(table_entry->short_adr) != router_rloc) { thread_router_addr_from_addr(table_entry->mac16) != router_rloc) {
mle_class_remove_entry(cur->id, table_entry); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), table_entry);
} }
} }
} }
@ -1105,7 +1100,7 @@ void thread_router_bootstrap_router_id_request(protocol_interface_info_entry_t *
} }
} }
static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req,mle_neigh_table_entry_t *neigh_info) static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *cur, uint8_t *dstAddress,thread_pending_child_id_req_t *child_req, struct mac_neighbor_table_entry *neigh_info)
{ {
uint16_t len = 12 + 4; //Leader data and short address uint16_t len = 12 + 4; //Leader data and short address
uint8_t *ptr; uint8_t *ptr;
@ -1117,7 +1112,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c
return -1; return -1;
} }
if (neigh_info->mode & MLE_THREAD_REQ_FULL_DATA_SET) { if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, neigh_info->index)) {
fullList = true; fullList = true;
} }
@ -1163,7 +1158,7 @@ static int mle_attach_child_id_response_build(protocol_interface_info_entry_t *c
ptr = mle_general_write_source_address(ptr, cur); ptr = mle_general_write_source_address(ptr, cur);
if (child_req->shortAddressReq) { if (child_req->shortAddressReq) {
ptr = mle_tlv_write_short_address(ptr, neigh_info->short_adr); ptr = mle_tlv_write_short_address(ptr, neigh_info->mac16);
} }
if (child_req->routeReq) { if (child_req->routeReq) {
@ -1214,12 +1209,10 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t
if (router_address >= 0xfffe) { if (router_address >= 0xfffe) {
return 0; return 0;
} }
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_table) {
return -1; ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
} if (thread_router_addr_from_addr(cur_entry->mac16) == router_address) {
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) {
if (thread_router_addr_from_addr(cur_entry->short_adr) == router_address) {
child_count++; child_count++;
} }
} }
@ -1228,22 +1221,19 @@ uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t
static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur) static uint16_t thread_router_bootstrap_child_address_generate(protocol_interface_info_entry_t *cur)
{ {
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_table) {
return -1;
}
if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) { if (thread_router_bootstrap_child_count_get(cur) >= cur->thread_info->maxChildCount) {
tr_info("Maximum count %d reached", cur->thread_info->maxChildCount); tr_info("Maximum count %d reached", cur->thread_info->maxChildCount);
return 0xffff; return 0xfffe;
} }
bool address_allocated = false; bool address_allocated = false;
for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) { for (uint16_t i = 0; i < cur->thread_info->maxChildCount; i++) {
address_allocated = false; address_allocated = false;
cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1; cur->thread_info->lastAllocatedChildAddress = (cur->thread_info->lastAllocatedChildAddress % THREAD_MAX_CHILD_ID_COUNT) + 1;
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if ( (cur_entry->short_adr & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) { if ( (cur_entry->mac16 & THREAD_CHILD_MASK) == cur->thread_info->lastAllocatedChildAddress) {
address_allocated = true; address_allocated = true;
break; break;
} }
@ -1254,29 +1244,29 @@ static uint16_t thread_router_bootstrap_child_address_generate(protocol_interfac
} }
if (address_allocated){ if (address_allocated){
// all possible addresses already allocated // all possible addresses already allocated
return 0xffff; return 0xfffe;
} }
return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress); return ((mac_helper_mac16_address_get(cur) & THREAD_ROUTER_MASK) | cur->thread_info->lastAllocatedChildAddress);
} }
static bool thread_child_id_request(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *entry_temp) static bool thread_child_id_request(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *entry_temp)
{ {
//Remove All Short address links from router //Remove All Short address links from router
if (entry_temp->short_adr != 0xffff) { if (entry_temp->mac16 < 0xfffe) {
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
} }
//allocate child address if current is router, 0xffff or not our child //allocate child address if current is router, 0xffff or not our child
if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->short_adr)) { if (!thread_addr_is_child(mac_helper_mac16_address_get(cur), entry_temp->mac16)) {
entry_temp->short_adr = thread_router_bootstrap_child_address_generate(cur); entry_temp->mac16 = thread_router_bootstrap_child_address_generate(cur);
} }
if (entry_temp->short_adr == 0xffff) { if (entry_temp->mac16 >= 0xfffe) {
return false; return false;
} }
// Store this child info to the NVM // Store this child info to the NVM
thread_dynamic_storage_child_info_store(cur->id, entry_temp); thread_dynamic_storage_child_info_store(cur, entry_temp);
//} //}
return true; return true;
} }
@ -1311,7 +1301,7 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c
memcpy(&ll64[8], req->euid64 , 8); memcpy(&ll64[8], req->euid64 , 8);
ll64[8] ^= 2; ll64[8] ^= 2;
//Allocate entry //Allocate entry
mle_neigh_table_entry_t *entry_temp = mle_class_get_entry_by_ll64(cur->id, req->linkMargin, ll64, true, &new_neigbour); mac_neighbor_table_entry_t *entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), ll64, true, &new_neigbour);
if (!entry_temp) { if (!entry_temp) {
//Send link reject //Send link reject
@ -1319,44 +1309,48 @@ void thread_router_bootstrap_child_id_handler(protocol_interface_info_entry_t *c
goto free_request; goto free_request;
} }
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, req->linkMargin, new_neigbour);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
// If mac frame couter is less than previous we need to leave the old one // If mac frame couter is less than previous we need to leave the old one
//Update or set neigh info //Update or set neigh info
entry_temp->holdTime = 90; mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, req->timeout);
mle_mode_parse_to_mac_entry(entry_temp, req->mode);
mle_entry_timeout_update(entry_temp, req->timeout); thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, req->mode);
entry_temp->mode = req->mode; entry_temp->connected_device = 1;
entry_temp->threadNeighbor = true; mle_service_frame_counter_entry_add(cur->id, entry_temp->index, req->mleFrameCounter);
entry_temp->handshakeReady = 1;
entry_temp->mle_frame_counter = req->mleFrameCounter;
if (req->shortAddressReq) { if (req->shortAddressReq) {
if (!thread_child_id_request(cur, entry_temp)) { if (!thread_child_id_request(cur, entry_temp)) {
mle_class_remove_entry(cur->id, entry_temp); mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
thread_link_reject_send(cur, ll64); thread_link_reject_send(cur, ll64);
goto free_request; goto free_request;
} }
} }
if (new_neigbour) { if (new_neigbour) {
mac_helper_devicetable_set(entry_temp, cur, req->frameCounter, req->keyId, new_neigbour); mlme_device_descriptor_t device_desc;
mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,req->frameCounter, false);
mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, req->keyId, new_neigbour);
} else { } else {
// in get response handler this will update the short address from MLE table // in get response handler this will update the short address from MLE table
mlme_get_t get_req; mlme_get_t get_req;
get_req.attr = macDeviceTable; get_req.attr = macDeviceTable;
get_req.attr_index = entry_temp->attribute_index; get_req.attr_index = entry_temp->index;
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
} }
//Register MLEID if RRFD device //Register MLEID if RRFD device
if ((entry_temp->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { if (!entry_temp->ffd_device) {
uint8_t tempIPv6Address[16]; uint8_t tempIPv6Address[16];
memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8); memcpy(tempIPv6Address, thread_info(cur)->threadPrivatePrefixInfo.ulaPrefix, 8);
memcpy(&tempIPv6Address[8], req->eiid, 8); memcpy(&tempIPv6Address[8], req->eiid, 8);
memcpy(&entry_temp->mlEid, req->eiid, 8);
thread_neighbor_class_add_mleid(&cur->thread_info->neighbor_class, entry_temp->index, req->eiid);
tr_debug("Register %s", trace_ipv6(tempIPv6Address)); tr_debug("Register %s", trace_ipv6(tempIPv6Address));
//Register GP --> 16 //Register GP --> 16
thread_nd_address_registration(cur, tempIPv6Address, entry_temp->short_adr, cur->mac_parameters->pan_id, entry_temp->mac64); thread_nd_address_registration(cur, tempIPv6Address, entry_temp->mac16, cur->mac_parameters->pan_id, entry_temp->mac64, NULL);
} }
mle_attach_child_id_response_build(cur,ll64,req, entry_temp); mle_attach_child_id_response_build(cur,ll64,req, entry_temp);
@ -1371,6 +1365,7 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
lowpan_context_t *ctx; lowpan_context_t *ctx;
uint8_t tempIPv6Address[16]; uint8_t tempIPv6Address[16];
uint8_t ctxId; uint8_t ctxId;
bool new_neighbour_created;
while (data_length) { while (data_length) {
//Read //Read
@ -1383,8 +1378,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
memcpy(&tempIPv6Address[8], ptr, 8); memcpy(&tempIPv6Address[8], ptr, 8);
tr_debug("Register %s", trace_ipv6(tempIPv6Address)); tr_debug("Register %s", trace_ipv6(tempIPv6Address));
//Register GP --> 16 //Register GP --> 16
thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64); int retVal = thread_nd_address_registration(cur, tempIPv6Address, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
thread_extension_address_registration(cur, tempIPv6Address, mac64); thread_extension_address_registration(cur, tempIPv6Address, mac64, new_neighbour_created, retVal == -2);
} else { } else {
tr_debug("No Context %u", ctxId); tr_debug("No Context %u", ctxId);
} }
@ -1403,8 +1398,8 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
} }
} else { } else {
//Register GP --> 16 //Register GP --> 16
thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64); int retVal = thread_nd_address_registration(cur, ptr, mac16, cur->mac_parameters->pan_id, mac64, &new_neighbour_created);
thread_extension_address_registration(cur, ptr, mac64); thread_extension_address_registration(cur, ptr, mac64, new_neighbour_created, retVal == -2);
} }
ptr += 16; ptr += 16;
@ -1415,14 +1410,12 @@ static void thread_address_registration_tlv_parse(uint8_t *ptr, uint16_t data_le
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers) void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, mle_security_header_t *security_headers)
{ {
(void) interface_id;
thread_leader_data_t leaderData; thread_leader_data_t leaderData;
mle_neigh_table_entry_t *entry_temp; mac_neighbor_table_entry_t *entry_temp;
bool rssiTLV; bool rssiTLV;
bool leaderDataReceived; bool leaderDataReceived;
protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); protocol_interface_info_entry_t *cur = mle_msg->interface_ptr;
if (!cur) {
return;
}
//TLV REQUSTED //TLV REQUSTED
if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) { if (mle_tlv_type_requested(MLE_TYPE_RSSI, mle_msg->data_ptr, mle_msg->data_length)) {
@ -1471,9 +1464,13 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
} }
// parent request received // parent request received
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) { if (entry_temp) {
entry_temp->mode = (MLE_FFD_DEV | MLE_RX_ON_IDLE | MLE_THREAD_REQ_FULL_DATA_SET); //Set MAC modes
mle_mode_parse_to_mac_entry(entry_temp, (MLE_FFD_DEV | MLE_RX_ON_IDLE));
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, MLE_THREAD_REQ_FULL_DATA_SET);
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index, linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
} }
if(!entry_temp) { if(!entry_temp) {
if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) { if (!mle_tlv_read_8_bit_tlv(MLE_TYPE_MODE, mle_msg->data_ptr, mle_msg->data_length, &mode)) {
@ -1487,17 +1484,17 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
return; return;
} }
if (mle_class_free_entry_count_get(cur->id) < 1) { if (mle_class_free_entry_count_get(cur) < 1) {
tr_info("Drop MLE message: no space left in the MLE table"); tr_info("Drop MLE message: no space left in the MLE table");
return; return;
} }
if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur->id) >= THREAD_MAX_MTD_CHILDREN) { if ((mode & MLE_DEV_MASK) == MLE_RFD_DEV && mle_class_rfd_entry_count_get(cur) >= THREAD_MAX_MTD_CHILDREN) {
tr_info("Drop MLE message: maximum MTD child count reached."); tr_info("Drop MLE message: maximum MTD child count reached.");
return; return;
} }
if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur->id) >= THREAD_MAX_SED_CHILDREN) { if (!(mode & MLE_RX_ON_IDLE) && mle_class_sleepy_entry_count_get(cur) >= THREAD_MAX_SED_CHILDREN) {
tr_info("Drop MLE message: maximum SED child count reached."); tr_info("Drop MLE message: maximum SED child count reached.");
return; return;
} }
@ -1571,10 +1568,14 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
return; return;
} }
// If we are in REED mode and receive child IR request from our parent, call connection error. // If we are in REED mode and receive child ID request from our parent, call connection error.
if (thread_am_reed(cur)) { if (thread_am_reed(cur)) {
if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) { if (thread_router_parent_address_check(cur, mle_msg->packet_src_address)) {
tr_debug("Child ID req from own parent -> connection error"); tr_debug("Child ID req from own parent -> connection error");
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (entry_temp) {
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
}
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
return; return;
} }
@ -1714,7 +1715,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { if (mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
//Correct TLV's lets response //Correct TLV's lets response
if (!thread_is_router_addr(shortAddress)) { if (!thread_is_router_addr(shortAddress)) {
if (leaderDataReceived && thread_info(cur)->thread_leader_data->partitionId == leaderData.partitionId) { if (leaderDataReceived && thread_partition_match(cur, &leaderData)) {
//REED or end device send response //REED or end device send response
thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen); thread_router_accept_to_endevice(cur, mle_msg, challengeTlv.dataPtr, challengeTlv.tlvLen);
} else { } else {
@ -1726,7 +1727,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
return; return;
} }
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) { if (!mle_tlv_read_16_bit_tlv(MLE_TYPE_SRC_ADDRESS, mle_msg->data_ptr, mle_msg->data_length, &shortAddress)) {
@ -1738,9 +1739,11 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
* *
*/ */
if (entry_temp && entry_temp->handshakeReady) { if (entry_temp && entry_temp->connected_device) {
mle_entry_timeout_refresh(entry_temp); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen); thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
thread_router_synch_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, requestTlv.dataPtr, requestTlv.tlvLen);
} }
} }
bool update_mac_mib = false; bool update_mac_mib = false;
@ -1759,7 +1762,7 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
} }
//validate partition id //validate partition id
if (thread_info(cur)->thread_leader_data->partitionId != leaderData.partitionId) { if (!thread_partition_match(cur, &leaderData)) {
tr_debug("Drop link request from wrong partition"); tr_debug("Drop link request from wrong partition");
return; return;
} }
@ -1767,26 +1770,28 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
if (entry_temp) { if (entry_temp) {
/*remove from child list when becoming router*/ /*remove from child list when becoming router*/
// Was this previously our child? If yes, update. // Was this previously our child? If yes, update.
if ((entry_temp->short_adr & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->short_adr) == cur->thread_info->routerShortAddress) { if ((entry_temp->mac16 & THREAD_CHILD_MASK) && thread_router_addr_from_addr(entry_temp->mac16) == cur->thread_info->routerShortAddress) {
thread_dynamic_storage_child_info_clear(cur->id, entry_temp); thread_dynamic_storage_child_info_clear(cur->id, entry_temp);
protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->short_adr); protocol_6lowpan_release_short_link_address_from_neighcache(cur, entry_temp->mac16);
} }
update_mac_mib = true; update_mac_mib = true;
entry_temp->short_adr = shortAddress; // short address refreshed entry_temp->mac16 = shortAddress; // short address refreshed
if (entry_temp->handshakeReady) { if (entry_temp->connected_device) {
if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) { if (mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisteredTlv)) {
if (thread_rfd_device(entry_temp->mode)) { if (!entry_temp->ffd_device) {
thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); thread_address_registration_tlv_parse(addressRegisteredTlv.dataPtr, addressRegisteredTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64);
} }
} }
mle_entry_timeout_refresh(entry_temp); mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) { if (!mle_neigh_entry_frame_counter_update(entry_temp, mle_msg->data_ptr, mle_msg->data_length, cur, security_headers->KeyIndex) && update_mac_mib) {
//GET //GET
mlme_get_t get_req; mlme_get_t get_req;
get_req.attr = macDeviceTable; get_req.attr = macDeviceTable;
get_req.attr_index = entry_temp->attribute_index; get_req.attr_index = entry_temp->index;
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
} }
response_type = MLE_COMMAND_ACCEPT; response_type = MLE_COMMAND_ACCEPT;
@ -1853,32 +1858,41 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
createNew = thread_bootstrap_link_create_check(cur, shortAddress); createNew = thread_bootstrap_link_create_check(cur, shortAddress);
//Send Response //Send Response
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, createNew, &new_entry);
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, createNew, &new_entry);
if (entry_temp) { if (entry_temp) {
thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, new_entry);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) { if (security_headers->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource)); thread_management_key_synch_req(cur->id, common_read_32_bit(security_headers->Keysource));
} }
entry_temp->threadNeighbor = true; entry_temp->mac16 = shortAddress;
entry_temp->short_adr = shortAddress; mlme_device_descriptor_t device_desc;
mac_helper_devicetable_set(entry_temp, cur, llFrameCounter, security_headers->KeyIndex, new_entry); mac_helper_device_description_write(cur, &device_desc, entry_temp->mac64, entry_temp->mac16,llFrameCounter, false);
if (entry_temp->timeout_rx) { mac_helper_devicetable_set(&device_desc, cur, entry_temp->index, security_headers->KeyIndex, new_entry);
mle_entry_timeout_refresh(entry_temp);
uint32_t link_lifetime;
if (new_entry) {
link_lifetime = THREAD_DEFAULT_LINK_LIFETIME;
} else { } else {
mle_entry_timeout_update(entry_temp, THREAD_DEFAULT_LINK_LIFETIME); link_lifetime = entry_temp->link_lifetime;
} }
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, link_lifetime);
if (thread_is_router_addr(shortAddress)) { if (thread_is_router_addr(shortAddress)) {
entry_temp->handshakeReady = 1; entry_temp->connected_device = 1;
} }
entry_temp->mode |= MLE_THREAD_REQ_FULL_DATA_SET; thread_neighbor_class_request_full_data_setup_set(&cur->thread_info->neighbor_class, entry_temp->index, true);
thread_routing_update_link_margin(cur, entry_temp->short_adr, linkMargin, linkMarginfronNeigh); thread_routing_update_link_margin(cur, entry_temp->mac16, linkMargin, linkMarginfronNeigh);
//Read Source address and Challenge //Read Source address and Challenge
mac_data_poll_protocol_poll_mode_decrement(cur); mac_data_poll_protocol_poll_mode_decrement(cur);
thread_router_accept_request_build(cur, mle_msg, entry_temp->short_adr, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin); thread_router_accept_request_build(cur, mle_msg, entry_temp->mac16, challengeTlv.dataPtr, challengeTlv.tlvLen, MLE_COMMAND_ACCEPT, rssiTLV, linkMargin);
blacklist_update(mle_msg->packet_src_address, true); blacklist_update(mle_msg->packet_src_address, true);
} else { } else {
@ -1899,11 +1913,12 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
mle_tlv_info_t addressRegisterTlv = {0}; mle_tlv_info_t addressRegisterTlv = {0};
mle_tlv_info_t challengeTlv = {0}; mle_tlv_info_t challengeTlv = {0};
mle_tlv_info_t tlv_req = {0}; mle_tlv_info_t tlv_req = {0};
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL); entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) { if (mle_tlv_read_8_bit_tlv(MLE_TYPE_STATUS, mle_msg->data_ptr, mle_msg->data_length, &status)) {
if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) { if (1 == status && thread_check_is_this_my_parent(cur, entry_temp)) {
tr_debug("parent has removed REED"); tr_debug("Parent has removed REED");
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), entry_temp);
thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL); thread_bootstrap_connection_error(cur->id, CON_PARENT_CONNECT_DOWN, NULL);
} }
return; return;
@ -1923,9 +1938,10 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
} }
//Keep alive updated //Keep alive updated
entry_temp->ttl = entry_temp->timeout_rx; thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
entry_temp->last_contact_time = protocol_core_monotonic_time; thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
entry_temp->mode = mode; mle_mode_parse_to_mac_entry(entry_temp, mode);
thread_neighbor_class_mode_parse_to_entry(&cur->thread_info->neighbor_class, entry_temp->index, mode);
addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED; addressRegisterTlv.tlvType = MLE_TYPE_UNASSIGNED;
mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv); mle_tlv_read_tlv(MLE_TYPE_ADDRESS_REGISTRATION, mle_msg->data_ptr, mle_msg->data_length, &addressRegisterTlv);
@ -1935,25 +1951,26 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req); mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &tlv_req);
if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION && if (addressRegisterTlv.tlvType == MLE_TYPE_ADDRESS_REGISTRATION &&
thread_rfd_device(entry_temp->mode)) { !entry_temp->ffd_device) {
tr_debug("Register child address"); tr_debug("Register child address");
thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->short_adr, entry_temp->mac64); thread_address_registration_tlv_parse(addressRegisterTlv.dataPtr, addressRegisterTlv.tlvLen, cur, entry_temp->mac16, entry_temp->mac64);
} }
if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) { if (mle_tlv_read_32_bit_tlv(MLE_TYPE_TIMEOUT, mle_msg->data_ptr, mle_msg->data_length, &timeout)) {
tr_debug("Setting child timeout, value=%"PRIu32, timeout); tr_debug("Setting child timeout, value=%"PRIu32, timeout);
entry_temp->holdTime = 90; mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, timeout);
mle_entry_timeout_update(entry_temp, timeout); } else {
mac_neighbor_table_neighbor_refresh(mac_neighbor_info(cur), entry_temp, entry_temp->link_lifetime);
} }
if (!leaderDataReceived) { if (!leaderDataReceived) {
tr_debug("Child synch req"); tr_debug("Child synch req");
} }
tr_debug("Keep-Alive -->Respond Child"); tr_debug("Keep-Alive -->Respond Child");
//Response //Response
thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->short_adr, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp); thread_child_update_response(cur, mle_msg->packet_src_address, mode, entry_temp->mac16, timeout, &addressRegisterTlv, &tlv_req, &challengeTlv, active_timestamp, pending_timestamp);
} }
break; break;
@ -1969,11 +1986,16 @@ void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *
case MLE_COMMAND_DATA_REQUEST: { case MLE_COMMAND_DATA_REQUEST: {
mle_tlv_info_t requestTlv; mle_tlv_info_t requestTlv;
tr_info("Recv Router Data Request"); tr_info("Recv Router Data Request");
entry_temp = mle_class_get_entry_by_ll64(cur->id, linkMargin, mle_msg->packet_src_address, false, NULL);
entry_temp = mac_neighbor_entry_get_by_ll64(mac_neighbor_info(cur), mle_msg->packet_src_address, false, NULL);
if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) { if (!entry_temp || !mle_tlv_read_tlv(MLE_TYPE_TLV_REQUEST, mle_msg->data_ptr, mle_msg->data_length, &requestTlv)) {
return; return;
} }
mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, entry_temp->mode); thread_neighbor_class_update_link(&cur->thread_info->neighbor_class, entry_temp->index,linkMargin, false);
thread_neighbor_last_communication_time_update(&cur->thread_info->neighbor_class, entry_temp->index);
uint8_t mode = mle_mode_write_from_mac_entry(entry_temp);
mode |= thread_neighbor_class_mode_write_from_entry(&cur->thread_info->neighbor_class, entry_temp->index);
mle_build_and_send_data_response_msg(cur, mle_msg->packet_src_address, mle_msg->data_ptr, mle_msg->data_length, &requestTlv, mode);
} }
break; break;
default: default:
@ -2184,7 +2206,10 @@ void thread_router_bootstrap_child_id_reject(protocol_interface_info_entry_t *cu
while (req) { while (req) {
tr_debug("Remove entry from list"); tr_debug("Remove entry from list");
//Remove entry from list //Remove entry from list
mle_class_remove_neighbour(cur->id, req->euid64, ADDR_802_15_4_LONG); mac_neighbor_table_entry_t *neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), req->euid64, ADDR_802_15_4_LONG);
if (neighbor) {
mac_neighbor_table_neighbor_remove(mac_neighbor_info(cur), neighbor);
}
ns_dyn_mem_free(req); ns_dyn_mem_free(req);
req = thread_child_id_request_entry_get_from_the_list(cur); req = thread_child_id_request_entry_get_from_the_list(cur);
@ -2206,7 +2231,6 @@ void thread_router_bootstrap_active_router_attach(protocol_interface_info_entry_
cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE; cur->lowpan_info |= INTERFACE_NWK_ROUTER_DEVICE;
thread_routing_activate(&cur->thread_info->routing); thread_routing_activate(&cur->thread_info->routing);
thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS); thread_router_synch_new_router(cur, ADDR_LINK_LOCAL_ALL_ROUTERS);
mle_class_mode_set(cur->id, MLE_CLASS_ROUTER);
thread_bootstrap_ready(cur); thread_bootstrap_ready(cur);
thread_bootstrap_network_prefixes_process(cur); thread_bootstrap_network_prefixes_process(cur);
thread_nd_service_activate(cur->id); thread_nd_service_activate(cur->id);
@ -2226,7 +2250,7 @@ static int thread_validate_own_routeid_from_new_mask(const uint8_t *master_route
return ret_val; return ret_val;
} }
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry) int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry)
{ {
(void) route_len; (void) route_len;
@ -2239,9 +2263,9 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur,
route_data = route_tlv; route_data = route_tlv;
uint16_t mac16 = mac_helper_mac16_address_get(cur); uint16_t mac16 = mac_helper_mac16_address_get(cur);
if (!thread_is_router_addr(entry->short_adr)) { if (!thread_is_router_addr(entry->mac16)) {
// Received route tlv from non router ignore // Received route tlv from non router ignore
tr_info("drop route Processing from end device %x", entry->short_adr); tr_info("drop route Processing from end device %x", entry->mac16);
return 0; return 0;
} }
@ -2251,21 +2275,20 @@ int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur,
thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer); thread_routing_leader_connection_validate(cur->thread_info,routing->networkFragmentationTimer);
routing->networkFragmentationTimer = 0; routing->networkFragmentationTimer = 0;
if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) { if (thread_validate_own_routeid_from_new_mask(router_id_mask, thread_router_id_from_addr(mac16)) != 0) {
tr_debug("RouterID not valid any More"); tr_debug("RouterID not valid any More");
thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL); thread_bootstrap_connection_error(cur->id, CON_ERROR_NETWORK_KICK, NULL);
return 0; return 0;
} }
} }
} else if (!thread_info(cur)->thread_endnode_parent || } else if (!thread_info(cur)->thread_endnode_parent ||
thread_info(cur)->thread_endnode_parent->shortAddress != entry->short_adr ) { thread_info(cur)->thread_endnode_parent->shortAddress != entry->mac16 ) {
return 0; return 0;
} }
/* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */ /* XXX Is short_src_adr ever reset? Is it undefined if info not in msg? */
/* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */ /* Don't add routing link if MLE link is NOT bi-directional (i.e. we can only hear) */
if (entry->handshakeReady) { if (entry->connected_device) {
thread_routing_add_link(cur, entry->short_adr, linkMargin, route_id_seq, router_id_mask, route_data, false); thread_routing_add_link(cur, entry->mac16, linkMargin, route_id_seq, router_id_mask, route_data, false);
} }
return 0; return 0;
@ -2342,6 +2365,13 @@ static void thread_reed_advertisements_cb(void* arg)
protocol_interface_info_entry_t *cur = arg; protocol_interface_info_entry_t *cur = arg;
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL; cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = NULL;
if (cur->nwk_bootstrap_state != ER_BOOTSRAP_DONE && cur->nwk_bootstrap_state != ER_MLE_ATTACH_READY) {
/* Own attach is ongoing, try to send advertisement after few seconds */
cur->thread_info->routerSelectParameters.reedAdvertisementTimeout = eventOS_timeout_ms(thread_reed_advertisements_cb, 2 * 1000, cur);
return;
}
if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED && if (cur->thread_info->thread_attached_state == THREAD_STATE_CONNECTED &&
cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){ cur->thread_info->thread_device_mode == THREAD_DEVICE_MODE_ROUTER){
thread_reed_advertise(cur); thread_reed_advertise(cur);
@ -2461,23 +2491,22 @@ void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_
return; return;
} }
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress) void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress)
{ {
if (entry_temp) { if (entry_temp) {
entry_temp->threadNeighbor = true;
if (entry_temp->timeout_rx == 0 || thread_is_router_addr(shortAddress)) { if (thread_is_router_addr(shortAddress)) {
entry_temp->timeout_rx = THREAD_DEFAULT_LINK_LIFETIME / MLE_TIMER_TICKS_SECONDS; entry_temp->link_lifetime = THREAD_DEFAULT_LINK_LIFETIME;
entry_temp->timeout_rx++; entry_temp->link_lifetime++;
} }
if (thread_is_router_addr(shortAddress)) { if (thread_is_router_addr(shortAddress)) {
//Update MAC Security PIB table by get & set Operation //Update MAC Security PIB table by get & set Operation
mlme_get_t get_req; mlme_get_t get_req;
get_req.attr = macDeviceTable; get_req.attr = macDeviceTable;
get_req.attr_index = entry_temp->attribute_index; get_req.attr_index = entry_temp->index;
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req); cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
entry_temp->ttl = entry_temp->timeout_rx; entry_temp->lifetime = entry_temp->link_lifetime;
} }
} else { } else {
// //
@ -2661,19 +2690,18 @@ static int thread_router_bootstrap_network_data_propagation(protocol_interface_i
static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate) static void thread_router_bootstrap_network_data_push_to_sleep_child(protocol_interface_info_entry_t *cur, bool stableDataUpdate)
{ {
uint8_t childLinkLocalAddress[16]; uint8_t childLinkLocalAddress[16];
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(cur->id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8); memcpy(childLinkLocalAddress, ADDR_LINK_LOCAL_PREFIX, 8);
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if (cur_entry->threadNeighbor) { if (!cur_entry->rx_on_idle) {
if (!(cur_entry->mode & MLE_RX_ON_IDLE)) { memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8);
memcpy(&childLinkLocalAddress[8], cur_entry->mac64, 8); childLinkLocalAddress[8] ^= 2;
childLinkLocalAddress[8] ^= 2; if (thread_neighbor_class_request_full_data_setup(&cur->thread_info->neighbor_class, cur_entry->index)) {
if (cur_entry->mode & MLE_THREAD_REQ_FULL_DATA_SET) { thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true);
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, true); } else {
} else { if (stableDataUpdate) {
if (stableDataUpdate) { thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false);
thread_router_bootstrap_network_data_propagation(cur, childLinkLocalAddress, false);
}
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -43,13 +43,14 @@ struct protocol_interface_info_entry;
struct thread_info_s; struct thread_info_s;
struct mle_security_header; struct mle_security_header;
struct buffer; struct buffer;
struct mac_neighbor_table_entry;
void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_reed_advertisements_start(protocol_interface_info_entry_t *cur);
void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_reed_merge_advertisement(protocol_interface_info_entry_t *cur);
int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur); int thread_router_bootstrap_mle_advertise(struct protocol_interface_info_entry *cur);
void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_child_information_clear(protocol_interface_info_entry_t *cur);
int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, mle_neigh_table_entry_t *child); int thread_router_bootstrap_reset_child_info(protocol_interface_info_entry_t *cur, struct mac_neighbor_table_entry *child);
uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur); uint16_t thread_router_bootstrap_child_count_get(protocol_interface_info_entry_t *cur);
void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_child_id_handler(struct protocol_interface_info_entry *cur);
void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_child_id_reject(struct protocol_interface_info_entry *cur);
@ -61,11 +62,11 @@ int thread_router_bootstrap_link_synch_start(struct protocol_interface_info_entr
bool thread_router_bootstrap_router_downgrade(struct protocol_interface_info_entry *cur); bool thread_router_bootstrap_router_downgrade(struct protocol_interface_info_entry *cur);
bool thread_router_bootstrap_reed_upgrade(struct protocol_interface_info_entry *cur); bool thread_router_bootstrap_reed_upgrade(struct protocol_interface_info_entry *cur);
void thread_router_bootstrap_active_router_attach(struct protocol_interface_info_entry *cur); void thread_router_bootstrap_active_router_attach(struct protocol_interface_info_entry *cur);
int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, mle_neigh_table_entry_t *entry); int thread_router_bootstrap_route_tlv_push(protocol_interface_info_entry_t *cur, uint8_t *route_tlv, uint8_t route_len, uint8_t linkMargin, struct mac_neighbor_table_entry *entry);
void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, struct mle_security_header *security_headers); void thread_router_bootstrap_mle_receive_cb(int8_t interface_id, mle_message_t *mle_msg, struct mle_security_header *security_headers);
void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks); void thread_router_bootstrap_timer(protocol_interface_info_entry_t *cur, uint32_t ticks);
uint32_t thread_router_bootstrap_random_upgrade_jitter(); uint32_t thread_router_bootstrap_random_upgrade_jitter(void);
void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, mle_neigh_table_entry_t *entry_temp, uint16_t shortAddress); void thread_router_bootstrap_advertiment_analyze(protocol_interface_info_entry_t *cur, uint8_t *src_address, struct mac_neighbor_table_entry *entry_temp, uint16_t shortAddress);
void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf); void thread_router_bootstrap_multicast_forwarder_enable(protocol_interface_info_entry_t *cur, buffer_t *buf);
void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur); void thread_router_bootstrap_anycast_address_register(protocol_interface_info_entry_t *cur);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -52,6 +52,7 @@
#include "6LoWPAN/Thread/thread_routing.h" #include "6LoWPAN/Thread/thread_routing.h"
#include "6LoWPAN/Thread/thread_leader_service.h" #include "6LoWPAN/Thread/thread_leader_service.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#define TRACE_GROUP "trou" #define TRACE_GROUP "trou"
@ -183,7 +184,7 @@ static inline thread_link_quality_e thread_quality_combine(thread_link_quality_e
/* Return the quality (worse of incoming and outgoing quality) for a neighbour router */ /* Return the quality (worse of incoming and outgoing quality) for a neighbour router */
static inline thread_link_quality_e thread_neighbour_router_quality(const thread_router_link_t *neighbour) static inline thread_link_quality_e thread_neighbour_router_quality(const thread_router_link_t *neighbour)
{ {
return thread_quality_combine(neighbour->incoming_quality, neighbour->outgoing_quality); return thread_quality_combine((thread_link_quality_e) neighbour->incoming_quality, (thread_link_quality_e) neighbour->outgoing_quality);
} }
@ -265,8 +266,8 @@ static int_fast8_t thread_route_fn(
uint16_t dest_router_addr = thread_router_addr_from_addr(dest); uint16_t dest_router_addr = thread_router_addr_from_addr(dest);
if (dest_router_addr == mac16) { if (dest_router_addr == mac16) {
/* We're this device's parent - transmit direct to it */ /* We're this device's parent - transmit direct to it */
mle_neigh_table_entry_t *entry = mle_class_get_by_link_address(cur->id, dest_addr, ADDR_802_15_4_SHORT); mac_neighbor_table_entry_t *entry = mac_neighbor_table_address_discover(mac_neighbor_info(cur), dest_addr, ADDR_802_15_4_SHORT);
if (!entry || (entry->mode & MLE_DEV_MASK) == MLE_RFD_DEV) { if (!entry || !entry->ffd_device) {
/* To cover some of draft-kelsey-thread-network-data-00, we send the /* To cover some of draft-kelsey-thread-network-data-00, we send the
* packet up to our own IP layer in the case where it's addressed to * packet up to our own IP layer in the case where it's addressed to
* an unrecognised child. The special IP forwarding rules can then * an unrecognised child. The special IP forwarding rules can then
@ -690,8 +691,8 @@ int_fast8_t thread_routing_add_link(protocol_interface_info_entry_t *cur,
if (our_quality_to_other_neighbour < QUALITY_10dB) { if (our_quality_to_other_neighbour < QUALITY_10dB) {
continue; continue;
} }
thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT; thread_link_quality_e neighbours_incoming_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_IN_MASK) >> ROUTE_DATA_IN_SHIFT);
thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT; thread_link_quality_e neighbours_outgoing_quality_to_other_neighbour = (thread_link_quality_e) ((byte & ROUTE_DATA_OUT_MASK) >> ROUTE_DATA_OUT_SHIFT);
thread_link_quality_e neighbours_quality_to_other_neighbour = thread_quality_combine(neighbours_incoming_quality_to_other_neighbour, thread_link_quality_e neighbours_quality_to_other_neighbour = thread_quality_combine(neighbours_incoming_quality_to_other_neighbour,
neighbours_outgoing_quality_to_other_neighbour); neighbours_outgoing_quality_to_other_neighbour);
if (neighbours_quality_to_other_neighbour < our_quality_to_other_neighbour) { if (neighbours_quality_to_other_neighbour < our_quality_to_other_neighbour) {
@ -975,6 +976,21 @@ static void thread_trickle_accelerate(trickle_t *t, const trickle_params_t *para
} }
} }
void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks)
{
trickle_t *t =&routing->mle_advert_timer;
if (!trickle_running(t, &thread_mle_advert_trickle_params)) {
return;
}
if ((t->t > t->now) && (t->t - t->now < ticks)) {
/* advance trickle elapsing time by number of ticks */
t->t = t->t + ticks - (t->t - t->now);
tr_debug("trickle advanced to %d, now %d ", t->t, t->now);
}
}
// This functions speeds up next advertisement depending on the disconnect period to leader // This functions speeds up next advertisement depending on the disconnect period to leader
void thread_routing_leader_connection_validate(thread_info_t *thread, uint16_t disconnect_period) void thread_routing_leader_connection_validate(thread_info_t *thread, uint16_t disconnect_period)
{ {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -187,6 +187,7 @@ void thread_routing_free(thread_routing_info_t *routing);
void thread_routing_activate(thread_routing_info_t *routing); void thread_routing_activate(thread_routing_info_t *routing);
void thread_routing_deactivate(thread_routing_info_t *routing); void thread_routing_deactivate(thread_routing_info_t *routing);
bool thread_routing_timer(struct thread_info_s *thread, uint8_t ticks); bool thread_routing_timer(struct thread_info_s *thread, uint8_t ticks);
void thread_routing_trickle_advance(thread_routing_info_t *routing, uint16_t ticks);
void thread_routing_leader_connection_validate(struct thread_info_s *thread, uint16_t disconnect_period); void thread_routing_leader_connection_validate(struct thread_info_s *thread, uint16_t disconnect_period);
void thread_routing_set_mesh_callbacks(protocol_interface_info_entry_t *cur); void thread_routing_set_mesh_callbacks(protocol_interface_info_entry_t *cur);
@ -233,6 +234,7 @@ int_fast8_t thread_routing_get_route_data(protocol_interface_info_entry_t *cur,
#define thread_routing_activate(routing) #define thread_routing_activate(routing)
#define thread_routing_deactivate(routing) #define thread_routing_deactivate(routing)
#define thread_routing_timer(thread, ticks) false #define thread_routing_timer(thread, ticks) false
#define thread_routing_trickle_advance(routing, ticks)
#define thread_routing_leader_connection_validate(thread, disconnect_period) #define thread_routing_leader_connection_validate(thread, disconnect_period)
#define thread_routing_set_mesh_callbacks(cur) #define thread_routing_set_mesh_callbacks(cur)
#define thread_routing_cost_get_by_router_id(routing, routerId) (0) #define thread_routing_cost_get_by_router_id(routing, routerId) (0)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2017, Arm Limited and affiliates. * Copyright (c) 2014-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -49,11 +49,13 @@
#include "6LoWPAN/Thread/thread_discovery.h" #include "6LoWPAN/Thread/thread_discovery.h"
#include "6LoWPAN/Thread/thread_nvm_store.h" #include "6LoWPAN/Thread/thread_nvm_store.h"
#include "6LoWPAN/Thread/thread_extension_bootstrap.h" #include "6LoWPAN/Thread/thread_extension_bootstrap.h"
#include "6LoWPAN/Thread/thread_neighbor_class.h"
#include "MLE/mle.h" #include "MLE/mle.h"
#include "thread_meshcop_lib.h" #include "thread_meshcop_lib.h"
#include "thread_diagcop_lib.h" #include "thread_diagcop_lib.h"
#include "coap_service_api.h" #include "coap_service_api.h"
#include "Service_Libs/mle_service/mle_service_api.h" #include "Service_Libs/mle_service/mle_service_api.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#define TRACE_GROUP "tapi" #define TRACE_GROUP "tapi"
@ -452,7 +454,7 @@ int thread_test_key_rotation_update(int8_t interface_id, uint32_t thrKeyRotation
if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) { if (cur->configure_flags & INTERFACE_BOOTSTRAP_DEFINED) {
linkConfiguration->key_rotation = thrKeyRotation; linkConfiguration->key_rotation = thrKeyRotation;
thread_calculate_key_guard_timer(cur, linkConfiguration, false); thread_key_guard_timer_calculate(cur, linkConfiguration, false);
ret_val = 0; ret_val = 0;
} }
} }
@ -593,7 +595,7 @@ int thread_test_security_material_set(int8_t interface_id, bool enableSecurity,
mle_service_security_set_security_key(cur->id, key_material, key_index, true); mle_service_security_set_security_key(cur->id, key_material, key_index, true);
//Gen also Next Key //Gen also Next Key
thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter); thread_security_next_key_generate(cur, linkConfiguration->master_key, thrKeySequenceCounter);
thread_calculate_key_guard_timer(cur, linkConfiguration, false); thread_key_guard_timer_calculate(cur, linkConfiguration, false);
} }
} else { } else {
ret_val = 0; ret_val = 0;
@ -625,7 +627,8 @@ int thread_test_version_set(int8_t interface_id, uint8_t version)
thread_version = version; thread_version = version;
cur = protocol_stack_interface_info_get_by_id(interface_id); cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur) { if (!cur) {
return -1; /*We already stored the new Thread version above, so even if cur is NULL the version is updated.*/
return 0;
} }
cur->thread_info->version = version; cur->thread_info->version = version;
return 0; return 0;
@ -1114,22 +1117,22 @@ int8_t thread_test_child_info_get(int8_t interface_id, uint8_t index, uint16_t *
protocol_interface_info_entry_t *cur; protocol_interface_info_entry_t *cur;
uint8_t n= 0; uint8_t n= 0;
cur = protocol_stack_interface_info_get_by_id(interface_id); cur = protocol_stack_interface_info_get_by_id(interface_id);
if (!cur || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) { if (!cur || !cur->mac_parameters || !cur->thread_info || cur->thread_info->thread_device_mode != THREAD_DEVICE_MODE_ROUTER) {
return -1; return -1;
} }
uint16_t mac16 = mac_helper_mac16_address_get(cur); uint16_t mac16 = mac_helper_mac16_address_get(cur);
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_table) { if (!mac_table_list) {
return -1; return -1;
} }
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) == thread_router_addr_from_addr(mac16)) { if (thread_router_addr_from_addr(cur_entry->mac16) == thread_router_addr_from_addr(mac16)) {
if (n == index) { if (n == index) {
*short_addr = cur_entry->short_adr; *short_addr = cur_entry->mac16;
memcpy(mac64,cur_entry->mac64, 8); memcpy(mac64,cur_entry->mac64, 8);
*sleepy = (cur_entry->mode & MLE_RX_ON_IDLE) != MLE_RX_ON_IDLE; *sleepy = cur_entry->rx_on_idle != true;
*margin = cur_entry->link_margin; *margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index);
return 0; return 0;
} }
n++; n++;
@ -1156,17 +1159,17 @@ int8_t thread_test_neighbour_info_get(int8_t interface_id, uint8_t index, uint16
return -1; return -1;
} }
uint16_t mac16 = mac_helper_mac16_address_get(cur); uint16_t mac16 = mac_helper_mac16_address_get(cur);
mle_neigh_table_list_t *mle_table = mle_class_active_list_get(interface_id); mac_neighbor_table_list_t *mac_table_list = &mac_neighbor_info(cur)->neighbour_list;
if (!mle_table) { if (!mac_table_list) {
return -1; return -1;
} }
ns_list_foreach(mle_neigh_table_entry_t, cur_entry, mle_table) { ns_list_foreach(mac_neighbor_table_entry_t, cur_entry, mac_table_list) {
if (cur_entry->threadNeighbor && thread_router_addr_from_addr(cur_entry->short_adr) != thread_router_addr_from_addr(mac16)) { if (thread_router_addr_from_addr(cur_entry->mac16) != thread_router_addr_from_addr(mac16)) {
if (n == index) { if (n == index) {
*short_addr = cur_entry->short_adr; *short_addr = cur_entry->mac16;
memcpy(mac64,cur_entry->mac64, 8); memcpy(mac64,cur_entry->mac64, 8);
*margin = cur_entry->link_margin; *margin = thread_neighbor_entry_linkmargin_get(&cur->thread_info->neighbor_class, cur_entry->index);
return 0; return 0;
} }
n++; n++;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -35,6 +35,7 @@
#include "NWK_INTERFACE/Include/protocol_timer.h" #include "NWK_INTERFACE/Include/protocol_timer.h"
#include "Service_Libs/etx/etx.h" #include "Service_Libs/etx/etx.h"
#include "6LoWPAN/MAC/mac_helper.h" #include "6LoWPAN/MAC/mac_helper.h"
#include "6LoWPAN/MAC/mpx_api.h"
#include "6LoWPAN/Mesh/mesh.h" #include "6LoWPAN/Mesh/mesh.h"
#include "6LoWPAN/IPHC_Decode/iphc_decompress.h" #include "6LoWPAN/IPHC_Decode/iphc_decompress.h"
#include "lowpan_adaptation_interface.h" #include "lowpan_adaptation_interface.h"
@ -42,9 +43,15 @@
#ifdef HAVE_RPL #ifdef HAVE_RPL
#include "RPL/rpl_data.h" #include "RPL/rpl_data.h"
#endif #endif
#include "6LoWPAN/ws/ws_common.h"
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
#include "6LoWPAN/Thread/thread_common.h"
#include "6LoWPAN/ws/ws_common.h"
#define TRACE_GROUP "6lAd" #define TRACE_GROUP "6lAd"
typedef void (adaptation_etx_update_cb)(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm);
// #define EXTRA_DEBUG_EXTRA // #define EXTRA_DEBUG_EXTRA
#ifdef EXTRA_DEBUG_EXTRA #ifdef EXTRA_DEBUG_EXTRA
#define tr_debug_extra(...) tr_debug(__VA_ARGS__) #define tr_debug_extra(...) tr_debug(__VA_ARGS__)
@ -88,6 +95,9 @@ typedef struct {
uint16_t max_indirect_big_packets_total; uint16_t max_indirect_big_packets_total;
uint16_t max_indirect_small_packets_per_child; uint16_t max_indirect_small_packets_per_child;
bool fragmenter_active; /*!< Fragmenter state */ bool fragmenter_active; /*!< Fragmenter state */
adaptation_etx_update_cb *etx_update_cb;
mpx_api_t *mpx_api;
uint16_t mpx_user_id;
ns_list_link_t link; /*!< List link entry */ ns_list_link_t link; /*!< List link entry */
} fragmenter_interface_t; } fragmenter_interface_t;
@ -101,8 +111,8 @@ static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_p
static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr, protocol_interface_info_entry_t *cur); static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interface_ptr, protocol_interface_info_entry_t *cur);
/* Data direction and message length validation */ /* Data direction and message length validation */
static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry); static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *mle_entry);
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf); static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr);
/* Common data tx request process functions */ /* Common data tx request process functions */
static void lowpan_active_buffer_state_reset(fragmenter_tx_entry_t *tx_buffer); static void lowpan_active_buffer_state_reset(fragmenter_tx_entry_t *tx_buffer);
@ -110,7 +120,7 @@ static uint8_t lowpan_data_request_unique_handle_get(fragmenter_interface_t *int
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size); static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size);
static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_interface_t *interface_ptr, bool indirect, bool fragmented, bool is_unicast); static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_interface_t *interface_ptr, bool indirect, bool fragmented, bool is_unicast);
static void lowpan_adaptation_data_request_primitiv_set(const buffer_t *buf, mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur); static void lowpan_adaptation_data_request_primitiv_set(const buffer_t *buf, mcps_data_req_t *dataReq, protocol_interface_info_entry_t *cur);
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr); static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr);
/* Tx confirmation local functions */ /* Tx confirmation local functions */
static bool lowpan_active_tx_handle_verify(uint8_t handle, buffer_t *buf); static bool lowpan_active_tx_handle_verify(uint8_t handle, buffer_t *buf);
@ -120,12 +130,49 @@ static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status);
static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr); static bool lowpan_adaptation_tx_process_ready(fragmenter_tx_entry_t *tx_ptr);
/* Fragmentation local functions */ /* Fragmentation local functions */
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur); static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr);
static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq); static bool lowpan_message_fragmentation_message_write(const fragmenter_tx_entry_t *frag_entry, mcps_data_req_t *dataReq);
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr); static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr); static fragmenter_tx_entry_t* lowpan_adaptation_indirect_mac_data_request_active(fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr);
static void lowpan_adaptation_etx_update_cb(protocol_interface_info_entry_t *cur, buffer_t *buf, const mcps_data_conf_t *confirm)
{
switch (confirm->status) {
case MLME_TX_NO_ACK:
case MLME_NO_DATA:
case MLME_SUCCESS:
if (buf->link_specific.ieee802_15_4.requestAck) {
if (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE) {
bool success = false;
if (confirm->status == MLME_SUCCESS) {
success = true;
}
// Gets table entry
mac_neighbor_table_entry_t *neigh_table_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type);
if (neigh_table_ptr) {
etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, neigh_table_ptr->index);
// Updates ETX statistics
etx_storage_t * etx_entry = etx_storage_entry_get(cur->id, neigh_table_ptr->index);
if (etx_entry) {
if (neigh_table_ptr->link_role == PRIORITY_PARENT_NEIGHBOUR) {
protocol_stats_update(STATS_ETX_1ST_PARENT, etx_entry->etx >> 4);
} else if (neigh_table_ptr->link_role == SECONDARY_PARENT_NEIGHBOUR) {
protocol_stats_update(STATS_ETX_2ND_PARENT, etx_entry->etx >> 4);
}
}
}
}
}
break;
default:
break;
}
}
//Discover //Discover
static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t interfaceId) static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t interfaceId)
{ {
@ -139,6 +186,18 @@ static fragmenter_interface_t *lowpan_adaptation_interface_discover(int8_t inter
return NULL; return NULL;
} }
static struct protocol_interface_info_entry *lowpan_adaptation_network_interface_discover(const mpx_api_t* api)
{
ns_list_foreach(fragmenter_interface_t, interface_ptr, &fragmenter_interface_list) {
if (api == interface_ptr->mpx_api) {
return protocol_stack_interface_info_get_by_id(interface_ptr->interface_id);
}
}
return NULL;
}
static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr , buffer_t *buf) static void lowpan_adaptation_tx_queue_write(fragmenter_interface_t *interface_ptr , buffer_t *buf)
{ {
@ -164,7 +223,7 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf
* Data confirm has freed the corresponding "active buffer" and this function will look for new buffer to be set as active buffer. * Data confirm has freed the corresponding "active buffer" and this function will look for new buffer to be set as active buffer.
*/ */
ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) { ns_list_foreach_safe(buffer_t, buf, &interface_ptr->directTxQueue) {
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf); bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
//Check that we not trig second active fragmentation process //Check that we not trig second active fragmentation process
if (fragmented_needed && interface_ptr->fragmenter_active) { if (fragmented_needed && interface_ptr->fragmenter_active) {
tr_debug("Do not trig Second active fragmentation"); tr_debug("Do not trig Second active fragmentation");
@ -179,9 +238,13 @@ static buffer_t * lowpan_adaptation_tx_queue_read(fragmenter_interface_t *interf
//fragmentation needed //fragmentation needed
static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf) static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_interface_t *interface_ptr)
{ {
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
if (interface_ptr->mpx_api) {
overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id);
}
if (buffer_data_length(buf) > (int16_t)mac_helper_max_payload_size(cur, overhead)) { if (buffer_data_length(buf) > (int16_t)mac_helper_max_payload_size(cur, overhead)) {
@ -191,9 +254,9 @@ static bool lowpan_adaptation_request_longer_than_mtu(protocol_interface_info_en
} }
} }
static bool lowpan_adaptation_indirect_data_request(mle_neigh_table_entry_t *mle_entry) static bool lowpan_adaptation_indirect_data_request(mac_neighbor_table_entry_t *entry_ptr)
{ {
if (mle_entry && !(mle_entry->mode & MLE_RX_ON_IDLE)) { if (entry_ptr && !(entry_ptr->rx_on_idle)) {
return true; return true;
} }
return false; return false;
@ -302,6 +365,14 @@ int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_si
return 0; return 0;
} }
void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id)
{
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id);
if (interface_ptr) {
interface_ptr->etx_update_cb = lowpan_adaptation_etx_update_cb;
}
}
int8_t lowpan_adaptation_interface_free(int8_t interface_id) int8_t lowpan_adaptation_interface_free(int8_t interface_id)
{ {
//Discover //Discover
@ -350,6 +421,44 @@ int8_t lowpan_adaptation_interface_reset(int8_t interface_id)
return 0; return 0;
} }
static void lowpan_adaptation_mpx_data_confirm(const mpx_api_t* api, const struct mcps_data_conf_s *data)
{
protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api);
lowpan_adaptation_interface_tx_confirm(interface, data);
}
static void lowpan_adaptation_mpx_data_indication(const mpx_api_t* api, const struct mcps_data_ind_s *data)
{
protocol_interface_info_entry_t * interface = lowpan_adaptation_network_interface_discover(api);
lowpan_adaptation_interface_data_ind(interface, data);
}
int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id)
{
//Discover
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(interface_id);
if (!interface_ptr) {
return -1;
}
if (!mpx_api && interface_ptr->mpx_api) {
//Disable Data Callbacks from MPX Class
interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, NULL, NULL, interface_ptr->mpx_user_id);
}
interface_ptr->mpx_api = mpx_api;
interface_ptr->mpx_user_id = mpx_user_id;
if (interface_ptr->mpx_api) {
//Register MPX callbacks: confirmation and indication
interface_ptr->mpx_api->mpx_user_registration(interface_ptr->mpx_api, lowpan_adaptation_mpx_data_confirm, lowpan_adaptation_mpx_data_indication, interface_ptr->mpx_user_id);
}
return 0;
}
static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size) static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_buffer_size)
{ {
@ -377,7 +486,7 @@ static fragmenter_tx_entry_t *lowpan_indirect_entry_allocate(uint16_t fragment_b
return indirec_entry; return indirec_entry;
} }
static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur) static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_entry_t *frag_entry, protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr)
{ {
uint8_t *ptr; uint8_t *ptr;
uint16_t uncompressed_size; uint16_t uncompressed_size;
@ -405,7 +514,11 @@ static int8_t lowpan_message_fragmentation_init(buffer_t *buf, fragmenter_tx_ent
frag_entry->orig_size = frag_entry->size; frag_entry->orig_size = frag_entry->size;
frag_entry->size += (uncompressed_size - frag_entry->pattern); frag_entry->size += (uncompressed_size - frag_entry->pattern);
uint_fast8_t overhead = mac_helper_frame_overhead(cur, buf); uint_fast16_t overhead = mac_helper_frame_overhead(cur, buf);
if (interface_ptr->mpx_api) {
overhead += interface_ptr->mpx_api->mpx_headroom_size_get(interface_ptr->mpx_api, interface_ptr->mpx_user_id);
}
frag_entry->frag_max = mac_helper_max_payload_size(cur, overhead); frag_entry->frag_max = mac_helper_max_payload_size(cur, overhead);
@ -498,24 +611,25 @@ static fragmenter_tx_entry_t * lowpan_adaptation_tx_process_init(fragmenter_inte
buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_entry_t *cur, buffer_t *buf) buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_entry_t *cur, buffer_t *buf)
{ {
mac_neighbor_table_entry_t *neigh_entry_ptr = NULL;
//Validate is link known and set indirect, datareq and security key id mode //Validate is link known and set indirect, datareq and security key id mode
if (buf->dst_sa.addr_type == ADDR_NONE) { if (buf->dst_sa.addr_type == ADDR_NONE) {
goto tx_error_handler; goto tx_error_handler;
} }
mle_neigh_table_entry_t *mle_entry = NULL;
/* If MLE is enabled, we will talk if we have an MLE association */ /* If MLE is enabled, we will talk if we have an MLE association */
if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) { if (buf->dst_sa.addr_type == ADDR_802_15_4_LONG ) {
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
} else if(buf->dst_sa.addr_type == ADDR_802_15_4_SHORT && (common_read_16_bit(buf->dst_sa.address + 2)) != 0xffff) { } else if(buf->dst_sa.addr_type == ADDR_802_15_4_SHORT && (common_read_16_bit(buf->dst_sa.address + 2)) != 0xffff) {
mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + 2, buf->dst_sa.addr_type);
} }
//Validate neighbour //Validate neighbour
if (!buf->options.ll_security_bypass_tx && mle_entry) { if (!buf->options.ll_security_bypass_tx && neigh_entry_ptr) {
if (mle_entry->handshakeReady || mle_entry->thread_commission) { if (neigh_entry_ptr->connected_device || neigh_entry_ptr->trusted_device) {
} else { } else {
//tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true)); //tr_warn("Drop TX to unassociated %s", trace_sockaddr(&buf->dst_sa, true));
@ -534,14 +648,14 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_
buf->link_specific.ieee802_15_4.requestAck = false; buf->link_specific.ieee802_15_4.requestAck = false;
} else { } else {
buf->link_specific.ieee802_15_4.requestAck = true; buf->link_specific.ieee802_15_4.requestAck = true;
buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(mle_entry); buf->link_specific.ieee802_15_4.indirectTxProcess = lowpan_adaptation_indirect_data_request(neigh_entry_ptr);
} }
if (buf->link_specific.ieee802_15_4.key_id_mode != B_SECURITY_KEY_ID_2) { if (buf->link_specific.ieee802_15_4.key_id_mode != B_SECURITY_KEY_ID_2) {
if (!buf->link_specific.ieee802_15_4.requestAck ) { if (!buf->link_specific.ieee802_15_4.requestAck ) {
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT; buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
} else if (mle_entry && !mle_entry->thread_commission) { } else if (ws_info(cur) || (neigh_entry_ptr && !neigh_entry_ptr->trusted_device)) {
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT; buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
} else { } else {
buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_IMPLICIT; buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_IMPLICIT;
@ -551,6 +665,11 @@ buffer_t * lowpan_adaptation_data_process_tx_preprocess(protocol_interface_info_
return buf; return buf;
tx_error_handler: tx_error_handler:
if (neigh_entry_ptr && neigh_entry_ptr->nud_active) {
mac_neighbor_info(cur)->active_nud_process--;
neigh_entry_ptr->nud_active = false;
}
socket_tx_buffer_event_and_free(buf, SOCKET_TX_FAIL); socket_tx_buffer_event_and_free(buf, SOCKET_TX_FAIL);
return NULL; return NULL;
@ -616,7 +735,7 @@ static bool lowpan_adaptation_indirect_cache_sanity_check(protocol_interface_inf
// entry is in cache and is not sent to mac => trigger this // entry is in cache and is not sent to mac => trigger this
tr_debug_extra("sanity check, push seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address)); tr_debug_extra("sanity check, push seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
fragmenter_tx_entry->indirect_data_cached = false; fragmenter_tx_entry->indirect_data_cached = false;
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry); lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
return true; return true;
} }
} }
@ -638,7 +757,7 @@ static bool lowpan_adaptation_indirect_cache_trigger(protocol_interface_info_ent
if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) { if (addr_ipv6_equal(tx_ptr->buf->dst_sa.address, fragmenter_tx_entry->buf->dst_sa.address)) {
tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address)); tr_debug_extra("pushing seq %d to addr %s", fragmenter_tx_entry->buf->seq, trace_ipv6(fragmenter_tx_entry->buf->dst_sa.address));
fragmenter_tx_entry->indirect_data_cached = false; fragmenter_tx_entry->indirect_data_cached = false;
lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry); lowpan_data_request_to_mac(cur, fragmenter_tx_entry->buf, fragmenter_tx_entry, interface_ptr);
return true; return true;
} }
} }
@ -674,7 +793,7 @@ static fragmenter_tx_entry_t* lowpan_adaptation_indirect_first_cached_request_ge
return NULL; return NULL;
} }
static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mle_neigh_table_entry_t *neighbour_to_count) static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info_entry_t *cur, fragmenter_interface_t *interface_ptr, mac_neighbor_table_entry_t *neighbour_to_count)
{ {
if (interface_ptr->max_indirect_small_packets_per_child == 0) { if (interface_ptr->max_indirect_small_packets_per_child == 0) {
return; return;
@ -683,7 +802,7 @@ static void lowpan_adaptation_make_room_for_small_packet(protocol_interface_info
uint_fast16_t count = 0; uint_fast16_t count = 0;
ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) { ns_list_foreach_reverse_safe(fragmenter_tx_entry_t, tx_entry, &interface_ptr->indirect_tx_queue) {
mle_neigh_table_entry_t *tx_neighbour = mle_class_get_by_link_address(cur->id, tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type); mac_neighbor_table_entry_t *tx_neighbour = mac_neighbor_table_address_discover(mac_neighbor_info(cur), tx_entry->buf->dst_sa.address + 2, tx_entry->buf->dst_sa.addr_type);
if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) { if (tx_neighbour == neighbour_to_count && buffer_data_length(tx_entry->buf) <= interface_ptr->indirect_big_packet_threshold) {
if (++count >= interface_ptr->max_indirect_small_packets_per_child) { if (++count >= interface_ptr->max_indirect_small_packets_per_child) {
lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry); lowpan_adaptation_indirect_queue_free_message(cur, interface_ptr, tx_entry);
@ -710,7 +829,7 @@ static void lowpan_adaptation_make_room_for_big_packet(struct protocol_interface
} }
} }
static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr) static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buffer_t *buf, fragmenter_tx_entry_t *tx_ptr, fragmenter_interface_t *interface_ptr)
{ {
mcps_data_req_t dataReq; mcps_data_req_t dataReq;
@ -737,7 +856,11 @@ static void lowpan_data_request_to_mac(protocol_interface_info_entry_t *cur, buf
} }
} }
cur->mac_api->mcps_data_req(cur->mac_api, &dataReq); if (interface_ptr->mpx_api) {
interface_ptr->mpx_api->mpx_data_request(interface_ptr->mpx_api, &dataReq, interface_ptr->mpx_user_id);
} else {
cur->mac_api->mcps_data_req(cur->mac_api, &dataReq);
}
} }
int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf) int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buffer_t *buf)
@ -756,7 +879,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
} }
//Check packet size //Check packet size
bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf); bool fragmented_needed = lowpan_adaptation_request_longer_than_mtu(cur, buf, interface_ptr);
bool is_unicast = buf->link_specific.ieee802_15_4.requestAck; bool is_unicast = buf->link_specific.ieee802_15_4.requestAck;
bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess; bool indirect = buf->link_specific.ieee802_15_4.indirectTxProcess;
if (!indirect) { if (!indirect) {
@ -783,7 +906,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
if (fragmented_needed) { if (fragmented_needed) {
//Fragmentation init //Fragmentation init
if (lowpan_message_fragmentation_init(buf, tx_ptr, cur) ) { if (lowpan_message_fragmentation_init(buf, tx_ptr, cur, interface_ptr) ) {
tr_error("Fragment init fail"); tr_error("Fragment init fail");
if (indirect) { if (indirect) {
ns_dyn_mem_free(tx_ptr->fragmenter_buf); ns_dyn_mem_free(tx_ptr->fragmenter_buf);
@ -801,9 +924,9 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
if (indirect) { if (indirect) {
//Add to indirectQUue //Add to indirectQUue
fragmenter_tx_entry_t *tx_ptr_cached; fragmenter_tx_entry_t *tx_ptr_cached;
mle_neigh_table_entry_t *mle_entry = mle_class_get_by_link_address(cur->id, buf->dst_sa.address + 2, buf->dst_sa.addr_type); mac_neighbor_table_entry_t *neigh_entry_ptr = mac_neighbor_table_address_discover(mac_neighbor_info(cur), buf->dst_sa.address + PAN_ID_LEN, buf->dst_sa.addr_type);
if (mle_entry) { if (neigh_entry_ptr) {
buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) mle_entry->timeout_rx * MLE_TIMER_TICKS_MS; buf->link_specific.ieee802_15_4.indirectTTL = (uint32_t) neigh_entry_ptr->link_lifetime * 1000;
} else { } else {
buf->link_specific.ieee802_15_4.indirectTTL = cur->mac_parameters->mac_in_direct_entry_timeout; buf->link_specific.ieee802_15_4.indirectTTL = cur->mac_parameters->mac_in_direct_entry_timeout;
} }
@ -812,7 +935,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
// Make room for new message if needed */ // Make room for new message if needed */
if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) { if (buffer_data_length(buf) <= interface_ptr->indirect_big_packet_threshold) {
lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, mle_entry); lowpan_adaptation_make_room_for_small_packet(cur, interface_ptr, neigh_entry_ptr);
} else { } else {
lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr); lowpan_adaptation_make_room_for_big_packet(cur, interface_ptr);
} }
@ -841,7 +964,7 @@ int8_t lowpan_adaptation_interface_tx(protocol_interface_info_entry_t *cur, buff
} }
} }
lowpan_data_request_to_mac(cur, buf, tx_ptr); lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
return 0; return 0;
@ -952,28 +1075,15 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
{ {
buf->link_specific.ieee802_15_4.indirectTTL -= 7000; buf->link_specific.ieee802_15_4.indirectTTL -= 7000;
//Push Back to MAC //Push Back to MAC
lowpan_data_request_to_mac(cur, buf, tx_ptr); lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
return 0; return 0;
} }
} }
switch (confirm->status) { if (interface_ptr->etx_update_cb) {
case MLME_TX_NO_ACK: interface_ptr->etx_update_cb(cur, buf, confirm);
case MLME_NO_DATA:
case MLME_SUCCESS:
if (buf->link_specific.ieee802_15_4.requestAck) {
bool success = false;
if (confirm->status == MLME_SUCCESS) {
success = true;
}
etx_transm_attempts_update(cur->id, 1 + confirm->tx_retries , success, buf->dst_sa.addr_type, buf->dst_sa.address);
}
break;
default:
break;
} }
//Switch original channel back //Switch original channel back
if (buf->link_specific.ieee802_15_4.rf_channel_switch) { if (buf->link_specific.ieee802_15_4.rf_channel_switch) {
mac_helper_mac_channel_set(cur, buf->link_specific.ieee802_15_4.selected_channel); mac_helper_mac_channel_set(cur, buf->link_specific.ieee802_15_4.selected_channel);
@ -983,7 +1093,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
switch (confirm->status) { switch (confirm->status) {
case MLME_BUSY_CHAN: case MLME_BUSY_CHAN:
lowpan_data_request_to_mac(cur, buf, tx_ptr); lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
break; break;
case MLME_SUCCESS: case MLME_SUCCESS:
@ -1005,7 +1115,7 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
return 0; return 0;
} }
} else { } else {
lowpan_data_request_to_mac(cur, buf, tx_ptr); lowpan_data_request_to_mac(cur, buf, tx_ptr, interface_ptr);
} }
break; break;
@ -1049,6 +1159,73 @@ int8_t lowpan_adaptation_interface_tx_confirm(protocol_interface_info_entry_t *c
} }
static bool mac_data_is_broadcast_addr(const sockaddr_t *addr)
{
return (addr->addr_type == ADDR_802_15_4_SHORT) &&
(addr->address[2] == 0xFF && addr->address[3] == 0xFF);
}
static bool mcps_data_indication_neighbor_validate(protocol_interface_info_entry_t *cur, const sockaddr_t *addr)
{
if (thread_info(cur) || ws_info(cur) || (cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_MLE)) {
mac_neighbor_table_entry_t * neighbor = mac_neighbor_table_address_discover(mac_neighbor_info(cur), addr->address + 2, addr->addr_type);
if (neighbor && (neighbor->connected_device || neighbor->trusted_device)) {
return true;
}
/* Otherwise, we don't know them */
return false;
} else {
//6lowpan without MLE don't can't do validation
return true;
}
}
void lowpan_adaptation_interface_data_ind(protocol_interface_info_entry_t *cur, const mcps_data_ind_t *data_ind)
{
buffer_t *buf = buffer_get(data_ind->msduLength);
if (!buf || !cur) {
return;
}
uint8_t *ptr;
buffer_data_add(buf, data_ind->msdu_ptr, data_ind->msduLength);
//tr_debug("MAC Paylod size %u %s",data_ind->msduLength, trace_array(data_ind->msdu_ptr, 8));
buf->options.lqi = data_ind->mpduLinkQuality;
buf->options.dbm = data_ind->signal_dbm;
buf->src_sa.addr_type = (addrtype_t)data_ind->SrcAddrMode;
ptr = common_write_16_bit(data_ind->SrcPANId, buf->src_sa.address);
memcpy(ptr, data_ind->SrcAddr, 8);
buf->dst_sa.addr_type = (addrtype_t)data_ind->DstAddrMode;
ptr = common_write_16_bit(data_ind->DstPANId, buf->dst_sa.address);
memcpy(ptr, data_ind->DstAddr, 8);
//Set Link spesific stuff to seperately
buf->link_specific.ieee802_15_4.srcPanId = data_ind->SrcPANId;
buf->link_specific.ieee802_15_4.dstPanId = data_ind->DstPANId;
if (mac_data_is_broadcast_addr(&buf->dst_sa)) {
buf->options.ll_broadcast_rx = true;
}
buf->interface = cur;
if (data_ind->Key.SecurityLevel) {
buf->link_specific.ieee802_15_4.fc_security = true;
if (cur->mac_security_key_usage_update_cb) {
cur->mac_security_key_usage_update_cb(cur, &data_ind->Key);
}
} else {
buf->link_specific.ieee802_15_4.fc_security = false;
if (mac_helper_default_security_level_get(cur) ||
!mcps_data_indication_neighbor_validate(cur, &buf->src_sa)) {
//SET By Pass
buf->options.ll_security_bypass_rx = true;
}
}
buf->info = (buffer_info_t)(B_TO_IPV6_TXRX | B_FROM_MAC | B_DIR_UP);
protocol_push(buf);
}
static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status) static uint8_t map_mlme_status_to_socket_event(uint8_t mlme_status)
{ {
uint8_t socket_event; uint8_t socket_event;
@ -1104,22 +1281,38 @@ static bool lowpan_tx_buffer_address_compare(sockaddr_t *dst_sa, uint8_t *addres
return true; return true;
} }
static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, uint8_t msduhandle) static void lowpan_adaptation_purge_from_mac(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, uint8_t msduhandle)
{ {
mcps_purge_t purge_req; mcps_purge_t purge_req;
purge_req.msduHandle = msduhandle; purge_req.msduHandle = msduhandle;
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req); if (interface_ptr->mpx_api) {
interface_ptr->mpx_api->mpx_data_purge(interface_ptr->mpx_api, &purge_req, interface_ptr->mpx_user_id);
} else {
if (cur->mac_api->mcps_purge_req) {
cur->mac_api->mcps_purge_req(cur->mac_api, &purge_req);
}
}
} }
static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr) static void lowpan_adaptation_indirect_queue_free_message(struct protocol_interface_info_entry *cur, fragmenter_interface_t *interface_ptr, fragmenter_tx_entry_t *tx_ptr)
{ {
tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq); tr_debug("Purge from indirect handle %u", tx_ptr->buf->seq);
if (cur->mac_api->mcps_purge_req) { lowpan_adaptation_purge_from_mac(cur, interface_ptr, tx_ptr->buf->seq);
lowpan_adaptation_purge_from_mac(cur, tx_ptr->buf->seq);
}
lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL); lowpan_adaptation_data_process_clean(interface_ptr, tx_ptr, SOCKET_TX_FAIL);
} }
void lowpan_adaptation_remove_free_indirect_table(protocol_interface_info_entry_t *cur_interface, mac_neighbor_table_entry_t *entry_ptr)
{
//Free firts by defined short address
if (entry_ptr->mac16 < 0xfffe) {
uint8_t temp_address[2];
common_write_16_bit(entry_ptr->mac16, temp_address);
lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, temp_address, ADDR_802_15_4_SHORT);
}
lowpan_adaptation_indirect_free_messages_from_queues_by_address(cur_interface, entry_ptr->mac64, ADDR_802_15_4_LONG);
}
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type) int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type)
{ {
fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id); fragmenter_interface_t *interface_ptr = lowpan_adaptation_interface_discover(cur->id);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2017, Arm Limited and affiliates. * Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -21,13 +21,21 @@
struct protocol_interface_info_entry; struct protocol_interface_info_entry;
struct mcps_data_conf_s; struct mcps_data_conf_s;
struct mcps_data_ind_s;
struct buffer; struct buffer;
struct mpx_api_s;
struct mac_neighbor_table_entry;
int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_size); int8_t lowpan_adaptation_interface_init(int8_t interface_id, uint16_t mac_mtu_size);
void lowpan_adaptation_interface_etx_update_enable(int8_t interface_id);
int8_t lowpan_adaptation_interface_free(int8_t interface_id); int8_t lowpan_adaptation_interface_free(int8_t interface_id);
int8_t lowpan_adaptation_interface_reset(int8_t interface_id); int8_t lowpan_adaptation_interface_reset(int8_t interface_id);
int8_t lowpan_adaptation_interface_mpx_register(int8_t interface_id, struct mpx_api_s *mpx_api, uint16_t mpx_user_id);
/** /**
* \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination * \brief call this before normatl TX. This function prepare buffer link spesific metadata and verify packet destination
*/ */
@ -37,10 +45,14 @@ int8_t lowpan_adaptation_interface_tx(struct protocol_interface_info_entry *cur,
int8_t lowpan_adaptation_interface_tx_confirm(struct protocol_interface_info_entry *cur, const struct mcps_data_conf_s *confirm); int8_t lowpan_adaptation_interface_tx_confirm(struct protocol_interface_info_entry *cur, const struct mcps_data_conf_s *confirm);
void lowpan_adaptation_interface_data_ind(struct protocol_interface_info_entry *cur, const struct mcps_data_ind_s *data_ind);
struct buffer *lowpan_adaptation_reassembly(struct protocol_interface_info_entry *cur, struct buffer *buf); struct buffer *lowpan_adaptation_reassembly(struct protocol_interface_info_entry *cur, struct buffer *buf);
bool lowpan_adaptation_tx_active(int8_t interface_id); bool lowpan_adaptation_tx_active(int8_t interface_id);
void lowpan_adaptation_remove_free_indirect_table(struct protocol_interface_info_entry *cur_interface, struct mac_neighbor_table_entry *entry_ptr);
int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type); int8_t lowpan_adaptation_indirect_free_messages_from_queues_by_address(struct protocol_interface_info_entry *cur, uint8_t *address_ptr, addrtype_t adr_type);
int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child); int8_t lowpan_adaptation_indirect_queue_params_set(struct protocol_interface_info_entry *cur, uint16_t indirect_big_packet_threshold, uint16_t max_indirect_big_packets_total, uint16_t max_indirect_small_packets_per_child);

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WS_BOOTSTRAP_H_
#define WS_BOOTSTRAP_H_
typedef enum {
WS_INIT_EVENT = 0, /**< tasklet initializion event*/
WS_DISCOVERY_START, /**< discovery start*/
WS_CONFIGURATION_START, /**< configuration learn start*/
WS_AUTHENTICATION_START, /**< authentication start*/
WS_OPERATION_START, /**< active operation start*/
WS_ROUTING_READY, /**< RPL routing connected to BR*/
WS_ADDRESS_ADDED /**< Address added to IF*/
} ws_bootsrap_event_type_e;
#ifdef HAVE_WS
int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode);
void ws_bootstrap_state_machine(protocol_interface_info_entry_t *cur);
/*State machine transactions*/
void ws_bootstrap_event_discovery_start(protocol_interface_info_entry_t *cur);
void ws_bootstrap_event_configuration_start(protocol_interface_info_entry_t *cur);
void ws_bootstrap_event_authentication_start(protocol_interface_info_entry_t *cur);
void ws_bootstrap_event_operation_start(protocol_interface_info_entry_t *cur);
void ws_bootstrap_event_routing_ready(protocol_interface_info_entry_t *cur);
void ws_bootstrap_configuration_trickle_reset(protocol_interface_info_entry_t *cur);
void ws_bootstrap_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
void ws_bootstrap_trigle_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
#else
#define ws_bootstrap_init(interface_id, bootstrap_mode) (-1)
#define ws_bootstrap_state_machine(cur)
#endif //HAVE_WS
#endif /* WS_BOOTSTRAP_H_ */

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WS_COMMON_H_
#define WS_COMMON_H_
#include "ns_types.h"
#include "fhss_api.h"
#include "fhss_config.h"
#include "net_fhss.h"
#include "6LoWPAN/ws/ws_common_defines.h"
#include "6LoWPAN/ws/ws_neighbor_class.h"
struct ws_pan_information_s;
struct ws_neighbor_class_s;
typedef struct parent_info_s {
uint16_t pan_id; /**< PAN ID */
uint8_t addr[8]; /**< address */
uint8_t link_quality; /**< LQI value measured during reception of the MPDU */
int8_t signal_dbm; /**< This extension for normal IEEE 802.15.4 Data indication */
ws_pan_information_t pan_information;
ws_utt_ie_t ws_utt;
ws_us_ie_t ws_us;
uint32_t timestamp; /**< Timestamp when packet was received */
}parent_info_t;
typedef struct ws_info_s {
char network_name[33]; // Network name max 32 octets + terminating 0.
uint16_t network_pan_id;
trickle_t trickle_pan_config_solicit;
trickle_t trickle_pan_config;
trickle_t trickle_pan_advertisement_solicit;
trickle_t trickle_pan_advertisement;
uint8_t rpl_state; // state from rpl_event_t
uint8_t pas_requests; // Amount of PAN solicits sent
parent_info_t parent_info;
uint32_t pan_version_timer; /**< border router version udate timeout */
uint32_t pan_version_timeout_timer; /**< routers will fallback to previous state after this */
uint8_t gtkhash[32];
bool configuration_learned:1;
struct ws_pan_information_s pan_information;
ws_hopping_schedule_t hopping_schdule;
struct ws_neighbor_class_s neighbor_storage;
struct fhss_timer *fhss_timer_ptr; // Platform adaptation for FHSS timers.
struct fhss_api *fhss_api;
} ws_info_t;
#ifdef HAVE_WS
int8_t ws_common_regulatory_domain_config(protocol_interface_info_entry_t *cur);
int8_t ws_common_allocate_and_init(protocol_interface_info_entry_t *cur);
void ws_common_seconds_timer(protocol_interface_info_entry_t *cur, uint32_t seconds);
void ws_common_fast_timer(protocol_interface_info_entry_t *cur, uint16_t ticks);
void ws_common_neighbor_update(protocol_interface_info_entry_t *cur, const uint8_t *ll_address);
#define ws_info(cur) ((cur)->ws_info)
#else
#define ws_info(cur) ((ws_info_t *) NULL)
#define ws_common_seconds_timer(cur, seconds)
#define ws_common_neighbor_update(cur, ll_address) ((void) 0)
#define ws_common_fast_timer(cur, ticks) ((void) 0)
#endif //HAVE_WS
#endif //WS_COMMON_H_

View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WS_COMMON_DEFINES_H_
#define WS_COMMON_DEFINES_H_
#define WH_IE_ELEMENT_HEADER_LENGTH 3
/* Header IE Sub elements */
#define WH_IE_UTT_TYPE 1 /**< Unicast Timing and Frame type information */
#define WH_IE_BT_TYPE 2 /**< Broadcast timing information */
#define WH_IE_FC_TYPE 3 /**< Flow Control for Extended Direct Frame Exchange */
#define WH_IE_RSL_TYPE 4 /**< Received Signal Level information */
#define WH_IE_MHDS_TYPE 5 /**< MHDS information for mesh routing */
#define WH_IE_VH_TYPE 6 /**< Vendor header information */
#define WS_WP_NESTED_IE 4 /**< WS nested Payload IE element'selement could include mltiple sub payload IE */
#define WS_WP_SUB_IE_ELEMENT_HEADER_LENGTH 2
/* Payload IE sub elements in side WS_WP_NESTED_IE */
#define WP_PAYLOAD_IE_US_TYPE 1 /**< Unicast Schedule information */
#define WP_PAYLOAD_IE_BS_TYPE 2 /**< Broadcast Schedule information */
#define WP_PAYLOAD_IE_VP_TYPE 3 /**< Vendor Payload information */
#define WP_PAYLOAD_IE_PAN_TYPE 4 /**< PAN Information */
#define WP_PAYLOAD_IE_NETNAME_TYPE 5 /**< Network Name information */
#define WP_PAYLOAD_IE_PAN_VER_TYPE 6 /**< Pan configuration version */
#define WP_PAYLOAD_IE_GTKHASH_TYPE 7 /**< GTK Hash information */
/* WS frame types to WH_IE_UTT_TYPE */
#define WS_FT_PAN_ADVERT 0 /**< PAN Advert */
#define WS_FT_PAN_ADVERT_SOL 1 /**< PAN Advert Solicit */
#define WS_FT_PAN_CONF 2 /**< PAN Config */
#define WS_FT_PAN_CONF_SOL 3 /**< PAN Config Solicit */
#define WS_FT_DATA 4 /**< data type inside MPX */
#define WS_FT_ACK 5 /**< Enhanced ACK */
#define WS_FT_EAPOL 6 /**< EAPOL message inside MPX */
/**
* @brief ws_pan_information_t PAN information
*/
typedef struct ws_pan_information_s {
uint16_t pan_size; /**< Number devices connected to Border Router. */
uint16_t routing_cost; /**< ETX to border Router. */
uint16_t pan_version; /**< Pan configuration version will be updatd by Border router at PAN. */
bool use_parent_bs:1; /**< 1 for force to follow parent broadcast schedule. 0 node may define own schedule. */
bool rpl_routing_method:1; /**< 1 when RPL routing is selected and 0 when L2 routing. */
unsigned version:3; /**< Pan version support. */
} ws_pan_information_t;
/**
* @brief ws_hopping_schedule_t Chanel hopping schedule information
*/
typedef struct ws_hopping_schedule_s {
uint8_t fhss_uc_dwell_interval;
uint8_t fhss_bc_dwell_interval;
uint8_t regulatory_domain; /**< PHY regulatory domain default to "KR" 0x09 */
uint8_t operating_class; /**< PHY operating class default to 1 */
uint8_t operating_mode; /**< PHY operating mode default to "1b" symbol rate 50, modulation index 1 */
uint8_t channel_plan; /**< 0: use regulatory domain values 1: application defined plan */
uint8_t channel_function; /**< 0: Fixed channel, 1:TR51CF, 2: Direct Hash, 3: Vendor defined */
uint8_t channel_spacing; /**< derived from regulatory domain. 0:200k, 1:400k, 2:600k, 3:100k */
uint8_t number_of_channels; /**< derived from regulatory domain */
uint8_t clock_drift;
uint8_t timing_accurancy;
uint16_t fixed_channel;
uint16_t fhss_bsi;
uint32_t fhss_broadcast_interval;
uint32_t channel_mask[8];
uint_fast24_t ch0_freq; // Default should be derived from regulatory domain
} ws_hopping_schedule_t;
/**
* @brief ws_utt_ie_t WS UTT-IE
*/
typedef struct ws_utt_ie {
uint8_t message_type;
uint_fast24_t ufsi;
} ws_utt_ie_t;
/**
* @brief ws_bt_ie_t WS BT-IE read
*/
typedef struct ws_bt_ie {
uint16_t broadcast_slot_number;
uint_fast24_t broadcast_interval_offset;
} ws_bt_ie_t;
/**
* @brief ws_channel_plan_zero_t WS channel plan 0 define domain and class
*/
typedef struct ws_channel_plan_zero {
uint8_t regulator_domain;
uint8_t operation_class;
} ws_channel_plan_zero_t;
/**
* @brief ws_channel_plan_one_t WS channel plan 1 define ch0, spasing and channel count
*/
typedef struct ws_channel_plan_one {
uint_fast24_t ch0;
unsigned channel_spacing:4;
uint16_t number_of_channel;
} ws_channel_plan_one_t;
/**
* @brief ws_channel_function_zero_t WS function 0 fixed channel
*/
typedef struct ws_channel_function_zero {
uint16_t fixed_channel;
} ws_channel_function_zero_t;
/**
* @brief ws_channel_function_three_t WS function 3 vendor spesific channel hop
*/
typedef struct ws_channel_function_three {
uint8_t channel_hop_count;
uint8_t *channel_list;
} ws_channel_function_three_t;
/**
* @brief ws_us_ie_t WS US-IE read
*/
typedef struct ws_us_ie {
uint8_t dwell_interval;
uint8_t clock_drift;
uint8_t timing_accurancy;
unsigned channel_plan:3;
unsigned channel_function:3;
unsigned excluded_channel_ctrl:2;
union {
ws_channel_plan_zero_t zero;
ws_channel_plan_one_t one;
} plan;
union {
ws_channel_function_zero_t zero;
ws_channel_function_three_t three;
} function;
} ws_us_ie_t;
/**
* @brief ws_bs_ie_t WS BS-IE read
*/
typedef struct ws_bs_ie {
uint32_t broadcast_interval;
uint16_t broadcast_schedule_identifier;
uint8_t dwell_interval;
uint8_t clock_drift;
uint8_t timing_accurancy;
unsigned channel_plan:3;
unsigned channel_function:3;
unsigned excluded_channel_ctrl:2;
union {
ws_channel_plan_zero_t zero;
ws_channel_plan_one_t one;
} plan;
union {
ws_channel_function_zero_t zero;
ws_channel_function_three_t three;
} function;
} ws_bs_ie_t;
#define MPX_KEY_MANAGEMENT_ENC_USER_ID 0x0001 /**< MPX Key management user ID */
#define MPX_LOWPAN_ENC_USER_ID 0xA0ED /**< MPX Lowpan User Id */
#define WS_FAN_VERSION_1_0 1
#define WS_NEIGHBOR_LINK_TIMEOUT 240
#define WS_NEIGHBOR_NUD_TIMEOUT WS_NEIGHBOR_LINK_TIMEOUT / 2
/*
* Threshold (referenced to DEVICE_MIN_SENS) above which a neighbor node may be considered for inclusion into candidate parent set
*/
#define CAND_PARENT_THRESHOLD 10
/*
* Hysteresis factor to be applied to CAND_PARENT_THRESHOLD when admitting or dropping nodes from the candidate parent set.
*/
#define CAND_PARENT_HYSTERISIS 3
/*
* value when send the first RPL DIS in 100ms ticks. Value is randomized between timeout/2 - timeout
*/
#define WS_RPL_DIS_INITIAL_TIMEOUT 600
/*
* value when send subsequent RPL DIS in 100 ms tics. Value is randomized between timeout/2 - timeout
*/
#define WS_RPL_DIS_TIMEOUT 1800
#endif /* WS_COMMON_DEFINES_H_ */

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2016-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WS_NEIGHBOR_CLASS_H_
#define WS_NEIGHBOR_CLASS_H_
#include "fhss_ws_extension.h"
#include "6LoWPAN/ws/ws_common_defines.h"
typedef struct ws_neighbor_class_entry {
fhss_ws_neighbor_timing_info_t fhss_data;
uint16_t rsl_in; /*!< RSL EWMA heard from neighbour*/
uint16_t rsl_out; /*!< RSL EWMA heard by neighbour*/
bool candidate_parent:1;
} ws_neighbor_class_entry_t;
/**
* Neighbor hopping info data base
*/
typedef struct ws_neighbor_class_s {
ws_neighbor_class_entry_t *neigh_info_list; /*!< Allocated hopping info array*/
uint8_t list_size; /*!< List size*/
} ws_neighbor_class_t;
/**
* ws_neighbor_class_alloc a function for allocate giving list size
*
* \param class_data pointer to structure which will be initialized by this function
* \param list_size define list size
*
* \return true Allocate Ok
* \return false Allocate Fail
*
*/
bool ws_neighbor_class_alloc(ws_neighbor_class_t *class_data, uint8_t list_size);
/**
* ws_neighbor_class_dealloc a function for free allocated neighbor hopping info
*
* \param class_data pointer to structure which will be initialized by this function
*
*/
void ws_neighbor_class_dealloc(ws_neighbor_class_t *class_data);
/**
* ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribut
*
* \param class_data pointer to structure which will be initialized by this function
* \param attribute_index define pointer to storage info
*
* \return NULL when Attribute is not correct
* \return Pointer to neighbor hopping info
*
*/
ws_neighbor_class_entry_t * ws_neighbor_class_entry_get(ws_neighbor_class_t *class_data, uint8_t attribute_index);
/**
* ws_neighbor_class_entry_t a function for search hopping info for giving neighbor attribute index
*
* \param class_data pointer to structure which will be initialized by this function
* \param entry which attribute index is counted.
*
* \return Attribute index of entry
*
*/
uint8_t ws_neighbor_class_entry_index_get(ws_neighbor_class_t *class_data, ws_neighbor_class_entry_t *entry);
/**
* ws_neighbor_class_entry_remove a function for clean information should be call when neighbor is removed
*
* \param class_data pointer to structure which will be initialized by this function
* \param attribute_index define pointer to storage info
*
*/
void ws_neighbor_class_entry_remove(ws_neighbor_class_t *class_data, uint8_t attribute_index);
/**
* ws_neighbor_class_neighbor_unicast_time_info_update a function for update neighbor unicast time information
*
* \param ws_neighbor pointer to neighbor
* \param ws_utt Unicast time IE data
* \param timestamp timestamp for received data
*
*/
void ws_neighbor_class_neighbor_unicast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_utt_ie_t *ws_utt, uint32_t timestamp);
/**
* ws_neighbor_class_neighbor_unicast_schedule_set a function for update neighbor unicast shedule information
*
* \param ws_neighbor pointer to neighbor
* \param ws_us Unicast schedule IE data
*
*/
void ws_neighbor_class_neighbor_unicast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_us_ie_t *ws_us);
/**
* ws_neighbor_class_neighbor_broadcast_time_info_update a function for update neighbor broadcast time information
*
* \param ws_neighbor pointer to neighbor
* \param ws_bt_ie Broadcast time IE data
* \param timestamp timestamp for received data
*
*/
void ws_neighbor_class_neighbor_broadcast_time_info_update(ws_neighbor_class_entry_t *ws_neighbor, ws_bt_ie_t *ws_bt_ie, uint32_t timestamp);
/**
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
*
* \param ws_neighbor pointer to neighbor
* \param ws_bs_ie Broadcast schedule IE data
*
*/
void ws_neighbor_class_neighbor_broadcast_schedule_set(ws_neighbor_class_entry_t *ws_neighbor, ws_bs_ie_t *ws_bs_ie);
/**
* ws_neighbor_class_rssi_from_dbm_calculate
*
* Calculates rssi value from dbm heard taking into account min sensitivity of radio
* dynamically adjusts min sensitivity if value is not properly set
*
* \param dbm_heard; dbm heard from the neighbour
*
*/
uint8_t ws_neighbor_class_rssi_from_dbm_calculate(int8_t dbm_heard);
/** Helper macros to read RSL values from neighbour class.
*
*/
#define ws_neighbor_class_rsl_in_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING)
#define ws_neighbor_class_rsl_out_get(ws_neighbour) (ws_neighbour->rsl_in >> WS_RSL_SCALING)
/**
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
*
* \param ws_neighbor pointer to neighbor
* \param dbm_heard; dbm heard from the neighbour
*
*/
void ws_neighbor_class_rsl_in_calculate(ws_neighbor_class_entry_t *ws_neighbor, int8_t dbm_heard);
/**
* ws_neighbor_class_neighbor_broadcast_schedule_set a function for update neighbor broadcast shedule information
*
* \param ws_neighbor pointer to neighbor
* \param rsl_reported; rsl value reported by neighbour in packet from RSL-IE
*
*/
void ws_neighbor_class_rsl_out_calculate(ws_neighbor_class_entry_t *ws_neighbor, uint8_t rsl_reported);
#endif /* WS_NEIGHBOR_CLASS_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2017, Arm Limited and affiliates. * Copyright (c) 2012-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -506,9 +506,8 @@ void border_router_start(protocol_interface_info_entry_t *cur, bool warm_link_re
if (warm_link_restart) { if (warm_link_restart) {
return; return;
} }
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
#ifndef NO_MLE #ifndef NO_MLE
mle_class_list_clean(cur->id);
blacklist_clear(); blacklist_clear();
#endif #endif
@ -708,8 +707,8 @@ static int8_t arm_border_router_interface_down(protocol_interface_info_entry_t *
cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
} }
cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id); cur->if_lowpan_security_params->mle_security_frame_counter = mle_service_security_get_frame_counter(cur->id);
mac_neighbor_table_neighbor_list_clean(mac_neighbor_info(cur));
#ifndef NO_MLE #ifndef NO_MLE
mle_class_list_clean(cur->id);
blacklist_clear(); blacklist_clear();
#endif #endif
if (nd_nwk) { if (nd_nwk) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -20,8 +20,8 @@
#include "ns_trace.h" #include "ns_trace.h"
#include "randLIB.h" #include "randLIB.h"
#include "NWK_INTERFACE/Include/protocol.h" #include "NWK_INTERFACE/Include/protocol.h"
#ifdef HAVE_RPL
#include "RPL/rpl_control.h" #include "RPL/rpl_control.h"
#ifdef HAVE_RPL
#include "RPL/rpl_data.h" #include "RPL/rpl_data.h"
#endif #endif
#include "RPL/rpl_protocol.h" #include "RPL/rpl_protocol.h"
@ -44,6 +44,8 @@
#include "common_functions.h" #include "common_functions.h"
#include "6LoWPAN/ND/nd_router_object.h" #include "6LoWPAN/ND/nd_router_object.h"
#include "6LoWPAN/Bootstraps/protocol_6lowpan.h" #include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
#include "6LoWPAN/ws/ws_common_defines.h"
#include "6LoWPAN/ws/ws_common.h"
#define TRACE_GROUP "icmp" #define TRACE_GROUP "icmp"
@ -420,6 +422,7 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
{ {
protocol_interface_info_entry_t *cur; protocol_interface_info_entry_t *cur;
uint8_t target[16]; uint8_t target[16];
uint8_t dummy_sllao[16];
bool proxy = false; bool proxy = false;
const uint8_t *sllao; const uint8_t *sllao;
const uint8_t *aro; const uint8_t *aro;
@ -439,7 +442,9 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
sllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_SRC_LL_ADDR, 0); sllao = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_SRC_LL_ADDR, 0);
/* If no SLLAO, ignore ARO (RFC 6775 6.5) */ /* If no SLLAO, ignore ARO (RFC 6775 6.5) */
if (sllao && cur->ipv6_neighbour_cache.recv_addr_reg) { /* This rule can be bypassed by setting flag "use_eui64_as_slla_in_aro" to true */
if (cur->ipv6_neighbour_cache.recv_addr_reg &&
(cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro || sllao)) {
aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 0); aro = icmpv6_find_option_in_buffer(buf, 20, ICMPV6_OPT_ADDR_REGISTRATION, 0);
} else { } else {
aro = NULL; aro = NULL;
@ -450,6 +455,15 @@ static buffer_t *icmpv6_ns_handler(buffer_t *buf)
goto drop; goto drop;
} }
/* If there was no SLLAO on ARO, use mac address to create dummy one... */
if (aro && !sllao && cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) {
dummy_sllao[0] = ICMPV6_OPT_SRC_LL_ADDR; // Type
dummy_sllao[1] = 2; // Length = 2x8 bytes
memcpy(dummy_sllao + 2, aro + 8, 8); // EUI-64
memset(dummy_sllao + 10, 0, 6); // Padding
sllao = dummy_sllao;
}
// Skip the 4 reserved bytes // Skip the 4 reserved bytes
dptr += 4; dptr += 4;
@ -529,7 +543,7 @@ drop:
} }
int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime) int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime)
{ {
int ret_val = -1; int ret_val = -1;
@ -564,7 +578,7 @@ void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur
} }
#endif // HAVE_IPV6_ND #endif // HAVE_IPV6_ND
if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src) if_address_entry_t *icmpv6_slaac_address_add(protocol_interface_info_entry_t *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src)
{ {
if_address_entry_t *address_entry; if_address_entry_t *address_entry;
uint8_t ipv6_address[16]; uint8_t ipv6_address[16];
@ -774,7 +788,7 @@ static buffer_t *icmpv6_ra_handler(buffer_t *buf)
ptr += 4; ptr += 4;
uint32_t preferred_lifetime = common_read_32_bit(ptr); uint32_t preferred_lifetime = common_read_32_bit(ptr);
ptr += 8; //Update 32-bit time and reserved 32-bit ptr += 8; //Update 32-bit time and reserved 32-bit
uint8_t *prefix_ptr = ptr; const uint8_t *prefix_ptr = ptr;
//Check is L Flag active //Check is L Flag active
if (prefix_flags & PIO_L) { if (prefix_flags & PIO_L) {
@ -990,6 +1004,10 @@ static buffer_t *icmpv6_na_handler(buffer_t *buf)
} }
ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address); ipv6_neighbour_update_from_na(&cur->ipv6_neighbour_cache, neighbour_entry, flags, buf->dst_sa.addr_type, buf->dst_sa.address);
if (ws_info(cur) && neighbour_entry->state == IP_NEIGHBOUR_REACHABLE) {
tr_debug("NA neigh update");
ws_common_neighbor_update(cur, target);
}
drop: drop:
return buffer_free(buf); return buffer_free(buf);
@ -1323,7 +1341,7 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
} else { } else {
/* RFC 4861 7.2.2. says we should use the source of traffic prompting the NS, if possible */ /* RFC 4861 7.2.2. says we should use the source of traffic prompting the NS, if possible */
/* This is also used to specify the address for ARO messages */ /* This is also used to specify the address for ARO messages */
if (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr)) { if (aro || (prompting_src_addr && addr_is_assigned_to_interface(cur, prompting_src_addr))) {
memcpy(buf->src_sa.address, prompting_src_addr, 16); memcpy(buf->src_sa.address, prompting_src_addr, 16);
} else { } else {
/* Otherwise, according to RFC 4861, we could use any address. /* Otherwise, according to RFC 4861, we could use any address.
@ -1347,7 +1365,15 @@ buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t ta
} }
} }
/* SLLAO is required if we're sending an ARO */ /* SLLAO is required if we're sending an ARO */
ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address); /* This rule can be bypassed with flag use_eui64_as_slla_in_aro */
if (!cur->ipv6_neighbour_cache.use_eui64_as_slla_in_aro) {
ptr = icmpv6_write_icmp_lla(cur, ptr, ICMPV6_OPT_SRC_LL_ADDR, aro, buf->src_sa.address);
}
/* If ARO Success sending is omitted, MAC ACK is used instead */
/* Setting callback for receiving ACK from adaptation layer */
if (aro && cur->ipv6_neighbour_cache.omit_aro_success) {
buf->ack_receive_cb = rpl_control_address_register_done;
}
} }
buf->src_sa.addr_type = ADDR_IPV6; buf->src_sa.addr_type = ADDR_IPV6;
@ -1481,6 +1507,12 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,
tr_debug("Build NA"); tr_debug("Build NA");
/* Check if ARO status == success, then sending can be omitted with flag */
if (aro && cur->ipv6_neighbour_cache.omit_aro_success && aro->status == ARO_SUCCESS) {
tr_debug("Omit success reply");
return NULL;
}
buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */ buffer_t *buf = buffer_get(8 + 16 + 16 + 16); /* fixed, target addr, target ll addr, aro */
if (!buf) { if (!buf) {
return NULL; return NULL;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -140,8 +140,8 @@ extern void icmpv6_recv_ra_routes(struct protocol_interface_info_entry *cur, boo
extern void icmpv6_recv_ra_prefixes(struct protocol_interface_info_entry *cur, bool enable); extern void icmpv6_recv_ra_prefixes(struct protocol_interface_info_entry *cur, bool enable);
extern void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len); extern void icmpv6_slaac_prefix_register_trig(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len);
extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime); extern int icmpv6_slaac_prefix_update(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime);
extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src); extern struct if_address_entry *icmpv6_slaac_address_add(struct protocol_interface_info_entry *cur, const uint8_t *prefix_ptr, uint8_t prefix_len, uint32_t valid_lifetime, uint32_t preferred_lifetime, bool skip_dad, slaac_src_e slaac_src);
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2017, Arm Limited and affiliates. * Copyright (c) 2015-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Arm Limited and affiliates. * Copyright (c) 2013-2018, Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");

Some files were not shown because too many files have changed in this diff Show More