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