1 /*!
2 * \file LmHandlerMsgDisplay.h
3 *
4 * \brief Common set of functions to display default messages from
5 * LoRaMacHandler.
6 *
7 * \copyright Revised BSD License, see section \ref LICENSE.
8 *
9 * \code
10 * ______ _
11 * / _____) _ | |
12 * ( (____ _____ ____ _| |_ _____ ____| |__
13 * \____ \| ___ | (_ _) ___ |/ ___) _ \
14 * _____) ) ____| | | || |_| ____( (___| | | |
15 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
16 * (C)2013-2019 Semtech
17 *
18 * \endcode
19 *
20 * \author Miguel Luis ( Semtech )
21 */
22 #include <stdlib.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include "utilities.h"
27 #include "timer.h"
28
29 #include "LmHandlerMsgDisplay.h"
30
31 /*!
32 * MAC status strings
33 */
34 const char* MacStatusStrings[] =
35 {
36 "OK", // LORAMAC_STATUS_OK
37 "Busy", // LORAMAC_STATUS_BUSY
38 "Service unknown", // LORAMAC_STATUS_SERVICE_UNKNOWN
39 "Parameter invalid", // LORAMAC_STATUS_PARAMETER_INVALID
40 "Frequency invalid", // LORAMAC_STATUS_FREQUENCY_INVALID
41 "Datarate invalid", // LORAMAC_STATUS_DATARATE_INVALID
42 "Frequency or datarate invalid", // LORAMAC_STATUS_FREQ_AND_DR_INVALID
43 "No network joined", // LORAMAC_STATUS_NO_NETWORK_JOINED
44 "Length error", // LORAMAC_STATUS_LENGTH_ERROR
45 "Region not supported", // LORAMAC_STATUS_REGION_NOT_SUPPORTED
46 "Skipped APP data", // LORAMAC_STATUS_SKIPPED_APP_DATA
47 "Duty-cycle restricted", // LORAMAC_STATUS_DUTYCYCLE_RESTRICTED
48 "No channel found", // LORAMAC_STATUS_NO_CHANNEL_FOUND
49 "No free channel found", // LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND
50 "Busy beacon reserved time", // LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME
51 "Busy ping-slot window time", // LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME
52 "Busy uplink collision", // LORAMAC_STATUS_BUSY_UPLINK_COLLISION
53 "Crypto error", // LORAMAC_STATUS_CRYPTO_ERROR
54 "FCnt handler error", // LORAMAC_STATUS_FCNT_HANDLER_ERROR
55 "MAC command error", // LORAMAC_STATUS_MAC_COMMAD_ERROR
56 "ClassB error", // LORAMAC_STATUS_CLASS_B_ERROR
57 "Confirm queue error", // LORAMAC_STATUS_CONFIRM_QUEUE_ERROR
58 "Multicast group undefined", // LORAMAC_STATUS_MC_GROUP_UNDEFINED
59 "Unknown error", // LORAMAC_STATUS_ERROR
60 };
61
62 /*!
63 * MAC event info status strings.
64 */
65 const char* EventInfoStatusStrings[] =
66 {
67 "OK", // LORAMAC_EVENT_INFO_STATUS_OK
68 "Error", // LORAMAC_EVENT_INFO_STATUS_ERROR
69 "Tx timeout", // LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT
70 "Rx 1 timeout", // LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT
71 "Rx 2 timeout", // LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT
72 "Rx1 error", // LORAMAC_EVENT_INFO_STATUS_RX1_ERROR
73 "Rx2 error", // LORAMAC_EVENT_INFO_STATUS_RX2_ERROR
74 "Join failed", // LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL
75 "Downlink repeated", // LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED
76 "Tx DR payload size error", // LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR
77 "Address fail", // LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL
78 "MIC fail", // LORAMAC_EVENT_INFO_STATUS_MIC_FAIL
79 "Multicast fail", // LORAMAC_EVENT_INFO_STATUS_MULTICAST_FAIL
80 "Beacon locked", // LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED
81 "Beacon lost", // LORAMAC_EVENT_INFO_STATUS_BEACON_LOST
82 "Beacon not found" // LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND
83 };
84
85 /*!
86 * Prints the provided buffer in HEX
87 *
88 * \param buffer Buffer to be printed
89 * \param size Buffer size to be printed
90 */
PrintHexBuffer(uint8_t * buffer,uint8_t size)91 void PrintHexBuffer( uint8_t *buffer, uint8_t size )
92 {
93 uint8_t newline = 0;
94
95 for( uint8_t i = 0; i < size; i++ )
96 {
97 if( newline != 0 )
98 {
99 printf( "\n" );
100 newline = 0;
101 }
102
103 printf( "%02X ", buffer[i] );
104
105 if( ( ( i + 1 ) % 16 ) == 0 )
106 {
107 newline = 1;
108 }
109 }
110 printf( "\n" );
111 }
112
DisplayNvmDataChange(LmHandlerNvmContextStates_t state,uint16_t size)113 void DisplayNvmDataChange( LmHandlerNvmContextStates_t state, uint16_t size )
114 {
115 if( state == LORAMAC_HANDLER_NVM_STORE )
116 {
117 printf( "\n###### ============ CTXS STORED ============ ######\n" );
118
119 }
120 else
121 {
122 printf( "\n###### =========== CTXS RESTORED =========== ######\n" );
123 }
124 printf( "Size : %i\n\n", size );
125 }
126
DisplayNetworkParametersUpdate(CommissioningParams_t * commissioningParams)127 void DisplayNetworkParametersUpdate( CommissioningParams_t *commissioningParams )
128 {
129 printf( "DevEui : %02X", commissioningParams->DevEui[0] );
130 for( int i = 1; i < 8; i++ )
131 {
132 printf( "-%02X", commissioningParams->DevEui[i] );
133 }
134 printf( "\n" );
135 printf( "JoinEui : %02X", commissioningParams->JoinEui[0] );
136 for( int i = 1; i < 8; i++ )
137 {
138 printf( "-%02X", commissioningParams->JoinEui[i] );
139 }
140 printf( "\n" );
141 printf( "Pin : %02X", commissioningParams->SePin[0] );
142 for( int i = 1; i < 4; i++ )
143 {
144 printf( "-%02X", commissioningParams->SePin[i] );
145 }
146 printf( "\n\n" );
147 }
148
DisplayMacMcpsRequestUpdate(LoRaMacStatus_t status,McpsReq_t * mcpsReq,TimerTime_t nextTxIn)149 void DisplayMacMcpsRequestUpdate( LoRaMacStatus_t status, McpsReq_t *mcpsReq, TimerTime_t nextTxIn )
150 {
151 switch( mcpsReq->Type )
152 {
153 case MCPS_CONFIRMED:
154 {
155 printf( "\n###### =========== MCPS-Request ============ ######\n" );
156 printf( "###### MCPS_CONFIRMED ######\n");
157 printf( "###### ===================================== ######\n");
158 break;
159 }
160 case MCPS_UNCONFIRMED:
161 {
162 printf( "\n###### =========== MCPS-Request ============ ######\n" );
163 printf( "###### MCPS_UNCONFIRMED ######\n");
164 printf( "###### ===================================== ######\n");
165 break;
166 }
167 case MCPS_PROPRIETARY:
168 {
169 printf( "\n###### =========== MCPS-Request ============ ######\n" );
170 printf( "###### MCPS_PROPRIETARY ######\n");
171 printf( "###### ===================================== ######\n");
172 break;
173 }
174 default:
175 {
176 printf( "\n###### =========== MCPS-Request ============ ######\n" );
177 printf( "###### MCPS_ERROR ######\n");
178 printf( "###### ===================================== ######\n");
179 break;
180 }
181 }
182 printf( "STATUS : %s\n", MacStatusStrings[status] );
183 if( status == LORAMAC_STATUS_DUTYCYCLE_RESTRICTED )
184 {
185 printf( "Next Tx in : %lu [ms]\n", nextTxIn );
186 }
187 }
188
DisplayMacMlmeRequestUpdate(LoRaMacStatus_t status,MlmeReq_t * mlmeReq,TimerTime_t nextTxIn)189 void DisplayMacMlmeRequestUpdate( LoRaMacStatus_t status, MlmeReq_t *mlmeReq, TimerTime_t nextTxIn )
190 {
191 switch( mlmeReq->Type )
192 {
193 case MLME_JOIN:
194 {
195 printf( "\n###### =========== MLME-Request ============ ######\n" );
196 printf( "###### MLME_JOIN ######\n");
197 printf( "###### ===================================== ######\n");
198 break;
199 }
200 case MLME_LINK_CHECK:
201 {
202 printf( "\n###### =========== MLME-Request ============ ######\n" );
203 printf( "###### MLME_LINK_CHECK ######\n");
204 printf( "###### ===================================== ######\n");
205 break;
206 }
207 case MLME_DEVICE_TIME:
208 {
209 printf( "\n###### =========== MLME-Request ============ ######\n" );
210 printf( "###### MLME_DEVICE_TIME ######\n");
211 printf( "###### ===================================== ######\n");
212 break;
213 }
214 case MLME_TXCW:
215 {
216 printf( "\n###### =========== MLME-Request ============ ######\n" );
217 printf( "###### MLME_TXCW ######\n");
218 printf( "###### ===================================== ######\n");
219 break;
220 }
221 default:
222 {
223 printf( "\n###### =========== MLME-Request ============ ######\n" );
224 printf( "###### MLME_UNKNOWN ######\n");
225 printf( "###### ===================================== ######\n");
226 break;
227 }
228 }
229 printf( "STATUS : %s\n", MacStatusStrings[status] );
230 if( status == LORAMAC_STATUS_DUTYCYCLE_RESTRICTED )
231 {
232 printf( "Next Tx in : %lu [ms]\n", nextTxIn );
233 }
234 }
235
DisplayJoinRequestUpdate(LmHandlerJoinParams_t * params)236 void DisplayJoinRequestUpdate( LmHandlerJoinParams_t *params )
237 {
238 if( params->CommissioningParams->IsOtaaActivation == true )
239 {
240 if( params->Status == LORAMAC_HANDLER_SUCCESS )
241 {
242 printf( "###### =========== JOINED ============ ######\n" );
243 printf( "\nOTAA\n\n" );
244 printf( "DevAddr : %08lX\n", params->CommissioningParams->DevAddr );
245 printf( "\n\n" );
246 printf( "DATA RATE : DR_%d\n\n", params->Datarate );
247 }
248 }
249 #if ( OVER_THE_AIR_ACTIVATION == 0 )
250 else
251 {
252 printf( "###### =========== JOINED ============ ######\n" );
253 printf( "\nABP\n\n" );
254 printf( "DevAddr : %08lX\n", params->CommissioningParams->DevAddr );
255 printf( "\n\n" );
256 }
257 #endif
258 }
259
DisplayTxUpdate(LmHandlerTxParams_t * params)260 void DisplayTxUpdate( LmHandlerTxParams_t *params )
261 {
262 MibRequestConfirm_t mibGet;
263
264 if( params->IsMcpsConfirm == 0 )
265 {
266 printf( "\n###### =========== MLME-Confirm ============ ######\n" );
267 printf( "STATUS : %s\n", EventInfoStatusStrings[params->Status] );
268 return;
269 }
270
271 printf( "\n###### =========== MCPS-Confirm ============ ######\n" );
272 printf( "STATUS : %s\n", EventInfoStatusStrings[params->Status] );
273
274 printf( "\n###### ===== UPLINK FRAME %8lu ===== ######\n", params->UplinkCounter );
275 printf( "\n" );
276
277 printf( "CLASS : %c\n", "ABC"[LmHandlerGetCurrentClass( )] );
278 printf( "\n" );
279 printf( "TX PORT : %d\n", params->AppData.Port );
280
281 if( params->AppData.BufferSize != 0 )
282 {
283 printf( "TX DATA : " );
284 if( params->MsgType == LORAMAC_HANDLER_CONFIRMED_MSG )
285 {
286 printf( "CONFIRMED - %s\n", ( params->AckReceived != 0 ) ? "ACK" : "NACK" );
287 }
288 else
289 {
290 printf( "UNCONFIRMED\n" );
291 }
292 PrintHexBuffer( params->AppData.Buffer, params->AppData.BufferSize );
293 }
294
295 printf( "\n" );
296 printf( "DATA RATE : DR_%d\n", params->Datarate );
297
298 mibGet.Type = MIB_CHANNELS;
299 if( LoRaMacMibGetRequestConfirm( &mibGet ) == LORAMAC_STATUS_OK )
300 {
301 printf( "U/L FREQ : %lu\n", mibGet.Param.ChannelList[params->Channel].Frequency );
302 }
303
304 printf( "TX POWER : %d\n", params->TxPower );
305
306 mibGet.Type = MIB_CHANNELS_MASK;
307 if( LoRaMacMibGetRequestConfirm( &mibGet ) == LORAMAC_STATUS_OK )
308 {
309 printf("CHANNEL MASK: ");
310 switch( LmHandlerGetActiveRegion( ) )
311 {
312 case LORAMAC_REGION_AS923:
313 case LORAMAC_REGION_CN779:
314 case LORAMAC_REGION_EU868:
315 case LORAMAC_REGION_IN865:
316 case LORAMAC_REGION_KR920:
317 case LORAMAC_REGION_EU433:
318 case LORAMAC_REGION_RU864:
319 {
320 printf( "%04X ", mibGet.Param.ChannelsMask[0] );
321 break;
322 }
323 case LORAMAC_REGION_AU915:
324 case LORAMAC_REGION_CN470:
325 case LORAMAC_REGION_US915:
326 {
327 for( uint8_t i = 0; i < 5; i++)
328 {
329 printf( "%04X ", mibGet.Param.ChannelsMask[i] );
330 }
331 break;
332 }
333 default:
334 {
335 printf( "\n###### ========= Unknown Region ============ ######" );
336 break;
337 }
338 }
339 printf("\n");
340 }
341
342 printf( "\n" );
343 }
344
DisplayRxUpdate(LmHandlerAppData_t * appData,LmHandlerRxParams_t * params)345 void DisplayRxUpdate( LmHandlerAppData_t *appData, LmHandlerRxParams_t *params )
346 {
347 const char *slotStrings[] = { "1", "2", "C", "C Multicast", "B Ping-Slot", "B Multicast Ping-Slot" };
348
349 if( params->IsMcpsIndication == 0 )
350 {
351 printf( "\n###### ========== MLME-Indication ========== ######\n" );
352 printf( "STATUS : %s\n", EventInfoStatusStrings[params->Status] );
353 return;
354 }
355
356 printf( "\n###### ========== MCPS-Indication ========== ######\n" );
357 printf( "STATUS : %s\n", EventInfoStatusStrings[params->Status] );
358
359 printf( "\n###### ===== DOWNLINK FRAME %8lu ===== ######\n", params->DownlinkCounter );
360
361 printf( "RX WINDOW : %s\n", slotStrings[params->RxSlot] );
362
363 printf( "RX PORT : %d\n", appData->Port );
364
365 if( appData->BufferSize != 0 )
366 {
367 printf( "RX DATA : \n" );
368 PrintHexBuffer( appData->Buffer, appData->BufferSize );
369 }
370
371 printf( "\n" );
372 printf( "DATA RATE : DR_%d\n", params->Datarate );
373 printf( "RX RSSI : %d\n", params->Rssi );
374 printf( "RX SNR : %d\n", params->Snr );
375
376 printf( "\n" );
377 }
378
DisplayBeaconUpdate(LoRaMacHandlerBeaconParams_t * params)379 void DisplayBeaconUpdate( LoRaMacHandlerBeaconParams_t *params )
380 {
381 switch( params->State )
382 {
383 default:
384 case LORAMAC_HANDLER_BEACON_ACQUIRING:
385 {
386 printf( "\n###### ========= BEACON ACQUIRING ========== ######\n" );
387 break;
388 }
389 case LORAMAC_HANDLER_BEACON_LOST:
390 {
391 printf( "\n###### ============ BEACON LOST ============ ######\n" );
392 break;
393 }
394 case LORAMAC_HANDLER_BEACON_RX:
395 {
396 printf( "\n###### ===== BEACON %8lu ==== ######\n", params->Info.Time.Seconds );
397 printf( "GW DESC : %d\n", params->Info.GwSpecific.InfoDesc );
398 printf( "GW INFO : " );
399 PrintHexBuffer( params->Info.GwSpecific.Info, 6 );
400 printf( "\n" );
401 printf( "FREQ : %lu\n", params->Info.Frequency );
402 printf( "DATA RATE : DR_%d\n", params->Info.Datarate );
403 printf( "RX RSSI : %d\n", params->Info.Rssi );
404 printf( "RX SNR : %d\n", params->Info.Snr );
405 printf( "\n" );
406 break;
407 }
408 case LORAMAC_HANDLER_BEACON_NRX:
409 {
410 printf( "\n###### ======== BEACON NOT RECEIVED ======== ######\n" );
411 break;
412 }
413 }
414 }
415
DisplayClassUpdate(DeviceClass_t deviceClass)416 void DisplayClassUpdate( DeviceClass_t deviceClass )
417 {
418 printf( "\n\n###### ===== Switch to Class %c done. ===== ######\n\n", "ABC"[deviceClass] );
419 }
420
DisplayAppInfo(const char * appName,const Version_t * appVersion,const Version_t * gitHubVersion)421 void DisplayAppInfo( const char* appName, const Version_t* appVersion, const Version_t* gitHubVersion )
422 {
423 printf( "\n###### ===================================== ######\n\n" );
424 printf( "Application name : %s\n", appName );
425 printf( "Application version: %d.%d.%d\n", appVersion->Fields.Major, appVersion->Fields.Minor, appVersion->Fields.Patch );
426 printf( "GitHub base version: %d.%d.%d\n", gitHubVersion->Fields.Major, gitHubVersion->Fields.Minor, gitHubVersion->Fields.Patch );
427 printf( "\n###### ===================================== ######\n\n" );
428 }
429