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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
mac_pd_sap.c
00001 /* 00002 * Copyright (c) 2014-2018, 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 "nsdynmemLIB.h" 00022 #include "randLIB.h" 00023 #include "ccmLIB.h" 00024 #include "common_functions.h" 00025 #include "platform/arm_hal_interrupt.h" 00026 #include "mac_api.h" 00027 #include "fhss_api.h " 00028 #include "MAC/IEEE802_15_4/sw_mac_internal.h" 00029 #include "MAC/IEEE802_15_4/mac_pd_sap.h" 00030 #include "MAC/IEEE802_15_4/mac_defines.h" 00031 #include "MAC/IEEE802_15_4/mac_header_helper_functions.h" 00032 #include "MAC/IEEE802_15_4/mac_timer.h" 00033 #include "MAC/IEEE802_15_4/mac_security_mib.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 /* Define TX Timeot Period */ 00040 // Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout 00041 #define NWKTX_TIMEOUT_PERIOD (1200*20) 00042 // Measured 3750us with 1280 byte secured packet from calculating TX time to starting CSMA timer on PHY. 00043 // Typically varies from 500us to several milliseconds depending on packet size and the platform. 00044 // MAC should learn and make this dynamic by sending first few packets with predefined CSMA period. 00045 #define MIN_FHSS_CSMA_PERIOD_US 5000 00046 00047 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); 00048 static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr); 00049 00050 void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00051 { 00052 rf_mac_setup->macCurrentBE = rf_mac_setup->macMinBE; 00053 } 00054 00055 static void mac_csma_BE_update(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00056 { 00057 if (rf_mac_setup->macCurrentBE < rf_mac_setup->macMaxBE) { 00058 rf_mac_setup->macCurrentBE++; 00059 } 00060 } 00061 00062 // 8-bit because maxBE is maximum 8 (according to 802.15.4) 00063 static uint8_t mac_csma_random_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00064 { 00065 return randLIB_get_random_in_range(0, (1 << rf_mac_setup->macCurrentBE) - 1); 00066 } 00067 00068 static uint16_t mac_csma_backoff_period_convert_to50us(uint8_t random, uint8_t backoff_period_in_10us) 00069 { 00070 return (random * backoff_period_in_10us) / 5; 00071 } 00072 00073 void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00074 { 00075 uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); 00076 uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff, rf_mac_setup->backoff_period_in_10us); 00077 if (backoff_slots == 0) { 00078 backoff_slots = 1; 00079 } 00080 00081 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, backoff_slots); 00082 } 00083 00084 00085 uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00086 { 00087 // Use minimum allowed CSMA-CA for asynch frames 00088 if (rf_mac_setup->active_pd_data_request->asynch_request) { 00089 return MIN_FHSS_CSMA_PERIOD_US; 00090 } 00091 uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); 00092 uint32_t backoff_in_us; 00093 //Multiple aUnitBackoffPeriod symbol time 00094 if (rf_mac_setup->rf_csma_extension_supported) { 00095 backoff_in_us = backoff * rf_mac_setup->aUnitBackoffPeriod * rf_mac_setup->symbol_time_us; 00096 } else { 00097 backoff_in_us = backoff * rf_mac_setup->backoff_period_in_10us * 10; 00098 } 00099 00100 if (backoff_in_us == 0) { 00101 backoff_in_us = 1; 00102 } 00103 if (rf_mac_setup->fhss_api) { 00104 // Synchronization error when backoff time is shorter than allowed. 00105 // TODO: Make this dynamic. 00106 if (backoff_in_us < MIN_FHSS_CSMA_PERIOD_US) { 00107 backoff_in_us += MIN_FHSS_CSMA_PERIOD_US; 00108 } 00109 // Backoff must be long enough to make multiple CCA checks 00110 if (backoff_in_us < (uint32_t)(rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1))) { 00111 backoff_in_us += ((rf_mac_setup->multi_cca_interval * (rf_mac_setup->number_of_csma_ca_periods - 1)) - backoff_in_us); 00112 } 00113 if (rf_mac_setup->mac_tx_retry) { 00114 backoff_in_us += rf_mac_setup->fhss_api->get_retry_period(rf_mac_setup->fhss_api, rf_mac_setup->active_pd_data_request->DstAddr, rf_mac_setup->dev_driver->phy_driver->phy_MTU); 00115 } 00116 } 00117 return backoff_in_us; 00118 } 00119 00120 00121 /* 00122 * \file mac_pd_sap.c 00123 * \brief Add short description about this file!!! 00124 * 00125 */ 00126 static bool mac_data_interface_read_last_ack_pending_status(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00127 { 00128 uint8_t pending = 1; 00129 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00130 if (dev_driver->extension) { 00131 dev_driver->extension(PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS, &pending); 00132 } 00133 00134 00135 return pending; 00136 00137 } 00138 00139 static void mac_tx_done_state_set(protocol_interface_rf_mac_setup_s *rf_ptr, mac_event_t event) 00140 { 00141 rf_ptr->mac_tx_result = event; 00142 00143 if (event == MAC_TX_DONE || event == MAC_TX_DONE_PENDING) { 00144 00145 } else { 00146 rf_ptr->macTxRequestAck = false; 00147 } 00148 rf_ptr->macRfRadioTxActive = false; 00149 rf_ptr->macTxProcessActive = false; 00150 mcps_sap_pd_confirm(rf_ptr); 00151 } 00152 00153 static void mac_data_interface_tx_to_cb(protocol_interface_rf_mac_setup_s *rf_ptr) 00154 { 00155 rf_ptr->macRfRadioTxActive = false; 00156 mac_tx_done_state_set(rf_ptr, MAC_TX_TIMEOUT); 00157 } 00158 00159 int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00160 { 00161 dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; 00162 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00163 00164 rf_mac_setup->macRfRadioTxActive = true; 00165 if (dev_driver->arm_net_virtual_tx_cb) { 00166 if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { 00167 timer_mac_start(rf_mac_setup, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/ 00168 } else { 00169 rf_mac_setup->macRfRadioTxActive = false; 00170 mac_data_interface_tx_to_cb(rf_mac_setup); 00171 } 00172 return 0; 00173 } 00174 00175 uint8_t *buffer; 00176 uint16_t length; 00177 if (rf_mac_setup->mac_ack_tx_active) { 00178 buffer = tx_buf->enhanced_ack_buf; 00179 length = tx_buf->ack_len; 00180 } else { 00181 buffer = tx_buf->buf ; 00182 length = tx_buf->len; 00183 } 00184 if (dev_driver->tx(buffer, length, 1, PHY_LAYER_PAYLOAD) == 0) { 00185 return 0; 00186 } 00187 00188 rf_mac_setup->macRfRadioTxActive = false; 00189 return -1; 00190 } 00191 00192 /** 00193 * Send a buffer to the MAC. 00194 * Used by the protocol core. 00195 * 00196 * \param buf pointer to buffer 00197 * 00198 */ 00199 int8_t mac_pd_sap_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00200 { 00201 if (!rf_mac_setup || !rf_mac_setup->macUpState || !rf_mac_setup->active_pd_data_request) { 00202 return -1; 00203 } 00204 00205 rf_mac_setup->mac_cca_retry = 0; 00206 rf_mac_setup->mac_tx_retry = 0; 00207 rf_mac_setup->macTxProcessActive = true; 00208 mac_csma_param_init(rf_mac_setup); 00209 mac_csma_backoff_start(rf_mac_setup); 00210 return 0; 00211 } 00212 00213 00214 /** 00215 * Abort active PHY transmission. 00216 * 00217 * \param rf_mac_setup pointer to MAC. 00218 * 00219 */ 00220 void mac_pd_abort_active_tx(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00221 { 00222 phy_csma_params_t csma_params; 00223 // Set TX time to 0 to abort current transmission 00224 csma_params.backoff_time = 0; 00225 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params); 00226 } 00227 00228 /** 00229 * Set PHY TX time. 00230 * 00231 * \param rf_mac_setup pointer to MAC. 00232 * \param tx_time TX timestamp to be set. 00233 * 00234 */ 00235 void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t tx_time, bool cca_enabled) 00236 { 00237 // With TX time set to zero, PHY sends immediately 00238 if (!tx_time) { 00239 tx_time++; 00240 } 00241 phy_csma_params_t csma_params; 00242 csma_params.backoff_time = tx_time; 00243 csma_params.cca_enabled = cca_enabled; 00244 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params); 00245 } 00246 00247 /** 00248 * Get PHY RX time. 00249 * 00250 * \param rf_mac_setup pointer to MAC 00251 * \return Timestamp of last PHY reception 00252 * 00253 */ 00254 static uint32_t mac_pd_sap_get_phy_rx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00255 { 00256 if (!rf_mac_setup->rf_csma_extension_supported) { 00257 return 0; 00258 } 00259 uint8_t rx_time_buffer[4]; 00260 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_READ_RX_TIME, rx_time_buffer); 00261 return common_read_32_bit(rx_time_buffer); 00262 } 00263 00264 /** 00265 * Run Mac data interface state Machine for mac timer. 00266 * 00267 */ 00268 void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00269 { 00270 00271 if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) { 00272 00273 if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) { 00274 00275 if (rf_mac_setup->rf_csma_extension_supported) { 00276 mac_sap_cca_fail_cb(rf_mac_setup); 00277 return; 00278 } 00279 00280 if (rf_mac_setup->fhss_api) { 00281 uint8_t *synch_info = NULL; 00282 mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request; 00283 if (!active_buf) { 00284 return; 00285 } 00286 bool cca_enabled; 00287 if (active_buf->fcf_dsn.frametype == MAC_FRAME_ACK) { 00288 cca_enabled = false; 00289 } else { 00290 cca_enabled = true; 00291 } 00292 00293 mac_pd_sap_set_phy_tx_time(rf_mac_setup, active_buf->tx_time, cca_enabled); 00294 if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 00295 // FHSS synchronization info is written in the end of transmitted (Beacon) buffer 00296 dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; 00297 synch_info = tx_buf->buf + rf_mac_setup->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; 00298 rf_mac_setup->fhss_api->write_synch_info(rf_mac_setup->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); 00299 } 00300 // Change to destination channel and write synchronization info to Beacon frames here 00301 int tx_handle_retval = rf_mac_setup->fhss_api->tx_handle(rf_mac_setup->fhss_api, !mac_is_ack_request_set(active_buf), 00302 active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), 00303 active_buf->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, 00304 rf_mac_setup->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); 00305 // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer 00306 if (tx_handle_retval == -1) { 00307 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, randLIB_get_random_in_range(20, 400) + 1); 00308 return; 00309 } 00310 // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back 00311 // to queue by using CCA fail event 00312 if (tx_handle_retval == -3) { 00313 mac_tx_done_state_set(rf_mac_setup, MAC_CCA_FAIL); 00314 return; 00315 } else if (tx_handle_retval == -2) { 00316 mac_tx_done_state_set(rf_mac_setup, MAC_UNKNOWN_DESTINATION); 00317 return; 00318 } 00319 } 00320 if (mac_plme_cca_req(rf_mac_setup) != 0) { 00321 mac_csma_backoff_start(rf_mac_setup); 00322 } 00323 } else if (rf_mac_setup->mac_tx_result == MAC_TX_TIMEOUT) { 00324 mac_data_interface_tx_to_cb(rf_mac_setup); 00325 } else if (rf_mac_setup->mac_tx_result == MAC_TIMER_ACK) { 00326 mac_data_interface_tx_done_cb(rf_mac_setup, PHY_LINK_TX_FAIL, 0, 0); 00327 } 00328 } 00329 } 00330 00331 static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) 00332 { 00333 if (rf_ptr->mac_ack_tx_active) { 00334 if (rf_ptr->active_pd_data_request) { 00335 mac_csma_backoff_start(rf_ptr); 00336 } 00337 } else { 00338 00339 rf_ptr->macRfRadioTxActive = false; 00340 if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) { 00341 //Send MAC_CCA_FAIL 00342 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00343 } else { 00344 timer_mac_stop(rf_ptr); 00345 mac_csma_BE_update(rf_ptr); 00346 if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request)) { 00347 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00348 } 00349 } 00350 } 00351 } 00352 00353 //static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr) 00354 //{ 00355 // if (rf_ptr->fhss_api && rf_ptr->fhss_api->get_retry_period) { 00356 // 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); 00357 // } 00358 // uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr); 00359 // uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff_length, rf_ptr->backoff_period_in_10us); 00360 // if (backoff_slots == 0) { 00361 // backoff_slots = 1; 00362 // } 00363 // return backoff_slots; 00364 //} 00365 00366 static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) 00367 { 00368 rf_ptr->macRfRadioTxActive = false; 00369 if (rf_ptr->mac_tx_retry < rf_ptr->mac_mlme_retry_max) { 00370 rf_ptr->mac_cca_retry = 0; 00371 rf_ptr->mac_tx_retry++; //Update retry counter 00372 mac_csma_param_init(rf_ptr); 00373 // Increase current backoff exponent when retry count grows 00374 for (int retry_index = rf_ptr->mac_tx_retry; retry_index > 0; retry_index--) { 00375 mac_csma_BE_update(rf_ptr); 00376 } 00377 rf_ptr->mac_tx_status.retry++; 00378 /*Send retry using random interval*/ 00379 if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request)) { 00380 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00381 } 00382 00383 } else { 00384 //Send TX Fail event 00385 // rf_mac_setup->ip_tx_active->bad_channel = rf_mac_setup->mac_channel; 00386 mac_tx_done_state_set(rf_ptr, MAC_TX_FAIL); 00387 } 00388 } 00389 00390 00391 static bool mac_data_asynch_channel_switch(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *active_buf) 00392 { 00393 if (!active_buf || !active_buf->asynch_request) { 00394 return false; 00395 } 00396 active_buf->asynch_channel = rf_ptr->mac_channel; //Store Original channel 00397 uint16_t channel = mlme_scan_analyze_next_channel(&active_buf->asynch_channel_list, true); 00398 if (channel <= 0xff) { 00399 mac_mlme_rf_channel_change(rf_ptr, channel); 00400 00401 } 00402 return true; 00403 } 00404 00405 00406 static void mac_data_ack_tx_finish(protocol_interface_rf_mac_setup_s *rf_ptr) 00407 { 00408 rf_ptr->mac_ack_tx_active = false; 00409 if (rf_ptr->fhss_api) { 00410 //SET tx completed false because ack isnot never queued 00411 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, false, 0xff); 00412 } 00413 if (rf_ptr->active_pd_data_request) { 00414 00415 mcps_pending_packet_counter_update_check(rf_ptr, rf_ptr->active_pd_data_request); 00416 //GEN TX failure 00417 mac_sap_cca_fail_cb(rf_ptr); 00418 } 00419 } 00420 00421 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) 00422 { 00423 00424 if (!rf_ptr->macRfRadioTxActive) { 00425 return -1; 00426 } 00427 00428 if (status == PHY_LINK_CCA_PREPARE) { 00429 00430 if (rf_ptr->mac_ack_tx_active) { 00431 //Accept direct non crypted acks and crypted only if neighbor is at list 00432 if (rf_ptr->ack_tx_possible || mac_sec_mib_device_description_get(rf_ptr, rf_ptr->enhanced_ack_buffer.DstAddr, rf_ptr->enhanced_ack_buffer.fcf_dsn.DstAddrMode, rf_ptr->enhanced_ack_buffer.DstPANId)) { 00433 return PHY_TX_ALLOWED; 00434 } 00435 00436 //Compare time to started time 00437 if (mac_mcps_sap_get_phy_timestamp(rf_ptr) - rf_ptr->enhanced_ack_handler_timestamp > ENHANCED_ACK_NEIGHBOUR_POLL_MAX_TIME_US || mcps_generic_ack_build(rf_ptr, false) != 0) { 00438 mac_data_ack_tx_finish(rf_ptr); 00439 } 00440 00441 return PHY_TX_NOT_ALLOWED; 00442 } 00443 00444 if (mac_data_asynch_channel_switch(rf_ptr, rf_ptr->active_pd_data_request)) { 00445 return PHY_TX_ALLOWED; 00446 } 00447 00448 if (rf_ptr->fhss_api) { 00449 mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request; 00450 if (!active_buf) { 00451 return PHY_TX_NOT_ALLOWED; 00452 } 00453 00454 // Change to destination channel and write synchronization info to Beacon frames here 00455 int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf), 00456 active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), 00457 active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length, 00458 rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); 00459 // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer 00460 if (tx_handle_retval == -1) { 00461 mac_sap_cca_fail_cb(rf_ptr); 00462 return PHY_TX_NOT_ALLOWED; 00463 } 00464 // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back 00465 // to queue by using CCA fail event 00466 if (tx_handle_retval == -3) { 00467 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00468 return PHY_TX_NOT_ALLOWED; 00469 } else if (tx_handle_retval == -2) { 00470 mac_tx_done_state_set(rf_ptr, MAC_UNKNOWN_DESTINATION); 00471 return PHY_TX_NOT_ALLOWED; 00472 } 00473 if (active_buf->csma_periods_left > 0) { 00474 active_buf->csma_periods_left--; 00475 active_buf->tx_time += rf_ptr->multi_cca_interval; 00476 mac_pd_sap_set_phy_tx_time(rf_ptr, active_buf->tx_time, true); 00477 return PHY_RESTART_CSMA; 00478 } 00479 } 00480 00481 return 0; 00482 } 00483 00484 // 00485 bool waiting_ack = false; 00486 00487 00488 if (rf_ptr->mac_ack_tx_active) { 00489 mac_data_ack_tx_finish(rf_ptr); 00490 return 0; 00491 } else { 00492 // Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event 00493 // Do not update CCA count when CCA_OK is received, PHY_LINK_TX_SUCCESS will update it 00494 if ((status != PHY_LINK_TX_DONE) && (status != PHY_LINK_TX_DONE_PENDING) && (status != PHY_LINK_CCA_OK)) { 00495 /* For PHY_LINK_TX_SUCCESS and PHY_LINK_CCA_FAIL cca_retry must always be > 0. 00496 * PHY_LINK_TX_FAIL either happened during transmission or when waiting Ack -> we must use the CCA count given by PHY. 00497 */ 00498 if ((cca_retry == 0) && (status != PHY_LINK_TX_FAIL)) { 00499 cca_retry = 1; 00500 } 00501 rf_ptr->mac_tx_status.cca_cnt += cca_retry; 00502 rf_ptr->mac_cca_retry += cca_retry; 00503 } 00504 rf_ptr->mac_tx_status.retry += tx_retry; 00505 rf_ptr->mac_tx_retry += tx_retry; 00506 timer_mac_stop(rf_ptr); 00507 } 00508 00509 switch (status) { 00510 case PHY_LINK_TX_SUCCESS: 00511 if (rf_ptr->macTxRequestAck) { 00512 timer_mac_start(rf_ptr, MAC_TIMER_ACK, rf_ptr->mac_ack_wait_duration); /*wait for ACK 1 ms*/ 00513 waiting_ack = true; 00514 } else { 00515 //TODO CHECK this is MAC_TX_ PERMIT OK 00516 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00517 } 00518 break; 00519 00520 case PHY_LINK_CCA_FAIL: 00521 mac_sap_cca_fail_cb(rf_ptr); 00522 break; 00523 00524 case PHY_LINK_CCA_OK: 00525 break; 00526 00527 case PHY_LINK_TX_FAIL: 00528 mac_sap_no_ack_cb(rf_ptr); 00529 break; 00530 00531 case PHY_LINK_TX_DONE: 00532 //mac_tx_result 00533 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00534 break; 00535 00536 case PHY_LINK_TX_DONE_PENDING: 00537 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE_PENDING); 00538 break; 00539 00540 default: 00541 break; 00542 } 00543 if (rf_ptr->fhss_api) { 00544 bool tx_is_done = false; 00545 if (rf_ptr->mac_tx_result == MAC_TX_DONE) { 00546 tx_is_done = true; 00547 } 00548 if (rf_ptr->active_pd_data_request->asynch_request == false) { 00549 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_is_done, rf_ptr->active_pd_data_request->msduHandle); 00550 } 00551 } 00552 return 0; 00553 } 00554 00555 00556 static int8_t mac_data_interface_tx_done_by_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_parsed_frame_t *buf) 00557 { 00558 00559 if (!rf_ptr->macRfRadioTxActive || !rf_ptr->active_pd_data_request || rf_ptr->active_pd_data_request->fcf_dsn.DSN != buf->fcf_dsn.DSN) { 00560 return -1; 00561 } 00562 00563 timer_mac_stop(rf_ptr); 00564 if (buf->fcf_dsn.framePending) { 00565 rf_ptr->mac_tx_result = MAC_TX_DONE_PENDING; 00566 } else { 00567 rf_ptr->mac_tx_result = MAC_TX_DONE; 00568 } 00569 rf_ptr->macRfRadioTxActive = false; 00570 rf_ptr->macTxProcessActive = false; 00571 mcps_sap_pd_ack(buf); 00572 00573 if (rf_ptr->fhss_api) { 00574 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle); 00575 } 00576 return 0; 00577 } 00578 00579 static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr) 00580 { 00581 if (!rf_ptr->active_pd_data_request || !rf_ptr->active_pd_data_request->fcf_dsn.ackRequested) { 00582 return false; //No active Data request anymore or no ACK request for current TX 00583 } 00584 00585 if (fcf_dsn->frameVersion != rf_ptr->active_pd_data_request->fcf_dsn.frameVersion) { 00586 return false; 00587 } 00588 00589 if (fcf_dsn->frameVersion == MAC_FRAME_VERSION_2015) { 00590 00591 //Validate ACK SRC address mode and address to Active TX dst address 00592 if (rf_ptr->active_pd_data_request->fcf_dsn.DstAddrMode != fcf_dsn->SrcAddrMode) { 00593 return false; 00594 } 00595 00596 if (fcf_dsn->SrcAddrMode) { 00597 uint8_t srcAddress[8]; 00598 uint8_t address_length = mac_address_length(fcf_dsn->SrcAddrMode); 00599 mac_header_get_src_address(fcf_dsn, data_ptr, srcAddress); 00600 if (memcmp(srcAddress, rf_ptr->active_pd_data_request->DstAddr, address_length)) { 00601 return false; 00602 } 00603 } 00604 00605 //Validate ACK DST address mode and address to Active TX src address 00606 if (rf_ptr->active_pd_data_request->fcf_dsn.SrcAddrMode != fcf_dsn->DstAddrMode) { 00607 return false; 00608 } 00609 00610 if (fcf_dsn->DstAddrMode) { 00611 uint8_t dstAddress[8]; 00612 uint8_t address_length = mac_address_length(fcf_dsn->DstAddrMode); 00613 mac_header_get_dst_address(fcf_dsn, data_ptr, dstAddress); 00614 if (memcmp(dstAddress, rf_ptr->active_pd_data_request->SrcAddr, address_length)) { 00615 return false; 00616 } 00617 } 00618 00619 if (rf_ptr->active_pd_data_request->fcf_dsn.sequenceNumberSuppress != fcf_dsn->sequenceNumberSuppress) { 00620 return false; //sequence number validation not correct 00621 } 00622 00623 if (!fcf_dsn->sequenceNumberSuppress && (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN)) { 00624 return false; 00625 } 00626 return true; 00627 } 00628 00629 if (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN) { 00630 return false; 00631 } 00632 return true; 00633 } 00634 00635 static int8_t mac_pd_sap_validate_fcf(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) 00636 { 00637 switch (fcf_read->frametype) { 00638 case FC_DATA_FRAME: 00639 if (fcf_read->SrcAddrMode == MAC_ADDR_MODE_NONE) { 00640 return -1; 00641 } else if (fcf_read->DstAddrMode == MAC_ADDR_MODE_NONE && fcf_read->frameVersion != MAC_FRAME_VERSION_2015) { 00642 return -1; 00643 } 00644 break; 00645 case FC_BEACON_FRAME: 00646 if (fcf_read->SrcAddrMode == MAC_ADDR_MODE_NONE || fcf_read->DstAddrMode != MAC_ADDR_MODE_NONE) { 00647 return -1; 00648 } 00649 break; 00650 case FC_ACK_FRAME: 00651 // Only accept version 2015 Acks 00652 if (fcf_read->frameVersion != MAC_FRAME_VERSION_2015) { 00653 return -1; 00654 } 00655 //Validate Ack doesn't request Ack 00656 if (fcf_read->ackRequested) { 00657 return -1; 00658 } 00659 //Validate ACK 00660 if (!mac_pd_sap_ack_validation(rf_ptr, fcf_read, pd_data_ind->data_ptr)) { 00661 return -1; 00662 } 00663 break; 00664 case FC_CMD_FRAME: 00665 break; 00666 default: 00667 return -1; 00668 } 00669 return 0; 00670 } 00671 00672 static bool mac_pd_sap_panid_filter_common(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint16_t own_pan_id) 00673 { 00674 // Beacon frames shouldn't be dropped as they might be used by load balancing 00675 if (fcf_read->frametype == MAC_FRAME_BEACON) { 00676 return true; 00677 } 00678 if (own_pan_id == 0xffff) { 00679 return true; 00680 } 00681 uint16_t dst_pan_id = mac_header_get_dst_panid(fcf_read, mac_header, 0xffff); 00682 if (dst_pan_id == 0xffff) { 00683 return true; 00684 } 00685 if (own_pan_id == dst_pan_id) { 00686 return true; 00687 } 00688 return false; 00689 } 00690 00691 static bool mac_pd_sap_panid_v2_filter(const uint8_t *ptr, const mac_fcf_sequence_t *fcf_read, uint16_t pan_id) 00692 { 00693 if ((fcf_read->DstAddrMode == MAC_ADDR_MODE_NONE) && (fcf_read->frametype == FC_DATA_FRAME || fcf_read->frametype == FC_CMD_FRAME)) { 00694 return true; 00695 } 00696 if ((fcf_read->DstAddrMode == MAC_ADDR_MODE_64_BIT) && (fcf_read->SrcAddrMode == MAC_ADDR_MODE_64_BIT) && fcf_read->intraPan) { 00697 return true; 00698 } 00699 return mac_pd_sap_panid_filter_common(ptr, fcf_read, pan_id); 00700 } 00701 00702 static bool mac_pd_sap_addr_filter_common(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr) 00703 { 00704 uint8_t cmp_table[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 00705 uint8_t dst_addr[8]; 00706 mac_header_get_dst_address(fcf_read, mac_header, dst_addr); 00707 00708 switch (fcf_read->DstAddrMode) { 00709 case MAC_ADDR_MODE_16_BIT: 00710 if (!memcmp(dst_addr, cmp_table, 2)) { 00711 return true; 00712 } 00713 uint8_t temp[2]; 00714 common_write_16_bit(mac_16bit_addr, temp); 00715 if (!memcmp(temp, dst_addr, 2)) { 00716 return true; 00717 } 00718 break; 00719 case MAC_ADDR_MODE_64_BIT: 00720 if (!memcmp(dst_addr, cmp_table, 8)) { 00721 return true; 00722 } 00723 if (!memcmp(mac_64bit_addr, dst_addr, 8)) { 00724 return true; 00725 } 00726 break; 00727 case MAC_ADDR_MODE_NONE: 00728 return true; 00729 break; 00730 default: 00731 break; 00732 } 00733 return false; 00734 } 00735 00736 static bool mac_pd_sap_addr_v2_filter(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr) 00737 { 00738 return mac_pd_sap_addr_filter_common(mac_header, fcf_read, mac_64bit_addr, mac_16bit_addr); 00739 } 00740 00741 static bool mac_pd_sap_rx_filter(const uint8_t *mac_header, const mac_fcf_sequence_t *fcf_read, uint8_t phy_filter_mask, uint8_t *mac_64bit_addr, uint16_t mac_16bit_addr, uint16_t pan_id) 00742 { 00743 uint8_t version = fcf_read->frameVersion; 00744 00745 if (version == MAC_FRAME_VERSION_2015 && !(phy_filter_mask & (1 << MAC_FRAME_VERSION_2))) { 00746 if (!mac_pd_sap_panid_v2_filter(mac_header, fcf_read, pan_id)) { 00747 return false; 00748 } 00749 if (!mac_pd_sap_addr_v2_filter(mac_header, fcf_read, mac_64bit_addr, mac_16bit_addr)) { 00750 return false; 00751 } 00752 } 00753 return true; 00754 } 00755 00756 static int8_t mac_pd_sap_generate_ack(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) 00757 { 00758 //Generate ACK when Extension is enabled and ACK is requested only for version 2 frames. 00759 if (!rf_ptr->mac_extension_enabled || !fcf_read->ackRequested || (fcf_read->frameVersion != MAC_FRAME_VERSION_2015)) { 00760 return 0; 00761 } 00762 if (rf_ptr->mac_ack_tx_active) { 00763 return -1; 00764 } 00765 00766 mcps_ack_data_payload_t ack_payload; 00767 mac_api_t *mac_api = get_sw_mac_api(rf_ptr); 00768 mac_api->enhanced_ack_data_req_cb(mac_api, &ack_payload, pd_data_ind->dbm, pd_data_ind->link_quality); 00769 //Calculate Delta time 00770 00771 if (mcps_generic_ack_data_request_init(rf_ptr, fcf_read, pd_data_ind->data_ptr, &ack_payload) != 0) { 00772 return -1; 00773 } 00774 00775 if (rf_ptr->enhanced_ack_buffer.aux_header.securityLevel == 0 || mac_sec_mib_device_description_get(rf_ptr, rf_ptr->enhanced_ack_buffer.DstAddr, rf_ptr->enhanced_ack_buffer.fcf_dsn.DstAddrMode, rf_ptr->enhanced_ack_buffer.DstPANId)) { 00776 rf_ptr->ack_tx_possible = true; 00777 } else { 00778 rf_ptr->ack_tx_possible = false; 00779 } 00780 00781 return mcps_generic_ack_build(rf_ptr, true); 00782 } 00783 00784 static mac_pre_parsed_frame_t *mac_pd_sap_allocate_receive_buffer(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf_read, arm_pd_sap_generic_ind_t *pd_data_ind) 00785 { 00786 mac_pre_parsed_frame_t *buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); 00787 if (!buffer) { 00788 return NULL; 00789 } 00790 00791 //Copy Pre Parsed values 00792 buffer->fcf_dsn = *fcf_read; 00793 buffer->timestamp = mac_pd_sap_get_phy_rx_time(rf_ptr); 00794 buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); 00795 /* Set default flags */ 00796 buffer->dbm = pd_data_ind->dbm; 00797 buffer->LQI = pd_data_ind->link_quality; 00798 buffer->mac_class_ptr = rf_ptr; 00799 return buffer; 00800 } 00801 00802 static int8_t mac_pd_sap_parse_length_fields(mac_pre_parsed_frame_t *buffer, arm_pd_sap_generic_ind_t *pd_data_ind, const uint8_t *parse_ptr) 00803 { 00804 if (buffer->fcf_dsn.frametype > FC_CMD_FRAME) { 00805 return -1; 00806 } 00807 buffer->mac_header_length = parse_ptr - pd_data_ind->data_ptr; 00808 int16_t length = pd_data_ind->data_len; 00809 buffer->mac_header_length += mac_header_address_length(&buffer->fcf_dsn); 00810 length -= buffer->mac_header_length; 00811 if (length < 0) { 00812 return -1; 00813 } 00814 00815 buffer->mac_payload_length = (buffer->frameLength - buffer->mac_header_length); 00816 00817 if (buffer->fcf_dsn.securityEnabled) { 00818 //Read KEYID Mode 00819 uint8_t key_id_mode, security_level, mic_len; 00820 uint8_t *security_ptr = &buffer->buf[buffer->mac_header_length]; 00821 uint8_t auxBaseHeader = *security_ptr; 00822 key_id_mode = (auxBaseHeader >> 3) & 3; 00823 security_level = auxBaseHeader & 7; 00824 00825 switch (key_id_mode) { 00826 case MAC_KEY_ID_MODE_IMPLICIT: 00827 if (security_level) { 00828 buffer->security_aux_header_length = 5; 00829 } else { 00830 buffer->security_aux_header_length = 1; 00831 } 00832 break; 00833 case MAC_KEY_ID_MODE_IDX: 00834 buffer->security_aux_header_length = 6; 00835 break; 00836 case MAC_KEY_ID_MODE_SRC4_IDX: 00837 buffer->security_aux_header_length = 10; 00838 break; 00839 default: 00840 buffer->security_aux_header_length = 14; 00841 break; 00842 } 00843 00844 length -= buffer->security_aux_header_length; 00845 mic_len = mac_security_mic_length_get(security_level); 00846 00847 length -= mic_len; 00848 00849 //Verify that data length is not negative 00850 if (length < 0) { 00851 return -1; 00852 } 00853 00854 buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); 00855 } 00856 //Do not accept command frame with length 0 00857 if (buffer->fcf_dsn.frametype == FC_CMD_FRAME && length == 0) { 00858 return -1; 00859 } 00860 return 0; 00861 } 00862 00863 int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) 00864 { 00865 protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s *)identifier; 00866 00867 if (!rf_ptr || !message) { 00868 return -1; 00869 } 00870 00871 if (!rf_ptr->macUpState) { 00872 return -2; 00873 } 00874 00875 if (message->id == MAC15_4_PD_SAP_DATA_IND) { 00876 arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); 00877 if (pd_data_ind->data_len < 3) { 00878 return -1; 00879 } 00880 00881 mac_fcf_sequence_t fcf_read; 00882 const uint8_t *ptr = mac_header_parse_fcf_dsn(&fcf_read, pd_data_ind->data_ptr); 00883 00884 mac_pre_parsed_frame_t *buffer = mac_pd_sap_allocate_receive_buffer(rf_ptr, &fcf_read, pd_data_ind); 00885 if (buffer && mac_filter_modify_link_quality(rf_ptr->mac_interface_id, buffer) == 1) { 00886 goto ERROR_HANDLER; 00887 } 00888 if (!rf_ptr->macProminousMode) { 00889 if (mac_pd_sap_validate_fcf(rf_ptr, &fcf_read, pd_data_ind)) { 00890 goto ERROR_HANDLER; 00891 } 00892 if (!mac_pd_sap_rx_filter(pd_data_ind->data_ptr, &fcf_read, rf_ptr->mac_frame_filters, rf_ptr->mac64, rf_ptr->mac_short_address, rf_ptr->pan_id)) { 00893 goto ERROR_HANDLER; 00894 } 00895 if (mac_pd_sap_generate_ack(rf_ptr, &fcf_read, pd_data_ind)) { 00896 goto ERROR_HANDLER; 00897 } 00898 if (buffer) { 00899 if (mac_pd_sap_parse_length_fields(buffer, pd_data_ind, ptr)) { 00900 goto ERROR_HANDLER; 00901 } 00902 if (!mac_header_information_elements_parse(buffer)) { 00903 goto ERROR_HANDLER; 00904 } 00905 if (buffer->fcf_dsn.frametype == FC_ACK_FRAME) { 00906 if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) { 00907 mcps_sap_pre_parsed_frame_buffer_free(buffer); 00908 } 00909 return 0; 00910 } 00911 } 00912 } 00913 if (!buffer) { 00914 sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); 00915 return -3; 00916 } 00917 if (mcps_sap_pd_ind(buffer) == 0) { 00918 return 0; 00919 } 00920 ERROR_HANDLER: 00921 mcps_sap_pre_parsed_frame_buffer_free(buffer); 00922 sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); 00923 return -1; 00924 00925 } else if (message->id == MAC15_4_PD_SAP_DATA_TX_CONFIRM) { 00926 arm_pd_sap_15_4_confirm_with_params_t *pd_data_cnf = &(message->message.mac15_4_pd_sap_confirm); 00927 return mac_data_interface_tx_done_cb(rf_ptr, pd_data_cnf->status, pd_data_cnf->cca_retry, pd_data_cnf->tx_retry); 00928 } 00929 00930 return -1; 00931 } 00932 00933 void mac_pd_sap_rf_low_level_function_set(void *mac_ptr, void *driver) 00934 { 00935 arm_device_driver_list_s *driver_ptr = (arm_device_driver_list_s *)driver; 00936 driver_ptr->phy_sap_identifier = (protocol_interface_rf_mac_setup_s *)mac_ptr; 00937 driver_ptr->phy_sap_upper_cb = mac_pd_sap_data_cb; 00938 } 00939
Generated on Tue Jul 12 2022 13:54:31 by
1.7.2