Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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     uint8_t parent_address[8];
00072     fhss_clear_active_event(fhss_structure, event->event_type);
00073     // skip the init event as there will be a timer event after
00074     if (event->event_type == FHSS_TIMER_EVENT) {
00075         // Stop network when lost number of FHSS_SYNCHRONIZATION_LOST synchronization beacons from parent in a row.
00076         if (fhss_structure->beacons_received_timer >= FHSS_SYNCHRONIZATION_LOST) {
00077             fhss_structure->callbacks.synch_lost_notification(fhss_structure->fhss_api);
00078             fhss_stats_update(fhss_structure, STATS_FHSS_SYNCH_LOST, 1);
00079             tr_err("FHSS synchronization lost");
00080         } else {
00081             uint16_t bc_density = (fhss_structure->number_of_channels / fhss_structure->synch_configuration.fhss_number_of_bc_channels);
00082             uint16_t channel_dwell_time = ((uint32_t)fhss_structure->synch_configuration.fhss_superframe_length * fhss_structure->synch_configuration.fhss_number_of_superframes) / 1000;
00083 
00084             fhss_beacon_periodic_start(fhss_structure, (bc_density * channel_dwell_time) * 2);
00085             // Send synchronization request
00086             fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
00087             fhss_structure->beacons_received_timer++;
00088 #ifdef FEA_TRACE_SUPPORT
00089             if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00090                 tr_debug("Update synch, attempt: %u, %s", fhss_structure->beacons_received_timer, trace_array(parent_address, 8));
00091             } else {
00092                 tr_err("No synch parent found");
00093             }
00094 #endif /*FEA_TRACE_SUPPORT*/
00095         }
00096     }
00097     // Compare if synchronization parent has changed and request beacon if needed
00098     else if(event->event_type == FHSS_COMPARE_SYNCH_PARENT)
00099     {
00100         if (fhss_compare_with_synch_parent_address(fhss_structure, fhss_structure->synch_parent)) {
00101             fhss_structure->synch_monitor.avg_synch_fix = 0;
00102             if(fhss_structure->synch_monitor.avg_synch_fix_counter > 0) {
00103                 fhss_structure->synch_monitor.avg_synch_fix_counter = 0;
00104             }
00105             // Send synchronization request
00106             fhss_structure->callbacks.send_fhss_frame(fhss_structure->fhss_api, FHSS_SYNCH_REQUEST_FRAME);
00107 #ifdef FEA_TRACE_SUPPORT
00108             if (!fhss_get_parent_address(fhss_structure, parent_address)) {
00109                 tr_debug("Synch parent changed, New: %s, Old: %s\n", trace_array(parent_address, 8), trace_array(fhss_structure->synch_parent, 8));
00110             } else {
00111                 tr_err("Synch parent changed : No parent found");
00112             }
00113 #endif /*FEA_TRACE_SUPPORT*/
00114         }
00115     }
00116     else if(event->event_type == FHSS_BROADCAST_CHANNEL)
00117     {
00118         uint16_t superframe_length = fhss_structure->synch_configuration.fhss_superframe_length;
00119         uint8_t number_of_superframes = fhss_structure->synch_configuration.fhss_number_of_superframes;
00120         // Given broadcast time is channel length minus 1 superframe
00121         fhss_structure->callbacks.broadcast_notify(fhss_structure->fhss_api, (uint32_t)superframe_length * (number_of_superframes - 1));
00122     }
00123     // Update Beacon info lifetimes
00124     else if(event->event_type == FHSS_UPDATE_SYNCH_INFO_STORAGE)
00125     {
00126         fhss_update_beacon_info_lifetimes(fhss_structure, fhss_read_timestamp_cb(fhss_structure->fhss_api));
00127     }
00128 }
00129 
00130 void fhss_beacon_build(fhss_structure_t *fhss_structure, uint8_t* dest)
00131 {
00132     fhss_synchronization_beacon_payload_s temp_payload;
00133     platform_enter_critical();
00134     fhss_beacon_update_payload(fhss_structure, &temp_payload);
00135     platform_exit_critical();
00136     fhss_beacon_encode_raw(dest, &temp_payload);
00137 }
00138 
00139 // this assumes that the buffer's data pointer is seeked to the beacon payload
00140 void fhss_beacon_received(fhss_structure_t *fhss_structure, const uint8_t *synch_info, const uint32_t elapsed_time) {
00141 
00142     if (fhss_structure) {
00143 
00144         if (synch_info) {
00145             fhss_synchronization_beacon_payload_s temp_payload;
00146             temp_payload.processing_delay = fhss_structure->fhss_configuration.fhss_tuning_parameters.rx_processing_delay;
00147             fhss_beacon_decode(&temp_payload, synch_info, elapsed_time, fhss_structure->number_of_channels);
00148 
00149             // use the received information
00150             fhss_sync_with_beacon(fhss_structure, &temp_payload);
00151         }
00152     }
00153 }
00154 
00155