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