Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mac_mlme.c
00001 /* 00002 * Copyright (c) 2013-2018, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /** 00018 * 00019 * \file mac_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 00072 static void mac_mlme_energy_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t channel) 00073 { 00074 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00075 rf_mac_setup->mac_channel = channel; 00076 if (rf_mac_setup->macRfRadioOn) { 00077 if (dev_driver->state_control) { 00078 dev_driver->state_control(PHY_INTERFACE_DOWN, 0); 00079 } 00080 } 00081 if (dev_driver->state_control) { 00082 dev_driver->state_control(PHY_INTERFACE_RX_ENERGY_STATE, channel); 00083 } 00084 rf_mac_setup->macRfRadioOn = true; 00085 rf_mac_setup->macRfRadioTxActive = false; 00086 } 00087 00088 uint16_t mlme_scan_analyze_next_channel(channel_list_s *mac_channel_list) 00089 { 00090 uint8_t i, j = 0, k = 1; 00091 uint32_t mask = 1; 00092 uint32_t *channel_mask = mac_channel_list->channel_mask; 00093 00094 if (mac_channel_list->channel_page == CHANNEL_PAGE_9 || 00095 mac_channel_list->channel_page == CHANNEL_PAGE_10) { 00096 k=8; 00097 } 00098 for(j=0; j<k; j++) 00099 { 00100 for (i=0; i<32; i++) 00101 { 00102 if (*channel_mask & mask) 00103 { 00104 *channel_mask &= ~mask; 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 uint32_t symbol_rate; 00118 00119 // Gets symbol rate for channel 00120 switch (channel_page) { 00121 case CHANNEL_PAGE_0: 00122 // 868 Mhz BPSK 00123 if (channel == 0) { 00124 symbol_rate = 20000; 00125 // 915 Mhz BPSK 00126 } else if (channel >= 1 && channel <= 10) { 00127 symbol_rate = 40000; 00128 // 2450 Mhz O-QPSK 00129 } else { 00130 symbol_rate = 62500; 00131 } 00132 break; 00133 case CHANNEL_PAGE_1: 00134 // 868 MHz ASK 00135 if (channel == 0) { 00136 symbol_rate = 12500; 00137 // 915 MHz ASK 00138 } else { 00139 symbol_rate = 50000; 00140 } 00141 break; 00142 case CHANNEL_PAGE_2: 00143 // 868 MHz O-QPSK 00144 if (channel == 0) { 00145 symbol_rate = 25000; 00146 // 915 MHz O-QPSK 00147 } else { 00148 symbol_rate = 62500; 00149 } 00150 break; 00151 case CHANNEL_PAGE_3: 00152 // 2450 CSS 00153 symbol_rate = 167000; 00154 break; 00155 case CHANNEL_PAGE_6: 00156 // 950 MHz BPSK 00157 if (channel <= 9) { 00158 symbol_rate = 20000; 00159 // 950 MHz GFSK 00160 } else { 00161 symbol_rate = 100000; 00162 } 00163 break; 00164 default: 00165 symbol_rate = 62500; 00166 break; 00167 } 00168 00169 return symbol_rate; 00170 } 00171 00172 static void mac_mlme_calc_scan_duration(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t channel) 00173 { 00174 rf_mac_setup->mlme_ED_counter = 1; 00175 00176 if (rf_mac_setup->scan_duration) { 00177 rf_mac_setup->mlme_ED_counter <<= rf_mac_setup->scan_duration; 00178 } 00179 00180 rf_mac_setup->mlme_ED_counter++; 00181 00182 if (rf_mac_setup->scan_type == MAC_ED_SCAN_TYPE) { 00183 // Gets symbol rate for channel that is scanned 00184 uint32_t symbol_rate = mac_mlme_channel_symbol_rate( 00185 rf_mac_setup->mac_channel_list.channel_page, channel); 00186 00187 // Energy scan duration is aBaseSuperframeDuration * (2^n + 1) 00188 // aBaseSuperframeDuration is 960 symbols e.g for 2.4Ghz O-QPSK with 62.5 ksymbols/s -> 15,36ms. 00189 // ED scan timer timeout is 4.8ms 00190 uint16_t frame_duration = (uint32_t) 960 * 100000 / symbol_rate; 00191 rf_mac_setup->mlme_ED_counter = (uint32_t) rf_mac_setup->mlme_ED_counter * frame_duration / 480; 00192 } 00193 } 00194 00195 static void mac_mlme_start_request(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00196 { 00197 mac_pre_build_frame_t *buf; 00198 platform_enter_critical(); 00199 00200 mac_mlme_rf_disable(rf_mac_setup); 00201 buf = rf_mac_setup->active_pd_data_request; 00202 rf_mac_setup->active_pd_data_request = NULL; 00203 mac_mlme_mac_radio_enable(rf_mac_setup); 00204 rf_mac_setup->macUpState = true; 00205 if (buf) { 00206 // Active packet is pushed back to queue and statistics will be cleared. They need to be updated here. 00207 sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_CCA_ATT, rf_mac_setup->mac_tx_status.cca_cnt); 00208 sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_RETRY, rf_mac_setup->mac_tx_status.retry); 00209 mcps_sap_pd_req_queue_write(rf_mac_setup, buf); 00210 } 00211 platform_exit_critical(); 00212 } 00213 00214 uint8_t mac_mlme_beacon_req_tx(protocol_interface_rf_mac_setup_s *rf_ptr) 00215 { 00216 00217 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0); 00218 00219 if (buf) { 00220 buf->fcf_dsn.DstAddrMode = MAC_ADDR_MODE_16_BIT; 00221 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_NONE; 00222 buf->fcf_dsn.frametype = FC_CMD_FRAME; 00223 buf->DstPANId = 0xffff; 00224 buf->DstAddr[0] = 0xff; 00225 buf->DstAddr[1] = 0xff; 00226 buf->mac_command_id = MAC_BEACON_REQ; 00227 buf->mac_header_length_with_security = 7; 00228 buf->mac_payload = &buf->mac_command_id; 00229 buf->mac_payload_length = 1; 00230 buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; 00231 buf->fcf_dsn.DstPanPresents = true; 00232 buf->fcf_dsn.SrcPanPresents = false; 00233 00234 tr_debug("BEA REQ tx"); 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); 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 } 00297 else if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_15_4_SUBGHZ_TYPE && 00298 (list->channel_page == 0 || list->channel_page == 1 || list->channel_page == 2)) { 00299 if (list->channel_mask[0] & 0x000007ff) { 00300 return true; 00301 } 00302 00303 return false; 00304 } else { 00305 for (int i=0; i < 8; i++) { 00306 if (list->channel_mask[i]) { 00307 return true; 00308 } 00309 } 00310 } 00311 00312 return false; 00313 } 00314 00315 static int mac_mlme_generate_scan_confirmation(mlme_scan_conf_t *conf, const mlme_scan_t *msg, uint8_t status) 00316 { 00317 memset(conf, 0, sizeof(mlme_scan_conf_t)); 00318 conf->status = status; 00319 if (!msg) { 00320 return -1; 00321 } 00322 conf->ScanType = msg->ScanType; 00323 conf->ChannelPage = msg->ChannelPage; 00324 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00325 /*If the scan is successful, this value will be modified properly in mlme_analyze_next_channel() 00326 and assigned in mlme_scan_operation()*/ 00327 conf->UnscannedChannels.channel_mask[0] = msg->ScanChannels.channel_mask[0]; 00328 } else if (msg->ScanType == MAC_ED_SCAN_TYPE) { 00329 conf->ED_values = ns_dyn_mem_temporary_alloc(MLME_MAC_RES_SIZE_MAX); 00330 if (!conf->ED_values) { 00331 tr_debug("Could not allocate memory for ED values"); 00332 conf->status = MLME_SUCCESS; 00333 return -2; 00334 } 00335 memset(conf->ED_values, 0, MLME_MAC_RES_SIZE_MAX); 00336 } 00337 return 0; 00338 } 00339 00340 void mac_mlme_scan_request(const mlme_scan_t *msg, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00341 { 00342 if (rf_mac_setup->mac_mlme_scan_resp){ 00343 mlme_scan_conf_t conf; 00344 mac_mlme_generate_scan_confirmation(&conf, msg, MLME_SCAN_IN_PROGRESS); 00345 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00346 ns_dyn_mem_free(conf.ED_values); 00347 return; 00348 } 00349 00350 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 00351 if (!resp) { 00352 mlme_scan_conf_t conf; 00353 tr_error("Mac Scan request fail, no memory"); 00354 mac_mlme_generate_scan_confirmation(&conf, NULL, MLME_SUCCESS); 00355 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00356 ns_dyn_mem_free(conf.ED_values); 00357 return; 00358 } 00359 00360 rf_mac_setup->mac_mlme_scan_resp = resp; 00361 //Validate channel list 00362 tr_debug("chan page %u, mask %"PRIx32, msg->ScanChannels.channel_page, msg->ScanChannels.channel_mask[0]); 00363 if (!mac_channel_list_validate(&msg->ScanChannels, rf_mac_setup)) { 00364 tr_debug("Unsupported channel list"); 00365 mac_mlme_generate_scan_confirmation(resp, msg, MLME_INVALID_PARAMETER); 00366 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00367 return; 00368 } 00369 00370 if (mac_mlme_generate_scan_confirmation(resp, msg, MLME_SUCCESS) != 0) { 00371 return; 00372 } 00373 00374 tr_debug("MAC: Start MLME scan"); 00375 00376 if (mac_mlme_rf_disable(rf_mac_setup) == 0) { 00377 rf_mac_setup->macCapRxOnIdle = false; 00378 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00379 rf_mac_setup->macUpState = true; 00380 } 00381 } else { 00382 tr_error("Failed to disable RF"); 00383 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00384 return; 00385 } 00386 00387 rf_mac_setup->scan_type = msg->ScanType; 00388 rf_mac_setup->scan_duration = msg->ScanDuration; 00389 rf_mac_setup->mac_channel_list = msg->ScanChannels; 00390 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00391 rf_mac_setup->scan_active = true; 00392 mac_mlme_scan_start(rf_mac_setup); 00393 } 00394 00395 int8_t mac_mlme_start_req(const mlme_start_t *s, struct protocol_interface_rf_mac_setup *rf_mac_setup) 00396 { 00397 if (!s || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 00398 return -1; 00399 } 00400 00401 tr_debug("MAC: Start network %u channel %x panid", s->LogicalChannel, s->PANId); 00402 mac_mlme_set_panid(rf_mac_setup, s->PANId); 00403 // Synchronize FHSS 00404 if (rf_mac_setup->fhss_api) { 00405 rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_SYNCHRONIZED, s->PANId); 00406 } 00407 00408 if (!rf_mac_setup->fhss_api) { 00409 rf_mac_setup->mac_channel = s->LogicalChannel; 00410 } 00411 mac_mlme_start_request(rf_mac_setup); 00412 if (s->PANCoordinator) { 00413 //tr_debug("Cordinator"); 00414 rf_mac_setup->macCapCordinator = true; 00415 rf_mac_setup->macCapRxOnIdle = true; 00416 } else { 00417 rf_mac_setup->macCapCordinator = false; 00418 } 00419 00420 if (s->BatteryLifeExtension) { 00421 rf_mac_setup->macCapBatteryPowered = true; 00422 } else { 00423 rf_mac_setup->macCapBatteryPowered = false; 00424 } 00425 mlme_start_conf_t conf; 00426 conf.status = MLME_SUCCESS; 00427 mac_mlme_start_confirm_handler(rf_mac_setup, &conf); 00428 return 0; 00429 } 00430 00431 int8_t mac_mlme_reset(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_reset_t *reset) { 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 00546 default: 00547 return -1; 00548 } 00549 return 0; 00550 } 00551 00552 static int8_t mac_mlme_8bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,mlme_attr_t attribute ,uint8_t value) 00553 { 00554 switch (attribute) { 00555 case phyCurrentChannel: 00556 mac_mlme_rf_channel_set(rf_mac_setup, value); 00557 break; 00558 case macBeaconPayloadLength: 00559 if (rf_mac_setup->max_beacon_payload_length < value) { 00560 return -1; 00561 } 00562 00563 rf_mac_setup->mac_beacon_payload_size = value; 00564 break; 00565 case macAutoRequestKeyIndex: 00566 rf_mac_setup->mac_auto_request.KeyIndex = value; 00567 break; 00568 00569 case macAutoRequestKeyIdMode: 00570 rf_mac_setup->mac_auto_request.KeyIdMode = value; 00571 break; 00572 00573 case macAutoRequestSecurityLevel: 00574 rf_mac_setup->mac_auto_request.SecurityLevel = value; 00575 break; 00576 case macMaxFrameRetries: 00577 if (value > 7) { 00578 return -1; 00579 } 00580 rf_mac_setup->mac_mlme_retry_max = value; 00581 break; 00582 00583 case macMinBE: 00584 if (value > rf_mac_setup->macMaxBE) { 00585 rf_mac_setup->macMinBE = value; 00586 } 00587 break; 00588 00589 case macMaxBE: 00590 if (value > 8 || value < 3) { 00591 return -1; 00592 } 00593 rf_mac_setup->macMaxBE = value; 00594 break; 00595 00596 case macMaxCSMABackoffs: 00597 if (value > 8 ) { 00598 return -1; 00599 } 00600 rf_mac_setup->macMaxCSMABackoffs = value; 00601 break; 00602 00603 default: 00604 return -1; 00605 } 00606 return 0; 00607 } 00608 00609 static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint32_t value) 00610 { 00611 (void)rf_mac_setup; 00612 (void) value; 00613 switch (attribute) { 00614 case macFrameCounter: 00615 platform_enter_critical(); 00616 rf_mac_setup->security_frame_counter = value; 00617 platform_exit_critical(); 00618 break; 00619 00620 default: 00621 return -1; 00622 } 00623 return 0; 00624 } 00625 00626 void mac_extended_mac_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *mac64) 00627 { 00628 if( !mac64 || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ){ 00629 return; 00630 } 00631 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00632 memcpy(rf_mac_setup->mac64, mac64, 8); //This should be random 00633 if (dev_driver->address_write) { 00634 dev_driver->address_write(PHY_MAC_64BIT, rf_mac_setup->mac64); 00635 } 00636 } 00637 00638 static int8_t mac_mlme_device_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00639 00640 if (set_req->value_size != sizeof(mlme_device_descriptor_t)) { 00641 return -1; 00642 } 00643 00644 return mac_sec_mib_device_description_set(set_req->attr_index,(mlme_device_descriptor_t *) set_req->value_pointer , rf_mac_setup); 00645 } 00646 00647 static int8_t mac_mlme_key_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00648 if (set_req->value_size != sizeof(mlme_key_descriptor_entry_t)) { 00649 return -1; 00650 } 00651 00652 return mac_sec_mib_key_description_set(set_req->attr_index,(mlme_key_descriptor_entry_t *) set_req->value_pointer , rf_mac_setup); 00653 } 00654 00655 static int8_t mac_mlme_default_key_source_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00656 if (set_req->value_size != 8) { 00657 return -1; 00658 } 00659 if (set_req->attr == macDefaultKeySource) { 00660 memcpy(rf_mac_setup->mac_default_key_source, (uint8_t *)set_req->value_pointer, 8); 00661 } else { 00662 memcpy(rf_mac_setup->mac_auto_request.Keysource, (uint8_t *)set_req->value_pointer, 8); 00663 } 00664 return 0; 00665 } 00666 00667 static int8_t mac_mlme_beacon_payload_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00668 { 00669 if (set_req->value_size > rf_mac_setup->max_beacon_payload_length) { 00670 return -1; 00671 } 00672 00673 memcpy(rf_mac_setup->mac_beacon_payload, set_req->value_pointer, set_req->value_size); 00674 memset(rf_mac_setup->mac_beacon_payload + set_req->value_size, 0, rf_mac_setup->max_beacon_payload_length - set_req->value_size); 00675 00676 return 0; 00677 } 00678 00679 static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) 00680 { 00681 if (set_req->value_size == 1) { 00682 const bool *pbool = set_req->value_pointer; 00683 //Check first boolean 00684 if (mac_mlme_boolean_set(rf_mac_setup,set_req->attr, *pbool) == 0) { 00685 return 0; 00686 } 00687 const uint8_t *pu8 = set_req->value_pointer; 00688 return mac_mlme_8bit_set(rf_mac_setup,set_req->attr, *pu8); 00689 00690 } else if (set_req->value_size == 2) { 00691 const uint16_t *pu16 = set_req->value_pointer; 00692 return mac_mlme_16bit_set(rf_mac_setup,set_req->attr, *pu16); 00693 } else if (set_req->value_size == 4) { 00694 const uint32_t *pu32 = set_req->value_pointer; 00695 return mac_mlme_32bit_set(rf_mac_setup,set_req->attr, *pu32); 00696 } 00697 return -1; 00698 } 00699 00700 int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) 00701 { 00702 if (!set_req || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ) { 00703 return -1; 00704 } 00705 00706 switch (set_req->attr) { 00707 case macDeviceTable: 00708 return mac_mlme_device_description_set(rf_mac_setup, set_req); 00709 case macKeyTable: 00710 return mac_mlme_key_description_set(rf_mac_setup, set_req); 00711 case macDefaultKeySource: 00712 case macAutoRequestKeySource: 00713 return mac_mlme_default_key_source_set(rf_mac_setup, set_req); 00714 case macBeaconPayload: 00715 return mac_mlme_beacon_payload_set(rf_mac_setup, set_req); 00716 case macLoadBalancingBeaconTx: 00717 return mac_mlme_beacon_tx(rf_mac_setup); 00718 case macCoordExtendedAddress: 00719 if( set_req->value_size == 8) { 00720 memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8); 00721 } 00722 return 0; 00723 default: 00724 return mac_mlme_handle_set_values(rf_mac_setup, set_req); 00725 } 00726 } 00727 00728 uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup) 00729 { 00730 uint32_t value; 00731 platform_enter_critical(); 00732 value = rf_mac_setup->security_frame_counter; 00733 platform_exit_critical(); 00734 return value; 00735 } 00736 00737 void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup) 00738 { 00739 platform_enter_critical(); 00740 rf_mac_setup->security_frame_counter++; 00741 platform_exit_critical(); 00742 } 00743 00744 void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup) 00745 { 00746 platform_enter_critical(); 00747 rf_mac_setup->security_frame_counter--; 00748 platform_exit_critical(); 00749 } 00750 00751 00752 int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req) 00753 { 00754 if (!get_req || !rf_mac_setup ) { 00755 return -1; 00756 } 00757 00758 switch (get_req->attr) { 00759 case macDeviceTable: 00760 get_req->value_pointer = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, get_req->attr_index); 00761 if (get_req->value_pointer) { 00762 get_req->value_size = sizeof(mlme_device_descriptor_t); 00763 } else { 00764 get_req->status = MLME_INVALID_INDEX; 00765 } 00766 break; 00767 00768 case macMaxFrameRetries: 00769 get_req->value_pointer = &rf_mac_setup->mac_mlme_retry_max; 00770 get_req->value_size = 1; 00771 break; 00772 00773 case macFrameCounter: 00774 platform_enter_critical(); 00775 get_req->value_pointer = &rf_mac_setup->security_frame_counter; 00776 platform_exit_critical(); 00777 get_req->value_size = 4; 00778 break; 00779 00780 default: 00781 get_req->status = MLME_UNSUPPORTED_ATTRIBUTE; 00782 break; 00783 00784 } 00785 return 0; 00786 } 00787 00788 static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00789 { 00790 uint16_t channel; 00791 mlme_scan_conf_t *resp = rf_mac_setup->mac_mlme_scan_resp; 00792 00793 if (rf_mac_setup->scan_type == MAC_ED_SCAN_TYPE) { 00794 resp->ED_values[resp->ResultListSize] = rf_mac_setup->max_ED; 00795 resp->ResultListSize++; 00796 } 00797 00798 channel = mlme_scan_analyze_next_channel(&rf_mac_setup->mac_channel_list); 00799 if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { 00800 resp->status = MLME_SUCCESS; 00801 tr_debug("Scan Complete..Halt MAC"); 00802 platform_enter_critical(); 00803 mac_mlme_mac_radio_disabled(rf_mac_setup); 00804 if (resp->ResultListSize == 0 && rf_mac_setup->scan_type == MAC_ACTIVE_SCAN) { 00805 resp->status = MLME_NO_BEACON; 00806 }else if( resp->ResultListSize == MLME_MAC_RES_SIZE_MAX ){ 00807 resp->status = MLME_LIMIT_REACHED; 00808 } 00809 resp->UnscannedChannels.channel_mask[0] = rf_mac_setup->mac_channel_list.channel_mask[0]; 00810 platform_exit_critical(); 00811 //Scan Confirmation 00812 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00813 tr_debug("Trig confirm"); 00814 rf_mac_setup->scan_active = false; 00815 } else { 00816 mac_mlme_scan_init((uint8_t) channel, rf_mac_setup); 00817 } 00818 } 00819 00820 void mac_frame_src_address_set_from_interface(uint8_t SrcAddrMode,protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t *addressPtr) 00821 { 00822 if( !rf_ptr ){ 00823 return; 00824 } 00825 if (SrcAddrMode == MAC_ADDR_MODE_16_BIT) { 00826 mac_mlme_write_mac16(rf_ptr, addressPtr); 00827 } else if (SrcAddrMode == MAC_ADDR_MODE_64_BIT) { 00828 mac_mlme_write_mac64(rf_ptr, addressPtr); 00829 } 00830 } 00831 00832 void mac_mlme_active_scan_response_timer_start(void *interface) 00833 { 00834 if (interface) { 00835 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s *)interface; 00836 if (rf_mac_setup) { 00837 if (rf_mac_setup->mac_mlme_event == ARM_NWK_MAC_MLME_SCAN) { 00838 eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id); 00839 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00840 rf_mac_setup->mlme_tick_count = rf_mac_setup->mlme_ED_counter; 00841 00842 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 300); 00843 } 00844 } 00845 } 00846 } 00847 00848 static void mac_mlme_timers_disable(protocol_interface_rf_mac_setup_s *rf_ptr) 00849 { 00850 platform_enter_critical(); 00851 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00852 eventOS_callback_timer_stop(rf_ptr->mlme_timer_id); 00853 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00854 } 00855 timer_mac_stop(rf_ptr); 00856 platform_exit_critical(); 00857 } 00858 00859 void mac_mlme_event_cb(void *mac_ptr) 00860 { 00861 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*) mac_ptr; 00862 if (!rf_mac_setup) { 00863 return; 00864 } 00865 arm_nwk_mlme_event_type_e event_type; 00866 event_type = rf_mac_setup->mac_mlme_event; 00867 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00868 switch (event_type) { 00869 case ARM_NWK_MAC_MLME_SCAN: 00870 mlme_scan_operation(rf_mac_setup); 00871 break; 00872 00873 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL: 00874 tr_debug("Data poll data wait TO"); 00875 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_NO_DATA); 00876 break; 00877 00878 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA: 00879 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_SUCCESS); 00880 break; 00881 00882 default: 00883 break; 00884 } 00885 } 00886 00887 static void mac_mcps_timer_cb(int8_t timer_id, uint16_t slots) 00888 { 00889 00890 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_MCPS_TIMER); 00891 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00892 return; 00893 } 00894 rf_ptr->mac_mcps_timer_event.event_data = slots; 00895 eventOS_event_send(&rf_ptr->mac_mcps_timer_event); 00896 00897 } 00898 00899 00900 static void mac_mlme_timer_cb(int8_t timer_id, uint16_t slots) 00901 { 00902 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_NWK_MLME_TIMER); 00903 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00904 return; 00905 } 00906 00907 if (rf_ptr->mlme_tick_count == 0) { 00908 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00909 if (rf_ptr->mac_mlme_event == ARM_NWK_MAC_MLME_ED_ANALYZE) { 00910 if (rf_ptr->mlme_ED_counter > 1) { 00911 uint8_t ed = 0; 00912 phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; 00913 rf_ptr->mlme_ED_counter--; 00914 if( dev_driver->extension ){ 00915 dev_driver->extension(PHY_EXTENSION_READ_CHANNEL_ENERGY, &ed); 00916 } 00917 if (ed > rf_ptr->max_ED) { 00918 rf_ptr->max_ED = ed; 00919 } 00920 00921 /*96 * 50us = 4.8ms*/ 00922 rf_ptr->mlme_tick_count = 0; 00923 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_ED_ANALYZE; 00924 eventOS_callback_timer_start(timer_id, slots); 00925 } else { 00926 mac_mlme_rf_disable(rf_ptr); 00927 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00928 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER, rf_ptr, false); 00929 } 00930 } else { 00931 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER,rf_ptr, true); 00932 } 00933 } 00934 } else { 00935 rf_ptr->mlme_tick_count--; 00936 eventOS_callback_timer_start(timer_id, slots); 00937 } 00938 } 00939 00940 static void mac_mlme_free_scan_temporary_data(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00941 { 00942 rf_mac_setup->scan_active = false; 00943 if (rf_mac_setup->mac_mlme_scan_resp) { 00944 mlme_scan_conf_t *r = rf_mac_setup->mac_mlme_scan_resp; 00945 tr_debug("%02x", r->ResultListSize); 00946 if( r->ED_values ){ 00947 ns_dyn_mem_free(r->ED_values); 00948 r->ED_values = NULL; 00949 } 00950 uint8_t i = 0; 00951 while (i < r->ResultListSize) { 00952 if (r->PAN_values[i]) { 00953 tr_debug("Free PAN result"); 00954 ns_dyn_mem_free(r->PAN_values[i]); 00955 } 00956 i++; 00957 } 00958 tr_debug("Free Response"); 00959 ns_dyn_mem_free(rf_mac_setup->mac_mlme_scan_resp); 00960 rf_mac_setup->mac_mlme_scan_resp = NULL; 00961 } 00962 } 00963 00964 void mac_mlme_set_active_state(protocol_interface_rf_mac_setup_s *entry, bool new_state) 00965 { 00966 if( entry ){ 00967 entry->macUpState = new_state; 00968 } 00969 } 00970 00971 void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_mac) 00972 { 00973 if (rf_mac) { 00974 if( rf_mac->dev_driver ){ 00975 rf_mac->dev_driver->phy_sap_identifier = NULL; 00976 rf_mac->dev_driver->phy_sap_upper_cb = NULL; 00977 } 00978 00979 eventOS_callback_timer_unregister(rf_mac->mlme_timer_id); 00980 eventOS_callback_timer_unregister(rf_mac->mac_timer_id); 00981 eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer); 00982 00983 ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf); 00984 ns_dyn_mem_free(rf_mac->mac_beacon_payload); 00985 00986 mac_sec_mib_deinit(rf_mac); 00987 ns_dyn_mem_free(rf_mac); 00988 } 00989 } 00990 00991 static uint8_t mac_backoff_ticks_calc(phy_device_driver_s * phy_driver) 00992 { 00993 //Calculate 20 symbol time which is typically 10 bytes 00994 const phy_device_channel_page_s *phy_channel_pages = phy_driver->phy_channel_pages; 00995 uint32_t datarate = dev_get_phy_datarate(phy_driver, phy_channel_pages->channel_page); 00996 if (datarate == 0) { 00997 datarate = 250000; 00998 } 00999 //How many 10us ticks backoff period is, assuming 4 bits per symbol (O-QPSK) 01000 unsigned int ticks = (2000000 / (datarate / 4)); 01001 if (ticks > 255) { 01002 ticks = 255; 01003 tr_warn("Backoff period too slow"); 01004 } 01005 return (uint8_t) ticks; 01006 } 01007 01008 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) 01009 { 01010 uint16_t total_length = 0; 01011 //allocate security 01012 if (!dev_driver || !mac64 || !dev_driver->phy_driver || !storage_sizes) { 01013 return NULL; 01014 } 01015 01016 protocol_interface_rf_mac_setup_s *entry = ns_dyn_mem_alloc(sizeof(protocol_interface_rf_mac_setup_s)); 01017 if (!entry) { 01018 return NULL; 01019 } 01020 //Init everything for 0, NULL or false 01021 memset(entry, 0, sizeof(protocol_interface_rf_mac_setup_s)); 01022 entry->ifs_timer_id = -1; 01023 entry->cca_timer_id = -1; 01024 entry->mlme_timer_id = -1; 01025 entry->mac_timer_id = -1; 01026 entry->bc_timer_id = -1; 01027 entry->mac_interface_id = -1; 01028 entry->dev_driver = dev_driver; 01029 entry->aUnitBackoffPeriod = 20; //This can be different in some Platform 20 comes from 12-symbol turnaround and 8 symbol CCA read 01030 01031 if (mac_sec_mib_init(entry, storage_sizes) != 0) { 01032 mac_mlme_data_base_deallocate(entry); 01033 return NULL; 01034 } 01035 01036 if (!dev_driver->phy_driver->phy_MTU) { 01037 mac_mlme_data_base_deallocate(entry); 01038 return NULL; 01039 } 01040 01041 //Allocate tx buffer by given MTU + header + tail 01042 total_length = dev_driver->phy_driver->phy_MTU; 01043 total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length); 01044 entry->dev_driver_tx_buffer.buf = ns_dyn_mem_alloc(total_length); 01045 if (!entry->dev_driver_tx_buffer.buf) { 01046 mac_mlme_data_base_deallocate(entry); 01047 return NULL; 01048 } 01049 01050 //allocate Beacon Payload buffer 01051 entry->max_beacon_payload_length = dev_driver->phy_driver->phy_MTU - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD; 01052 entry->mac_beacon_payload = ns_dyn_mem_alloc(entry->max_beacon_payload_length); 01053 if (!entry->mac_beacon_payload) { 01054 mac_mlme_data_base_deallocate(entry); 01055 return NULL; 01056 } 01057 01058 entry->mac_tasklet_id = mac_mcps_sap_tasklet_init(); 01059 if (entry->mac_tasklet_id < 0) { 01060 mac_mlme_data_base_deallocate(entry); 01061 return NULL; 01062 } 01063 01064 entry->mlme_timer_id = eventOS_callback_timer_register(mac_mlme_timer_cb); 01065 entry->mac_timer_id = eventOS_callback_timer_register(timer_mac_interrupt); 01066 entry->mac_mcps_timer = eventOS_callback_timer_register(mac_mcps_timer_cb); 01067 if (entry->mlme_timer_id == -1 || entry->mac_timer_id == -1 || entry->mac_mcps_timer == -1) { 01068 mac_mlme_data_base_deallocate(entry); 01069 return NULL; 01070 } 01071 entry->macCapRxOnIdle = true; 01072 entry->macCapSecrutityCapability = true; 01073 entry->pan_id = entry->mac_short_address = 0xffff; 01074 mac_extended_mac_set(entry, mac64); 01075 entry->mac_ack_wait_duration = MAC_ACK_WAIT_DURATION; 01076 entry->mac_mlme_retry_max = MAC_DEFAULT_MAX_FRAME_RETRIES; 01077 memset(entry->mac_default_key_source, 0xff, 8); 01078 memset(entry->mac_auto_request.Keysource, 0xff, 8); 01079 memset(entry->mac_beacon_payload, 0, entry->max_beacon_payload_length); 01080 entry->mac_auto_request.SecurityLevel = 6; 01081 entry->mac_auto_request.KeyIndex = 0xff; 01082 mac_pd_sap_rf_low_level_function_set(entry, entry->dev_driver); 01083 entry->mac_sequence = randLIB_get_8bit(); 01084 entry->mac_bea_sequence = randLIB_get_8bit(); 01085 entry->fhss_api = NULL; 01086 entry->macMinBE = 3; 01087 entry->macMaxBE = 5; 01088 entry->macMaxCSMABackoffs = MAC_CCA_MAX; 01089 entry->mac_mcps_timer_event.priority = ARM_LIB_LOW_PRIORITY_EVENT; 01090 entry->mac_mcps_timer_event.event_type = MAC_MCPS_INDIRECT_TIMER_CB; 01091 entry->mac_mcps_timer_event.data_ptr = entry; 01092 entry->mac_mcps_timer_event.receiver = entry->mac_tasklet_id; 01093 entry->mac_mcps_timer_event.sender = 0; 01094 entry->mac_mcps_timer_event.event_id = 0; 01095 bool rf_support = false; 01096 dev_driver->phy_driver->extension(PHY_EXTENSION_DYNAMIC_RF_SUPPORTED, (uint8_t*)&rf_support); 01097 entry->rf_csma_extension_supported = rf_support; 01098 if (entry->rf_csma_extension_supported) { 01099 entry->dev_driver->phy_driver->extension(PHY_EXTENSION_GET_SYMBOLS_PER_SECOND, (uint8_t*) &entry->symbol_rate); 01100 entry->symbol_time_us = 1000000 / entry->symbol_rate; 01101 tr_debug("SW-MAC driver support rf extension %"PRIu32" symbol/seconds %"PRIu32" us symbol time length", entry->symbol_rate, entry->symbol_time_us); 01102 } 01103 01104 //How many 10us ticks backoff period is for waiting 20symbols which is typically 10 bytes time 01105 entry->backoff_period_in_10us = mac_backoff_ticks_calc(dev_driver->phy_driver); 01106 return entry; 01107 } 01108 01109 uint8_t mac_mlme_set_new_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01110 { 01111 uint8_t ret_val = 0; 01112 01113 if (rf_setup) { 01114 rf_setup->mac_sequence++; 01115 ret_val = rf_setup->mac_sequence; 01116 } 01117 return ret_val; 01118 } 01119 01120 uint8_t mac_mlme_set_new_beacon_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01121 { 01122 uint8_t ret_val = 0; 01123 01124 if (rf_setup) { 01125 rf_setup->mac_bea_sequence++; 01126 ret_val = rf_setup->mac_bea_sequence; 01127 } 01128 return ret_val; 01129 } 01130 01131 static int8_t mac_mlme_set_panid(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t pan_id) 01132 { 01133 phy_device_driver_s *dev_driver = rf_setup->dev_driver->phy_driver; 01134 if (!dev_driver->address_write) { 01135 if (dev_driver->link_type == PHY_LINK_TUN) { 01136 rf_setup->pan_id = pan_id; 01137 return 0; 01138 } 01139 return -1; 01140 } 01141 01142 uint8_t temp_8[2]; 01143 rf_setup->pan_id = pan_id; 01144 common_write_16_bit(pan_id, temp_8); 01145 01146 return dev_driver->address_write(PHY_MAC_PANID, temp_8); 01147 } 01148 01149 static void mac_mle_write_mac16_to_phy(phy_device_driver_s *dev_driver, uint16_t mac16) 01150 { 01151 uint8_t temp[2]; 01152 common_write_16_bit(mac16, temp); 01153 if (dev_driver->address_write) { 01154 dev_driver->address_write(PHY_MAC_16BIT, temp); 01155 } 01156 } 01157 01158 static int8_t mac_mlme_set_mac16(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t mac16) 01159 { 01160 int8_t ret_val = -1; 01161 if (rf_setup) { 01162 01163 rf_setup->mac_short_address = mac16; 01164 //SET RF 16-bit 01165 if (mac16 > 0xfffd) { 01166 rf_setup->shortAdressValid = false; 01167 } else { 01168 rf_setup->shortAdressValid = true; 01169 } 01170 mac_mle_write_mac16_to_phy(rf_setup->dev_driver->phy_driver, mac16); 01171 ret_val = 0; 01172 } 01173 return ret_val; 01174 } 01175 01176 static void mac_mlme_write_mac64(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01177 { 01178 memcpy(addrPtr, rf_setup->mac64, 8); 01179 } 01180 01181 static void mac_mlme_write_mac16(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01182 { 01183 common_write_16_bit(rf_setup->mac_short_address, addrPtr); 01184 } 01185 01186 uint16_t mac_mlme_get_panid(protocol_interface_rf_mac_setup_s *rf_setup) 01187 { 01188 uint16_t panId = 0xffff; 01189 if (rf_setup) { 01190 panId = rf_setup->pan_id; 01191 } 01192 return panId; 01193 } 01194 01195 static bool add_or_update_beacon(mlme_scan_conf_t* conf, mlme_beacon_ind_t *data, fhss_api_t *fhss_api) 01196 { 01197 bool found = false; 01198 bool update_beacon = false; 01199 for( int i=0; i < conf->ResultListSize; i++){ 01200 mlme_pan_descriptor_t *cur_desc = conf->PAN_values[i]; 01201 if( !cur_desc ){ //Not an active or passive scan 01202 break; 01203 } 01204 /* When FHSS is enabled, logical channel check is not valid 01205 * as the Beacon can be sent on any enabled channel */ 01206 if (fhss_api || (cur_desc->LogicalChannel == data->PANDescriptor.LogicalChannel)) { 01207 if (cur_desc->CoordPANId == data->PANDescriptor.CoordPANId) { 01208 if (cur_desc->LinkQuality < data->PANDescriptor.LinkQuality) { 01209 cur_desc->CoordAddrMode = data->PANDescriptor.CoordAddrMode; 01210 memcpy(cur_desc->CoordAddress, data->PANDescriptor.CoordAddress, 8); 01211 cur_desc->LinkQuality = data->PANDescriptor.LinkQuality; 01212 update_beacon = true; 01213 } 01214 found = true; 01215 } 01216 } 01217 } 01218 if(!found && conf->ResultListSize != MLME_MAC_RES_SIZE_MAX) { 01219 mlme_pan_descriptor_t *desc = ns_dyn_mem_temporary_alloc(sizeof(mlme_pan_descriptor_t)); 01220 if( !desc ){ 01221 return false; 01222 } 01223 memset(desc, 0, sizeof(mlme_pan_descriptor_t)); 01224 mlme_pan_descriptor_t *dat = &data->PANDescriptor; 01225 01226 desc->CoordAddrMode = dat->CoordAddrMode; 01227 desc->CoordPANId = dat->CoordPANId; 01228 memcpy(desc->CoordAddress, dat->CoordAddress, 8); 01229 desc->LogicalChannel = dat->LogicalChannel; 01230 desc->ChannelPage = dat->ChannelPage; 01231 memcpy(desc->SuperframeSpec, dat->SuperframeSpec, 2); 01232 desc->GTSPermit = dat->GTSPermit; 01233 desc->LinkQuality = dat->LinkQuality; 01234 desc->Timestamp = dat->Timestamp; 01235 desc->SecurityFailure = dat->SecurityFailure; 01236 01237 desc->Key.SecurityLevel = dat->Key.SecurityLevel; 01238 desc->Key.KeyIdMode = dat->Key.KeyIdMode; 01239 desc->Key.KeyIndex = dat->Key.KeyIndex; 01240 memcpy(desc->Key.Keysource, dat->Key.Keysource, 8); 01241 01242 conf->PAN_values[conf->ResultListSize] = desc; 01243 conf->ResultListSize++; 01244 update_beacon = true; 01245 } 01246 return update_beacon; 01247 } 01248 01249 int mac_mlme_beacon_notify(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_beacon_ind_t *data) 01250 { 01251 bool update_beacon = true; 01252 bool contains_fhss_synch_info = false; 01253 if( !rf_mac_setup || !data){ 01254 return -1; 01255 } 01256 01257 /* Cut FHSS synchronization info from Beacon payload length. 01258 * Synchronization info is stored later in this function but 01259 * should not be delivered to upper layer as a part of Beacon payload. 01260 */ 01261 if (rf_mac_setup->fhss_api) { 01262 if (data->beacon_data_length > FHSS_SYNCH_INFO_START) { 01263 data->beacon_data_length -= FHSS_SYNCH_INFO_LENGTH; 01264 contains_fhss_synch_info = true; 01265 } else { 01266 // Received single channel Beacon when FHSS enabled. 01267 return 0; 01268 } 01269 } 01270 01271 mac_api_t *mac = get_sw_mac_api(rf_mac_setup); 01272 if (mac && mac->mlme_ind_cb) { 01273 mac->mlme_ind_cb(mac, MLME_BEACON_NOTIFY, data); 01274 } 01275 01276 tr_debug("Beacon Notify: %s", trace_array(data->beacon_data, data->beacon_data_length)); 01277 01278 if (rf_mac_setup->mac_mlme_scan_resp) { 01279 mlme_scan_conf_t* conf = rf_mac_setup->mac_mlme_scan_resp; 01280 update_beacon = add_or_update_beacon(conf, data, rf_mac_setup->fhss_api); 01281 } 01282 if (rf_mac_setup->fhss_api && (update_beacon == true)) { 01283 if (contains_fhss_synch_info == true) { 01284 // Assume synchronization info is found from the end of the Beacon payload 01285 uint8_t *synch_info_start = data->beacon_data + data->beacon_data_length; 01286 rf_mac_setup->fhss_api->receive_frame(rf_mac_setup->fhss_api, data->PANDescriptor.CoordPANId, data->PANDescriptor.CoordAddress, 01287 data->PANDescriptor.Timestamp, synch_info_start, FHSS_SYNCH_FRAME); 01288 } 01289 } 01290 01291 return 0; 01292 } 01293 01294 int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length) 01295 { 01296 (void) length; 01297 protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_driver_id(driver_id); 01298 if (!mac_setup) { 01299 return -1; 01300 } 01301 mlme_primitive primitive = (mlme_primitive) *data_ptr; 01302 if (primitive == MLME_SCAN) { 01303 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 01304 if (!resp) { 01305 return -1; 01306 } 01307 memset(resp, 0, sizeof(mlme_scan_conf_t)); 01308 resp->ScanType = MAC_ACTIVE_SCAN; 01309 mac_setup->mac_mlme_scan_resp = resp; 01310 mac_mlme_scan_confirmation_handle(mac_setup); 01311 } 01312 return 0; 01313 } 01314 01315 static void mac_mlme_start_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_start_conf_t *conf) 01316 { 01317 if (rf_ptr->tun_extension_rf_driver) { 01318 virtual_data_req_t start_conf; 01319 uint8_t buf_temp[2]; 01320 uint8_t payload_buf[2]; 01321 // Add some random data as empty payload is not allowed 01322 payload_buf[0] = 0; 01323 payload_buf[1] = 0; 01324 01325 memset(&start_conf, 0, sizeof(virtual_data_req_t)); 01326 buf_temp[0] = NAP_MLME_CONFIRM; 01327 buf_temp[1] = MLME_START; 01328 start_conf.parameters = buf_temp; 01329 start_conf.parameter_length = sizeof(buf_temp); 01330 start_conf.msdu = payload_buf; 01331 start_conf.msduLength = sizeof(payload_buf); 01332 01333 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&start_conf, rf_ptr->tun_extension_rf_driver->id); 01334 } else if (get_sw_mac_api(rf_ptr)) { 01335 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01336 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_START, conf); 01337 } 01338 } 01339 } 01340 01341 static void mac_mlme_scan_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_scan_conf_t *conf) 01342 { 01343 if (conf->ScanType == MAC_ACTIVE_SCAN) { 01344 tr_debug("Active Scan Result"); 01345 } else if (conf->ScanType == MAC_ED_SCAN_TYPE) { 01346 tr_debug("ED Scan Result"); 01347 } 01348 if (rf_ptr->tun_extension_rf_driver) { 01349 virtual_data_req_t scan_conf; 01350 uint8_t buf_temp[2]; 01351 uint8_t payload_buf[2]; 01352 // Add some random data as empty payload is not allowed 01353 payload_buf[0] = 0; 01354 payload_buf[1] = 0; 01355 01356 memset(&scan_conf, 0, sizeof(virtual_data_req_t)); 01357 buf_temp[0] = NAP_MLME_CONFIRM; 01358 buf_temp[1] = MLME_SCAN; 01359 scan_conf.parameters = buf_temp; 01360 scan_conf.parameter_length = sizeof(buf_temp); 01361 scan_conf.msdu = payload_buf; 01362 scan_conf.msduLength = sizeof(payload_buf); 01363 01364 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&scan_conf, rf_ptr->tun_extension_rf_driver->id); 01365 } else if (get_sw_mac_api(rf_ptr)) { 01366 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01367 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_SCAN, conf); 01368 } 01369 } 01370 } 01371 01372 void mac_mlme_scan_confirmation_handle(protocol_interface_rf_mac_setup_s *rf_ptr) 01373 { 01374 if( !rf_ptr ){ 01375 return; 01376 } 01377 mlme_scan_conf_t *r = rf_ptr->mac_mlme_scan_resp; 01378 01379 if (r) { 01380 mac_mlme_scan_confirm_handler(rf_ptr, r); 01381 } 01382 mac_mlme_free_scan_temporary_data(rf_ptr); 01383 } 01384 01385 void mac_mlme_mac_radio_disabled(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01386 { 01387 if( !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ){ 01388 return; 01389 } 01390 platform_enter_critical(); 01391 timer_mac_stop(rf_mac_setup); 01392 mac_mlme_rf_disable(rf_mac_setup); 01393 platform_exit_critical(); 01394 } 01395 01396 void mac_mlme_mac_radio_enable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01397 { 01398 if( !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver){ 01399 return; 01400 } 01401 platform_enter_critical(); 01402 mac_mlme_rf_receiver_enable(rf_mac_setup); 01403 platform_exit_critical(); 01404 } 01405 01406 static int8_t mac_mlme_rf_disable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01407 { 01408 int8_t ret_val = 0; 01409 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01410 if (!dev_driver->state_control) { 01411 if (dev_driver->link_type == PHY_LINK_TUN) { 01412 rf_mac_setup->macRfRadioOn = false; 01413 rf_mac_setup->macRfRadioTxActive = false; 01414 return 0; 01415 } 01416 return -1; 01417 } 01418 if (rf_mac_setup->macRfRadioOn) { 01419 ret_val = dev_driver->state_control(PHY_INTERFACE_DOWN, 0); 01420 rf_mac_setup->macRfRadioOn = false; 01421 rf_mac_setup->macRfRadioTxActive = false; 01422 } 01423 01424 return ret_val; 01425 } 01426 01427 static int8_t mac_mlme_rf_receiver_enable(struct protocol_interface_rf_mac_setup *rf_mac_setup) 01428 { 01429 int8_t retval; 01430 01431 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01432 if (!dev_driver->state_control) { 01433 if (dev_driver->link_type == PHY_LINK_TUN) { 01434 rf_mac_setup->macRfRadioOn = true; 01435 return 0; 01436 } 01437 return -1; 01438 } 01439 01440 if (rf_mac_setup->macRfRadioOn) { 01441 return 0; 01442 } 01443 01444 if (rf_mac_setup->macProminousMode) { 01445 tr_debug("Sniffer mode"); 01446 retval = dev_driver->state_control(PHY_INTERFACE_SNIFFER_STATE, rf_mac_setup->mac_channel); 01447 } else { 01448 retval = dev_driver->state_control(PHY_INTERFACE_UP, rf_mac_setup->mac_channel); 01449 } 01450 rf_mac_setup->macRfRadioOn = true; 01451 //tr_debug("Enable radio with channel %u", rf_mac_setup->mac_channel); 01452 return retval; 01453 } 01454 01455 /** 01456 * Initialize MAC channel selection sequence 01457 * 01458 * TODO: initialize channel select sequence 01459 * in coordinator mode 01460 * 01461 * \param new_channel channel to set 01462 * 01463 * \return 0 success 01464 * \return -1 HW error 01465 */ 01466 static int8_t mac_mlme_rf_channel_set(struct protocol_interface_rf_mac_setup *rf_setup, uint8_t new_channel) 01467 { 01468 if (new_channel == rf_setup->mac_channel) { 01469 return 0; 01470 } 01471 mac_pre_build_frame_t *buf; 01472 01473 //Disable allways 01474 mac_mlme_mac_radio_disabled(rf_setup); 01475 buf = rf_setup->active_pd_data_request; 01476 rf_setup->active_pd_data_request = NULL; 01477 //Set Channel 01478 rf_setup->mac_channel = new_channel; 01479 //Enable Radio 01480 mac_mlme_mac_radio_enable(rf_setup); 01481 if (buf) { 01482 mcps_sap_pd_req_queue_write(rf_setup, buf); 01483 } 01484 01485 return 0; 01486 } 01487 01488 /** 01489 * MAC channel change 01490 * 01491 * \param new_channel channel to set 01492 * 01493 * \return 0 success 01494 * \return -1 error 01495 */ 01496 int8_t mac_mlme_rf_channel_change(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t new_channel) 01497 { 01498 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01499 return -1; 01500 } 01501 01502 if (!rf_mac_setup->dev_driver->phy_driver->extension) { 01503 if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_TUN) { 01504 rf_mac_setup->mac_channel = new_channel; 01505 return 0; 01506 } 01507 return -1; 01508 } 01509 if (new_channel == rf_mac_setup->mac_channel) { 01510 return 0; 01511 } 01512 platform_enter_critical(); 01513 rf_mac_setup->mac_channel = new_channel; 01514 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CHANNEL, &rf_mac_setup->mac_channel); 01515 platform_exit_critical(); 01516 return 0; 01517 } 01518 01519 void mac_mlme_poll_process_confirm(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t status) 01520 { 01521 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01522 return; 01523 } 01524 01525 //Free active Data buffer 01526 if (rf_mac_setup->active_pd_data_request) { 01527 mcps_sap_prebuild_frame_buffer_free(rf_mac_setup->active_pd_data_request); 01528 rf_mac_setup->active_pd_data_request = NULL; 01529 } 01530 //Disable timer 01531 rf_mac_setup->macWaitingData = false; 01532 rf_mac_setup->macDataPollReq = false; 01533 rf_mac_setup->macRxDataAtPoll = false; 01534 01535 if (!rf_mac_setup->macCapRxOnIdle) { 01536 //Disable Radio If we are RX off at idle device 01537 //tr_debug("disbale by aceptance data"); 01538 if (!rf_mac_setup->macRfRadioTxActive ) { 01539 //Disable radio if no active TX and radio is enabled 01540 //tr_debug("RF disable"); 01541 mac_mlme_mac_radio_disabled(rf_mac_setup); 01542 } 01543 } 01544 01545 mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup); 01546 if( mac_api ) { 01547 mlme_poll_conf_t confirm; 01548 confirm.status = status; 01549 mac_api->mlme_conf_cb(mac_api,MLME_POLL, &confirm); 01550 } 01551 //Trig Packet from queue 01552 mac_mcps_trig_buffer_from_queue(rf_mac_setup); 01553 01554 } 01555 01556 void mac_mlme_poll_req(protocol_interface_rf_mac_setup_s *cur, const mlme_poll_t *poll_req) 01557 { 01558 if( !cur || !poll_req ){ 01559 return; 01560 } 01561 if (cur->macDataPollReq ) { 01562 tr_debug("Poll Active do not start new"); 01563 return; 01564 } 01565 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0); 01566 if (!buf) { 01567 tr_debug("No mem for data Req"); 01568 //Confirmation call here 01569 return; 01570 } 01571 01572 buf->fcf_dsn.frametype = FC_CMD_FRAME; 01573 buf->fcf_dsn.ackRequested = true; 01574 buf->fcf_dsn.intraPan = true; 01575 01576 buf->DstPANId = poll_req->CoordPANId; 01577 buf->SrcPANId = poll_req->CoordPANId; 01578 buf->fcf_dsn.DstAddrMode = poll_req->CoordAddrMode; 01579 memcpy(buf->DstAddr, poll_req->CoordAddress, 8); 01580 01581 buf->mac_command_id = MAC_DATA_REQ; 01582 buf->mac_payload = &buf->mac_command_id; 01583 buf->mac_payload_length = 1; 01584 buf->mac_header_length_with_security = 3; 01585 01586 mac_header_security_parameter_set(&buf->aux_header, &poll_req->Key); 01587 01588 if (buf->aux_header.securityLevel) { 01589 buf->fcf_dsn.securityEnabled = true; 01590 buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; 01591 01592 } 01593 cur->macDataPollReq = true; 01594 cur->macWaitingData = true; 01595 cur->macRxDataAtPoll = false; 01596 01597 buf->security_mic_len = mac_security_mic_length_get(buf->aux_header.securityLevel); 01598 buf->mac_header_length_with_security += mac_header_security_aux_header_length(buf->aux_header.securityLevel, buf->aux_header.KeyIdMode); 01599 01600 if ( cur->mac_short_address > 0xfffd ) { 01601 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01602 } else { 01603 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01604 } 01605 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, cur, buf->SrcAddr); 01606 //Check PanID presents at header 01607 buf->fcf_dsn.DstPanPresents = mac_dst_panid_present(&buf->fcf_dsn); 01608 buf->fcf_dsn.SrcPanPresents = mac_src_panid_present(&buf->fcf_dsn); 01609 buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn); 01610 buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; 01611 mcps_sap_pd_req_queue_write(cur, buf); 01612 } 01613 01614 static bool mac_mlme_beacon_at_queue(protocol_interface_rf_mac_setup_s *rf_ptr) { 01615 mac_pre_build_frame_t *buf = rf_ptr->active_pd_data_request; 01616 if (buf && buf->fcf_dsn.frametype == FC_BEACON_FRAME ) { 01617 return true; 01618 } 01619 01620 buf = rf_ptr->pd_data_request_queue_to_go; 01621 01622 while(buf) { 01623 if (buf->fcf_dsn.frametype == FC_BEACON_FRAME ) { 01624 return true; 01625 } 01626 buf = buf->next; 01627 } 01628 return false; 01629 } 01630 01631 int8_t mac_mlme_beacon_tx(protocol_interface_rf_mac_setup_s *rf_ptr) 01632 { 01633 if (!rf_ptr || !rf_ptr->macCapCordinator) { 01634 return -1; 01635 } 01636 01637 //Verify if beacon is already generated to queue 01638 if (mac_mlme_beacon_at_queue(rf_ptr)) { 01639 return -2; 01640 } 01641 01642 uint16_t length = 4; 01643 length += rf_ptr->mac_beacon_payload_size; 01644 // Add more space for FHSS synchronization info 01645 if (rf_ptr->fhss_api) { 01646 length += FHSS_SYNCH_INFO_LENGTH; 01647 } 01648 /* if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01649 length += 2; 01650 }*/ 01651 01652 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(length); 01653 if(!buf) { 01654 return -1; 01655 } 01656 uint8_t sf_2 = 0x0f; 01657 01658 buf->fcf_dsn.frametype = FC_BEACON_FRAME; 01659 buf->fcf_dsn.DstAddrMode = MAC_ADDR_MODE_NONE; 01660 01661 if (rf_ptr->beaconSrcAddressModeLong) { 01662 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01663 buf->mac_header_length_with_security = 13; 01664 } else { 01665 if (rf_ptr->shortAdressValid) { 01666 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01667 buf->mac_header_length_with_security = 7; 01668 } else { 01669 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01670 buf->mac_header_length_with_security = 13; 01671 } 01672 } 01673 buf->SrcPANId = mac_mlme_get_panid(rf_ptr); 01674 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, rf_ptr, buf->SrcAddr); 01675 buf->fcf_dsn.DstPanPresents = false; 01676 buf->fcf_dsn.SrcPanPresents = true; 01677 01678 uint8_t *ptr = buf->mac_payload; 01679 01680 *ptr++ = 0xff;//Superframe disabled 01681 01682 if (rf_ptr->macCapCordinator) { 01683 sf_2 |= 0x40; //Cord 01684 } 01685 01686 if (rf_ptr->macCapBatteryPowered) { 01687 sf_2 |= 0x10; //Battery 01688 } 01689 01690 if (rf_ptr->macCapAssocationPermit) { 01691 sf_2 |= 0x80; //Permit 01692 } 01693 *ptr++ = sf_2; //Superframe desc MSB 01694 ptr = common_write_16_bit(0, ptr); //NO GTS Support 01695 01696 if (rf_ptr->mac_beacon_payload_size) { 01697 memcpy(ptr, rf_ptr->mac_beacon_payload, rf_ptr->mac_beacon_payload_size); 01698 01699 /*if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01700 uint8_t beacon_join_priority = rf_ptr->beacon_join_priority_tx_cb_ptr(rf_ptr->mac_interface_id); 01701 ptr[PLAIN_BEACON_PAYLOAD_SIZE] = BEACON_OPTION_JOIN_PRIORITY_TYPE_LEN; 01702 ptr[PLAIN_BEACON_PAYLOAD_SIZE + 1] = beacon_join_priority; 01703 ptr += BEACON_OPTION_JOIN_PRIORITY_LEN; 01704 }*/ 01705 } 01706 buf->priority = MAC_PD_DATA_HIGH_PRIOTITY; 01707 01708 tr_debug("BEA tx"); 01709 mcps_sap_pd_req_queue_write(rf_ptr, buf); 01710 sw_mac_stats_update(rf_ptr, STAT_MAC_BEA_TX_COUNT, 0); 01711 return 0; 01712 } 01713
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2