Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_mcps_sap.c Source File

mac_mcps_sap.c

00001 /*
00002  * Copyright (c) 2014-2019, 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 
00018 /*
00019  * \file mac_mcps_sap.c
00020  * \brief Add short description about this file!!!
00021  *
00022  */
00023 #include "nsconfig.h"
00024 #include "ns_types.h"
00025 #include "eventOS_event.h"
00026 #include "eventOS_scheduler.h"
00027 #include "eventOS_callback_timer.h"
00028 #include "string.h"
00029 #include "ns_trace.h"
00030 #include "nsdynmemLIB.h"
00031 #include "ccmLIB.h"
00032 #include "mlme.h"
00033 #include "mac_api.h"
00034 #include "fhss_api.h "
00035 #include "platform/arm_hal_interrupt.h"
00036 #include "common_functions.h"
00037 
00038 #include "MAC/IEEE802_15_4/sw_mac_internal.h"
00039 #include "MAC/IEEE802_15_4/mac_defines.h"
00040 #include "MAC/IEEE802_15_4/mac_timer.h"
00041 #include "MAC/IEEE802_15_4/mac_security_mib.h"
00042 #include "MAC/IEEE802_15_4/mac_mlme.h"
00043 #include "MAC/IEEE802_15_4/mac_filter.h"
00044 #include "MAC/IEEE802_15_4/mac_pd_sap.h"
00045 #include "MAC/IEEE802_15_4/mac_mcps_sap.h"
00046 #include "MAC/IEEE802_15_4/mac_header_helper_functions.h"
00047 #include "MAC/IEEE802_15_4/mac_indirect_data.h"
00048 #include "MAC/rf_driver_storage.h"
00049 
00050 #include "sw_mac.h"
00051 
00052 #define TRACE_GROUP "mMCp"
00053 
00054 // Used to set TX time (us) with FHSS. Must be <= 65ms.
00055 #define MAC_TX_PROCESSING_DELAY_INITIAL 2000
00056 
00057 typedef struct {
00058     uint8_t address[8];
00059     unsigned addr_type: 2;
00060     uint8_t nonce_ptr[8];
00061     uint32_t frameCounter;
00062     uint8_t keyId;
00063 } neighbour_security_update_t;
00064 
00065 void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer);
00066 static mac_pre_build_frame_t *mcps_sap_pd_req_queue_read(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool is_bc_queue, bool flush);
00067 static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
00068 static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mac_pre_parsed_frame_t *ack_buf);
00069 static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00070 static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00071 static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00072 static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
00073 static void mac_pd_data_confirm_failure_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup);
00074 
00075 static int8_t mac_tasklet_event_handler = -1;
00076 
00077 static ns_mem_heap_size_t ns_dyn_mem_rate_limiting_threshold = 0xFFFFFFFF;
00078 
00079 /**
00080  * Get PHY time stamp.
00081  *
00082  * \param rf_mac_setup pointer to MAC
00083  * \return Timestamp from PHY
00084  *
00085  */
00086 uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00087 {
00088     uint32_t timestamp;
00089     rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_TIMESTAMP, (uint8_t *)&timestamp);
00090     return timestamp;
00091 }
00092 
00093 static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter)
00094 {
00095     if ((current_counter - packet_counter) >= 2) {
00096         return true;
00097     }
00098     return false;
00099 }
00100 
00101 static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
00102 {
00103     if (!buffer->asynch_request) {
00104         return true;
00105     }
00106 
00107     if (mlme_scan_analyze_next_channel(&buffer->asynch_channel_list, false) > 0x00ff) {
00108         mac_mlme_rf_channel_change(rf_mac_setup, buffer->asynch_channel);
00109         return true;
00110     }
00111 
00112     return false;
00113 
00114 }
00115 
00116 
00117 static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00118 {
00119     if (rf_mac_setup->macCapRxOnIdle || rf_mac_setup->macWaitingData || rf_mac_setup->scan_active) {
00120         return;
00121     }
00122 
00123     if (!rf_mac_setup->macRfRadioTxActive) {
00124         mac_mlme_mac_radio_disabled(rf_mac_setup);
00125     }
00126 }
00127 
00128 static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm, mac_pre_parsed_frame_t *ack_buf)
00129 {
00130     mac_data_poll_radio_disable_check(rf_mac_setup);
00131 
00132     if (get_sw_mac_api(rf_mac_setup)) {
00133         if (rf_mac_setup->mac_extension_enabled) {
00134             mcps_data_conf_payload_t data_conf;
00135             memset(&data_conf, 0, sizeof(mcps_data_conf_payload_t));
00136             if (ack_buf) {
00137                 data_conf.payloadIeList = ack_buf->payloadsIePtr;
00138                 data_conf.payloadIeListLength = ack_buf->payloadsIeLength;
00139                 data_conf.headerIeList = ack_buf->headerIePtr;
00140                 data_conf.headerIeListLength = ack_buf->headerIeLength;
00141                 data_conf.payloadLength = ack_buf->mac_payload_length;
00142                 data_conf.payloadPtr = ack_buf->macPayloadPtr;
00143             }
00144             //Check Payload Here
00145             get_sw_mac_api(rf_mac_setup)->data_conf_ext_cb(get_sw_mac_api(rf_mac_setup), confirm, &data_conf);
00146         } else {
00147             get_sw_mac_api(rf_mac_setup)->data_conf_cb(get_sw_mac_api(rf_mac_setup), confirm);
00148         }
00149     }
00150 }
00151 
00152 void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_data_req_t *data_req)
00153 {
00154     mcps_data_req_ie_list_t ie_list;
00155     memset(&ie_list, 0, sizeof(mcps_data_req_ie_list_t));
00156     mcps_sap_data_req_handler_ext(rf_mac_setup, data_req, &ie_list, NULL);
00157 }
00158 
00159 static bool mac_ie_vector_length_validate(ns_ie_iovec_t *ie_vector, uint16_t iov_length,  uint16_t *length_out)
00160 {
00161     if (length_out) {
00162         *length_out = 0;
00163     }
00164 
00165     if (!iov_length) {
00166         return true;
00167     }
00168 
00169     if (iov_length != 0 && !ie_vector) {
00170         return false;
00171     }
00172 
00173     uint16_t msg_length = 0;
00174     ns_ie_iovec_t *msg_iov = ie_vector;
00175     for (uint_fast16_t i = 0; i < iov_length; i++) {
00176         if (msg_iov->iovLen != 0 && !msg_iov->ieBase) {
00177             return false;
00178         }
00179         msg_length += msg_iov->iovLen;
00180         if (msg_length < msg_iov->iovLen) {
00181             return false;
00182         }
00183         msg_iov++;
00184     }
00185 
00186     if (length_out) {
00187         *length_out = msg_length;
00188     }
00189 
00190     return true;
00191 
00192 }
00193 
00194 
00195 void mcps_sap_data_req_handler_ext(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_data_req_t *data_req, const mcps_data_req_ie_list_t *ie_list, const channel_list_s *asynch_channel_list)
00196 {
00197     uint8_t status = MLME_SUCCESS;
00198     mac_pre_build_frame_t *buffer = NULL;
00199 
00200 
00201     if (!rf_mac_setup->mac_security_enabled) {
00202         if (data_req->Key.SecurityLevel) {
00203             status = MLME_UNSUPPORTED_SECURITY;
00204             goto verify_status;
00205         }
00206     }
00207 
00208     uint16_t ie_header_length = 0;
00209     uint16_t ie_payload_length = 0;
00210 
00211     if (!mac_ie_vector_length_validate(ie_list->headerIeVectorList, ie_list->headerIovLength, &ie_header_length)) {
00212         status = MLME_INVALID_PARAMETER;
00213         goto verify_status;
00214     }
00215 
00216     if (!mac_ie_vector_length_validate(ie_list->payloadIeVectorList, ie_list->payloadIovLength, &ie_payload_length)) {
00217         status = MLME_INVALID_PARAMETER;
00218         goto verify_status;
00219     }
00220 
00221     if ((ie_header_length || ie_payload_length || asynch_channel_list) && !rf_mac_setup->mac_extension_enabled) {
00222         //Report error when feature is not enaled yet
00223         status = MLME_INVALID_PARAMETER;
00224         goto verify_status;
00225     } else if (asynch_channel_list && data_req->TxAckReq) {
00226         //Report Asynch Message is not allowed to call with ACK requested.
00227         status = MLME_INVALID_PARAMETER;
00228         goto verify_status;
00229     }
00230 
00231     if ((data_req->msduLength + ie_header_length + ie_payload_length) > rf_mac_setup->dev_driver->phy_driver->phy_MTU - MAC_DATA_PACKET_MIN_HEADER_LENGTH) {
00232         tr_debug("packet %u, %u", data_req->msduLength, rf_mac_setup->dev_driver->phy_driver->phy_MTU);
00233         status = MLME_FRAME_TOO_LONG;
00234         goto verify_status;
00235     }
00236     buffer = mcps_sap_prebuild_frame_buffer_get(0);
00237     //tr_debug("Data Req");
00238     if (!buffer) {
00239         //Make Confirm Here
00240         status = MLME_TRANSACTION_OVERFLOW;
00241         goto verify_status;
00242     }
00243 
00244     if (!rf_mac_setup->macUpState || rf_mac_setup->scan_active) {
00245         status = MLME_TRX_OFF;
00246         goto verify_status;
00247     }
00248 
00249     if (asynch_channel_list) {
00250         //Copy Asynch data list
00251         buffer->asynch_channel_list = *asynch_channel_list;
00252         buffer->asynch_request = true;
00253     }
00254 
00255     buffer->upper_layer_request = true;
00256     buffer->fcf_dsn.frametype = FC_DATA_FRAME;
00257     buffer->fcf_dsn.ackRequested = data_req->TxAckReq;
00258 
00259     buffer->mac_header_length_with_security = 3;
00260     mac_header_security_parameter_set(&buffer->aux_header, &data_req->Key);
00261     buffer->security_mic_len = mac_security_mic_length_get(buffer->aux_header.securityLevel);
00262     if (buffer->aux_header.securityLevel) {
00263         buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
00264         buffer->fcf_dsn.securityEnabled = true;
00265     }
00266 
00267     buffer->mac_header_length_with_security += mac_header_security_aux_header_length(buffer->aux_header.securityLevel, buffer->aux_header.KeyIdMode);
00268 
00269     buffer->msduHandle = data_req->msduHandle;
00270     buffer->fcf_dsn.DstAddrMode = data_req->DstAddrMode;
00271     memcpy(buffer->DstAddr, data_req->DstAddr, 8);
00272     buffer->DstPANId = data_req->DstPANId;
00273     buffer->SrcPANId = mac_mlme_get_panid(rf_mac_setup);
00274     buffer->fcf_dsn.SrcAddrMode = data_req->SrcAddrMode;
00275     buffer->fcf_dsn.framePending = data_req->PendingBit;
00276 
00277     if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE && !rf_mac_setup->mac_extension_enabled) {
00278         if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
00279             status = MLME_INVALID_ADDRESS;
00280             goto verify_status;
00281         }
00282 
00283         if (rf_mac_setup->shortAdressValid) {
00284             buffer->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT;
00285         } else {
00286             buffer->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT;
00287         }
00288     }
00289 
00290     mac_frame_src_address_set_from_interface(buffer->fcf_dsn.SrcAddrMode, rf_mac_setup, buffer->SrcAddr);
00291 
00292     buffer->ie_elements.headerIeVectorList = ie_list->headerIeVectorList;
00293     buffer->ie_elements.headerIovLength = ie_list->headerIovLength;
00294     buffer->ie_elements.payloadIeVectorList = ie_list->payloadIeVectorList;
00295     buffer->ie_elements.payloadIovLength = ie_list->payloadIovLength;
00296     buffer->headerIeLength = ie_header_length;
00297     buffer->payloadsIeLength = ie_payload_length;
00298 
00299 
00300     if (rf_mac_setup->mac_extension_enabled) {
00301         //Handle mac extension's
00302         buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2015;
00303         if (ie_header_length || ie_payload_length) {
00304             buffer->fcf_dsn.informationElementsPresets = true;
00305         }
00306 
00307         buffer->fcf_dsn.sequenceNumberSuppress = data_req->SeqNumSuppressed;
00308         if (buffer->fcf_dsn.sequenceNumberSuppress) {
00309             buffer->mac_header_length_with_security--;
00310         }
00311         /* PAN-ID compression bit enable when necessary */
00312         if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE && buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
00313             buffer->fcf_dsn.intraPan = !data_req->PanIdSuppressed;
00314         } else if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
00315             buffer->fcf_dsn.intraPan = data_req->PanIdSuppressed;
00316         } else if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE || (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT && buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_64_BIT)) {
00317             buffer->fcf_dsn.intraPan = data_req->PanIdSuppressed;
00318         } else { /* two addresses, at least one address short */
00319             // ignore or fault panidsuppressed
00320             if (buffer->DstPANId == buffer->SrcPANId) {
00321                 buffer->fcf_dsn.intraPan = true;
00322             }
00323         }
00324     } else {
00325         /* PAN-ID compression bit enable when necessary */
00326         if ((buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.SrcAddrMode) && (buffer->DstPANId == buffer->SrcPANId)) {
00327             buffer->fcf_dsn.intraPan = true;
00328         }
00329     }
00330 
00331     //Check PanID presents at header
00332     buffer->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buffer->fcf_dsn);
00333     buffer->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buffer->fcf_dsn);
00334     //Calculate address length
00335     buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
00336     buffer->mac_payload = data_req->msdu;
00337     buffer->mac_payload_length = data_req->msduLength;
00338     //check that header + payload length is not bigger than MAC MTU
00339     if (data_req->InDirectTx) {
00340         mac_indirect_queue_write(rf_mac_setup, buffer);
00341     } else {
00342         mcps_sap_pd_req_queue_write(rf_mac_setup, buffer);
00343     }
00344 
00345 verify_status:
00346     if (status != MLME_SUCCESS) {
00347         tr_debug("DATA REQ Fail %u", status);
00348         rf_mac_setup->mac_mcps_data_conf_fail.msduHandle = data_req->msduHandle;
00349         rf_mac_setup->mac_mcps_data_conf_fail.status = status;
00350         mcps_sap_prebuild_frame_buffer_free(buffer);
00351         if (mcps_sap_pd_confirm_failure(rf_mac_setup) != 0) {
00352             // event sending failed, calling handler directly
00353             mac_pd_data_confirm_failure_handle(rf_mac_setup);
00354         }
00355     }
00356 }
00357 
00358 static int8_t mac_virtual_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *data_ptr, uint16_t data_length)
00359 {
00360 
00361     if (!rf_mac_setup->macUpState || data_length > rf_mac_setup->dev_driver->phy_driver->phy_MTU) {
00362         return -1;
00363     }
00364 
00365     //protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)api;
00366     mac_pre_build_frame_t *buffer = mcps_sap_prebuild_frame_buffer_get(data_length);
00367     //tr_debug("Data Req");
00368     if (!buffer) {
00369         //Make Confirm Here
00370         return -1;
00371     }
00372 
00373     mac_header_parse_fcf_dsn(&buffer->fcf_dsn, data_ptr);
00374     // Use MAC sequence as handle
00375     buffer->msduHandle = buffer->fcf_dsn.DSN;
00376     memcpy(buffer->mac_payload, data_ptr,  data_length);
00377     buffer->mac_payload_length = data_length;
00378 
00379     // Read destination MAC address from MAC header
00380     mac_header_get_dst_address(&buffer->fcf_dsn, data_ptr, buffer->DstAddr);
00381 
00382     mcps_sap_pd_req_queue_write(rf_mac_setup, buffer);
00383 
00384     if (!buffer->fcf_dsn.ackRequested) {
00385         phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
00386         driver->phy_tx_done_cb(rf_mac_setup->tun_extension_rf_driver->id, 1, PHY_LINK_TX_SUCCESS, 1, 1);
00387     }
00388     return 0;
00389 }
00390 
00391 static int8_t mac_virtual_mlme_nap_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const arm_mlme_req_t *mlme_req)
00392 {
00393     const uint8_t *ptr = mlme_req->mlme_ptr;
00394     switch (mlme_req->primitive) {
00395         case MLME_SCAN: {
00396             if (mlme_req->ptr_length != 47) {
00397                 return -1;
00398             }
00399 
00400             mlme_scan_t mlme_scan_req;
00401             mlme_scan_req.ScanType = (mac_scan_type_t) * ptr++;
00402             mlme_scan_req.ScanChannels.channel_page = (channel_page_e) * ptr++;
00403             memcpy(mlme_scan_req.ScanChannels.channel_mask, ptr, 32);
00404             ptr += 32;
00405             mlme_scan_req.ScanDuration = *ptr++;
00406             mlme_scan_req.ChannelPage = *ptr++;
00407             mlme_scan_req.Key.SecurityLevel = *ptr++;
00408             mlme_scan_req.Key.KeyIdMode = *ptr++;
00409             mlme_scan_req.Key.KeyIndex = *ptr++;
00410             memcpy(mlme_scan_req.Key.Keysource, ptr, 8);
00411             mac_mlme_scan_request(&mlme_scan_req, rf_mac_setup);
00412             return 0;
00413         }
00414         case MLME_SET: {
00415             if (mlme_req->ptr_length < 3) {
00416                 return -1;
00417             }
00418             mlme_set_t mlme_set_req;
00419             mlme_set_req.attr = (mlme_attr_t) * ptr++;
00420             mlme_set_req.attr_index = *ptr++;
00421             mlme_set_req.value_pointer = ptr;
00422             mlme_set_req.value_size = mlme_req->ptr_length - 2;
00423 
00424             return mac_mlme_set_req(rf_mac_setup, &mlme_set_req);
00425         }
00426         case MLME_START: {
00427             mlme_start_t mlme_start_req;
00428             if (mlme_req->ptr_length != 34) {
00429                 return -1;
00430             }
00431             mlme_start_req.PANId = common_read_16_bit(ptr);
00432             ptr += 2;
00433             mlme_start_req.LogicalChannel = *ptr++;
00434             mlme_start_req.StartTime = common_read_32_bit(ptr);
00435             ptr += 4;
00436             mlme_start_req.BeaconOrder = *ptr++;
00437             mlme_start_req.SuperframeOrder = *ptr++;
00438             mlme_start_req.PANCoordinator = *ptr++;
00439             mlme_start_req.BatteryLifeExtension = *ptr++;
00440             mlme_start_req.CoordRealignment = *ptr++;
00441             mlme_start_req.CoordRealignKey.SecurityLevel = *ptr++;
00442             mlme_start_req.CoordRealignKey.KeyIdMode = *ptr++;
00443             mlme_start_req.CoordRealignKey.KeyIndex = *ptr++;
00444             memcpy(mlme_start_req.CoordRealignKey.Keysource, ptr, 8);
00445             ptr += 8;
00446             mlme_start_req.BeaconRealignKey.SecurityLevel = *ptr++;
00447             mlme_start_req.BeaconRealignKey.KeyIdMode = *ptr++;
00448             mlme_start_req.BeaconRealignKey.KeyIndex = *ptr++;
00449             memcpy(mlme_start_req.BeaconRealignKey.Keysource, ptr, 8);
00450             ptr += 8;
00451             return mac_mlme_start_req(&mlme_start_req, rf_mac_setup);
00452         }
00453         default:
00454             break;
00455     }
00456     return -1;
00457 }
00458 
00459 
00460 int8_t mac_virtual_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
00461 {
00462     if (!identifier || !message) {
00463         return -1;
00464     }
00465 
00466     if (message->id == MACTUN_PD_SAP_NAP_IND) {
00467         return mac_virtual_data_req_handler(identifier, message->message.generic_data_ind.data_ptr,  message->message.generic_data_ind.data_len);
00468     }
00469 
00470     if (message->id == MACTUN_MLME_NAP_EXTENSION) {
00471         return mac_virtual_mlme_nap_req_handler(identifier, &message->message.mlme_request);
00472     }
00473     return -1;
00474 }
00475 
00476 
00477 
00478 //static void mac_data_interface_minium_security_level_get(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_security_level_descriptor_t *security_level_compare) {
00479 //    //TODO get securily level table and verify current packet
00480 //    (void)rf_mac_setup;
00481 //    //Accept all true from mac
00482 //    security_level_compare->SecurityMinimum = 0;
00483 //}
00484 
00485 static void mac_security_interface_aux_ccm_nonce_set(uint8_t *noncePtr, uint8_t *mac64, uint32_t securityFrameCounter, uint8_t securityLevel)
00486 {
00487     memcpy(noncePtr, mac64, 8);
00488     noncePtr += 8;
00489     noncePtr = common_write_32_bit(securityFrameCounter, noncePtr);
00490     *noncePtr = securityLevel;
00491 }
00492 
00493 /* Compare two security levels, as per 802.15.4-2011 7.4.1.1 */
00494 /* Returns true if sec1 is at least as secure as sec2 */
00495 //static bool mac_security_interface_security_level_compare(uint8_t sec1, uint8_t sec2)
00496 //{
00497 //    /* bit 2 is "encrypted" - must be as encrypted
00498 //    bits 1-0 are "authentication level" - must be at least as high */
00499 //    return (sec1 & 4) >= (sec2 & 4) &&
00500 //           (sec1 & 3) >= (sec2 & 3);
00501 //}
00502 
00503 
00504 static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme_security_t *security_params)
00505 {
00506     uint8_t *key;
00507     mlme_key_descriptor_t *key_description;
00508     mlme_key_device_descriptor_t *key_device_description = NULL;
00509     uint8_t device_descriptor_handle;
00510     uint8_t openPayloadLength = 0;
00511     bool security_by_pass = false;
00512     protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s *)b->mac_class_ptr;
00513 //    mlme_security_level_descriptor_t security_level_compare;
00514 
00515 
00516     if (!rf_mac_setup->mac_security_enabled) {
00517         if (security_params->SecurityLevel) {
00518             return MLME_UNSUPPORTED_SECURITY;
00519         }
00520         //TODO verify this with Kevin
00521         return MLME_UNSUPPORTED_LEGACY;
00522     }
00523 
00524 //    security_level_compare.FrameType = b->fcf_dsn.frametype;
00525     if (b->fcf_dsn.frametype == MAC_FRAME_CMD) {
00526         openPayloadLength = 1;
00527 //        security_level_compare.CommandFrameIdentifier = mcps_mac_command_frame_id_get(b);
00528     }
00529 
00530     //TODO do this proper way when security description  is implemeted
00531 
00532 //    mac_data_interface_minium_security_level_get(rf_mac_setup, &security_level_compare);
00533 //
00534 //    //Validate Security Level
00535 //    if (!mac_security_interface_security_level_compare(security_params->SecurityLevel, security_level_compare.SecurityMinimum)) {
00536 //        //Drop packet reason rx level was less secured than requested one
00537 //        tr_debug("RX Security level less than minimum level");
00538 //        return MLME_IMPROPER_SECURITY_LEVEL;
00539 //    }
00540 
00541     neighbour_security_update_t neighbour_validation;
00542     memset(&neighbour_validation, 0, sizeof(neighbour_validation));
00543     neighbour_validation.frameCounter = mcps_mac_security_frame_counter_read(b);
00544 
00545     if (neighbour_validation.frameCounter == 0xffffffff) {
00546         tr_debug("Max Framecounter value..Drop");
00547         return MLME_COUNTER_ERROR;
00548     }
00549 
00550     //READ SRC Address
00551 
00552     uint16_t SrcPANId = mac_header_get_src_panid(&b->fcf_dsn, mac_header_message_start_pointer(b), rf_mac_setup->pan_id);
00553     mac_header_get_src_address(&b->fcf_dsn, mac_header_message_start_pointer(b), neighbour_validation.address);
00554     neighbour_validation.addr_type = b->fcf_dsn.SrcAddrMode;
00555     neighbour_validation.keyId = security_params->KeyIndex;
00556 
00557     // Get A Key description
00558     key_description =  mac_sec_key_description_get(rf_mac_setup, security_params, b->fcf_dsn.SrcAddrMode, neighbour_validation.address, SrcPANId);
00559     if (!key_description) {
00560         return MLME_UNAVAILABLE_KEY;
00561     }
00562 
00563     if (key_description->unique_key_descriptor) {
00564         //Discover device table by device description handle
00565         key_device_description = key_description->KeyDeviceList;
00566         device_descriptor_handle = key_device_description->DeviceDescriptorHandle;
00567         //Discover device descriptor by handle
00568         b->neigh_info = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, device_descriptor_handle);
00569         if (!b->neigh_info) {
00570             return MLME_UNSUPPORTED_SECURITY;
00571         }
00572     } else {
00573 
00574         if (!b->neigh_info) {
00575             if (SrcPANId == rf_mac_setup->pan_id && rf_mac_setup->mac_security_bypass_unknow_device &&
00576                     (b->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT && security_params->SecurityLevel > AES_SECURITY_LEVEL_ENC)) {
00577                 security_by_pass = true;//Accept by pass only from same PAN-ID
00578             } else {
00579                 return MLME_UNSUPPORTED_SECURITY;
00580             }
00581         }
00582 
00583         device_descriptor_handle = mac_mib_device_descption_attribute_get_by_descriptor(rf_mac_setup, b->neigh_info);
00584         key_device_description =  mac_sec_mib_key_device_description_discover_from_list(key_description, device_descriptor_handle);
00585     }
00586 
00587     if (key_device_description) {
00588         //validate BlackList status
00589         if (key_device_description->Blacklisted) {
00590             tr_debug("Blacklisted key for device %s", trace_array(b->neigh_info->ExtAddress, 8));
00591             return MLME_UNAVAILABLE_KEY;
00592         }
00593 
00594         if (b->neigh_info) {
00595             uint32_t min_accepted_frame_counter = mac_mib_key_device_frame_counter_get(key_description, b->neigh_info, device_descriptor_handle);
00596             if (neighbour_validation.frameCounter < min_accepted_frame_counter) {
00597                 tr_debug("MLME_COUNTER_ERROR");
00598                 return MLME_COUNTER_ERROR;
00599             }
00600         }
00601 
00602     }
00603 
00604     key = key_description->Key;
00605     if (security_by_pass) {
00606         memcpy(neighbour_validation.nonce_ptr, neighbour_validation.address, 8);
00607     } else {
00608         memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8);
00609     }
00610 
00611     ccm_globals_t ccm_ptr;
00612 
00613     if (!ccm_sec_init(&ccm_ptr, security_params->SecurityLevel, key, AES_CCM_DECRYPT, 2)) {
00614         return MLME_UNSUPPORTED_SECURITY;
00615     }
00616 
00617     mac_security_interface_aux_ccm_nonce_set(ccm_ptr.exp_nonce, neighbour_validation.nonce_ptr, neighbour_validation.frameCounter, security_params->SecurityLevel);
00618 
00619     if (ccm_ptr.mic_len) {
00620         // this is asuming that there is no headroom for buffers.
00621         ccm_ptr.adata_len = mcps_mac_header_length_from_received_frame(b) + openPayloadLength;
00622         //SET MIC PTR
00623         ccm_ptr.mic = mcps_security_mic_pointer_get(b);
00624         ccm_ptr.adata_ptr = mac_header_message_start_pointer(b);
00625     }
00626 
00627     ccm_ptr.data_ptr = (mcps_mac_payload_pointer_get(b) + openPayloadLength);
00628     ccm_ptr.data_len = b->mac_payload_length - openPayloadLength;
00629     if (ccm_process_run(&ccm_ptr) != 0) {
00630         return MLME_SECURITY_FAIL;
00631     }
00632 
00633     //Update key device and key description tables
00634     if (!security_by_pass) {
00635 
00636         mac_sec_mib_key_device_frame_counter_set(key_description, b->neigh_info, neighbour_validation.frameCounter + 1, device_descriptor_handle);
00637 
00638         if (!key_device_description) {
00639             if (!rf_mac_setup->secFrameCounterPerKey) {
00640                 // Black list old used keys by this device
00641                 mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
00642             }
00643 
00644             key_device_description =  mac_sec_mib_key_device_description_list_update(key_description);
00645             if (key_device_description) {
00646                 tr_debug("Set new device user %u for key", device_descriptor_handle);
00647                 key_device_description->DeviceDescriptorHandle = device_descriptor_handle;
00648             }
00649         }
00650     }
00651 
00652     return MLME_SUCCESS;
00653 }
00654 
00655 static void mcps_comm_status_indication_generate(uint8_t status, mac_pre_parsed_frame_t *buf, mac_api_t *mac)
00656 {
00657     mlme_comm_status_t comm_status;
00658     protocol_interface_rf_mac_setup_s *rf_ptr = buf->mac_class_ptr;
00659     memset(&comm_status, 0, sizeof(mlme_comm_status_t));
00660     comm_status.status = status;
00661     //Call com status
00662     comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_ptr->pan_id);
00663     comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
00664     mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
00665     comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00666     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.SrcAddr);
00667     mac_header_security_components_read(buf, &comm_status.Key);
00668     mac->mlme_ind_cb(mac, MLME_COMM_STATUS, &comm_status);
00669 }
00670 
00671 
00672 
00673 static int8_t mac_data_interface_host_accept_data(mcps_data_ind_t *data_ind, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00674 {
00675     if ((data_ind->DstAddrMode == MAC_ADDR_MODE_16_BIT) && (data_ind->DstAddr[0] == 0xff && data_ind->DstAddr[1] == 0xff)) {
00676         return -1;
00677     }
00678 
00679 
00680     if (data_ind->msduLength) {
00681         if (!rf_mac_setup->macRxDataAtPoll && rf_mac_setup->macDataPollReq) {
00682             eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
00683             rf_mac_setup->macRxDataAtPoll = true;
00684             eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 400); //20ms
00685             rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA;
00686             rf_mac_setup->mlme_tick_count = 0;
00687         }
00688         return 0;
00689     } else {
00690         eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
00691         mac_mlme_poll_process_confirm(rf_mac_setup, MLME_NO_DATA);
00692         return -1;
00693     }
00694 
00695 }
00696 
00697 static int8_t mac_data_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_api_t *mac)
00698 {
00699     int8_t retval = -1;
00700     uint8_t status;
00701 
00702     //allocate Data ind primitiv and parse packet to that
00703     mcps_data_ind_t *data_ind = ns_dyn_mem_temporary_alloc(sizeof(mcps_data_ind_t));
00704 
00705     if (!data_ind) {
00706         goto DROP_PACKET;
00707     }
00708     memset(data_ind, 0, sizeof(mcps_data_ind_t));
00709     //Parse data
00710     data_ind->DSN = buf->fcf_dsn.DSN;
00711     data_ind->DstAddrMode = buf->fcf_dsn.DstAddrMode;
00712     mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->DstAddr);
00713     data_ind->SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00714 
00715     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->SrcAddr);
00716 
00717     data_ind->SrcPANId = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
00718     data_ind->DstPANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
00719 
00720     data_ind->mpduLinkQuality = buf->LQI;
00721     data_ind->signal_dbm = buf->dbm;
00722     data_ind->timestamp = buf->timestamp;
00723     /* Parse security part */
00724     mac_header_security_components_read(buf, &data_ind->Key);
00725 
00726     buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, data_ind->SrcAddr, data_ind->SrcAddrMode, data_ind->SrcPANId);
00727     if (buf->fcf_dsn.securityEnabled) {
00728         status = mac_data_interface_decrypt_packet(buf, &data_ind->Key);
00729         if (status != MLME_SUCCESS) {
00730             mcps_comm_status_indication_generate(status, buf, mac);
00731             goto DROP_PACKET;
00732         }
00733     }
00734 
00735     if (!mac_payload_information_elements_parse(buf)) {
00736         goto DROP_PACKET;
00737     }
00738     data_ind->msduLength = buf->mac_payload_length;
00739     data_ind->msdu_ptr = buf->macPayloadPtr;
00740 
00741     /* Validate Polling device */
00742     if (!rf_mac_setup->macCapRxOnIdle) {
00743         if (mac_data_interface_host_accept_data(data_ind, rf_mac_setup) != 0) {
00744             //tr_debug("Drop by not Accept");
00745             goto DROP_PACKET;
00746         }
00747     }
00748 
00749     if (mac) {
00750 
00751         if (buf->fcf_dsn.frameVersion == MAC_FRAME_VERSION_2015) {
00752             if (!rf_mac_setup->mac_extension_enabled) {
00753                 goto DROP_PACKET;
00754             }
00755             mcps_data_ie_list_t ie_list;
00756             ie_list.payloadIeList = buf->payloadsIePtr;
00757             ie_list.payloadIeListLength = buf->payloadsIeLength;
00758             ie_list.headerIeList = buf->headerIePtr;
00759             ie_list.headerIeListLength = buf->headerIeLength;
00760             //Swap compressed address to broadcast when dst Address is elided
00761             if (buf->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
00762                 data_ind->DstAddrMode = MAC_ADDR_MODE_16_BIT;
00763                 data_ind->DstAddr[0] = 0xff;
00764                 data_ind->DstAddr[1] = 0xff;
00765             }
00766             mac->data_ind_ext_cb(mac, data_ind, &ie_list);
00767 
00768         } else {
00769             mac->data_ind_cb(mac, data_ind);
00770         }
00771         retval = 0;
00772     }
00773 
00774 DROP_PACKET:
00775     ns_dyn_mem_free(data_ind);
00776     mcps_sap_pre_parsed_frame_buffer_free(buf);
00777     return retval;
00778 }
00779 
00780 static void mac_lib_res_no_data_to_req(mac_pre_parsed_frame_t *buffer, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00781 {
00782     mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0);
00783     if (!buf) {
00784         return;
00785     }
00786 
00787     buf->fcf_dsn.SrcAddrMode = buffer->fcf_dsn.DstAddrMode;
00788     buf->fcf_dsn.DstAddrMode = buffer->fcf_dsn.SrcAddrMode;
00789     //SET PANID
00790     buf->SrcPANId = mac_header_get_dst_panid(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), rf_mac_setup->pan_id);
00791     buf->DstPANId = buf->SrcPANId;
00792 
00793     mac_header_get_dst_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->SrcAddr);
00794     mac_header_get_src_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->DstAddr);
00795 
00796     buf->fcf_dsn.securityEnabled = buffer->fcf_dsn.securityEnabled;
00797     buf->fcf_dsn.intraPan = true;
00798     buf->fcf_dsn.ackRequested = true;
00799     buf->mac_header_length_with_security = 3;
00800     //Check PanID presents at header
00801     buf->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buf->fcf_dsn);
00802     buf->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buf->fcf_dsn);
00803 
00804     if (buffer->fcf_dsn.securityEnabled) {
00805         buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
00806         buf->aux_header.securityLevel = rf_mac_setup->mac_auto_request.SecurityLevel;
00807         buf->aux_header.KeyIdMode = rf_mac_setup->mac_auto_request.KeyIdMode;
00808         buf->aux_header.KeyIndex = rf_mac_setup->mac_auto_request.KeyIndex;
00809         memcpy(buf->aux_header.Keysource, rf_mac_setup->mac_auto_request.Keysource, 8);
00810     }
00811     buf->fcf_dsn.frametype = FC_DATA_FRAME;
00812     buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY;
00813     buf->mac_payload = NULL;
00814     buf->mac_payload_length = 0;
00815     buf->security_mic_len = mac_security_mic_length_get(buf->aux_header.securityLevel);
00816     buf->mac_header_length_with_security += mac_header_security_aux_header_length(buf->aux_header.securityLevel, buf->aux_header.KeyIdMode);
00817     buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn);
00818     mcps_sap_pd_req_queue_write(rf_mac_setup, buf);
00819 }
00820 
00821 static int8_t mac_beacon_request_handler(mac_pre_parsed_frame_t *buffer, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00822 {
00823 
00824     if (buffer->fcf_dsn.SrcAddrMode != MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode != MAC_ADDR_MODE_16_BIT) {
00825         return -1;
00826     }
00827     // Note FHSS from received beacon request
00828     if (rf_mac_setup->fhss_api) {
00829         rf_mac_setup->fhss_api->receive_frame(rf_mac_setup->fhss_api, 0, NULL, 0, NULL, FHSS_SYNCH_REQUEST_FRAME);
00830     }
00831     // mac_data_interface_build_beacon() uses the same buffer to build the response
00832     // and it is then feed to protocol buffer. Buffer should be freed only if it returns zero.
00833     return mac_mlme_beacon_tx(rf_mac_setup);
00834 
00835 }
00836 
00837 static int8_t mac_command_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup,  mac_api_t *mac)
00838 {
00839     int8_t retval = -1;
00840     mlme_security_t security_params;
00841     uint8_t mac_command;
00842     uint8_t status;
00843     uint8_t temp_src_address[8];
00844 
00845 
00846     //Read address and pan-id
00847     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), temp_src_address);
00848     uint8_t address_mode = buf->fcf_dsn.SrcAddrMode;
00849     uint16_t pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
00850     buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, temp_src_address, address_mode, pan_id);
00851     //Decrypt Packet if secured
00852     if (buf->fcf_dsn.securityEnabled) {
00853         mac_header_security_components_read(buf, &security_params);
00854 
00855         status = mac_data_interface_decrypt_packet(buf, &security_params);
00856         if (status != MLME_SUCCESS) {
00857 
00858             mcps_comm_status_indication_generate(status, buf, mac);
00859             goto DROP_PACKET;
00860         }
00861     }
00862 
00863     mac_command = mcps_mac_command_frame_id_get(buf);
00864 
00865     switch (mac_command) {
00866         case MAC_DATA_REQ:
00867             //Here 2 check
00868             if (mac_indirect_data_req_handle(buf, rf_mac_setup) == 0) {
00869                 mac_lib_res_no_data_to_req(buf, rf_mac_setup);
00870             }
00871             retval = 0;
00872             break;
00873         case MAC_BEACON_REQ:
00874             retval = mac_beacon_request_handler(buf, rf_mac_setup);
00875             break;
00876 
00877         default:
00878             break;
00879     }
00880 
00881 DROP_PACKET:
00882     mcps_sap_pre_parsed_frame_buffer_free(buf);
00883     return retval;
00884 }
00885 
00886 static void mac_nap_tun_data_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00887 {
00888     phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
00889     if (driver->phy_rx_cb) {
00890         driver->phy_rx_cb(buf->buf, buf->frameLength, buf->LQI, buf->dbm, rf_mac_setup->tun_extension_rf_driver->id);
00891     }
00892     mcps_sap_pre_parsed_frame_buffer_free(buf);
00893 }
00894 
00895 static void mac_data_interface_parse_beacon(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00896 {
00897     mlme_beacon_ind_t ind_data;
00898 
00899     uint16_t len;
00900     uint8_t *ptr;
00901     mlme_beacon_gts_spec_t gts_spec;
00902 //    uint8_t *gts_info = NULL;
00903     uint8_t *pending_address_list = NULL;
00904     uint8_t SuperframeSpec[2];
00905 
00906     uint16_t src_pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
00907 
00908     //validate beacon pan-id and filter other network out
00909     if (rf_mac_setup->pan_id < 0xffff && (rf_mac_setup->pan_id != src_pan_id && !rf_mac_setup->macAcceptAnyBeacon)) {
00910         tr_debug("Drop Beacon by unknow panid");
00911         return;
00912     }
00913 
00914     if (!mac_payload_information_elements_parse(buf)) {
00915         return;
00916     }
00917 
00918     /*Add received bytes in statistics*/
00919     tr_debug("mac_parse_beacon");
00920 
00921     ptr = buf->macPayloadPtr;
00922     len = buf->mac_payload_length;
00923     SuperframeSpec[0] = *ptr++;
00924     SuperframeSpec[1] = *ptr++;
00925     gts_spec.description_count = (*ptr & 7);
00926     gts_spec.gts_permit = ((*ptr++ & 0x80) >> 7);
00927     len -= 3;
00928     if (gts_spec.description_count) {
00929         tr_error("GTS info count not zero");
00930         //calucalate Length
00931         uint8_t gts_field_length = ((gts_spec.description_count) * 3);
00932         if (len < gts_field_length) {
00933             return;
00934         }
00935         len -= gts_field_length;
00936         ptr += gts_field_length;
00937     }
00938     //Pendinlist
00939     ind_data.PendAddrSpec.short_address_count = (*ptr & 7);
00940     ind_data.PendAddrSpec.extended_address_count = ((*ptr++ & 0x70) >> 4);
00941     len -= 1;
00942     if (ind_data.PendAddrSpec.short_address_count || ind_data.PendAddrSpec.extended_address_count) {
00943         if ((ind_data.PendAddrSpec.extended_address_count + ind_data.PendAddrSpec.short_address_count)  > 7) {
00944             //over 7 address
00945             return;
00946         }
00947         uint8_t pending_address_list_size = (ind_data.PendAddrSpec.short_address_count * 2);
00948         pending_address_list_size += (ind_data.PendAddrSpec.extended_address_count * 8);
00949         if (len < pending_address_list_size) {
00950             return;
00951         }
00952         pending_address_list = ptr;
00953         ptr += pending_address_list_size;
00954         len -= pending_address_list_size;
00955     }
00956 
00957     memset(&ind_data.PANDescriptor, 0, sizeof(mlme_pan_descriptor_t));
00958 
00959     if (rf_mac_setup->fhss_api) {
00960         ind_data.PANDescriptor.LogicalChannel = 0; //Force Allways same channel
00961     } else {
00962         ind_data.PANDescriptor.LogicalChannel = rf_mac_setup->mac_channel;
00963     }
00964     ind_data.PANDescriptor.ChannelPage = 0;
00965     ind_data.PANDescriptor.CoordAddrMode = buf->fcf_dsn.SrcAddrMode;
00966     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), ind_data.PANDescriptor.CoordAddress);
00967     ind_data.PANDescriptor.CoordPANId = src_pan_id;
00968     ind_data.PANDescriptor.LinkQuality = buf->LQI;
00969     ind_data.PANDescriptor.GTSPermit = gts_spec.gts_permit;
00970     ind_data.PANDescriptor.Timestamp = buf->timestamp;
00971     mac_header_security_components_read(buf, &ind_data.PANDescriptor.Key);
00972     ind_data.PANDescriptor.SecurityFailure = 0;
00973     ind_data.PANDescriptor.SuperframeSpec[0] = SuperframeSpec[0];
00974     ind_data.PANDescriptor.SuperframeSpec[1] = SuperframeSpec[1];
00975 
00976     ind_data.BSN = buf->fcf_dsn.DSN;
00977     ind_data.AddrList = pending_address_list;
00978     ind_data.beacon_data_length = len;
00979     ind_data.beacon_data = ptr;
00980 
00981     mac_mlme_beacon_notify(rf_mac_setup, &ind_data);
00982 
00983 }
00984 
00985 static void mac_data_interface_frame_handler(mac_pre_parsed_frame_t *buf)
00986 {
00987     protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
00988     if (!rf_mac_setup) {
00989         mcps_sap_pre_parsed_frame_buffer_free(buf);
00990         return;
00991     }
00992     /* push data to stack if sniffer mode is enabled */
00993     if (rf_mac_setup->macProminousMode) {
00994         mac_nap_tun_data_handler(buf, rf_mac_setup);
00995         return;
00996     }
00997     mac_api_t *mac = get_sw_mac_api(rf_mac_setup);
00998     if (!mac || (rf_mac_setup->mac_mlme_scan_resp && buf->fcf_dsn.frametype != MAC_FRAME_BEACON)) {
00999         mcps_sap_pre_parsed_frame_buffer_free(buf);
01000         return;
01001     }
01002     if (buf->fcf_dsn.ackRequested == false) {
01003         sw_mac_stats_update(rf_mac_setup, STAT_MAC_BC_RX_COUNT, 0);
01004     }
01005     sw_mac_stats_update(rf_mac_setup, STAT_MAC_RX_COUNT, 0);
01006     switch (buf->fcf_dsn.frametype) {
01007         case MAC_FRAME_BEACON:
01008             sw_mac_stats_update(rf_mac_setup, STAT_MAC_BEA_RX_COUNT, 0);
01009             mac_data_interface_parse_beacon(buf, rf_mac_setup);
01010             mcps_sap_pre_parsed_frame_buffer_free(buf);
01011             break;
01012         case MAC_FRAME_DATA:
01013             if (rf_mac_setup->tun_extension_rf_driver) {
01014                 mac_nap_tun_data_handler(buf, rf_mac_setup);
01015                 return;
01016             }
01017             mac_data_sap_rx_handler(buf, rf_mac_setup, mac);
01018             break;
01019         case MAC_FRAME_CMD:
01020             if (rf_mac_setup->tun_extension_rf_driver) {
01021                 if (mcps_mac_command_frame_id_get(buf) != MAC_BEACON_REQ) {
01022                     mac_nap_tun_data_handler(buf, rf_mac_setup);
01023                     return;
01024                 }
01025             }
01026 
01027             //Handle Command Frame
01028             mac_command_sap_rx_handler(buf, rf_mac_setup, mac);
01029             break;
01030 
01031         default:
01032             mcps_sap_pre_parsed_frame_buffer_free(buf);
01033     }
01034 
01035 }
01036 
01037 static void mac_mcps_asynch_finish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
01038 {
01039     if (buffer->asynch_request && rf_mac_setup->fhss_api) {
01040         // Must return to scheduled channel after asynch process by calling TX done
01041         rf_mac_setup->fhss_api->data_tx_done(rf_mac_setup->fhss_api, false, true, buffer->msduHandle);
01042     }
01043 }
01044 
01045 void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup)
01046 {
01047     if (!rf_mac_setup) {
01048         return;
01049     }
01050     while (!rf_mac_setup->active_pd_data_request) {
01051         bool is_bc_queue = false;
01052         mac_pre_build_frame_t *buffer;
01053         // With FHSS, poll broadcast queue on broadcast channel first
01054         if (rf_mac_setup->fhss_api) {
01055             if (rf_mac_setup->fhss_api->is_broadcast_channel(rf_mac_setup->fhss_api) == true) {
01056                 if (rf_mac_setup->pd_data_request_bc_queue_to_go) {
01057                     is_bc_queue = true;
01058                 }
01059             }
01060         }
01061         buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false);
01062 
01063         if (buffer) {
01064             rf_mac_setup->active_pd_data_request = buffer;
01065             if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
01066                 rf_mac_setup->active_pd_data_request = NULL;
01067                 mac_mcps_asynch_finish(rf_mac_setup, buffer);
01068                 mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
01069             } else {
01070                 return;
01071             }
01072         } else {
01073             return;
01074         }
01075     }
01076 }
01077 
01078 static int8_t mac_ack_sap_rx_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
01079 {
01080     //allocate Data ind primitiv and parse packet to that
01081     mlme_security_t key;
01082     uint8_t SrcAddr[8];         /**< Source address */
01083     memset(SrcAddr, 0, 8);
01084     memset(&key, 0, sizeof(mlme_security_t));
01085     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), SrcAddr);
01086     uint16_t pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf), rf_mac_setup->pan_id);
01087     /* Parse security part */
01088     mac_header_security_components_read(buf, &key);
01089 
01090     buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, SrcAddr, buf->fcf_dsn.SrcAddrMode, pan_id);
01091     if (buf->fcf_dsn.securityEnabled) {
01092         uint8_t status = mac_data_interface_decrypt_packet(buf, &key);
01093         if (status != MLME_SUCCESS) {
01094             rf_mac_setup->mac_tx_result = MAC_ACK_SECURITY_FAIL;
01095             return -1;
01096         }
01097     }
01098 
01099     if (buf->mac_payload_length && !mac_payload_information_elements_parse(buf)) {
01100         rf_mac_setup->mac_tx_result = MAC_ACK_SECURITY_FAIL;
01101         return -1;
01102     }
01103 
01104     return 0;
01105 }
01106 
01107 static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup)
01108 {
01109     if (rf_mac_setup->active_pd_data_request) {
01110         mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
01111         if (mac_data_request_confirmation_finnish(rf_mac_setup, buffer)) {
01112             rf_mac_setup->active_pd_data_request = NULL;
01113             mac_mcps_asynch_finish(rf_mac_setup, buffer);
01114             mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
01115         } else {
01116             if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
01117                 rf_mac_setup->active_pd_data_request = NULL;
01118                 mac_mcps_asynch_finish(rf_mac_setup, buffer);
01119                 mcps_data_confirm_handle(rf_mac_setup, buffer, NULL);
01120             } else {
01121                 return;
01122             }
01123         }
01124     }
01125 
01126     mac_mcps_trig_buffer_from_queue(rf_mac_setup);
01127 }
01128 
01129 static void mac_pd_data_confirm_failure_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup)
01130 {
01131     mcps_data_conf_t mcps_data_conf;
01132     memset(&mcps_data_conf, 0, sizeof(mcps_data_conf_t));
01133     mcps_data_conf.msduHandle = rf_mac_setup->mac_mcps_data_conf_fail.msduHandle;
01134     mcps_data_conf.status = rf_mac_setup->mac_mcps_data_conf_fail.status;
01135     mcps_data_confirm_cb(rf_mac_setup, &mcps_data_conf, NULL);
01136 }
01137 
01138 static void mac_pd_data_ack_handler(mac_pre_parsed_frame_t *buf)
01139 {
01140     protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
01141 
01142     if (!rf_mac_setup->active_pd_data_request) {
01143         mcps_sap_pre_parsed_frame_buffer_free(buf);
01144     } else {
01145         mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
01146 
01147         if (mac_ack_sap_rx_handler(buf, rf_mac_setup)) {
01148             //Do not forward ACK payload but Accept ACK
01149             mcps_sap_pre_parsed_frame_buffer_free(buf);
01150             buf = NULL;
01151 
01152         }
01153 
01154         rf_mac_setup->active_pd_data_request = NULL;
01155         mcps_data_confirm_handle(rf_mac_setup, buffer, buf);
01156         mcps_sap_pre_parsed_frame_buffer_free(buf);
01157 
01158     }
01159 
01160     mac_mcps_trig_buffer_from_queue(rf_mac_setup);
01161 }
01162 
01163 
01164 static void mac_mcps_sap_data_tasklet(arm_event_s *event)
01165 {
01166     uint8_t event_type = event->event_type;
01167 
01168     switch (event_type) {
01169         case MCPS_SAP_DATA_IND_EVENT:
01170             if (event->data_ptr) {
01171                 mac_data_interface_frame_handler((mac_pre_parsed_frame_t *)event->data_ptr);
01172             }
01173 
01174             break;
01175 
01176         case MCPS_SAP_DATA_CNF_EVENT:
01177             //mac_data_interface_tx_done(event->data_ptr);
01178             mac_pd_data_confirm_handle((protocol_interface_rf_mac_setup_s *)event->data_ptr);
01179             break;
01180 
01181         case MCPS_SAP_DATA_CNF_FAIL_EVENT:
01182             mac_pd_data_confirm_failure_handle((protocol_interface_rf_mac_setup_s *)event->data_ptr);
01183             break;
01184 
01185         case MCPS_SAP_DATA_ACK_CNF_EVENT:
01186             mac_pd_data_ack_handler((mac_pre_parsed_frame_t *)event->data_ptr);
01187             break;
01188 
01189         case MAC_MLME_EVENT_HANDLER:
01190             mac_mlme_event_cb(event->data_ptr);
01191             break;
01192         case MAC_MCPS_INDIRECT_TIMER_CB:
01193             mac_indirect_data_ttl_handle((protocol_interface_rf_mac_setup_s *)event->data_ptr, (uint16_t)event->event_data);
01194             break;
01195 
01196         case MAC_MLME_SCAN_CONFIRM_HANDLER:
01197             mac_mlme_scan_confirmation_handle((protocol_interface_rf_mac_setup_s *) event->data_ptr);
01198             break;
01199         case MAC_SAP_TRIG_TX:
01200             mac_clear_active_event((protocol_interface_rf_mac_setup_s *) event->data_ptr, MAC_SAP_TRIG_TX);
01201             mac_mcps_trig_buffer_from_queue((protocol_interface_rf_mac_setup_s *) event->data_ptr);
01202         //No break necessary
01203         default:
01204             break;
01205     }
01206 }
01207 
01208 int8_t mac_mcps_sap_tasklet_init(void)
01209 {
01210     if (mac_tasklet_event_handler < 0) {
01211         mac_tasklet_event_handler = eventOS_event_handler_create(&mac_mcps_sap_data_tasklet, 0);
01212     }
01213 
01214     return mac_tasklet_event_handler;
01215 }
01216 
01217 mac_pre_build_frame_t *mcps_sap_prebuild_frame_buffer_get(uint16_t payload_size)
01218 {
01219     mac_pre_build_frame_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(mac_pre_build_frame_t));
01220     if (!buffer) {
01221         return NULL;
01222     }
01223     memset(buffer, 0, sizeof(mac_pre_build_frame_t));
01224     buffer->aux_header.frameCounter = 0xffffffff;
01225     if (payload_size) {
01226         //Mac interlnal payload allocate
01227         buffer->mac_payload = ns_dyn_mem_temporary_alloc(payload_size);
01228         if (!buffer->mac_payload) {
01229             ns_dyn_mem_free(buffer);
01230             return NULL;
01231         }
01232         buffer->mac_allocated_payload_ptr = true;
01233         buffer->mac_payload_length = payload_size;
01234     } else {
01235         buffer->mac_allocated_payload_ptr = false;
01236     }
01237     return buffer;
01238 }
01239 
01240 
01241 void mcps_sap_prebuild_frame_buffer_free(mac_pre_build_frame_t *buffer)
01242 {
01243     if (!buffer) {
01244         return;
01245     }
01246 
01247     if (buffer->mac_allocated_payload_ptr) {
01248         ns_dyn_mem_free(buffer->mac_payload);
01249     }
01250     //Free Buffer frame
01251     ns_dyn_mem_free(buffer);
01252 
01253 }
01254 
01255 static mlme_key_descriptor_t *mac_frame_security_key_get(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01256 {
01257     /* Encrypt the packet payload if AES encyption bit is set */
01258     mlme_security_t key_source;
01259     key_source.KeyIdMode = buffer->aux_header.KeyIdMode;
01260     key_source.KeyIndex = buffer->aux_header.KeyIndex;
01261     key_source.SecurityLevel = buffer->aux_header.securityLevel;
01262     memcpy(key_source.Keysource, buffer->aux_header.Keysource, 8);
01263     return mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
01264 }
01265 
01266 
01267 static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mlme_key_descriptor_t *key_description)
01268 {
01269     /* Encrypt the packet payload if AES encyption bit is set */
01270     mlme_device_descriptor_t *device_description;
01271     uint8_t *nonce_ext_64_ptr;
01272 
01273     if (key_description->unique_key_descriptor) {
01274         device_description = mac_sec_mib_device_description_get_attribute_index(rf_ptr, key_description->KeyDeviceList->DeviceDescriptorHandle);
01275         if (!device_description) {
01276 
01277             buffer->status = MLME_UNAVAILABLE_KEY;
01278             return false;
01279         }
01280         nonce_ext_64_ptr = device_description->ExtAddress;
01281     } else {
01282         //Discover device descriptor only unicast packet which need ack
01283         if (buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.ackRequested) {
01284             device_description =  mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode, buffer->DstPANId);
01285             if (!device_description) {
01286                 buffer->status = MLME_UNAVAILABLE_KEY;
01287                 return false;
01288             }
01289         }
01290         nonce_ext_64_ptr = rf_ptr->mac64;
01291     }
01292 
01293     uint8_t *key_ptr = key_description->Key;
01294 
01295     //Check If frame counter overflow is coming
01296     if (buffer->aux_header.frameCounter == 0xffffffff) {
01297         buffer->status = MLME_COUNTER_ERROR;
01298         return false;
01299     }
01300 
01301     if (!ccm_sec_init(ccm_ptr, buffer->aux_header.securityLevel, key_ptr, AES_CCM_ENCRYPT, 2)) {
01302         buffer->status = MLME_SECURITY_FAIL;
01303         return false;
01304     }
01305 
01306     mac_security_interface_aux_ccm_nonce_set(ccm_ptr->exp_nonce, nonce_ext_64_ptr, buffer->aux_header.frameCounter,
01307                                              buffer->aux_header.securityLevel);
01308     return true;
01309 
01310 }
01311 
01312 
01313 static void mac_common_data_confirmation_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buf)
01314 {
01315     mac_event_t m_event;
01316     /* Raed MAC TX state */
01317     m_event = (mac_event_t) rf_mac_setup->mac_tx_result;
01318     rf_mac_setup->mac_tx_result = MAC_STATE_IDLE;
01319 
01320     /* Discard Tx timeout timer */
01321     timer_mac_stop(rf_mac_setup);
01322     if (m_event == MAC_CCA_FAIL) {
01323         sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_CCA_FAIL, 0);
01324         tr_debug("MAC CCA fail");
01325         /* CCA fail */
01326         //rf_mac_setup->cca_failure++;
01327         buf->status = MLME_BUSY_CHAN;
01328     } else {
01329         sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_COUNT, buf->mac_payload_length);
01330         if (m_event == MAC_TX_FAIL) {
01331             sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_FAIL, 0);
01332             tr_debug("MAC tx fail");
01333             buf->status = MLME_TX_NO_ACK;
01334         } else if (m_event == MAC_TX_DONE) {
01335             if (mac_is_ack_request_set(buf) == false) {
01336                 sw_mac_stats_update(rf_mac_setup, STAT_MAC_BC_TX_COUNT, 0);
01337             }
01338             if (buf->fcf_dsn.frametype == FC_CMD_FRAME && buf->mac_command_id == MAC_DATA_REQ) {
01339                 buf->status = MLME_NO_DATA;
01340             } else {
01341                 buf->status = MLME_SUCCESS;
01342             }
01343 
01344         } else if (m_event == MAC_TX_DONE_PENDING) {
01345             buf->status = MLME_SUCCESS;
01346         } else if (m_event == MAC_TX_TIMEOUT) {
01347             /* Make MAC Soft Reset */;
01348             tr_debug("Driver TO event");
01349             //Disable allways
01350             mac_mlme_mac_radio_disabled(rf_mac_setup);
01351             //Enable Radio
01352             mac_mlme_mac_radio_enable(rf_mac_setup);
01353             buf->status = MLME_TRANSACTION_EXPIRED;
01354         } else if (m_event == MAC_UNKNOWN_DESTINATION) {
01355             buf->status = MLME_UNAVAILABLE_KEY;
01356         } else if (m_event == MAC_ACK_SECURITY_FAIL) {
01357             buf->status = MLME_TX_NO_ACK;
01358         }/** else if (m_event == MAC_TX_PRECOND_FAIL) {
01359            * Nothing to do, status already set to buf->status.
01360         }**/
01361     }
01362 }
01363 
01364 void mac_data_wait_timer_start(protocol_interface_rf_mac_setup_s *rf_mac_setup)
01365 {
01366     eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
01367     eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 200); //10ms
01368     rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL;
01369     rf_mac_setup->mlme_tick_count = 30; //300ms
01370 }
01371 
01372 static void mac_data_interface_internal_tx_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buf)
01373 {
01374     //GET Interface
01375 
01376     switch (buf->mac_command_id) {
01377         case MAC_DATA_REQ:
01378 
01379             if (buf->status == MLME_SUCCESS) {
01380                 if (!rf_mac_setup->macRxDataAtPoll) {
01381                     //Start Timer
01382                     mac_data_wait_timer_start(rf_mac_setup);
01383                     //Set Buffer back to
01384                 }
01385                 rf_mac_setup->active_pd_data_request = buf;
01386                 return;
01387 
01388             } else {
01389                 //Disable Radio
01390                 if (!rf_mac_setup->macCapRxOnIdle) {
01391                     mac_mlme_mac_radio_disabled(rf_mac_setup);
01392                 }
01393                 rf_mac_setup->macDataPollReq = false;
01394 
01395                 mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup);
01396 
01397                 if (mac_api) {
01398                     mlme_poll_conf_t confirm;
01399                     confirm.status = buf->status;
01400                     mac_api->mlme_conf_cb(mac_api, MLME_POLL, &confirm);
01401                 }
01402 
01403             }
01404             break;
01405 
01406         case MAC_BEACON_REQ:
01407             mac_mlme_active_scan_response_timer_start(rf_mac_setup);
01408             break;
01409 
01410         default:
01411             if (rf_mac_setup->tun_extension_rf_driver) {
01412                 if (buf->fcf_dsn.ackRequested) {
01413                     phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
01414                     driver->phy_tx_done_cb(rf_mac_setup->tun_extension_rf_driver->id, 1, (phy_link_tx_status_e)buf->status, rf_mac_setup->mac_tx_status.cca_cnt, rf_mac_setup->mac_tx_status.retry);
01415                 }
01416             }
01417             break;
01418     }
01419 
01420     mcps_sap_prebuild_frame_buffer_free(buf);
01421 
01422 }
01423 
01424 static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mac_pre_parsed_frame_t *ack_buf)
01425 {
01426 
01427     sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt);
01428     sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry);
01429     mcps_data_conf_t confirm;
01430     if (rf_ptr->fhss_api && !buffer->asynch_request) {
01431         // FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted
01432         if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) {
01433             if (rf_ptr->fhss_api->data_tx_fail(rf_ptr->fhss_api, buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) {
01434 
01435                 if (rf_ptr->mac_tx_result == MAC_TX_FAIL) {
01436                     buffer->fhss_retry_count += 1 + rf_ptr->mac_tx_status.retry;
01437                 } else {
01438                     buffer->fhss_retry_count += rf_ptr->mac_tx_status.retry;
01439                 }
01440                 buffer->fhss_cca_retry_count += rf_ptr->mac_tx_status.cca_cnt;
01441                 mcps_sap_pd_req_queue_write(rf_ptr, buffer);
01442                 return;
01443             }
01444         }
01445     }
01446     confirm.cca_retries = rf_ptr->mac_tx_status.cca_cnt + buffer->fhss_cca_retry_count;
01447     confirm.tx_retries = rf_ptr->mac_tx_status.retry + buffer->fhss_retry_count;
01448     mac_common_data_confirmation_handle(rf_ptr, buffer);
01449     confirm.msduHandle = buffer->msduHandle;
01450     confirm.status = buffer->status;
01451     if (ack_buf) {
01452         confirm.timestamp = ack_buf->timestamp;
01453     } else {
01454         confirm.timestamp = 0;
01455     }
01456 
01457     if (buffer->upper_layer_request) {
01458         //Check tunnel
01459         mcps_sap_prebuild_frame_buffer_free(buffer);
01460         mcps_data_confirm_cb(rf_ptr, &confirm, ack_buf);
01461     } else {
01462         mac_data_interface_internal_tx_confirm_handle(rf_ptr, buffer);
01463     }
01464 }
01465 
01466 static void mac_security_data_params_set(ccm_globals_t *ccm_ptr, uint8_t *data_ptr, uint16_t msduLength)
01467 {
01468     ccm_ptr->data_len = msduLength;
01469     ccm_ptr->data_ptr = data_ptr;
01470 }
01471 
01472 
01473 static void mac_security_authentication_data_params_set(ccm_globals_t *ccm_ptr, uint8_t *a_data_ptr,
01474                                                         uint8_t a_data_length)
01475 {
01476     if (ccm_ptr->mic_len) {
01477 
01478         ccm_ptr->adata_len = a_data_length;
01479         ccm_ptr->adata_ptr = a_data_ptr;
01480         ccm_ptr->mic = ccm_ptr->data_ptr;
01481         ccm_ptr->mic += ccm_ptr->data_len;
01482     }
01483 }
01484 
01485 static uint32_t mcps_calculate_tx_time(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint32_t time_to_tx)
01486 {
01487     // Max. time to TX is 65ms
01488     if (time_to_tx > 65000) {
01489         time_to_tx = 65000;
01490     }
01491     return mac_mcps_sap_get_phy_timestamp(rf_mac_setup) + time_to_tx;
01492 }
01493 
01494 static void mcps_generic_sequence_number_allocate(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01495 {
01496     if (buffer->fcf_dsn.frameVersion < MAC_FRAME_VERSION_2015 || (buffer->fcf_dsn.frameVersion ==  MAC_FRAME_VERSION_2015 &&  !buffer->fcf_dsn.sequenceNumberSuppress)) {
01497         /* Allocate SQN */
01498         switch (buffer->fcf_dsn.frametype) {
01499             case MAC_FRAME_CMD:
01500             case MAC_FRAME_DATA:
01501                 buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr);
01502                 break;
01503             case MAC_FRAME_BEACON:
01504                 buffer->fcf_dsn.DSN = mac_mlme_set_new_beacon_sqn(rf_ptr);
01505                 break;
01506             default:
01507                 break;
01508         }
01509     }
01510 }
01511 
01512 
01513 static uint32_t mcps_generic_backoff_calc(protocol_interface_rf_mac_setup_s *rf_ptr)
01514 {
01515     uint32_t random_period = mac_csma_backoff_get(rf_ptr);
01516     if (rf_ptr->rf_csma_extension_supported) {
01517         return mcps_calculate_tx_time(rf_ptr, random_period);
01518     }
01519     return random_period;
01520 }
01521 
01522 static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01523 {
01524     phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver;
01525     dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer;
01526 
01527     ccm_globals_t ccm_ptr;
01528 
01529     if (buffer->mac_header_length_with_security == 0) {
01530         rf_ptr->mac_tx_status.length = buffer->mac_payload_length;
01531         uint8_t *ptr = tx_buf->buf;
01532         if (dev_driver->phy_header_length) {
01533             ptr += dev_driver->phy_header_length;
01534         }
01535         tx_buf->len = buffer->mac_payload_length;
01536 
01537         memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length);
01538         buffer->tx_time = mcps_generic_backoff_calc(rf_ptr);
01539         return 0;
01540     }
01541 
01542     //This will prepare MHR length with Header IE
01543     mac_header_information_elements_preparation(buffer);
01544 
01545     mcps_generic_sequence_number_allocate(rf_ptr, buffer);
01546     mlme_key_descriptor_t *key_desc = NULL;
01547     if (buffer->fcf_dsn.securityEnabled) {
01548         bool increment_framecounter = false;
01549         //Remember to update security counter here!
01550         key_desc = mac_frame_security_key_get(rf_ptr, buffer);
01551         if (!key_desc) {
01552             buffer->status = MLME_UNAVAILABLE_KEY;
01553             return -2;
01554         }
01555 
01556         //GET Counter
01557         uint32_t new_frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
01558         // If buffer frame counter is set, this is FHSS channel retry, update frame counter only if something was sent after failure
01559         if ((buffer->aux_header.frameCounter == 0xffffffff) || buffer->asynch_request || mac_data_counter_too_small(new_frameCounter, buffer->aux_header.frameCounter)) {
01560             buffer->aux_header.frameCounter = new_frameCounter;
01561             increment_framecounter = true;
01562         }
01563 
01564         if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
01565             return -2;
01566         }
01567         //Increment security counter
01568         if (increment_framecounter) {
01569             mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
01570         }
01571     }
01572 
01573     //Calculate Payload length here with IE extension
01574     uint16_t frame_length = mac_buffer_total_payload_length(buffer);
01575     //Storage Mac Payload length here
01576     uint16_t mac_payload_length = frame_length;
01577 
01578     if (mac_payload_length > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE &&
01579             dev_driver->phy_MTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) {
01580         /* IEEE 802.15.4-2003 only allowed unsecured payloads up to 102 bytes
01581         * (always leaving room for maximum MAC overhead).
01582         * IEEE 802.15.4-2006 allows bigger if MAC header is small enough, but
01583         * we have to set the version field.
01584         */
01585         if (buffer->fcf_dsn.frameVersion < MAC_FRAME_VERSION_2006) {
01586             buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
01587         }
01588     }
01589 
01590     if (rf_ptr->mac_ack_tx_active) {
01591         if (buffer->fcf_dsn.securityEnabled) {
01592             ccm_free(&ccm_ptr);
01593         }
01594         return 0;
01595     }
01596 
01597     //Add MHR length to total length
01598     frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
01599     if ((frame_length) > dev_driver->phy_MTU - 2) {
01600         tr_debug("Too Long %u, %u pa %u header %u mic %u", frame_length, mac_payload_length, buffer->mac_header_length_with_security,  buffer->security_mic_len, dev_driver->phy_MTU);
01601         buffer->status = MLME_FRAME_TOO_LONG;
01602         //decrement security counter
01603         if (key_desc) {
01604             mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
01605         }
01606         return -1;
01607     }
01608 
01609     rf_ptr->mac_tx_status.length = frame_length;
01610     uint8_t *ptr = tx_buf->buf;
01611     if (dev_driver->phy_header_length) {
01612         ptr += dev_driver->phy_header_length;
01613     }
01614 
01615     tx_buf->len = frame_length;
01616     uint8_t *mhr_start = ptr;
01617     buffer->tx_time = mcps_generic_backoff_calc(rf_ptr);
01618 
01619     ptr = mac_generic_packet_write(rf_ptr, ptr, buffer);
01620 
01621 
01622     if (buffer->fcf_dsn.securityEnabled) {
01623         uint8_t open_payload = 0;
01624         if (buffer->fcf_dsn.frametype == MAC_FRAME_CMD) {
01625             open_payload = 1;
01626         }
01627         mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security + open_payload)), (mac_payload_length - open_payload));
01628         mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security + open_payload));
01629         ccm_process_run(&ccm_ptr);
01630     }
01631 
01632     return 0;
01633 }
01634 
01635 int8_t mcps_generic_ack_data_request_init(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload)
01636 {
01637     mac_pre_build_frame_t *buffer = &rf_ptr->enhanced_ack_buffer;
01638     //save timestamp
01639     rf_ptr->enhanced_ack_handler_timestamp = mac_mcps_sap_get_phy_timestamp(rf_ptr);
01640 
01641     memset(buffer, 0, sizeof(mac_pre_build_frame_t));
01642     buffer->fcf_dsn.frametype = FC_ACK_FRAME;
01643     buffer->fcf_dsn.frameVersion = fcf->frameVersion;
01644     buffer->fcf_dsn.framePending = rf_ptr->mac_frame_pending;
01645     buffer->fcf_dsn.DSN = fcf->DSN;
01646     buffer->fcf_dsn.intraPan = fcf->intraPan;
01647     buffer->fcf_dsn.sequenceNumberSuppress = fcf->sequenceNumberSuppress;
01648     buffer->fcf_dsn.DstPanPresents = fcf->DstPanPresents;
01649     buffer->fcf_dsn.SrcAddrMode = fcf->DstAddrMode;
01650     buffer->fcf_dsn.SrcPanPresents = fcf->SrcPanPresents;
01651     buffer->fcf_dsn.DstAddrMode = fcf->SrcAddrMode;
01652 
01653     if (buffer->fcf_dsn.sequenceNumberSuppress) {
01654         buffer->mac_header_length_with_security = 2;
01655     } else {
01656         buffer->mac_header_length_with_security = 3;
01657     }
01658 
01659     buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
01660 
01661     buffer->DstPANId = mac_header_get_src_panid(fcf, data_ptr, rf_ptr->pan_id);
01662     buffer->SrcPANId = mac_header_get_dst_panid(fcf, data_ptr, rf_ptr->pan_id);
01663     mac_header_get_src_address(fcf, data_ptr, buffer->DstAddr);
01664     mac_header_get_dst_address(fcf, data_ptr, buffer->SrcAddr);
01665 
01666     //Security
01667     buffer->fcf_dsn.securityEnabled = fcf->securityEnabled;
01668     if (buffer->fcf_dsn.securityEnabled) {
01669         //Read Security AUX headers
01670         const uint8_t *ptr = data_ptr;
01671         ptr += mac_header_off_set_to_aux_header(fcf);
01672         //Start parsing AUX header
01673         mlme_security_t aux_parse;
01674         mac_header_security_aux_header_parse(ptr, &aux_parse);
01675         buffer->aux_header.KeyIdMode = aux_parse.KeyIdMode;
01676         buffer->aux_header.KeyIndex = aux_parse.KeyIndex;
01677         buffer->aux_header.securityLevel = aux_parse.SecurityLevel;
01678         memcpy(buffer->aux_header.Keysource, aux_parse.Keysource, 8);
01679 
01680         buffer->security_mic_len = mac_security_mic_length_get(buffer->aux_header.securityLevel);
01681         buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
01682         buffer->mac_header_length_with_security += mac_header_security_aux_header_length(buffer->aux_header.securityLevel, buffer->aux_header.KeyIdMode);
01683 
01684     }
01685 
01686     uint16_t ie_header_length = 0;
01687     uint16_t ie_payload_length = 0;
01688 
01689     if (!mac_ie_vector_length_validate(ack_payload->ie_elements.headerIeVectorList, ack_payload->ie_elements.headerIovLength, &ie_header_length)) {
01690         return -1;
01691     }
01692 
01693     if (!mac_ie_vector_length_validate(ack_payload->ie_elements.payloadIeVectorList, ack_payload->ie_elements.payloadIovLength, &ie_payload_length)) {
01694         return -1;
01695     }
01696 
01697     buffer->ie_elements.headerIeVectorList = ack_payload->ie_elements.headerIeVectorList;
01698     buffer->ie_elements.headerIovLength = ack_payload->ie_elements.headerIovLength;
01699     buffer->ie_elements.payloadIeVectorList = ack_payload->ie_elements.payloadIeVectorList;
01700     buffer->ie_elements.payloadIovLength = ack_payload->ie_elements.payloadIovLength;
01701     buffer->headerIeLength = ie_header_length;
01702     buffer->payloadsIeLength = ie_payload_length;
01703     buffer->mac_payload = ack_payload->payloadPtr;
01704     buffer->mac_payload_length = ack_payload->payloadLength;
01705 
01706     //This will prepare MHR length with Header IE
01707     mac_header_information_elements_preparation(buffer);
01708     return 0;
01709 }
01710 
01711 
01712 int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool init_build)
01713 {
01714     phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver;
01715     dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer;
01716 
01717     ccm_globals_t ccm_ptr;
01718     mac_pre_build_frame_t *buffer = &rf_ptr->enhanced_ack_buffer;
01719     mlme_key_descriptor_t *key_desc = NULL;
01720 
01721     if (buffer->fcf_dsn.securityEnabled) {
01722         //Remember to update security counter here!
01723         key_desc = mac_frame_security_key_get(rf_ptr, buffer);
01724         if (!key_desc) {
01725             buffer->status = MLME_UNAVAILABLE_KEY;
01726             return -2;
01727         }
01728         if (init_build) {
01729             buffer->aux_header.frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
01730         }
01731         if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
01732             return -2;
01733         }
01734         if (init_build) {
01735             //Increment security counter
01736             mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
01737         }
01738     }
01739 
01740     //Calculate Payload length here with IE extension
01741     uint16_t frame_length = mac_buffer_total_payload_length(buffer);
01742     //Storage Mac Payload length here
01743     uint16_t mac_payload_length = frame_length;
01744 
01745     //Add MHR length to total length
01746     frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
01747     uint16_t ack_mtu_size;
01748     if (ENHANCED_ACK_MAX_LENGTH > dev_driver->phy_MTU) {
01749         ack_mtu_size = dev_driver->phy_MTU;
01750     } else {
01751         ack_mtu_size = ENHANCED_ACK_MAX_LENGTH;
01752     }
01753 
01754 
01755     if ((frame_length) > ack_mtu_size - 2) {
01756         buffer->status = MLME_FRAME_TOO_LONG;
01757 
01758         if (key_desc) {
01759             //decrement security counter
01760             mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
01761             ccm_free(&ccm_ptr);
01762         }
01763         return -1;
01764     }
01765 
01766     rf_ptr->mac_tx_status.length = frame_length;
01767     uint8_t *ptr = tx_buf->enhanced_ack_buf;
01768     if (dev_driver->phy_header_length) {
01769         ptr += dev_driver->phy_header_length;
01770     }
01771 
01772     tx_buf->ack_len = frame_length;
01773     uint8_t *mhr_start = ptr;
01774     buffer->tx_time = mac_mcps_sap_get_phy_timestamp(rf_ptr) + 300; //Send 300 us later
01775 
01776     ptr = mac_generic_packet_write(rf_ptr, ptr, buffer);
01777 
01778 
01779     if (buffer->fcf_dsn.securityEnabled) {
01780         mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security)), (mac_payload_length));
01781         mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security));
01782         ccm_process_run(&ccm_ptr);
01783     }
01784     //Disable TX Time
01785     phy_csma_params_t csma_params;
01786     csma_params.backoff_time = 0;
01787     csma_params.cca_enabled = false;
01788     rf_ptr->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CSMA_PARAMETERS, (uint8_t *) &csma_params);
01789     if (rf_ptr->active_pd_data_request) {
01790         timer_mac_stop(rf_ptr);
01791         mac_pd_abort_active_tx(rf_ptr);
01792     }
01793     return mcps_pd_data_cca_trig(rf_ptr, buffer);
01794 }
01795 
01796 
01797 static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01798 {
01799     phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver;
01800     dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer;
01801     ccm_globals_t ccm_ptr;
01802 
01803     if (!buffer) {
01804         return -1;
01805     }
01806 
01807     if (buffer->mac_header_length_with_security == 0) {
01808         rf_ptr->mac_tx_status.length = buffer->mac_payload_length;
01809         uint8_t *ptr = tx_buf->buf;
01810         if (dev_driver->phy_header_length) {
01811             ptr += dev_driver->phy_header_length;
01812         }
01813         tx_buf->len = buffer->mac_payload_length;
01814 
01815         memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length);
01816         buffer->tx_time = mcps_generic_backoff_calc(rf_ptr);
01817         return 0;
01818     }
01819 
01820     if (buffer->fcf_dsn.securityEnabled) {
01821 
01822         mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_ptr, buffer);
01823         if (!key_desc) {
01824             buffer->status = MLME_UNAVAILABLE_KEY;
01825             return -2;
01826         }
01827 
01828         if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
01829             return -2;
01830         }
01831     }
01832 
01833     //Calculate Payload length here with IE extension
01834     uint16_t frame_length = mac_buffer_total_payload_length(buffer);
01835     //Storage Mac Payload length here
01836     uint16_t mac_payload_length = frame_length;
01837 
01838     //Add MHR length to total length
01839     frame_length += buffer->mac_header_length_with_security + buffer->security_mic_len;
01840 
01841     rf_ptr->mac_tx_status.length = frame_length;
01842     uint8_t *ptr = tx_buf->buf;
01843     if (dev_driver->phy_header_length) {
01844         ptr += dev_driver->phy_header_length;
01845     }
01846 
01847     tx_buf->len = frame_length;
01848     uint8_t *mhr_start = ptr;
01849 
01850     buffer->tx_time = mcps_generic_backoff_calc(rf_ptr);
01851 
01852     ptr = mac_generic_packet_write(rf_ptr, ptr, buffer);
01853 
01854     if (buffer->fcf_dsn.securityEnabled) {
01855         uint8_t open_payload = 0;
01856         if (buffer->fcf_dsn.frametype == MAC_FRAME_CMD) {
01857             open_payload = 1;
01858         }
01859         mac_security_data_params_set(&ccm_ptr, (mhr_start + (buffer->mac_header_length_with_security + open_payload)), (mac_payload_length - open_payload));
01860         mac_security_authentication_data_params_set(&ccm_ptr, mhr_start, (buffer->mac_header_length_with_security + open_payload));
01861         ccm_process_run(&ccm_ptr);
01862     }
01863 
01864     return 0;
01865 }
01866 
01867 static int8_t mcps_pd_data_cca_trig(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01868 {
01869     platform_enter_critical();
01870     mac_mlme_mac_radio_enable(rf_ptr);
01871     rf_ptr->macTxProcessActive = true;
01872     if (rf_ptr->rf_csma_extension_supported) {
01873         //Write TX time
01874         bool cca_enabled;
01875         if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {
01876             cca_enabled = false;
01877             rf_ptr->mac_ack_tx_active = true;
01878         } else {
01879             if (rf_ptr->mac_ack_tx_active) {
01880                 mac_csma_backoff_start(rf_ptr);
01881                 platform_exit_critical();
01882                 return -1;
01883             }
01884             cca_enabled = true;
01885         }
01886         // Use double CCA check with FHSS for data packets only
01887         if (rf_ptr->fhss_api && !rf_ptr->mac_ack_tx_active && !rf_ptr->active_pd_data_request->asynch_request) {
01888             if ((buffer->tx_time - (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1))) > mac_mcps_sap_get_phy_timestamp(rf_ptr)) {
01889                 buffer->csma_periods_left = rf_ptr->number_of_csma_ca_periods - 1;
01890                 buffer->tx_time -= (rf_ptr->multi_cca_interval * (rf_ptr->number_of_csma_ca_periods - 1));
01891             }
01892         }
01893         mac_pd_sap_set_phy_tx_time(rf_ptr, buffer->tx_time, cca_enabled);
01894         if (mac_plme_cca_req(rf_ptr) != 0) {
01895             if (buffer->fcf_dsn.frametype == MAC_FRAME_ACK) {
01896                 rf_ptr->mac_ack_tx_active = false;
01897                 // For Ack, stop the active TX process
01898                 rf_ptr->macTxProcessActive = false;
01899                 // If MAC had TX process active before Ack transmission,
01900                 // the TX process has to be restarted in case the Ack transmission failed.
01901                 if (rf_ptr->active_pd_data_request) {
01902                     mac_csma_backoff_start(rf_ptr);
01903                 }
01904                 platform_exit_critical();
01905                 return -1;
01906             }
01907             mac_csma_backoff_start(rf_ptr);
01908         }
01909     } else {
01910         timer_mac_start(rf_ptr, MAC_TIMER_CCA, (uint16_t)(buffer->tx_time / 50));
01911     }
01912     platform_exit_critical();
01913     return 0;
01914 }
01915 
01916 static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01917 {
01918     rf_ptr->macTxRequestAck = false;
01919 
01920 
01921     memset(&(rf_ptr->mac_tx_status), 0, sizeof(mac_tx_status_t));
01922     rf_ptr->mac_cca_retry = 0;
01923     rf_ptr->mac_tx_retry = 0;
01924     mac_csma_param_init(rf_ptr);
01925     if (mcps_generic_packet_build(rf_ptr, buffer) != 0) {
01926         return -1;
01927     }
01928     rf_ptr->macTxRequestAck = buffer->fcf_dsn.ackRequested;
01929     if (!rf_ptr->mac_ack_tx_active) {
01930         return mcps_pd_data_cca_trig(rf_ptr, buffer);
01931     } else {
01932         return 0;
01933     }
01934 
01935 }
01936 
01937 int8_t mcps_pd_data_rebuild(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01938 {
01939     if (mcps_generic_packet_rebuild(rf_ptr, buffer) != 0) {
01940         return -1;
01941     }
01942 
01943     return mcps_pd_data_cca_trig(rf_ptr, buffer);
01944 }
01945 
01946 
01947 bool mac_is_ack_request_set(mac_pre_build_frame_t *buffer)
01948 {
01949     return buffer->fcf_dsn.ackRequested;
01950 }
01951 
01952 int mac_convert_frame_type_to_fhss(uint8_t frame_type)
01953 {
01954     if (FC_BEACON_FRAME == frame_type) {
01955         return FHSS_SYNCH_FRAME;
01956     }
01957     if (FC_CMD_FRAME == frame_type) {
01958         return FHSS_SYNCH_REQUEST_FRAME;
01959     }
01960     return FHSS_DATA_FRAME;
01961 }
01962 
01963 void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
01964 {
01965     if (!rf_mac_setup || !buffer) {
01966         return;
01967     }
01968     if (!rf_mac_setup->active_pd_data_request) {
01969         // Push broadcast buffers to queue when broadcast disabled flag is set
01970         if ((rf_mac_setup->macBroadcastDisabled == true) && !mac_is_ack_request_set(buffer)) {
01971             goto push_to_queue;
01972         }
01973         if (rf_mac_setup->fhss_api && (buffer->asynch_request == false)) {
01974             uint16_t frame_length = buffer->mac_payload_length + buffer->headerIeLength + buffer->payloadsIeLength;
01975             if (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
01976                                                             buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), frame_length,
01977                                                             rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == false) {
01978                 goto push_to_queue;
01979             }
01980         }
01981         //Start TX process immediately
01982         rf_mac_setup->active_pd_data_request = buffer;
01983         if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
01984             rf_mac_setup->mac_tx_result = MAC_TX_PRECOND_FAIL;
01985             rf_mac_setup->macTxRequestAck = false;
01986             if (mcps_sap_pd_confirm(rf_mac_setup) != 0) {
01987                 // can't send event, try calling error handler directly
01988                 rf_mac_setup->mac_mcps_data_conf_fail.msduHandle = buffer->msduHandle;
01989                 rf_mac_setup->mac_mcps_data_conf_fail.status = buffer->status;
01990                 mcps_sap_prebuild_frame_buffer_free(buffer);
01991                 rf_mac_setup->active_pd_data_request = NULL;
01992                 mac_pd_data_confirm_failure_handle(rf_mac_setup);
01993             }
01994         }
01995 
01996         return;
01997     }
01998 push_to_queue:
01999     rf_mac_setup->direct_queue_bytes += buffer->mac_payload_length;
02000     mac_pre_build_frame_t *prev = NULL;
02001     mac_pre_build_frame_t *cur = rf_mac_setup->pd_data_request_queue_to_go;
02002     bool use_bc_queue = false;
02003 
02004     // When FHSS is enabled, broadcast buffers are pushed to own queue
02005     if (rf_mac_setup->fhss_api && (buffer->asynch_request == false)) {
02006         if (rf_mac_setup->fhss_api->use_broadcast_queue(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
02007                                                         mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) {
02008             cur = rf_mac_setup->pd_data_request_bc_queue_to_go;
02009             use_bc_queue = true;
02010             rf_mac_setup->broadcast_queue_size++;
02011         }
02012     }
02013     if (use_bc_queue == false) {
02014         rf_mac_setup->unicast_queue_size++;
02015     }
02016     sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_QUEUE, rf_mac_setup->unicast_queue_size + rf_mac_setup->broadcast_queue_size);
02017 
02018     //Push to queue
02019     if (!cur) {
02020         if (rf_mac_setup->fhss_api && (use_bc_queue == true)) {
02021             rf_mac_setup->pd_data_request_bc_queue_to_go = buffer;
02022             return;
02023         } else {
02024             rf_mac_setup->pd_data_request_queue_to_go = buffer;
02025             return;
02026         }
02027     }
02028 
02029     while (cur) {
02030         if (cur->priority < buffer->priority) {
02031             //Set before cur
02032             if (prev) {
02033                 prev->next = buffer;
02034                 buffer->next = cur;
02035             } else {
02036                 buffer->next = cur;
02037                 if (rf_mac_setup->fhss_api && (use_bc_queue == true)) {
02038                     rf_mac_setup->pd_data_request_bc_queue_to_go = buffer;
02039                 } else {
02040                     rf_mac_setup->pd_data_request_queue_to_go = buffer;
02041                 }
02042             }
02043             cur = NULL;
02044 
02045         } else if (cur->next == NULL) {
02046             cur->next = buffer;
02047             cur = NULL;
02048         } else {
02049             prev = cur;
02050             cur = cur->next;
02051         }
02052     }
02053 }
02054 
02055 static mac_pre_build_frame_t *mcps_sap_pd_req_queue_read(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool is_bc_queue, bool flush)
02056 {
02057     mac_pre_build_frame_t *queue = rf_mac_setup->pd_data_request_queue_to_go;
02058     if (is_bc_queue == true) {
02059         queue = rf_mac_setup->pd_data_request_bc_queue_to_go;
02060     }
02061 
02062     if (!queue) {
02063         return NULL;
02064     }
02065 
02066     mac_pre_build_frame_t *buffer = queue;
02067     mac_pre_build_frame_t *prev = NULL;
02068     // With FHSS, check TX conditions
02069     if (rf_mac_setup->fhss_api) {
02070         while (buffer) {
02071             if (buffer->asynch_request || (flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
02072                                                                                                           buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length,
02073                                                                                                           rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == true)) {
02074                 break;
02075             }
02076             prev = buffer;
02077             buffer = buffer->next;
02078         }
02079     }
02080     // This check is here to prevent (Linux) border router from pushing broadcast frames to RF interface on unicast channel.
02081     while (buffer) {
02082         /* Allow returning buffer when:
02083          * - Flush is enabled
02084          * - Broadcast not disabled
02085          * - Broadcast is disabled and buffer has unicast destination
02086          */
02087         if ((flush == true) || (rf_mac_setup->macBroadcastDisabled == false) || ((rf_mac_setup->macBroadcastDisabled == true) && mac_is_ack_request_set(buffer))) {
02088             break;
02089         }
02090         prev = buffer;
02091         buffer = buffer->next;
02092     }
02093     if (!buffer) {
02094         return NULL;
02095     }
02096     // When other than first buffer is read out, link next buffer to previous buffer
02097     if (prev) {
02098         prev->next = buffer->next;
02099     }
02100 
02101     // When the first buffer is read out, set next buffer as the new first buffer
02102     if (is_bc_queue == false) {
02103         if (!prev) {
02104             rf_mac_setup->pd_data_request_queue_to_go = buffer->next;
02105         }
02106         rf_mac_setup->unicast_queue_size--;
02107     } else {
02108         if (!prev) {
02109             rf_mac_setup->pd_data_request_bc_queue_to_go = buffer->next;
02110         }
02111         rf_mac_setup->broadcast_queue_size--;
02112     }
02113     buffer->next = NULL;
02114     rf_mac_setup->direct_queue_bytes -= buffer->mac_payload_length;
02115 
02116     sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_QUEUE, rf_mac_setup->unicast_queue_size + rf_mac_setup->broadcast_queue_size);
02117     return buffer;
02118 }
02119 
02120 void mcps_sap_pre_parsed_frame_buffer_free(mac_pre_parsed_frame_t *buf)
02121 {
02122     ns_dyn_mem_free(buf);
02123 }
02124 
02125 mac_pre_parsed_frame_t *mcps_sap_pre_parsed_frame_buffer_get(const uint8_t *data_ptr, uint16_t frame_length)
02126 {
02127     // check that system has enough space to handle the new packet
02128     const mem_stat_t *ns_dyn_mem_stat = ns_dyn_mem_get_mem_stat();
02129     if (ns_dyn_mem_stat && ns_dyn_mem_stat->heap_sector_allocated_bytes > ns_dyn_mem_rate_limiting_threshold) {
02130         return NULL;
02131     }
02132 
02133     mac_pre_parsed_frame_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(mac_pre_parsed_frame_t) + frame_length);
02134 
02135     if (buffer) {
02136         memset(buffer, 0, sizeof(mac_pre_parsed_frame_t) + frame_length);
02137         buffer->frameLength = frame_length;
02138         memcpy(mac_header_message_start_pointer(buffer), data_ptr, frame_length);
02139     }
02140 
02141     return buffer;
02142 }
02143 
02144 static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
02145 {
02146     rf_mac_setup->active_mac_events |= (1 << event_type);
02147 }
02148 
02149 static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
02150 {
02151     rf_mac_setup->active_mac_events &= ~(1 << event_type);
02152 }
02153 
02154 static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
02155 {
02156     if (rf_mac_setup->active_mac_events & (1 << event_type)) {
02157         return true;
02158     }
02159     return false;
02160 }
02161 
02162 int8_t mcps_sap_pd_ind(mac_pre_parsed_frame_t *buffer)
02163 {
02164     if (mac_tasklet_event_handler < 0 || !buffer) {
02165         return -1;
02166     }
02167 
02168     arm_event_s event = {
02169         .receiver = mac_tasklet_event_handler,
02170         .sender = 0,
02171         .event_id = 0,
02172         .data_ptr = buffer,
02173         .event_type = MCPS_SAP_DATA_IND_EVENT,
02174         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
02175     };
02176 
02177     return eventOS_event_send(&event);
02178 }
02179 
02180 int8_t mcps_sap_pd_confirm(void *mac_ptr)
02181 {
02182     if (mac_tasklet_event_handler < 0  || !mac_ptr) {
02183         return -2;
02184     }
02185     arm_event_s event = {
02186         .receiver = mac_tasklet_event_handler,
02187         .sender = 0,
02188         .event_id = 0,
02189         .data_ptr = mac_ptr,
02190         .event_type = MCPS_SAP_DATA_CNF_EVENT,
02191         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
02192     };
02193 
02194     return eventOS_event_send(&event);
02195 }
02196 
02197 int8_t mcps_sap_pd_confirm_failure(void *mac_ptr)
02198 {
02199     if (mac_tasklet_event_handler < 0  || !mac_ptr) {
02200         return -2;
02201     }
02202     arm_event_s event = {
02203         .receiver = mac_tasklet_event_handler,
02204         .sender = 0,
02205         .event_id = 0,
02206         .data_ptr = mac_ptr,
02207         .event_type = MCPS_SAP_DATA_CNF_FAIL_EVENT,
02208         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
02209     };
02210 
02211     return eventOS_event_send(&event);
02212 }
02213 
02214 void mcps_sap_pd_ack(void *ack_ptr)
02215 {
02216     if (mac_tasklet_event_handler < 0  || !ack_ptr) {
02217         return;
02218     }
02219     arm_event_s event = {
02220         .receiver = mac_tasklet_event_handler,
02221         .sender = 0,
02222         .event_id = 0,
02223         .data_ptr = ack_ptr,
02224         .event_type = MCPS_SAP_DATA_ACK_CNF_EVENT,
02225         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
02226     };
02227 
02228     eventOS_event_send(&event);
02229 }
02230 
02231 void mcps_sap_trig_tx(void *mac_ptr)
02232 {
02233     if (mac_tasklet_event_handler < 0  || !mac_ptr) {
02234         return;
02235     }
02236     if (mac_read_active_event(mac_ptr, MAC_SAP_TRIG_TX) == true) {
02237         return;
02238     }
02239     arm_event_s event = {
02240         .receiver = mac_tasklet_event_handler,
02241         .sender = 0,
02242         .event_id = 0,
02243         .data_ptr = mac_ptr,
02244         .event_type = MAC_SAP_TRIG_TX,
02245         .priority = ARM_LIB_MED_PRIORITY_EVENT,
02246     };
02247 
02248     if (eventOS_event_send(&event) == 0) {
02249         mac_set_active_event(mac_ptr, MAC_SAP_TRIG_TX);
02250     }
02251 }
02252 
02253 
02254 void mac_generic_event_trig(uint8_t event_type, void *mac_ptr, bool low_latency)
02255 {
02256     arm_library_event_priority_e priority;
02257     if (low_latency) {
02258         priority = ARM_LIB_LOW_PRIORITY_EVENT;
02259     } else {
02260         priority = ARM_LIB_HIGH_PRIORITY_EVENT;
02261     }
02262     arm_event_s event = {
02263         .receiver = mac_tasklet_event_handler,
02264         .sender = 0,
02265         .event_id = 0,
02266         .data_ptr = mac_ptr,
02267         .event_type = event_type,
02268         .priority = priority,
02269     };
02270 
02271     eventOS_event_send(&event);
02272 }
02273 
02274 void mac_mcps_buffer_queue_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
02275 {
02276 
02277     if (rf_mac_setup->active_pd_data_request) {
02278         mcps_sap_prebuild_frame_buffer_free(rf_mac_setup->active_pd_data_request);
02279         rf_mac_setup->active_pd_data_request = NULL;
02280     }
02281 
02282     while (rf_mac_setup->pd_data_request_queue_to_go) {
02283         mac_pre_build_frame_t *buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, false, true);
02284         if (buffer) {
02285             mcps_sap_prebuild_frame_buffer_free(buffer);
02286         }
02287     }
02288 
02289     while (rf_mac_setup->pd_data_request_bc_queue_to_go) {
02290         mac_pre_build_frame_t *buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, true, true);
02291         if (buffer) {
02292             mcps_sap_prebuild_frame_buffer_free(buffer);
02293         }
02294     }
02295 
02296     while (rf_mac_setup->indirect_pd_data_request_queue) {
02297         mac_pre_build_frame_t *buffer = rf_mac_setup->indirect_pd_data_request_queue;
02298         if (buffer) {
02299             rf_mac_setup->indirect_pd_data_request_queue = buffer->next;
02300             mcps_sap_prebuild_frame_buffer_free(buffer);
02301         }
02302     }
02303 }
02304 /**
02305  * Function return list start pointer
02306  */
02307 static mac_pre_build_frame_t *mcps_sap_purge_from_list(mac_pre_build_frame_t *list_ptr_original, uint8_t msduhandle, uint8_t *status)
02308 {
02309     mac_pre_build_frame_t *list_prev = NULL;
02310     mac_pre_build_frame_t *list_ptr = list_ptr_original;
02311     while (list_ptr) {
02312         if (list_ptr->fcf_dsn.frametype == MAC_FRAME_DATA && list_ptr->msduHandle == msduhandle) {
02313 
02314             if (list_prev) {
02315                 list_prev->next = list_ptr->next;
02316             } else {
02317                 list_ptr_original = list_ptr->next;
02318             }
02319             list_ptr->next = NULL;
02320 
02321             //Free data and buffer
02322             mcps_sap_prebuild_frame_buffer_free(list_ptr);
02323             list_ptr = NULL;
02324             *status = true;
02325         } else {
02326             list_prev = list_ptr;
02327             list_ptr = list_ptr->next;
02328         }
02329     }
02330     return list_ptr_original;
02331 }
02332 
02333 
02334 static bool mcps_sap_purge_req_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t msduhandle)
02335 {
02336     //Discover from TX queue data packets with given
02337     uint8_t status = false;
02338     rf_mac_setup->pd_data_request_queue_to_go = mcps_sap_purge_from_list(rf_mac_setup->pd_data_request_queue_to_go, msduhandle, &status);
02339 
02340     if (!status) {
02341         rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
02342     }
02343 
02344     return status;
02345 }
02346 
02347 uint8_t mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
02348 {
02349     mcps_purge_conf_t confirmation;
02350     confirmation.msduHandle = purge_req->msduHandle;
02351 
02352     if (mcps_sap_purge_req_from_queue(rf_mac_setup, confirmation.msduHandle)) {
02353         confirmation.status = MLME_SUCCESS;
02354     } else {
02355         confirmation.status = MLME_INVALID_HANDLE;
02356     }
02357 
02358     if (get_sw_mac_api(rf_mac_setup)) {
02359         get_sw_mac_api(rf_mac_setup)->purge_conf_cb(get_sw_mac_api(rf_mac_setup), &confirmation);
02360     }
02361 
02362     return confirmation.status;
02363 }
02364 
02365 int mcps_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage)
02366 {
02367     const mem_stat_t *ns_dyn_mem_stat = ns_dyn_mem_get_mem_stat();
02368 
02369     if (ns_dyn_mem_stat && free_heap_percentage < 100) {
02370         ns_dyn_mem_rate_limiting_threshold = ns_dyn_mem_stat->heap_sector_size / 100 * (100 - free_heap_percentage);
02371         return 0;
02372     }
02373 
02374     return -1;
02375 }
02376 
02377 void mcps_pending_packet_counter_update_check(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
02378 {
02379     if (buffer->fcf_dsn.securityEnabled) {
02380         mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_mac_setup, buffer);
02381         if (key_desc) {
02382             uint32_t current_counter = mac_sec_mib_key_outgoing_frame_counter_get(rf_mac_setup, key_desc);
02383             if (mac_data_counter_too_small(current_counter, buffer->aux_header.frameCounter)) {
02384                 buffer->aux_header.frameCounter = current_counter;
02385                 mac_sec_mib_key_outgoing_frame_counter_increment(rf_mac_setup, key_desc);
02386             }
02387         }
02388     }
02389 }