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.
mac_pd_sap.c
00001 /* 00002 * Copyright (c) 2014-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "nsconfig.h" 00018 #include "ns_types.h" 00019 #include "eventOS_event.h" 00020 #include "string.h" 00021 #include "ns_trace.h" 00022 #include "nsdynmemLIB.h" 00023 #include "randLIB.h" 00024 #include "ccmLIB.h" 00025 #include "common_functions.h" 00026 #include "platform/arm_hal_interrupt.h" 00027 #include "mac_api.h" 00028 #include "fhss_api.h " 00029 #include "MAC/IEEE802_15_4/sw_mac_internal.h" 00030 #include "MAC/IEEE802_15_4/mac_pd_sap.h" 00031 #include "MAC/IEEE802_15_4/mac_defines.h" 00032 #include "MAC/IEEE802_15_4/mac_header_helper_functions.h" 00033 #include "MAC/IEEE802_15_4/mac_timer.h" 00034 #include "MAC/IEEE802_15_4/mac_mlme.h" 00035 #include "MAC/IEEE802_15_4/mac_filter.h" 00036 #include "MAC/IEEE802_15_4/mac_mcps_sap.h" 00037 #include "MAC/rf_driver_storage.h" 00038 00039 00040 #define TRACE_GROUP "mPDs" 00041 00042 /* Define TX Timeot Period */ 00043 // Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout 00044 #define NWKTX_TIMEOUT_PERIOD (1200*20) 00045 00046 static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry); 00047 00048 static void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00049 { 00050 rf_mac_setup->macCurrentBE = rf_mac_setup->macMinBE; 00051 } 00052 00053 static void mac_csma_BE_update(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00054 { 00055 if (rf_mac_setup->macCurrentBE < rf_mac_setup->macMaxBE) { 00056 rf_mac_setup->macCurrentBE++; 00057 } 00058 } 00059 00060 // 8-bit because maxBE is maximum 8 (according to 802.15.4) 00061 static uint8_t mac_csma_random_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00062 { 00063 return randLIB_get_random_in_range(0, (1 << rf_mac_setup->macCurrentBE) - 1); 00064 } 00065 00066 static uint16_t mac_csma_backoff_period_convert_to50us(uint8_t random, uint8_t backoff_period_in_10us) 00067 { 00068 return (random * backoff_period_in_10us) / 5; 00069 } 00070 00071 static void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00072 { 00073 uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); 00074 uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff, rf_mac_setup->backoff_period_in_10us); 00075 if (backoff_slots == 0) { 00076 backoff_slots = 1; 00077 } 00078 00079 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, backoff_slots); 00080 } 00081 00082 /* 00083 * \file mac_pd_sap.c 00084 * \brief Add short description about this file!!! 00085 * 00086 */ 00087 static bool mac_data_interface_read_last_ack_pending_status(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00088 { 00089 uint8_t pending = 1; 00090 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00091 if (dev_driver->extension) { 00092 dev_driver->extension(PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS, &pending); 00093 } 00094 00095 00096 return pending; 00097 00098 } 00099 00100 static void mac_tx_done_state_set(protocol_interface_rf_mac_setup_s *rf_ptr, mac_event_t event ) 00101 { 00102 rf_ptr->mac_tx_result = event; 00103 00104 if(event == MAC_TX_DONE || event == MAC_TX_DONE_PENDING) { 00105 00106 } else { 00107 rf_ptr->macTxRequestAck = false; 00108 } 00109 rf_ptr->macRfRadioTxActive = false; 00110 rf_ptr->macTxProcessActive = false; 00111 mcps_sap_pd_confirm(rf_ptr); 00112 } 00113 00114 static void mac_data_interface_tx_to_cb(protocol_interface_rf_mac_setup_s *rf_ptr) 00115 { 00116 rf_ptr->macRfRadioTxActive = false; 00117 mac_tx_done_state_set(rf_ptr, MAC_TX_TIMEOUT); 00118 } 00119 00120 static int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_ptr) { 00121 dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; 00122 phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; 00123 00124 00125 if (dev_driver->arm_net_virtual_tx_cb) { 00126 if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { 00127 rf_ptr->macRfRadioTxActive = true; 00128 timer_mac_start(rf_ptr, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/ 00129 } else { 00130 mac_data_interface_tx_to_cb(rf_ptr); 00131 } 00132 return 0; 00133 } 00134 00135 if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { 00136 rf_ptr->macRfRadioTxActive = true; 00137 return 0; 00138 } 00139 return -1; 00140 } 00141 00142 /** 00143 * Send a buffer to the MAC. 00144 * Used by the protocol core. 00145 * 00146 * \param buf pointer to buffer 00147 * 00148 */ 00149 int8_t mac_pd_sap_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00150 { 00151 if (!rf_mac_setup || !rf_mac_setup->macUpState || !rf_mac_setup->active_pd_data_request) { 00152 return -1; 00153 } 00154 00155 rf_mac_setup->mac_cca_retry = 0; 00156 rf_mac_setup->mac_tx_retry = 0; 00157 rf_mac_setup->macTxProcessActive = true; 00158 mac_csma_param_init(rf_mac_setup); 00159 mac_csma_backoff_start(rf_mac_setup); 00160 return 0; 00161 } 00162 00163 /** 00164 * Run Mac data interface state Machine for mac timer. 00165 * 00166 */ 00167 void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00168 { 00169 if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) { 00170 00171 if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) { 00172 if (rf_mac_setup->fhss_api) { 00173 uint8_t *synch_info = NULL; 00174 mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request; 00175 if (!active_buf) { 00176 return; 00177 } 00178 if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 00179 // FHSS synchronization info is written in the end of transmitted (Beacon) buffer 00180 dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; 00181 synch_info = tx_buf->buf + rf_mac_setup->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; 00182 } 00183 // Change to destination channel and write synchronization info to Beacon frames here 00184 int tx_handle_retval = rf_mac_setup->fhss_api->tx_handle(rf_mac_setup->fhss_api, !mac_is_ack_request_set(active_buf), 00185 active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), 00186 synch_info, active_buf->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, 00187 rf_mac_setup->dev_driver->phy_driver->phy_tail_length); 00188 // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer 00189 if (tx_handle_retval == -1) { 00190 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, randLIB_get_random_in_range(20, 400) + 1); 00191 return; 00192 } 00193 // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back 00194 // to queue by using CCA fail event 00195 if (tx_handle_retval == -3) { 00196 mac_tx_done_state_set(rf_mac_setup, MAC_CCA_FAIL); 00197 return; 00198 } 00199 } 00200 if (mac_plme_cca_req(rf_mac_setup) != 0) { 00201 mac_csma_backoff_start(rf_mac_setup); 00202 } 00203 } else if (rf_mac_setup->mac_tx_result == MAC_TX_TIMEOUT) { 00204 mac_data_interface_tx_to_cb(rf_mac_setup); 00205 } else if (rf_mac_setup->mac_tx_result == MAC_TIMER_ACK) { 00206 mac_data_interface_tx_done_cb(rf_mac_setup,PHY_LINK_TX_FAIL, 0, 0 ); 00207 } 00208 } 00209 } 00210 00211 static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { 00212 rf_ptr->macRfRadioTxActive = false; 00213 if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs) { 00214 //Send MAC_CCA_FAIL 00215 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00216 } else { 00217 timer_mac_stop(rf_ptr); 00218 mac_csma_BE_update(rf_ptr); 00219 mac_csma_backoff_start(rf_ptr); 00220 } 00221 } 00222 00223 static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr) 00224 { 00225 if (rf_ptr->fhss_api) { 00226 return rf_ptr->fhss_api->get_retry_period(rf_ptr->fhss_api, rf_ptr->active_pd_data_request->DstAddr, rf_ptr->dev_driver->phy_driver->phy_MTU); 00227 } 00228 uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr); 00229 uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff_length, rf_ptr->backoff_period_in_10us); 00230 if (backoff_slots == 0) { 00231 backoff_slots = 1; 00232 } 00233 return backoff_slots; 00234 } 00235 00236 static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { 00237 rf_ptr->macRfRadioTxActive = false; 00238 if (rf_ptr->mac_tx_retry < rf_ptr->mac_mlme_retry_max) { 00239 rf_ptr->mac_cca_retry = 0; 00240 rf_ptr->mac_tx_retry++; //Update retry counter 00241 mac_csma_param_init(rf_ptr); 00242 rf_ptr->mac_tx_status.retry++; 00243 /*Send retry using random interval*/ 00244 timer_mac_start(rf_ptr, MAC_TIMER_CCA, mac_get_retry_period(rf_ptr)); 00245 } else { 00246 //Send TX Fail event 00247 // rf_mac_setup->ip_tx_active->bad_channel = rf_mac_setup->mac_channel; 00248 mac_tx_done_state_set(rf_ptr, MAC_TX_FAIL); 00249 } 00250 } 00251 00252 00253 static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry) 00254 { 00255 00256 if (!rf_ptr->macRfRadioTxActive) { 00257 return -1; 00258 } 00259 bool waiting_ack = false; 00260 // Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event 00261 if ((status != PHY_LINK_TX_DONE) && (status != PHY_LINK_TX_DONE_PENDING)) { 00262 /* For PHY_LINK_TX_SUCCESS and PHY_LINK_CCA_FAIL cca_retry must always be > 0. 00263 * PHY_LINK_TX_FAIL either happened during transmission or when waiting Ack -> we must use the CCA count given by PHY. 00264 */ 00265 if ((cca_retry == 0) && (status != PHY_LINK_TX_FAIL)) { 00266 cca_retry = 1; 00267 } 00268 rf_ptr->mac_tx_status.cca_cnt += cca_retry; 00269 rf_ptr->mac_cca_retry += cca_retry; 00270 } 00271 rf_ptr->mac_tx_status.retry += tx_retry; 00272 rf_ptr->mac_tx_retry += tx_retry; 00273 timer_mac_stop(rf_ptr); 00274 00275 switch (status) { 00276 case PHY_LINK_TX_SUCCESS: 00277 if (rf_ptr->macTxRequestAck) { 00278 timer_mac_start(rf_ptr, MAC_TIMER_ACK, rf_ptr->mac_ack_wait_duration); /*wait for ACK 1 ms*/ 00279 waiting_ack = true; 00280 } else { 00281 //TODO CHECK this is MAC_TX_ PERMIT OK 00282 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00283 } 00284 break; 00285 00286 case PHY_LINK_CCA_FAIL: 00287 mac_sap_cca_fail_cb(rf_ptr); 00288 break; 00289 00290 case PHY_LINK_TX_FAIL: 00291 mac_sap_no_ack_cb(rf_ptr); 00292 break; 00293 00294 case PHY_LINK_TX_DONE: 00295 //mac_tx_result 00296 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00297 break; 00298 00299 case PHY_LINK_TX_DONE_PENDING: 00300 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE_PENDING); 00301 00302 break; 00303 } 00304 if (rf_ptr->fhss_api) { 00305 bool tx_is_done = false; 00306 if (rf_ptr->mac_tx_result == MAC_TX_DONE) { 00307 tx_is_done = true; 00308 } 00309 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_is_done, rf_ptr->active_pd_data_request->msduHandle); 00310 } 00311 return 0; 00312 } 00313 00314 int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) 00315 { 00316 protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s*)identifier; 00317 00318 if (!rf_ptr || !message ) { 00319 return -1; 00320 } 00321 00322 if (!rf_ptr->macUpState) { 00323 return -2; 00324 } 00325 00326 if (message->id == MAC15_4_PD_SAP_DATA_IND) { 00327 const uint8_t *ptr; 00328 00329 arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); 00330 00331 if (pd_data_ind->data_len < 3 ) { 00332 return -1; 00333 } 00334 ptr = pd_data_ind->data_ptr; 00335 00336 mac_pre_parsed_frame_t *buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); 00337 00338 if (!buffer) { 00339 tr_error("pd_ind buffer get fail %u", pd_data_ind->data_len); 00340 sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); 00341 return -3; 00342 } 00343 if (rf_ptr->fhss_api) { 00344 buffer->timestamp = rf_ptr->fhss_api->read_timestamp(rf_ptr->fhss_api); 00345 } 00346 buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); 00347 mac_header_parse_fcf_dsn(&buffer->fcf_dsn, ptr); 00348 00349 int16_t length = pd_data_ind->data_len; 00350 ptr += 3; 00351 // Upward direction functions assume no headroom and are trusting that removed bytes are still valid. 00352 // see mac.c:655 00353 00354 /* Set default flags */ 00355 buffer->dbm = pd_data_ind->dbm; 00356 buffer->LQI = pd_data_ind->link_quality; 00357 buffer->mac_class_ptr = rf_ptr; 00358 buffer->mac_header_length = 3; 00359 00360 if (!rf_ptr->macProminousMode) { 00361 00362 if (buffer->fcf_dsn.frametype > FC_CMD_FRAME || buffer->fcf_dsn.frametype == FC_ACK_FRAME) { 00363 goto ERROR_HANDLER; 00364 } 00365 //Verify Length after address field 00366 switch (buffer->fcf_dsn.DstAddrMode) { 00367 case MAC_ADDR_MODE_64_BIT: 00368 buffer->mac_header_length += 10; 00369 break; 00370 case MAC_ADDR_MODE_16_BIT: 00371 buffer->mac_header_length += 4; 00372 break; 00373 case MAC_ADDR_MODE_NONE: 00374 break; 00375 } 00376 00377 switch (buffer->fcf_dsn.SrcAddrMode) { 00378 case MAC_ADDR_MODE_64_BIT: 00379 buffer->mac_header_length += 8; 00380 if (!buffer->fcf_dsn.intraPan) { 00381 buffer->mac_header_length += 2; 00382 } 00383 break; 00384 case MAC_ADDR_MODE_16_BIT: 00385 buffer->mac_header_length += 2; 00386 if (!buffer->fcf_dsn.intraPan) { 00387 buffer->mac_header_length += 2; 00388 } 00389 break; 00390 case MAC_ADDR_MODE_NONE: 00391 break; 00392 } 00393 00394 length -= buffer->mac_header_length; 00395 00396 if (length < 0) { 00397 goto ERROR_HANDLER; 00398 } 00399 00400 buffer->mac_payload_length = (buffer->frameLength - buffer->mac_header_length); 00401 00402 if (buffer->fcf_dsn.securityEnabled) { 00403 //Read KEYID Mode 00404 uint8_t key_id_mode, security_level, mic_len; 00405 uint8_t *security_ptr = &buffer->buf[buffer->mac_header_length]; 00406 uint8_t auxBaseHeader = *security_ptr; 00407 key_id_mode = (auxBaseHeader >> 3) & 3; 00408 security_level = auxBaseHeader & 7; 00409 switch (key_id_mode) { 00410 case MAC_KEY_ID_MODE_IMPLICIT: 00411 if (security_level) { 00412 buffer->security_aux_header_length = 5; 00413 } else { 00414 buffer->security_aux_header_length = 1; 00415 } 00416 break; 00417 case MAC_KEY_ID_MODE_IDX: 00418 buffer->security_aux_header_length = 6; 00419 break; 00420 case MAC_KEY_ID_MODE_SRC4_IDX: 00421 buffer->security_aux_header_length = 10; 00422 break; 00423 default: 00424 buffer->security_aux_header_length = 14; 00425 break; 00426 } 00427 00428 length -= buffer->security_aux_header_length; 00429 00430 switch (security_level) { 00431 case 1: 00432 case 5: 00433 mic_len = 4; 00434 break; 00435 case 2: 00436 case 6: 00437 mic_len = 8; 00438 break; 00439 case 3: 00440 case 7: 00441 mic_len = 16; 00442 break; 00443 default: 00444 mic_len = 0; 00445 break; 00446 } 00447 00448 length -= mic_len; 00449 00450 //Verify that data length is not negative 00451 if (length < 0) { 00452 goto ERROR_HANDLER; 00453 } 00454 00455 buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); 00456 } 00457 00458 switch (buffer->fcf_dsn.frametype) { 00459 case FC_DATA_FRAME: 00460 if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) { 00461 goto ERROR_HANDLER; 00462 } 00463 break; 00464 case FC_BEACON_FRAME: 00465 if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode != MAC_ADDR_MODE_NONE) { 00466 goto ERROR_HANDLER; 00467 } 00468 break; 00469 default: 00470 if (length == 0) { 00471 goto ERROR_HANDLER; 00472 } 00473 break; 00474 } 00475 00476 } 00477 00478 if (mcps_sap_pd_ind(buffer) == 0) { 00479 return 0; 00480 } 00481 ERROR_HANDLER: 00482 mcps_sap_pre_parsed_frame_buffer_free(buffer); 00483 return -1; 00484 00485 00486 } else if (message->id == MAC15_4_PD_SAP_DATA_TX_CONFIRM) { 00487 arm_pd_sap_15_4_confirm_with_params_t *pd_data_cnf = &(message->message.mac15_4_pd_sap_confirm); 00488 return mac_data_interface_tx_done_cb(rf_ptr, pd_data_cnf->status, pd_data_cnf->cca_retry, pd_data_cnf->tx_retry); 00489 } 00490 00491 return -1; 00492 } 00493 00494 void mac_pd_sap_rf_low_level_function_set(void *mac_ptr, void *driver) 00495 { 00496 arm_device_driver_list_s *driver_ptr = (arm_device_driver_list_s*)driver; 00497 driver_ptr->phy_sap_identifier = (protocol_interface_rf_mac_setup_s *)mac_ptr; 00498 driver_ptr->phy_sap_upper_cb = mac_pd_sap_data_cb; 00499 } 00500
Generated on Tue Jul 12 2022 14:24:12 by
