Fabio Gatti / Mbed OS poc_lorawan
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002  * Copyright (c) 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 #include <stdio.h>
00018 
00019 #include "lorawan/LoRaWANInterface.h"
00020 #include "lorawan/system/lorawan_data_structures.h"
00021 #include "events/EventQueue.h"
00022 
00023 // Application helpers
00024 #include "DummySensor.h"
00025 #include "trace_helper.h"
00026 #include "lora_radio_helper.h"
00027 
00028 using namespace events;
00029 
00030 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
00031 // This example only communicates with much shorter messages (<30 bytes).
00032 // If longer messages are used, these buffers must be changed accordingly.
00033 uint8_t tx_buffer[30];
00034 uint8_t rx_buffer[30];
00035 
00036 /*
00037  * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
00038  */
00039 #define TX_TIMER                        10000
00040 
00041 /**
00042  * Maximum number of events for the event queue.
00043  * 10 is the safe number for the stack events, however, if application
00044  * also uses the queue for whatever purposes, this number should be increased.
00045  */
00046 #define MAX_NUMBER_OF_EVENTS            10
00047 
00048 
00049 // Maximum number of retries for CONFIRMED messages before giving up
00050 #define LORAWAN_CONFIRMED_MSG_RETRY_COUNTER  3 
00051 //DR_5=SF_7; DR_4=SF_8; DR_3=SF_9; DR_2=SF_10; DR_1=SF_11; DR_0=SF_12
00052 #define LORAWAN_DATA_RATE                    DR_5 
00053 // app port
00054 #define LORAWAN_APP_PORT                     15
00055 // tx message type 
00056 #define LORAWAN_TX_MSG_TYPE                  MSG_UNCONFIRMED_FLAG
00057 // number of channel 
00058 #define LORAWAN_CHANNEL_NBR                  3
00059 // timeout retry when channel is block in msec 
00060 #define LORAWAN_CHANNEL_RETRY                3000
00061 
00062 
00063 
00064 /**
00065  * Dummy pin for dummy sensor
00066  */
00067 #define PC_9                            0
00068 
00069 /**
00070  * Dummy sensor class object
00071  */
00072 DS1820  ds1820(PC_9);
00073 
00074 /**
00075 * This event queue is the global event queue for both the
00076 * application and stack. To conserve memory, the stack is designed to run
00077 * in the same thread as the application and the application is responsible for
00078 * providing an event queue to the stack that will be used for ISR deferment as
00079 * well as application information event queuing.
00080 */
00081 static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE);
00082 
00083 /**
00084  * Event handler.
00085  *
00086  * This will be passed to the LoRaWAN stack to queue events for the
00087  * application which in turn drive the application.
00088  */
00089 static void lora_event_handler(lorawan_event_t event);
00090 
00091 /**
00092  * Constructing Mbed LoRaWANInterface and passing it the radio object from lora_radio_helper.
00093  */
00094 static LoRaWANInterface lorawan(radio);
00095 
00096 /**
00097  * Application specific callbacks
00098  */
00099 static lorawan_app_callbacks_t callbacks;
00100 
00101 
00102 static void LoRa_PrintChannels() {
00103     /* print list of all channel frequencies */
00104     lorawan_channelplan_t channelPlan {};
00105     static loramac_channel_t channelbuf[10];
00106     
00107     channelPlan.channels = channelbuf;
00108     if (lorawan.get_channel_plan(channelPlan) == LORAWAN_STATUS_OK) {
00109         for (uint8_t i = 0; i < channelPlan.nb_channels; i++) {
00110             loramac_channel_t chan = channelPlan.channels[i];
00111             printf(" CHAN %d ID %d FREQ %lu RX1FREQ %lu Band %d DR min %d max %d\n",
00112                    (int) i, (int) chan.id, chan.ch_param.frequency,
00113                    chan.ch_param.rx1_frequency, (int) chan.ch_param.band,
00114                    (int) chan.ch_param.dr_range.fields.min,
00115                    (int) chan.ch_param.dr_range.fields.max);
00116         }
00117     } else {
00118         printf(" COULD NOT GET CHANNEL PLAN\n");
00119     }
00120 }
00121 
00122 /**
00123  * Entry point for application
00124  */
00125 int main(void)
00126 {
00127     static loramac_channel_t ttnChannels[] = {
00128         {0, {868100000, 0, {(DR_5 << 4) | DR_0}, 1}},
00129         {1, {868300000, 0, {(DR_5 << 4) | DR_0}, 1}},
00130         {2, {868500000, 0, {(DR_5 << 4) | DR_0}, 1}},
00131         {3, {867100000, 0, {(DR_5 << 4) | DR_0}, 0}},
00132         {4, {867300000, 0, {(DR_5 << 4) | DR_0}, 0}},
00133         {5, {867500000, 0, {(DR_5 << 4) | DR_0}, 0}},
00134         {6, {867700000, 0, {(DR_5 << 4) | DR_0}, 0}},
00135         {7, {867900000, 0, {(DR_5 << 4) | DR_0}, 0}}
00136 };
00137     lorawan_channelplan_t channelPlan {};
00138     // setup tracing
00139     setup_trace();
00140 
00141     // stores the status of a call to LoRaWAN protocol
00142     lorawan_status_t retcode;
00143     printf("---------------------------- \n");
00144 // LORAWAN: Initialize LoRaWAN stack
00145     if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
00146         printf(" LoRa initialization failed! \n");
00147         return -1;
00148     }
00149     printf(" Mbed LoRaWANStack initialized \n");
00150 
00151 // LORAWAN: prepare application callbacks
00152     callbacks.events = mbed::callback(lora_event_handler);
00153     lorawan.add_app_callbacks(&callbacks);
00154 
00155 // LORAWAN: Set number of retries in case of CONFIRMED messages
00156     if (lorawan.set_confirmed_msg_retries(LORAWAN_CONFIRMED_MSG_RETRY_COUNTER)
00157             != LORAWAN_STATUS_OK) {
00158         printf(" Set_confirmed_msg_retries failed! \n");
00159         return -1;
00160     }
00161     printf(" CONFIRMED message retries : %d \n",
00162            LORAWAN_CONFIRMED_MSG_RETRY_COUNTER);
00163  
00164  // LORAWAN: settaggio canali   
00165     channelPlan.channels = (loramac_channel_t*) ttnChannels;
00166     channelPlan.nb_channels = LORAWAN_CHANNEL_NBR;
00167     if (lorawan.set_channel_plan(channelPlan) == LORAWAN_STATUS_OK) {
00168         printf(" [+] Setting TTN channels\n");
00169     } else {
00170         printf(" [-] Failed to set TTN channels! Debug return code.\n");
00171     }
00172     LoRa_PrintChannels();
00173       
00174 // LORAWAN:  data rate
00175 //   if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
00176 //      printf("\r\n enable_adaptive_datarate failed! \r\n");
00177 //     return -1;
00178 // }
00179     
00180     // Enable adaptive data rate
00181     if (lorawan.disable_adaptive_datarate() != LORAWAN_STATUS_OK) {
00182         printf(" disable_adaptive_datarate failed! \r\n");
00183         return -1;
00184     }
00185     printf(" Adaptive data  rate (ADR) - disabled \r\n");
00186     lorawan.set_datarate(LORAWAN_DATA_RATE);
00187 
00188     retcode = lorawan.connect();
00189 
00190     if (retcode == LORAWAN_STATUS_OK ||
00191             retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
00192     } else {
00193         printf(" Connection error, code = %d \n", retcode);
00194         return -1;
00195     }
00196 
00197     printf(" Connection - In Progress ...\n");
00198 
00199     // make your event queue dispatching events forever
00200     ev_queue.dispatch_forever();
00201 
00202     return 0;
00203 }
00204 
00205 /**
00206  * Sends a message to the Network Server
00207  */
00208 static void send_message()
00209 {
00210     uint16_t packet_len;
00211     int16_t retcode;
00212     float sensor_value;
00213  
00214 
00215     if (ds1820.begin()) {
00216         ds1820.startConversion();
00217         sensor_value = ds1820.read();
00218         printf("\n -------------------------\n");
00219         printf(" Dummy Sensor Value = %3.1f \n", sensor_value);
00220         ds1820.startConversion();
00221     } else {
00222         printf(" No sensor found \n");
00223         return;
00224     }
00225  
00226     packet_len = sprintf((char *) tx_buffer, " Dummy Sensor Value is %3.1f",
00227                          sensor_value);
00228 
00229     retcode = lorawan.send(LORAWAN_APP_PORT, tx_buffer, packet_len,
00230                            LORAWAN_TX_MSG_TYPE);
00231 
00232     if (retcode < 0) {
00233         retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf(" send - WOULD BLOCK\r\n")
00234         : printf(" send() - Error code %d \n", retcode);
00235 
00236         if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
00237             //retry in 3 seconds
00238             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00239                 ev_queue.call_in(LORAWAN_CHANNEL_RETRY, send_message);
00240             }
00241         }
00242         return;
00243     }
00244     
00245     printf(" %d bytes scheduled for transmission \n", retcode);
00246     memset(tx_buffer, 0, sizeof(tx_buffer));
00247 }
00248 
00249 /**
00250  * Receive a message from the Network Server
00251  */
00252 static void receive_message()
00253 {
00254     uint8_t port;
00255     int flags;
00256     int16_t retcode = lorawan.receive(rx_buffer, sizeof(rx_buffer), port, flags);
00257 
00258     if (retcode < 0) {
00259         printf(" receive() - Error code %d \r\n", retcode);
00260         return;
00261     }
00262 
00263     printf(" RX Data on port %u (%d bytes): ", port, retcode);
00264     for (uint8_t i = 0; i < retcode; i++) {
00265         printf("%02x ", rx_buffer[i]);
00266     }
00267     printf("\n");
00268     
00269     memset(rx_buffer, 0, sizeof(rx_buffer));
00270 }
00271 
00272 /**
00273  * Event handler
00274  */
00275 static void lora_event_handler(lorawan_event_t event)
00276 {
00277     int16_t retcode;
00278     lorawan_tx_metadata additional_data; 
00279     int backoff_data;
00280     
00281     switch (event) {
00282         case CONNECTED:
00283             printf(" Connection - Successful \n");
00284             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00285                 send_message();
00286             } else {
00287                 ev_queue.call_every(TX_TIMER, send_message);
00288             }
00289 
00290             break;
00291         case DISCONNECTED:
00292             ev_queue.break_dispatch();
00293             printf(" Disconnected Successfully \n");
00294             break;
00295         case TX_DONE:
00296             printf(" Message Sent to Network Server \n");
00297             
00298             retcode = lorawan.get_tx_metadata(additional_data);
00299             switch (retcode)
00300             {
00301                 case LORAWAN_STATUS_NOT_INITIALIZED:
00302                   printf(" Lorawan stack not initialized\n");
00303                   break;
00304               
00305                 case LORAWAN_STATUS_METADATA_NOT_AVAILABLE:
00306                   printf(" Metadata not available\n");
00307                   break;
00308               
00309                 case LORAWAN_STATUS_OK :
00310                    printf(" TX Channel: %d \n",additional_data.channel);
00311                    printf(" TOA (msec): %d \n",additional_data.tx_toa);
00312                    printf(" Data rate: %u \n",additional_data.data_rate);
00313                    break;
00314             }
00315             
00316             retcode = lorawan.get_backoff_metadata(backoff_data);
00317             switch (retcode)
00318             {
00319                 case LORAWAN_STATUS_NOT_INITIALIZED:
00320                   printf(" Lorawan stack not initialized\n");
00321                   break;
00322               
00323                 case LORAWAN_STATUS_METADATA_NOT_AVAILABLE:
00324                   printf(" Backoff not available\n");
00325                   break;
00326               
00327                 case LORAWAN_STATUS_OK :
00328                    printf(" Backoff: %d \n",backoff_data);
00329                    break;
00330             }           
00331             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00332                 send_message();
00333             }
00334             break;
00335         case TX_TIMEOUT:
00336         case TX_ERROR:
00337         case TX_CRYPTO_ERROR:
00338         case TX_SCHEDULING_ERROR:
00339             printf(" Transmission Error - EventCode = %d \r\n", event);
00340             // try again
00341             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00342                 send_message();
00343             }
00344             break;
00345         case RX_DONE:
00346             printf(" Received message from Network Server \r\n");
00347             receive_message();
00348             break;
00349         case RX_TIMEOUT:
00350         case RX_ERROR:
00351             printf(" Error in reception - Code = %d \r\n", event);
00352             break;
00353         case JOIN_FAILURE:
00354             printf(" OTAA Failed - Check Keys \r\n");
00355             break;
00356         case UPLINK_REQUIRED:
00357             printf(" Uplink required by NS \r\n");
00358             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00359                 send_message();
00360             }
00361             break;
00362         default: 
00363             MBED_ASSERT(" Unknown Event");
00364     }
00365 }
00366 
00367 
00368 // EOF