LoRaMacFunc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-07-13 Rick the first version
  9. */
  10. #include "LoRaMacFunc.h"
  11. #include "sample.h"
  12. #include "LoRaMacConfig.h"
  13. #include "rtthread.h"
  14. #if( OVER_THE_AIR_ACTIVATION == 0 )
  15. uint8_t FNwkSIntKey[] = LORAWAN_F_NWK_S_INT_KEY;
  16. uint8_t SNwkSIntKey[] = LORAWAN_S_NWK_S_INT_KEY;
  17. uint8_t NwkSEncKey[] = LORAWAN_NWK_S_ENC_KEY;
  18. uint8_t AppSKey[] = LORAWAN_APP_S_KEY;
  19. uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
  20. #else
  21. uint8_t AppKey[] = LORAWAN_APP_KEY;
  22. uint8_t NwkKey[] = LORAWAN_NWK_KEY;
  23. uint8_t devEui[] = LORAWAN_DEVICE_EUI;
  24. uint8_t joinEui[] = LORAWAN_JOIN_EUI;
  25. #endif
  26. uint8_t AppPort = LORAWAN_APP_PORT;
  27. uint8_t AppDataSize = 1;
  28. uint8_t AppDataBuffer[LORAWAN_APP_DATA_MAX_SIZE];
  29. uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
  30. uint32_t TxDutyCycleTime;
  31. bool NextTx = true;
  32. TimerEvent_t TxNextPacketTimer;
  33. typedef enum
  34. {
  35. LORAMAC_HANDLER_UNCONFIRMED_MSG = 0,
  36. LORAMAC_HANDLER_CONFIRMED_MSG = !LORAMAC_HANDLER_UNCONFIRMED_MSG
  37. }LoRaMacHandlerMsgTypes_t;
  38. extern enum eDeviceState
  39. {
  40. DEVICE_STATE_RESTORE,
  41. DEVICE_STATE_START,
  42. DEVICE_STATE_JOIN,
  43. DEVICE_STATE_SEND,
  44. DEVICE_STATE_CYCLE,
  45. DEVICE_STATE_RXC,
  46. DEVICE_STATE_SLEEP
  47. }DeviceState;
  48. typedef struct LoRaMacHandlerAppData_s
  49. {
  50. LoRaMacHandlerMsgTypes_t MsgType;
  51. uint8_t Port;
  52. uint8_t BufferSize;
  53. uint8_t *Buffer;
  54. }LoRaMacHandlerAppData_t;
  55. LoRaMacHandlerAppData_t AppData =
  56. {
  57. .MsgType = LORAMAC_HANDLER_UNCONFIRMED_MSG,
  58. .Buffer = NULL,
  59. .BufferSize = 0,
  60. .Port = 0
  61. };
  62. const char* MacStatusStrings[] =
  63. {
  64. "OK", // LORAMAC_STATUS_OK
  65. "Busy", // LORAMAC_STATUS_BUSY
  66. "Service unknown", // LORAMAC_STATUS_SERVICE_UNKNOWN
  67. "Parameter invalid", // LORAMAC_STATUS_PARAMETER_INVALID
  68. "Frequency invalid", // LORAMAC_STATUS_FREQUENCY_INVALID
  69. "Datarate invalid", // LORAMAC_STATUS_DATARATE_INVALID
  70. "Frequency or datarate invalid", // LORAMAC_STATUS_FREQ_AND_DR_INVALID
  71. "No network joined", // LORAMAC_STATUS_NO_NETWORK_JOINED
  72. "Length error", // LORAMAC_STATUS_LENGTH_ERROR
  73. "Region not supported", // LORAMAC_STATUS_REGION_NOT_SUPPORTED
  74. "Skipped APP data", // LORAMAC_STATUS_SKIPPED_APP_DATA
  75. "Duty-cycle restricted", // LORAMAC_STATUS_DUTYCYCLE_RESTRICTED
  76. "No channel found", // LORAMAC_STATUS_NO_CHANNEL_FOUND
  77. "No free channel found", // LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND
  78. "Busy beacon reserved time", // LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME
  79. "Busy ping-slot window time", // LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME
  80. "Busy uplink collision", // LORAMAC_STATUS_BUSY_UPLINK_COLLISION
  81. "Crypto error", // LORAMAC_STATUS_CRYPTO_ERROR
  82. "FCnt handler error", // LORAMAC_STATUS_FCNT_HANDLER_ERROR
  83. "MAC command error", // LORAMAC_STATUS_MAC_COMMAD_ERROR
  84. "ClassB error", // LORAMAC_STATUS_CLASS_B_ERROR
  85. "Confirm queue error", // LORAMAC_STATUS_CONFIRM_QUEUE_ERROR
  86. "Multicast group undefined", // LORAMAC_STATUS_MC_GROUP_UNDEFINED
  87. "Unknown error", // LORAMAC_STATUS_ERROR
  88. };
  89. /*!
  90. * MAC event info status strings.
  91. */
  92. const char* EventInfoStatusStrings[] =
  93. {
  94. "OK", // LORAMAC_EVENT_INFO_STATUS_OK
  95. "Error", // LORAMAC_EVENT_INFO_STATUS_ERROR
  96. "Tx timeout", // LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT
  97. "Rx 1 timeout", // LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT
  98. "Rx 2 timeout", // LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT
  99. "Rx1 error", // LORAMAC_EVENT_INFO_STATUS_RX1_ERROR
  100. "Rx2 error", // LORAMAC_EVENT_INFO_STATUS_RX2_ERROR
  101. "Join failed", // LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL
  102. "Downlink repeated", // LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED
  103. "Tx DR payload size error", // LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR
  104. "Downlink too many frames loss", // LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS
  105. "Address fail", // LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL
  106. "MIC fail", // LORAMAC_EVENT_INFO_STATUS_MIC_FAIL
  107. "Multicast fail", // LORAMAC_EVENT_INFO_STATUS_MULTICAST_FAIL
  108. "Beacon locked", // LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED
  109. "Beacon lost", // LORAMAC_EVENT_INFO_STATUS_BEACON_LOST
  110. "Beacon not found" // LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND
  111. };
  112. void PrintHexBuffer( uint8_t *buffer, uint8_t size )
  113. {
  114. uint8_t newline = 0;
  115. for( uint8_t i = 0; i < size; i++ )
  116. {
  117. if( newline != 0 )
  118. {
  119. printf( "\r\n" );
  120. newline = 0;
  121. }
  122. printf( "%02X ", buffer[i] );
  123. if( ( ( i + 1 ) % 16 ) == 0 )
  124. {
  125. newline = 1;
  126. }
  127. }
  128. printf( "\r\n" );
  129. }
  130. void JoinNetwork( void )
  131. {
  132. LoRaMacStatus_t status;
  133. MlmeReq_t mlmeReq;
  134. mlmeReq.Type = MLME_JOIN;
  135. mlmeReq.Req.Join.Datarate = LORAWAN_DEFAULT_DATARATE;
  136. status = LoRaMacMlmeRequest( &mlmeReq );
  137. if( status == LORAMAC_STATUS_OK )
  138. {
  139. rt_kprintf( "###### ===== JOINING ==== ######\r\n" );
  140. DeviceState = DEVICE_STATE_SLEEP;
  141. }
  142. else
  143. {
  144. DeviceState = DEVICE_STATE_CYCLE;
  145. }
  146. }
  147. void PrepareTxFrame( uint8_t port )
  148. {
  149. AppDataBuffer[0] = 0x01;
  150. AppDataSize = 1;
  151. }
  152. void UserPrepareTxFrame( uint8_t port,uint8_t *buffer,uint8_t size )
  153. {
  154. memset1(AppDataBuffer,0,sizeof(AppDataBuffer));
  155. memcpy1(AppDataBuffer,buffer,sizeof(AppDataBuffer));
  156. AppDataSize = size;
  157. }
  158. bool SendFrame( void )//协议栈自用发送函数
  159. {
  160. McpsReq_t mcpsReq;
  161. LoRaMacTxInfo_t txInfo;
  162. if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
  163. {
  164. mcpsReq.Type = MCPS_UNCONFIRMED;
  165. mcpsReq.Req.Unconfirmed.fBuffer = NULL;
  166. mcpsReq.Req.Unconfirmed.fBufferSize = 0;
  167. mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  168. }
  169. else
  170. {
  171. if( IsTxConfirmed == false )
  172. {
  173. mcpsReq.Type = MCPS_UNCONFIRMED;
  174. mcpsReq.Req.Unconfirmed.fPort = AppPort;
  175. mcpsReq.Req.Unconfirmed.fBuffer = AppDataBuffer;
  176. mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
  177. mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  178. }
  179. else
  180. {
  181. mcpsReq.Type = MCPS_CONFIRMED;
  182. mcpsReq.Req.Confirmed.fPort = AppPort;
  183. mcpsReq.Req.Confirmed.fBuffer = AppDataBuffer;
  184. mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
  185. mcpsReq.Req.Confirmed.NbTrials = 1;
  186. mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  187. }
  188. }
  189. AppData.MsgType = ( mcpsReq.Type == MCPS_CONFIRMED ) ? LORAMAC_HANDLER_CONFIRMED_MSG : LORAMAC_HANDLER_UNCONFIRMED_MSG;
  190. AppData.Port = mcpsReq.Req.Unconfirmed.fPort;
  191. AppData.Buffer = mcpsReq.Req.Unconfirmed.fBuffer;
  192. AppData.BufferSize = mcpsReq.Req.Unconfirmed.fBufferSize;
  193. LoRaMacStatus_t status;
  194. status = LoRaMacMcpsRequest( &mcpsReq );
  195. if( status == LORAMAC_STATUS_OK )
  196. {
  197. return false;
  198. }
  199. return true;
  200. }
  201. bool DataSend( uint8_t *buffer, uint8_t size)//用户用发送函数(Unconfirmed Dataup)
  202. {
  203. McpsReq_t mcpsReq;
  204. LoRaMacTxInfo_t txInfo;
  205. UserPrepareTxFrame(3,buffer,size);
  206. if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
  207. {
  208. mcpsReq.Type = MCPS_UNCONFIRMED;
  209. mcpsReq.Req.Unconfirmed.fBuffer = NULL;
  210. mcpsReq.Req.Unconfirmed.fBufferSize = 0;
  211. mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  212. }
  213. else
  214. {
  215. if( IsTxConfirmed == false )
  216. {
  217. mcpsReq.Type = MCPS_UNCONFIRMED;
  218. mcpsReq.Req.Unconfirmed.fPort = AppPort;
  219. mcpsReq.Req.Unconfirmed.fBuffer = AppDataBuffer;
  220. mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
  221. mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  222. }
  223. else
  224. {
  225. mcpsReq.Type = MCPS_CONFIRMED;
  226. mcpsReq.Req.Confirmed.fPort = AppPort;
  227. mcpsReq.Req.Confirmed.fBuffer = AppDataBuffer;
  228. mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
  229. mcpsReq.Req.Confirmed.NbTrials = 3;
  230. mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  231. }
  232. }
  233. AppData.MsgType = ( mcpsReq.Type == MCPS_CONFIRMED ) ? LORAMAC_HANDLER_CONFIRMED_MSG : LORAMAC_HANDLER_UNCONFIRMED_MSG;
  234. AppData.Port = mcpsReq.Req.Unconfirmed.fPort;
  235. AppData.Buffer = mcpsReq.Req.Unconfirmed.fBuffer;
  236. AppData.BufferSize = mcpsReq.Req.Unconfirmed.fBufferSize;
  237. LoRaMacStatus_t status;
  238. status = LoRaMacMcpsRequest( &mcpsReq );
  239. if( status == LORAMAC_STATUS_OK )
  240. {
  241. return false;
  242. }
  243. return true;
  244. }
  245. bool ConfirmedDataSend( uint8_t *buffer, uint8_t size, uint8_t nbtrials)//用户用发送函数(Confirmed Dataup)
  246. {
  247. McpsReq_t mcpsReq;
  248. LoRaMacTxInfo_t txInfo;
  249. UserPrepareTxFrame(10,buffer,size);
  250. if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
  251. {
  252. mcpsReq.Type = MCPS_UNCONFIRMED;
  253. mcpsReq.Req.Unconfirmed.fBuffer = NULL;
  254. mcpsReq.Req.Unconfirmed.fBufferSize = 0;
  255. mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  256. }
  257. else
  258. {
  259. mcpsReq.Type = MCPS_CONFIRMED;
  260. mcpsReq.Req.Confirmed.fPort = AppPort;
  261. mcpsReq.Req.Confirmed.fBuffer = AppDataBuffer;
  262. mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
  263. mcpsReq.Req.Confirmed.NbTrials = nbtrials;
  264. mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
  265. }
  266. AppData.MsgType = ( mcpsReq.Type == MCPS_CONFIRMED ) ? LORAMAC_HANDLER_CONFIRMED_MSG : LORAMAC_HANDLER_UNCONFIRMED_MSG;
  267. AppData.Port = mcpsReq.Req.Unconfirmed.fPort;
  268. AppData.Buffer = mcpsReq.Req.Unconfirmed.fBuffer;
  269. AppData.BufferSize = mcpsReq.Req.Unconfirmed.fBufferSize;
  270. LoRaMacStatus_t status;
  271. status = LoRaMacMcpsRequest( &mcpsReq );
  272. if( status == LORAMAC_STATUS_OK )
  273. {
  274. return false;
  275. }
  276. return true;
  277. }
  278. void OnTxNextPacketTimerEvent( void )
  279. {
  280. MibRequestConfirm_t mibReq;
  281. LoRaMacStatus_t status;
  282. TimerStop( &TxNextPacketTimer );
  283. mibReq.Type = MIB_NETWORK_ACTIVATION;
  284. status = LoRaMacMibGetRequestConfirm( &mibReq );
  285. if( status == LORAMAC_STATUS_OK )
  286. {
  287. if( mibReq.Param.NetworkActivation == ACTIVATION_TYPE_NONE )
  288. {
  289. JoinNetwork( );
  290. }
  291. else
  292. {
  293. DeviceState = DEVICE_STATE_SEND;
  294. NextTx = true;
  295. }
  296. }
  297. }
  298. void McpsConfirm( McpsConfirm_t *mcpsConfirm )
  299. {
  300. printf( "\r\n###### ===== MCPS-Confirm ==== ######\r\n" );
  301. printf( "STATUS : %s\r\n", EventInfoStatusStrings[mcpsConfirm->Status] );
  302. if( mcpsConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK )
  303. {
  304. }
  305. else
  306. {
  307. switch( mcpsConfirm->McpsRequest )
  308. {
  309. case MCPS_UNCONFIRMED:
  310. {
  311. break;
  312. }
  313. case MCPS_CONFIRMED:
  314. {
  315. break;
  316. }
  317. case MCPS_PROPRIETARY:
  318. {
  319. break;
  320. }
  321. default:
  322. break;
  323. }
  324. }
  325. MibRequestConfirm_t mibGet;
  326. MibRequestConfirm_t mibReq;
  327. mibReq.Type = MIB_DEVICE_CLASS;
  328. LoRaMacMibGetRequestConfirm( &mibReq );
  329. SendDoneCallback(AppDataBuffer,AppData.BufferSize);
  330. printf( "\r\n###### ===== UPLINK FRAME %lu ==== ######\r\n", mcpsConfirm->UpLinkCounter );
  331. printf( "\r\n" );
  332. printf( "CLASS : %c\r\n", "ABC"[mibReq.Param.Class] );
  333. printf( "\r\n" );
  334. printf( "TX PORT : %d\r\n", AppData.Port );
  335. if( AppData.BufferSize != 0 )
  336. {
  337. printf( "TX TYPE : " );
  338. if( AppData.MsgType == LORAMAC_HANDLER_CONFIRMED_MSG )
  339. {
  340. printf( "CONFIRMED - %s\r\n", ( mcpsConfirm->AckReceived != 0 ) ? "ACK" : "NACK" );
  341. }
  342. else
  343. {
  344. printf( "UNCONFIRMED\r\n" );
  345. }
  346. printf( "Send Buffer : " );
  347. PrintHexBuffer( AppData.Buffer, AppData.BufferSize );
  348. }
  349. printf( "DATA RATE : DR_%d\r\n", mcpsConfirm->Datarate );
  350. mibGet.Type = MIB_CHANNELS;
  351. if( LoRaMacMibGetRequestConfirm( &mibGet ) == LORAMAC_STATUS_OK )
  352. {
  353. printf( "U/L FREQ : %lu\r\n", mibGet.Param.ChannelList[mcpsConfirm->Channel].Frequency );
  354. }
  355. printf( "TX POWER : %d\r\n", mcpsConfirm->TxPower );
  356. mibGet.Type = MIB_CHANNELS_MASK;
  357. if( LoRaMacMibGetRequestConfirm( &mibGet ) == LORAMAC_STATUS_OK )
  358. {
  359. printf("CHANNEL MASK: ");
  360. #ifdef LORAWAN_DRIVER_REGION_EU433
  361. for( uint8_t i = 0; i < 1; i++)
  362. #else
  363. for( uint8_t i = 0; i < 5; i++)
  364. #endif
  365. {
  366. printf("%04X ", mibGet.Param.ChannelsMask[i] );
  367. }
  368. printf("\r\n");
  369. }
  370. printf( "\r\n" );
  371. }
  372. /*!
  373. * \brief MCPS-Indication event function
  374. *
  375. * \param [IN] mcpsIndication - Pointer to the indication structure,
  376. * containing indication attributes.
  377. */
  378. void McpsIndication( McpsIndication_t *mcpsIndication )
  379. {
  380. printf( "\r\n###### ===== MCPS-Indication ==== ######\r\n" );
  381. printf( "STATUS : %s\r\n", EventInfoStatusStrings[mcpsIndication->Status] );
  382. if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
  383. {
  384. return;
  385. }
  386. switch( mcpsIndication->McpsIndication )
  387. {
  388. case MCPS_UNCONFIRMED:
  389. {
  390. break;
  391. }
  392. case MCPS_CONFIRMED:
  393. {
  394. break;
  395. }
  396. case MCPS_PROPRIETARY:
  397. {
  398. break;
  399. }
  400. case MCPS_MULTICAST:
  401. {
  402. break;
  403. }
  404. default:
  405. break;
  406. }
  407. if( mcpsIndication->FramePending == true )
  408. {
  409. OnTxNextPacketTimerEvent( );
  410. }
  411. if( mcpsIndication->RxData == true )
  412. {
  413. ReceiveDoneCallback(mcpsIndication->Buffer,mcpsIndication->BufferSize);
  414. }
  415. const char *slotStrings[] = { "1", "2", "C", "C Multicast", "B Ping-Slot", "B Multicast Ping-Slot" };
  416. printf( "\r\n###### ===== DOWNLINK FRAME %lu ==== ######\r\n", mcpsIndication->DownLinkCounter );
  417. printf( "RX WINDOW : %s\r\n", slotStrings[mcpsIndication->RxSlot] );
  418. printf( "RX PORT : %d\r\n", mcpsIndication->Port );
  419. if( mcpsIndication->BufferSize != 0 )
  420. {
  421. printf( "RX DATA : \r\n" );
  422. PrintHexBuffer( mcpsIndication->Buffer, mcpsIndication->BufferSize );
  423. }
  424. printf( "\r\n" );
  425. printf( "DATA RATE : DR_%d\r\n", mcpsIndication->RxDatarate );
  426. printf( "RX RSSI : %d\r\n", mcpsIndication->Rssi );
  427. printf( "RX SNR : %d\r\n", mcpsIndication->Snr );
  428. printf( "\r\n" );
  429. }
  430. void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
  431. {
  432. printf( "\r\n###### ===== MLME-Confirm ==== ######\r\n" );
  433. printf( "STATUS : %s\r\n", EventInfoStatusStrings[mlmeConfirm->Status] );
  434. if( mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK )
  435. {
  436. }
  437. switch( mlmeConfirm->MlmeRequest )
  438. {
  439. case MLME_JOIN:
  440. {
  441. if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
  442. {
  443. MibRequestConfirm_t mibGet;
  444. printf( "###### ===== JOINED ==== ######\r\n" );
  445. printf( "\r\nOTAA\r\n\r\n" );
  446. mibGet.Type = MIB_DEV_ADDR;
  447. LoRaMacMibGetRequestConfirm( &mibGet );
  448. printf( "DevAddr : %08lX\r\n", mibGet.Param.DevAddr );
  449. mibGet.Type = MIB_CHANNELS_DATARATE;
  450. LoRaMacMibGetRequestConfirm( &mibGet );
  451. printf( "DATA RATE : DR_%d\r\n", mibGet.Param.ChannelsDatarate );
  452. printf( "\r\nWatting for Link Check\r\n" );
  453. DeviceState = DEVICE_STATE_SEND;
  454. }
  455. else
  456. {
  457. JoinNetwork( );
  458. }
  459. break;
  460. }
  461. case MLME_LINK_CHECK:
  462. {
  463. if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
  464. {
  465. }
  466. break;
  467. }
  468. default:
  469. break;
  470. }
  471. }
  472. /*!
  473. * \brief MLME-Indication event function
  474. *
  475. * \param [IN] mlmeIndication - Pointer to the indication structure.
  476. */
  477. void MlmeIndication( MlmeIndication_t *mlmeIndication )
  478. {
  479. if( mlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED )
  480. {
  481. printf( "\r\n###### ===== MLME-Indication ==== ######\r\n" );
  482. printf( "STATUS : %s\r\n", EventInfoStatusStrings[mlmeIndication->Status] );
  483. }
  484. if( mlmeIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
  485. {
  486. }
  487. switch( mlmeIndication->MlmeIndication )
  488. {
  489. case MLME_SCHEDULE_UPLINK:
  490. {
  491. OnTxNextPacketTimerEvent( );
  492. break;
  493. }
  494. default:
  495. break;
  496. }
  497. }
  498. void OnMacProcessNotify(void)
  499. {
  500. }