1 /*!
2  * \file      LmHandler.h
3  *
4  * \brief     Implements the LoRaMac layer handling.
5  *            Provides the possibility to register applicative packages.
6  *
7  * \remark    Inspired by the examples provided on the en.i-cube_lrwan fork.
8  *            MCD Application Team ( STMicroelectronics International )
9  *
10  * \copyright Revised BSD License, see section \ref LICENSE.
11  *
12  * \code
13  *                ______                              _
14  *               / _____)             _              | |
15  *              ( (____  _____ ____ _| |_ _____  ____| |__
16  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
17  *               _____) ) ____| | | || |_| ____( (___| | | |
18  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
19  *              (C)2013-2018 Semtech
20  *
21  * \endcode
22  *
23  * \author    Miguel Luis ( Semtech )
24  */
25 #ifndef __LORAMAC_HANDLER_H__
26 #define __LORAMAC_HANDLER_H__
27 
28 #ifdef __cplusplus
29 extern "C"
30 {
31 #endif
32 
33 #include "LmHandlerTypes.h"
34 
35 typedef struct LmHandlerJoinParams_s
36 {
37     CommissioningParams_t *CommissioningParams;
38     int8_t Datarate;
39     LmHandlerErrorStatus_t Status;
40 }LmHandlerJoinParams_t;
41 
42 typedef struct LmHandlerTxParams_s
43 {
44     uint8_t IsMcpsConfirm;
45     LoRaMacEventInfoStatus_t Status;
46     CommissioningParams_t *CommissioningParams;
47     LmHandlerMsgTypes_t MsgType;
48     uint8_t AckReceived;
49     int8_t Datarate;
50     uint32_t UplinkCounter;
51     LmHandlerAppData_t AppData;
52     int8_t TxPower;
53     uint8_t Channel;
54 }LmHandlerTxParams_t;
55 
56 typedef struct LmHandlerRxParams_s
57 {
58     uint8_t IsMcpsIndication;
59     LoRaMacEventInfoStatus_t Status;
60     CommissioningParams_t *CommissioningParams;
61     int8_t Datarate;
62     int8_t Rssi;
63     int8_t Snr;
64     uint32_t DownlinkCounter;
65     int8_t RxSlot;
66 }LmHandlerRxParams_t;
67 
68 typedef struct LoRaMacHandlerBeaconParams_s
69 {
70     LoRaMacEventInfoStatus_t Status;
71     LmHandlerBeaconState_t State;
72     BeaconInfo_t Info;
73 }LoRaMacHandlerBeaconParams_t;
74 
75 typedef struct LmHandlerParams_s
76 {
77     /*!
78      * Region
79      */
80     LoRaMacRegion_t Region;
81     /*!
82      * Holds the ADR state
83      */
84     bool AdrEnable;
85     /*!
86      * Uplink frame type
87      */
88     LmHandlerMsgTypes_t IsTxConfirmed;
89     /*!
90      * Uplink datarate, when \ref AdrEnable is OFF
91      */
92     int8_t TxDatarate;
93     /*!
94      * Enables/Disables a public network usage
95      */
96     bool PublicNetworkEnable;
97     /*!
98      * LoRaWAN ETSI duty cycle control enable/disable
99      *
100      * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
101      */
102     bool DutyCycleEnabled;
103     /*!
104      * Application data buffer maximum size
105      */
106     uint8_t DataBufferMaxSize;
107     /*!
108      * Application data buffer pointer
109      */
110     uint8_t *DataBuffer;
111     /*!
112      * Class B ping-slot periodicity.
113      */
114     uint8_t PingSlotPeriodicity;
115 }LmHandlerParams_t;
116 
117 typedef struct LmHandlerCallbacks_s
118 {
119     /*!
120      * Get the current battery level
121      *
122      * \retval value  Battery level ( 0: very low, 254: fully charged )
123      */
124     uint8_t ( *GetBatteryLevel )( void );
125     /*!
126      * Get the current temperature
127      *
128      * \retval value  Temperature in degree Celsius
129      */
130     float ( *GetTemperature )( void );
131     /*!
132      * Returns a pseudo random seed generated using the MCU Unique ID
133      *
134      * \retval seed Generated pseudo random seed
135      */
136     uint32_t ( *GetRandomSeed )( void );
137     /*!
138      *\brief    Will be called each time a Radio IRQ is handled by the MAC
139      *          layer.
140      *
141      *\warning  Runs in a IRQ context. Should only change variables state.
142      */
143     void ( *OnMacProcess )( void );
144     /*!
145      * Notifies the upper layer that the NVM context has changed
146      *
147      * \param [IN] state Indicates if we are storing (true) or
148      *                   restoring (false) the NVM context
149      *
150      * \param [IN] size Number of data bytes which were stored or restored.
151      */
152     void ( *OnNvmDataChange )( LmHandlerNvmContextStates_t state, uint16_t size );
153     /*!
154      * Notifies the upper layer that a network parameters have been set
155      *
156      * \param [IN] params notification parameters
157      */
158     void ( *OnNetworkParametersChange )( CommissioningParams_t *params );
159     /*!
160      * Notifies the upper layer that a MCPS request has been made to the MAC layer
161      *
162      * \param   [IN] status      - Request returned status
163      * \param   [IN] mcpsRequest - Performed MCPS-Request. Refer to \ref McpsReq_t.
164      * \param   [IN] nextTxDelay - Time to wait until another TX is possible.
165      */
166     void ( *OnMacMcpsRequest )( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxDelay );
167     /*!
168      * Notifies the upper layer that a MLME request has been made to the MAC layer
169      *
170      * \param   [IN] status      - Request returned status
171      * \param   [IN] mlmeRequest - Performed MLME-Request. Refer to \ref MlmeReq_t.
172      * \param   [IN] nextTxDelay - Time to wait until another TX is possible.
173      */
174     void ( *OnMacMlmeRequest )( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxDelay );
175     /*!
176      * Notifies the upper layer that a network has been joined
177      *
178      * \param [IN] params notification parameters
179      */
180     void ( *OnJoinRequest )( LmHandlerJoinParams_t *params );
181     /*!
182      * Notifies upper layer that a frame has been transmitted
183      *
184      * \param [IN] params notification parameters
185      */
186     void ( *OnTxData )( LmHandlerTxParams_t *params );
187     /*!
188      * Notifies the upper layer that an applicative frame has been received
189      *
190      * \param [IN] appData Received applicative data
191      * \param [IN] params notification parameters
192      */
193     void ( *OnRxData )( LmHandlerAppData_t *appData, LmHandlerRxParams_t *params );
194     /*!
195      * Confirms the LoRaWAN device class change
196      *
197      * \param [IN] deviceClass New end-device class
198      */
199     void ( *OnClassChange )( DeviceClass_t deviceClass );
200     /*!
201      * Notifies the upper layer that the beacon status has changed
202      *
203      * \param [IN] params notification parameters
204      */
205     void ( *OnBeaconStatusChange )( LoRaMacHandlerBeaconParams_t *params );
206 #if( LMH_SYS_TIME_UPDATE_NEW_API == 1 )
207     /*!
208      * Notifies the upper layer that the system time has been updated.
209      *
210      * \param [in] isSynchronized Indicates if the system time is synchronized in the range +/-1 second
211      * \param [in] timeCorrection Received time correction value
212      */
213     void ( *OnSysTimeUpdate )( bool isSynchronized, int32_t timeCorrection );
214 #else
215     /*!
216      * Notifies the upper layer that the system time has been updated.
217      */
218     void ( *OnSysTimeUpdate )( void );
219 #endif
220 }LmHandlerCallbacks_t;
221 
222 /*!
223  * LoRaMac handler initialisation
224  *
225  * \param [IN] callbacks     LoRaMac handler callbacks
226  * \param [IN] handlerParams LoRaMac handler parameters
227  *
228  * \retval none
229  */
230 LmHandlerErrorStatus_t LmHandlerInit( LmHandlerCallbacks_t *callbacks,
231                                       LmHandlerParams_t *handlerParams );
232 
233 /*!
234  * Indicates if the LoRaMacHandler is busy
235  *
236  * \retval status [true] Busy, [false] free
237  */
238 bool LmHandlerIsBusy( void );
239 
240 /*!
241  * Processes the LoRaMac and Radio events.
242  * When no pendig operation asks to go in low power mode.
243  *
244  * \remark This function must be called in the main loop.
245  */
246 void LmHandlerProcess( void );
247 
248 /*!
249  * Gets current duty-cycle wait time
250  *
251  * \retval time to wait in ms
252  */
253 TimerTime_t LmHandlerGetDutyCycleWaitTime( void );
254 
255 /*!
256  * Instructs the MAC layer to send a ClassA uplink
257  *
258  * \param [IN] appData Data to be sent
259  * \param [IN] isTxConfirmed Indicates if the uplink requires an acknowledgement
260  *
261  * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been
262  *                processed else \ref LORAMAC_HANDLER_ERROR
263  */
264 LmHandlerErrorStatus_t LmHandlerSend( LmHandlerAppData_t *appData, LmHandlerMsgTypes_t isTxConfirmed );
265 
266 /*!
267  * Join a LoRa Network in classA
268  *
269  * \Note if the device is ABP, this is a pass through function
270  */
271 void LmHandlerJoin( void );
272 
273 /*!
274  * Check whether the Device is joined to the network
275  *
276  * \param [IN] none
277  *
278  * \retval status Returns \ref LORAMAC_HANDLER_SET if joined else \ref LORAMAC_HANDLER_RESET
279  */
280 LmHandlerFlagStatus_t LmHandlerJoinStatus( void );
281 
282 /*!
283  * Informs the server on the ping-slot periodicity to use
284  *
285  * \param [IN] periodicity Is equal to 2^periodicity seconds.
286  *                         Example: 2^3 = 8 seconds. The end-device will open an Rx slot every 8 seconds.
287  *
288  * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been
289  *                processed else \ref LORAMAC_HANDLER_ERROR
290  */
291 LmHandlerErrorStatus_t LmHandlerPingSlotReq( uint8_t periodicity );
292 
293 /*!
294  * Request the MAC layer to change LoRaWAN class
295  *
296  * \Note Callback \ref LmHandlerConfirmClass informs upper layer that the change has occurred
297  * \Note Only switch from class A to class B/C OR from class B/C to class A is allowed
298  *
299  * \param [IN] newClass New class to be requested
300  *
301  * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been
302  *                processed else \ref LORAMAC_HANDLER_ERROR
303  */
304 LmHandlerErrorStatus_t LmHandlerRequestClass( DeviceClass_t newClass );
305 
306 /*!
307  * Gets the current LoRaWAN class
308  *
309  * \retval currentClass Current LoRaWAN class
310  */
311 DeviceClass_t LmHandlerGetCurrentClass( void );
312 
313 /*!
314  * Gets the current datarate
315  *
316  * \retval currentDatarate Current datarate
317  */
318 int8_t LmHandlerGetCurrentDatarate( void );
319 
320 /*!
321  * Gets the current active region
322  *
323  * \retval currentRegion Current active region
324  */
325 LoRaMacRegion_t LmHandlerGetActiveRegion( void );
326 
327 /*!
328  * Set system maximum tolerated rx error in milliseconds
329  *
330  * \param [IN] maxErrorInMs Maximum tolerated error in milliseconds
331  *
332  * \retval status Returns \ref LORAMAC_HANDLER_SUCCESS if request has been
333  *                processed else \ref LORAMAC_HANDLER_ERROR
334  */
335 LmHandlerErrorStatus_t LmHandlerSetSystemMaxRxError( uint32_t maxErrorInMs );
336 
337 /*!
338  * Requests network server time update
339  *
340  * \retval status Returns \ref LORAMAC_HANDLER_SET if joined else \ref LORAMAC_HANDLER_RESET
341  */
342 LmHandlerErrorStatus_t LmHandlerDeviceTimeReq( void );
343 
344 /*
345  *=============================================================================
346  * PACKAGES HANDLING
347  *=============================================================================
348  */
349 LmHandlerErrorStatus_t LmHandlerPackageRegister( uint8_t id, void *params );
350 bool LmHandlerPackageIsInitialized( uint8_t id );
351 
352 #ifdef __cplusplus
353 }
354 #endif
355 
356 #endif // __LORAMAC_HANDLER_H__
357