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