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_mlme.c
00001 /* 00002 * Copyright (c) 2013-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_mlme.c 00020 * \brief MLME API for MAC control 00021 * 00022 * MLME API for MAC certification. 00023 * 00024 */ 00025 00026 #include "nsconfig.h" 00027 #include <string.h> 00028 #include "ns_types.h" 00029 #include "eventOS_event.h" 00030 #include "eventOS_scheduler.h" 00031 #include "eventOS_callback_timer.h" 00032 #include "ns_trace.h" 00033 #include "randLIB.h" 00034 #include "nsdynmemLIB.h" 00035 #include "platform/arm_hal_interrupt.h" 00036 #include "common_functions.h" 00037 #include "sw_mac.h" 00038 #include "mlme.h" 00039 #include "mac_api.h" 00040 #include "fhss_api.h " 00041 00042 #include "MAC/IEEE802_15_4/sw_mac_internal.h" 00043 #include "MAC/IEEE802_15_4/mac_defines.h" 00044 #include "MAC/IEEE802_15_4/mac_header_helper_functions.h" 00045 #include "MAC/IEEE802_15_4/mac_indirect_data.h" 00046 #include "MAC/IEEE802_15_4/mac_security_mib.h" 00047 #include "MAC/IEEE802_15_4/mac_mlme.h" 00048 #include "MAC/IEEE802_15_4/mac_timer.h" 00049 #include "MAC/IEEE802_15_4/mac_pd_sap.h" 00050 #include "MAC/IEEE802_15_4/mac_mcps_sap.h" 00051 #include "MAC/virtual_rf/virtual_rf_defines.h" 00052 #include "MAC/rf_driver_storage.h" 00053 00054 #define TRACE_GROUP "mlme" 00055 00056 #define MAC_ACK_WAIT_DURATION 90 00057 00058 static int8_t mac_mlme_rf_disable(struct protocol_interface_rf_mac_setup *rf_mac_setup); 00059 static int8_t mac_mlme_rf_receiver_enable(struct protocol_interface_rf_mac_setup *rf_mac_setup); 00060 00061 static void mac_mlme_write_mac16(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr); 00062 static void mac_mlme_write_mac64(struct protocol_interface_rf_mac_setup *rf_setup, uint8_t *addrPtr); 00063 static void mac_mlme_timers_disable(protocol_interface_rf_mac_setup_s *rf_ptr); 00064 static void mac_mlme_free_scan_temporary_data(protocol_interface_rf_mac_setup_s *rf_mac_setup); 00065 static int8_t mac_mlme_set_panid(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t pan_id); 00066 static int8_t mac_mlme_set_mac16(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t mac16); 00067 static int8_t mac_mlme_rf_channel_set(struct protocol_interface_rf_mac_setup *rf_setup, uint8_t new_channel); 00068 static void mac_mlme_timer_cb(int8_t timer_id, uint16_t slots); 00069 static void mac_mlme_start_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_start_conf_t *conf); 00070 static void mac_mlme_scan_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_scan_conf_t *conf); 00071 static int mac_mlme_set_symbol_rate(protocol_interface_rf_mac_setup_s *rf_mac_setup); 00072 00073 static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t channel) 00074 { 00075 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00076 rf_mac_setup->mac_channel = channel; 00077 if (rf_mac_setup->macRfRadioOn) { 00078 if (dev_driver->state_control) { 00079 dev_driver->state_control(PHY_INTERFACE_DOWN, 0); 00080 } 00081 } 00082 if (dev_driver->state_control) { 00083 dev_driver->state_control(PHY_INTERFACE_RX_ENERGY_STATE, channel); 00084 } 00085 rf_mac_setup->macRfRadioOn = true; 00086 rf_mac_setup->macRfRadioTxActive = false; 00087 } 00088 00089 uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list, bool clear_channel) 00090 { 00091 uint8_t i, j = 0, k = 1; 00092 uint32_t mask = 1; 00093 uint32_t *channel_mask = mac_channel_list->channel_mask; 00094 00095 if (mac_channel_list->channel_page == CHANNEL_PAGE_9 || 00096 mac_channel_list->channel_page == CHANNEL_PAGE_10) { 00097 k = 8; 00098 } 00099 for (j = 0; j < k; j++) { 00100 for (i = 0; i < 32; i++) { 00101 if (*channel_mask & mask) { 00102 if (clear_channel) { 00103 *channel_mask &= ~mask; 00104 } 00105 return (i + j * 32); 00106 } 00107 mask <<= 1; 00108 } 00109 mask = 1; 00110 channel_mask++; 00111 } 00112 return 0xffff; 00113 } 00114 00115 static uint32_t mac_mlme_channel_symbol_rate(uint8_t channel_page, uint8_t channel) 00116 { 00117 00118 uint32_t symbol_rate; 00119 00120 // Gets symbol rate for channel 00121 switch (channel_page) { 00122 case CHANNEL_PAGE_0: 00123 // 868 Mhz BPSK 00124 if (channel == 0) { 00125 symbol_rate = 20000; 00126 // 915 Mhz BPSK 00127 } else if (channel >= 1 && channel <= 10) { 00128 symbol_rate = 40000; 00129 // 2450 Mhz O-QPSK 00130 } else { 00131 symbol_rate = 62500; 00132 } 00133 break; 00134 case CHANNEL_PAGE_1: 00135 // 868 MHz ASK 00136 if (channel == 0) { 00137 symbol_rate = 12500; 00138 // 915 MHz ASK 00139 } else { 00140 symbol_rate = 50000; 00141 } 00142 break; 00143 case CHANNEL_PAGE_2: 00144 // 868 MHz O-QPSK 00145 if (channel == 0) { 00146 symbol_rate = 25000; 00147 // 915 MHz O-QPSK 00148 } else { 00149 symbol_rate = 62500; 00150 } 00151 break; 00152 case CHANNEL_PAGE_3: 00153 // 2450 CSS 00154 symbol_rate = 167000; 00155 break; 00156 case CHANNEL_PAGE_6: 00157 // 950 MHz BPSK 00158 if (channel <= 9) { 00159 symbol_rate = 20000; 00160 // 950 MHz GFSK 00161 } else { 00162 symbol_rate = 100000; 00163 } 00164 break; 00165 default: 00166 symbol_rate = 62500; 00167 break; 00168 } 00169 00170 return symbol_rate; 00171 } 00172 00173 static void mac_mlme_calc_scan_duration(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t channel) 00174 { 00175 rf_mac_setup->mlme_ED_counter = 1; 00176 00177 if (rf_mac_setup->scan_duration) { 00178 rf_mac_setup->mlme_ED_counter <<= rf_mac_setup->scan_duration; 00179 } 00180 00181 rf_mac_setup->mlme_ED_counter++; 00182 00183 if (rf_mac_setup->scan_type == MAC_ED_SCAN_TYPE) { 00184 // Gets symbol rate for channel that is scanned 00185 uint32_t symbol_rate = mac_mlme_channel_symbol_rate( 00186 rf_mac_setup->mac_channel_list.channel_page, channel); 00187 00188 // Energy scan duration is aBaseSuperframeDuration * (2^n + 1) 00189 // aBaseSuperframeDuration is 960 symbols e.g for 2.4Ghz O-QPSK with 62.5 ksymbols/s -> 15,36ms. 00190 // ED scan timer timeout is 4.8ms 00191 uint16_t frame_duration = (uint32_t) 960 * 100000 / symbol_rate; 00192 rf_mac_setup->mlme_ED_counter = (uint32_t) rf_mac_setup->mlme_ED_counter * frame_duration / 480; 00193 } 00194 } 00195 00196 static void mac_mlme_start_request(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00197 { 00198 mac_pre_build_frame_t *buf; 00199 platform_enter_critical(); 00200 00201 mac_mlme_rf_disable(rf_mac_setup); 00202 buf = rf_mac_setup->active_pd_data_request; 00203 rf_mac_setup->active_pd_data_request = NULL; 00204 mac_mlme_mac_radio_enable(rf_mac_setup); 00205 rf_mac_setup->macUpState = true; 00206 if (buf) { 00207 // Active packet is pushed back to queue and statistics will be cleared. They need to be updated here. 00208 sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_CCA_ATT, rf_mac_setup->mac_tx_status.cca_cnt); 00209 sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_RETRY, rf_mac_setup->mac_tx_status.retry); 00210 mcps_sap_pd_req_queue_write(rf_mac_setup, buf); 00211 } 00212 platform_exit_critical(); 00213 } 00214 00215 uint8_t mac_mlme_beacon_req_tx(protocol_interface_rf_mac_setup_s *rf_ptr) 00216 { 00217 00218 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0); 00219 00220 if (buf) { 00221 buf->fcf_dsn.DstAddrMode = MAC_ADDR_MODE_16_BIT; 00222 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_NONE; 00223 buf->fcf_dsn.frametype = FC_CMD_FRAME; 00224 buf->DstPANId = 0xffff; 00225 buf->DstAddr[0] = 0xff; 00226 buf->DstAddr[1] = 0xff; 00227 buf->mac_command_id = MAC_BEACON_REQ; 00228 buf->mac_header_length_with_security = 7; 00229 buf->mac_payload = &buf->mac_command_id; 00230 buf->mac_payload_length = 1; 00231 buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; 00232 buf->fcf_dsn.DstPanPresents = true; 00233 buf->fcf_dsn.SrcPanPresents = false; 00234 00235 mcps_sap_pd_req_queue_write(rf_ptr, buf); 00236 return 1; 00237 } 00238 return 0; 00239 } 00240 00241 static void mac_mlme_scan_init(uint8_t channel, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00242 { 00243 mac_mlme_calc_scan_duration(rf_mac_setup, channel); 00244 00245 switch (rf_mac_setup->scan_type) { 00246 /* ED Scan */ 00247 case MAC_ED_SCAN_TYPE: 00248 //tr_debug("Energy Scan"); 00249 rf_mac_setup->max_ED = 0; 00250 mac_mlme_energy_scan_start(rf_mac_setup, channel); 00251 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_ED_ANALYZE; 00252 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 96); 00253 break; 00254 case MAC_PASSIVE_SCAN: 00255 case MAC_ACTIVE_SCAN: /*Active*/ 00256 tr_debug("Scan channel %u", channel); 00257 rf_mac_setup->mac_channel = channel; 00258 rf_mac_setup->macCapRxOnIdle = true; 00259 mac_mlme_start_request(rf_mac_setup); 00260 if (rf_mac_setup->scan_type == MAC_ACTIVE_SCAN) { 00261 mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request; 00262 /* If there is active data request, it must be Beacon request which were failed to send on previous channel. 00263 * Do not push new Beacon request to queue as the MAC will try to send the current active data request anyway. 00264 */ 00265 if (!active_buf || (active_buf && active_buf->fcf_dsn.frametype != FC_CMD_FRAME)) { 00266 mac_mlme_beacon_req_tx(rf_mac_setup); 00267 } 00268 } 00269 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00270 rf_mac_setup->mlme_tick_count = rf_mac_setup->mlme_ED_counter; 00271 //tr_debug("mlme_tick_count: %x", rf_mac_setup->mlme_tick_count); 00272 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 300); 00273 break; 00274 case MAC_ORPHAN_SCAN: /*Orphan*/ 00275 break; 00276 } 00277 } 00278 00279 static void mac_mlme_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00280 { 00281 uint8_t channel; 00282 00283 channel = (uint8_t) mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true); 00284 mac_mlme_scan_init(channel, rf_mac_setup); 00285 } 00286 00287 static bool mac_channel_list_validate(const channel_list_s *list, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00288 { 00289 if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_15_4_2_4GHZ_TYPE && 00290 list->channel_page == 0) { 00291 //Accept only Channels channels 11-26 00292 if (list->channel_mask[0] & 0x7fff800) { 00293 return true; 00294 } 00295 return false; 00296 } else if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_15_4_SUBGHZ_TYPE && 00297 (list->channel_page == 0 || list->channel_page == 1 || list->channel_page == 2)) { 00298 if (list->channel_mask[0] & 0x000007ff) { 00299 return true; 00300 } 00301 00302 return false; 00303 } else { 00304 for (int i = 0; i < 8; i++) { 00305 if (list->channel_mask[i]) { 00306 return true; 00307 } 00308 } 00309 } 00310 00311 return false; 00312 } 00313 00314 static int mac_mlme_generate_scan_confirmation(mlme_scan_conf_t *conf, const mlme_scan_t *msg, uint8_t status) 00315 { 00316 memset(conf, 0, sizeof(mlme_scan_conf_t)); 00317 conf->status = status; 00318 if (!msg) { 00319 return -1; 00320 } 00321 conf->ScanType = msg->ScanType; 00322 conf->ChannelPage = msg->ChannelPage; 00323 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00324 /*If the scan is successful, this value will be modified properly in mlme_analyze_next_channel() 00325 and assigned in mlme_scan_operation()*/ 00326 conf->UnscannedChannels.channel_mask[0] = msg->ScanChannels.channel_mask[0]; 00327 } else if (msg->ScanType == MAC_ED_SCAN_TYPE) { 00328 conf->ED_values = ns_dyn_mem_temporary_alloc(MLME_MAC_RES_SIZE_MAX); 00329 if (!conf->ED_values) { 00330 tr_debug("Could not allocate memory for ED values"); 00331 conf->status = MLME_SUCCESS; 00332 return -2; 00333 } 00334 memset(conf->ED_values, 0, MLME_MAC_RES_SIZE_MAX); 00335 } 00336 return 0; 00337 } 00338 00339 void mac_mlme_scan_request(const mlme_scan_t *msg, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00340 { 00341 if (rf_mac_setup->mac_mlme_scan_resp) { 00342 mlme_scan_conf_t conf; 00343 mac_mlme_generate_scan_confirmation(&conf, msg, MLME_SCAN_IN_PROGRESS); 00344 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00345 ns_dyn_mem_free(conf.ED_values); 00346 return; 00347 } 00348 00349 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 00350 if (!resp) { 00351 mlme_scan_conf_t conf; 00352 tr_error("Mac Scan request fail, no memory"); 00353 mac_mlme_generate_scan_confirmation(&conf, NULL, MLME_SUCCESS); 00354 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00355 ns_dyn_mem_free(conf.ED_values); 00356 return; 00357 } 00358 00359 rf_mac_setup->mac_mlme_scan_resp = resp; 00360 //Validate channel list 00361 tr_debug("chan page %u, mask %"PRIx32, msg->ScanChannels.channel_page, msg->ScanChannels.channel_mask[0]); 00362 if (!mac_channel_list_validate(&msg->ScanChannels, rf_mac_setup)) { 00363 tr_debug("Unsupported channel list"); 00364 mac_mlme_generate_scan_confirmation(resp, msg, MLME_INVALID_PARAMETER); 00365 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00366 return; 00367 } 00368 00369 if (mac_mlme_generate_scan_confirmation(resp, msg, MLME_SUCCESS) != 0) { 00370 return; 00371 } 00372 00373 tr_debug("MAC: Start MLME scan"); 00374 00375 if (mac_mlme_rf_disable(rf_mac_setup) == 0) { 00376 rf_mac_setup->macCapRxOnIdle = false; 00377 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00378 rf_mac_setup->macUpState = true; 00379 } 00380 } else { 00381 tr_error("Failed to disable RF"); 00382 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00383 return; 00384 } 00385 00386 rf_mac_setup->scan_type = msg->ScanType; 00387 rf_mac_setup->scan_duration = msg->ScanDuration; 00388 rf_mac_setup->mac_channel_list = msg->ScanChannels; 00389 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00390 rf_mac_setup->scan_active = true; 00391 mac_mlme_scan_start(rf_mac_setup); 00392 } 00393 00394 int8_t mac_mlme_start_req(const mlme_start_t *s, struct protocol_interface_rf_mac_setup *rf_mac_setup) 00395 { 00396 if (!s || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 00397 return -1; 00398 } 00399 00400 tr_debug("MAC: Start network %u channel %x panid", s->LogicalChannel, s->PANId); 00401 mac_mlme_set_panid(rf_mac_setup, s->PANId); 00402 00403 // Synchronize FHSS 00404 if (rf_mac_setup->fhss_api) { 00405 rf_mac_setup->mac_channel = rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_SYNCHRONIZED, s->PANId); 00406 } else { 00407 rf_mac_setup->mac_channel = s->LogicalChannel; 00408 } 00409 00410 mac_mlme_start_request(rf_mac_setup); 00411 if (s->PANCoordinator) { 00412 //tr_debug("Cordinator"); 00413 rf_mac_setup->macCapCordinator = true; 00414 rf_mac_setup->macCapRxOnIdle = true; 00415 } else { 00416 rf_mac_setup->macCapCordinator = false; 00417 } 00418 00419 if (s->BatteryLifeExtension) { 00420 rf_mac_setup->macCapBatteryPowered = true; 00421 } else { 00422 rf_mac_setup->macCapBatteryPowered = false; 00423 } 00424 mlme_start_conf_t conf; 00425 conf.status = MLME_SUCCESS; 00426 mac_mlme_start_confirm_handler(rf_mac_setup, &conf); 00427 return 0; 00428 } 00429 00430 int8_t mac_mlme_reset(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_reset_t *reset) 00431 { 00432 if (!reset || !rf_mac_setup) { 00433 return -1; 00434 } 00435 00436 // Stop FHSS 00437 if (rf_mac_setup->fhss_api) { 00438 rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_UNSYNCHRONIZED, 0); 00439 } 00440 00441 mac_mlme_timers_disable(rf_mac_setup); 00442 mac_mlme_mac_radio_disabled(rf_mac_setup); 00443 mac_mlme_set_active_state(rf_mac_setup, false); 00444 mac_mlme_free_scan_temporary_data(rf_mac_setup); 00445 mac_mcps_buffer_queue_free(rf_mac_setup); 00446 rf_mac_setup->macProminousMode = false; 00447 rf_mac_setup->macWaitingData = false; 00448 rf_mac_setup->macDataPollReq = false; 00449 rf_mac_setup->macRxDataAtPoll = false; 00450 //Clean MAC 00451 if (reset->SetDefaultPIB) { 00452 tr_debug("RESET MAC PIB"); 00453 rf_mac_setup->mac_short_address = 0xffff; 00454 rf_mac_setup->pan_id = 0xffff; 00455 rf_mac_setup->macCapRxOnIdle = true; 00456 rf_mac_setup->mac_security_enabled = false; 00457 rf_mac_setup->macCapCordinator = false; 00458 rf_mac_setup->mac_mlme_retry_max = MAC_DEFAULT_MAX_FRAME_RETRIES; 00459 } 00460 00461 return 0; 00462 } 00463 00464 00465 static int8_t mac_mlme_boolean_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, bool value) 00466 { 00467 switch (attribute) { 00468 case macSecurityEnabled: 00469 rf_mac_setup->mac_security_enabled = value; 00470 break; 00471 00472 case macRxOnWhenIdle: 00473 rf_mac_setup->macCapRxOnIdle = value; 00474 break; 00475 00476 case macPromiscuousMode: 00477 rf_mac_setup->macProminousMode = value; 00478 break; 00479 00480 case macGTSPermit: 00481 rf_mac_setup->macGTSPermit = value; 00482 break; 00483 00484 case macAssociationPermit: 00485 rf_mac_setup->macCapAssocationPermit = value; 00486 break; 00487 case macThreadForceLongAddressForBeacon: 00488 rf_mac_setup->beaconSrcAddressModeLong = value; 00489 break; 00490 00491 case macAssociatedPANCoord: 00492 00493 break; 00494 00495 case macTimestampSupported: 00496 00497 break; 00498 00499 case macBattLifeExt: 00500 00501 break; 00502 00503 case macAutoRequest: 00504 00505 break; 00506 00507 case macLoadBalancingAcceptAnyBeacon: 00508 rf_mac_setup->macAcceptAnyBeacon = value; 00509 if (rf_mac_setup->dev_driver->phy_driver->extension) { 00510 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_ACCEPT_ANY_BEACON, (uint8_t *)&value); 00511 } 00512 break; 00513 case macAcceptByPassUnknowDevice: 00514 rf_mac_setup->mac_security_bypass_unknow_device = value; 00515 break; 00516 00517 default: 00518 return -1; 00519 } 00520 return 0; 00521 } 00522 00523 static int8_t mac_mlme_16bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint16_t value) 00524 { 00525 switch (attribute) { 00526 case macCoordShortAddress: 00527 rf_mac_setup->coord_short_address = value; 00528 break; 00529 case macPANId: 00530 mac_mlme_set_panid(rf_mac_setup, value); 00531 break; 00532 00533 case macShortAddress: 00534 mac_mlme_set_mac16(rf_mac_setup, value); 00535 break; 00536 00537 case macSyncSymbolOffset: 00538 //TODO: change this to return real error 00539 //This is read only 00540 break; 00541 00542 case macTransactionPersistenceTime: 00543 //TODO: check this also 00544 break; 00545 case macDeviceDescriptionPanIDUpdate: 00546 mac_sec_mib_device_description_pan_update(rf_mac_setup, value); 00547 break; 00548 00549 default: 00550 return -1; 00551 } 00552 return 0; 00553 } 00554 00555 static int8_t mac_mlme_8bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint8_t value) 00556 { 00557 switch (attribute) { 00558 case phyCurrentChannel: 00559 mac_mlme_rf_channel_set(rf_mac_setup, value); 00560 break; 00561 case macBeaconPayloadLength: 00562 if (rf_mac_setup->max_beacon_payload_length < value) { 00563 return -1; 00564 } 00565 00566 rf_mac_setup->mac_beacon_payload_size = value; 00567 break; 00568 case macAutoRequestKeyIndex: 00569 rf_mac_setup->mac_auto_request.KeyIndex = value; 00570 break; 00571 00572 case macAutoRequestKeyIdMode: 00573 rf_mac_setup->mac_auto_request.KeyIdMode = value; 00574 break; 00575 00576 case macAutoRequestSecurityLevel: 00577 rf_mac_setup->mac_auto_request.SecurityLevel = value; 00578 break; 00579 case macMaxFrameRetries: 00580 if (value > 7) { 00581 return -1; 00582 } 00583 rf_mac_setup->mac_mlme_retry_max = value; 00584 break; 00585 00586 case macMinBE: 00587 if (value < rf_mac_setup->macMaxBE) { 00588 rf_mac_setup->macMinBE = value; 00589 } 00590 break; 00591 00592 case macMaxBE: 00593 if (value > 8 || value < 3) { 00594 return -1; 00595 } 00596 rf_mac_setup->macMaxBE = value; 00597 break; 00598 00599 case macMaxCSMABackoffs: 00600 if (value > 8) { 00601 return -1; 00602 } 00603 rf_mac_setup->macMaxCSMABackoffs = value; 00604 break; 00605 00606 default: 00607 return -1; 00608 } 00609 return 0; 00610 } 00611 00612 static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint8_t index, uint32_t value) 00613 { 00614 00615 switch (attribute) { 00616 case macFrameCounter: 00617 if (rf_mac_setup->secFrameCounterPerKey) { 00618 mlme_key_descriptor_t *key_desc = mac_sec_key_description_get_by_attribute(rf_mac_setup, index); 00619 if (!key_desc) { 00620 return -1; 00621 } 00622 mac_sec_mib_key_outgoing_frame_counter_set(rf_mac_setup, key_desc, value); 00623 } else { 00624 mac_sec_mib_key_outgoing_frame_counter_set(rf_mac_setup, NULL, value); 00625 } 00626 00627 break; 00628 00629 default: 00630 return -1; 00631 } 00632 return 0; 00633 } 00634 00635 void mac_extended_mac_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *mac64) 00636 { 00637 if (!mac64 || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 00638 return; 00639 } 00640 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00641 memcpy(rf_mac_setup->mac64, mac64, 8); //This should be random 00642 if (dev_driver->address_write) { 00643 dev_driver->address_write(PHY_MAC_64BIT, rf_mac_setup->mac64); 00644 } 00645 } 00646 00647 static uint32_t mac_calc_ack_wait_duration(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t symbols) 00648 { 00649 uint32_t AckWaitDuration = 0; 00650 if (rf_mac_setup->rf_csma_extension_supported) { 00651 AckWaitDuration = symbols * rf_mac_setup->symbol_time_us; 00652 } 00653 return AckWaitDuration; 00654 } 00655 00656 static int8_t mac_mlme_set_ack_wait_duration(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00657 { 00658 uint16_t symbols = common_read_16_bit_inverse((uint8_t *)set_req->value_pointer); 00659 uint32_t ack_wait_time_us = mac_calc_ack_wait_duration(rf_mac_setup, symbols); 00660 if (ack_wait_time_us < 50) { 00661 return -1; 00662 } 00663 // MAC timer uses 50us resolution 00664 rf_mac_setup->mac_ack_wait_duration = ack_wait_time_us / 50; 00665 tr_debug("Set macAckWaitDuration: %uus", rf_mac_setup->mac_ack_wait_duration * 50); 00666 00667 return 0; 00668 } 00669 00670 static int8_t mac_mlme_device_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00671 { 00672 00673 if (set_req->value_size != sizeof(mlme_device_descriptor_t)) { 00674 return -1; 00675 } 00676 00677 return mac_sec_mib_device_description_set(set_req->attr_index, (mlme_device_descriptor_t *) set_req->value_pointer, rf_mac_setup); 00678 } 00679 00680 static int8_t mac_mlme_key_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00681 { 00682 if (set_req->value_size != sizeof(mlme_key_descriptor_entry_t)) { 00683 return -1; 00684 } 00685 00686 return mac_sec_mib_key_description_set(set_req->attr_index, (mlme_key_descriptor_entry_t *) set_req->value_pointer, rf_mac_setup); 00687 } 00688 00689 static int8_t mac_mlme_default_key_source_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00690 { 00691 if (set_req->value_size != 8) { 00692 return -1; 00693 } 00694 if (set_req->attr == macDefaultKeySource) { 00695 memcpy(rf_mac_setup->mac_default_key_source, (uint8_t *)set_req->value_pointer, 8); 00696 } else { 00697 memcpy(rf_mac_setup->mac_auto_request.Keysource, (uint8_t *)set_req->value_pointer, 8); 00698 } 00699 return 0; 00700 } 00701 00702 static int8_t mac_mlme_beacon_payload_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00703 { 00704 if (set_req->value_size > rf_mac_setup->max_beacon_payload_length) { 00705 return -1; 00706 } 00707 00708 memcpy(rf_mac_setup->mac_beacon_payload, set_req->value_pointer, set_req->value_size); 00709 memset(rf_mac_setup->mac_beacon_payload + set_req->value_size, 0, rf_mac_setup->max_beacon_payload_length - set_req->value_size); 00710 00711 return 0; 00712 } 00713 00714 static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00715 { 00716 if (set_req->value_size == 1) { 00717 const bool *pbool = set_req->value_pointer; 00718 //Check first boolean 00719 if (mac_mlme_boolean_set(rf_mac_setup, set_req->attr, *pbool) == 0) { 00720 return 0; 00721 } 00722 const uint8_t *pu8 = set_req->value_pointer; 00723 return mac_mlme_8bit_set(rf_mac_setup, set_req->attr, *pu8); 00724 00725 } else if (set_req->value_size == 2) { 00726 const uint16_t *pu16 = set_req->value_pointer; 00727 return mac_mlme_16bit_set(rf_mac_setup, set_req->attr, *pu16); 00728 } else if (set_req->value_size == 4) { 00729 const uint32_t *pu32 = set_req->value_pointer; 00730 return mac_mlme_32bit_set(rf_mac_setup, set_req->attr, set_req->attr_index, *pu32); 00731 } 00732 return -1; 00733 } 00734 00735 static int8_t mac_mlme_set_multi_csma_parameters(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00736 { 00737 mlme_multi_csma_ca_param_t multi_csma_params; 00738 memcpy(&multi_csma_params, set_req->value_pointer, sizeof(mlme_multi_csma_ca_param_t)); 00739 rf_mac_setup->multi_cca_interval = multi_csma_params.multi_cca_interval; 00740 rf_mac_setup->number_of_csma_ca_periods = multi_csma_params.number_of_csma_ca_periods; 00741 tr_debug("Multi CSMA-CA, interval: %u, periods %u", rf_mac_setup->multi_cca_interval, rf_mac_setup->number_of_csma_ca_periods); 00742 return 0; 00743 } 00744 00745 int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00746 { 00747 if (!set_req || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 00748 return -1; 00749 } 00750 uint8_t *pu8 = NULL; 00751 switch (set_req->attr) { 00752 case macAckWaitDuration: 00753 return mac_mlme_set_ack_wait_duration(rf_mac_setup, set_req); 00754 case macDeviceTable: 00755 return mac_mlme_device_description_set(rf_mac_setup, set_req); 00756 case macKeyTable: 00757 return mac_mlme_key_description_set(rf_mac_setup, set_req); 00758 case macDefaultKeySource: 00759 case macAutoRequestKeySource: 00760 return mac_mlme_default_key_source_set(rf_mac_setup, set_req); 00761 case macBeaconPayload: 00762 return mac_mlme_beacon_payload_set(rf_mac_setup, set_req); 00763 case macLoadBalancingBeaconTx: 00764 return mac_mlme_beacon_tx(rf_mac_setup); 00765 case macCoordExtendedAddress: 00766 if (set_req->value_size == 8) { 00767 memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8); 00768 } 00769 return 0; 00770 case macTXPower: 00771 pu8 = (uint8_t *) set_req->value_pointer; 00772 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_TX_POWER, pu8); 00773 tr_debug("Set TX output power to %u%%", *pu8); 00774 return 0; 00775 case macCCAThreshold: 00776 pu8 = (uint8_t *) set_req->value_pointer; 00777 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CCA_THRESHOLD, pu8); 00778 tr_debug("Set CCA threshold to %u%%", *pu8); 00779 return 0; 00780 case macMultiCSMAParameters: 00781 return mac_mlme_set_multi_csma_parameters(rf_mac_setup, set_req); 00782 case macRfConfiguration: 00783 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_RF_CONFIGURATION, (uint8_t *) set_req->value_pointer); 00784 mac_mlme_set_symbol_rate(rf_mac_setup); 00785 phy_rf_channel_configuration_s *config_params = (phy_rf_channel_configuration_s *)set_req->value_pointer; 00786 tr_info("RF config update:"); 00787 tr_info("Frequency(ch0): %"PRIu32"Hz", config_params->channel_0_center_frequency); 00788 tr_info("Channel spacing: %"PRIu32"Hz", config_params->channel_spacing); 00789 tr_info("Datarate: %"PRIu32"bps", config_params->datarate); 00790 tr_info("Number of channels: %u", config_params->number_of_channels); 00791 tr_info("Modulation: %u", config_params->modulation); 00792 tr_info("Modulation index: %u", config_params->modulation_index); 00793 return 0; 00794 default: 00795 return mac_mlme_handle_set_values(rf_mac_setup, set_req); 00796 } 00797 } 00798 00799 int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req) 00800 { 00801 if (!get_req || !rf_mac_setup) { 00802 return -1; 00803 } 00804 00805 switch (get_req->attr) { 00806 case macDeviceTable: 00807 get_req->value_pointer = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, get_req->attr_index); 00808 if (get_req->value_pointer) { 00809 get_req->value_size = sizeof(mlme_device_descriptor_t); 00810 } else { 00811 get_req->status = MLME_INVALID_INDEX; 00812 } 00813 break; 00814 00815 case macMaxFrameRetries: 00816 get_req->value_pointer = &rf_mac_setup->mac_mlme_retry_max; 00817 get_req->value_size = 1; 00818 break; 00819 00820 case macFrameCounter: 00821 if (rf_mac_setup->secFrameCounterPerKey) { 00822 mlme_key_descriptor_t *key_desc = mac_sec_key_description_get_by_attribute(rf_mac_setup, get_req->attr_index); 00823 if (!key_desc) { 00824 return -1; 00825 } 00826 get_req->value_pointer = &key_desc->KeyFrameCounter; 00827 } else { 00828 get_req->value_pointer = &rf_mac_setup->security_frame_counter; 00829 } 00830 00831 get_req->value_size = 4; 00832 break; 00833 00834 default: 00835 get_req->status = MLME_UNSUPPORTED_ATTRIBUTE; 00836 break; 00837 00838 } 00839 return 0; 00840 } 00841 00842 static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00843 { 00844 uint16_t channel; 00845 mlme_scan_conf_t *resp = rf_mac_setup->mac_mlme_scan_resp; 00846 00847 if (rf_mac_setup->scan_type == MAC_ED_SCAN_TYPE) { 00848 resp->ED_values[resp->ResultListSize] = rf_mac_setup->max_ED; 00849 resp->ResultListSize++; 00850 } 00851 00852 channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list, true); 00853 if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { 00854 resp->status = MLME_SUCCESS; 00855 platform_enter_critical(); 00856 mac_mlme_mac_radio_disabled(rf_mac_setup); 00857 if (resp->ResultListSize == 0 && rf_mac_setup->scan_type == MAC_ACTIVE_SCAN) { 00858 resp->status = MLME_NO_BEACON; 00859 } else if (resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { 00860 resp->status = MLME_LIMIT_REACHED; 00861 } 00862 resp->UnscannedChannels.channel_mask[0] = rf_mac_setup->mac_channel_list.channel_mask[0]; 00863 platform_exit_critical(); 00864 //Scan Confirmation 00865 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00866 rf_mac_setup->scan_active = false; 00867 } else { 00868 mac_mlme_scan_init((uint8_t) channel, rf_mac_setup); 00869 } 00870 } 00871 00872 void mac_frame_src_address_set_from_interface(uint8_t SrcAddrMode, protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t *addressPtr) 00873 { 00874 if (!rf_ptr) { 00875 return; 00876 } 00877 if (SrcAddrMode == MAC_ADDR_MODE_16_BIT) { 00878 mac_mlme_write_mac16(rf_ptr, addressPtr); 00879 } else if (SrcAddrMode == MAC_ADDR_MODE_64_BIT) { 00880 mac_mlme_write_mac64(rf_ptr, addressPtr); 00881 } 00882 } 00883 00884 void mac_mlme_active_scan_response_timer_start(void *interface) 00885 { 00886 if (interface) { 00887 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s *)interface; 00888 if (rf_mac_setup) { 00889 if (rf_mac_setup->mac_mlme_event == ARM_NWK_MAC_MLME_SCAN) { 00890 eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id); 00891 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00892 rf_mac_setup->mlme_tick_count = rf_mac_setup->mlme_ED_counter; 00893 00894 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 300); 00895 } 00896 } 00897 } 00898 } 00899 00900 static void mac_mlme_timers_disable(protocol_interface_rf_mac_setup_s *rf_ptr) 00901 { 00902 platform_enter_critical(); 00903 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00904 eventOS_callback_timer_stop(rf_ptr->mlme_timer_id); 00905 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00906 } 00907 timer_mac_stop(rf_ptr); 00908 platform_exit_critical(); 00909 } 00910 00911 void mac_mlme_event_cb(void *mac_ptr) 00912 { 00913 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s *) mac_ptr; 00914 if (!rf_mac_setup) { 00915 return; 00916 } 00917 arm_nwk_mlme_event_type_e event_type; 00918 event_type = rf_mac_setup->mac_mlme_event; 00919 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00920 switch (event_type) { 00921 case ARM_NWK_MAC_MLME_SCAN: 00922 mlme_scan_operation(rf_mac_setup); 00923 break; 00924 00925 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL: 00926 tr_debug("Data poll data wait TO"); 00927 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_NO_DATA); 00928 break; 00929 00930 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA: 00931 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_SUCCESS); 00932 break; 00933 00934 default: 00935 break; 00936 } 00937 } 00938 00939 static void mac_mcps_timer_cb(int8_t timer_id, uint16_t slots) 00940 { 00941 00942 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_MCPS_TIMER); 00943 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00944 return; 00945 } 00946 rf_ptr->mac_mcps_timer_event.event_data = slots; 00947 eventOS_event_send(&rf_ptr->mac_mcps_timer_event); 00948 00949 } 00950 00951 00952 static void mac_mlme_timer_cb(int8_t timer_id, uint16_t slots) 00953 { 00954 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_NWK_MLME_TIMER); 00955 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00956 return; 00957 } 00958 00959 if (rf_ptr->mlme_tick_count == 0) { 00960 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00961 if (rf_ptr->mac_mlme_event == ARM_NWK_MAC_MLME_ED_ANALYZE) { 00962 if (rf_ptr->mlme_ED_counter > 1) { 00963 uint8_t ed = 0; 00964 phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; 00965 rf_ptr->mlme_ED_counter--; 00966 if (dev_driver->extension) { 00967 dev_driver->extension(PHY_EXTENSION_READ_CHANNEL_ENERGY, &ed); 00968 } 00969 if (ed > rf_ptr->max_ED) { 00970 rf_ptr->max_ED = ed; 00971 } 00972 00973 /*96 * 50us = 4.8ms*/ 00974 rf_ptr->mlme_tick_count = 0; 00975 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_ED_ANALYZE; 00976 eventOS_callback_timer_start(timer_id, slots); 00977 } else { 00978 mac_mlme_rf_disable(rf_ptr); 00979 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00980 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER, rf_ptr, false); 00981 } 00982 } else { 00983 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER, rf_ptr, true); 00984 } 00985 } 00986 } else { 00987 rf_ptr->mlme_tick_count--; 00988 eventOS_callback_timer_start(timer_id, slots); 00989 } 00990 } 00991 00992 static void mac_mlme_free_scan_temporary_data(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00993 { 00994 rf_mac_setup->scan_active = false; 00995 if (rf_mac_setup->mac_mlme_scan_resp) { 00996 mlme_scan_conf_t *r = rf_mac_setup->mac_mlme_scan_resp; 00997 if (r->ED_values) { 00998 ns_dyn_mem_free(r->ED_values); 00999 r->ED_values = NULL; 01000 } 01001 uint8_t i = 0; 01002 while (i < r->ResultListSize) { 01003 if (r->PAN_values[i]) { 01004 ns_dyn_mem_free(r->PAN_values[i]); 01005 } 01006 i++; 01007 } 01008 ns_dyn_mem_free(rf_mac_setup->mac_mlme_scan_resp); 01009 rf_mac_setup->mac_mlme_scan_resp = NULL; 01010 } 01011 } 01012 01013 void mac_mlme_set_active_state(protocol_interface_rf_mac_setup_s *entry, bool new_state) 01014 { 01015 if (entry) { 01016 entry->macUpState = new_state; 01017 } 01018 } 01019 01020 void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_mac) 01021 { 01022 if (rf_mac) { 01023 if (rf_mac->dev_driver) { 01024 rf_mac->dev_driver->phy_sap_identifier = NULL; 01025 rf_mac->dev_driver->phy_sap_upper_cb = NULL; 01026 } 01027 01028 eventOS_callback_timer_unregister(rf_mac->mlme_timer_id); 01029 eventOS_callback_timer_unregister(rf_mac->mac_timer_id); 01030 eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer); 01031 01032 ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf); 01033 ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.enhanced_ack_buf); 01034 ns_dyn_mem_free(rf_mac->mac_beacon_payload); 01035 01036 mac_sec_mib_deinit(rf_mac); 01037 ns_dyn_mem_free(rf_mac); 01038 } 01039 } 01040 01041 static uint8_t mac_backoff_ticks_calc(phy_device_driver_s *phy_driver) 01042 { 01043 //Calculate 20 symbol time which is typically 10 bytes 01044 const phy_device_channel_page_s *phy_channel_pages = phy_driver->phy_channel_pages; 01045 uint32_t datarate = dev_get_phy_datarate(phy_driver, phy_channel_pages->channel_page); 01046 if (datarate == 0) { 01047 datarate = 250000; 01048 } 01049 //How many 10us ticks backoff period is, assuming 4 bits per symbol (O-QPSK) 01050 unsigned int ticks = (2000000 / (datarate / 4)); 01051 if (ticks > 255) { 01052 ticks = 255; 01053 tr_warn("Backoff period too slow"); 01054 } 01055 return (uint8_t) ticks; 01056 } 01057 01058 static int mac_mlme_set_symbol_rate(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01059 { 01060 if (rf_mac_setup->rf_csma_extension_supported) { 01061 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, (uint8_t *) &rf_mac_setup->symbol_rate); 01062 rf_mac_setup->symbol_time_us = 1000000 / rf_mac_setup->symbol_rate; 01063 tr_debug("SW-MAC driver support rf extension %"PRIu32" symbol/seconds %"PRIu32" us symbol time length", rf_mac_setup->symbol_rate, rf_mac_setup->symbol_time_us); 01064 return 0; 01065 } 01066 return -1; 01067 } 01068 01069 protocol_interface_rf_mac_setup_s *mac_mlme_data_base_allocate(uint8_t *mac64, arm_device_driver_list_s *dev_driver, mac_description_storage_size_t *storage_sizes) 01070 { 01071 uint16_t total_length = 0; 01072 //allocate security 01073 if (!dev_driver || !mac64 || !dev_driver->phy_driver || !storage_sizes) { 01074 return NULL; 01075 } 01076 01077 protocol_interface_rf_mac_setup_s *entry = ns_dyn_mem_alloc(sizeof(protocol_interface_rf_mac_setup_s)); 01078 if (!entry) { 01079 return NULL; 01080 } 01081 //Init everything for 0, NULL or false 01082 memset(entry, 0, sizeof(protocol_interface_rf_mac_setup_s)); 01083 entry->ifs_timer_id = -1; 01084 entry->cca_timer_id = -1; 01085 entry->mlme_timer_id = -1; 01086 entry->mac_timer_id = -1; 01087 entry->bc_timer_id = -1; 01088 entry->mac_interface_id = -1; 01089 entry->dev_driver = dev_driver; 01090 entry->aUnitBackoffPeriod = 20; //This can be different in some Platform 20 comes from 12-symbol turnaround and 8 symbol CCA read 01091 entry->number_of_csma_ca_periods = MAC_DEFAULT_NUMBER_OF_CSMA_PERIODS; 01092 entry->multi_cca_interval = MAC_DEFAULT_CSMA_MULTI_CCA_INTERVAL; 01093 01094 if (mac_sec_mib_init(entry, storage_sizes) != 0) { 01095 mac_mlme_data_base_deallocate(entry); 01096 return NULL; 01097 } 01098 01099 if (!dev_driver->phy_driver->phy_MTU) { 01100 mac_mlme_data_base_deallocate(entry); 01101 return NULL; 01102 } 01103 01104 //Allocate tx buffer by given MTU + header + tail 01105 total_length = dev_driver->phy_driver->phy_MTU; 01106 total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length); 01107 entry->dev_driver_tx_buffer.buf = ns_dyn_mem_alloc(total_length); 01108 if (!entry->dev_driver_tx_buffer.buf) { 01109 mac_mlme_data_base_deallocate(entry); 01110 return NULL; 01111 } 01112 01113 //allocate Beacon Payload buffer 01114 entry->max_beacon_payload_length = dev_driver->phy_driver->phy_MTU - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD; 01115 entry->mac_beacon_payload = ns_dyn_mem_alloc(entry->max_beacon_payload_length); 01116 if (!entry->mac_beacon_payload) { 01117 mac_mlme_data_base_deallocate(entry); 01118 return NULL; 01119 } 01120 01121 entry->mac_tasklet_id = mac_mcps_sap_tasklet_init(); 01122 if (entry->mac_tasklet_id < 0) { 01123 mac_mlme_data_base_deallocate(entry); 01124 return NULL; 01125 } 01126 01127 entry->mlme_timer_id = eventOS_callback_timer_register(mac_mlme_timer_cb); 01128 entry->mac_timer_id = eventOS_callback_timer_register(timer_mac_interrupt); 01129 entry->mac_mcps_timer = eventOS_callback_timer_register(mac_mcps_timer_cb); 01130 if (entry->mlme_timer_id == -1 || entry->mac_timer_id == -1 || entry->mac_mcps_timer == -1) { 01131 mac_mlme_data_base_deallocate(entry); 01132 return NULL; 01133 } 01134 entry->macCapRxOnIdle = true; 01135 entry->macCapSecrutityCapability = true; 01136 entry->pan_id = entry->mac_short_address = 0xffff; 01137 mac_extended_mac_set(entry, mac64); 01138 entry->mac_ack_wait_duration = MAC_ACK_WAIT_DURATION; 01139 entry->mac_mlme_retry_max = MAC_DEFAULT_MAX_FRAME_RETRIES; 01140 memset(entry->mac_default_key_source, 0xff, 8); 01141 memset(entry->mac_auto_request.Keysource, 0xff, 8); 01142 memset(entry->mac_beacon_payload, 0, entry->max_beacon_payload_length); 01143 entry->mac_auto_request.SecurityLevel = 6; 01144 entry->mac_auto_request.KeyIndex = 0xff; 01145 mac_pd_sap_rf_low_level_function_set(entry, entry->dev_driver); 01146 entry->mac_sequence = randLIB_get_8bit(); 01147 entry->mac_bea_sequence = randLIB_get_8bit(); 01148 entry->fhss_api = NULL; 01149 entry->macMinBE = 3; 01150 entry->macMaxBE = 5; 01151 entry->macMaxCSMABackoffs = MAC_CCA_MAX; 01152 entry->mac_mcps_timer_event.priority = ARM_LIB_LOW_PRIORITY_EVENT; 01153 entry->mac_mcps_timer_event.event_type = MAC_MCPS_INDIRECT_TIMER_CB; 01154 entry->mac_mcps_timer_event.data_ptr = entry; 01155 entry->mac_mcps_timer_event.receiver = entry->mac_tasklet_id; 01156 entry->mac_mcps_timer_event.sender = 0; 01157 entry->mac_mcps_timer_event.event_id = 0; 01158 bool rf_support = false; 01159 dev_driver->phy_driver->extension(PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, (uint8_t *)&rf_support); 01160 entry->rf_csma_extension_supported = rf_support; 01161 dev_driver->phy_driver->extension(PHY_EXTENSION_FILTERING_SUPPORT, (uint8_t *)&entry->mac_frame_filters); 01162 if (entry->mac_frame_filters & (1 << MAC_FRAME_VERSION_2)) { 01163 tr_debug("PHY supports 802.15.4-2015 frame filtering"); 01164 } 01165 mac_mlme_set_symbol_rate(entry); 01166 01167 //How many 10us ticks backoff period is for waiting 20symbols which is typically 10 bytes time 01168 entry->backoff_period_in_10us = mac_backoff_ticks_calc(dev_driver->phy_driver); 01169 return entry; 01170 } 01171 01172 uint8_t mac_mlme_set_new_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01173 { 01174 uint8_t ret_val = 0; 01175 01176 if (rf_setup) { 01177 rf_setup->mac_sequence++; 01178 ret_val = rf_setup->mac_sequence; 01179 } 01180 return ret_val; 01181 } 01182 01183 uint8_t mac_mlme_set_new_beacon_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01184 { 01185 uint8_t ret_val = 0; 01186 01187 if (rf_setup) { 01188 rf_setup->mac_bea_sequence++; 01189 ret_val = rf_setup->mac_bea_sequence; 01190 } 01191 return ret_val; 01192 } 01193 01194 static int8_t mac_mlme_set_panid(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t pan_id) 01195 { 01196 phy_device_driver_s *dev_driver = rf_setup->dev_driver->phy_driver; 01197 if (!dev_driver->address_write) { 01198 if (dev_driver->link_type == PHY_LINK_TUN) { 01199 rf_setup->pan_id = pan_id; 01200 return 0; 01201 } 01202 return -1; 01203 } 01204 01205 uint8_t temp_8[2]; 01206 rf_setup->pan_id = pan_id; 01207 common_write_16_bit(pan_id, temp_8); 01208 01209 return dev_driver->address_write(PHY_MAC_PANID, temp_8); 01210 } 01211 01212 static void mac_mle_write_mac16_to_phy(phy_device_driver_s *dev_driver, uint16_t mac16) 01213 { 01214 uint8_t temp[2]; 01215 common_write_16_bit(mac16, temp); 01216 if (dev_driver->address_write) { 01217 dev_driver->address_write(PHY_MAC_16BIT, temp); 01218 } 01219 } 01220 01221 static int8_t mac_mlme_set_mac16(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t mac16) 01222 { 01223 int8_t ret_val = -1; 01224 if (rf_setup) { 01225 01226 rf_setup->mac_short_address = mac16; 01227 //SET RF 16-bit 01228 if (mac16 > 0xfffd) { 01229 rf_setup->shortAdressValid = false; 01230 } else { 01231 rf_setup->shortAdressValid = true; 01232 } 01233 mac_mle_write_mac16_to_phy(rf_setup->dev_driver->phy_driver, mac16); 01234 ret_val = 0; 01235 } 01236 return ret_val; 01237 } 01238 01239 static void mac_mlme_write_mac64(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01240 { 01241 memcpy(addrPtr, rf_setup->mac64, 8); 01242 } 01243 01244 static void mac_mlme_write_mac16(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01245 { 01246 common_write_16_bit(rf_setup->mac_short_address, addrPtr); 01247 } 01248 01249 uint16_t mac_mlme_get_panid(protocol_interface_rf_mac_setup_s *rf_setup) 01250 { 01251 uint16_t panId = 0xffff; 01252 if (rf_setup) { 01253 panId = rf_setup->pan_id; 01254 } 01255 return panId; 01256 } 01257 01258 static bool add_or_update_beacon(mlme_scan_conf_t *conf, mlme_beacon_ind_t *data, fhss_api_t *fhss_api) 01259 { 01260 bool found = false; 01261 bool update_beacon = false; 01262 for (int i = 0; i < conf->ResultListSize; i++) { 01263 mlme_pan_descriptor_t *cur_desc = conf->PAN_values[i]; 01264 if (!cur_desc) { //Not an active or passive scan 01265 break; 01266 } 01267 /* When FHSS is enabled, logical channel check is not valid 01268 * as the Beacon can be sent on any enabled channel */ 01269 if (fhss_api || (cur_desc->LogicalChannel == data->PANDescriptor.LogicalChannel)) { 01270 if (cur_desc->CoordPANId == data->PANDescriptor.CoordPANId) { 01271 if (cur_desc->LinkQuality < data->PANDescriptor.LinkQuality) { 01272 cur_desc->CoordAddrMode = data->PANDescriptor.CoordAddrMode; 01273 memcpy(cur_desc->CoordAddress, data->PANDescriptor.CoordAddress, 8); 01274 cur_desc->LinkQuality = data->PANDescriptor.LinkQuality; 01275 update_beacon = true; 01276 } 01277 found = true; 01278 } 01279 } 01280 } 01281 if (!found && conf->ResultListSize != MLME_MAC_RES_SIZE_MAX) { 01282 mlme_pan_descriptor_t *desc = ns_dyn_mem_temporary_alloc(sizeof(mlme_pan_descriptor_t)); 01283 if (!desc) { 01284 return false; 01285 } 01286 memset(desc, 0, sizeof(mlme_pan_descriptor_t)); 01287 mlme_pan_descriptor_t *dat = &data->PANDescriptor; 01288 01289 desc->CoordAddrMode = dat->CoordAddrMode; 01290 desc->CoordPANId = dat->CoordPANId; 01291 memcpy(desc->CoordAddress, dat->CoordAddress, 8); 01292 desc->LogicalChannel = dat->LogicalChannel; 01293 desc->ChannelPage = dat->ChannelPage; 01294 memcpy(desc->SuperframeSpec, dat->SuperframeSpec, 2); 01295 desc->GTSPermit = dat->GTSPermit; 01296 desc->LinkQuality = dat->LinkQuality; 01297 desc->Timestamp = dat->Timestamp; 01298 desc->SecurityFailure = dat->SecurityFailure; 01299 01300 desc->Key.SecurityLevel = dat->Key.SecurityLevel; 01301 desc->Key.KeyIdMode = dat->Key.KeyIdMode; 01302 desc->Key.KeyIndex = dat->Key.KeyIndex; 01303 memcpy(desc->Key.Keysource, dat->Key.Keysource, 8); 01304 01305 conf->PAN_values[conf->ResultListSize] = desc; 01306 conf->ResultListSize++; 01307 update_beacon = true; 01308 } 01309 return update_beacon; 01310 } 01311 01312 int mac_mlme_beacon_notify(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_beacon_ind_t *data) 01313 { 01314 bool update_beacon = true; 01315 bool contains_fhss_synch_info = false; 01316 if (!rf_mac_setup || !data) { 01317 return -1; 01318 } 01319 01320 /* Cut FHSS synchronization info from Beacon payload length. 01321 * Synchronization info is stored later in this function but 01322 * should not be delivered to upper layer as a part of Beacon payload. 01323 */ 01324 if (rf_mac_setup->fhss_api) { 01325 if (data->beacon_data_length > FHSS_SYNCH_INFO_START) { 01326 data->beacon_data_length -= FHSS_SYNCH_INFO_LENGTH; 01327 contains_fhss_synch_info = true; 01328 } else { 01329 // Received single channel Beacon when FHSS enabled. 01330 return 0; 01331 } 01332 } 01333 01334 mac_api_t *mac = get_sw_mac_api(rf_mac_setup); 01335 if (mac && mac->mlme_ind_cb) { 01336 mac->mlme_ind_cb(mac, MLME_BEACON_NOTIFY, data); 01337 } 01338 01339 if (rf_mac_setup->mac_mlme_scan_resp) { 01340 mlme_scan_conf_t *conf = rf_mac_setup->mac_mlme_scan_resp; 01341 update_beacon = add_or_update_beacon(conf, data, rf_mac_setup->fhss_api); 01342 } 01343 if (rf_mac_setup->fhss_api && (update_beacon == true)) { 01344 if (contains_fhss_synch_info == true) { 01345 // Assume synchronization info is found from the end of the Beacon payload 01346 uint8_t *synch_info_start = data->beacon_data + data->beacon_data_length; 01347 rf_mac_setup->fhss_api->receive_frame(rf_mac_setup->fhss_api, data->PANDescriptor.CoordPANId, data->PANDescriptor.CoordAddress, 01348 data->PANDescriptor.Timestamp, synch_info_start, FHSS_SYNCH_FRAME); 01349 } 01350 } 01351 01352 return 0; 01353 } 01354 01355 int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length) 01356 { 01357 (void) length; 01358 protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_driver_id(driver_id); 01359 if (!mac_setup) { 01360 return -1; 01361 } 01362 mlme_primitive primitive = (mlme_primitive) * data_ptr; 01363 if (primitive == MLME_SCAN) { 01364 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 01365 if (!resp) { 01366 return -1; 01367 } 01368 memset(resp, 0, sizeof(mlme_scan_conf_t)); 01369 resp->ScanType = MAC_ACTIVE_SCAN; 01370 mac_setup->mac_mlme_scan_resp = resp; 01371 mac_mlme_scan_confirmation_handle(mac_setup); 01372 } 01373 return 0; 01374 } 01375 01376 static void mac_mlme_start_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_start_conf_t *conf) 01377 { 01378 if (rf_ptr->tun_extension_rf_driver) { 01379 virtual_data_req_t start_conf; 01380 uint8_t buf_temp[2]; 01381 uint8_t payload_buf[2]; 01382 // Add some random data as empty payload is not allowed 01383 payload_buf[0] = 0; 01384 payload_buf[1] = 0; 01385 01386 memset(&start_conf, 0, sizeof(virtual_data_req_t)); 01387 buf_temp[0] = NAP_MLME_CONFIRM; 01388 buf_temp[1] = MLME_START; 01389 start_conf.parameters = buf_temp; 01390 start_conf.parameter_length = sizeof(buf_temp); 01391 start_conf.msdu = payload_buf; 01392 start_conf.msduLength = sizeof(payload_buf); 01393 01394 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&start_conf, rf_ptr->tun_extension_rf_driver->id); 01395 } else if (get_sw_mac_api(rf_ptr)) { 01396 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01397 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_START, conf); 01398 } 01399 } 01400 } 01401 01402 static void mac_mlme_scan_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_scan_conf_t *conf) 01403 { 01404 if (rf_ptr->tun_extension_rf_driver) { 01405 virtual_data_req_t scan_conf; 01406 uint8_t buf_temp[2]; 01407 uint8_t payload_buf[2]; 01408 // Add some random data as empty payload is not allowed 01409 payload_buf[0] = 0; 01410 payload_buf[1] = 0; 01411 01412 memset(&scan_conf, 0, sizeof(virtual_data_req_t)); 01413 buf_temp[0] = NAP_MLME_CONFIRM; 01414 buf_temp[1] = MLME_SCAN; 01415 scan_conf.parameters = buf_temp; 01416 scan_conf.parameter_length = sizeof(buf_temp); 01417 scan_conf.msdu = payload_buf; 01418 scan_conf.msduLength = sizeof(payload_buf); 01419 01420 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&scan_conf, rf_ptr->tun_extension_rf_driver->id); 01421 } else if (get_sw_mac_api(rf_ptr)) { 01422 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01423 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_SCAN, conf); 01424 } 01425 } 01426 } 01427 01428 void mac_mlme_scan_confirmation_handle(protocol_interface_rf_mac_setup_s *rf_ptr) 01429 { 01430 if (!rf_ptr) { 01431 return; 01432 } 01433 mlme_scan_conf_t *r = rf_ptr->mac_mlme_scan_resp; 01434 01435 if (r) { 01436 mac_mlme_scan_confirm_handler(rf_ptr, r); 01437 } 01438 mac_mlme_free_scan_temporary_data(rf_ptr); 01439 } 01440 01441 void mac_mlme_mac_radio_disabled(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01442 { 01443 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01444 return; 01445 } 01446 platform_enter_critical(); 01447 timer_mac_stop(rf_mac_setup); 01448 mac_mlme_rf_disable(rf_mac_setup); 01449 platform_exit_critical(); 01450 } 01451 01452 void mac_mlme_mac_radio_enable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01453 { 01454 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01455 return; 01456 } 01457 platform_enter_critical(); 01458 mac_mlme_rf_receiver_enable(rf_mac_setup); 01459 platform_exit_critical(); 01460 } 01461 01462 static int8_t mac_mlme_rf_disable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01463 { 01464 int8_t ret_val = 0; 01465 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01466 if (!dev_driver->state_control) { 01467 if (dev_driver->link_type == PHY_LINK_TUN) { 01468 rf_mac_setup->macRfRadioOn = false; 01469 rf_mac_setup->macRfRadioTxActive = false; 01470 return 0; 01471 } 01472 return -1; 01473 } 01474 if (rf_mac_setup->macRfRadioOn) { 01475 ret_val = dev_driver->state_control(PHY_INTERFACE_DOWN, 0); 01476 rf_mac_setup->macRfRadioOn = false; 01477 rf_mac_setup->macRfRadioTxActive = false; 01478 } 01479 01480 return ret_val; 01481 } 01482 01483 static int8_t mac_mlme_rf_receiver_enable(struct protocol_interface_rf_mac_setup *rf_mac_setup) 01484 { 01485 int8_t retval; 01486 01487 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01488 if (!dev_driver->state_control) { 01489 if (dev_driver->link_type == PHY_LINK_TUN) { 01490 rf_mac_setup->macRfRadioOn = true; 01491 return 0; 01492 } 01493 return -1; 01494 } 01495 01496 if (rf_mac_setup->macRfRadioOn) { 01497 return 0; 01498 } 01499 01500 if (rf_mac_setup->macProminousMode) { 01501 tr_debug("Sniffer mode"); 01502 retval = dev_driver->state_control(PHY_INTERFACE_SNIFFER_STATE, rf_mac_setup->mac_channel); 01503 } else { 01504 retval = dev_driver->state_control(PHY_INTERFACE_UP, rf_mac_setup->mac_channel); 01505 } 01506 rf_mac_setup->macRfRadioOn = true; 01507 //tr_debug("Enable radio with channel %u", rf_mac_setup->mac_channel); 01508 return retval; 01509 } 01510 01511 /** 01512 * Initialize MAC channel selection sequence 01513 * 01514 * TODO: initialize channel select sequence 01515 * in coordinator mode 01516 * 01517 * \param new_channel channel to set 01518 * 01519 * \return 0 success 01520 * \return -1 HW error 01521 */ 01522 static int8_t mac_mlme_rf_channel_set(struct protocol_interface_rf_mac_setup *rf_setup, uint8_t new_channel) 01523 { 01524 if (new_channel == rf_setup->mac_channel) { 01525 return 0; 01526 } 01527 mac_pre_build_frame_t *buf; 01528 01529 //Disable allways 01530 mac_mlme_mac_radio_disabled(rf_setup); 01531 buf = rf_setup->active_pd_data_request; 01532 rf_setup->active_pd_data_request = NULL; 01533 //Set Channel 01534 rf_setup->mac_channel = new_channel; 01535 //Enable Radio 01536 mac_mlme_mac_radio_enable(rf_setup); 01537 if (buf) { 01538 mcps_sap_pd_req_queue_write(rf_setup, buf); 01539 } 01540 01541 return 0; 01542 } 01543 01544 /** 01545 * MAC channel change 01546 * 01547 * \param new_channel channel to set 01548 * 01549 * \return 0 success 01550 * \return -1 error 01551 */ 01552 int8_t mac_mlme_rf_channel_change(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t new_channel) 01553 { 01554 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01555 return -1; 01556 } 01557 01558 if (!rf_mac_setup->dev_driver->phy_driver->extension) { 01559 if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_TUN) { 01560 rf_mac_setup->mac_channel = new_channel; 01561 return 0; 01562 } 01563 return -1; 01564 } 01565 if (new_channel == rf_mac_setup->mac_channel) { 01566 return 0; 01567 } 01568 platform_enter_critical(); 01569 if (rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CHANNEL, &new_channel) == 0) { 01570 rf_mac_setup->mac_channel = new_channel; 01571 } 01572 platform_exit_critical(); 01573 return 0; 01574 } 01575 01576 void mac_mlme_poll_process_confirm(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t status) 01577 { 01578 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01579 return; 01580 } 01581 01582 //Free active Data buffer 01583 if (rf_mac_setup->active_pd_data_request) { 01584 mcps_sap_prebuild_frame_buffer_free(rf_mac_setup->active_pd_data_request); 01585 rf_mac_setup->active_pd_data_request = NULL; 01586 } 01587 //Disable timer 01588 rf_mac_setup->macWaitingData = false; 01589 rf_mac_setup->macDataPollReq = false; 01590 rf_mac_setup->macRxDataAtPoll = false; 01591 01592 if (!rf_mac_setup->macCapRxOnIdle) { 01593 //Disable Radio If we are RX off at idle device 01594 //tr_debug("disbale by aceptance data"); 01595 if (!rf_mac_setup->macRfRadioTxActive) { 01596 //Disable radio if no active TX and radio is enabled 01597 //tr_debug("RF disable"); 01598 mac_mlme_mac_radio_disabled(rf_mac_setup); 01599 } 01600 } 01601 01602 mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup); 01603 if (mac_api) { 01604 mlme_poll_conf_t confirm; 01605 confirm.status = status; 01606 mac_api->mlme_conf_cb(mac_api, MLME_POLL, &confirm); 01607 } 01608 //Trig Packet from queue 01609 mac_mcps_trig_buffer_from_queue(rf_mac_setup); 01610 01611 } 01612 01613 void mac_mlme_poll_req(protocol_interface_rf_mac_setup_s *cur, const mlme_poll_t *poll_req) 01614 { 01615 if (!cur || !poll_req) { 01616 return; 01617 } 01618 if (cur->macDataPollReq) { 01619 tr_debug("Poll Active do not start new"); 01620 return; 01621 } 01622 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0); 01623 if (!buf) { 01624 tr_debug("No mem for data Req"); 01625 //Confirmation call here 01626 return; 01627 } 01628 01629 buf->fcf_dsn.frametype = FC_CMD_FRAME; 01630 buf->fcf_dsn.ackRequested = true; 01631 buf->fcf_dsn.intraPan = true; 01632 01633 buf->DstPANId = poll_req->CoordPANId; 01634 buf->SrcPANId = poll_req->CoordPANId; 01635 buf->fcf_dsn.DstAddrMode = poll_req->CoordAddrMode; 01636 memcpy(buf->DstAddr, poll_req->CoordAddress, 8); 01637 01638 buf->mac_command_id = MAC_DATA_REQ; 01639 buf->mac_payload = &buf->mac_command_id; 01640 buf->mac_payload_length = 1; 01641 buf->mac_header_length_with_security = 3; 01642 01643 mac_header_security_parameter_set(&buf->aux_header, &poll_req->Key); 01644 01645 if (buf->aux_header.securityLevel) { 01646 buf->fcf_dsn.securityEnabled = true; 01647 buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; 01648 01649 } 01650 cur->macDataPollReq = true; 01651 cur->macWaitingData = true; 01652 cur->macRxDataAtPoll = false; 01653 01654 buf->security_mic_len = mac_security_mic_length_get(buf->aux_header.securityLevel); 01655 buf->mac_header_length_with_security += mac_header_security_aux_header_length(buf->aux_header.securityLevel, buf->aux_header.KeyIdMode); 01656 01657 if (cur->mac_short_address > 0xfffd) { 01658 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01659 } else { 01660 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01661 } 01662 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, cur, buf->SrcAddr); 01663 //Check PanID presents at header 01664 buf->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buf->fcf_dsn); 01665 buf->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buf->fcf_dsn); 01666 buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn); 01667 buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; 01668 mcps_sap_pd_req_queue_write(cur, buf); 01669 } 01670 01671 static bool mac_mlme_beacon_at_queue(protocol_interface_rf_mac_setup_s *rf_ptr) 01672 { 01673 mac_pre_build_frame_t *buf = rf_ptr->active_pd_data_request; 01674 if (buf && buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 01675 return true; 01676 } 01677 01678 buf = rf_ptr->pd_data_request_queue_to_go; 01679 01680 while (buf) { 01681 if (buf->fcf_dsn.frametype == FC_BEACON_FRAME) { 01682 return true; 01683 } 01684 buf = buf->next; 01685 } 01686 return false; 01687 } 01688 01689 int8_t mac_mlme_beacon_tx(protocol_interface_rf_mac_setup_s *rf_ptr) 01690 { 01691 if (!rf_ptr || !rf_ptr->macCapCordinator) { 01692 return -1; 01693 } 01694 01695 //Verify if beacon is already generated to queue 01696 if (mac_mlme_beacon_at_queue(rf_ptr)) { 01697 return -2; 01698 } 01699 01700 uint16_t length = 4; 01701 length += rf_ptr->mac_beacon_payload_size; 01702 // Add more space for FHSS synchronization info 01703 if (rf_ptr->fhss_api) { 01704 length += FHSS_SYNCH_INFO_LENGTH; 01705 } 01706 /* if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01707 length += 2; 01708 }*/ 01709 01710 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(length); 01711 if (!buf) { 01712 return -1; 01713 } 01714 uint8_t sf_2 = 0x0f; 01715 01716 buf->fcf_dsn.frametype = FC_BEACON_FRAME; 01717 buf->fcf_dsn.DstAddrMode = MAC_ADDR_MODE_NONE; 01718 01719 if (rf_ptr->beaconSrcAddressModeLong) { 01720 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01721 buf->mac_header_length_with_security = 13; 01722 } else { 01723 if (rf_ptr->shortAdressValid) { 01724 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01725 buf->mac_header_length_with_security = 7; 01726 } else { 01727 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01728 buf->mac_header_length_with_security = 13; 01729 } 01730 } 01731 buf->SrcPANId = mac_mlme_get_panid(rf_ptr); 01732 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, rf_ptr, buf->SrcAddr); 01733 buf->fcf_dsn.DstPanPresents = false; 01734 buf->fcf_dsn.SrcPanPresents = true; 01735 01736 uint8_t *ptr = buf->mac_payload; 01737 01738 *ptr++ = 0xff;//Superframe disabled 01739 01740 if (rf_ptr->macCapCordinator) { 01741 sf_2 |= 0x40; //Cord 01742 } 01743 01744 if (rf_ptr->macCapBatteryPowered) { 01745 sf_2 |= 0x10; //Battery 01746 } 01747 01748 if (rf_ptr->macCapAssocationPermit) { 01749 sf_2 |= 0x80; //Permit 01750 } 01751 *ptr++ = sf_2; //Superframe desc MSB 01752 ptr = common_write_16_bit(0, ptr); //NO GTS Support 01753 01754 if (rf_ptr->mac_beacon_payload_size) { 01755 memcpy(ptr, rf_ptr->mac_beacon_payload, rf_ptr->mac_beacon_payload_size); 01756 01757 /*if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01758 uint8_t beacon_join_priority = rf_ptr->beacon_join_priority_tx_cb_ptr(rf_ptr->mac_interface_id); 01759 ptr[PLAIN_BEACON_PAYLOAD_SIZE] = BEACON_OPTION_JOIN_PRIORITY_TYPE_LEN; 01760 ptr[PLAIN_BEACON_PAYLOAD_SIZE + 1] = beacon_join_priority; 01761 ptr += BEACON_OPTION_JOIN_PRIORITY_LEN; 01762 }*/ 01763 } 01764 buf->priority = MAC_PD_DATA_HIGH_PRIOTITY; 01765 mcps_sap_pd_req_queue_write(rf_ptr, buf); 01766 sw_mac_stats_update(rf_ptr, STAT_MAC_BEA_TX_COUNT, 0); 01767 return 0; 01768 } 01769
Generated on Tue Jul 12 2022 13:54:31 by
1.7.2