Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

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-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
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 typedef struct {
00055     uint8_t address[8];
00056     unsigned addr_type:2;
00057     uint8_t nonce_ptr[8];
00058     uint32_t frameCounter;
00059     uint8_t keyId;
00060 }neighbour_security_update_t;
00061 
00062 void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer);
00063 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);
00064 static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
00065 static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer);
00066 static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00067 static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00068 static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type);
00069 
00070 static int8_t mac_tasklet_event_handler = -1;
00071 
00072 
00073 static void mac_data_poll_radio_disable_check(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00074 {
00075     if (rf_mac_setup->macCapRxOnIdle || rf_mac_setup->macWaitingData || rf_mac_setup->scan_active) {
00076         return;
00077     }
00078 
00079     if (!rf_mac_setup->macRfRadioTxActive ) {
00080         mac_mlme_mac_radio_disabled(rf_mac_setup);
00081     }
00082 }
00083 
00084 static void mcps_data_confirm_cb(protocol_interface_rf_mac_setup_s *rf_mac_setup, mcps_data_conf_t *confirm)
00085 {
00086 
00087     mac_data_poll_radio_disable_check(rf_mac_setup);
00088 
00089     if( get_sw_mac_api(rf_mac_setup) ) {
00090         get_sw_mac_api(rf_mac_setup)->data_conf_cb(get_sw_mac_api(rf_mac_setup), confirm);
00091     }
00092 }
00093 
00094 void mcps_sap_data_req_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup , const mcps_data_req_t *data_req ) {
00095     uint8_t status = MLME_SUCCESS;
00096     mac_pre_build_frame_t *buffer = NULL;
00097 
00098     if (!rf_mac_setup->mac_security_enabled) {
00099         if (data_req->Key.SecurityLevel) {
00100             status = MLME_UNSUPPORTED_SECURITY;
00101             goto verify_status;
00102         }
00103     }
00104 
00105     if (data_req->msduLength > rf_mac_setup->dev_driver->phy_driver->phy_MTU - MAC_DATA_PACKET_MIN_HEADER_LENGTH) {
00106         tr_debug("packet %u, %u",data_req->msduLength, rf_mac_setup->dev_driver->phy_driver->phy_MTU);
00107         status = MLME_FRAME_TOO_LONG;
00108         goto verify_status;
00109     }
00110     //protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)api;
00111     buffer = mcps_sap_prebuild_frame_buffer_get(0);
00112     //tr_debug("Data Req");
00113     if (!buffer) {
00114         //Make Confirm Here
00115         status = MLME_TRANSACTION_OVERFLOW;
00116         goto verify_status;
00117     }
00118 
00119     if (!rf_mac_setup->macUpState || rf_mac_setup->scan_active) {
00120         status = MLME_TRX_OFF;
00121         tr_debug("Drop MAC tx packet when mac disabled");
00122         goto verify_status;
00123     }
00124     buffer->upper_layer_request = true;
00125     buffer->fcf_dsn.frametype = FC_DATA_FRAME;
00126     buffer->fcf_dsn.ackRequested = data_req->TxAckReq;
00127 
00128     buffer->mac_header_length_with_security = 3;
00129     mac_header_security_parameter_set(&buffer->aux_header, &data_req->Key);
00130     buffer->security_mic_len = mac_security_mic_length_get(buffer->aux_header.securityLevel);
00131     if (buffer->aux_header.securityLevel) {
00132         buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
00133         buffer->fcf_dsn.securityEnabled = true;
00134     }
00135 
00136     buffer->mac_header_length_with_security += mac_header_security_aux_header_length(buffer->aux_header.securityLevel, buffer->aux_header.KeyIdMode);
00137 
00138     buffer->msduHandle = data_req->msduHandle;
00139     buffer->fcf_dsn.DstAddrMode = data_req->DstAddrMode;
00140     memcpy(buffer->DstAddr, data_req->DstAddr, 8);
00141     buffer->DstPANId = data_req->DstPANId;
00142     buffer->SrcPANId = mac_mlme_get_panid(rf_mac_setup);
00143     buffer->fcf_dsn.SrcAddrMode = data_req->SrcAddrMode;
00144     buffer->fcf_dsn.framePending = data_req->PendingBit;
00145 
00146     if (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_NONE) {
00147         if (buffer->fcf_dsn.DstAddrMode == MAC_ADDR_MODE_NONE) {
00148             status = MLME_INVALID_ADDRESS;
00149             goto verify_status;
00150         }
00151 
00152         if (rf_mac_setup->shortAdressValid) {
00153             buffer->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT;
00154         } else {
00155             buffer->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT;
00156         }
00157     }
00158 
00159     mac_frame_src_address_set_from_interface(buffer->fcf_dsn.SrcAddrMode, rf_mac_setup, buffer->SrcAddr);
00160 
00161     if (buffer->DstPANId == buffer->SrcPANId) {
00162         buffer->fcf_dsn.intraPan = true;
00163     }
00164 
00165     //Calculate address length
00166     buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
00167     buffer->mac_payload = data_req->msdu;
00168     buffer->mac_payload_length = data_req->msduLength;
00169     //check that header + payload length is not bigger than MAC MTU
00170     if (data_req->InDirectTx) {
00171         mac_indirect_queue_write(rf_mac_setup, buffer);
00172     } else {
00173         mcps_sap_pd_req_queue_write(rf_mac_setup, buffer);
00174     }
00175 
00176     verify_status:
00177     if (status != MLME_SUCCESS){
00178         mcps_data_conf_t confirm;
00179         memset(&confirm, 0, sizeof(mcps_data_conf_t));
00180         confirm.msduHandle = data_req->msduHandle;
00181         confirm.status = status;
00182         tr_debug("DATA REQ Fail %u", status);
00183         mcps_sap_prebuild_frame_buffer_free(buffer);
00184         mcps_data_confirm_cb(rf_mac_setup, &confirm);
00185     }
00186 }
00187 
00188 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) {
00189 
00190     if (!rf_mac_setup->macUpState || data_length > rf_mac_setup->dev_driver->phy_driver->phy_MTU) {
00191         return -1;
00192     }
00193 
00194     //protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)api;
00195     mac_pre_build_frame_t *buffer = mcps_sap_prebuild_frame_buffer_get(data_length);
00196     //tr_debug("Data Req");
00197     if (!buffer) {
00198         //Make Confirm Here
00199         return -1;
00200     }
00201 
00202     mac_header_parse_fcf_dsn(&buffer->fcf_dsn, data_ptr);
00203     // Use MAC sequence as handle
00204     buffer->msduHandle = data_ptr[2];
00205     memcpy(buffer->mac_payload,data_ptr,  data_length);
00206     buffer->mac_payload_length = data_length;
00207 
00208     // Read destination MAC address from MAC header
00209     mac_header_get_dst_address(&buffer->fcf_dsn, data_ptr, buffer->DstAddr);
00210 
00211     mcps_sap_pd_req_queue_write(rf_mac_setup, buffer);
00212 
00213     if (!buffer->fcf_dsn.ackRequested) {
00214         phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
00215         driver->phy_tx_done_cb(rf_mac_setup->tun_extension_rf_driver->id, 1, PHY_LINK_TX_SUCCESS, 1, 1);
00216     }
00217     return 0;
00218 }
00219 
00220 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)
00221 {
00222     const uint8_t *ptr = mlme_req->mlme_ptr;
00223     switch(mlme_req->primitive){
00224         case MLME_SCAN:{
00225             if (mlme_req->ptr_length != 47) {
00226                 return -1;
00227             }
00228 
00229             mlme_scan_t mlme_scan_req;
00230             mlme_scan_req.ScanType = *ptr++;
00231             mlme_scan_req.ScanChannels.channel_page = *ptr++;
00232             memcpy(mlme_scan_req.ScanChannels.channel_mask, ptr, 32);
00233             ptr += 32;
00234             mlme_scan_req.ScanDuration = *ptr++;
00235             mlme_scan_req.ChannelPage = *ptr++;
00236             mlme_scan_req.Key.SecurityLevel = *ptr++;
00237             mlme_scan_req.Key.KeyIdMode = *ptr++;
00238             mlme_scan_req.Key.KeyIndex = *ptr++;
00239             memcpy(mlme_scan_req.Key.Keysource, ptr, 8);
00240             mac_mlme_scan_request(&mlme_scan_req, rf_mac_setup);
00241             return 0;
00242             break;
00243         }
00244         case MLME_SET:{
00245             if (mlme_req->ptr_length < 3) {
00246                 return -1;
00247             }
00248             mlme_set_t mlme_set_req;
00249             mlme_set_req.attr = *ptr++;
00250             mlme_set_req.attr_index = *ptr++;
00251             mlme_set_req.value_pointer = ptr;
00252             mlme_set_req.value_size = mlme_req->ptr_length - 2;
00253 
00254             return mac_mlme_set_req(rf_mac_setup, &mlme_set_req);
00255         }
00256         case MLME_START:{
00257             mlme_start_t mlme_start_req;
00258             if (mlme_req->ptr_length != 34) {
00259                 return -1;
00260             }
00261             mlme_start_req.PANId = common_read_16_bit(ptr);
00262             ptr += 2;
00263             mlme_start_req.LogicalChannel = *ptr++;
00264             mlme_start_req.StartTime = common_read_32_bit(ptr);
00265             ptr += 4;
00266             mlme_start_req.BeaconOrder = *ptr++;
00267             mlme_start_req.SuperframeOrder = *ptr++;
00268             mlme_start_req.PANCoordinator = *ptr++;
00269             mlme_start_req.BatteryLifeExtension = *ptr++;
00270             mlme_start_req.CoordRealignment = *ptr++;
00271             mlme_start_req.CoordRealignKey.SecurityLevel = *ptr++;
00272             mlme_start_req.CoordRealignKey.KeyIdMode = *ptr++;
00273             mlme_start_req.CoordRealignKey.KeyIndex = *ptr++;
00274             memcpy(mlme_start_req.CoordRealignKey.Keysource, ptr, 8);
00275             ptr += 8;
00276             mlme_start_req.BeaconRealignKey.SecurityLevel = *ptr++;
00277             mlme_start_req.BeaconRealignKey.KeyIdMode = *ptr++;
00278             mlme_start_req.BeaconRealignKey.KeyIndex = *ptr++;
00279             memcpy(mlme_start_req.BeaconRealignKey.Keysource, ptr, 8);
00280             ptr += 8;
00281             return mac_mlme_start_req(&mlme_start_req, rf_mac_setup);
00282         }
00283         default:
00284             break;
00285     }
00286     return -1;
00287 }
00288 
00289 
00290 int8_t mac_virtual_sap_data_cb(void *identifier, arm_phy_sap_msg_t *message)
00291 {
00292     if (!identifier || !message) {
00293         return -1;
00294     }
00295 
00296     if (message->id == MACTUN_PD_SAP_NAP_IND) {
00297         return mac_virtual_data_req_handler(identifier,message->message.generic_data_ind.data_ptr,  message->message.generic_data_ind.data_len);
00298     }
00299 
00300     if (message->id == MACTUN_MLME_NAP_EXTENSION) {
00301         return mac_virtual_mlme_nap_req_handler(identifier, &message->message.mlme_request);
00302     }
00303     return -1;
00304 }
00305 
00306 
00307 
00308 //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) {
00309 //    //TODO get securily level table and verify current packet
00310 //    (void)rf_mac_setup;
00311 //    //Accept all true from mac
00312 //    security_level_compare->SecurityMinimum = 0;
00313 //}
00314 
00315 static void mac_security_interface_aux_ccm_nonce_set(uint8_t *noncePtr, uint8_t *mac64, uint32_t securityFrameCounter, uint8_t securityLevel)
00316 {
00317     memcpy(noncePtr, mac64, 8);
00318     noncePtr += 8;
00319     noncePtr = common_write_32_bit(securityFrameCounter, noncePtr);
00320     *noncePtr = securityLevel;
00321 }
00322 
00323 /* Compare two security levels, as per 802.15.4-2011 7.4.1.1 */
00324 /* Returns true if sec1 is at least as secure as sec2 */
00325 //static bool mac_security_interface_security_level_compare(uint8_t sec1, uint8_t sec2)
00326 //{
00327 //    /* bit 2 is "encrypted" - must be as encrypted
00328 //    bits 1-0 are "authentication level" - must be at least as high */
00329 //    return (sec1 & 4) >= (sec2 & 4) &&
00330 //           (sec1 & 3) >= (sec2 & 3);
00331 //}
00332 
00333 
00334 static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme_security_t *security_params)
00335 {
00336     uint8_t *key;
00337     mlme_key_descriptor_t *key_description;
00338     mlme_key_device_descriptor_t *key_device_description = NULL;
00339     uint8_t device_descriptor_handle;
00340     uint8_t openPayloadLength = 0;
00341     protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)b->mac_class_ptr;
00342 //    mlme_security_level_descriptor_t security_level_compare;
00343 
00344 
00345     if (!rf_mac_setup->mac_security_enabled) {
00346         if (security_params->SecurityLevel) {
00347             return MLME_UNSUPPORTED_SECURITY;
00348         }
00349         //TODO verify this with Kevin
00350         return MLME_UNSUPPORTED_LEGACY;
00351     }
00352 
00353 //    security_level_compare.FrameType = b->fcf_dsn.frametype;
00354     if (b->fcf_dsn.frametype == MAC_FRAME_CMD) {
00355         openPayloadLength = 1;
00356 //        security_level_compare.CommandFrameIdentifier = mcps_mac_command_frame_id_get(b);
00357     }
00358 
00359     //TODO do this proper way when security description  is implemeted
00360 
00361 //    mac_data_interface_minium_security_level_get(rf_mac_setup, &security_level_compare);
00362 //
00363 //    //Validate Security Level
00364 //    if (!mac_security_interface_security_level_compare(security_params->SecurityLevel, security_level_compare.SecurityMinimum)) {
00365 //        //Drop packet reason rx level was less secured than requested one
00366 //        tr_debug("RX Security level less than minimum level");
00367 //        return MLME_IMPROPER_SECURITY_LEVEL;
00368 //    }
00369 
00370     neighbour_security_update_t neighbour_validation;
00371     memset(&neighbour_validation, 0, sizeof(neighbour_validation));
00372     neighbour_validation.frameCounter = mcps_mac_security_frame_counter_read(b);
00373 
00374     if (neighbour_validation.frameCounter == 0xffffffff) {
00375         tr_debug("Max Framecounter value..Drop");
00376         return MLME_COUNTER_ERROR;
00377     }
00378 
00379     //READ SRC Address
00380 
00381     uint16_t SrcPANId = mac_header_get_src_panid(&b->fcf_dsn, mac_header_message_start_pointer(b));
00382     mac_header_get_src_address(&b->fcf_dsn, mac_header_message_start_pointer(b), neighbour_validation.address);
00383     neighbour_validation.addr_type = b->fcf_dsn.SrcAddrMode;
00384     neighbour_validation.keyId = security_params->KeyIndex;
00385 
00386     // Get A Key description
00387     key_description =  mac_sec_key_description_get(rf_mac_setup, security_params, b->fcf_dsn.SrcAddrMode, neighbour_validation.address, SrcPANId);
00388     if (!key_description) {
00389         return MLME_UNAVAILABLE_KEY;
00390     }
00391 
00392     if (key_description->unique_key_descriptor) {
00393         //Discover device table by device description handle
00394         key_device_description = key_description->KeyDeviceList;
00395         device_descriptor_handle = key_device_description->DeviceDescriptorHandle;
00396         //Discover device descriptor by handle
00397         b->neigh_info = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, device_descriptor_handle);
00398         if (!b->neigh_info) {
00399             return MLME_UNSUPPORTED_SECURITY;
00400         }
00401     } else {
00402 
00403         if (!b->neigh_info) {
00404             return MLME_UNSUPPORTED_SECURITY;
00405         }
00406 
00407         device_descriptor_handle = mac_mib_device_descption_attribute_get_by_descriptor(rf_mac_setup, b->neigh_info);
00408         key_device_description =  mac_sec_mib_key_device_description_discover_from_list(key_description, device_descriptor_handle);
00409     }
00410 
00411     if (key_device_description) {
00412         //validate BlackList status
00413         if (key_device_description->Blacklisted) {
00414             tr_debug("Blacklisted key for device %s", trace_array(b->neigh_info->ExtAddress, 8));
00415             return MLME_UNAVAILABLE_KEY;
00416         }
00417 
00418         if (neighbour_validation.frameCounter < b->neigh_info->FrameCounter ) {
00419             tr_debug("MLME_COUNTER_ERROR");
00420             return MLME_COUNTER_ERROR;
00421         }
00422     }
00423 
00424     key = key_description->Key;
00425     memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8);
00426 
00427     ccm_globals_t *ccm_ptr = ccm_sec_init(security_params->SecurityLevel, key, AES_CCM_DECRYPT, 2);
00428 
00429     if (!ccm_ptr) {
00430         return MLME_UNSUPPORTED_SECURITY;
00431     }
00432 
00433     mac_security_interface_aux_ccm_nonce_set(ccm_ptr->exp_nonce, neighbour_validation.nonce_ptr, neighbour_validation.frameCounter, security_params->SecurityLevel);
00434 
00435     if (ccm_ptr->mic_len) {
00436      // this is asuming that there is no headroom for buffers.
00437      ccm_ptr->adata_len = mcps_mac_header_length_from_received_frame(b) + openPayloadLength;
00438      //SET MIC PTR
00439      ccm_ptr->mic = mcps_security_mic_pointer_get(b);
00440      ccm_ptr->adata_ptr = mac_header_message_start_pointer(b);
00441     }
00442 
00443     ccm_ptr->data_ptr = (mcps_mac_payload_pointer_get(b) + openPayloadLength);
00444     ccm_ptr->data_len = mcps_payload_length_from_received_frame(b) - openPayloadLength;
00445     if (ccm_process_run(ccm_ptr) != 0) {
00446         tr_warning("MIC Fail adata %s", trace_array(ccm_ptr->adata_ptr, ccm_ptr->adata_len));
00447         tr_warning("Nonce %s", trace_array(ccm_ptr->exp_nonce, 13));
00448         if (openPayloadLength) {
00449             tr_warning("%s", tr_array(ccm_ptr->data_ptr,  ccm_ptr->data_len));
00450         }
00451         return MLME_SECURITY_FAIL;
00452     }
00453 
00454     //Update key device and key description tables
00455 
00456     b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1;
00457     if (!key_device_description) {
00458         // Black list old used keys by this device
00459         mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
00460         key_device_description =  mac_sec_mib_key_device_description_list_update(key_description);
00461         if (key_device_description) {
00462             tr_debug("Set new device user %u for key", device_descriptor_handle);
00463             key_device_description->DeviceDescriptorHandle = device_descriptor_handle;
00464         }
00465     }
00466 
00467     return MLME_SUCCESS;
00468 }
00469 
00470 static void mcps_comm_status_indication_generate(uint8_t status, mac_pre_parsed_frame_t *buf, mac_api_t * mac)
00471 {
00472     mlme_comm_status_t comm_status;
00473     memset(&comm_status,0 ,sizeof(mlme_comm_status_t) );
00474     comm_status.status = status;
00475     //Call com status
00476     comm_status.PANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00477     comm_status.DstAddrMode = buf->fcf_dsn.DstAddrMode;;
00478     mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.DstAddr);
00479     comm_status.SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00480     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), comm_status.SrcAddr);
00481     mac_header_security_components_read(buf, &comm_status.Key);
00482     mac->mlme_ind_cb(mac,MLME_COMM_STATUS , &comm_status);
00483 }
00484 
00485 
00486 
00487 static int8_t mac_data_interface_host_accept_data(mcps_data_ind_t * data_ind, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00488 {
00489     if ((data_ind->DstAddrMode == MAC_ADDR_MODE_16_BIT) && (data_ind->DstAddr[0] == 0xff && data_ind->DstAddr[1] == 0xff)) {
00490         tr_debug("Drop Multicast packet");
00491         return -1;
00492     }
00493 
00494 
00495     if (data_ind->msduLength) {
00496         if (!rf_mac_setup->macRxDataAtPoll && rf_mac_setup->macDataPollReq) {
00497             eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
00498             rf_mac_setup->macRxDataAtPoll = true;
00499             eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 400); //20ms
00500             rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA;
00501             rf_mac_setup->mlme_tick_count = 0;
00502         }
00503         return 0;
00504     } else {
00505         eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
00506         mac_mlme_poll_process_confirm(rf_mac_setup, MLME_NO_DATA);
00507         return -1;
00508     }
00509 
00510 }
00511 
00512 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)
00513 {
00514     int8_t retval = -1;
00515     uint8_t status;
00516     //allocate Data ind primitiv and parse packet to that
00517     mcps_data_ind_t * data_ind = ns_dyn_mem_temporary_alloc(sizeof(mcps_data_ind_t));
00518 
00519     if (!data_ind) {
00520         goto DROP_PACKET;
00521     }
00522     memset(data_ind, 0, sizeof(mcps_data_ind_t));
00523     //Parse data
00524     data_ind->DSN = buf->fcf_dsn.DSN;
00525     data_ind->DstAddrMode = buf->fcf_dsn.DstAddrMode;
00526     data_ind->DstPANId = mac_header_get_dst_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00527     mac_header_get_dst_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->DstAddr);
00528     data_ind->SrcAddrMode = buf->fcf_dsn.SrcAddrMode;
00529     data_ind->SrcPANId = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00530     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), data_ind->SrcAddr);
00531 
00532     data_ind->mpduLinkQuality = buf->LQI;
00533     data_ind->signal_dbm = buf->dbm;
00534     /* Parse security part */
00535     mac_header_security_components_read(buf, &data_ind->Key);
00536     data_ind->msduLength = buf->mac_payload_length;
00537     data_ind->msdu_ptr = mcps_mac_payload_pointer_get(buf);
00538 
00539 
00540 
00541     buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, data_ind->SrcAddr, data_ind->SrcAddrMode);
00542     if (buf->fcf_dsn.securityEnabled) {
00543         status = mac_data_interface_decrypt_packet(buf, &data_ind->Key);
00544         if (status != MLME_SUCCESS) {
00545             mcps_comm_status_indication_generate(status, buf, mac);
00546             goto DROP_PACKET;
00547         }
00548     }
00549 
00550     /* Validate Polling device */
00551     if (!rf_mac_setup->macCapRxOnIdle) {
00552         if (mac_data_interface_host_accept_data(data_ind, rf_mac_setup) != 0) {
00553             //tr_debug("Drop by not Accept");
00554             goto DROP_PACKET;
00555         }
00556     }
00557 
00558     if (mac) {
00559         mac->data_ind_cb(mac, data_ind);
00560         retval = 0;
00561     }
00562 
00563     DROP_PACKET:
00564     ns_dyn_mem_free(data_ind);
00565     mcps_sap_pre_parsed_frame_buffer_free(buf);
00566     return retval;
00567 }
00568 
00569 static void mac_lib_res_no_data_to_req(mac_pre_parsed_frame_t *buffer, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00570 {
00571     mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0);
00572     if (!buf) {
00573         return;
00574     }
00575 
00576     buf->fcf_dsn.SrcAddrMode = buffer->fcf_dsn.DstAddrMode;
00577     buf->fcf_dsn.DstAddrMode = buffer->fcf_dsn.SrcAddrMode;
00578     //SET PANID
00579     buf->SrcPANId = mac_header_get_dst_panid(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer));
00580     buf->DstPANId = buf->SrcPANId;
00581 
00582     mac_header_get_dst_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->SrcAddr);
00583     mac_header_get_src_address(&buffer->fcf_dsn, mac_header_message_start_pointer(buffer), buf->DstAddr);
00584 
00585     buf->fcf_dsn.securityEnabled = buffer->fcf_dsn.securityEnabled;
00586     buf->fcf_dsn.intraPan = true;
00587     buf->fcf_dsn.ackRequested = true;
00588     buf->mac_header_length_with_security = 3;
00589     if (buffer->fcf_dsn.securityEnabled) {
00590         buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
00591         buf->aux_header.securityLevel = rf_mac_setup->mac_auto_request.SecurityLevel;
00592         buf->aux_header.KeyIdMode = rf_mac_setup->mac_auto_request.KeyIdMode;
00593         buf->aux_header.KeyIndex = rf_mac_setup->mac_auto_request.KeyIndex;
00594         memcpy(buf->aux_header.Keysource, rf_mac_setup->mac_auto_request.Keysource, 8);
00595     }
00596     buf->fcf_dsn.frametype = FC_DATA_FRAME;
00597     buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY;
00598     buf->mac_payload = NULL;
00599     buf->mac_payload_length = 0;
00600     buf->security_mic_len = mac_security_mic_length_get(buf->aux_header.securityLevel);
00601     buf->mac_header_length_with_security += mac_header_security_aux_header_length(buf->aux_header.securityLevel, buf->aux_header.KeyIdMode);
00602     buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn);
00603     mcps_sap_pd_req_queue_write(rf_mac_setup, buf);
00604 }
00605 
00606 static int8_t mac_beacon_request_handler(mac_pre_parsed_frame_t *buffer, protocol_interface_rf_mac_setup_s *rf_mac_setup) {
00607 
00608     if (buffer->fcf_dsn.SrcAddrMode != MAC_ADDR_MODE_NONE || buffer->fcf_dsn.DstAddrMode != MAC_ADDR_MODE_16_BIT) {
00609         return -1;
00610     }
00611     // Note FHSS from received beacon request
00612     if (rf_mac_setup->fhss_api) {
00613         rf_mac_setup->fhss_api->receive_frame(rf_mac_setup->fhss_api, 0, NULL, 0, NULL, FHSS_SYNCH_REQUEST_FRAME);
00614     }
00615     // mac_data_interface_build_beacon() uses the same buffer to build the response
00616     // and it is then feed to protocol buffer. Buffer should be freed only if it returns zero.
00617     return mac_mlme_beacon_tx(rf_mac_setup);
00618 
00619 }
00620 
00621 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)
00622 {
00623     int8_t retval = -1;
00624     mlme_security_t security_params;
00625     uint8_t mac_command;
00626     uint8_t status;
00627     uint8_t temp_src_address[8];
00628 
00629 
00630     //Read address and pan-id
00631     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), temp_src_address);
00632     uint8_t address_mode = buf->fcf_dsn.SrcAddrMode;
00633     buf->neigh_info = mac_sec_mib_device_description_get(rf_mac_setup, temp_src_address, address_mode);
00634     //Decrypt Packet if secured
00635     if (buf->fcf_dsn.securityEnabled) {
00636         mac_header_security_components_read(buf, &security_params);
00637 
00638         status = mac_data_interface_decrypt_packet(buf, &security_params);
00639         if (status != MLME_SUCCESS) {
00640 
00641             mcps_comm_status_indication_generate(status, buf, mac);
00642             goto DROP_PACKET;
00643         }
00644     }
00645 
00646     mac_command = mcps_mac_command_frame_id_get(buf);
00647 
00648     switch (mac_command) {
00649         case MAC_DATA_REQ:
00650             //Here 2 check
00651             if (mac_indirect_data_req_handle(buf, rf_mac_setup) == 0) {
00652                 tr_debug("Trig Dummy packet");
00653                 mac_lib_res_no_data_to_req(buf, rf_mac_setup);
00654             }
00655             retval = 0;
00656             break;
00657         case MAC_BEACON_REQ:
00658             retval = mac_beacon_request_handler(buf, rf_mac_setup);
00659             break;
00660 
00661         default:
00662             break;
00663     }
00664 
00665     DROP_PACKET:
00666     mcps_sap_pre_parsed_frame_buffer_free(buf);
00667     return retval;
00668 }
00669 
00670 static void mac_nap_tun_data_handler(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00671 {
00672     phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
00673     if (driver->phy_rx_cb) {
00674         driver->phy_rx_cb(buf->buf, buf->frameLength, buf->LQI, buf->dbm, rf_mac_setup->tun_extension_rf_driver->id);
00675     }
00676     mcps_sap_pre_parsed_frame_buffer_free(buf);
00677 }
00678 
00679 static void mac_data_interface_parse_beacon(mac_pre_parsed_frame_t *buf, protocol_interface_rf_mac_setup_s *rf_mac_setup)
00680 {
00681     mlme_beacon_ind_t ind_data;
00682 
00683     uint16_t len;
00684     uint8_t *ptr;
00685     mlme_beacon_gts_spec_t gts_spec;
00686 //    uint8_t *gts_info = NULL;
00687     uint8_t *pending_address_list = NULL;
00688     uint8_t SuperframeSpec[2];
00689 
00690     uint16_t src_pan_id = mac_header_get_src_panid(&buf->fcf_dsn, mac_header_message_start_pointer(buf));
00691 
00692     //validate beacon pan-id and filter other network out
00693     if (rf_mac_setup->pan_id < 0xffff && (rf_mac_setup->pan_id != src_pan_id && !rf_mac_setup->macAcceptAnyBeacon)) {
00694         tr_debug("Drop Beacon by unknow panid");
00695         return;
00696     }
00697 
00698     /*Add received bytes in statistics*/
00699     tr_debug("mac_parse_beacon");
00700 
00701     ptr = mcps_mac_payload_pointer_get(buf);
00702     len = mcps_payload_length_from_received_frame(buf);
00703     SuperframeSpec[0] = *ptr++;
00704     SuperframeSpec[1] = *ptr++;
00705     gts_spec.description_count = (*ptr & 7);
00706     gts_spec.gts_permit = ((*ptr++ & 0x80) >> 7);
00707     len -= 3;
00708     if (gts_spec.description_count) {
00709         tr_error("GTS info count not zero");
00710         //calucalate Length
00711         uint8_t gts_field_length = ((gts_spec.description_count) * 3);
00712         if (len < gts_field_length ) {
00713             return;
00714         }
00715 //        gts_info = ptr;
00716         len -= gts_field_length;
00717         ptr += gts_field_length;
00718     }
00719     //Pendinlist
00720     ind_data.PendAddrSpec.short_address_count = (*ptr & 7);
00721     ind_data.PendAddrSpec.extended_address_count = ((*ptr++ & 0x70) >> 4);
00722     len -= 1;
00723     if (ind_data.PendAddrSpec.short_address_count || ind_data.PendAddrSpec.extended_address_count) {
00724         if ((ind_data.PendAddrSpec.extended_address_count + ind_data.PendAddrSpec.short_address_count)  > 7) {
00725             //over 7 address
00726             return;
00727         }
00728         uint8_t pending_address_list_size = (ind_data.PendAddrSpec.short_address_count * 2);
00729         pending_address_list_size += (ind_data.PendAddrSpec.extended_address_count *8);
00730         if (len < pending_address_list_size) {
00731             return;
00732         }
00733         pending_address_list = ptr;
00734         ptr += pending_address_list_size;
00735         len -= pending_address_list_size;
00736     }
00737 
00738     memset(&ind_data.PANDescriptor, 0, sizeof(mlme_pan_descriptor_t));
00739 
00740     if (rf_mac_setup->fhss_api) {
00741         ind_data.PANDescriptor.LogicalChannel = 0; //Force Allways same channel
00742     } else {
00743         ind_data.PANDescriptor.LogicalChannel = rf_mac_setup->mac_channel;
00744     }
00745     ind_data.PANDescriptor.ChannelPage = 0;
00746     ind_data.PANDescriptor.CoordAddrMode = buf->fcf_dsn.SrcAddrMode;
00747     mac_header_get_src_address(&buf->fcf_dsn, mac_header_message_start_pointer(buf), ind_data.PANDescriptor.CoordAddress);
00748     ind_data.PANDescriptor.CoordPANId = src_pan_id;
00749     ind_data.PANDescriptor.LinkQuality = buf->LQI;
00750     ind_data.PANDescriptor.GTSPermit = gts_spec.gts_permit;
00751     ind_data.PANDescriptor.Timestamp = buf->timestamp;
00752     mac_header_security_components_read(buf, &ind_data.PANDescriptor.Key);
00753     ind_data.PANDescriptor.SecurityFailure = 0;
00754     ind_data.PANDescriptor.SuperframeSpec[0] = SuperframeSpec[0];
00755     ind_data.PANDescriptor.SuperframeSpec[1] = SuperframeSpec[1];
00756 
00757     ind_data.BSN = buf->fcf_dsn.DSN;
00758     ind_data.AddrList = pending_address_list;
00759     ind_data.beacon_data_length = len;
00760     ind_data.beacon_data = ptr;
00761 
00762     mac_mlme_beacon_notify(rf_mac_setup, &ind_data);
00763 
00764 }
00765 
00766 static void mac_data_interface_frame_handler(mac_pre_parsed_frame_t *buf)
00767 {
00768     protocol_interface_rf_mac_setup_s *rf_mac_setup = buf->mac_class_ptr;
00769     if (!rf_mac_setup) {
00770         tr_debug("Drop by no mac class");
00771         mcps_sap_pre_parsed_frame_buffer_free(buf);
00772         return;
00773     }
00774 
00775     if ( mac_filter_modify_link_quality(rf_mac_setup->mac_interface_id,buf) == 1) {
00776         mcps_sap_pre_parsed_frame_buffer_free(buf);
00777         return;
00778     }
00779     //Sniffer Should push here data to stack!!!!
00780     mac_api_t * mac = get_sw_mac_api(rf_mac_setup);
00781     if( !mac || (rf_mac_setup->mac_mlme_scan_resp && buf->fcf_dsn.frametype != MAC_FRAME_BEACON)) {
00782         mcps_sap_pre_parsed_frame_buffer_free(buf);
00783         return;
00784     }
00785     if (buf->fcf_dsn.ackRequested == false) {
00786         sw_mac_stats_update(rf_mac_setup, STAT_MAC_BC_RX_COUNT, 0);
00787     }
00788     sw_mac_stats_update(rf_mac_setup, STAT_MAC_RX_COUNT, 0);
00789     switch (buf->fcf_dsn.frametype) {
00790         case MAC_FRAME_BEACON:
00791             sw_mac_stats_update(rf_mac_setup, STAT_MAC_BEA_RX_COUNT, 0);
00792             mac_data_interface_parse_beacon(buf, rf_mac_setup);
00793             mcps_sap_pre_parsed_frame_buffer_free(buf);
00794             break;
00795         case MAC_FRAME_DATA:
00796             if (rf_mac_setup->tun_extension_rf_driver) {
00797                 mac_nap_tun_data_handler(buf, rf_mac_setup);
00798                 return;
00799             }
00800             mac_data_sap_rx_handler(buf, rf_mac_setup, mac);
00801             break;
00802         case MAC_FRAME_CMD:
00803             if (rf_mac_setup->tun_extension_rf_driver) {
00804                 if (mcps_mac_command_frame_id_get(buf) != MAC_BEACON_REQ) {
00805                     mac_nap_tun_data_handler(buf, rf_mac_setup);
00806                     return;
00807                 }
00808             }
00809 
00810             //Handle Command Frame
00811             mac_command_sap_rx_handler(buf, rf_mac_setup, mac);
00812             break;
00813 
00814         default:
00815             mcps_sap_pre_parsed_frame_buffer_free(buf);
00816     }
00817 
00818 }
00819 
00820 void mac_mcps_trig_buffer_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00821 {
00822     if (!rf_mac_setup) {
00823         return;
00824     }
00825     while (!rf_mac_setup->active_pd_data_request) {
00826         bool is_bc_queue = false;
00827         mac_pre_build_frame_t *buffer;
00828         // With FHSS, poll broadcast queue on broadcast channel first
00829         if (rf_mac_setup->fhss_api) {
00830             if (rf_mac_setup->fhss_api->is_broadcast_channel(rf_mac_setup->fhss_api) == true) {
00831                 if (rf_mac_setup->pd_data_request_bc_queue_to_go) {
00832                     is_bc_queue = true;
00833                 }
00834             }
00835         }
00836         buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, is_bc_queue, false);
00837 
00838         if (buffer) {
00839             rf_mac_setup->active_pd_data_request = buffer;
00840             if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
00841                 rf_mac_setup->active_pd_data_request = NULL;
00842                 mcps_data_confirm_handle(rf_mac_setup, buffer);
00843             } else {
00844                 return;
00845             }
00846         } else {
00847             return;
00848         }
00849     }
00850 }
00851 
00852 static void mac_pd_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup) {
00853 
00854     if (!rf_mac_setup->active_pd_data_request) {
00855         tr_debug("No pending TX process anymore");
00856     } else {
00857         mac_pre_build_frame_t *buffer = rf_mac_setup->active_pd_data_request;
00858         rf_mac_setup->active_pd_data_request = NULL;
00859         mcps_data_confirm_handle(rf_mac_setup, buffer);
00860     }
00861 
00862     mac_mcps_trig_buffer_from_queue(rf_mac_setup);
00863 }
00864 
00865 static void mac_mcps_sap_data_tasklet(arm_event_s *event)
00866 {
00867     uint8_t event_type = event->event_type;
00868 
00869     switch (event_type) {
00870         case MCPS_SAP_DATA_IND_EVENT:
00871             if (event->data_ptr) {
00872                 mac_data_interface_frame_handler((mac_pre_parsed_frame_t*)event->data_ptr);
00873             }
00874 
00875             break;
00876 
00877         case MCPS_SAP_DATA_CNF_EVENT:
00878             //mac_data_interface_tx_done(event->data_ptr);
00879             mac_pd_data_confirm_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr);
00880             break;
00881 
00882         case MAC_MLME_EVENT_HANDLER:
00883             mac_mlme_event_cb(event->data_ptr);
00884             break;
00885         case MAC_MCPS_INDIRECT_TIMER_CB:
00886             mac_indirect_data_ttl_handle((protocol_interface_rf_mac_setup_s*)event->data_ptr, (uint16_t)event->event_data);
00887             break;
00888 
00889         case MAC_MLME_SCAN_CONFIRM_HANDLER:
00890             mac_mlme_scan_confirmation_handle((protocol_interface_rf_mac_setup_s *) event->data_ptr);
00891             break;
00892         case MAC_SAP_TRIG_TX:
00893             mac_clear_active_event((protocol_interface_rf_mac_setup_s *) event->data_ptr, MAC_SAP_TRIG_TX);
00894             mac_mcps_trig_buffer_from_queue((protocol_interface_rf_mac_setup_s *) event->data_ptr);
00895             //No break necessary
00896         default:
00897             break;
00898     }
00899 }
00900 
00901 int8_t mac_mcps_sap_tasklet_init(void)
00902 {
00903     if (mac_tasklet_event_handler < 0) {
00904         mac_tasklet_event_handler = eventOS_event_handler_create(&mac_mcps_sap_data_tasklet, 0);
00905     }
00906 
00907     return mac_tasklet_event_handler;
00908 }
00909 
00910 mac_pre_build_frame_t * mcps_sap_prebuild_frame_buffer_get(uint16_t payload_size)
00911 {
00912     mac_pre_build_frame_t * buffer = ns_dyn_mem_temporary_alloc(sizeof(mac_pre_build_frame_t));
00913     if (!buffer) {
00914         return NULL;
00915     }
00916     memset(buffer, 0, sizeof(mac_pre_build_frame_t));
00917     if (payload_size) {
00918         //Mac interlnal payload allocate
00919         buffer->mac_payload = ns_dyn_mem_temporary_alloc(payload_size);
00920         if (!buffer->mac_payload) {
00921             ns_dyn_mem_free(buffer);
00922             return NULL;
00923         }
00924         buffer->mac_allocated_payload_ptr = true;
00925         buffer->mac_payload_length = payload_size;
00926     } else {
00927         buffer->mac_allocated_payload_ptr = false;
00928     }
00929     return buffer;
00930 }
00931 
00932 
00933 void mcps_sap_prebuild_frame_buffer_free(mac_pre_build_frame_t *buffer)
00934 {
00935     if (!buffer) {
00936         return;
00937     }
00938 
00939     if (buffer->mac_allocated_payload_ptr) {
00940         ns_dyn_mem_free(buffer->mac_payload);
00941     }
00942     //Free Buffer frame
00943     ns_dyn_mem_free(buffer);
00944 
00945 }
00946 
00947 static ccm_globals_t * mac_frame_security_parameters_init(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
00948 {
00949     /* Encrypt the packet payload if AES encyption bit is set */
00950     mlme_security_t key_source;
00951     key_source.KeyIdMode = buffer->aux_header.KeyIdMode;
00952     key_source.KeyIndex = buffer->aux_header.KeyIndex;
00953     key_source.SecurityLevel = buffer->aux_header.securityLevel;
00954     memcpy(key_source.Keysource, buffer->aux_header.Keysource, 8);
00955     mlme_key_descriptor_t *key_description =  mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
00956 
00957     if (!key_description ) {
00958         buffer->status = MLME_UNAVAILABLE_KEY;
00959         return NULL;
00960 
00961     }
00962     mlme_device_descriptor_t *device_description;
00963     uint8_t *nonce_ext_64_ptr;
00964 
00965     if (key_description->unique_key_descriptor) {
00966         device_description = mac_sec_mib_device_description_get_attribute_index(rf_ptr, key_description->KeyDeviceList->DeviceDescriptorHandle);
00967         if (!device_description) {
00968 
00969             buffer->status = MLME_UNAVAILABLE_KEY;
00970             return NULL;
00971         }
00972         nonce_ext_64_ptr = device_description->ExtAddress;
00973     } else {
00974         //Discover device descriptor only unicast packet which need ack
00975         if (buffer->fcf_dsn.DstAddrMode && buffer->fcf_dsn.ackRequested) {
00976             device_description =  mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode);
00977             if (!device_description) {
00978 
00979                 buffer->status = MLME_UNAVAILABLE_KEY;
00980                 return NULL;
00981             }
00982         }
00983         nonce_ext_64_ptr = rf_ptr->mac64;
00984     }
00985 
00986     uint8_t *key_ptr = key_description->Key;
00987 
00988     //Remember to update security counter here!
00989     buffer->aux_header.frameCounter = rf_ptr->security_frame_counter;
00990 
00991     //Check If frame counter overflow is coming
00992     if (buffer->aux_header.frameCounter == 0xffffffff) {
00993         buffer->status = MLME_COUNTER_ERROR;
00994         return NULL;
00995     }
00996 
00997     ccm_globals_t *ccm_ptr = ccm_sec_init(buffer->aux_header.securityLevel, key_ptr, AES_CCM_ENCRYPT, 2);
00998     if (!ccm_ptr) {
00999         buffer->status = MLME_SECURITY_FAIL;
01000         return NULL;
01001     }
01002 
01003     mac_security_interface_aux_ccm_nonce_set(ccm_ptr->exp_nonce, nonce_ext_64_ptr, buffer->aux_header.frameCounter,
01004                                              buffer->aux_header.securityLevel);
01005     //Increment security counter
01006     rf_ptr->security_frame_counter++;
01007     return ccm_ptr;
01008 
01009 }
01010 
01011 
01012 static void mac_common_data_confirmation_handle (protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buf)
01013 {
01014     mac_event_t m_event;
01015     /* Raed MAC TX state */
01016     m_event = (mac_event_t) rf_mac_setup->mac_tx_result;
01017     rf_mac_setup->mac_tx_result = MAC_STATE_IDLE;
01018 
01019     /* Discard Tx timeout timer */
01020     timer_mac_stop(rf_mac_setup);
01021     if (m_event == MAC_CCA_FAIL) {
01022         sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_CCA_FAIL, 0);
01023         /* CCA fail */
01024         //rf_mac_setup->cca_failure++;
01025         buf->status = MLME_BUSY_CHAN;
01026     } else {
01027         sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_COUNT, buf->mac_payload_length);
01028         if (m_event == MAC_TX_FAIL) {
01029             sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_FAIL, 0);
01030             tr_error("MAC tx fail");
01031             buf->status = MLME_TX_NO_ACK;
01032         } else if (m_event == MAC_TX_DONE) {
01033             if (mac_is_ack_request_set(buf) == false) {
01034                 sw_mac_stats_update(rf_mac_setup, STAT_MAC_BC_TX_COUNT, 0);
01035             }
01036             if (buf->fcf_dsn.frametype == FC_CMD_FRAME && buf->mac_command_id == MAC_DATA_REQ) {
01037                 buf->status = MLME_NO_DATA;
01038             } else {
01039                 buf->status = MLME_SUCCESS;
01040             }
01041 
01042         } else if (m_event == MAC_TX_DONE_PENDING) {
01043             buf->status = MLME_SUCCESS;
01044         } else if (m_event == MAC_TX_TIMEOUT) {
01045             /* Make MAC Soft Reset */;
01046             tr_debug("Driver TO event");
01047             //Disable allways
01048             mac_mlme_mac_radio_disabled(rf_mac_setup);
01049             //Enable Radio
01050             mac_mlme_mac_radio_enable(rf_mac_setup);
01051             buf->status = MLME_TRANSACTION_EXPIRED;
01052         }
01053     }
01054 }
01055 
01056 void mac_data_wait_timer_start(protocol_interface_rf_mac_setup_s *rf_mac_setup)
01057 {
01058     eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id);
01059     eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 200); //10ms
01060     rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL;
01061     rf_mac_setup->mlme_tick_count = 30; //300ms
01062 }
01063 
01064 static void mac_data_interface_internal_tx_confirm_handle(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buf)
01065 {
01066     //GET Interface
01067 
01068     switch (buf->mac_command_id) {
01069         case MAC_DATA_REQ:
01070 
01071             if (buf->status == MLME_SUCCESS) {
01072                 if (!rf_mac_setup->macRxDataAtPoll) {
01073                     //Start Timer
01074                     mac_data_wait_timer_start(rf_mac_setup);
01075                     //Set Buffer back to
01076                 }
01077                 rf_mac_setup->active_pd_data_request = buf;
01078                 return;
01079 
01080             } else {
01081                 //Disable Radio
01082                 if (!rf_mac_setup->macCapRxOnIdle) {
01083                     mac_mlme_mac_radio_disabled(rf_mac_setup);
01084                 }
01085                 rf_mac_setup->macDataPollReq = false;
01086 
01087                 mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup);
01088 
01089                 if( mac_api ) {
01090                     mlme_poll_conf_t confirm;
01091                     confirm.status = buf->status;
01092                     mac_api->mlme_conf_cb(mac_api,MLME_POLL, &confirm);
01093                 }
01094 
01095             }
01096             break;
01097 
01098         case MAC_BEACON_REQ:
01099             mac_mlme_active_scan_response_timer_start(rf_mac_setup);
01100             break;
01101 
01102         default:
01103             if (rf_mac_setup->tun_extension_rf_driver) {
01104                 if (buf->fcf_dsn.ackRequested) {
01105                     phy_device_driver_s *driver = rf_mac_setup->tun_extension_rf_driver->phy_driver;
01106                     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);
01107                 }
01108             }
01109             break;
01110     }
01111 
01112     mcps_sap_prebuild_frame_buffer_free(buf);
01113 
01114 }
01115 
01116 static void mcps_data_confirm_handle(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) {
01117 
01118     sw_mac_stats_update(rf_ptr, STAT_MAC_TX_CCA_ATT, rf_ptr->mac_tx_status.cca_cnt);
01119     sw_mac_stats_update(rf_ptr, STAT_MAC_TX_RETRY, rf_ptr->mac_tx_status.retry);
01120     mcps_data_conf_t confirm;
01121     if (rf_ptr->fhss_api) {
01122         // FHSS checks if this failed buffer needs to be pushed back to TX queue and retransmitted
01123         if ((rf_ptr->mac_tx_result == MAC_TX_FAIL) || (rf_ptr->mac_tx_result == MAC_CCA_FAIL)) {
01124             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) {
01125                 mcps_sap_pd_req_queue_write(rf_ptr, buffer);
01126                 tr_debug("Channel retry, TX result: %u, handle: %u", rf_ptr->mac_tx_result, buffer->msduHandle);
01127                 return;
01128             }
01129         }
01130     }
01131     confirm.cca_retries = rf_ptr->mac_tx_status.cca_cnt;
01132     confirm.tx_retries = rf_ptr->mac_tx_status.retry;
01133     mac_common_data_confirmation_handle(rf_ptr, buffer);
01134     confirm.msduHandle = buffer->msduHandle;
01135     confirm.status = buffer->status;
01136     confirm.timestamp = 0;
01137 
01138     if (buffer->upper_layer_request) {
01139         //Check tunnel
01140         mcps_sap_prebuild_frame_buffer_free(buffer);
01141         mcps_data_confirm_cb(rf_ptr, &confirm);
01142     } else {
01143         mac_data_interface_internal_tx_confirm_handle(rf_ptr, buffer);
01144     }
01145 }
01146 
01147 static void mac_security_data_params_set(ccm_globals_t *ccm_ptr, uint8_t *data_ptr, uint16_t msduLength)
01148 {
01149     ccm_ptr->data_len = msduLength;
01150     ccm_ptr->data_ptr = data_ptr;
01151 }
01152 
01153 
01154 static void mac_security_authentication_data_params_set(ccm_globals_t *ccm_ptr, uint8_t *a_data_ptr,
01155         uint8_t a_data_length)
01156 {
01157     if (ccm_ptr->mic_len) {
01158 
01159         ccm_ptr->adata_len = a_data_length;
01160         ccm_ptr->adata_ptr = a_data_ptr;
01161         ccm_ptr->mic = ccm_ptr->data_ptr;
01162         ccm_ptr->mic += ccm_ptr->data_len;
01163     }
01164 }
01165 
01166 static uint8_t *mac_security_interface_aux_security_header_write(uint8_t *ptr, const mac_aux_security_header_t *auxHeader)
01167 {
01168     uint8_t auxBaseHeader;
01169     auxBaseHeader = auxHeader->securityLevel;
01170     auxBaseHeader |= (auxHeader->KeyIdMode << 3);
01171     *ptr++ = auxBaseHeader;
01172     ptr = common_write_32_bit_inverse(auxHeader->frameCounter, ptr);
01173 
01174     switch (auxHeader->KeyIdMode) {
01175         case MAC_KEY_ID_MODE_SRC8_IDX:
01176             memcpy(ptr, auxHeader->Keysource, 8);
01177             ptr += 8;
01178             *ptr++ = auxHeader->KeyIndex;
01179             break;
01180         case MAC_KEY_ID_MODE_SRC4_IDX:
01181             memcpy(ptr, auxHeader->Keysource, 4);
01182             ptr += 4;
01183             *ptr++ = auxHeader->KeyIndex;
01184             break;
01185         case MAC_KEY_ID_MODE_IDX:
01186             *ptr++ = auxHeader->KeyIndex;
01187             break;
01188         default:
01189             break;
01190     }
01191     return ptr;
01192 }
01193 
01194 
01195 static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer) {
01196     phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver;
01197     dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer;
01198     uint8_t open_payload = 0;
01199     uint8_t *ptr;
01200     ccm_globals_t *ccm_ptr = NULL;
01201 
01202     if (buffer->mac_header_length_with_security == 0) {
01203         rf_ptr->mac_tx_status.length = buffer->mac_payload_length;
01204         ptr = tx_buf->buf;
01205         if (dev_driver->phy_header_length) {
01206             ptr += dev_driver->phy_header_length;
01207         }
01208         tx_buf->len = buffer->mac_payload_length;
01209 
01210         memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length );
01211         return 0;
01212     }
01213 
01214     if (buffer->fcf_dsn.frametype != FC_DATA_FRAME) {
01215         open_payload = 1;
01216     }
01217 
01218     if (buffer->fcf_dsn.frametype == MAC_FRAME_BEACON) {
01219         buffer->fcf_dsn.DSN = mac_mlme_set_new_beacon_sqn(rf_ptr);
01220     } else {
01221         buffer->fcf_dsn.DSN = mac_mlme_set_new_sqn(rf_ptr);
01222     }
01223 
01224     if (buffer->fcf_dsn.securityEnabled) {
01225         ccm_ptr = mac_frame_security_parameters_init(rf_ptr, buffer);
01226         if ( !ccm_ptr) {
01227             return -2;
01228         }
01229     }
01230 
01231     if (buffer->mac_payload_length > MAC_IEEE_802_15_4_MAX_MAC_SAFE_PAYLOAD_SIZE &&
01232             dev_driver->phy_MTU == MAC_IEEE_802_15_4_MAX_PHY_PACKET_SIZE) {
01233         /* IEEE 802.15.4-2003 only allowed unsecured payloads up to 102 bytes
01234         * (always leaving room for maximum MAC overhead).
01235         * IEEE 802.15.4-2006 allows bigger if MAC header is small enough, but
01236         * we have to set the version field.
01237         */
01238         buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
01239     }
01240     //Frame length
01241     uint16_t frame_length = buffer->mac_header_length_with_security + buffer->mac_payload_length + buffer->security_mic_len;
01242     if ((frame_length) > dev_driver->phy_MTU - 2) {
01243         tr_debug("Too Long %u, %u pa %u header %u mic",frame_length, buffer->mac_payload_length, buffer->mac_header_length_with_security,  buffer->security_mic_len);
01244         buffer->status = MLME_FRAME_TOO_LONG;
01245         return -1;
01246     }
01247 
01248     rf_ptr->mac_tx_status.length = frame_length;
01249     ptr = tx_buf->buf;
01250     if (dev_driver->phy_header_length) {
01251         ptr += dev_driver->phy_header_length;
01252     }
01253     tx_buf->len = frame_length;
01254 
01255     ptr = mcps_generic_header_write(ptr, buffer);
01256 
01257     if (buffer->fcf_dsn.securityEnabled) {
01258         ptr = mac_security_interface_aux_security_header_write(ptr, &buffer->aux_header);
01259         ccm_ptr->data_len = (buffer->mac_payload_length - open_payload);
01260             ccm_ptr->data_ptr = ptr + open_payload;
01261         mac_security_data_params_set(ccm_ptr, (ptr + open_payload), (buffer->mac_payload_length - open_payload));
01262         mac_security_authentication_data_params_set(ccm_ptr, (ptr  - buffer->mac_header_length_with_security), (buffer->mac_header_length_with_security +open_payload));
01263         //Copy Payload
01264         memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length);
01265         ccm_process_run(ccm_ptr);
01266     } else {
01267         //Copy Payload
01268         memcpy(ptr, buffer->mac_payload, buffer->mac_payload_length );
01269     }
01270     return 0;
01271 }
01272 
01273 static int8_t mcps_pd_data_request(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
01274 {
01275     rf_ptr->macTxRequestAck = false;
01276     memset(&(rf_ptr->mac_tx_status), 0, sizeof(mac_tx_status_t));
01277     if (mcps_generic_packet_build(rf_ptr, buffer) != 0) {
01278         return -1;
01279     }
01280     rf_ptr->macTxRequestAck = buffer->fcf_dsn.ackRequested;
01281 
01282     mac_mlme_mac_radio_enable(rf_ptr);
01283     /* Trig MAC TX */
01284     return mac_pd_sap_req(rf_ptr);
01285 }
01286 
01287 bool mac_is_ack_request_set(mac_pre_build_frame_t *buffer)
01288 {
01289     return buffer->fcf_dsn.ackRequested;
01290 }
01291 
01292 int mac_convert_frame_type_to_fhss(uint8_t frame_type)
01293 {
01294     if (FC_BEACON_FRAME == frame_type) {
01295         return FHSS_SYNCH_FRAME;
01296     }
01297     if (FC_CMD_FRAME == frame_type) {
01298         return FHSS_SYNCH_REQUEST_FRAME;
01299     }
01300     return FHSS_DATA_FRAME;
01301 }
01302 
01303 void mcps_sap_pd_req_queue_write(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
01304 {
01305     if( !rf_mac_setup || !buffer){
01306         return;
01307     }
01308     if (!rf_mac_setup->active_pd_data_request) {
01309         // Push broadcast buffers to queue when broadcast disabled flag is set
01310         if ((rf_mac_setup->macBroadcastDisabled == true) && !mac_is_ack_request_set(buffer)) {
01311             goto push_to_queue;
01312         }
01313         if (rf_mac_setup->fhss_api) {
01314             if (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
01315                 buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length,
01316                 rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == false) {
01317                 goto push_to_queue;
01318             }
01319         }
01320         //Start TX process immediately
01321         rf_mac_setup->active_pd_data_request = buffer;
01322         if (mcps_pd_data_request(rf_mac_setup, buffer) != 0) {
01323             rf_mac_setup->active_pd_data_request = NULL;
01324             mcps_data_conf_t confirm;
01325             memset(&confirm, 0, sizeof(mcps_data_conf_t));
01326             confirm.msduHandle = buffer->msduHandle;
01327             confirm.status = buffer->status;
01328             bool requested_from_up = buffer->upper_layer_request;
01329             mcps_sap_prebuild_frame_buffer_free(buffer);
01330             if (requested_from_up) {
01331                 mcps_data_confirm_cb(rf_mac_setup, &confirm);
01332             }
01333             //Call
01334         }
01335 
01336         return;
01337     }
01338 push_to_queue:
01339     rf_mac_setup->direct_queue_bytes += buffer->mac_payload_length;
01340     mac_pre_build_frame_t *prev = NULL;
01341     mac_pre_build_frame_t *cur = rf_mac_setup->pd_data_request_queue_to_go;
01342     bool use_bc_queue = false;
01343 
01344     // When FHSS is enabled, broadcast buffers are pushed to own queue
01345     if (rf_mac_setup->fhss_api) {
01346         if (rf_mac_setup->fhss_api->use_broadcast_queue(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
01347                 mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype)) == true) {
01348             cur = rf_mac_setup->pd_data_request_bc_queue_to_go;
01349             use_bc_queue = true;
01350             rf_mac_setup->broadcast_queue_size++;
01351         }
01352     }
01353     if (use_bc_queue == false) {
01354         rf_mac_setup->unicast_queue_size++;
01355     }
01356     sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_QUEUE, rf_mac_setup->unicast_queue_size + rf_mac_setup->broadcast_queue_size);
01357 
01358     //Push to queue
01359     if (!cur) {
01360         if (rf_mac_setup->fhss_api && (use_bc_queue == true)) {
01361             rf_mac_setup->pd_data_request_bc_queue_to_go = buffer;
01362             return;
01363         } else {
01364             rf_mac_setup->pd_data_request_queue_to_go = buffer;
01365             return;
01366         }
01367     }
01368 
01369     while(cur) {
01370         if (cur->priority < buffer->priority) {
01371             //Set before cur
01372             if (prev) {
01373                 prev->next = buffer;
01374                 buffer->next = cur;
01375             } else {
01376                 buffer->next = cur;
01377                 if (rf_mac_setup->fhss_api && (use_bc_queue == true)) {
01378                     rf_mac_setup->pd_data_request_bc_queue_to_go = buffer;
01379                 } else {
01380                     rf_mac_setup->pd_data_request_queue_to_go = buffer;
01381                 }
01382             }
01383             cur = NULL;
01384 
01385         } else if( cur->next == NULL) {
01386             cur->next = buffer;
01387             cur = NULL;
01388         } else {
01389             prev = cur;
01390             cur = cur->next;
01391         }
01392     }
01393 }
01394 
01395 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)
01396 {
01397     mac_pre_build_frame_t *queue = rf_mac_setup->pd_data_request_queue_to_go;
01398     if (is_bc_queue == true) {
01399         queue = rf_mac_setup->pd_data_request_bc_queue_to_go;
01400     }
01401 
01402     if (!queue) {
01403         return NULL;
01404     }
01405 
01406     mac_pre_build_frame_t *buffer = queue;
01407     mac_pre_build_frame_t *prev = NULL;
01408     // With FHSS, check TX conditions
01409     if (rf_mac_setup->fhss_api) {
01410         while (buffer) {
01411             if ((flush == true) || (rf_mac_setup->fhss_api->check_tx_conditions(rf_mac_setup->fhss_api, !mac_is_ack_request_set(buffer),
01412                     buffer->msduHandle, mac_convert_frame_type_to_fhss(buffer->fcf_dsn.frametype), buffer->mac_payload_length,
01413                     rf_mac_setup->dev_driver->phy_driver->phy_header_length, rf_mac_setup->dev_driver->phy_driver->phy_tail_length) == true)) {
01414                 break;
01415             }
01416             prev = buffer;
01417             buffer = buffer->next;
01418         }
01419     }
01420     // This check is here to prevent (Linux) border router from pushing broadcast frames to RF interface on unicast channel.
01421     while (buffer) {
01422         /* Allow returning buffer when:
01423          * - Flush is enabled
01424          * - Broadcast not disabled
01425          * - Broadcast is disabled and buffer has unicast destination
01426          */
01427         if ((flush == true) || (rf_mac_setup->macBroadcastDisabled == false) || ((rf_mac_setup->macBroadcastDisabled == true) && mac_is_ack_request_set(buffer))) {
01428             break;
01429         }
01430         prev = buffer;
01431         buffer = buffer->next;
01432     }
01433     if (!buffer) {
01434         return NULL;
01435     }
01436     // When other than first buffer is read out, link next buffer to previous buffer
01437     if (prev) {
01438         prev->next = buffer->next;
01439     }
01440 
01441     // When the first buffer is read out, set next buffer as the new first buffer
01442     if (is_bc_queue == false) {
01443         if (!prev) {
01444             rf_mac_setup->pd_data_request_queue_to_go = buffer->next;
01445         }
01446         rf_mac_setup->unicast_queue_size--;
01447     } else {
01448         if (!prev) {
01449             rf_mac_setup->pd_data_request_bc_queue_to_go = buffer->next;
01450         }
01451         rf_mac_setup->broadcast_queue_size--;
01452     }
01453     buffer->next = NULL;
01454     rf_mac_setup->direct_queue_bytes -= buffer->mac_payload_length;
01455 
01456     sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_QUEUE, rf_mac_setup->unicast_queue_size + rf_mac_setup->broadcast_queue_size);
01457     return buffer;
01458 }
01459 
01460 void mcps_sap_pre_parsed_frame_buffer_free(mac_pre_parsed_frame_t *buf)
01461 {
01462     ns_dyn_mem_free(buf);
01463 }
01464 
01465 mac_pre_parsed_frame_t * mcps_sap_pre_parsed_frame_buffer_get(const uint8_t *data_ptr, uint16_t frame_length)
01466 {
01467     mac_pre_parsed_frame_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(mac_pre_parsed_frame_t) + frame_length);
01468 
01469     if (buffer) {
01470         memset(buffer, 0, sizeof(mac_pre_parsed_frame_t) + frame_length);
01471         buffer->frameLength = frame_length;
01472         memcpy(mac_header_message_start_pointer(buffer), data_ptr, frame_length);
01473     }
01474     return buffer;
01475 }
01476 
01477 static void mac_set_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
01478 {
01479     rf_mac_setup->active_mac_events |= (1 << event_type);
01480 }
01481 
01482 static void mac_clear_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
01483 {
01484     rf_mac_setup->active_mac_events &= ~(1 << event_type);
01485 }
01486 
01487 static bool mac_read_active_event(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t event_type)
01488 {
01489     if (rf_mac_setup->active_mac_events & (1 << event_type)) {
01490         return true;
01491     }
01492     return false;
01493 }
01494 
01495 int8_t mcps_sap_pd_ind(mac_pre_parsed_frame_t *buffer)
01496 {
01497     if (mac_tasklet_event_handler < 0 || !buffer) {
01498         return -1;
01499     }
01500 
01501     arm_event_s event = {
01502             .receiver = mac_tasklet_event_handler,
01503             .sender = 0,
01504             .event_id = 0,
01505             .data_ptr = buffer,
01506             .event_type = MCPS_SAP_DATA_IND_EVENT,
01507             .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
01508     };
01509 
01510     return eventOS_event_send(&event);
01511 }
01512 
01513 void mcps_sap_pd_confirm(void *mac_ptr)
01514 {
01515     if (mac_tasklet_event_handler < 0  || !mac_ptr) {
01516         return;
01517     }
01518     arm_event_s event = {
01519         .receiver = mac_tasklet_event_handler,
01520         .sender = 0,
01521         .event_id = 0,
01522         .data_ptr = mac_ptr,
01523         .event_type = MCPS_SAP_DATA_CNF_EVENT,
01524         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
01525     };
01526 
01527     if (eventOS_event_send(&event) != 0) {
01528         tr_error("mcps_sap_pd_confirm(): event send failed");
01529     }
01530 }
01531 
01532 void mcps_sap_trig_tx(void *mac_ptr)
01533 {
01534     if (mac_tasklet_event_handler < 0  || !mac_ptr) {
01535         return;
01536     }
01537     if (mac_read_active_event(mac_ptr, MAC_SAP_TRIG_TX) == true) {
01538         return;
01539     }
01540     arm_event_s event = {
01541         .receiver = mac_tasklet_event_handler,
01542         .sender = 0,
01543         .event_id = 0,
01544         .data_ptr = mac_ptr,
01545         .event_type = MAC_SAP_TRIG_TX,
01546         .priority = ARM_LIB_MED_PRIORITY_EVENT,
01547     };
01548 
01549     if (eventOS_event_send(&event) != 0) {
01550         tr_error("mcps_sap_trig_tx(): event send failed");
01551     } else {
01552         mac_set_active_event(mac_ptr, MAC_SAP_TRIG_TX);
01553     }
01554 }
01555 
01556 
01557 void mac_generic_event_trig(uint8_t event_type, void *mac_ptr, bool low_latency)
01558 {
01559     arm_library_event_priority_e priority;
01560     if (low_latency) {
01561         priority = ARM_LIB_LOW_PRIORITY_EVENT;
01562     } else {
01563         priority = ARM_LIB_HIGH_PRIORITY_EVENT;
01564     }
01565     arm_event_s event = {
01566         .receiver = mac_tasklet_event_handler,
01567         .sender = 0,
01568         .event_id = 0,
01569         .data_ptr = mac_ptr,
01570         .event_type = event_type,
01571         .priority = priority,
01572     };
01573 
01574     if (eventOS_event_send(&event) != 0) {
01575         tr_error("mac_generic_event_trig(): event send failed");
01576     }
01577 }
01578 
01579 void mac_mcps_buffer_queue_free(protocol_interface_rf_mac_setup_s *rf_mac_setup) {
01580 
01581     if (rf_mac_setup->active_pd_data_request) {
01582         mcps_sap_prebuild_frame_buffer_free(rf_mac_setup->active_pd_data_request);
01583         rf_mac_setup->active_pd_data_request = NULL;
01584     }
01585 
01586     while (rf_mac_setup->pd_data_request_queue_to_go) {
01587         mac_pre_build_frame_t *buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, false, true);
01588         if (buffer) {
01589             mcps_sap_prebuild_frame_buffer_free(buffer);
01590         }
01591     }
01592 
01593     while (rf_mac_setup->pd_data_request_bc_queue_to_go) {
01594         mac_pre_build_frame_t *buffer = mcps_sap_pd_req_queue_read(rf_mac_setup, true, true);
01595         if (buffer) {
01596             mcps_sap_prebuild_frame_buffer_free(buffer);
01597         }
01598     }
01599 
01600     while (rf_mac_setup->indirect_pd_data_request_queue) {
01601         mac_pre_build_frame_t *buffer = rf_mac_setup->indirect_pd_data_request_queue;
01602         if (buffer) {
01603             rf_mac_setup->indirect_pd_data_request_queue = buffer->next;
01604             mcps_sap_prebuild_frame_buffer_free(buffer);
01605         }
01606     }
01607 }
01608 /**
01609  * Function return list start pointer
01610  */
01611 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)
01612 {
01613     mac_pre_build_frame_t *list_prev = NULL;
01614     mac_pre_build_frame_t *list_ptr = list_ptr_original;
01615     while (list_ptr) {
01616         if (list_ptr->fcf_dsn.frametype == MAC_FRAME_DATA && list_ptr->msduHandle == msduhandle) {
01617 
01618             if (list_prev) {
01619                 list_prev->next = list_ptr->next;
01620             } else {
01621                 list_ptr_original = list_ptr->next;
01622             }
01623             list_ptr->next = NULL;
01624 
01625             //Free data and buffer
01626             mcps_sap_prebuild_frame_buffer_free(list_ptr);
01627             list_ptr = NULL;
01628             *status = true;
01629         } else {
01630             list_prev = list_ptr;
01631             list_ptr = list_ptr->next;
01632         }
01633     }
01634     return list_ptr_original;
01635 }
01636 
01637 
01638 static bool mcps_sap_purge_req_from_queue(protocol_interface_rf_mac_setup_s *rf_mac_setup , uint8_t msduhandle)
01639 {
01640     //Discover from TX queue data packets with given
01641     uint8_t status = false;
01642     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);
01643 
01644     if (status) {
01645         return true;
01646     }
01647 
01648     rf_mac_setup->indirect_pd_data_request_queue = mcps_sap_purge_from_list(rf_mac_setup->indirect_pd_data_request_queue, msduhandle, &status);
01649 
01650     return status;
01651 
01652 }
01653 
01654 void mcps_sap_purge_reg_handler(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mcps_purge_t *purge_req)
01655 {
01656     mcps_purge_conf_t confirmation;
01657     confirmation.msduHandle = purge_req->msduHandle;
01658 
01659     if (mcps_sap_purge_req_from_queue(rf_mac_setup , confirmation.msduHandle)) {
01660         confirmation.status = MLME_SUCCESS;
01661     } else {
01662         confirmation.status = MLME_INVALID_HANDLE;
01663     }
01664 
01665     if( get_sw_mac_api(rf_mac_setup) ) {
01666         get_sw_mac_api(rf_mac_setup)->purge_conf_cb(get_sw_mac_api(rf_mac_setup), &confirmation);
01667     }
01668 }