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.
Fork of OmniWheels by
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 Fri Jul 22 2022 04:53:54 by
 1.7.2 
    