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