Denislam Valeev / Mbed OS Nucleo_rtos_basic
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMacMcps.cpp Source File

LoRaMacMcps.cpp

00001 /**
00002  / _____)             _              | |
00003 ( (____  _____ ____ _| |_ _____  ____| |__
00004  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
00005  _____) ) ____| | | || |_| ____( (___| | | |
00006 (______/|_____)_|_|_| \__)_____)\____)_| |_|
00007     (C)2013 Semtech
00008  ___ _____ _   ___ _  _____ ___  ___  ___ ___
00009 / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
00010 \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
00012 embedded.connectivity.solutions===============
00013 
00014 Description: LoRaWAN stack layer that controls both MAC and PHY underneath
00015 
00016 License: Revised BSD License, see LICENSE.TXT file include in the project
00017 
00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
00019 
00020 
00021 Copyright (c) 2017, Arm Limited and affiliates.
00022 
00023 SPDX-License-Identifier: BSD-3-Clause
00024 */
00025 
00026 #include "LoRaMac.h"
00027 #include "lorastack/mac/LoRaMacMcps.h"
00028 
00029 LoRaMacMcps::LoRaMacMcps()
00030 : _lora_mac(NULL), _lora_phy(NULL)
00031 {
00032 }
00033 
00034 LoRaMacMcps::~LoRaMacMcps()
00035 {
00036 }
00037 
00038 void LoRaMacMcps::activate_mcps_subsystem(LoRaMac *mac, LoRaPHY *phy)
00039 {
00040     _lora_mac = mac;
00041     _lora_phy = phy;
00042 }
00043 
00044 lorawan_status_t LoRaMacMcps::set_request(loramac_mcps_req_t  *mcpsRequest,
00045                                           loramac_protocol_params *params)
00046 {
00047 
00048     if (mcpsRequest == NULL || _lora_phy == NULL || _lora_mac == NULL) {
00049         return LORAWAN_STATUS_PARAMETER_INVALID;
00050     }
00051 
00052     get_phy_params_t get_phy;
00053     phy_param_t  phyParam;
00054     lorawan_status_t status = LORAWAN_STATUS_SERVICE_UNKNOWN;
00055     loramac_mhdr_t  machdr;
00056     verification_params_t verify;
00057     uint8_t fport = 0;
00058     void *fbuffer;
00059     uint16_t fbuffer_size;
00060     int8_t datarate = DR_0;
00061     bool ready_to_send = false;
00062 
00063     machdr.value  = 0;
00064 
00065     // Before performing any MCPS request, clear the confirmation structure
00066     memset((uint8_t*) &confirmation, 0, sizeof(confirmation));
00067 
00068     confirmation.status = LORAMAC_EVENT_INFO_STATUS_ERROR ;
00069 
00070     // ack_timeout_retry_counter must be reset every time a new request (unconfirmed or confirmed) is performed.
00071     params->ack_timeout_retry_counter = 1;
00072 
00073     switch (mcpsRequest->type ) {
00074         case MCPS_UNCONFIRMED : {
00075             ready_to_send = true;
00076             params->max_ack_timeout_retries = 1;
00077 
00078             machdr.bits.mtype  = FRAME_TYPE_DATA_UNCONFIRMED_UP ;
00079             fport = mcpsRequest->req.unconfirmed .fport ;
00080             fbuffer = mcpsRequest->f_buffer;
00081             fbuffer_size = mcpsRequest->f_buffer_size;
00082             datarate = mcpsRequest->req.unconfirmed .data_rate ;
00083             break;
00084         }
00085         case MCPS_CONFIRMED : {
00086             ready_to_send = true;
00087             params->max_ack_timeout_retries = mcpsRequest->req.confirmed .nb_trials ;
00088 
00089             machdr.bits.mtype  = FRAME_TYPE_DATA_CONFIRMED_UP ;
00090             fport = mcpsRequest->req.confirmed .fport ;
00091             fbuffer = mcpsRequest->f_buffer;
00092             fbuffer_size = mcpsRequest->f_buffer_size;
00093             datarate = mcpsRequest->req.confirmed .data_rate ;
00094             break;
00095         }
00096         case MCPS_PROPRIETARY : {
00097             ready_to_send = true;
00098             params->max_ack_timeout_retries = 1;
00099 
00100             machdr.bits.mtype  = FRAME_TYPE_PROPRIETARY ;
00101             fbuffer = mcpsRequest->f_buffer;
00102             fbuffer_size = mcpsRequest->f_buffer_size;
00103             datarate = mcpsRequest->req.proprietary .data_rate ;
00104             break;
00105         }
00106         default:
00107             break;
00108     }
00109 
00110     // Filter fPorts
00111     // TODO: Does not work with PROPRIETARY messages
00112     //    if( IsFPortAllowed( fPort ) == false )
00113     //    {
00114     //        return LORAWAN_STATUS_PARAMETER_INVALID;
00115     //    }
00116 
00117     // Get the minimum possible datarate
00118     get_phy.attribute = PHY_MIN_TX_DR ;
00119     phyParam = _lora_phy->get_phy_params(&get_phy);
00120 
00121     // Apply the minimum possible datarate.
00122     // Some regions have limitations for the minimum datarate.
00123     datarate = MAX(datarate, (int8_t)phyParam.value );
00124 
00125     if (ready_to_send == true) {
00126         if (params->sys_params.adr_on == false) {
00127             verify.datarate = datarate;
00128 
00129             if (_lora_phy->verify(&verify, PHY_TX_DR ) == true) {
00130                 params->sys_params.channel_data_rate = verify.datarate;
00131             } else {
00132                 return LORAWAN_STATUS_PARAMETER_INVALID;
00133             }
00134         }
00135 
00136         status = _lora_mac->send(&machdr, fport, fbuffer, fbuffer_size);
00137         if (status == LORAWAN_STATUS_OK) {
00138             confirmation.req_type = mcpsRequest->type ;
00139             params->flags.bits.mcps_req = 1;
00140         } else {
00141             params->is_node_ack_requested = false;
00142         }
00143     }
00144 
00145     return status;
00146 }