takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_pd_sap.c Source File

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