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