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-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_mlme.h" 00034 #include "MAC/IEEE802_15_4/mac_filter.h" 00035 #include "MAC/IEEE802_15_4/mac_mcps_sap.h" 00036 #include "MAC/rf_driver_storage.h" 00037 00038 /* Define TX Timeot Period */ 00039 // Hardcoded to 1200ms. Should be changed dynamic: (FHSS) channel retries needs longer timeout 00040 #define NWKTX_TIMEOUT_PERIOD (1200*20) 00041 00042 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); 00043 00044 void mac_csma_param_init(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00045 { 00046 rf_mac_setup->macCurrentBE = rf_mac_setup->macMinBE; 00047 } 00048 00049 static void mac_csma_BE_update(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00050 { 00051 if (rf_mac_setup->macCurrentBE < rf_mac_setup->macMaxBE) { 00052 rf_mac_setup->macCurrentBE++; 00053 } 00054 } 00055 00056 // 8-bit because maxBE is maximum 8 (according to 802.15.4) 00057 static uint8_t mac_csma_random_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00058 { 00059 return randLIB_get_random_in_range(0, (1 << rf_mac_setup->macCurrentBE) - 1); 00060 } 00061 00062 static uint16_t mac_csma_backoff_period_convert_to50us(uint8_t random, uint8_t backoff_period_in_10us) 00063 { 00064 return (random * backoff_period_in_10us) / 5; 00065 } 00066 00067 static void mac_csma_backoff_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00068 { 00069 uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); 00070 uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff, rf_mac_setup->backoff_period_in_10us); 00071 if (backoff_slots == 0) { 00072 backoff_slots = 1; 00073 } 00074 00075 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, backoff_slots); 00076 } 00077 00078 00079 uint32_t mac_csma_backoff_get(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00080 { 00081 uint8_t backoff = mac_csma_random_backoff_get(rf_mac_setup); 00082 uint32_t backoff_in_us; 00083 //Multiple aUnitBackoffPeriod symbol time 00084 if (rf_mac_setup->rf_csma_extension_supported) { 00085 backoff_in_us = backoff * rf_mac_setup->aUnitBackoffPeriod * rf_mac_setup->symbol_time_us; 00086 } else { 00087 backoff_in_us = backoff * rf_mac_setup->backoff_period_in_10us * 10; 00088 } 00089 00090 if (backoff_in_us == 0) { 00091 backoff_in_us = 1; 00092 } 00093 return backoff_in_us; 00094 } 00095 00096 00097 /* 00098 * \file mac_pd_sap.c 00099 * \brief Add short description about this file!!! 00100 * 00101 */ 00102 static bool mac_data_interface_read_last_ack_pending_status(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00103 { 00104 uint8_t pending = 1; 00105 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00106 if (dev_driver->extension) { 00107 dev_driver->extension(PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS, &pending); 00108 } 00109 00110 00111 return pending; 00112 00113 } 00114 00115 static void mac_tx_done_state_set(protocol_interface_rf_mac_setup_s *rf_ptr, mac_event_t event ) 00116 { 00117 rf_ptr->mac_tx_result = event; 00118 00119 if(event == MAC_TX_DONE || event == MAC_TX_DONE_PENDING) { 00120 00121 } else { 00122 rf_ptr->macTxRequestAck = false; 00123 } 00124 rf_ptr->macRfRadioTxActive = false; 00125 rf_ptr->macTxProcessActive = false; 00126 mcps_sap_pd_confirm(rf_ptr); 00127 } 00128 00129 static void mac_data_interface_tx_to_cb(protocol_interface_rf_mac_setup_s *rf_ptr) 00130 { 00131 rf_ptr->macRfRadioTxActive = false; 00132 mac_tx_done_state_set(rf_ptr, MAC_TX_TIMEOUT); 00133 } 00134 00135 int8_t mac_plme_cca_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) { 00136 dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; 00137 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00138 00139 00140 if (dev_driver->arm_net_virtual_tx_cb) { 00141 if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { 00142 rf_mac_setup->macRfRadioTxActive = true; 00143 timer_mac_start(rf_mac_setup, MAC_TX_TIMEOUT, NWKTX_TIMEOUT_PERIOD); /*Start Timeout timer for virtual packet loss*/ 00144 } else { 00145 mac_data_interface_tx_to_cb(rf_mac_setup); 00146 } 00147 return 0; 00148 } 00149 00150 if (dev_driver->tx(tx_buf->buf, tx_buf->len, 1, PHY_LAYER_PAYLOAD) == 0) { 00151 rf_mac_setup->macRfRadioTxActive = true; 00152 return 0; 00153 } 00154 return -1; 00155 } 00156 00157 /** 00158 * Send a buffer to the MAC. 00159 * Used by the protocol core. 00160 * 00161 * \param buf pointer to buffer 00162 * 00163 */ 00164 int8_t mac_pd_sap_req(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00165 { 00166 if (!rf_mac_setup || !rf_mac_setup->macUpState || !rf_mac_setup->active_pd_data_request) { 00167 return -1; 00168 } 00169 00170 rf_mac_setup->mac_cca_retry = 0; 00171 rf_mac_setup->mac_tx_retry = 0; 00172 rf_mac_setup->macTxProcessActive = true; 00173 mac_csma_param_init(rf_mac_setup); 00174 mac_csma_backoff_start(rf_mac_setup); 00175 return 0; 00176 } 00177 00178 00179 /** 00180 * Set PHY TX time. 00181 * 00182 * \param rf_mac_setup pointer to MAC. 00183 * \param tx_time TX timestamp to be set. 00184 * 00185 */ 00186 void mac_pd_sap_set_phy_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t tx_time, bool cca_enabled) 00187 { 00188 // With TX time set to zero, PHY sends immediately 00189 if (!tx_time) { 00190 tx_time++; 00191 } 00192 phy_csma_params_t csma_params; 00193 csma_params.backoff_time = tx_time; 00194 csma_params.cca_enabled = cca_enabled; 00195 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t*) &csma_params); 00196 } 00197 00198 /** 00199 * Get PHY RX time. 00200 * 00201 * \param rf_mac_setup pointer to MAC 00202 * \return Timestamp of last PHY reception 00203 * 00204 */ 00205 static uint32_t mac_pd_sap_get_phy_rx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00206 { 00207 uint8_t rx_time_buffer[4]; 00208 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_READ_RX_TIME, rx_time_buffer); 00209 return common_read_32_bit(rx_time_buffer); 00210 } 00211 00212 /** 00213 * Run Mac data interface state Machine for mac timer. 00214 * 00215 */ 00216 void mac_pd_sap_state_machine(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00217 { 00218 00219 if (rf_mac_setup->macUpState && rf_mac_setup->macTxProcessActive) { 00220 00221 if (rf_mac_setup->mac_tx_result == MAC_TIMER_CCA) { 00222 if (rf_mac_setup->fhss_api) { 00223 uint8_t *synch_info = NULL; 00224 mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request; 00225 if (!active_buf) { 00226 return; 00227 } 00228 bool cca_enabled; 00229 if (active_buf->fcf_dsn.frametype == MAC_FRAME_ACK) { 00230 cca_enabled = false; 00231 } else { 00232 cca_enabled = true; 00233 } 00234 00235 mac_pd_sap_set_phy_tx_time(rf_mac_setup, active_buf->tx_time, cca_enabled); 00236 if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 00237 // FHSS synchronization info is written in the end of transmitted (Beacon) buffer 00238 dev_driver_tx_buffer_s *tx_buf = &rf_mac_setup->dev_driver_tx_buffer; 00239 synch_info = tx_buf->buf + rf_mac_setup->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; 00240 rf_mac_setup->fhss_api->write_synch_info(rf_mac_setup->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); 00241 } 00242 // Change to destination channel and write synchronization info to Beacon frames here 00243 int tx_handle_retval = rf_mac_setup->fhss_api->tx_handle(rf_mac_setup->fhss_api, !mac_is_ack_request_set(active_buf), 00244 active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), 00245 active_buf->mac_payload_length, rf_mac_setup->dev_driver->phy_driver->phy_header_length, 00246 rf_mac_setup->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); 00247 // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer 00248 if (tx_handle_retval == -1) { 00249 timer_mac_start(rf_mac_setup, MAC_TIMER_CCA, randLIB_get_random_in_range(20, 400) + 1); 00250 return; 00251 } 00252 // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back 00253 // to queue by using CCA fail event 00254 if (tx_handle_retval == -3) { 00255 mac_tx_done_state_set(rf_mac_setup, MAC_CCA_FAIL); 00256 return; 00257 } 00258 } 00259 if (mac_plme_cca_req(rf_mac_setup) != 0) { 00260 mac_csma_backoff_start(rf_mac_setup); 00261 } 00262 } else if (rf_mac_setup->mac_tx_result == MAC_TX_TIMEOUT) { 00263 mac_data_interface_tx_to_cb(rf_mac_setup); 00264 } else if (rf_mac_setup->mac_tx_result == MAC_TIMER_ACK) { 00265 mac_data_interface_tx_done_cb(rf_mac_setup,PHY_LINK_TX_FAIL, 0, 0 ); 00266 } 00267 } 00268 } 00269 00270 static void mac_sap_cca_fail_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { 00271 rf_ptr->macRfRadioTxActive = false; 00272 if (rf_ptr->mac_cca_retry > rf_ptr->macMaxCSMABackoffs || (rf_ptr->active_pd_data_request && rf_ptr->active_pd_data_request->asynch_request)) { 00273 //Send MAC_CCA_FAIL 00274 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00275 } else { 00276 timer_mac_stop(rf_ptr); 00277 mac_csma_BE_update(rf_ptr); 00278 if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { 00279 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00280 } 00281 } 00282 } 00283 00284 //static uint16_t mac_get_retry_period(protocol_interface_rf_mac_setup_s *rf_ptr) 00285 //{ 00286 // if (rf_ptr->fhss_api && rf_ptr->fhss_api->get_retry_period) { 00287 // 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); 00288 // } 00289 // uint8_t backoff_length = mac_csma_random_backoff_get(rf_ptr); 00290 // uint16_t backoff_slots = mac_csma_backoff_period_convert_to50us(backoff_length, rf_ptr->backoff_period_in_10us); 00291 // if (backoff_slots == 0) { 00292 // backoff_slots = 1; 00293 // } 00294 // return backoff_slots; 00295 //} 00296 00297 static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) { 00298 rf_ptr->macRfRadioTxActive = false; 00299 if (rf_ptr->mac_tx_retry < rf_ptr->mac_mlme_retry_max) { 00300 rf_ptr->mac_cca_retry = 0; 00301 rf_ptr->mac_tx_retry++; //Update retry counter 00302 mac_csma_param_init(rf_ptr); 00303 rf_ptr->mac_tx_status.retry++; 00304 /*Send retry using random interval*/ 00305 if (mcps_pd_data_rebuild(rf_ptr, rf_ptr->active_pd_data_request) ) { 00306 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00307 } 00308 00309 } else { 00310 //Send TX Fail event 00311 // rf_mac_setup->ip_tx_active->bad_channel = rf_mac_setup->mac_channel; 00312 mac_tx_done_state_set(rf_ptr, MAC_TX_FAIL); 00313 } 00314 } 00315 00316 static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter) 00317 { 00318 if((current_counter - packet_counter) >= 2) { 00319 return true; 00320 } 00321 return false; 00322 } 00323 00324 00325 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) 00326 { 00327 00328 if (!rf_ptr->macRfRadioTxActive) { 00329 return -1; 00330 } 00331 00332 if (status == PHY_LINK_CCA_PREPARE) { 00333 if (rf_ptr->fhss_api) { 00334 if (rf_ptr->mac_ack_tx_active) { 00335 return 0; 00336 } 00337 mac_pre_build_frame_t *active_buf = rf_ptr->active_pd_data_request; 00338 if (!active_buf) { 00339 return -1; 00340 } 00341 00342 if (active_buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 00343 // FHSS synchronization info is written in the end of transmitted (Beacon) buffer 00344 dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer; 00345 uint8_t *synch_info = tx_buf->buf + rf_ptr->dev_driver->phy_driver->phy_header_length + tx_buf->len - FHSS_SYNCH_INFO_LENGTH; 00346 rf_ptr->fhss_api->write_synch_info(rf_ptr->fhss_api, synch_info, 0, FHSS_SYNCH_FRAME, 0); 00347 } 00348 if (active_buf->asynch_request == false) { 00349 // Change to destination channel and write synchronization info to Beacon frames here 00350 int tx_handle_retval = rf_ptr->fhss_api->tx_handle(rf_ptr->fhss_api, !mac_is_ack_request_set(active_buf), 00351 active_buf->DstAddr, mac_convert_frame_type_to_fhss(active_buf->fcf_dsn.frametype), 00352 active_buf->mac_payload_length, rf_ptr->dev_driver->phy_driver->phy_header_length, 00353 rf_ptr->dev_driver->phy_driver->phy_tail_length, active_buf->tx_time); 00354 // When FHSS TX handle returns -1, transmission of the packet is currently not allowed -> restart CCA timer 00355 if (tx_handle_retval == -1) { 00356 mac_sap_cca_fail_cb(rf_ptr); 00357 return -2; 00358 } 00359 // When FHSS TX handle returns -3, we are trying to transmit broadcast packet on unicast channel -> push back 00360 // to queue by using CCA fail event 00361 if (tx_handle_retval == -3) { 00362 mac_tx_done_state_set(rf_ptr, MAC_CCA_FAIL); 00363 return -3; 00364 } 00365 } 00366 } 00367 return 0; 00368 } 00369 00370 // 00371 bool waiting_ack = false; 00372 00373 00374 if (rf_ptr->mac_ack_tx_active) { 00375 rf_ptr->mac_ack_tx_active = false; 00376 if (rf_ptr->active_pd_data_request) { 00377 00378 if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) { 00379 uint32_t current_counter = mac_mlme_framecounter_get(rf_ptr); 00380 if (mac_data_counter_too_small(current_counter, rf_ptr->active_pd_data_request->aux_header.frameCounter)) { 00381 rf_ptr->active_pd_data_request->aux_header.frameCounter = current_counter; 00382 mac_mlme_framecounter_increment(rf_ptr); 00383 } 00384 } 00385 //GEN TX failure 00386 mac_sap_cca_fail_cb(rf_ptr); 00387 } 00388 return 0; 00389 } else { 00390 // Do not update CCA count when Ack is received, it was already updated with PHY_LINK_TX_SUCCESS event 00391 if ((status != PHY_LINK_TX_DONE) && (status != PHY_LINK_TX_DONE_PENDING)) { 00392 /* For PHY_LINK_TX_SUCCESS and PHY_LINK_CCA_FAIL cca_retry must always be > 0. 00393 * PHY_LINK_TX_FAIL either happened during transmission or when waiting Ack -> we must use the CCA count given by PHY. 00394 */ 00395 if ((cca_retry == 0) && (status != PHY_LINK_TX_FAIL)) { 00396 cca_retry = 1; 00397 } 00398 rf_ptr->mac_tx_status.cca_cnt += cca_retry; 00399 rf_ptr->mac_cca_retry += cca_retry; 00400 } 00401 rf_ptr->mac_tx_status.retry += tx_retry; 00402 rf_ptr->mac_tx_retry += tx_retry; 00403 timer_mac_stop(rf_ptr); 00404 } 00405 00406 switch (status) { 00407 case PHY_LINK_TX_SUCCESS: 00408 if (rf_ptr->macTxRequestAck) { 00409 timer_mac_start(rf_ptr, MAC_TIMER_ACK, rf_ptr->mac_ack_wait_duration); /*wait for ACK 1 ms*/ 00410 waiting_ack = true; 00411 } else { 00412 //TODO CHECK this is MAC_TX_ PERMIT OK 00413 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00414 } 00415 break; 00416 00417 case PHY_LINK_CCA_FAIL: 00418 mac_sap_cca_fail_cb(rf_ptr); 00419 break; 00420 00421 case PHY_LINK_TX_FAIL: 00422 mac_sap_no_ack_cb(rf_ptr); 00423 break; 00424 00425 case PHY_LINK_TX_DONE: 00426 //mac_tx_result 00427 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE); 00428 break; 00429 00430 case PHY_LINK_TX_DONE_PENDING: 00431 mac_tx_done_state_set(rf_ptr, MAC_TX_DONE_PENDING); 00432 break; 00433 00434 default: 00435 break; 00436 } 00437 if (rf_ptr->fhss_api) { 00438 bool tx_is_done = false; 00439 if (rf_ptr->mac_tx_result == MAC_TX_DONE) { 00440 tx_is_done = true; 00441 } 00442 if (rf_ptr->active_pd_data_request->asynch_request == false) { 00443 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, waiting_ack, tx_is_done, rf_ptr->active_pd_data_request->msduHandle); 00444 } 00445 } 00446 return 0; 00447 } 00448 00449 00450 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) 00451 { 00452 00453 if (!rf_ptr->macRfRadioTxActive) { 00454 return -1; 00455 } 00456 00457 timer_mac_stop(rf_ptr); 00458 if (buf->fcf_dsn.framePending) { 00459 rf_ptr->mac_tx_result = MAC_TX_DONE_PENDING; 00460 } else { 00461 rf_ptr->mac_tx_result = MAC_TX_DONE; 00462 } 00463 rf_ptr->macRfRadioTxActive = false; 00464 rf_ptr->macTxProcessActive = false; 00465 mcps_sap_pd_ack(buf); 00466 00467 if (rf_ptr->fhss_api) { 00468 if (rf_ptr->active_pd_data_request->asynch_request == false) { 00469 rf_ptr->fhss_api->data_tx_done(rf_ptr->fhss_api, false, true, rf_ptr->active_pd_data_request->msduHandle); 00470 } 00471 } 00472 return 0; 00473 } 00474 00475 static bool mac_pd_sap_ack_validation(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf_sequence_t *fcf_dsn, const uint8_t *data_ptr) 00476 { 00477 if (!rf_ptr->active_pd_data_request || !rf_ptr->active_pd_data_request->fcf_dsn.ackRequested) { 00478 return false; //No active Data request anymore or no ACK request for current TX 00479 } 00480 00481 if (fcf_dsn->frameVersion != rf_ptr->active_pd_data_request->fcf_dsn.frameVersion) { 00482 return false; 00483 } 00484 00485 if (fcf_dsn->frameVersion == MAC_FRAME_VERSION_2015) { 00486 00487 //Validate ACK SRC address mode and address to Active TX dst address 00488 if (rf_ptr->active_pd_data_request->fcf_dsn.DstAddrMode != fcf_dsn->SrcAddrMode) { 00489 return false; 00490 } 00491 00492 if (fcf_dsn->SrcAddrMode) { 00493 uint8_t srcAddress[8]; 00494 uint8_t address_length = mac_address_length(fcf_dsn->SrcAddrMode); 00495 mac_header_get_src_address(fcf_dsn, data_ptr, srcAddress); 00496 if (memcmp(srcAddress, rf_ptr->active_pd_data_request->DstAddr, address_length)) { 00497 return false; 00498 } 00499 } 00500 00501 //Validate ACK DST address mode and address to Active TX src address 00502 if (rf_ptr->active_pd_data_request->fcf_dsn.SrcAddrMode != fcf_dsn->DstAddrMode) { 00503 return false; 00504 } 00505 00506 if (fcf_dsn->DstAddrMode) { 00507 uint8_t dstAddress[8]; 00508 uint8_t address_length = mac_address_length(fcf_dsn->DstAddrMode); 00509 mac_header_get_dst_address(fcf_dsn, data_ptr, dstAddress); 00510 if (memcmp(dstAddress, rf_ptr->active_pd_data_request->SrcAddr, address_length)) { 00511 return false; 00512 } 00513 } 00514 00515 if (rf_ptr->active_pd_data_request->fcf_dsn.sequenceNumberSuppress != fcf_dsn->sequenceNumberSuppress) { 00516 return false; //sequence number validation not correct 00517 } 00518 00519 if (!fcf_dsn->sequenceNumberSuppress && (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN)) { 00520 return false; 00521 } 00522 return true; 00523 } 00524 00525 if (rf_ptr->active_pd_data_request->fcf_dsn.DSN != fcf_dsn->DSN) { 00526 return false; 00527 } 00528 return true; 00529 } 00530 00531 int8_t mac_pd_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message) 00532 { 00533 protocol_interface_rf_mac_setup_s *rf_ptr = (protocol_interface_rf_mac_setup_s*)identifier; 00534 mac_pre_parsed_frame_t *buffer = NULL; 00535 00536 if (!rf_ptr || !message ) { 00537 return -1; 00538 } 00539 00540 if (!rf_ptr->macUpState) { 00541 return -2; 00542 } 00543 00544 if (message->id == MAC15_4_PD_SAP_DATA_IND) { 00545 const uint8_t *ptr; 00546 arm_pd_sap_generic_ind_t *pd_data_ind = &(message->message.generic_data_ind); 00547 00548 if (pd_data_ind->data_len < 3 ) { 00549 return -1; 00550 } 00551 ptr = pd_data_ind->data_ptr; 00552 00553 uint32_t time_stamp = 0; 00554 if (rf_ptr->rf_csma_extension_supported) { 00555 time_stamp = mac_pd_sap_get_phy_rx_time(rf_ptr); 00556 } 00557 mac_fcf_sequence_t fcf_read; 00558 ptr = mac_header_parse_fcf_dsn(&fcf_read, ptr); 00559 //Check PanID presents at header 00560 fcf_read.DstPanPresents = mac_dst_panid_present(&fcf_read); 00561 fcf_read.SrcPanPresents = mac_src_panid_present(&fcf_read); 00562 int16_t length = pd_data_ind->data_len; 00563 if (!rf_ptr->macProminousMode) { 00564 00565 //Unsupported Frame 00566 if (fcf_read.frametype > FC_CMD_FRAME || (fcf_read.frametype == FC_ACK_FRAME && fcf_read.frameVersion != MAC_FRAME_VERSION_2015)) { 00567 goto ERROR_HANDLER; 00568 } 00569 00570 switch (fcf_read.frametype) { 00571 case FC_DATA_FRAME: 00572 if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE) { 00573 return -1; 00574 } else if (fcf_read.DstAddrMode == MAC_ADDR_MODE_NONE && fcf_read.frameVersion != MAC_FRAME_VERSION_2015) { 00575 return -1; 00576 } 00577 break; 00578 case FC_BEACON_FRAME: 00579 if (fcf_read.SrcAddrMode == MAC_ADDR_MODE_NONE || fcf_read.DstAddrMode != MAC_ADDR_MODE_NONE) { 00580 return -1; 00581 } 00582 break; 00583 case FC_ACK_FRAME: 00584 //Validate here that we are waiting ack 00585 if (fcf_read.ackRequested) { 00586 return -1; 00587 } 00588 00589 //Validate ACK 00590 if (!mac_pd_sap_ack_validation(rf_ptr, &fcf_read, pd_data_ind->data_ptr)) { 00591 return -1; 00592 } 00593 break; 00594 00595 default: 00596 break; 00597 } 00598 00599 //Generate ACK when Extension is enabled and ACK is requested 00600 if (rf_ptr->mac_extension_enabled && fcf_read.ackRequested && fcf_read.frameVersion == MAC_FRAME_VERSION_2015) { 00601 //SEND ACK here 00602 if (rf_ptr->mac_ack_tx_active) { 00603 return -1; 00604 } 00605 00606 mcps_ack_data_payload_t ack_payload; 00607 mac_api_t *mac_api = get_sw_mac_api(rf_ptr); 00608 mac_api->enhanced_ack_data_req_cb(mac_api, &ack_payload, pd_data_ind->dbm, pd_data_ind->link_quality); 00609 //Calculate Delta time 00610 00611 if (mcps_generic_ack_build(rf_ptr, &fcf_read, pd_data_ind->data_ptr, &ack_payload, time_stamp) !=0) { 00612 return -1; 00613 } 00614 00615 rf_ptr->mac_ack_tx_active = true; 00616 } 00617 } 00618 00619 buffer = mcps_sap_pre_parsed_frame_buffer_get(pd_data_ind->data_ptr, pd_data_ind->data_len); 00620 00621 if (!buffer) { 00622 sw_mac_stats_update(rf_ptr, STAT_MAC_RX_DROP, 0); 00623 return -3; 00624 } 00625 00626 //Copy Pre Parsed values 00627 buffer->fcf_dsn = fcf_read; 00628 buffer->timestamp = time_stamp; 00629 00630 buffer->ack_pendinfg_status = mac_data_interface_read_last_ack_pending_status(rf_ptr); 00631 00632 00633 // Upward direction functions assume no headroom and are trusting that removed bytes are still valid. 00634 // see mac.c:655 00635 00636 /* Set default flags */ 00637 buffer->dbm = pd_data_ind->dbm; 00638 buffer->LQI = pd_data_ind->link_quality; 00639 buffer->mac_class_ptr = rf_ptr; 00640 //Dnamic calculation for FCF + SEQ parse 00641 buffer->mac_header_length = ptr - pd_data_ind->data_ptr; 00642 00643 if (!rf_ptr->macProminousMode) { 00644 00645 if (buffer->fcf_dsn.frametype > FC_CMD_FRAME) { 00646 goto ERROR_HANDLER; 00647 } 00648 00649 buffer->mac_header_length += mac_header_address_length(&buffer->fcf_dsn); 00650 00651 length -= buffer->mac_header_length; 00652 00653 if (length < 0) { 00654 goto ERROR_HANDLER; 00655 } 00656 00657 buffer->mac_payload_length = (buffer->frameLength - buffer->mac_header_length); 00658 00659 if (buffer->fcf_dsn.securityEnabled) { 00660 //Read KEYID Mode 00661 uint8_t key_id_mode, security_level, mic_len; 00662 uint8_t *security_ptr = &buffer->buf[buffer->mac_header_length]; 00663 uint8_t auxBaseHeader = *security_ptr; 00664 key_id_mode = (auxBaseHeader >> 3) & 3; 00665 security_level = auxBaseHeader & 7; 00666 00667 switch (key_id_mode) { 00668 case MAC_KEY_ID_MODE_IMPLICIT: 00669 if (security_level) { 00670 buffer->security_aux_header_length = 5; 00671 } else { 00672 buffer->security_aux_header_length = 1; 00673 } 00674 break; 00675 case MAC_KEY_ID_MODE_IDX: 00676 buffer->security_aux_header_length = 6; 00677 break; 00678 case MAC_KEY_ID_MODE_SRC4_IDX: 00679 buffer->security_aux_header_length = 10; 00680 break; 00681 default: 00682 buffer->security_aux_header_length = 14; 00683 break; 00684 } 00685 00686 length -= buffer->security_aux_header_length; 00687 mic_len = mac_security_mic_length_get(security_level); 00688 00689 length -= mic_len; 00690 00691 //Verify that data length is not negative 00692 if (length < 0) { 00693 goto ERROR_HANDLER; 00694 } 00695 00696 buffer->mac_payload_length -= (buffer->security_aux_header_length + mic_len); 00697 } 00698 00699 00700 } 00701 //Do not accept commend frame with length 0 00702 if (fcf_read.frametype == FC_CMD_FRAME && length == 0) { 00703 goto ERROR_HANDLER; 00704 } 00705 00706 //Parse IE Elements 00707 if (!mac_header_information_elements_parse(buffer)) { 00708 goto ERROR_HANDLER; 00709 } 00710 00711 if (!rf_ptr->macProminousMode && buffer->fcf_dsn.frametype == FC_ACK_FRAME) { 00712 if (mac_data_interface_tx_done_by_ack_cb(rf_ptr, buffer)) { 00713 mcps_sap_pre_parsed_frame_buffer_free(buffer); 00714 } 00715 return 0; 00716 00717 } else { 00718 00719 if (mcps_sap_pd_ind(buffer) == 0) { 00720 return 0; 00721 } 00722 } 00723 ERROR_HANDLER: 00724 mcps_sap_pre_parsed_frame_buffer_free(buffer); 00725 return -1; 00726 00727 00728 } else if (message->id == MAC15_4_PD_SAP_DATA_TX_CONFIRM) { 00729 arm_pd_sap_15_4_confirm_with_params_t *pd_data_cnf = &(message->message.mac15_4_pd_sap_confirm); 00730 return mac_data_interface_tx_done_cb(rf_ptr, pd_data_cnf->status, pd_data_cnf->cca_retry, pd_data_cnf->tx_retry); 00731 } 00732 00733 return -1; 00734 } 00735 00736 void mac_pd_sap_rf_low_level_function_set(void *mac_ptr, void *driver) 00737 { 00738 arm_device_driver_list_s *driver_ptr = (arm_device_driver_list_s*)driver; 00739 driver_ptr->phy_sap_identifier = (protocol_interface_rf_mac_setup_s *)mac_ptr; 00740 driver_ptr->phy_sap_upper_cb = mac_pd_sap_data_cb; 00741 } 00742
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2