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