Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LoRaMac.cpp
00001 /** 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 Description: LoRa MAC layer implementation 00015 00016 License: Revised BSD License, see LICENSE.TXT file include in the project 00017 00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 00019 00020 Copyright (c) 2017, Arm Limited and affiliates. 00021 00022 SPDX-License-Identifier: BSD-3-Clause 00023 */ 00024 #include <stdlib.h> 00025 #include "LoRaMac.h" 00026 #include "LoRaMacCrypto.h" 00027 00028 #if defined(FEATURE_COMMON_PAL) 00029 #include "mbed_trace.h" 00030 #define TRACE_GROUP "LMAC" 00031 #else 00032 #define tr_debug(...) (void(0)) //dummies if feature common pal is not added 00033 #define tr_info(...) (void(0)) //dummies if feature common pal is not added 00034 #define tr_error(...) (void(0)) //dummies if feature common pal is not added 00035 #endif //defined(FEATURE_COMMON_PAL) 00036 00037 using namespace events; 00038 00039 /*! 00040 * Maximum length of the fOpts field 00041 */ 00042 #define LORA_MAC_COMMAND_MAX_FOPTS_LENGTH 15 00043 00044 /*! 00045 * LoRaMac duty cycle for the back-off procedure during the first hour. 00046 */ 00047 #define BACKOFF_DC_1_HOUR 100 00048 00049 /*! 00050 * LoRaMac duty cycle for the back-off procedure during the next 10 hours. 00051 */ 00052 #define BACKOFF_DC_10_HOURS 1000 00053 00054 /*! 00055 * LoRaMac duty cycle for the back-off procedure during the next 24 hours. 00056 */ 00057 #define BACKOFF_DC_24_HOURS 10000 00058 00059 /*! 00060 * Check the MAC layer state every MAC_STATE_CHECK_TIMEOUT in ms. 00061 */ 00062 #define MAC_STATE_CHECK_TIMEOUT 1000 00063 00064 /*! 00065 * The maximum number of times the MAC layer tries to get an acknowledge. 00066 */ 00067 #define MAX_ACK_RETRIES 8 00068 00069 /*! 00070 * The frame direction definition for uplink communications. 00071 */ 00072 #define UP_LINK 0 00073 00074 /*! 00075 * The frame direction definition for downlink communications. 00076 */ 00077 #define DOWN_LINK 1 00078 00079 00080 LoRaMac::LoRaMac(LoRaWANTimeHandler &lora_time) 00081 : mac_commands(*this), _lora_time(lora_time) 00082 { 00083 lora_phy = NULL; 00084 //radio_events_t RadioEvents; 00085 _params.keys.dev_eui = NULL; 00086 _params.keys.app_eui = NULL; 00087 _params.keys.app_key = NULL; 00088 00089 memset(_params.keys.nwk_skey, 0, sizeof(_params.keys.nwk_skey)); 00090 memset(_params.keys.app_skey, 0, sizeof(_params.keys.app_skey)); 00091 00092 _params.dev_nonce = 0; 00093 _params.net_id = 0; 00094 _params.dev_addr = 0; 00095 _params.buffer_pkt_len = 0; 00096 _params.payload_length = 0; 00097 _params.ul_frame_counter = 0; 00098 _params.dl_frame_counter = 0; 00099 _params.is_ul_frame_counter_fixed = false; 00100 _params.is_rx_window_enabled = true; 00101 _params.is_nwk_joined = false; 00102 _params.adr_ack_counter = 0; 00103 _params.is_node_ack_requested = false; 00104 _params.is_srv_ack_requested = false; 00105 _params.ul_nb_rep_counter = 0; 00106 _params.timers.mac_init_time = 0; 00107 _params.mac_state = LORAMAC_IDLE; 00108 _params.max_ack_timeout_retries = 1; 00109 _params.ack_timeout_retry_counter = 1; 00110 _params.is_ack_retry_timeout_expired = false; 00111 _params.timers.tx_toa = 0; 00112 00113 _params.multicast_channels = NULL; 00114 00115 _params.sys_params.adr_on = false; 00116 _params.sys_params.max_duty_cycle = 0; 00117 00118 mac_primitives = NULL; 00119 ev_queue = NULL; 00120 } 00121 00122 LoRaMac::~LoRaMac() 00123 { 00124 } 00125 00126 00127 /*************************************************************************** 00128 * ISRs - Handlers * 00129 **************************************************************************/ 00130 void LoRaMac::handle_tx_done(void) 00131 { 00132 const int ret = ev_queue->call(this, &LoRaMac::on_radio_tx_done); 00133 MBED_ASSERT(ret != 0); 00134 (void)ret; 00135 } 00136 00137 void LoRaMac::handle_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) 00138 { 00139 const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_done, payload, size, rssi, snr); 00140 MBED_ASSERT(ret != 0); 00141 (void)ret; 00142 } 00143 00144 void LoRaMac::handle_rx_error(void) 00145 { 00146 const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_error); 00147 MBED_ASSERT(ret != 0); 00148 (void)ret; 00149 } 00150 00151 void LoRaMac::handle_rx_timeout(void) 00152 { 00153 const int ret = ev_queue->call(this, &LoRaMac::on_radio_rx_timeout); 00154 MBED_ASSERT(ret != 0); 00155 (void)ret; 00156 } 00157 00158 void LoRaMac::handle_tx_timeout(void) 00159 { 00160 const int ret = ev_queue->call(this, &LoRaMac::on_radio_tx_timeout); 00161 MBED_ASSERT(ret != 0); 00162 (void)ret; 00163 } 00164 00165 void LoRaMac::handle_cad_done(bool cad) 00166 { 00167 //TODO Not implemented yet 00168 //const int ret = ev_queue->call(this, &LoRaMac::OnRadioCadDone, cad); 00169 //MBED_ASSERT(ret != 0); 00170 //(void)ret; 00171 } 00172 00173 void LoRaMac::handle_fhss_change_channel(uint8_t cur_channel) 00174 { 00175 // TODO Not implemented yet 00176 //const int ret = ev_queue->call(this, &LoRaMac::OnRadioFHSSChangeChannel, cur_channel); 00177 //MBED_ASSERT(ret != 0); 00178 //(void)ret; 00179 } 00180 00181 void LoRaMac::handle_mac_state_check_timer_event(void) 00182 { 00183 const int ret = ev_queue->call(this, &LoRaMac::on_mac_state_check_timer_event); 00184 MBED_ASSERT(ret != 0); 00185 (void)ret; 00186 } 00187 00188 void LoRaMac::handle_delayed_tx_timer_event(void) 00189 { 00190 const int ret = ev_queue->call(this, &LoRaMac::on_tx_delayed_timer_event); 00191 MBED_ASSERT(ret != 0); 00192 (void)ret; 00193 } 00194 00195 void LoRaMac::handle_ack_timeout() 00196 { 00197 const int ret = ev_queue->call(this, &LoRaMac::on_ack_timeout_timer_event); 00198 MBED_ASSERT(ret != 0); 00199 (void)ret; 00200 } 00201 00202 void LoRaMac::handle_rx1_timer_event(void) 00203 { 00204 const int ret = ev_queue->call(this, &LoRaMac::on_rx_window1_timer_event); 00205 MBED_ASSERT(ret != 0); 00206 (void)ret; 00207 } 00208 00209 void LoRaMac::handle_rx2_timer_event(void) 00210 { 00211 const int ret = ev_queue->call(this, &LoRaMac::on_rx_window2_timer_event); 00212 MBED_ASSERT(ret != 0); 00213 (void)ret; 00214 } 00215 00216 /*************************************************************************** 00217 * Radio event callbacks - delegated to Radio driver * 00218 **************************************************************************/ 00219 void LoRaMac::on_radio_tx_done( void ) 00220 { 00221 get_phy_params_t get_phy; 00222 phy_param_t phy_param; 00223 set_band_txdone_params_t tx_done_params; 00224 lorawan_time_t cur_time = _lora_time.get_current_time( ); 00225 loramac_mlme_confirm_t mlme_confirm = mlme.get_confirmation(); 00226 00227 if (_params.dev_class != CLASS_C ) { 00228 lora_phy->put_radio_to_sleep(); 00229 } else { 00230 open_continuous_rx2_window(); 00231 } 00232 00233 // Setup timers 00234 if(_params.is_rx_window_enabled == true) { 00235 _lora_time.start(_params.timers.rx_window1_timer, _params.rx_window1_delay); 00236 00237 if (_params.dev_class != CLASS_C ) { 00238 _lora_time.start(_params.timers.rx_window2_timer, _params.rx_window2_delay); 00239 } 00240 00241 if ((_params.dev_class == CLASS_C ) || 00242 (_params.is_node_ack_requested == true)) { 00243 get_phy.attribute = PHY_ACK_TIMEOUT ; 00244 phy_param = lora_phy->get_phy_params(&get_phy); 00245 _lora_time.start(_params.timers.ack_timeout_timer, 00246 _params.rx_window2_delay + phy_param.value ); 00247 } 00248 } else { 00249 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00250 mlme_confirm.status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 00251 00252 if (_params.flags.value == 0) { 00253 _params.flags.bits.mcps_req = 1; 00254 } 00255 00256 _params.flags.bits.mac_done = 1; 00257 } 00258 00259 // Verify if the last uplink was a join request 00260 if ((_params.flags.bits.mlme_req == 1) && 00261 (mlme_confirm.req_type == MLME_JOIN )) { 00262 _params.is_last_tx_join_request = true; 00263 } else { 00264 _params.is_last_tx_join_request = false; 00265 } 00266 00267 // Store last Tx channel 00268 _params.last_channel_idx = _params.channel; 00269 00270 // Update last tx done time for the current channel 00271 tx_done_params.channel = _params.channel; 00272 tx_done_params.joined = _params.is_nwk_joined; 00273 tx_done_params.last_tx_done_time = cur_time; 00274 lora_phy->set_last_tx_done(&tx_done_params); 00275 00276 // Update Aggregated last tx done time 00277 _params.timers.aggregated_last_tx_time = cur_time; 00278 00279 if (_params.is_node_ack_requested == false) { 00280 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00281 _params.ul_nb_rep_counter++; 00282 } 00283 } 00284 00285 void LoRaMac::prepare_rx_done_abort(void) 00286 { 00287 _params.mac_state |= LORAMAC_RX_ABORT; 00288 00289 if (_params.is_node_ack_requested) { 00290 handle_ack_timeout(); 00291 } 00292 00293 _params.flags.bits.mcps_ind = 1; 00294 _params.flags.bits.mac_done = 1; 00295 00296 // Trigger MAC state check event timer as soon as possible 00297 _lora_time.start(_params.timers.mac_state_check_timer, 1); 00298 } 00299 00300 void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, 00301 int8_t snr) 00302 { 00303 loramac_mhdr_t mac_hdr; 00304 loramac_frame_ctrl_t fctrl; 00305 cflist_params_t cflist; 00306 get_phy_params_t get_phy; 00307 phy_param_t phy_param; 00308 bool skip_indication = false; 00309 00310 uint8_t pkt_header_len = 0; 00311 uint32_t address = 0; 00312 uint8_t app_payload_start_index = 0; 00313 uint8_t frame_len = 0; 00314 uint32_t mic = 0; 00315 uint32_t mic_rx = 0; 00316 00317 uint16_t sequence_counter = 0; 00318 uint16_t sequence_counter_prev = 0; 00319 uint16_t sequence_counter_diff = 0; 00320 uint32_t downlink_counter = 0; 00321 00322 multicast_params_t *cur_multicast_params = NULL; 00323 uint8_t *nwk_skey = _params.keys.nwk_skey; 00324 uint8_t *app_skey = _params.keys.app_skey; 00325 00326 uint8_t multicast = 0; 00327 00328 bool is_mic_ok = false; 00329 00330 mcps.get_confirmation().ack_received = false; 00331 mcps.get_indication().rssi = rssi; 00332 mcps.get_indication().snr = snr; 00333 mcps.get_indication().rx_slot = _params.rx_slot; 00334 mcps.get_indication().port = 0; 00335 mcps.get_indication().multicast = 0; 00336 mcps.get_indication().fpending_status = 0; 00337 mcps.get_indication().buffer = NULL; 00338 mcps.get_indication().buffer_size = 0; 00339 mcps.get_indication().is_data_recvd = false; 00340 mcps.get_indication().is_ack_recvd = false; 00341 mcps.get_indication().dl_frame_counter = 0; 00342 mcps.get_indication().type = MCPS_UNCONFIRMED ; 00343 00344 lora_phy->put_radio_to_sleep(); 00345 00346 _lora_time.stop( _params.timers.rx_window2_timer ); 00347 00348 mac_hdr.value = payload[pkt_header_len++]; 00349 00350 switch (mac_hdr.bits.mtype ) { 00351 00352 case FRAME_TYPE_JOIN_ACCEPT : 00353 if (_params.is_nwk_joined == true) { 00354 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00355 prepare_rx_done_abort(); 00356 return; 00357 } 00358 00359 if (0 != decrypt_join_frame(payload + 1, size - 1, 00360 _params.keys.app_key, 00361 _params.payload + 1)) { 00362 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL ; 00363 return; 00364 } 00365 00366 _params.payload[0] = mac_hdr.value ; 00367 00368 if (0 != compute_join_frame_mic(_params.payload, size - LORAMAC_MFR_LEN, 00369 _params.keys.app_key, &mic)) { 00370 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL ; 00371 return; 00372 } 00373 00374 mic_rx |= (uint32_t) _params.payload[size - LORAMAC_MFR_LEN]; 00375 mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 1] << 8); 00376 mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 2] << 16); 00377 mic_rx |= ((uint32_t) _params.payload[size - LORAMAC_MFR_LEN + 3] << 24); 00378 00379 if (mic_rx == mic) { 00380 00381 if (0 != compute_skeys_for_join_frame(_params.keys.app_key, 00382 _params.payload + 1, 00383 _params.dev_nonce, 00384 _params.keys.nwk_skey, 00385 _params.keys.app_skey)) { 00386 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL ; 00387 return; 00388 } 00389 00390 _params.net_id = (uint32_t) _params.payload[4]; 00391 _params.net_id |= ((uint32_t) _params.payload[5] << 8); 00392 _params.net_id |= ((uint32_t) _params.payload[6] << 16); 00393 00394 _params.dev_addr = (uint32_t) _params.payload[7]; 00395 _params.dev_addr |= ((uint32_t) _params.payload[8] << 8); 00396 _params.dev_addr |= ((uint32_t) _params.payload[9] << 16); 00397 _params.dev_addr |= ((uint32_t) _params.payload[10] << 24); 00398 00399 // DLSettings 00400 _params.sys_params.rx1_dr_offset = (_params.payload[11] >> 4) & 0x07; 00401 _params.sys_params.rx2_channel.datarate = _params.payload[11] & 0x0F; 00402 00403 // RxDelay 00404 _params.sys_params.recv_delay1 = (_params.payload[12] & 0x0F); 00405 00406 if (_params.sys_params.recv_delay1 == 0) { 00407 _params.sys_params.recv_delay1 = 1; 00408 } 00409 00410 _params.sys_params.recv_delay1 *= 1000; 00411 _params.sys_params.recv_delay2 = _params.sys_params.recv_delay1 + 1000; 00412 00413 // Apply CF list 00414 cflist.payload = &_params.payload[13]; 00415 // Size of the regular payload is 12. Plus 1 byte MHDR and 4 bytes MIC 00416 cflist.size = size - 17; 00417 00418 lora_phy->apply_cf_list(&cflist); 00419 00420 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00421 _params.is_nwk_joined = true; 00422 } else { 00423 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL ; 00424 } 00425 00426 break; 00427 00428 case FRAME_TYPE_DATA_CONFIRMED_DOWN : 00429 case FRAME_TYPE_DATA_UNCONFIRMED_DOWN : 00430 { 00431 // Check if the received payload size is valid 00432 get_phy.datarate = mcps.get_indication().rx_datarate; 00433 get_phy.attribute = PHY_MAX_PAYLOAD ; 00434 00435 // Get the maximum payload length 00436 if (_params.is_repeater_supported == true) { 00437 get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER ; 00438 } 00439 00440 phy_param = lora_phy->get_phy_params(&get_phy); 00441 00442 if (MAX(0, (int16_t) ((int16_t)size - (int16_t)LORA_MAC_FRMPAYLOAD_OVERHEAD )) > (int32_t)phy_param.value ) { 00443 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00444 prepare_rx_done_abort(); 00445 return; 00446 } 00447 00448 address = payload[pkt_header_len++]; 00449 address |= ((uint32_t)payload[pkt_header_len++] << 8); 00450 address |= ((uint32_t)payload[pkt_header_len++] << 16); 00451 address |= ((uint32_t)payload[pkt_header_len++] << 24); 00452 00453 if (address != _params.dev_addr) { 00454 00455 cur_multicast_params = _params.multicast_channels; 00456 00457 while (cur_multicast_params != NULL) { 00458 00459 if (address == cur_multicast_params->address ) { 00460 multicast = 1; 00461 nwk_skey = cur_multicast_params->nwk_skey ; 00462 app_skey = cur_multicast_params->app_skey ; 00463 downlink_counter = cur_multicast_params->dl_frame_counter ; 00464 break; 00465 } 00466 00467 cur_multicast_params = cur_multicast_params->next ; 00468 } 00469 00470 if (multicast == 0) { 00471 // We are not the destination of this frame. 00472 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL ; 00473 prepare_rx_done_abort(); 00474 return; 00475 } 00476 } else { 00477 multicast = 0; 00478 nwk_skey = _params.keys.nwk_skey; 00479 app_skey = _params.keys.app_skey; 00480 downlink_counter = _params.dl_frame_counter; 00481 } 00482 00483 fctrl.value = payload[pkt_header_len++]; 00484 00485 sequence_counter = (uint16_t )payload[pkt_header_len++]; 00486 sequence_counter |= (uint16_t)payload[pkt_header_len++] << 8; 00487 00488 app_payload_start_index = 8 + fctrl.bits.fopts_len ; 00489 00490 mic_rx |= (uint32_t)payload[size - LORAMAC_MFR_LEN]; 00491 mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 1] << 8); 00492 mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16); 00493 mic_rx |= ((uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24); 00494 00495 sequence_counter_prev = (uint16_t)downlink_counter; 00496 sequence_counter_diff = (sequence_counter - sequence_counter_prev); 00497 00498 if (sequence_counter_diff < (1 << 15)) { 00499 00500 downlink_counter += sequence_counter_diff; 00501 compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey, 00502 address, DOWN_LINK, downlink_counter, &mic); 00503 if (mic_rx == mic) { 00504 is_mic_ok = true; 00505 } 00506 00507 } else { 00508 // check for sequence roll-over 00509 uint32_t downlink_counter_tmp = downlink_counter + 0x10000 + (int16_t)sequence_counter_diff; 00510 compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey, 00511 address, DOWN_LINK, downlink_counter_tmp, &mic); 00512 00513 if (mic_rx == mic ) { 00514 is_mic_ok = true; 00515 downlink_counter = downlink_counter_tmp; 00516 } 00517 } 00518 00519 // Check for a the maximum allowed counter difference 00520 get_phy.attribute = PHY_MAX_FCNT_GAP ; 00521 phy_param = lora_phy->get_phy_params(&get_phy); 00522 00523 if (sequence_counter_diff >= phy_param.value ) { 00524 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS ; 00525 mcps.get_indication().dl_frame_counter = downlink_counter; 00526 prepare_rx_done_abort( ); 00527 return; 00528 } 00529 00530 if (is_mic_ok == true) { 00531 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00532 mcps.get_indication().multicast = multicast; 00533 mcps.get_indication().fpending_status = fctrl.bits.fpending ; 00534 mcps.get_indication().buffer = NULL; 00535 mcps.get_indication().buffer_size = 0; 00536 mcps.get_indication().dl_frame_counter = downlink_counter; 00537 00538 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00539 00540 _params.adr_ack_counter = 0; 00541 mac_commands.clear_repeat_buffer(); 00542 00543 // Update 32 bits downlink counter 00544 if (multicast == 1) { 00545 mcps.get_indication().type = MCPS_MULTICAST ; 00546 00547 if ((cur_multicast_params->dl_frame_counter == downlink_counter) && 00548 (cur_multicast_params->dl_frame_counter != 0)) { 00549 00550 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 00551 mcps.get_indication().dl_frame_counter = downlink_counter; 00552 prepare_rx_done_abort(); 00553 00554 return; 00555 } 00556 00557 cur_multicast_params->dl_frame_counter = downlink_counter; 00558 00559 } else { 00560 00561 if (mac_hdr.bits.mtype == FRAME_TYPE_DATA_CONFIRMED_DOWN ) { 00562 _params.is_srv_ack_requested = true; 00563 mcps.get_indication().type = MCPS_CONFIRMED ; 00564 00565 if ((_params.dl_frame_counter == downlink_counter ) && 00566 (_params.dl_frame_counter != 0)) { 00567 // Duplicated confirmed downlink. Skip indication. 00568 // In this case, the MAC layer shall accept the MAC commands 00569 // which are included in the downlink retransmission. 00570 // It should not provide the same frame to the application 00571 // layer again. 00572 skip_indication = true; 00573 } 00574 } else { 00575 _params.is_srv_ack_requested = false; 00576 mcps.get_indication().type = MCPS_UNCONFIRMED ; 00577 00578 if ((_params.dl_frame_counter == downlink_counter) && 00579 (_params.dl_frame_counter != 0)) { 00580 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED ; 00581 mcps.get_indication().dl_frame_counter = downlink_counter; 00582 prepare_rx_done_abort(); 00583 return; 00584 } 00585 } 00586 _params.dl_frame_counter = downlink_counter; 00587 } 00588 00589 // This must be done before parsing the payload and the MAC commands. 00590 // We need to reset the MacCommandsBufferIndex here, since we need 00591 // to take retransmissions and repetitions into account. Error cases 00592 // will be handled in function OnMacStateCheckTimerEvent. 00593 if (mcps.get_confirmation().req_type == MCPS_CONFIRMED ) { 00594 if (fctrl.bits.ack == 1) { 00595 // Reset MacCommandsBufferIndex when we have received an ACK. 00596 mac_commands.clear_command_buffer(); 00597 } 00598 } else { 00599 // Reset the variable if we have received any valid frame. 00600 mac_commands.clear_command_buffer(); 00601 } 00602 00603 // Process payload and MAC commands 00604 if (((size - 4) - app_payload_start_index) > 0) { 00605 uint8_t port = payload[app_payload_start_index++]; 00606 frame_len = (size - 4) - app_payload_start_index; 00607 00608 mcps.get_indication().port = port; 00609 00610 if (port == 0) { 00611 // Only allow frames which do not have fOpts 00612 if (fctrl.bits.fopts_len == 0) { 00613 if (0 != decrypt_payload(payload + app_payload_start_index, 00614 frame_len, 00615 nwk_skey, 00616 address, 00617 DOWN_LINK, 00618 downlink_counter, 00619 _params.payload)) { 00620 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL ; 00621 } 00622 00623 // Decode frame payload MAC commands 00624 if (mac_commands.process_mac_commands(_params.payload, 0, frame_len, snr, 00625 mlme.get_confirmation(), 00626 _params.sys_params, *lora_phy) != LORAWAN_STATUS_OK) { 00627 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00628 } 00629 } else { 00630 skip_indication = true; 00631 } 00632 } else { 00633 if (fctrl.bits.fopts_len > 0) { 00634 // Decode Options field MAC commands. Omit the fPort. 00635 if (mac_commands.process_mac_commands(payload, 8, app_payload_start_index - 1, snr, 00636 mlme.get_confirmation(), 00637 _params.sys_params, *lora_phy ) != LORAWAN_STATUS_OK) { 00638 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00639 } 00640 } 00641 00642 if (0 != decrypt_payload(payload + app_payload_start_index, 00643 frame_len, 00644 app_skey, 00645 address, 00646 DOWN_LINK, 00647 downlink_counter, 00648 _params.payload)) { 00649 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL ; 00650 } 00651 00652 if (skip_indication == false) { 00653 mcps.get_indication().buffer = _params.payload; 00654 mcps.get_indication().buffer_size = frame_len; 00655 mcps.get_indication().is_data_recvd = true; 00656 } 00657 } 00658 } else { 00659 if (fctrl.bits.fopts_len > 0) { 00660 // Decode Options field MAC commands 00661 if (mac_commands.process_mac_commands(payload, 8, app_payload_start_index, snr, 00662 mlme.get_confirmation(), 00663 _params.sys_params, *lora_phy) != LORAWAN_STATUS_OK) { 00664 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00665 } 00666 } 00667 } 00668 00669 if (skip_indication == false) { 00670 // Check if the frame is an acknowledgement 00671 if (fctrl.bits.ack == 1) { 00672 mcps.get_confirmation().ack_received = true; 00673 mcps.get_indication().is_ack_recvd = true; 00674 00675 // Stop the AckTimeout timer as no more retransmissions 00676 // are needed. 00677 _lora_time.stop(_params.timers.ack_timeout_timer); 00678 } else { 00679 mcps.get_confirmation().ack_received = false; 00680 00681 if (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries) { 00682 // Stop the AckTimeout timer as no more retransmissions 00683 // are needed. 00684 _lora_time.stop( _params.timers.ack_timeout_timer ); 00685 } 00686 } 00687 } 00688 // Provide always an indication, skip the callback to the user application, 00689 // in case of a confirmed downlink retransmission. 00690 _params.flags.bits.mcps_ind = 1; 00691 _params.flags.bits.mcps_ind_skip = skip_indication; 00692 } else { 00693 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL ; 00694 00695 prepare_rx_done_abort( ); 00696 return; 00697 } 00698 } 00699 00700 break; 00701 00702 case FRAME_TYPE_PROPRIETARY : 00703 { 00704 memcpy(_params.payload, &payload[pkt_header_len], size); 00705 00706 mcps.get_indication().type = MCPS_PROPRIETARY ; 00707 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_OK ; 00708 mcps.get_indication().buffer = _params.payload; 00709 mcps.get_indication().buffer_size = size - pkt_header_len; 00710 00711 _params.flags.bits.mcps_ind = 1; 00712 break; 00713 } 00714 default: 00715 mcps.get_indication().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 00716 prepare_rx_done_abort(); 00717 break; 00718 } 00719 _params.flags.bits.mac_done = 1; 00720 00721 _lora_time.start(_params.timers.mac_state_check_timer, 1); 00722 } 00723 00724 void LoRaMac::on_radio_tx_timeout( void ) 00725 { 00726 if (_params.dev_class != CLASS_C ) { 00727 lora_phy->put_radio_to_sleep(); 00728 } else { 00729 open_continuous_rx2_window(); 00730 } 00731 00732 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 00733 00734 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ; 00735 00736 _params.flags.bits.mac_done = 1; 00737 } 00738 00739 void LoRaMac::on_radio_rx_error( void ) 00740 { 00741 if (_params.dev_class != CLASS_C ) { 00742 lora_phy->put_radio_to_sleep(); 00743 } else { 00744 open_continuous_rx2_window(); 00745 } 00746 00747 if (_params.rx_slot == RX_SLOT_WIN_1 ) { 00748 if (_params.is_node_ack_requested == true) { 00749 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ; 00750 } 00751 00752 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_ERROR ; 00753 00754 if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time) >= _params.rx_window2_delay) { 00755 _lora_time.stop(_params.timers.rx_window2_timer); 00756 _params.flags.bits.mac_done = 1; 00757 } 00758 00759 } else { 00760 00761 if (_params.is_node_ack_requested == true) { 00762 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 00763 } 00764 00765 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_ERROR ; 00766 00767 _params.flags.bits.mac_done = 1; 00768 } 00769 } 00770 00771 void LoRaMac::on_radio_rx_timeout(void) 00772 { 00773 if (_params.dev_class != CLASS_C ) { 00774 lora_phy->put_radio_to_sleep(); 00775 } else { 00776 open_continuous_rx2_window(); 00777 } 00778 00779 if (_params.rx_slot == RX_SLOT_WIN_1 ) { 00780 if (_params.is_node_ack_requested == true) { 00781 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT ; 00782 } 00783 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT ; 00784 00785 if (_lora_time.get_elapsed_time(_params.timers.aggregated_last_tx_time ) >= _params.rx_window2_delay) { 00786 _lora_time.stop(_params.timers.rx_window2_timer); 00787 _params.flags.bits.mac_done = 1; 00788 } 00789 00790 } else { 00791 00792 if (_params.is_node_ack_requested == true) { 00793 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 00794 } 00795 00796 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT ; 00797 00798 if (_params.dev_class != CLASS_C ) { 00799 _params.flags.bits.mac_done = 1; 00800 } 00801 } 00802 } 00803 00804 /*************************************************************************** 00805 * Timer event callbacks - deliberated locally * 00806 **************************************************************************/ 00807 void LoRaMac::on_mac_state_check_timer_event(void) 00808 { 00809 get_phy_params_t get_phy; 00810 phy_param_t phy_param; 00811 bool tx_timeout = false; 00812 00813 _lora_time.stop(_params.timers.mac_state_check_timer); 00814 00815 if (_params.flags.bits.mac_done == 1) { 00816 00817 if ((_params.mac_state & LORAMAC_RX_ABORT) == LORAMAC_RX_ABORT) { 00818 _params.mac_state &= ~LORAMAC_RX_ABORT; 00819 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00820 } 00821 00822 if ((_params.flags.bits.mlme_req == 1) || (_params.flags.bits.mcps_req == 1)) { 00823 00824 if ((mcps.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT ) || 00825 ( mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT )) { 00826 // Stop transmit cycle due to tx timeout. 00827 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00828 mac_commands.clear_command_buffer(); 00829 mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; 00830 mcps.get_confirmation().ack_received = false; 00831 mcps.get_confirmation().tx_toa = 0; 00832 tx_timeout = true; 00833 } 00834 } 00835 00836 if ((_params.is_node_ack_requested == false) && (tx_timeout == false)) { 00837 if ((_params.flags.bits.mlme_req == 1) || ((_params.flags.bits.mcps_req == 1))) { 00838 if ((_params.flags.bits.mlme_req == 1) && (mlme.get_confirmation().req_type == MLME_JOIN )) { 00839 // Procedure for the join request 00840 mlme.get_confirmation().nb_retries = _params.join_request_trial_counter; 00841 00842 if (mlme.get_confirmation().status == LORAMAC_EVENT_INFO_STATUS_OK ) { 00843 // Node joined successfully 00844 _params.ul_frame_counter = 0; 00845 _params.ul_nb_rep_counter = 0; 00846 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00847 } else { 00848 if (_params.join_request_trial_counter >= _params.max_join_request_trials) { 00849 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00850 } else { 00851 _params.flags.bits.mac_done = 0; 00852 // Sends the same frame again 00853 handle_delayed_tx_timer_event(); 00854 } 00855 } 00856 } else { 00857 // Procedure for all other frames 00858 if ((_params.ul_nb_rep_counter >= _params.sys_params.retry_num) || 00859 (_params.flags.bits.mcps_ind == 1)) { 00860 if (_params.flags.bits.mcps_ind == 0) { 00861 // Maximum repetitions without downlink. Reset MacCommandsBufferIndex. Increase ADR Ack counter. 00862 // Only process the case when the MAC did not receive a downlink. 00863 mac_commands.clear_command_buffer(); 00864 _params.adr_ack_counter++; 00865 } 00866 00867 _params.ul_nb_rep_counter = 0; 00868 00869 if (_params.is_ul_frame_counter_fixed == false) { 00870 _params.ul_frame_counter++; 00871 } 00872 00873 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00874 } else { 00875 _params.flags.bits.mac_done = 0; 00876 // Sends the same frame again 00877 handle_delayed_tx_timer_event(); 00878 } 00879 } 00880 } 00881 } 00882 00883 if (_params.flags.bits.mcps_ind == 1) { 00884 // Procedure if we received a frame 00885 if ((mcps.get_confirmation().ack_received == true) || 00886 (_params.ack_timeout_retry_counter > _params.max_ack_timeout_retries)) { 00887 _params.is_ack_retry_timeout_expired = false; 00888 _params.is_node_ack_requested = false; 00889 if (_params.is_ul_frame_counter_fixed == false) { 00890 _params.ul_frame_counter++; 00891 } 00892 mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; 00893 00894 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00895 } 00896 } 00897 00898 if ((_params.is_ack_retry_timeout_expired == true) && 00899 ((_params.mac_state & LORAMAC_TX_DELAYED) == 0)) { 00900 00901 // Retransmissions procedure for confirmed uplinks 00902 _params.is_ack_retry_timeout_expired = false; 00903 if ((_params.ack_timeout_retry_counter < _params.max_ack_timeout_retries) && 00904 (_params.ack_timeout_retry_counter <= MAX_ACK_RETRIES)) { 00905 00906 _params.ack_timeout_retry_counter++; 00907 00908 if ((_params.ack_timeout_retry_counter % 2) == 1) { 00909 get_phy.attribute = PHY_NEXT_LOWER_TX_DR ; 00910 get_phy.datarate = _params.sys_params.channel_data_rate; 00911 phy_param = lora_phy->get_phy_params( &get_phy ); 00912 _params.sys_params.channel_data_rate = phy_param.value ; 00913 } 00914 00915 // Try to send the frame again 00916 if (schedule_tx() == LORAWAN_STATUS_OK) { 00917 _params.flags.bits.mac_done = 0; 00918 } else { 00919 // The DR is not applicable for the payload size 00920 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR ; 00921 00922 mac_commands.clear_command_buffer(); 00923 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00924 _params.is_node_ack_requested = false; 00925 mcps.get_confirmation().ack_received = false; 00926 mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; 00927 mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; 00928 00929 if (_params.is_ul_frame_counter_fixed == false) { 00930 _params.ul_frame_counter++; 00931 } 00932 } 00933 } else { 00934 lora_phy->restore_default_channels(); 00935 00936 _params.mac_state &= ~LORAMAC_TX_RUNNING; 00937 00938 mac_commands.clear_command_buffer(); 00939 _params.is_node_ack_requested = false; 00940 mcps.get_confirmation().ack_received = false; 00941 mcps.get_confirmation().nb_retries = _params.ack_timeout_retry_counter; 00942 00943 if (_params.is_ul_frame_counter_fixed == false) { 00944 _params.ul_frame_counter++; 00945 } 00946 } 00947 } 00948 } 00949 00950 // Handle reception for Class B and Class C 00951 if ((_params.mac_state & LORAMAC_RX) == LORAMAC_RX) { 00952 _params.mac_state &= ~LORAMAC_RX; 00953 } 00954 00955 if (_params.mac_state == LORAMAC_IDLE) { 00956 if (_params.flags.bits.mcps_req == 1) { 00957 _params.flags.bits.mcps_req = 0; 00958 mac_primitives->mcps_confirm(&mcps.get_confirmation()); 00959 } 00960 00961 if (_params.flags.bits.mlme_req == 1) { 00962 _params.flags.bits.mlme_req = 0; 00963 mac_primitives->mlme_confirm(&mlme.get_confirmation()); 00964 } 00965 00966 // Verify if sticky MAC commands are pending or not 00967 if (mac_commands.is_sticky_mac_command_pending() == true) { 00968 // Setup MLME indication 00969 set_mlme_schedule_ul_indication(); 00970 } 00971 00972 // Procedure done. Reset variables. 00973 _params.flags.bits.mac_done = 0; 00974 } else { 00975 // Operation not finished restart timer 00976 _lora_time.start(_params.timers.mac_state_check_timer, MAC_STATE_CHECK_TIMEOUT); 00977 } 00978 00979 // Handle MCPS indication 00980 if (_params.flags.bits.mcps_ind == 1) { 00981 _params.flags.bits.mcps_ind = 0; 00982 00983 if (_params.dev_class== CLASS_C ) { 00984 // Activate RX2 window for Class C 00985 open_continuous_rx2_window(); 00986 } 00987 00988 if (_params.flags.bits.mcps_ind_skip == 0) { 00989 mac_primitives->mcps_indication(&mcps.get_indication()); 00990 } 00991 00992 _params.flags.bits.mcps_ind_skip = 0; 00993 } 00994 00995 // Handle MLME indication 00996 if (_params.flags.bits.mlme_ind == 1) { 00997 _params.flags.bits.mlme_ind = 0; 00998 mac_primitives->mlme_indication(&mlme.get_indication()); 00999 } 01000 } 01001 01002 void LoRaMac::on_tx_delayed_timer_event(void) 01003 { 01004 loramac_mhdr_t mac_hdr; 01005 loramac_frame_ctrl_t fctrl; 01006 01007 lorawan_status_t status = LORAWAN_STATUS_OK; 01008 01009 _lora_time.stop(_params.timers.tx_delayed_timer); 01010 _params.mac_state &= ~LORAMAC_TX_DELAYED; 01011 01012 if ((_params.flags.bits.mlme_req == 1 ) && 01013 (mlme.get_confirmation().req_type == MLME_JOIN )) { 01014 01015 reset_mac_parameters(); 01016 01017 _params.sys_params.channel_data_rate = lora_phy->get_alternate_DR(_params.join_request_trial_counter + 1); 01018 01019 mac_hdr.value = 0; 01020 mac_hdr.bits.mtype = FRAME_TYPE_JOIN_REQ ; 01021 01022 fctrl.value = 0; 01023 fctrl.bits.adr = _params.sys_params.adr_on; 01024 01025 /* In case of join request retransmissions, the stack must prepare 01026 * the frame again, because the network server keeps track of the random 01027 * LoRaMacDevNonce values to prevent reply attacks. */ 01028 status = prepare_frame(&mac_hdr, &fctrl, 0, NULL, 0); 01029 } 01030 01031 if (status == LORAWAN_STATUS_OK) { 01032 schedule_tx(); 01033 } else { 01034 tr_error("Delayed TX: PrepareFrame returned error %d", status); 01035 } 01036 } 01037 01038 void LoRaMac::on_rx_window1_timer_event(void) 01039 { 01040 _lora_time.stop(_params.timers.rx_window1_timer); 01041 _params.rx_slot = RX_SLOT_WIN_1 ; 01042 01043 _params.rx_window1_config.channel = _params.channel; 01044 _params.rx_window1_config.dr_offset = _params.sys_params.rx1_dr_offset; 01045 _params.rx_window1_config.dl_dwell_time = _params.sys_params.downlink_dwell_time; 01046 _params.rx_window1_config.is_repeater_supported = _params.is_repeater_supported; 01047 _params.rx_window1_config.is_rx_continuous = false; 01048 _params.rx_window1_config.rx_slot = _params.rx_slot; 01049 01050 if (_params.dev_class == CLASS_C ) { 01051 lora_phy->put_radio_to_standby(); 01052 } 01053 01054 lora_phy->rx_config(&_params.rx_window1_config, 01055 (int8_t*) &mcps.get_indication().rx_datarate); 01056 01057 rx_window_setup(_params.rx_window1_config.is_rx_continuous, 01058 _params.sys_params.max_rx_win_time); 01059 } 01060 01061 void LoRaMac::on_rx_window2_timer_event(void) 01062 { 01063 _lora_time.stop(_params.timers.rx_window2_timer); 01064 01065 _params.rx_window2_config.channel = _params.channel; 01066 _params.rx_window2_config.frequency = _params.sys_params.rx2_channel.frequency; 01067 _params.rx_window2_config.dl_dwell_time = _params.sys_params.downlink_dwell_time; 01068 _params.rx_window2_config.is_repeater_supported = _params.is_repeater_supported; 01069 _params.rx_window2_config.rx_slot = RX_SLOT_WIN_2 ; 01070 01071 if (_params.dev_class != CLASS_C ) { 01072 _params.rx_window2_config.is_rx_continuous = false; 01073 } else { 01074 // Setup continuous listening for class c 01075 _params.rx_window2_config.is_rx_continuous = true; 01076 } 01077 01078 if (lora_phy->rx_config(&_params.rx_window2_config, 01079 (int8_t*) &mcps.get_indication().rx_datarate) == true) { 01080 01081 rx_window_setup(_params.rx_window2_config.is_rx_continuous, 01082 _params.sys_params.max_rx_win_time); 01083 01084 _params.rx_slot = RX_SLOT_WIN_2 ; 01085 } 01086 } 01087 01088 void LoRaMac::on_ack_timeout_timer_event(void) 01089 { 01090 _lora_time.stop(_params.timers.ack_timeout_timer); 01091 01092 if (_params.is_node_ack_requested == true) { 01093 _params.is_ack_retry_timeout_expired = true; 01094 _params.mac_state &= ~LORAMAC_ACK_REQ; 01095 } 01096 if (_params.dev_class == CLASS_C ) { 01097 _params.flags.bits.mac_done = 1; 01098 } 01099 } 01100 01101 void LoRaMac::rx_window_setup(bool rx_continuous, uint32_t max_rx_window_time) 01102 { 01103 lora_phy->setup_rx_window(rx_continuous, max_rx_window_time); 01104 } 01105 01106 bool LoRaMac::validate_payload_length(uint8_t length, int8_t datarate, 01107 uint8_t fopts_len) 01108 { 01109 get_phy_params_t get_phy; 01110 phy_param_t phy_param; 01111 uint16_t max_value = 0; 01112 uint16_t payloadSize = 0; 01113 01114 // Setup PHY request 01115 get_phy.datarate = datarate; 01116 get_phy.attribute = PHY_MAX_PAYLOAD ; 01117 01118 // Get the maximum payload length 01119 if (_params.is_repeater_supported == true) { 01120 get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER ; 01121 } 01122 phy_param = lora_phy->get_phy_params(&get_phy); 01123 max_value = phy_param.value ; 01124 01125 // Calculate the resulting payload size 01126 payloadSize = (length + fopts_len); 01127 01128 // Validation of the application payload size 01129 if ((payloadSize <= max_value) && 01130 (payloadSize <= LORAMAC_PHY_MAXPAYLOAD)) { 01131 return true; 01132 } 01133 return false; 01134 } 01135 01136 void LoRaMac::set_mlme_schedule_ul_indication(void) 01137 { 01138 mlme.get_indication().indication_type = MLME_SCHEDULE_UPLINK ; 01139 _params.flags.bits.mlme_ind = 1; 01140 } 01141 01142 // This is not actual transmission. It just schedules a message in response 01143 // to MCPS request 01144 lorawan_status_t LoRaMac::send(loramac_mhdr_t *machdr, uint8_t fport, 01145 void *fbuffer, uint16_t fbuffer_size) 01146 { 01147 loramac_frame_ctrl_t fctrl; 01148 01149 fctrl.value = 0; 01150 fctrl.bits.fopts_len = 0; 01151 fctrl.bits.fpending = 0; 01152 fctrl.bits.ack = false; 01153 fctrl.bits.adr_ack_req = false; 01154 fctrl.bits.adr = _params.sys_params.adr_on; 01155 01156 // Prepare the frame 01157 lorawan_status_t status = prepare_frame(machdr, &fctrl, fport, fbuffer, 01158 fbuffer_size); 01159 01160 // Validate status 01161 if (status != LORAWAN_STATUS_OK) { 01162 return status; 01163 } 01164 01165 // Reset confirm parameters 01166 mcps.get_confirmation().nb_retries = 0; 01167 mcps.get_confirmation().ack_received = false; 01168 mcps.get_confirmation().ul_frame_counter = _params.ul_frame_counter; 01169 01170 status = schedule_tx(); 01171 01172 return status; 01173 } 01174 01175 lorawan_status_t LoRaMac::schedule_tx(void) 01176 { 01177 lorawan_time_t dutyCycleTimeOff = 0; 01178 channel_selection_params_t nextChan; 01179 get_phy_params_t getPhy; 01180 phy_param_t phyParam; 01181 01182 // Check if the device is off 01183 if (_params.sys_params.max_duty_cycle == 255) { 01184 return LORAWAN_STATUS_DEVICE_OFF; 01185 } 01186 01187 if (_params.sys_params.max_duty_cycle == 0) { 01188 _params.timers.aggregated_timeoff = 0; 01189 } 01190 01191 // Update Backoff 01192 calculate_backOff(_params.last_channel_idx); 01193 01194 nextChan.aggregate_timeoff = _params.timers.aggregated_timeoff; 01195 nextChan.current_datarate = _params.sys_params.channel_data_rate; 01196 _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; 01197 nextChan.dc_enabled = _params.is_dutycycle_on; 01198 nextChan.joined = _params.is_nwk_joined; 01199 nextChan.last_aggregate_tx_time = _params.timers.aggregated_last_tx_time; 01200 01201 // Select channel 01202 while (lora_phy->set_next_channel(&nextChan, &_params.channel, 01203 &dutyCycleTimeOff, 01204 &_params.timers.aggregated_timeoff) == false) { 01205 // Set the default datarate 01206 getPhy.attribute = PHY_DEF_TX_DR ; 01207 phyParam = lora_phy->get_phy_params(&getPhy); 01208 _params.sys_params.channel_data_rate = phyParam.value ; 01209 // Update datarate in the function parameters 01210 nextChan.current_datarate = _params.sys_params.channel_data_rate; 01211 } 01212 01213 tr_debug("Next Channel Idx=%d, DR=%d", _params.channel, nextChan.current_datarate); 01214 01215 // Compute Rx1 windows parameters 01216 uint8_t dr_offset = lora_phy->apply_DR_offset(_params.sys_params.channel_data_rate, 01217 _params.sys_params.rx1_dr_offset); 01218 01219 lora_phy->compute_rx_win_params(dr_offset, _params.sys_params.min_rx_symb, 01220 _params.sys_params.max_sys_rx_error, 01221 &_params.rx_window1_config); 01222 01223 // Compute Rx2 windows parameters 01224 lora_phy->compute_rx_win_params(_params.sys_params.rx2_channel.datarate, 01225 _params.sys_params.min_rx_symb, 01226 _params.sys_params.max_sys_rx_error, 01227 &_params.rx_window2_config); 01228 01229 if (_params.is_nwk_joined == false) { 01230 _params.rx_window1_delay = _params.sys_params.join_accept_delay1 01231 + _params.rx_window1_config.window_offset; 01232 _params.rx_window2_delay = _params.sys_params.join_accept_delay2 01233 + _params.rx_window2_config.window_offset; 01234 } else { 01235 if (validate_payload_length(_params.payload_length, 01236 _params.sys_params.channel_data_rate, 01237 mac_commands.get_mac_cmd_length()) == false) { 01238 return LORAWAN_STATUS_LENGTH_ERROR; 01239 } 01240 _params.rx_window1_delay = _params.sys_params.recv_delay1 01241 + _params.rx_window1_config.window_offset; 01242 _params.rx_window2_delay = _params.sys_params.recv_delay2 01243 + _params.rx_window2_config.window_offset; 01244 } 01245 01246 // Schedule transmission of frame 01247 if (dutyCycleTimeOff == 0) { 01248 // Try to send now 01249 return send_frame_on_channel(_params.channel); 01250 } else { 01251 // Send later - prepare timer 01252 _params.mac_state |= LORAMAC_TX_DELAYED; 01253 tr_debug("Next Transmission in %lu ms", dutyCycleTimeOff); 01254 01255 _lora_time.start(_params.timers.tx_delayed_timer, dutyCycleTimeOff); 01256 01257 return LORAWAN_STATUS_OK; 01258 } 01259 } 01260 01261 void LoRaMac::calculate_backOff(uint8_t channel) 01262 { 01263 backoff_params_t backoff_params; 01264 01265 backoff_params.joined = _params.is_nwk_joined; 01266 _params.is_dutycycle_on = MBED_CONF_LORA_DUTY_CYCLE_ON; 01267 backoff_params.dc_enabled = _params.is_dutycycle_on; 01268 backoff_params.channel = channel; 01269 backoff_params.elapsed_time = _lora_time.get_elapsed_time(_params.timers.mac_init_time); 01270 backoff_params.tx_toa = _params.timers.tx_toa; 01271 backoff_params.last_tx_was_join_req = _params.is_last_tx_join_request; 01272 01273 // Update regional back-off 01274 lora_phy->calculate_backoff(&backoff_params); 01275 01276 // Update aggregated time-off 01277 _params.timers.aggregated_timeoff = _params.timers.aggregated_timeoff 01278 + (_params.timers.tx_toa * _params.sys_params.aggregated_duty_cycle 01279 - _params.timers.tx_toa); 01280 } 01281 01282 void LoRaMac::reset_mac_parameters(void) 01283 { 01284 get_phy_params_t get_phy; 01285 phy_param_t phy_param; 01286 01287 _params.is_nwk_joined = false; 01288 01289 // Counters 01290 _params.ul_frame_counter = 0; 01291 _params.dl_frame_counter = 0; 01292 _params.adr_ack_counter = 0; 01293 01294 _params.ul_nb_rep_counter = 0; 01295 01296 _params.max_ack_timeout_retries = 1; 01297 _params.ack_timeout_retry_counter = 1; 01298 _params.is_ack_retry_timeout_expired = false; 01299 01300 _params.sys_params.max_duty_cycle = 0; 01301 _params.sys_params.aggregated_duty_cycle = 1; 01302 01303 mac_commands.clear_command_buffer(); 01304 mac_commands.clear_repeat_buffer(); 01305 mac_commands.clear_mac_commands_in_next_tx(); 01306 01307 _params.is_rx_window_enabled = true; 01308 01309 get_phy.attribute = PHY_DEF_TX_POWER ; 01310 phy_param = lora_phy->get_phy_params(&get_phy); 01311 01312 _params.sys_params.channel_tx_power = phy_param.value ; 01313 01314 get_phy.attribute = PHY_DEF_TX_DR ; 01315 phy_param = lora_phy->get_phy_params(&get_phy); 01316 _params.sys_params.channel_data_rate = phy_param.value ; 01317 01318 get_phy.attribute = PHY_DEF_DR1_OFFSET ; 01319 phy_param = lora_phy->get_phy_params(&get_phy); 01320 _params.sys_params.rx1_dr_offset = phy_param.value ; 01321 01322 get_phy.attribute = PHY_DEF_RX2_FREQUENCY ; 01323 phy_param = lora_phy->get_phy_params(&get_phy); 01324 _params.sys_params.rx2_channel.frequency = phy_param.value ; 01325 get_phy.attribute = PHY_DEF_RX2_DR ; 01326 phy_param = lora_phy->get_phy_params(&get_phy); 01327 _params.sys_params.rx2_channel.datarate = phy_param.value ; 01328 01329 get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME ; 01330 phy_param = lora_phy->get_phy_params(&get_phy); 01331 _params.sys_params.uplink_dwell_time = phy_param.value ; 01332 01333 get_phy.attribute = PHY_DEF_MAX_EIRP ; 01334 phy_param = lora_phy->get_phy_params(&get_phy); 01335 _params.sys_params.max_eirp = phy_param.value ; 01336 01337 get_phy.attribute = PHY_DEF_ANTENNA_GAIN ; 01338 phy_param = lora_phy->get_phy_params(&get_phy); 01339 _params.sys_params.antenna_gain = phy_param.value ; 01340 01341 _params.is_node_ack_requested = false; 01342 _params.is_srv_ack_requested = false; 01343 01344 // Reset Multicast downlink counters 01345 multicast_params_t *cur = _params.multicast_channels; 01346 while (cur != NULL) { 01347 cur->dl_frame_counter = 0; 01348 cur = cur->next ; 01349 } 01350 01351 // Initialize channel index. 01352 _params.channel = 0; 01353 _params.last_channel_idx = _params.channel; 01354 } 01355 01356 bool LoRaMac::is_fPort_allowed (uint8_t fPort) 01357 { 01358 if ((fPort == 0) || (fPort > 224)) { 01359 return false; 01360 } 01361 return true; 01362 } 01363 01364 void LoRaMac::open_continuous_rx2_window (void) 01365 { 01366 handle_rx2_timer_event(); 01367 _params.rx_slot = RX_SLOT_WIN_CLASS_C ; 01368 } 01369 01370 static void memcpy_convert_endianess(uint8_t *dst, const uint8_t *src, 01371 uint16_t size) 01372 { 01373 dst = dst + (size - 1); 01374 while (size--) { 01375 *dst-- = *src++; 01376 } 01377 } 01378 01379 lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr, 01380 loramac_frame_ctrl_t *fctrl, 01381 uint8_t fport, void *fbuffer, 01382 uint16_t fbuffer_size) 01383 { 01384 uint16_t i; 01385 uint8_t pkt_header_len = 0; 01386 uint32_t mic = 0; 01387 const void* payload = fbuffer; 01388 uint8_t frame_port = fport; 01389 lorawan_status_t status = LORAWAN_STATUS_OK; 01390 01391 _params.buffer_pkt_len = 0; 01392 01393 _params.is_node_ack_requested = false; 01394 01395 if (fbuffer == NULL) { 01396 fbuffer_size = 0; 01397 } 01398 01399 _params.payload_length = fbuffer_size; 01400 01401 _params.buffer[pkt_header_len++] = machdr->value ; 01402 01403 switch (machdr->bits.mtype ) { 01404 01405 case FRAME_TYPE_JOIN_REQ : 01406 01407 _params.buffer_pkt_len = pkt_header_len; 01408 memcpy_convert_endianess(_params.buffer + _params.buffer_pkt_len, 01409 _params.keys.app_eui, 8); 01410 _params.buffer_pkt_len += 8; 01411 memcpy_convert_endianess(_params.buffer + _params.buffer_pkt_len, 01412 _params.keys.dev_eui, 8); 01413 _params.buffer_pkt_len += 8; 01414 01415 _params.dev_nonce = lora_phy->get_radio_rng(); 01416 01417 _params.buffer[_params.buffer_pkt_len++] = _params.dev_nonce & 0xFF; 01418 _params.buffer[_params.buffer_pkt_len++] = (_params.dev_nonce >> 8) & 0xFF; 01419 01420 if (0 != compute_join_frame_mic(_params.buffer, 01421 _params.buffer_pkt_len & 0xFF, 01422 _params.keys.app_key, &mic)) { 01423 return LORAWAN_STATUS_CRYPTO_FAIL; 01424 } 01425 01426 _params.buffer[_params.buffer_pkt_len++] = mic & 0xFF; 01427 _params.buffer[_params.buffer_pkt_len++] = (mic >> 8) & 0xFF; 01428 _params.buffer[_params.buffer_pkt_len++] = (mic >> 16) & 0xFF; 01429 _params.buffer[_params.buffer_pkt_len++] = (mic >> 24) & 0xFF; 01430 01431 break; 01432 case FRAME_TYPE_DATA_CONFIRMED_UP : 01433 _params.is_node_ack_requested = true; 01434 //Intentional fallthrough 01435 case FRAME_TYPE_DATA_UNCONFIRMED_UP : { 01436 if (_params.is_nwk_joined == false) { 01437 // No network has been joined yet 01438 return LORAWAN_STATUS_NO_NETWORK_JOINED; 01439 } 01440 01441 if (_params.sys_params.adr_on) { 01442 if (lora_phy->get_next_ADR(true, 01443 _params.sys_params.channel_data_rate, 01444 _params.sys_params.channel_tx_power, 01445 _params.adr_ack_counter)) { 01446 fctrl->bits.adr_ack_req = 1; 01447 } 01448 } 01449 01450 if (_params.is_srv_ack_requested == true) { 01451 _params.is_srv_ack_requested = false; 01452 fctrl->bits.ack = 1; 01453 } 01454 01455 _params.buffer[pkt_header_len++] = (_params.dev_addr) & 0xFF; 01456 _params.buffer[pkt_header_len++] = (_params.dev_addr >> 8) & 0xFF; 01457 _params.buffer[pkt_header_len++] = (_params.dev_addr >> 16) & 0xFF; 01458 _params.buffer[pkt_header_len++] = (_params.dev_addr >> 24) & 0xFF; 01459 01460 _params.buffer[pkt_header_len++] = fctrl->value ; 01461 01462 _params.buffer[pkt_header_len++] = _params.ul_frame_counter & 0xFF; 01463 _params.buffer[pkt_header_len++] = (_params.ul_frame_counter >> 8) 01464 & 0xFF; 01465 01466 // Copy the MAC commands which must be re-send into the MAC command buffer 01467 mac_commands.copy_repeat_commands_to_buffer(); 01468 01469 const uint8_t mac_commands_len = mac_commands.get_mac_cmd_length(); 01470 01471 if ((payload != NULL) && (_params.payload_length > 0)) { 01472 if (mac_commands.is_mac_command_in_next_tx() == true) { 01473 if (mac_commands_len <= LORA_MAC_COMMAND_MAX_FOPTS_LENGTH) { 01474 fctrl->bits.fopts_len += mac_commands_len; 01475 01476 // Update FCtrl field with new value of OptionsLength 01477 _params.buffer[0x05] = fctrl->value ; 01478 01479 const uint8_t *buffer = 01480 mac_commands.get_mac_commands_buffer(); 01481 for (i = 0; i < mac_commands_len; i++) { 01482 _params.buffer[pkt_header_len++] = buffer[i]; 01483 } 01484 } else { 01485 _params.payload_length = mac_commands_len; 01486 payload = mac_commands.get_mac_commands_buffer(); 01487 frame_port = 0; 01488 } 01489 } 01490 } else { 01491 if ((mac_commands_len > 0) 01492 && (mac_commands.is_mac_command_in_next_tx() == true)) { 01493 _params.payload_length = mac_commands_len; 01494 payload = mac_commands.get_mac_commands_buffer(); 01495 frame_port = 0; 01496 } 01497 } 01498 01499 // Store MAC commands which must be re-send in case the device does not receive a downlink anymore 01500 mac_commands.parse_mac_commands_to_repeat(); 01501 01502 if ((payload != NULL) && (_params.payload_length > 0)) { 01503 _params.buffer[pkt_header_len++] = frame_port; 01504 01505 if (frame_port == 0) { 01506 // Reset buffer index as the mac commands are being sent on port 0 01507 mac_commands.clear_command_buffer(); 01508 if (0 != encrypt_payload((uint8_t*) payload, _params.payload_length, 01509 _params.keys.nwk_skey, _params.dev_addr, 01510 UP_LINK, 01511 _params.ul_frame_counter, 01512 &_params.buffer[pkt_header_len])) { 01513 status = LORAWAN_STATUS_CRYPTO_FAIL; 01514 } 01515 } else { 01516 if (0 != encrypt_payload((uint8_t*) payload, _params.payload_length, 01517 _params.keys.app_skey, _params.dev_addr, 01518 UP_LINK, 01519 _params.ul_frame_counter, 01520 &_params.buffer[pkt_header_len])) { 01521 status = LORAWAN_STATUS_CRYPTO_FAIL; 01522 } 01523 } 01524 } 01525 01526 _params.buffer_pkt_len = pkt_header_len + _params.payload_length; 01527 01528 if (0 != compute_mic(_params.buffer, _params.buffer_pkt_len, 01529 _params.keys.nwk_skey, 01530 _params.dev_addr, 01531 UP_LINK, 01532 _params.ul_frame_counter, &mic)) { 01533 status = LORAWAN_STATUS_CRYPTO_FAIL; 01534 } 01535 01536 _params.buffer[_params.buffer_pkt_len + 0] = mic & 0xFF; 01537 _params.buffer[_params.buffer_pkt_len + 1] = (mic >> 8) & 0xFF; 01538 _params.buffer[_params.buffer_pkt_len + 2] = (mic >> 16) & 0xFF; 01539 _params.buffer[_params.buffer_pkt_len + 3] = (mic >> 24) & 0xFF; 01540 01541 _params.buffer_pkt_len += LORAMAC_MFR_LEN; 01542 } 01543 break; 01544 case FRAME_TYPE_PROPRIETARY : 01545 if ((fbuffer != NULL) && (_params.payload_length > 0)) { 01546 memcpy(_params.buffer + pkt_header_len, (uint8_t*) fbuffer, 01547 _params.payload_length); 01548 _params.buffer_pkt_len = pkt_header_len + _params.payload_length; 01549 } 01550 break; 01551 default: 01552 status = LORAWAN_STATUS_SERVICE_UNKNOWN; 01553 } 01554 01555 return status; 01556 } 01557 01558 lorawan_status_t LoRaMac::send_frame_on_channel(uint8_t channel) 01559 { 01560 tx_config_params_t tx_config; 01561 int8_t tx_power = 0; 01562 01563 tx_config.channel = channel; 01564 tx_config.datarate = _params.sys_params.channel_data_rate; 01565 tx_config.tx_power = _params.sys_params.channel_tx_power; 01566 tx_config.max_eirp = _params.sys_params.max_eirp; 01567 tx_config.antenna_gain = _params.sys_params.antenna_gain; 01568 tx_config.pkt_len = _params.buffer_pkt_len; 01569 01570 lora_phy->tx_config(&tx_config, &tx_power, &_params.timers.tx_toa); 01571 01572 mlme.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 01573 01574 mcps.get_confirmation().status = LORAMAC_EVENT_INFO_STATUS_ERROR ; 01575 mcps.get_confirmation().data_rate = _params.sys_params.channel_data_rate; 01576 mcps.get_confirmation().tx_power = tx_power; 01577 01578 // Store the time on air 01579 mcps.get_confirmation().tx_toa = _params.timers.tx_toa; 01580 mlme.get_confirmation().tx_toa = _params.timers.tx_toa; 01581 01582 // Starts the MAC layer status check timer 01583 _lora_time.start(_params.timers.mac_state_check_timer, 01584 MAC_STATE_CHECK_TIMEOUT); 01585 01586 if (_params.is_nwk_joined == false) { 01587 _params.join_request_trial_counter++; 01588 } 01589 01590 // Send now 01591 lora_phy->handle_send(_params.buffer, _params.buffer_pkt_len); 01592 01593 _params.mac_state |= LORAMAC_TX_RUNNING; 01594 01595 return LORAWAN_STATUS_OK; 01596 } 01597 01598 lorawan_status_t LoRaMac::set_tx_continuous_wave(uint16_t timeout) 01599 { 01600 cw_mode_params_t continuous_wave; 01601 01602 continuous_wave.channel = _params.channel; 01603 continuous_wave.datarate = _params.sys_params.channel_data_rate; 01604 continuous_wave.tx_power = _params.sys_params.channel_tx_power; 01605 continuous_wave.max_eirp = _params.sys_params.max_eirp; 01606 continuous_wave.antenna_gain = _params.sys_params.antenna_gain; 01607 continuous_wave.timeout = timeout; 01608 01609 lora_phy->set_tx_cont_mode(&continuous_wave); 01610 01611 // Starts the MAC layer status check timer 01612 _lora_time.start(_params.timers.mac_state_check_timer, 01613 MAC_STATE_CHECK_TIMEOUT); 01614 01615 _params.mac_state |= LORAMAC_TX_RUNNING; 01616 01617 return LORAWAN_STATUS_OK; 01618 } 01619 01620 lorawan_status_t LoRaMac::set_tx_continuous_wave1(uint16_t timeout, 01621 uint32_t frequency, 01622 uint8_t power) 01623 { 01624 cw_mode_params_t continuous_wave; 01625 01626 continuous_wave.channel = 0; 01627 continuous_wave.datarate = 0; 01628 continuous_wave.tx_power = power; 01629 continuous_wave.max_eirp = 0; 01630 continuous_wave.antenna_gain = 0; 01631 continuous_wave.timeout = timeout; 01632 01633 lora_phy->set_tx_cont_mode(&continuous_wave); 01634 01635 // Starts the MAC layer status check timer 01636 _lora_time.start(_params.timers.mac_state_check_timer, 01637 MAC_STATE_CHECK_TIMEOUT); 01638 01639 _params.mac_state |= LORAMAC_TX_RUNNING; 01640 01641 return LORAWAN_STATUS_OK; 01642 } 01643 01644 lorawan_status_t LoRaMac::initialize(loramac_primitives_t *primitives, 01645 LoRaPHY *phy, EventQueue *queue) 01646 { 01647 get_phy_params_t get_phy; 01648 phy_param_t phy_param; 01649 01650 //store event queue pointer 01651 ev_queue = queue; 01652 01653 if (!primitives) { 01654 return LORAWAN_STATUS_PARAMETER_INVALID; 01655 } 01656 01657 lora_phy = phy; 01658 01659 // Activate MLME subsystem 01660 mlme.activate_mlme_subsystem(this, lora_phy, &mac_commands); 01661 01662 // Activate MCPS subsystem 01663 mcps.activate_mcps_subsystem(this, lora_phy); 01664 01665 // Activate MIB subsystem 01666 mib.activate_mib_subsystem(this, lora_phy); 01667 01668 // Activate channel planning subsystem 01669 channel_plan.activate_channelplan_subsystem(lora_phy, &mib); 01670 01671 mac_primitives = primitives; 01672 01673 _params.flags.value = 0; 01674 01675 _params.dev_class = CLASS_A ; 01676 _params.mac_state = LORAMAC_IDLE; 01677 01678 _params.join_request_trial_counter = 0; 01679 _params.max_join_request_trials = 1; 01680 _params.is_repeater_supported = false; 01681 01682 // Reset duty cycle times 01683 _params.timers.aggregated_last_tx_time = 0; 01684 _params.timers.aggregated_timeoff = 0; 01685 01686 // Reset to defaults 01687 get_phy.attribute = PHY_DUTY_CYCLE ; 01688 phy_param = lora_phy->get_phy_params(&get_phy); 01689 // load default at this moment. Later can be changed using json 01690 _params.is_dutycycle_on = (bool) phy_param.value ; 01691 01692 get_phy.attribute = PHY_DEF_TX_POWER ; 01693 phy_param = lora_phy->get_phy_params(&get_phy); 01694 _params.sys_params.channel_tx_power = phy_param.value ; 01695 01696 get_phy.attribute = PHY_DEF_TX_DR ; 01697 phy_param = lora_phy->get_phy_params(&get_phy); 01698 _params.sys_params.channel_data_rate = phy_param.value ; 01699 01700 get_phy.attribute = PHY_MAX_RX_WINDOW ; 01701 phy_param = lora_phy->get_phy_params(&get_phy); 01702 _params.sys_params.max_rx_win_time = phy_param.value ; 01703 01704 get_phy.attribute = PHY_RECEIVE_DELAY1 ; 01705 phy_param = lora_phy->get_phy_params(&get_phy); 01706 _params.sys_params.recv_delay1 = phy_param.value ; 01707 01708 get_phy.attribute = PHY_RECEIVE_DELAY2 ; 01709 phy_param = lora_phy->get_phy_params(&get_phy); 01710 _params.sys_params.recv_delay2 = phy_param.value ; 01711 01712 get_phy.attribute = PHY_JOIN_ACCEPT_DELAY1 ; 01713 phy_param = lora_phy->get_phy_params(&get_phy); 01714 _params.sys_params.join_accept_delay1 = phy_param.value ; 01715 01716 get_phy.attribute = PHY_JOIN_ACCEPT_DELAY2 ; 01717 phy_param = lora_phy->get_phy_params(&get_phy); 01718 _params.sys_params.join_accept_delay2 = phy_param.value ; 01719 01720 get_phy.attribute = PHY_DEF_DR1_OFFSET ; 01721 phy_param = lora_phy->get_phy_params(&get_phy); 01722 _params.sys_params.rx1_dr_offset = phy_param.value ; 01723 01724 get_phy.attribute = PHY_DEF_RX2_FREQUENCY ; 01725 phy_param = lora_phy->get_phy_params(&get_phy); 01726 _params.sys_params.rx2_channel.frequency = phy_param.value ; 01727 01728 get_phy.attribute = PHY_DEF_RX2_DR ; 01729 phy_param = lora_phy->get_phy_params(&get_phy); 01730 _params.sys_params.rx2_channel.datarate = phy_param.value ; 01731 01732 get_phy.attribute = PHY_DEF_UPLINK_DWELL_TIME ; 01733 phy_param = lora_phy->get_phy_params(&get_phy); 01734 _params.sys_params.uplink_dwell_time = phy_param.value ; 01735 01736 get_phy.attribute = PHY_DEF_DOWNLINK_DWELL_TIME ; 01737 phy_param = lora_phy->get_phy_params(&get_phy); 01738 _params.sys_params.downlink_dwell_time = phy_param.value ; 01739 01740 get_phy.attribute = PHY_DEF_MAX_EIRP ; 01741 phy_param = lora_phy->get_phy_params(&get_phy); 01742 _params.sys_params.max_eirp = phy_param.f_value ; 01743 01744 get_phy.attribute = PHY_DEF_ANTENNA_GAIN ; 01745 phy_param = lora_phy->get_phy_params(&get_phy); 01746 _params.sys_params.antenna_gain = phy_param.f_value ; 01747 01748 // Init parameters which are not set in function ResetMacParameters 01749 _params.sys_params.max_sys_rx_error = 10; 01750 _params.sys_params.min_rx_symb = 6; 01751 _params.sys_params.retry_num = 1; 01752 01753 reset_mac_parameters(); 01754 01755 // Random seed initialization 01756 srand(lora_phy->get_radio_rng()); 01757 01758 _params.is_nwk_public = MBED_CONF_LORA_PUBLIC_NETWORK; 01759 lora_phy->setup_public_network_mode(_params.is_nwk_public); 01760 lora_phy->put_radio_to_sleep(); 01761 01762 // Initialize timers 01763 _lora_time.init(_params.timers.mac_state_check_timer, 01764 mbed::callback(this, &LoRaMac::handle_mac_state_check_timer_event)); 01765 _lora_time.init(_params.timers.tx_delayed_timer, 01766 mbed::callback(this, &LoRaMac::handle_delayed_tx_timer_event)); 01767 _lora_time.init(_params.timers.rx_window1_timer, 01768 mbed::callback(this, &LoRaMac::handle_rx1_timer_event)); 01769 _lora_time.init(_params.timers.rx_window2_timer, 01770 mbed::callback(this, &LoRaMac::handle_rx2_timer_event)); 01771 _lora_time.init(_params.timers.ack_timeout_timer, 01772 mbed::callback(this, &LoRaMac::handle_ack_timeout)); 01773 01774 // Store the current initialization time 01775 _params.timers.mac_init_time = _lora_time.get_current_time(); 01776 01777 return LORAWAN_STATUS_OK; 01778 } 01779 01780 void LoRaMac::disconnect() 01781 { 01782 // Cancel all timers 01783 _lora_time.stop(_params.timers.mac_state_check_timer); 01784 _lora_time.stop(_params.timers.tx_delayed_timer); 01785 _lora_time.stop(_params.timers.rx_window1_timer); 01786 _lora_time.stop(_params.timers.rx_window2_timer); 01787 _lora_time.stop(_params.timers.ack_timeout_timer); 01788 01789 // Put radio to sleep 01790 lora_phy->put_radio_to_sleep(); 01791 01792 // Reset internal state 01793 _params.is_nwk_joined = false; 01794 _params.is_ack_retry_timeout_expired = false; 01795 _params.is_rx_window_enabled = true; 01796 _params.is_node_ack_requested = false; 01797 _params.is_srv_ack_requested = false; 01798 _params.flags.value = 0; 01799 _params.mac_state = 0; 01800 01801 // Clear MAC commands 01802 mac_commands.clear_command_buffer(); 01803 mac_commands.clear_repeat_buffer(); 01804 mac_commands.clear_mac_commands_in_next_tx(); 01805 01806 // Set internal state to idle. 01807 _params.mac_state = LORAMAC_IDLE; 01808 } 01809 01810 lorawan_status_t LoRaMac::query_tx_possible(uint8_t size, 01811 loramac_tx_info_t * tx_info) 01812 { 01813 get_phy_params_t get_phy; 01814 phy_param_t phy_param; 01815 01816 uint8_t fopt_len = mac_commands.get_mac_cmd_length() 01817 + mac_commands.get_repeat_commands_length(); 01818 01819 if (tx_info == NULL) { 01820 return LORAWAN_STATUS_PARAMETER_INVALID; 01821 } 01822 01823 // if applicaion has turned on ADR, we want to opt it out 01824 if (_params.sys_params.adr_on) { 01825 lora_phy->get_next_ADR(false, _params.sys_params.channel_data_rate, 01826 _params.sys_params.channel_tx_power, 01827 _params.adr_ack_counter); 01828 } 01829 01830 // Setup PHY request 01831 get_phy.datarate = _params.sys_params.channel_data_rate; 01832 get_phy.attribute = PHY_MAX_PAYLOAD ; 01833 01834 // Change request in case repeater is supported 01835 if (_params.is_repeater_supported == true) { 01836 get_phy.attribute = PHY_MAX_PAYLOAD_REPEATER ; 01837 } 01838 phy_param = lora_phy->get_phy_params(&get_phy); 01839 tx_info->current_payload_size = phy_param.value ; 01840 01841 // Verify if the fOpts fit into the maximum payload 01842 if (tx_info->current_payload_size >= fopt_len) { 01843 tx_info->max_possible_payload_size = tx_info->current_payload_size - fopt_len; 01844 } else { 01845 tx_info->max_possible_payload_size = tx_info->current_payload_size ; 01846 // The fOpts don't fit into the maximum payload. Omit the MAC commands to 01847 // ensure that another uplink is possible. 01848 fopt_len = 0; 01849 mac_commands.clear_command_buffer(); 01850 mac_commands.clear_repeat_buffer(); 01851 } 01852 01853 // Verify if the fOpts and the payload fit into the maximum payload 01854 if (validate_payload_length(size, _params.sys_params.channel_data_rate, 01855 fopt_len) == false) { 01856 return LORAWAN_STATUS_LENGTH_ERROR; 01857 } 01858 return LORAWAN_STATUS_OK; 01859 } 01860 01861 lorawan_status_t LoRaMac::add_channel_plan(const lorawan_channelplan_t& plan) 01862 { 01863 // Validate if the MAC is in a correct state 01864 if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { 01865 if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { 01866 return LORAWAN_STATUS_BUSY; 01867 } 01868 } 01869 01870 return channel_plan.set_plan(plan); 01871 } 01872 01873 lorawan_status_t LoRaMac::remove_channel_plan() 01874 { 01875 if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { 01876 if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { 01877 return LORAWAN_STATUS_BUSY; 01878 } 01879 } 01880 01881 return channel_plan.remove_plan(); 01882 01883 } 01884 01885 lorawan_status_t LoRaMac::get_channel_plan(lorawan_channelplan_t& plan) 01886 { 01887 return channel_plan.get_plan(plan, &_params); 01888 } 01889 01890 lorawan_status_t LoRaMac::remove_single_channel(uint8_t id) 01891 { 01892 if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { 01893 if ((_params.mac_state & LORAMAC_TX_CONFIG) != LORAMAC_TX_CONFIG) { 01894 return LORAWAN_STATUS_BUSY; 01895 } 01896 } 01897 01898 return channel_plan.remove_single_channel(id); 01899 } 01900 01901 lorawan_status_t LoRaMac::multicast_channel_link(multicast_params_t *channel_param) 01902 { 01903 if (channel_param == NULL) { 01904 return LORAWAN_STATUS_PARAMETER_INVALID; 01905 } 01906 if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { 01907 return LORAWAN_STATUS_BUSY; 01908 } 01909 01910 // Reset downlink counter 01911 channel_param->dl_frame_counter = 0; 01912 01913 if (_params.multicast_channels == NULL) { 01914 // New node is the fist element 01915 _params.multicast_channels = channel_param; 01916 } else { 01917 multicast_params_t *cur = _params.multicast_channels; 01918 01919 // Search the last node in the list 01920 while (cur->next != NULL) { 01921 cur = cur->next ; 01922 } 01923 // This function always finds the last node 01924 cur->next = channel_param; 01925 } 01926 01927 return LORAWAN_STATUS_OK; 01928 } 01929 01930 lorawan_status_t LoRaMac::multicast_channel_unlink( 01931 multicast_params_t *channel_param) 01932 { 01933 if (channel_param == NULL) { 01934 return LORAWAN_STATUS_PARAMETER_INVALID; 01935 } 01936 if ((_params.mac_state & LORAMAC_TX_RUNNING) == LORAMAC_TX_RUNNING) { 01937 return LORAWAN_STATUS_BUSY; 01938 } 01939 01940 if (_params.multicast_channels != NULL) { 01941 if (_params.multicast_channels == channel_param) { 01942 // First element 01943 _params.multicast_channels = channel_param->next ; 01944 } else { 01945 multicast_params_t *cur = _params.multicast_channels; 01946 01947 // Search the node in the list 01948 while (cur->next && cur->next != channel_param) { 01949 cur = cur->next ; 01950 } 01951 // If we found the node, remove it 01952 if (cur->next ) { 01953 cur->next = channel_param->next ; 01954 } 01955 } 01956 channel_param->next = NULL; 01957 } 01958 01959 return LORAWAN_STATUS_OK; 01960 } 01961 01962 lorawan_status_t LoRaMac::mlme_request( loramac_mlme_req_t *mlmeRequest ) 01963 { 01964 return mlme.set_request(mlmeRequest, &_params); 01965 } 01966 01967 lorawan_status_t LoRaMac::mcps_request( loramac_mcps_req_t *mcpsRequest ) 01968 { 01969 if (_params.mac_state != LORAMAC_IDLE) { 01970 return LORAWAN_STATUS_BUSY; 01971 } 01972 01973 return mcps.set_request(mcpsRequest, &_params); 01974 } 01975 01976 lorawan_status_t LoRaMac::mib_get_request_confirm( loramac_mib_req_confirm_t *mibGet ) 01977 { 01978 return mib.get_request(mibGet, &_params); 01979 } 01980 01981 lorawan_status_t LoRaMac::mib_set_request_confirm( loramac_mib_req_confirm_t *mibSet ) 01982 { 01983 return mib.set_request(mibSet, &_params); 01984 } 01985 01986 radio_events_t *LoRaMac::get_phy_event_handlers() 01987 { 01988 radio_events.tx_done = mbed::callback(this, &LoRaMac::handle_tx_done); 01989 radio_events.rx_done = mbed::callback(this, &LoRaMac::handle_rx_done); 01990 radio_events.rx_error = mbed::callback(this, &LoRaMac::handle_rx_error); 01991 radio_events.tx_timeout = mbed::callback(this, &LoRaMac::handle_tx_timeout); 01992 radio_events.rx_timeout = mbed::callback(this, &LoRaMac::handle_rx_timeout); 01993 01994 return &radio_events; 01995 } 01996 01997 #if defined(LORAWAN_COMPLIANCE_TEST) 01998 /*************************************************************************** 01999 * Compliance testing * 02000 **************************************************************************/ 02001 02002 lorawan_status_t LoRaMac::LoRaMacSetTxTimer( uint32_t TxDutyCycleTime ) 02003 { 02004 _lora_time.start(tx_next_packet_timer, TxDutyCycleTime); 02005 return LORAWAN_STATUS_OK; 02006 } 02007 02008 lorawan_status_t LoRaMac::LoRaMacStopTxTimer( ) 02009 { 02010 _lora_time.stop(tx_next_packet_timer); 02011 return LORAWAN_STATUS_OK; 02012 } 02013 02014 void LoRaMac::LoRaMacTestRxWindowsOn( bool enable ) 02015 { 02016 _params.is_rx_window_enabled = enable; 02017 } 02018 02019 void LoRaMac::LoRaMacTestSetMic( uint16_t txPacketCounter ) 02020 { 02021 _params.ul_frame_counter = txPacketCounter; 02022 _params.is_ul_frame_counter_fixed = true; 02023 } 02024 02025 void LoRaMac::LoRaMacTestSetDutyCycleOn( bool enable ) 02026 { 02027 VerifyParams_t verify; 02028 02029 verify.DutyCycle = enable; 02030 02031 if(lora_phy->verify(&verify, PHY_DUTY_CYCLE ) == true) 02032 { 02033 _params.is_dutycycle_on = enable; 02034 } 02035 } 02036 02037 void LoRaMac::LoRaMacTestSetChannel( uint8_t channel ) 02038 { 02039 _params.channel = channel; 02040 } 02041 #endif
Generated on Tue Jul 12 2022 13:30:21 by
