Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Tue Jul 12 2022 14:24:12 by
