Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mle_service_buffer.c Source File

mle_service_buffer.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 /*
00019  * \file mle_service_buffer.c
00020  * \brief Add short description about this file!!!
00021  *
00022  */
00023 #include "nsconfig.h"
00024 #include <string.h>
00025 #include <ns_types.h>
00026 #include "ns_trace.h"
00027 #include "eventOS_event.h"
00028 #include "eventOS_scheduler.h"
00029 #include "eventOS_event_timer.h"
00030 #include "nsdynmemLIB.h"
00031 #include "ns_list.h"
00032 #include "Service_Libs/mle_service/mle_service_buffer.h"
00033 #include "Service_Libs/mle_service/mle_service_interface.h"
00034 
00035 #define TRACE_GROUP "msbu"
00036 
00037 typedef NS_LIST_HEAD (mle_service_msg_buf_t, link) mle_service_msg_list_t;
00038 
00039 static mle_service_msg_list_t srv_buf_list;
00040 
00041 mle_service_msg_buf_t *mle_service_buffer_find(uint16_t id)
00042 {
00043     ns_list_foreach(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00044         if (cur_ptr->msg_id == id) {
00045             return cur_ptr;
00046         }
00047     }
00048     return NULL;
00049 }
00050 
00051 mle_service_msg_buf_t * mle_service_buffer_find_for_response(uint8_t *responseData, uint16_t length)
00052 {
00053     ns_list_foreach(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00054         if (cur_ptr->challengePtr && (cur_ptr->challengeLen == length)) {
00055 
00056             if (memcmp(cur_ptr->challengePtr,responseData, length ) == 0) {
00057                 return cur_ptr;
00058             }
00059         }
00060     }
00061     return NULL;
00062 }
00063 
00064 
00065 uint8_t * mle_service_buffer_get_data_pointer(uint16_t msgId)
00066 {
00067     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00068     if (!buf) {
00069         return NULL;
00070     }
00071 
00072     return mle_msg_data_pointer(buf);
00073 }
00074 
00075 int mle_service_buffer_update_length(uint16_t msgId, uint16_t tail_length)
00076 {
00077     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00078     if (!buf) {
00079         return -1;
00080     }
00081 
00082     if (buf->size < (buf->buf_end + tail_length)) {
00083         return -2;
00084     }
00085 
00086     mle_msg_length_set(buf, tail_length);
00087     return 0;
00088 }
00089 
00090 int mle_service_buffer_update_length_by_ptr(uint16_t msgId, uint8_t *data_end_ptr)
00091 {
00092     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00093     uint16_t new_end;
00094     if (!buf) {
00095         return -1;
00096     }
00097     new_end = data_end_ptr - buf->buf;
00098     if (buf->size < new_end) {
00099         return -2;
00100     }
00101 
00102     buf->buf_end = new_end;
00103     return 0;
00104 }
00105 
00106 int mle_service_buffer_tail_get(uint16_t msgId, uint16_t tail_length)
00107 {
00108     mle_service_msg_buf_t *buffer = mle_service_buffer_find(msgId);
00109 
00110     if (!buffer) {
00111         return -2;
00112     }
00113 
00114     if (buffer->size < (buffer->buf_end + tail_length)) {
00115         //Allocate new buffer
00116         uint8_t *ptr;
00117 
00118         if (tail_length % 64) {//Allocate min 64 bytes every timemore space
00119             tail_length += (64 - (tail_length % 64));
00120         }
00121 
00122         tail_length += buffer->buf_end;
00123 
00124 
00125 
00126         uint8_t *temporary_buf = ns_dyn_mem_alloc(tail_length);
00127         if (!temporary_buf) {
00128             return -1;
00129         }
00130         //Copy old data to to new buffer and set front headroon empyty
00131         ptr = (temporary_buf);
00132         memcpy(ptr, buffer->buf, buffer->buf_end);
00133         //Update new buffer params
00134         buffer->size = tail_length;
00135         ns_dyn_mem_free(buffer->buf);
00136         buffer->buf = temporary_buf;
00137         if (buffer->challengePtr) {
00138             buffer->challengePtr = buffer->buf + 3;
00139         }
00140     }
00141     return 0;
00142 }
00143 
00144 int mle_service_buffer_set_msg_type(uint16_t msgId, uint8_t message_type)
00145 {
00146     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00147     if (!buf) {
00148         return -1;
00149     }
00150 
00151     uint8_t *ptr = buf->buf; // Message type is allways first byte
00152     *ptr = message_type;
00153     return 0;
00154 }
00155 
00156 int mle_service_buffer_set_response(uint16_t msgId)
00157 {
00158     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00159     if (!buf) {
00160         return -1;
00161     }
00162 
00163     buf->response_status = true;
00164     return 0;
00165 }
00166 
00167 bool mle_service_check_msg_response(uint16_t msgId)
00168 {
00169     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00170     if (!buf) {
00171         return false;
00172     }
00173 
00174     return buf->response_status;
00175 }
00176 
00177 int mle_service_buffer_set_timeout_cb(uint16_t msgId, mle_service_message_timeout_cb *cb)
00178 {
00179     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00180     if (!buf) {
00181         return -1;
00182     }
00183 
00184     buf->timeout_cb = cb;
00185     return 0;
00186 }
00187 
00188 uint8_t * mle_service_buffer_get_msg_destination_address_pointer(uint16_t msgId)
00189 {
00190     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00191     if (!buf) {
00192         return NULL;
00193     }
00194 
00195     return buf->dst_address;
00196 }
00197 
00198 int mle_service_buffer_set_msg_destination_address(uint16_t msgId, uint8_t *address_ptr)
00199 {
00200     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00201     if (!buf) {
00202         return -1;
00203     }
00204 
00205     memcpy(buf->dst_address, address_ptr, 16);
00206     return 0;
00207 }
00208 
00209 int mle_service_buffer_set_msg_rf_channel(uint16_t msgId, uint8_t channel)
00210 {
00211     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00212     if (!buf) {
00213         return -1;
00214     }
00215     buf->selected_rf_channel = channel;
00216     buf->selected_channel = true;
00217     return 0;
00218 }
00219 
00220 int mle_service_buffer_set_msg_security_mode(uint16_t msgId, bool key_id_mode_2)
00221 {
00222     mle_service_msg_buf_t *buf = mle_service_buffer_find(msgId);
00223     if (!buf) {
00224         return -1;
00225     }
00226 
00227     buf->enable_link_layer_security = true;
00228     buf->psk_key_id_mode_2 = key_id_mode_2;
00229     return 0;
00230 }
00231 
00232 
00233 void mle_service_buffer_clean_buffers_by_interface_id(int8_t interface_id)
00234 {
00235     ns_list_foreach_safe(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00236         if (cur_ptr->interfaceId == interface_id) {
00237             mle_service_buffer_free(cur_ptr);
00238         }
00239     }
00240 }
00241 
00242 uint16_t mle_service_buffer_count_by_interface_id(int8_t interface_id)
00243 {
00244     uint16_t result = 0;
00245     ns_list_foreach_safe(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00246         if (cur_ptr->interfaceId == interface_id) {
00247             result++;
00248         }
00249     }
00250     return result;
00251 }
00252 
00253 
00254 mle_service_msg_buf_t * mle_service_buffer_get(uint16_t data_length)
00255 {
00256     mle_service_msg_buf_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(mle_service_msg_buf_t));
00257     if (!buffer) {
00258         return NULL;
00259     }
00260 
00261     //Allocate allways excat 64 byte blocks
00262     if (data_length % 64) {
00263         data_length += (64 - (data_length % 64));
00264     }
00265 
00266 
00267     buffer->buf = ns_dyn_mem_temporary_alloc(data_length);
00268     if (!buffer->buf) {
00269         //NOTE: We cannot call mle_service_buffer_free() here. Element is not yet fully constructed.
00270         ns_dyn_mem_free(buffer);
00271         return NULL;
00272     }
00273 
00274     buffer->size = data_length;
00275     buffer->timeout_cb = NULL;
00276     buffer->response_status = false;
00277     //NO retry by default
00278     buffer->timeout_init = 0;
00279     buffer->timeout = 0;
00280     buffer->timeout_max = 0;
00281     buffer->retrans_max = 0;
00282     buffer->retrans = 0;
00283     buffer->buf_end = 1;
00284     buffer->msg_id = 0;
00285     buffer->challengePtr = NULL;
00286     buffer->challengeLen = 0;
00287     buffer->delayed_response = 0;
00288     buffer->interfaceId = -1;
00289     buffer->tokens_delay = false;
00290     buffer->tokens_priority = false;
00291     buffer->message_sent = false;
00292     buffer->selected_channel = false;
00293     buffer->selected_pan_id = false;
00294     buffer->enable_link_layer_security = false;
00295     buffer->psk_key_id_mode_2 = false;
00296     memset (&buffer->security_header, 0 , sizeof(mle_security_header_t));
00297     ns_list_add_to_start(&srv_buf_list, buffer);
00298 
00299     return buffer;
00300 }
00301 
00302 int mle_service_buffer_free(mle_service_msg_buf_t *buf)
00303 {
00304     if (!buf) {
00305         return -1;
00306     }
00307     ns_list_remove(&srv_buf_list, buf); //Remove from the list
00308     ns_dyn_mem_free(buf->buf);//Free Allocated Data
00309     ns_dyn_mem_free(buf);// Free entry
00310 
00311     return 0;
00312 }
00313 
00314 uint16_t mle_service_buffer_tokens_delay_count(void)
00315 {
00316     uint16_t buffer_count = 0;
00317 
00318     ns_list_foreach(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00319         if (cur_ptr->tokens_delay) {
00320             buffer_count++;
00321         }
00322     }
00323 
00324     return buffer_count;
00325 }
00326 
00327 /**
00328  * MLE service transaction timeout and retry handling
00329  */
00330 bool mle_service_buffer_timer_tick(uint16_t ticks, mle_service_buffer_timeout_cb *timeout_cb)
00331 {
00332     bool activeTimerNeed = false;
00333 
00334     ns_list_foreach_reverse_safe(mle_service_msg_buf_t, cur_ptr, &srv_buf_list) {
00335         activeTimerNeed = true;
00336         if (cur_ptr->timeout <= ticks) {
00337             cur_ptr->tokens_delay = false;
00338             timeout_cb(cur_ptr);
00339         } else {
00340             cur_ptr->timeout -= ticks;
00341             if (cur_ptr->tokens_delay) {
00342                 timeout_cb(cur_ptr);
00343             }
00344         }
00345     }
00346     return activeTimerNeed;
00347 }
00348 
00349