takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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