takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fhss_common.c Source File

fhss_common.c

00001 /*
00002  * Copyright (c) 2015-2018, 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 #include "nsconfig.h"
00018 #include "ns_types.h"
00019 #include "ns_trace.h"
00020 #include "fhss_api.h "
00021 #include "fhss_config.h "
00022 #include "fhss.h"
00023 #include "fhss_common.h"
00024 #include "fhss_ws.h"
00025 #include "fhss_statistics.h"
00026 #include "fhss_channel.h"
00027 #include "channel_list.h"
00028 #include "nsdynmemLIB.h"
00029 #include "eventOS_event.h"
00030 #include "eventOS_callback_timer.h"
00031 #include <string.h>
00032 
00033 #define TRACE_GROUP "fhssc"
00034 
00035 static fhss_structure_t *fhss_struct = NULL;
00036 
00037 static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
00038 static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id);
00039 static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
00040 static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
00041 
00042 
00043 fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer)
00044 {
00045     if (fhss_struct || !fhss_api || !fhss_timer) {
00046         return NULL;
00047     }
00048     fhss_struct = ns_dyn_mem_alloc(sizeof(fhss_structure_t));
00049     if (!fhss_struct) {
00050         return NULL;
00051     }
00052     memset(fhss_struct, 0, sizeof(fhss_structure_t));
00053     fhss_struct->fhss_api = fhss_api;
00054     fhss_struct->platform_functions = *fhss_timer;
00055     fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
00056     if (!fhss_struct->platform_functions.fhss_resolution_divider) {
00057         fhss_struct->platform_functions.fhss_resolution_divider = 1;
00058     }
00059     return fhss_struct;
00060 }
00061 
00062 int8_t fhss_free_instance(fhss_api_t *fhss_api)
00063 {
00064     if (!fhss_struct || fhss_struct->fhss_api != fhss_api) {
00065         return -1;
00066     }
00067     ns_dyn_mem_free(fhss_struct);
00068     fhss_struct = NULL;
00069     return 0;
00070 }
00071 
00072 static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
00073 {
00074     (void) slots;
00075     fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
00076     if (fhss_structure) {
00077         fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
00078     }
00079 }
00080 
00081 static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
00082 {
00083     if (timer_id < 0 || !fhss_struct) {
00084         return NULL;
00085     }
00086     if (fhss_struct->fhss_event_timer == timer_id) {
00087         return fhss_struct;
00088     }
00089     return NULL;
00090 }
00091 
00092 fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api)
00093 {
00094     if (!fhss_api || !fhss_struct) {
00095         return NULL;
00096     }
00097     if (fhss_struct->fhss_api == fhss_api) {
00098         return fhss_struct;
00099     }
00100     return NULL;
00101 }
00102 
00103 static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type)
00104 {
00105     fhss_structure->active_fhss_events |= (1 << event_type);
00106 }
00107 
00108 void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type)
00109 {
00110     fhss_structure->active_fhss_events &= ~(1 << event_type);
00111 }
00112 
00113 static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type)
00114 {
00115     if (fhss_structure->active_fhss_events & (1 << event_type)) {
00116         return true;
00117     }
00118     return false;
00119 }
00120 
00121 int8_t fhss_disable(fhss_structure_t *fhss_structure)
00122 {
00123     if (!fhss_structure) {
00124         return -1;
00125     }
00126     fhss_structure->fhss_api->synch_state_set(fhss_structure->fhss_api, FHSS_UNSYNCHRONIZED, 0);
00127     ns_dyn_mem_free(fhss_structure->bs);
00128     ns_dyn_mem_free(fhss_structure->ws);
00129     ns_dyn_mem_free(fhss_structure);
00130     fhss_struct = 0;
00131     return 0;
00132 }
00133 
00134 void fhss_start_timer(fhss_structure_t *fhss_structure, uint32_t time, void (*callback)(const fhss_api_t *fhss_api, uint16_t))
00135 {
00136     if (callback){
00137         // Don't allow starting with zero slots
00138         if (time < fhss_structure->platform_functions.fhss_resolution_divider) {
00139             time = fhss_structure->platform_functions.fhss_resolution_divider;
00140         }
00141         fhss_structure->platform_functions.fhss_timer_start(time / fhss_structure->platform_functions.fhss_resolution_divider, callback, fhss_structure->fhss_api);
00142     }
00143 }
00144 
00145 int fhss_timeout_start(fhss_structure_t *fhss_structure, uint32_t time)
00146 {
00147     if (!fhss_structure) {
00148         return -1;
00149     }
00150     fhss_structure->fhss_timeout = time;
00151     fhss_structure->fhss_timer = 0;
00152     return 0;
00153 }
00154 
00155 int fhss_timeout_stop(fhss_structure_t *fhss_structure)
00156 {
00157     if (!fhss_structure) {
00158         return -1;
00159     }
00160     fhss_structure->fhss_timeout = 0;
00161     fhss_structure->fhss_timer = 0;
00162     return 0;
00163 }
00164 
00165 int fhss_update_synch_parent_address(fhss_structure_t *fhss_structure)
00166 {
00167     uint8_t parent_address[8];
00168 
00169     if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00170         memcpy(fhss_structure->synch_parent, parent_address, 8);
00171         return 0;
00172     }
00173     return -1;
00174 }
00175 
00176 void fhss_trig_event(fhss_structure_t *fhss_structure, uint8_t event_type)
00177 {
00178     if (!fhss_structure || fhss_read_active_event(fhss_structure, event_type) == true) {
00179         return;
00180     }
00181     arm_event_s event;
00182     event.receiver = fhss_structure->beacon_tasklet_id;
00183     event.sender = 0;
00184     event.event_type = event_type;
00185     event.event_id = 0;
00186     event.data_ptr = fhss_structure;
00187     event.priority = ARM_LIB_HIGH_PRIORITY_EVENT;
00188     event.event_data = 0;
00189     if (eventOS_event_send(&event) != 0) {
00190         tr_error("Event trigger failed: eventOS_event_send() failed");
00191     } else {
00192         fhss_set_active_event(fhss_structure, event_type);
00193     }
00194 }
00195 
00196 int fhss_get_parent_address(fhss_structure_t *fhss_structure, uint8_t *p_addr)
00197 {
00198     int ret_val = -1;
00199     if (!fhss_structure || !p_addr) {
00200         return -1;
00201     }
00202 
00203     ret_val = fhss_structure->callbacks.read_coord_mac_address(fhss_structure->fhss_api, p_addr);
00204 
00205     if (ret_val) {
00206         // Use default synchronization parent when RPL parent not found
00207         memcpy(p_addr, fhss_structure->synch_parent, 8);
00208         ret_val = 0;
00209     }
00210     return ret_val;
00211 }
00212 
00213 int fhss_compare_with_synch_parent_address(fhss_structure_t *fhss_structure, const uint8_t *source_addr)
00214 {
00215     int ret_val = -1;
00216     if (!fhss_structure || !source_addr) {
00217         return ret_val;
00218     }
00219     uint8_t parent_address[8];
00220 
00221     if (fhss_is_synch_root(fhss_structure) == false) {
00222         if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00223             ret_val = memcmp(source_addr, parent_address, 8);
00224         }
00225     }
00226     return ret_val;
00227 }
00228 
00229 uint32_t fhss_read_timestamp_cb(const fhss_api_t *api)
00230 {
00231     fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
00232     if (!fhss_structure) {
00233         return 0;
00234     }
00235     return (fhss_structure->platform_functions.fhss_get_timestamp(api) * fhss_structure->platform_functions.fhss_resolution_divider);
00236 }
00237 
00238 int fhss_init_callbacks_cb(const fhss_api_t *api, fhss_callback_t *callbacks)
00239 {
00240     fhss_structure_t *fhss_structure = fhss_get_object_with_api(api);
00241     if (!fhss_structure || !callbacks) {
00242         return -1;
00243     }
00244     fhss_structure->callbacks = *callbacks;
00245     return 0;
00246 }
00247 
00248 
00249 fhss_failed_tx_t *fhss_failed_handle_find(fhss_structure_t *fhss_structure, uint8_t handle)
00250 {
00251     ns_list_foreach(fhss_failed_tx_t, cur, &fhss_structure->fhss_failed_tx_list) {
00252         if (cur->handle == handle) {
00253             return cur;
00254         }
00255     }
00256     return NULL;
00257 }
00258 
00259 int fhss_failed_handle_add(fhss_structure_t *fhss_structure, uint8_t handle, uint8_t bad_channel)
00260 {
00261     fhss_failed_tx_t *failed_tx = ns_dyn_mem_alloc(sizeof(fhss_failed_tx_t));
00262     if (!failed_tx) {
00263         return -1;
00264     }
00265     failed_tx->bad_channel = bad_channel;
00266     failed_tx->retries_done = 0;
00267     failed_tx->handle = handle;
00268     ns_list_add_to_end(&fhss_structure->fhss_failed_tx_list, failed_tx);
00269     return 0;
00270 }
00271 
00272 int fhss_failed_handle_remove(fhss_structure_t *fhss_structure, uint8_t handle)
00273 {
00274     fhss_failed_tx_t *failed_tx = fhss_failed_handle_find(fhss_structure, handle);
00275     if (!failed_tx) {
00276         return -1;
00277     }
00278     ns_list_remove(&fhss_structure->fhss_failed_tx_list, failed_tx);
00279     ns_dyn_mem_free(failed_tx); // Free entry
00280     return 0;
00281 }
00282 
00283 void fhss_failed_list_free(fhss_structure_t *fhss_structure)
00284 {
00285     for (uint16_t i = 0; i<256; i++) {
00286         fhss_failed_handle_remove(fhss_structure, i);
00287     }
00288 }
00289 
00290 uint32_t fhss_get_tx_time(fhss_structure_t *fhss_structure, uint16_t bytes_to_send, uint8_t phy_header_length, uint8_t phy_tail_length)
00291 {
00292     return ((1000000 / (fhss_structure->callbacks.read_datarate(fhss_structure->fhss_api) / 8)) * (bytes_to_send + phy_header_length + phy_tail_length));
00293 }