Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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