init
Embed:
(wiki syntax)
Show/hide line numbers
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:24:47 by
1.7.2