EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fhss_beacon_tasklet.c Source File

fhss_beacon_tasklet.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 #include "nsconfig.h"
00020 #include "common_functions.h"
00021 #include "eventOS_event.h"
00022 #include "eventOS_event_timer.h"
00023 #include "ns_trace.h"
00024 #include "fhss_api.h "
00025 #include "fhss_config.h "
00026 #include "fhss.h"
00027 #include "fhss_beacon.h"
00028 #include "fhss_statistics.h"
00029 
00030 #include <string.h> // memset
00031 
00032 #define TRACE_GROUP "fhss"
00033 
00034 static void fhss_beacon_tasklet_func(arm_event_s* event);
00035 
00036 int8_t fhss_beacon_create_tasklet(fhss_structure_t *fhss_structure)
00037 {
00038     if (fhss_structure->beacon_tasklet_id < 0) {
00039         fhss_structure->beacon_tasklet_id = eventOS_event_handler_create(fhss_beacon_tasklet_func, FHSS_TASKLET_INIT_EVENT);
00040     }
00041     return fhss_structure->beacon_tasklet_id;
00042 }
00043 
00044 int fhss_beacon_periodic_start(fhss_structure_t *fhss_structure,
00045                                 uint32_t time_to_first_beacon)
00046 {
00047     int ret_val = -1;
00048 
00049     if (fhss_structure) {
00050         fhss_beacon_periodic_stop(fhss_structure);
00051         ret_val = fhss_timeout_start(fhss_structure, time_to_first_beacon * 1000);
00052     }
00053     return ret_val;
00054 }
00055 
00056 void fhss_beacon_periodic_stop(fhss_structure_t *fhss_structure)
00057 {
00058     if (fhss_structure) {
00059         fhss_timeout_stop(fhss_structure);
00060     }
00061 }
00062 
00063 static void fhss_beacon_tasklet_func(arm_event_s* event)
00064 {
00065     fhss_structure_t *fhss_structure = (fhss_structure_t *)event->data_ptr;
00066     if (!fhss_structure) {
00067         return;
00068     }
00069     uint8_t parent_address[8];
00070     fhss_clear_active_event(fhss_structure, event->event_type);
00071     // skip the init event as there will be a timer event after
00072     if (event->event_type == FHSS_TIMER_EVENT) {
00073         // Stop network when lost number of FHSS_SYNCHRONIZATION_LOST synchronization beacons from parent in a row.
00074         if (fhss_structure->beacons_received_timer >= FHSS_SYNCHRONIZATION_LOST) {
00075             fhss_structure->callbacks.synch_lost_notification(fhss_structure->fhss_api);
00076             fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_LOST, 1);
00077             tr_err("FHSS synchronization lost");
00078         } else {
00079             uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels);
00080             uint16_t channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000;
00081 
00082             fhss_beacon_periodic_start(fhss_structure, (bc_density * channel_dwell_time) * 2);
00083             // Send synchronization request
00084             fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
00085             fhss_structure->beacons_received_timer++;
00086 #ifdef FEA_TRACE_SUPPORT
00087             if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00088                 tr_debug("Update synch, attempt: %u, %s", fhss_structure->beacons_received_timer, trace_array(parent_address, 8));
00089             } else {
00090                 tr_err("No synch parent found");
00091             }
00092 #endif /*FEA_TRACE_SUPPORT*/
00093         }
00094     }
00095     // Compare if synchronization parent has changed and request beacon if needed
00096     else if(event->event_type == FHSS_COMPARE_SYNCH_PARENT)
00097     {
00098         if (fhss_compare_with_synch_parent_address(fhss_structure, fhss_structure->synch_parent)) {
00099             fhss_structure->synch_monitor.avg_synch_fix = 0;
00100             if(fhss_structure->synch_monitor.avg_synch_fix_counter > 0) {
00101                 fhss_structure->synch_monitor.avg_synch_fix_counter = 0;
00102             }
00103             // Send synchronization request
00104             fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
00105 #ifdef FEA_TRACE_SUPPORT
00106             if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00107                 tr_debug("Synch parent changed, New: %s, Old: %s\n", trace_array(parent_address, 8), trace_array(fhss_structure->synch_parent, 8));
00108             } else {
00109                 tr_err("Synch parent changed : No parent found");
00110             }
00111 #endif /*FEA_TRACE_SUPPORT*/
00112         }
00113     }
00114     else if(event->event_type == FHSS_BROADCAST_CHANNEL)
00115     {
00116         uint16_t superframe_length = fhss_structure->synch_configuration.fhss_superframe_length;
00117         uint8_t number_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes;
00118         // Given broadcast time is channel length minus 1 superframe
00119         fhss_structure->callbacks.broadcast_notify(fhss_structure->fhss_api, (uint32_t)superframe_length * (number_of_superframes - 1));
00120     }
00121     // Update Beacon info lifetimes
00122     else if(event->event_type == FHSS_UPDATE_SYNCH_INFO_STORAGE)
00123     {
00124         fhss_update_beacon_info_lifetimes(fhss_structure, fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api));
00125     }
00126 }
00127 
00128 void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest)
00129 {
00130     fhss_synchronization_beacon_payload_s temp_payload;
00131 
00132     fhss_beacon_update_payload(fhss_structure, &temp_payload);
00133     fhss_beacon_encode_raw(dest, &temp_payload);
00134 }
00135 
00136 // this assumes that the buffer's data pointer is seeked to the beacon payload
00137 void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time) {
00138 
00139     if (fhss_structure) {
00140 
00141         if (synch_info) {
00142             fhss_synchronization_beacon_payload_s temp_payload;
00143             temp_payload.processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
00144             fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels);
00145 
00146             // use the received information
00147             fhss_sync_with_beacon(fhss_structure, &temp_payload);
00148         }
00149     }
00150 }
00151 
00152