Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mle_service.c Source File

mle_service.c

00001 /*
00002  * Copyright (c) 2015-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "nsconfig.h"
00019 #include <string.h>
00020 #include <ns_types.h>
00021 #include "ns_trace.h"
00022 #include "eventOS_event.h"
00023 #include "eventOS_scheduler.h"
00024 #include "eventOS_event_timer.h"
00025 #include "nsdynmemLIB.h"
00026 #include "ns_list.h"
00027 #include "randLIB.h"
00028 #include "socket_api.h"
00029 #include "Core/include/socket.h"
00030 #include "net_interface.h"
00031 #include "common_functions.h"
00032 #include "Common_Protocols/ipv6_constants.h"
00033 #include "NWK_INTERFACE/Include/protocol.h" // just for protocol_core_monotonic_time
00034 #include "Service_Libs/mle_service/mle_service_api.h"
00035 #include "Service_Libs/mle_service/mle_service_security.h"
00036 #include "Service_Libs/mle_service/mle_service_buffer.h"
00037 #include "Service_Libs/mle_service/mle_service_interface.h"
00038 #include "MLE/mle.h"
00039 #include "MLE/mle_tlv.h"
00040 #include "mac_common_defines.h"
00041 #include "6LoWPAN/MAC/mac_helper.h"
00042 
00043 #define TRACE_GROUP "mleS"
00044 
00045 /* Fixed-point randomisation limits for randlib_randomise_base() - RFC 3315
00046  * says RAND is uniformly distributed between -0.1 and +0.1
00047  */
00048 #define MLE_RAND_LOW   0x7333 // 1 - 0.1; minimum for "1+RAND"
00049 #define MLE_RAND_HIGH  0x8CCD // 1 + 0.1; maximum for "1+RAND"
00050 
00051 typedef struct {
00052     int8_t mle_socket;
00053     int8_t mle_socket_service_tasklet;
00054     uint8_t mle_adata[46];
00055     uint8_t mle_adata_length;
00056     arm_event_storage_t *mle_service_timer_storage;
00057     bool mle_frame_counter_check_enabled: 1;
00058     bool mle_frag_msg_security_enabled: 1;
00059     bool mle_accept_invalid_frame_counter: 1;
00060 } mle_service_class_t;
00061 
00062 #define MLE_SOCKET_SERVICE_TASKLET_INIT      1
00063 #define MLE_SOCKET_SERVICE_TIMER             2
00064 
00065 #define MLE_SOCKET_SERVICE_TIMER_ID          1
00066 
00067 #define MLE_SOCKET_TIMER_UPDATE_PERIOD_IN_MS 100
00068 
00069 mle_service_class_t *mle_service = NULL;
00070 
00071 static uint8_t *mle_security_aux_header_write(uint8_t *ptr, const mle_security_header_t *auxHeader);
00072 static void mle_security_aux_ccm_nonce_set(uint8_t *noncePtr, uint8_t *mac64, uint32_t securityFrameCounter, uint8_t securityLevel);
00073 static uint8_t mle_security_aux_header_size(uint8_t keyIdMode);
00074 
00075 /**
00076  * Enable service Timeout timer
00077  */
00078 static void mle_service_timer_start(void);
00079 
00080 /**
00081  * Disable service Timeout timer
00082  */
00083 static void mle_service_timer_stop(void);
00084 
00085 /**
00086  * MLE service event handler
00087  */
00088 static void mle_socket_service_tasklet(arm_event_s *event);
00089 
00090 /**
00091  * MLE service allocated and initialized
00092  */
00093 static bool mle_service_allocate(void);
00094 
00095 /**
00096  * Create TX buffer and add to list
00097  */
00098 static mle_service_msg_buf_t *mle_tr_create(uint16_t buffer_length);
00099 
00100 /**
00101  * Parse Security Header
00102  */
00103 static buffer_t *mle_service_parse_security_header(buffer_t *buf, mle_security_header_t *securityHeader,
00104         uint16_t *header_len);
00105 
00106 /**
00107  * Decode secured message
00108  */
00109 static buffer_t *mle_service_message_security_decode(buffer_t *buf, mle_security_header_t *securityHeader,
00110         uint8_t *security_key);
00111 
00112 /**
00113  *  Mle service generic MLE message handler
00114  */
00115 static void mle_service_socket_callback(void *cb);
00116 
00117 static int mle_service_build_packet_send(service_instance_t *srv_ptr, mle_security_components_t *sec_params, mle_service_msg_buf_t *buffer);
00118 
00119 /**
00120  * Check message sent tokens
00121  */
00122 static bool mle_service_message_tokens_check(service_instance_t *cur_ptr, bool priority);
00123 
00124 /**
00125  * Service instance timeout handler
00126  */
00127 static bool mle_service_instance_timeout_handler(uint16_t ticks, service_instance_t *cur_ptr);
00128 
00129 
00130 static void mle_service_timer_start(void)
00131 {
00132     if (!mle_service->mle_service_timer_storage) {
00133 
00134         arm_event_s event = {
00135                 .receiver = mle_service->mle_socket_service_tasklet,
00136                 .sender = 0,
00137                 .event_id = MLE_SOCKET_SERVICE_TIMER_ID,
00138                 .data_ptr = NULL,
00139                 .event_type = MLE_SOCKET_SERVICE_TIMER,
00140                 .priority = ARM_LIB_LOW_PRIORITY_EVENT,
00141         };
00142 
00143         mle_service->mle_service_timer_storage  = eventOS_event_timer_request_every(&event, eventOS_event_timer_ms_to_ticks(MLE_SOCKET_TIMER_UPDATE_PERIOD_IN_MS));
00144         if (!mle_service->mle_service_timer_storage) {
00145             tr_error("Mle servicetimer start fail");
00146         }
00147     }
00148 }
00149 /**
00150  * Disable service Timeout timer
00151  */
00152 static void mle_service_timer_stop(void)
00153 {
00154     if (mle_service->mle_service_timer_storage) {
00155         eventOS_cancel(mle_service->mle_service_timer_storage);
00156         mle_service->mle_service_timer_storage = NULL;
00157     }
00158 }
00159 
00160 static void mle_service_tr_timeout_handler(mle_service_msg_buf_t *cur_ptr)
00161 {
00162     uint16_t bufId = cur_ptr->msg_id;
00163     mle_service_message_timeout_cb *timeout = NULL;
00164 
00165     if (cur_ptr->timeout_cb && !cur_ptr->tokens_delay) {
00166         timeout = cur_ptr->timeout_cb;
00167     }
00168 
00169     if (!cur_ptr->delayed_response && !cur_ptr->tokens_delay) {
00170         //Update Retry Counter
00171         cur_ptr->retrans++;
00172         if (cur_ptr->retrans_max != 0 ) {
00173 
00174             if (cur_ptr->retrans >= cur_ptr->retrans_max) {
00175                 // retransmission count exceeded.
00176                 if (timeout) {
00177                     timeout(cur_ptr->interfaceId, cur_ptr->msg_id, true);
00178                 }
00179                 //Cuold be call timeout cb here
00180                 mle_service_msg_free(bufId);
00181                 return;
00182             } else {
00183                 if (timeout) {
00184                     if (!timeout(cur_ptr->interfaceId, cur_ptr->msg_id, false) ) {
00185                         //User want to stop retry
00186                         mle_service_msg_free(bufId);
00187                         return;
00188                     }
00189                 }
00190             }
00191         } else {
00192             mle_service_msg_free(bufId);
00193             return;
00194         }
00195     }
00196     service_instance_t *srv_ptr = mle_service_interface_find(cur_ptr->interfaceId);
00197     mle_security_components_t *sec_params = mle_service_security_params_get(cur_ptr->interfaceId);
00198 
00199     if (!srv_ptr || !sec_params) {
00200         mle_service_msg_free(bufId);
00201         return;
00202     }
00203 
00204     // Check if message needs to be delayed or removed because lack of message tokens
00205     if (!mle_service_message_tokens_check(srv_ptr, cur_ptr->tokens_priority)) {
00206         if (mle_service_buffer_tokens_delay_count() <= MLE_TOKEN_BUFFER_MAX_NBR) {
00207             // If message timeout has occurred delay because of tokens
00208             if (!cur_ptr->tokens_delay) {
00209                 cur_ptr->tokens_delay = true;
00210                 // Give time to wait free tokens
00211                 if (cur_ptr->timeout < MLE_TOKEN_DELAY) {
00212                     cur_ptr->timeout = MLE_TOKEN_DELAY;
00213                 }
00214             }
00215             // Delay has already been applied, now wait just for tokens
00216             cur_ptr->delayed_response = MLE_NO_DELAY;
00217         } else {
00218             mle_service_msg_free(bufId);
00219             tr_debug("MLE tokens message freed");
00220         }
00221         return;
00222     } else {
00223         cur_ptr->tokens_delay = false;
00224     }
00225 
00226     //Trig Buffer to socket
00227     mle_service_build_packet_send(srv_ptr, sec_params, cur_ptr);
00228 
00229     if (cur_ptr->retrans_max == 0) {
00230         mle_service_msg_free(bufId);//Remove packet which not need any retry after 1 retry
00231         return;
00232     }
00233 
00234     //Trig Retry or first packet
00235     if (cur_ptr->delayed_response ) {
00236         cur_ptr->delayed_response = MLE_NO_DELAY;
00237         cur_ptr->timeout = cur_ptr->timeout_init;
00238         return;
00239     }
00240 
00241 
00242     // RFC 3315 says:
00243     //     RT = 2*RTprev + RAND*RTprev,
00244     // We calculate this as
00245     //     RT = RTprev + (1+RAND)*RTprev
00246     cur_ptr->timeout = cur_ptr->timeout_init + randLIB_randomise_base(cur_ptr->timeout_init, MLE_RAND_LOW, MLE_RAND_HIGH);
00247     // Catch 16-bit integer overflow
00248     if (cur_ptr->timeout < cur_ptr->timeout_init) {
00249         cur_ptr->timeout = 0xFFFF;
00250     }
00251     // Check against MRT
00252     if (cur_ptr->timeout_max != 0 && cur_ptr->timeout > cur_ptr->timeout_max) {
00253         cur_ptr->timeout = randLIB_randomise_base(cur_ptr->timeout_max, MLE_RAND_LOW, MLE_RAND_HIGH);
00254     }
00255     cur_ptr->timeout_init = cur_ptr->timeout;
00256 }
00257 
00258 /**
00259  * MLE service timeout handling
00260  */
00261 bool mle_service_timer_tick(uint16_t ticks)
00262 {
00263     if (!mle_service ) {
00264         tr_debug("MLE not ready");
00265         return false;
00266     }
00267 
00268     bool active_timer_needed = false;
00269 
00270     // MLE service interface instance timeout handling
00271     if (mle_service_interface_timer_tick(ticks, mle_service_instance_timeout_handler)) {
00272         active_timer_needed = true;
00273     }
00274 
00275     // MLE service transaction timeout and retry handling
00276     if (mle_service_buffer_timer_tick(ticks, mle_service_tr_timeout_handler)) {
00277         active_timer_needed = true;
00278     }
00279 
00280     return active_timer_needed;
00281 }
00282 
00283 static void mle_socket_service_tasklet(arm_event_s *event)
00284 {
00285     if (event->event_type == MLE_SOCKET_SERVICE_TIMER) {
00286         if (!mle_service_timer_tick(1)) {
00287             mle_service_timer_stop();
00288         }
00289     }
00290 }
00291 
00292 static bool mle_service_allocate(void)
00293 {
00294     if (mle_service ) {
00295         return true;
00296     }
00297     mle_service = ns_dyn_mem_alloc(sizeof(mle_service_class_t));
00298     if (!mle_service) {
00299         return false;
00300     }
00301 
00302     mle_service->mle_socket = -1;
00303     mle_service->mle_socket_service_tasklet = eventOS_event_handler_create(mle_socket_service_tasklet, MLE_SOCKET_SERVICE_TASKLET_INIT);
00304     if (mle_service->mle_socket_service_tasklet < 0) {
00305         ns_dyn_mem_free(mle_service);
00306         mle_service = NULL;
00307         return false;
00308     }
00309     mle_service->mle_service_timer_storage = NULL;
00310     mle_service->mle_frame_counter_check_enabled = false;
00311     mle_service->mle_frag_msg_security_enabled = false;
00312     mle_service->mle_accept_invalid_frame_counter = false;
00313 
00314     return true;
00315 }
00316 
00317 static mle_service_msg_buf_t *mle_tr_create(uint16_t buffer_length)
00318 {
00319     uint16_t tr_id;
00320     mle_service_msg_buf_t *msg_ptr;
00321     msg_ptr = mle_service_buffer_get(buffer_length);
00322     if (msg_ptr == NULL) {
00323         return NULL;
00324     }
00325 
00326     tr_id = randLIB_get_16bit();// 16 bits for random
00327     // Ensure a unique non-zero transaction id for each transaction
00328     while (tr_id == 0 || mle_service_buffer_find(tr_id) != NULL) {
00329         tr_id = tr_id + 1;
00330     }
00331     msg_ptr->msg_id = tr_id;
00332     return msg_ptr;
00333 }
00334 
00335 static void mle_service_set_src_ll64(service_instance_t *srv_ptr, uint8_t *address)
00336 {
00337     memcpy(address,ADDR_LINK_LOCAL_PREFIX, 8);
00338     address += 8;
00339     memcpy(address,srv_ptr->mac64, 8);
00340     *address ^= 2;
00341 
00342 }
00343 static buffer_t *mle_security_interface_aux_header_parse(buffer_t *b, mle_security_header_t *auxSecHeader)
00344 {
00345     uint8_t auxBaseHeader;
00346     uint8_t *ptr = buffer_data_pointer(b);
00347 
00348     auxBaseHeader = *ptr;
00349 
00350     auxSecHeader->KeyIdMode = (auxBaseHeader >> 3) & 3;
00351     auxSecHeader->securityLevel = auxBaseHeader & 7;
00352     auxSecHeader->frameCounter = common_read_32_bit_inverse(ptr + 1);
00353     ptr += 5;
00354 
00355     switch (auxSecHeader->KeyIdMode) {
00356         case MAC_KEY_ID_MODE_SRC8_IDX:
00357             memcpy(auxSecHeader->Keysource, ptr, 8);
00358             ptr += 8;
00359             auxSecHeader->KeyIndex = *ptr++;
00360             break;
00361         case MAC_KEY_ID_MODE_SRC4_IDX:
00362             memcpy(auxSecHeader->Keysource, ptr, 4);
00363             ptr += 4;
00364             auxSecHeader->KeyIndex = *ptr++;
00365             break;
00366         case MAC_KEY_ID_MODE_IDX:
00367             auxSecHeader->KeyIndex = *ptr++;
00368             break;
00369         case MAC_KEY_ID_MODE_IMPLICIT:
00370         default:
00371             auxSecHeader->KeyIndex = 0;
00372             break;
00373     }
00374 
00375     buffer_data_pointer_set(b, ptr);
00376 
00377     if (buffer_data_length(b) < 0) {
00378         b = buffer_free(b);
00379     }
00380 
00381     return b;
00382 }
00383 
00384 static buffer_t *mle_service_parse_security_header(buffer_t *buf, mle_security_header_t *securityHeader,
00385         uint16_t *header_len)
00386 {
00387     uint16_t msg_len;
00388 
00389     msg_len = buffer_data_length(buf);
00390     buf = mle_security_interface_aux_header_parse(buf, securityHeader);
00391     if (!buf) {
00392         return NULL;
00393     }
00394     //Clear Headers off
00395     *header_len = (msg_len - buffer_data_length(buf));
00396     return buf;
00397 }
00398 
00399 /**
00400  * Build MLE ADATA for CCM security
00401  */
00402 static void mle_service_a_data_set(uint8_t *ptr, uint8_t *src_address, uint8_t *dest_address)
00403 {
00404     memcpy(ptr, src_address, 16);
00405     ptr += 16;
00406     memcpy(ptr, dest_address, 16);
00407 }
00408 
00409 static buffer_t *mle_service_message_security_decode(buffer_t *buf, mle_security_header_t *securityHeader,
00410         uint8_t *security_key)
00411 {
00412     ccm_globals_t *ccm_ptr;
00413     uint16_t payload_len = buffer_data_length(buf);
00414 
00415     ccm_ptr = ccm_sec_init(securityHeader->securityLevel, security_key, AES_CCM_DECRYPT, 2);
00416     if (!ccm_ptr) {
00417         return buffer_free(buf);
00418     } else if (ccm_ptr->mic_len >= payload_len) {
00419         return buffer_free(buf);
00420     }
00421 
00422     //SET Nonce
00423     buf->src_sa .address [8] ^= 2;
00424     mle_security_aux_ccm_nonce_set(ccm_ptr->exp_nonce, &(buf->src_sa .address [8]),
00425             securityHeader->frameCounter, securityHeader->securityLevel);
00426     buf->src_sa .address [8] ^= 2;
00427 
00428     if (ccm_ptr->mic_len) {
00429         payload_len -= ccm_ptr->mic_len;
00430         buf->buf_end  -= ccm_ptr->mic_len;
00431 
00432         ccm_ptr->data_ptr = buffer_data_pointer(buf);
00433         ccm_ptr->adata_ptr = mle_service->mle_adata;
00434         ccm_ptr->data_len = payload_len;
00435         ccm_ptr->adata_len = mle_service->mle_adata_length;
00436         //SET MIC
00437         ccm_ptr->mic = ccm_ptr->data_ptr;
00438         ccm_ptr->mic += payload_len;
00439     } else {
00440         ccm_ptr->data_len = payload_len;
00441         ccm_ptr->data_ptr = buffer_data_pointer(buf);
00442     }
00443 
00444     if (ccm_process_run(ccm_ptr) != 0) {
00445         tr_error("MLE mic fail!");
00446         buf = buffer_free(buf);
00447     }
00448     return buf;
00449 }
00450 
00451 
00452 static buffer_t *mle_message_security_header_set(buffer_t *buf,service_instance_t *srv_ptr,mle_security_components_t *sec_params, mle_security_header_t *security_header)
00453 {
00454     uint8_t *ptr;
00455     //Verify first security level
00456     if (security_header->securityLevel) {
00457         //Get Security keys
00458         ccm_globals_t *ccm_ptr;
00459         uint16_t header_size;
00460         uint16_t data_len;
00461         data_len = buffer_data_length(buf);
00462         ptr = mle_service_security_get_key(security_header,sec_params, srv_ptr->interface_id );
00463         if (!ptr) {
00464             goto drop_buffer;
00465         }
00466         // Init
00467         ccm_ptr = ccm_sec_init(security_header->securityLevel, ptr, AES_CCM_ENCRYPT, 2);
00468         if (!ccm_ptr) {
00469             goto drop_buffer;
00470         }
00471 
00472         header_size = mle_security_aux_header_size(security_header->KeyIdMode);
00473 
00474         //SET Nonce
00475         mle_security_aux_ccm_nonce_set(ccm_ptr->exp_nonce, srv_ptr->mac64, security_header->frameCounter, security_header->securityLevel);
00476         if (ccm_ptr->mic_len) {
00477             buf = buffer_headroom(buf, (ccm_ptr->mic_len + 32 + header_size));
00478             if (buf) {
00479                 uint8_t *ptr2;
00480                 //Move current data to left by mic_len bytes
00481                 ptr = buffer_data_pointer(buf);
00482                 //Set new data pointer
00483                 ptr2 = ptr;
00484                 ptr2 -= ccm_ptr->mic_len;
00485 
00486                 memmove(ptr2, ptr, data_len);
00487 
00488                 //Cut Mic len
00489                 buf->buf_end  -= ccm_ptr->mic_len;
00490 
00491                 ptr -= header_size + ccm_ptr->mic_len;
00492                 ptr = mle_security_aux_header_write(ptr, security_header);
00493                 ptr -= header_size;
00494                 //Set pointer to Adata
00495                 ptr -= (32);
00496                 mle_service_a_data_set(ptr, buf->src_sa .address , buf->dst_sa .address );
00497                 //Create ADATA
00498                 ccm_ptr->adata_ptr = ptr;
00499                 ccm_ptr->adata_len = (32 + header_size);
00500 
00501                 //SET ptr to show to real payload
00502                 buf->buf_ptr  -= ccm_ptr->mic_len;
00503             } else {
00504                 tr_warn("Security header alloc fail");
00505                 buf = (buffer_t *) 0;
00506                 return buf;
00507             }
00508         }
00509         ptr = buffer_data_pointer(buf);
00510         ccm_ptr->data_ptr = ptr;
00511         ccm_ptr->data_len = data_len;
00512 
00513         ccm_ptr->mic = ptr;
00514         ccm_ptr->mic += data_len;
00515         ccm_process_run(ccm_ptr);
00516         if (ccm_ptr->mic_len) {
00517             //SET Calculated mic
00518             buf->buf_end  += ccm_ptr->mic_len;
00519         }
00520         buffer_data_reserve_header(buf, header_size);
00521     }
00522 
00523     buf = buffer_headroom(buf, 1);
00524     if (buf) {
00525         ptr = buffer_data_reserve_header(buf, 1);
00526         if (security_header->securityLevel) {
00527             *ptr++ = 0; // security
00528         } else {
00529             *ptr++ = 0xff; // No security
00530         }
00531     } else {
00532         tr_warn("HeadRoom Fail");
00533     }
00534     return buf;
00535     drop_buffer:
00536 
00537     return buffer_free(buf);
00538 }
00539 
00540 static int mle_service_build_packet_send(service_instance_t *srv_ptr, mle_security_components_t *sec_params, mle_service_msg_buf_t *buffer)
00541 {
00542     buffer_t *buf;
00543     uint8_t *ptr;
00544     uint16_t header_length = 1; //Include security header
00545 
00546     //allocate Buffer for MLE header and Message length
00547     if (buffer->security_header.securityLevel) {
00548         header_length += mle_security_aux_header_size(buffer->security_header.KeyIdMode);
00549 
00550         header_length += 32; //AuthData
00551     }
00552 
00553     buf = buffer_get(buffer->buf_end + header_length);
00554     if (!buf) {
00555         return -1;
00556     }
00557 
00558     if (buffer->security_header.securityLevel) {
00559         uint8_t *dada_ptr = buffer->buf + 1;
00560         uint16_t dada_length = buffer->buf_end - 1;
00561 
00562         mle_tlv_info_t option_info;
00563         //Update mle frame counter evry time for every packet
00564         buffer->security_header.frameCounter = mle_service_security_get_framecounter(sec_params, true);
00565         buffer->security_header.KeyIndex = mle_service_security_get_default_key_id(sec_params);
00566         //Update MAC frame Counter and MLE frame counter to current one allways
00567         if (mle_tlv_option_discover(dada_ptr, dada_length, MLE_TYPE_LL_FRAME_COUNTER, &option_info) == 4) {
00568             // GET frame counter from interface
00569             uint32_t counter;
00570             if (mac_helper_link_frame_counter_read(srv_ptr->interface_id, &counter) == 0) {
00571                 common_write_32_bit(counter,option_info.dataPtr);
00572             }
00573         }
00574 
00575         if (mle_tlv_option_discover(dada_ptr, dada_length, MLE_TYPE_MLE_FRAME_COUNTER, &option_info) == 4) {
00576             common_write_32_bit(buffer->security_header.frameCounter, option_info.dataPtr);
00577         }
00578     }
00579 
00580     //XXX Everything below this point is so broken. API of socket_buffer_sendmsg says buf should not have any metadata
00581 
00582     //Set LL64 Source (for mle_message_security_header_set, and sendmsg picks it up too, although it shouldn't)
00583     mle_service_set_src_ll64(srv_ptr,buf->src_sa .address );
00584     //Set Destination address (for benefit of mle_message_security_header_set, not sendmsg)
00585     memcpy(buf->dst_sa .address , buffer->dst_address, 16);
00586 
00587     // Normal Thread behaviour is for end devices to send multicasts as unicasts
00588     // to parent - this overrides.
00589     if (addr_is_ipv6_multicast(buffer->dst_address)) {
00590         buf->options .ll_broadcast_tx  = true;
00591     }
00592     buf->src_sa .addr_type  = buf->dst_sa .addr_type  = ADDR_IPV6 ;
00593     buf->src_sa .port  = buf->dst_sa .port  = MLE_ALLOCATED_PORT;
00594     //Copy Payload
00595     ptr = buffer_data_pointer(buf);
00596     memcpy(ptr, buffer->buf, buffer->buf_end);
00597     buffer_data_length_set(buf, buffer->buf_end );
00598 
00599     //Add security header and encode message
00600     buf = mle_message_security_header_set(buf, srv_ptr, sec_params, &buffer->security_header);
00601 
00602     if (!buf) {
00603         return -1;
00604     }
00605 
00606     if (mle_service->mle_frag_msg_security_enabled) {
00607         // Enable link layer security for fragmented packets
00608         buf->options .ll_sec_bypass_frag_deny  = true;
00609     }
00610 
00611     if (buffer->selected_channel) {
00612         buf->link_specific.ieee802_15_4.rf_channel_switch = true;
00613         buf->link_specific.ieee802_15_4.selected_channel = buffer->selected_rf_channel;
00614     }
00615 
00616     //Marks message sent
00617     buffer->message_sent = true;
00618 
00619     if (buffer->selected_pan_id) {
00620         buf->link_specific.ieee802_15_4.useDefaultPanId = false;
00621         buf->link_specific.ieee802_15_4.dstPanId = buffer->packet_panid;
00622     }
00623 
00624     int8_t security;
00625 
00626     if (buffer->enable_link_layer_security) {
00627         security = 1;
00628         if (buffer->psk_key_id_mode_2) {
00629             buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_2;
00630         } else {
00631             buf->link_specific.ieee802_15_4.key_id_mode = B_SECURITY_KEY_ID_MODE_DEFAULT;
00632         }
00633     } else {
00634         security = 0;
00635     }
00636     socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &security, sizeof(int8_t));
00637 
00638     //sendmsg always takes destination from msg, not from the buffer, so must specify there
00639     ns_address_t dst_addr;
00640     dst_addr.type = ADDRESS_IPV6;
00641     memcpy(dst_addr.address, buffer->dst_address, 16);
00642     dst_addr.identifier = MLE_ALLOCATED_PORT;
00643 
00644     ns_msghdr_t msg = {
00645         .msg_name = &dst_addr,
00646         .msg_namelen = sizeof dst_addr
00647     };
00648     //Push to socket
00649     //XXX This is so broken. API of socket_buffer_sendmsg says buf should not have any metadata
00650     socket_buffer_sendmsg(mle_service->mle_socket, buf, &msg, 0);
00651     return 0;
00652 }
00653 
00654 static void mle_service_socket_callback(void *cb)
00655 {
00656     socket_buffer_callback_t *cb_buf = cb;
00657     uint8_t mle_security_byte;
00658     uint16_t security_header_length;
00659     mle_security_header_t securityHeader;
00660     mle_message_t mle_msg;
00661     if (!cb_buf) {
00662         tr_warn("mle sck cb without buf!");
00663         return;
00664     }
00665     buffer_t *buf = cb_buf->buf ;
00666     if (cb_buf->event_type != SOCKET_DATA || !buf) {
00667         return;
00668     }
00669 
00670     service_instance_t *service_handler = mle_service_interface_find(cb_buf->interface_id);
00671     mle_security_components_t * sec_params = mle_service_security_params_get(cb_buf->interface_id);
00672 
00673     if (!service_handler || !sec_params) {
00674         tr_warn("service handler not registerd");
00675         goto error_handler;
00676     }
00677 
00678     // MLE messages are only allowed to Link local address
00679     if (!addr_is_ipv6_link_local(buf->src_sa .address ) ||
00680          addr_ipv6_scope(buf->dst_sa .address , NULL) != IPV6_SCOPE_LINK_LOCAL) {
00681         // Security failure so drop packet
00682         goto error_handler;
00683     }
00684 
00685     //Start Parsing Header
00686     mle_security_byte = buffer_pull_uint8(buf);
00687 
00688     if (mle_security_byte == 0xff) {
00689         securityHeader.KeyIndex = 0;
00690         securityHeader.KeyIdMode = MAC_KEY_ID_MODE_IDX;
00691         securityHeader.securityLevel = 0;
00692     } else if(mle_security_byte == 0) {
00693 
00694         //SET adata
00695         uint8_t *sec_header_ptr = buffer_data_pointer(buf);
00696 
00697 
00698         buf = mle_service_parse_security_header(buf, &securityHeader, &security_header_length);
00699         if (!buf) {
00700             goto error_handler;
00701         }
00702 
00703         //SET adata and length
00704         mle_service->mle_adata_length = (32 + security_header_length);
00705 
00706         //copy data
00707         mle_service_a_data_set(mle_service->mle_adata, buf->src_sa .address , buf->dst_sa .address );
00708         memcpy(&mle_service->mle_adata[32],sec_header_ptr, security_header_length);
00709     } else {
00710         goto error_handler;
00711     }
00712 
00713     bool security_bypass;
00714     securityHeader.invalid_frame_counter = false;
00715     if (securityHeader.securityLevel) {
00716 
00717         if (sec_params->sec_level == 0) {
00718             tr_debug("Drop secured packet when security is disabled");
00719             goto error_handler;
00720         }
00721         //Get A key here
00722         uint8_t *key_ptr = mle_service_security_get_key(&securityHeader, sec_params, service_handler->interface_id);
00723         if (!key_ptr) {
00724             goto error_handler;
00725         }
00726 
00727 
00728         /* MLE neighbour table frame counter check */
00729         mle_neigh_table_entry_t *neighbour = NULL;
00730         uint32_t keySeq;
00731         if (securityHeader.KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
00732             keySeq = common_read_32_bit(securityHeader.Keysource);
00733         } else {
00734             keySeq = (uint32_t)securityHeader.KeyIndex;
00735         }
00736 
00737         if (mle_service->mle_frame_counter_check_enabled) {
00738             neighbour = mle_class_discover_entry_by_ll64(service_handler->interface_id,buf->src_sa .address );
00739             if (neighbour){
00740                 //key pending is set - incoming frame counter will be reset when new sequence is heard or lower framecounter is heard
00741                 if (neighbour->new_key_pending) {
00742                     if ((securityHeader.frameCounter < neighbour->mle_frame_counter || keySeq != neighbour->last_key_sequence)) {
00743                         neighbour->mle_frame_counter = 0;
00744                         neighbour->last_key_sequence = keySeq;
00745                         neighbour->new_key_pending = false;
00746                         goto start_decode; //Skip validation part
00747                     }
00748                 }
00749                 //key pending not set - continue normal operation
00750                 if (keySeq < neighbour->last_key_sequence) {
00751                     tr_warn("Dropping packet because key sequence smaller: %"PRIu32" < %"PRIu32,
00752                             keySeq, neighbour->last_key_sequence);
00753                     goto error_handler;
00754                 }
00755                 if (securityHeader.frameCounter <= neighbour->mle_frame_counter && keySeq == neighbour->last_key_sequence){
00756                     if (mle_service->mle_accept_invalid_frame_counter) {
00757                         securityHeader.invalid_frame_counter = true;
00758                     } else {
00759                         tr_warn("Dropping packet MLE frame counter is not higher:%"PRIu32" <= %"PRIu32,securityHeader.frameCounter,neighbour->mle_frame_counter);
00760                         goto error_handler;
00761                     }
00762                 }
00763             }
00764         }
00765         start_decode:
00766         buf = mle_service_message_security_decode(buf, &securityHeader,key_ptr);
00767         if (!buf) {
00768             goto error_handler;
00769         }
00770         security_bypass = false;
00771         if (mle_service->mle_frame_counter_check_enabled && !securityHeader.invalid_frame_counter) {
00772             if (neighbour) {
00773                 neighbour->mle_frame_counter = securityHeader.frameCounter;
00774                 neighbour->last_key_sequence = keySeq;
00775             }
00776         }
00777     } else {
00778         if (sec_params->sec_level) {
00779             if (!service_handler->recv_security_bypass_cb) {
00780                 tr_debug("Drop unsecured packet when security is enabled");
00781                 goto error_handler;
00782             }
00783             security_bypass = true;
00784         } else {
00785             security_bypass = false;
00786         }
00787     }
00788 
00789 
00790 
00791     mle_msg.message_type = buffer_pull_uint8(buf);
00792     mle_msg.data_length = buffer_data_length(buf);
00793     mle_msg.data_ptr = buffer_data_pointer(buf);
00794     mle_msg.dst_pan_id = buf->link_specific.ieee802_15_4.dstPanId;
00795     mle_msg.src_pan_id = buf->link_specific.ieee802_15_4.srcPanId;
00796     if (mle_message_malformed_check(mle_msg.data_ptr, mle_msg.data_length) != 0) {
00797         tr_debug("Malfor");
00798         goto error_handler;
00799     }
00800     mle_msg.packet_src_address = buf->src_sa .address ;
00801     mle_msg.packet_dst_address = buf->dst_sa .address ;
00802     mle_msg.dbm = buf->options .dbm ;
00803     mle_msg.lqi = buf->options .lqi ;
00804 
00805     if (security_bypass) {
00806         /* Security by pass message handler call */
00807         service_handler->recv_security_bypass_cb(service_handler->interface_id, &mle_msg);
00808     } else {
00809 
00810         if (service_handler->recv_cb) {
00811             service_handler->recv_cb(service_handler->interface_id, &mle_msg, &securityHeader);
00812         }
00813     }
00814 
00815     error_handler:
00816     if (buf) {
00817         buffer_free(buf);
00818     }
00819 }
00820 
00821 static bool mle_service_message_tokens_check(service_instance_t *cur_ptr, bool priority)
00822 {
00823     if (!cur_ptr || cur_ptr->token_bucket_size == 0) {
00824         return true;
00825     }
00826 
00827     if (priority) {
00828         if (cur_ptr->token_bucket > MLE_TOKEN_BUFFER_MIN_NBR) {
00829             cur_ptr->token_bucket--;
00830         }
00831         return true;
00832     }
00833 
00834     if (cur_ptr->token_bucket > 0) {
00835         cur_ptr->token_bucket--;
00836         return true;
00837     } else {
00838         return false;
00839     }
00840 }
00841 
00842 static bool mle_service_instance_timeout_handler(uint16_t ticks, service_instance_t *cur_ptr)
00843 {
00844     if (!cur_ptr || cur_ptr->token_bucket_size == 0 || cur_ptr->token_bucket_rate == 0) {
00845         return false;
00846         }
00847 
00848     cur_ptr->token_bucket_ticks += ticks;
00849 
00850     while (cur_ptr->token_bucket_ticks >= cur_ptr->token_bucket_rate) {
00851         cur_ptr->token_bucket_ticks -= cur_ptr->token_bucket_rate;
00852         cur_ptr->token_bucket += cur_ptr->token_bucket_count;
00853     }
00854 
00855     if (cur_ptr->token_bucket < cur_ptr->token_bucket_size) {
00856         return true;
00857     } else {
00858         cur_ptr->token_bucket = cur_ptr->token_bucket_size;
00859         return false;
00860     }
00861 }
00862 
00863 int mle_service_interface_register(int8_t interface_id, mle_service_receive_cb *receive_cb, uint8_t *mac64, uint8_t challengeLength)
00864 {
00865     service_instance_t *srv_ptr;
00866 
00867     if (challengeLength < 4 || challengeLength > 32) {
00868         return -1;
00869     } else if (!receive_cb) {
00870         return -1;
00871     } else if (!mac64) {
00872         return -1;
00873     }
00874 
00875     if (!mle_service_allocate()) {
00876         tr_error("dhcp Sockets data base alloc fail");
00877         return -1;
00878     }
00879 
00880     if (mle_service_security_instance_allocate(interface_id) != 0) {
00881         return -1;
00882     }
00883 
00884     srv_ptr = mle_service_interface_get(interface_id);
00885     if (!srv_ptr) {
00886         goto error_handler;
00887     }
00888 
00889     srv_ptr->recv_cb = receive_cb;
00890     srv_ptr->challenge_length = challengeLength;
00891     memcpy(srv_ptr->mac64, mac64, 8);
00892 
00893     if (mle_service->mle_socket < 0) {
00894         if (socket_create(SOCKET_FAMILY_IPV6, SOCKET_TYPE_DGRAM, 0, &mle_service->mle_socket, MLE_ALLOCATED_PORT, mle_service_socket_callback, true) != eOK) {
00895             mle_service->mle_socket = -1;
00896         }
00897     }
00898 
00899     if (mle_service->mle_socket < 0 ) {
00900         tr_error("Sockets not available");
00901         goto error_handler;
00902     } else {
00903         const int16_t hops = 255;
00904         const uint32_t address_pref = SOCKET_IPV6_PREFER_SRC_6LOWPAN_LONG;
00905         const int8_t security = 0;
00906         const bool loop = false;
00907         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_UNICAST_HOPS, &hops, sizeof hops);
00908         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_HOPS, &hops, sizeof hops);
00909         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_MULTICAST_LOOP, &loop, sizeof loop);
00910         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_IPV6_ADDR_PREFERENCES, &address_pref, sizeof address_pref);
00911         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_LINK_LAYER_SECURITY, &security, sizeof security);
00912         //Set service interface id
00913         socket_setsockopt(mle_service->mle_socket, SOCKET_IPPROTO_IPV6, SOCKET_INTERFACE_SELECT, &srv_ptr->interface_id, sizeof srv_ptr->interface_id);
00914     }
00915 
00916     return 0;
00917 
00918     error_handler:
00919     mle_service_interface_delete(interface_id);
00920     mle_service_security_instance_delete(interface_id);
00921     return -1;
00922 }
00923 
00924 bool mle_service_interface_registeration_validate(int8_t interface_id)
00925 {
00926     if (mle_service_interface_find(interface_id) ) {
00927         return true;
00928     }
00929 
00930     return false;
00931 }
00932 
00933 
00934 int mle_service_interface_receiver_handler_update(int8_t interface_id, mle_service_receive_cb *receive_cb)
00935 {
00936     service_instance_t *srv_ptr;
00937 
00938     srv_ptr = mle_service_interface_find(interface_id);
00939     if (!srv_ptr) {
00940         return -1;
00941     }
00942 
00943     srv_ptr->recv_cb = receive_cb;
00944 
00945     return 0;
00946 }
00947 
00948 int mle_service_interface_receiver_bypass_handler_update(int8_t interface_id, mle_service_receive_security_bypass_cb *receive_cb)
00949 {
00950     service_instance_t *srv_ptr;
00951 
00952     srv_ptr = mle_service_interface_find(interface_id);
00953     if (!srv_ptr) {
00954         return -1;
00955     }
00956 
00957     srv_ptr->recv_security_bypass_cb = receive_cb;
00958 
00959     return 0;
00960 }
00961 
00962 void mle_service_interface_unregister(int8_t interface_id)
00963 {
00964     //Remove service from list and free class
00965     mle_service_interface_delete(interface_id);
00966     //Remove Security Instance
00967     mle_service_security_instance_delete(interface_id);
00968     //Free Tx queue by unregistered interface id
00969     mle_service_buffer_clean_buffers_by_interface_id(interface_id);
00970 
00971     if (mle_service) {
00972         if (mle_service_interface_list_empty()) {
00973             tr_debug("Free Socket");
00974             socket_close(mle_service->mle_socket);
00975             mle_service->mle_socket = -1;
00976         }
00977     }
00978 }
00979 
00980 int mle_service_reset_frame_counters(int8_t interfaceId)
00981 {
00982     mle_service_security_set_frame_counter(interfaceId, 0);
00983     mle_class_set_new_key_pending(interfaceId);
00984     return 0;
00985 }
00986 
00987 void mle_service_interface_tx_queue_clean(int8_t interface_id)
00988 {
00989     mle_service_buffer_clean_buffers_by_interface_id(interface_id);
00990 }
00991 
00992 uint16_t mle_service_interface_tx_queue_size(int8_t interface_id)
00993 {
00994     return mle_service_buffer_count_by_interface_id(interface_id);
00995 }
00996 
00997 int mle_service_interface_token_bucket_settings_set(int8_t interface_id, uint8_t size, uint8_t rate, uint8_t count)
00998 {
00999     service_instance_t *srv_ptr;
01000 
01001     srv_ptr = mle_service_interface_find(interface_id);
01002     if (!srv_ptr) {
01003         return -1;
01004     }
01005     srv_ptr->token_bucket = size;
01006     srv_ptr->token_bucket_ticks = 0;
01007     srv_ptr->token_bucket_size = size;
01008     srv_ptr->token_bucket_rate = rate;
01009     srv_ptr->token_bucket_count = count;
01010 
01011     return 0;
01012 }
01013 
01014 uint16_t mle_service_msg_allocate(int8_t interface_id, uint16_t data_length, bool challengeAllocate, uint8_t type)
01015 {
01016     uint16_t temporary_length = 64;
01017     mle_service_msg_buf_t *buf;
01018     //Verify that Interface is registered
01019     service_instance_t *srv_ptr = mle_service_interface_find(interface_id);
01020     if (!srv_ptr) {
01021         return 0;
01022     }
01023 
01024     mle_security_components_t * sec_params = mle_service_security_params_get(interface_id);
01025     if (!sec_params) {
01026         return 0;
01027     }
01028 
01029     if (data_length > 63) {
01030         temporary_length = data_length  + 1;
01031     }
01032 
01033     if (challengeAllocate) {
01034         temporary_length += (srv_ptr->challenge_length + 2 );
01035     }
01036 
01037     buf = mle_tr_create(temporary_length);
01038     if (!buf) {
01039         return 0;
01040     }
01041     //Set interface id to buffer
01042     buf->interfaceId = interface_id;
01043 
01044     mle_service_buffer_set_msg_type(buf->msg_id, type);
01045 
01046     if (challengeAllocate) {
01047         //SET Challenge all ways to front
01048         uint8_t *ptr = mle_msg_data_pointer(buf);
01049         *ptr++ = MLE_TYPE_CHALLENGE;
01050         *ptr++ = srv_ptr->challenge_length;
01051         buf->challengeLen = srv_ptr->challenge_length;
01052         buf->challengePtr = ptr;
01053         randLIB_get_n_bytes_random(ptr, srv_ptr->challenge_length);
01054         mle_msg_length_set(buf,(srv_ptr->challenge_length +2));
01055     } else {
01056         //NO retry by default
01057         buf->timeout_init = buf->timeout = buf->timeout_max = 0;
01058         buf->retrans_max = 0;
01059     }
01060     //Set default security level and key id mode
01061     //Key id, frame counter will be updated when default need to be change
01062     buf->security_header.securityLevel = sec_params->sec_level;
01063     buf->security_header.KeyIdMode = MAC_KEY_ID_MODE_IDX;
01064 
01065     return buf->msg_id;
01066 }
01067 
01068 uint8_t * mle_service_get_data_pointer(uint16_t msgId)
01069 {
01070     return mle_service_buffer_get_data_pointer(msgId);
01071 }
01072 
01073 uint8_t * mle_service_get_payload_start_point(uint16_t msgId)
01074 {
01075     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
01076     if (!buf) {
01077         return NULL;
01078     }
01079     uint8_t *ptr = buf->buf;
01080 
01081     return (ptr + 1);
01082 }
01083 
01084 uint16_t  mle_service_get_payload_length(uint16_t msgId)
01085 {
01086     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
01087     if (!buf) {
01088         return 0;
01089     }
01090 
01091     if (buf->buf_end == 0) {
01092         return 0;
01093     }
01094 
01095     return (buf->buf_end -1);
01096 
01097 }
01098 
01099 int mle_service_update_length(uint16_t msgId, uint16_t tail_length)
01100 {
01101     return mle_service_buffer_update_length(msgId, tail_length);
01102 }
01103 
01104 int mle_service_update_length_by_ptr(uint16_t msgId, uint8_t *data_end_ptr)
01105 {
01106     return mle_service_buffer_update_length_by_ptr(msgId, data_end_ptr);
01107 }
01108 
01109 int mle_service_msg_update_security_params(uint16_t msgId, uint8_t security_level, uint8_t key_id_mode, uint32_t keysequence)
01110 {
01111     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
01112     if (!buf) {
01113         return -1;
01114     }
01115 
01116     if (security_level > AES_SECURITY_LEVEL_ENC_MIC128 ) {
01117         return -2;
01118     } else if (security_level && key_id_mode != MAC_KEY_ID_MODE_IDX && key_id_mode != MAC_KEY_ID_MODE_SRC4_IDX) {
01119         return -2;
01120     }
01121 
01122     buf->security_header.securityLevel = security_level;
01123     buf->security_header.KeyIdMode = key_id_mode;
01124     common_write_32_bit(keysequence,buf->security_header.Keysource);
01125     return 0;
01126 }
01127 
01128 int mle_service_set_packet_callback(uint16_t msgId, mle_service_message_timeout_cb *cb)
01129 {
01130     return mle_service_buffer_set_timeout_cb(msgId, cb);
01131 }
01132 
01133 int mle_service_set_msg_response_true(uint16_t msgId)
01134 {
01135     return mle_service_buffer_set_response(msgId);
01136 }
01137 
01138 uint8_t * mle_service_get_msg_destination_address_pointer(uint16_t msgId)
01139 {
01140     return mle_service_buffer_get_msg_destination_address_pointer(msgId);
01141 }
01142 
01143 int mle_service_set_msg_destination_address(uint16_t msgId, const uint8_t *dstAddress)
01144 {
01145     if (!dstAddress) {
01146         return -2;
01147     }
01148 
01149     uint8_t *address_ptr = mle_service_buffer_get_msg_destination_address_pointer(msgId);
01150 
01151     if (!address_ptr) {
01152         return -1;
01153     }
01154     memcpy(address_ptr, dstAddress, 16);
01155     return 0;
01156 }
01157 
01158 int mle_service_set_msg_panid(uint16_t msgId, uint16_t panid)
01159 {
01160     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
01161 
01162     if (!buf) {
01163         return -1;
01164     }
01165     buf->selected_pan_id = true;
01166     buf->packet_panid = panid;
01167     return 0;
01168 }
01169 
01170 int mle_service_msg_free(uint16_t msgId)
01171 {
01172     return mle_service_buffer_free(mle_service_buffer_find(msgId));
01173 }
01174 
01175 bool mle_service_transaction_buffer_get_for_response(uint8_t *responseData, uint16_t length, uint16_t *msgId)
01176 {
01177     mle_service_msg_buf_t *buffer = mle_service_buffer_find_for_response(responseData, length);
01178     if (!buffer) {
01179         return false;
01180     }
01181 
01182     *msgId = buffer->msg_id;
01183     return true;
01184 }
01185 
01186 bool mle_service_check_msg_sent(uint16_t msgId)
01187 {
01188     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
01189 
01190     if (!buf) {
01191         return false;
01192     }
01193 
01194     return buf->message_sent;
01195 }
01196 
01197 int mle_service_message_tail_get(uint16_t msgId, uint16_t tail_length)
01198 {
01199     return mle_service_buffer_tail_get(msgId,tail_length);
01200 }
01201 
01202 int mle_service_set_msg_timeout_parameters(uint16_t msgId, mle_message_timeout_params_t *timeout_params)
01203 {
01204     mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId);
01205 
01206     if (!buffer) {
01207         return -1;
01208     }
01209 
01210     buffer->timeout_init = randLIB_randomise_base(timeout_params->timeout_init * 10, MLE_RAND_LOW, MLE_RAND_HIGH);
01211     buffer->timeout = buffer->timeout_init;
01212     buffer->timeout_max = timeout_params->timeout_max * 10;
01213     buffer->retrans_max = timeout_params->retrans_max;
01214     buffer->delayed_response = timeout_params->delay;
01215     return 0;
01216 }
01217 
01218 int mle_service_set_msg_token_bucket_priority(uint16_t msgId)
01219 {
01220     mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId);
01221 
01222     if (!buffer) {
01223         return -1;
01224     }
01225 
01226     buffer->tokens_priority = true;
01227     return 0;
01228 }
01229 
01230 int mle_service_send_message(uint16_t msgId)
01231 {
01232     mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId);
01233 
01234     if (!buffer) {
01235         return -1;
01236     }
01237 
01238     service_instance_t *srv_ptr = mle_service_interface_find(buffer->interfaceId);
01239     mle_security_components_t *sec_params = mle_service_security_params_get(buffer->interfaceId);
01240 
01241     if (!srv_ptr || !sec_params) {
01242         mle_service_buffer_free(buffer);
01243         return -1;
01244     }
01245 
01246     //Trig timer
01247     mle_service_timer_start();
01248 
01249     if (buffer->delayed_response) {
01250         //set random jitter for response
01251         buffer->timeout = randLIB_get_random_in_range(1, buffer->delayed_response);
01252         return 0;
01253     }
01254 
01255     // Check if message needs to be delayed or removed because lack of message tokens
01256     if (!mle_service_message_tokens_check(srv_ptr, buffer->tokens_priority)) {
01257         if (mle_service_buffer_tokens_delay_count() <= MLE_TOKEN_BUFFER_MAX_NBR) {
01258             buffer->tokens_delay = true;
01259             // Give time to wait free tokens
01260             if (buffer->timeout < MLE_TOKEN_DELAY) {
01261                 buffer->timeout = MLE_TOKEN_DELAY;
01262             }
01263         } else {
01264             mle_service_buffer_free(mle_service_buffer_find(buffer->msg_id));
01265             tr_debug("MLE tokens message freed");
01266         }
01267         return 0;
01268     }
01269 
01270     if (mle_service_build_packet_send(srv_ptr,sec_params, buffer) != 0 ) {
01271         tr_warn("MLE message sending failed, ipv6=%s", trace_ipv6(buffer->dst_address));
01272         buffer->delayed_response = 1;
01273         buffer->timeout = 1;
01274         buffer->retrans_max++;
01275     } else {
01276         if (buffer->retrans_max == 0 && !buffer->timeout) {
01277             //Free msg
01278             mle_service_buffer_free(mle_service_buffer_find(buffer->msg_id));
01279         }
01280     }
01281 
01282     return 0;
01283 }
01284 
01285 int mle_service_security_init(int8_t interfaceId, uint8_t security_level, uint32_t security_frame_counter, mle_service_key_request_by_counter_cb * key_counter_req, mle_service_security_notify_cb *notify)
01286 {
01287     mle_security_components_t *srv_ptr = mle_service_security_params_get(interfaceId);
01288     if (!srv_ptr) {
01289         return -1;
01290     }
01291 
01292     if (security_level > AES_SECURITY_LEVEL_ENC_MIC128) {
01293         return -2;
01294     }
01295 
01296     mle_service_security_parameters_init(srv_ptr);
01297     srv_ptr->sec_level = security_level;
01298     srv_ptr->key_req = key_counter_req;
01299     srv_ptr->security_notify = notify;
01300     srv_ptr->security_frame_counter = security_frame_counter;
01301     return 0;
01302 }
01303 
01304 
01305 bool mle_service_security_set_frame_counter(int8_t interfaceId, uint32_t frame_counter)
01306 {
01307     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01308     if (!sec_ptr) {
01309         return false;
01310     }
01311 
01312     sec_ptr->security_frame_counter = frame_counter;
01313 
01314     return true;
01315 }
01316 
01317 uint32_t mle_service_security_get_frame_counter(int8_t interfaceId)
01318 {
01319     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01320     if (!sec_ptr) {
01321         return 0;
01322     }
01323 
01324     return sec_ptr->security_frame_counter;
01325 }
01326 
01327 uint8_t * mle_service_security_default_key_get(int8_t interfaceId)
01328 {
01329     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01330     if (!sec_ptr) {
01331         return NULL;
01332     }
01333 
01334     return mle_service_security_get_default_key(sec_ptr);
01335 }
01336 
01337 uint8_t  mle_service_security_default_key_id_get(int8_t interfaceId)
01338 {
01339     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01340     if (!sec_ptr) {
01341         return 0;
01342     }
01343 
01344     return mle_service_security_get_default_key_id(sec_ptr);
01345 }
01346 
01347 uint8_t * mle_service_security_next_key_get(int8_t interfaceId)
01348 {
01349     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01350     if (!sec_ptr) {
01351         return NULL;
01352     }
01353 
01354     return mle_service_security_get_next_key(sec_ptr);
01355 }
01356 
01357 uint8_t  mle_service_security_next_key_id_get(int8_t interfaceId)
01358 {
01359     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01360     if (!sec_ptr) {
01361         return 0;
01362     }
01363 
01364     return mle_service_security_get_next_key_id(sec_ptr);
01365 }
01366 
01367 uint8_t  mle_service_security_level_get(int8_t interfaceId)
01368 {
01369     mle_security_components_t *sec_ptr = mle_service_security_params_get(interfaceId);
01370     if (!sec_ptr) {
01371         return 0;
01372     }
01373 
01374     return sec_ptr->sec_level;
01375 }
01376 
01377 bool mle_service_security_key_trig(int8_t interfaceId, uint8_t keyId)
01378 {
01379     return mle_service_security_key_update_trig(interfaceId, mle_service_security_params_get(interfaceId), keyId);
01380 
01381 }
01382 
01383 bool mle_service_security_set_security_key(int8_t interfaceId, const uint8_t *security_key, uint8_t keyId, bool primary)
01384 {
01385     bool master_key_changed = false;
01386     master_key_changed = mle_service_security_key_set(mle_service_security_params_get(interfaceId), security_key, keyId, primary);
01387     if (master_key_changed && primary) {
01388         mle_service_reset_frame_counters(interfaceId);
01389     }
01390     return master_key_changed;
01391 }
01392 
01393 int mle_service_reject_message_build(int8_t interfaceId, uint8_t *dstIpv6, bool force_unsecure)
01394 {
01395     uint16_t buf_id = mle_service_msg_allocate(interfaceId, 32, false, MLE_COMMAND_REJECT);
01396     if (buf_id == 0) {
01397         return -1;
01398     }
01399     tr_debug("MLE Reject MSG Build");
01400 
01401     if (force_unsecure) {
01402         mle_service_msg_update_security_params(buf_id, 0, 0, 0);
01403     }
01404 
01405     //SET Destination address
01406     mle_service_set_msg_destination_address(buf_id, dstIpv6);
01407 
01408     //Set message priority
01409     mle_service_set_msg_token_bucket_priority(buf_id);
01410 
01411     mle_service_send_message(buf_id);
01412 
01413     return 0;
01414 }
01415 
01416 static uint8_t *mle_security_aux_header_write(uint8_t *ptr, const mle_security_header_t *auxHeader)
01417 {
01418     uint8_t auxBaseHeader;
01419     auxBaseHeader = auxHeader->securityLevel;
01420     auxBaseHeader |= (auxHeader->KeyIdMode << 3);
01421     *ptr++ = auxBaseHeader;
01422     ptr = common_write_32_bit_inverse(auxHeader->frameCounter, ptr);
01423 
01424     switch (auxHeader->KeyIdMode) {
01425         case MAC_KEY_ID_MODE_SRC8_IDX:
01426             memcpy(ptr, auxHeader->Keysource, 8);
01427             ptr += 8;
01428             *ptr++ = auxHeader->KeyIndex;
01429             break;
01430         case MAC_KEY_ID_MODE_SRC4_IDX:
01431             memcpy(ptr, auxHeader->Keysource, 4);
01432             ptr += 4;
01433             *ptr++ = auxHeader->KeyIndex;
01434             break;
01435         case MAC_KEY_ID_MODE_IDX:
01436             *ptr++ = auxHeader->KeyIndex;
01437             break;
01438         case MAC_KEY_ID_MODE_IMPLICIT:
01439         default:
01440             break;
01441     }
01442     return ptr;
01443 }
01444 
01445 static void mle_security_aux_ccm_nonce_set(uint8_t *noncePtr, uint8_t *mac64, uint32_t securityFrameCounter, uint8_t securityLevel)
01446 {
01447     memcpy(noncePtr, mac64, 8);
01448     noncePtr += 8;
01449     noncePtr = common_write_32_bit(securityFrameCounter, noncePtr);
01450     *noncePtr = securityLevel;
01451 }
01452 
01453 static uint8_t mle_security_aux_header_size(uint8_t keyIdMode)
01454 {
01455     uint8_t auxHeaderLength;
01456     if (keyIdMode == 0) {
01457         auxHeaderLength = 5; //No Key ID selected
01458     } else if (keyIdMode == 1) {
01459         auxHeaderLength = 6; //key ID without Source
01460     } else if (keyIdMode == 2) {
01461         auxHeaderLength = 10; //key ID with 32-bitSource
01462     } else {
01463         auxHeaderLength = 14; //key ID with 64-bitSource
01464     }
01465 
01466     return auxHeaderLength;
01467 }
01468 
01469 void mle_service_set_frame_counter_check(bool value)
01470 {
01471     if (mle_service) {
01472         mle_service->mle_frame_counter_check_enabled = value;
01473     }
01474 }
01475 
01476 void mle_service_set_fragmented_msg_ll_security(bool value)
01477 {
01478     if (mle_service) {
01479         mle_service->mle_frag_msg_security_enabled = value;
01480     }
01481 }
01482 
01483 int mle_service_set_msg_rf_channel(uint16_t msgId, uint8_t channel)
01484 {
01485     return mle_service_buffer_set_msg_rf_channel(msgId, channel);
01486 }
01487 
01488 int mle_service_set_msg_link_layer_security_mode(uint16_t msgId, bool use_key_id_mode_2)
01489 {
01490     return mle_service_buffer_set_msg_security_mode(msgId, use_key_id_mode_2);
01491 }
01492 
01493 void mle_service_set_accept_invalid_frame_counter(bool value)
01494 {
01495     if (mle_service) {
01496         mle_service->mle_accept_invalid_frame_counter = value;
01497     }
01498 }
01499