Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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-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