BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
mac_mlme.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 2013-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /** 00018 * 00019 * \file mac_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 static uint16_t mlme_scan_analyze_next_channel(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00089 { 00090 uint8_t i, j = 0, k = 1; 00091 uint32_t mask = 1; 00092 uint32_t *channel_mask = rf_mac_setup->mac_channel_list.channel_mask; 00093 00094 if (rf_mac_setup->mac_channel_list.channel_page == CHANNEL_PAGE_9 || 00095 rf_mac_setup->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 00232 tr_debug("BEA REQ tx"); 00233 mcps_sap_pd_req_queue_write(rf_ptr, buf); 00234 return 1; 00235 } 00236 return 0; 00237 } 00238 00239 static void mac_mlme_scan_init(uint8_t channel, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00240 { 00241 mac_mlme_calc_scan_duration(rf_mac_setup, channel); 00242 00243 switch (rf_mac_setup->scan_type) { 00244 /* ED Scan */ 00245 case MAC_ED_SCAN_TYPE: 00246 //tr_debug("Energy Scan"); 00247 rf_mac_setup->max_ED = 0; 00248 mac_mlme_energy_scan_start(rf_mac_setup, channel); 00249 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_ED_ANALYZE; 00250 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 96); 00251 break; 00252 case MAC_PASSIVE_SCAN: 00253 case MAC_ACTIVE_SCAN: /*Active*/ 00254 tr_debug("Scan channel %u", channel); 00255 rf_mac_setup->mac_channel = channel; 00256 rf_mac_setup->macCapRxOnIdle = true; 00257 mac_mlme_start_request(rf_mac_setup); 00258 if (rf_mac_setup->scan_type == MAC_ACTIVE_SCAN) { 00259 mac_pre_build_frame_t *active_buf = rf_mac_setup->active_pd_data_request; 00260 /* If there is active data request, it must be Beacon request which were failed to send on previous channel. 00261 * Do not push new Beacon request to queue as the MAC will try to send the current active data request anyway. 00262 */ 00263 if (!active_buf || (active_buf && active_buf->fcf_dsn.frametype != FC_CMD_FRAME)) { 00264 mac_mlme_beacon_req_tx(rf_mac_setup); 00265 } 00266 } 00267 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00268 rf_mac_setup->mlme_tick_count = rf_mac_setup->mlme_ED_counter; 00269 //tr_debug("mlme_tick_count: %x", rf_mac_setup->mlme_tick_count); 00270 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 300); 00271 break; 00272 case MAC_ORPHAN_SCAN: /*Orphan*/ 00273 break; 00274 } 00275 } 00276 00277 static void mac_mlme_scan_start(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00278 { 00279 uint8_t channel; 00280 00281 channel = (uint8_t) mlme_scan_analyze_next_channel(rf_mac_setup); 00282 mac_mlme_scan_init(channel, rf_mac_setup); 00283 } 00284 00285 static bool mac_channel_list_validate(const channel_list_s *list, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00286 { 00287 if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_15_4_2_4GHZ_TYPE && 00288 list->channel_page == 0) { 00289 //Accept only Channels channels 11-26 00290 if (list->channel_mask[0] & 0x7fff800) { 00291 return true; 00292 } 00293 return false; 00294 } 00295 else if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_15_4_SUBGHZ_TYPE && 00296 (list->channel_page == 0 || list->channel_page == 1 || list->channel_page == 2)) { 00297 if (list->channel_mask[0] & 0x000007ff) { 00298 return true; 00299 } 00300 00301 return false; 00302 } else { 00303 for (int i=0; i < 8; i++) { 00304 if (list->channel_mask[i]) { 00305 return true; 00306 } 00307 } 00308 } 00309 00310 return false; 00311 } 00312 00313 static int mac_mlme_generate_scan_confirmation(mlme_scan_conf_t *conf, const mlme_scan_t *msg, uint8_t status) 00314 { 00315 memset(conf, 0, sizeof(mlme_scan_conf_t)); 00316 conf->status = status; 00317 if (!msg) { 00318 return -1; 00319 } 00320 conf->ScanType = msg->ScanType; 00321 conf->ChannelPage = msg->ChannelPage; 00322 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00323 /*If the scan is successful, this value will be modified properly in mlme_analyze_next_channel() 00324 and assigned in mlme_scan_operation()*/ 00325 conf->UnscannedChannels.channel_mask[0] = msg->ScanChannels.channel_mask[0]; 00326 } else if (msg->ScanType == MAC_ED_SCAN_TYPE) { 00327 conf->ED_values = ns_dyn_mem_temporary_alloc(MLME_MAC_RES_SIZE_MAX); 00328 if (!conf->ED_values) { 00329 tr_debug("Could not allocate memory for ED values"); 00330 conf->status = MLME_SUCCESS; 00331 return -2; 00332 } 00333 memset(conf->ED_values, 0, MLME_MAC_RES_SIZE_MAX); 00334 } 00335 return 0; 00336 } 00337 00338 void mac_mlme_scan_request(const mlme_scan_t *msg, protocol_interface_rf_mac_setup_s *rf_mac_setup) 00339 { 00340 if (rf_mac_setup->mac_mlme_scan_resp){ 00341 mlme_scan_conf_t conf; 00342 mac_mlme_generate_scan_confirmation(&conf, msg, MLME_SCAN_IN_PROGRESS); 00343 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00344 ns_dyn_mem_free(conf.ED_values); 00345 return; 00346 } 00347 00348 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 00349 if (!resp) { 00350 mlme_scan_conf_t conf; 00351 tr_error("Mac Scan request fail, no memory"); 00352 mac_mlme_generate_scan_confirmation(&conf, NULL, MLME_SUCCESS); 00353 mac_mlme_scan_confirm_handler(rf_mac_setup, &conf); 00354 ns_dyn_mem_free(conf.ED_values); 00355 return; 00356 } 00357 00358 rf_mac_setup->mac_mlme_scan_resp = resp; 00359 //Validate channel list 00360 tr_debug("chan page %u, mask %"PRIx32, msg->ScanChannels.channel_page, msg->ScanChannels.channel_mask[0]); 00361 if (!mac_channel_list_validate(&msg->ScanChannels, rf_mac_setup)) { 00362 tr_debug("Unsupported channel list"); 00363 mac_mlme_generate_scan_confirmation(resp, msg, MLME_INVALID_PARAMETER); 00364 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00365 return; 00366 } 00367 00368 if (mac_mlme_generate_scan_confirmation(resp, msg, MLME_SUCCESS) != 0) { 00369 return; 00370 } 00371 00372 tr_debug("MAC: Start MLME scan"); 00373 00374 if (mac_mlme_rf_disable(rf_mac_setup) == 0) { 00375 rf_mac_setup->macCapRxOnIdle = false; 00376 if (msg->ScanType == MAC_ACTIVE_SCAN) { 00377 rf_mac_setup->macUpState = true; 00378 } 00379 } else { 00380 tr_error("Failed to disable RF"); 00381 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00382 return; 00383 } 00384 00385 rf_mac_setup->scan_type = msg->ScanType; 00386 rf_mac_setup->scan_duration = msg->ScanDuration; 00387 rf_mac_setup->mac_channel_list = msg->ScanChannels; 00388 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00389 rf_mac_setup->scan_active = true; 00390 mac_mlme_scan_start(rf_mac_setup); 00391 } 00392 00393 int8_t mac_mlme_start_req(const mlme_start_t *s, struct protocol_interface_rf_mac_setup *rf_mac_setup) 00394 { 00395 if (!s || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 00396 return -1; 00397 } 00398 00399 tr_debug("MAC: Start network %u channel %x panid", s->LogicalChannel, s->PANId); 00400 mac_mlme_set_panid(rf_mac_setup, s->PANId); 00401 // Synchronize FHSS 00402 if (rf_mac_setup->fhss_api) { 00403 rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_SYNCHRONIZED, s->PANId); 00404 } 00405 00406 if (!rf_mac_setup->fhss_api) { 00407 rf_mac_setup->mac_channel = s->LogicalChannel; 00408 } 00409 mac_mlme_start_request(rf_mac_setup); 00410 if (s->PANCoordinator) { 00411 //tr_debug("Cordinator"); 00412 rf_mac_setup->macCapCordinator = true; 00413 rf_mac_setup->macCapRxOnIdle = true; 00414 } else { 00415 rf_mac_setup->macCapCordinator = false; 00416 } 00417 00418 if (s->BatteryLifeExtension) { 00419 rf_mac_setup->macCapBatteryPowered = true; 00420 } else { 00421 rf_mac_setup->macCapBatteryPowered = false; 00422 } 00423 mlme_start_conf_t conf; 00424 conf.status = MLME_SUCCESS; 00425 mac_mlme_start_confirm_handler(rf_mac_setup, &conf); 00426 return 0; 00427 } 00428 00429 int8_t mac_mlme_reset(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_reset_t *reset) { 00430 if (!reset || !rf_mac_setup) { 00431 return -1; 00432 } 00433 00434 // Stop FHSS 00435 if (rf_mac_setup->fhss_api) { 00436 rf_mac_setup->fhss_api->synch_state_set(rf_mac_setup->fhss_api, FHSS_UNSYNCHRONIZED, 0); 00437 } 00438 00439 mac_mlme_timers_disable(rf_mac_setup); 00440 mac_mlme_mac_radio_disabled(rf_mac_setup); 00441 mac_mlme_set_active_state(rf_mac_setup, false); 00442 mac_mlme_free_scan_temporary_data(rf_mac_setup); 00443 mac_mcps_buffer_queue_free(rf_mac_setup); 00444 rf_mac_setup->macProminousMode = false; 00445 rf_mac_setup->macWaitingData = false; 00446 rf_mac_setup->macDataPollReq = false; 00447 rf_mac_setup->macRxDataAtPoll = false; 00448 //Clean MAC 00449 if (reset->SetDefaultPIB) { 00450 tr_debug("RESET MAC PIB"); 00451 rf_mac_setup->mac_short_address = 0xffff; 00452 rf_mac_setup->pan_id = 0xffff; 00453 rf_mac_setup->macCapRxOnIdle = true; 00454 rf_mac_setup->mac_security_enabled = false; 00455 rf_mac_setup->macCapCordinator = false; 00456 rf_mac_setup->mac_mlme_retry_max = MAC_DEFAULT_MAX_FRAME_RETRIES; 00457 } 00458 00459 return 0; 00460 } 00461 00462 00463 static int8_t mac_mlme_boolean_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,mlme_attr_t attribute ,bool value) 00464 { 00465 switch (attribute) { 00466 case macSecurityEnabled: 00467 rf_mac_setup->mac_security_enabled = value; 00468 break; 00469 00470 case macRxOnWhenIdle: 00471 rf_mac_setup->macCapRxOnIdle = value; 00472 break; 00473 00474 case macPromiscuousMode: 00475 rf_mac_setup->macProminousMode = value; 00476 break; 00477 00478 case macGTSPermit: 00479 rf_mac_setup->macGTSPermit = value; 00480 break; 00481 00482 case macAssociationPermit: 00483 rf_mac_setup->macCapAssocationPermit = value; 00484 break; 00485 case macThreadForceLongAddressForBeacon: 00486 rf_mac_setup->beaconSrcAddressModeLong = value; 00487 break; 00488 00489 case macAssociatedPANCoord: 00490 00491 break; 00492 00493 case macTimestampSupported: 00494 00495 break; 00496 00497 case macBattLifeExt: 00498 00499 break; 00500 00501 case macAutoRequest: 00502 00503 break; 00504 00505 case macLoadBalancingAcceptAnyBeacon: 00506 rf_mac_setup->macAcceptAnyBeacon = value; 00507 if (rf_mac_setup->dev_driver->phy_driver->extension) { 00508 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_ACCEPT_ANY_BEACON, (uint8_t*)&value); 00509 } 00510 break; 00511 00512 default: 00513 return -1; 00514 } 00515 return 0; 00516 } 00517 00518 static int8_t mac_mlme_16bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,mlme_attr_t attribute, uint16_t value) 00519 { 00520 switch (attribute) { 00521 case macCoordShortAddress: 00522 rf_mac_setup->coord_short_address = value; 00523 break; 00524 case macPANId: 00525 mac_mlme_set_panid(rf_mac_setup, value); 00526 break; 00527 00528 case macShortAddress: 00529 mac_mlme_set_mac16(rf_mac_setup, value); 00530 break; 00531 00532 case macSyncSymbolOffset: 00533 //TODO: change this to return real error 00534 //This is read only 00535 break; 00536 00537 case macTransactionPersistenceTime: 00538 //TODO: check this also 00539 break; 00540 00541 default: 00542 return -1; 00543 } 00544 return 0; 00545 } 00546 00547 static int8_t mac_mlme_8bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,mlme_attr_t attribute ,uint8_t value) 00548 { 00549 switch (attribute) { 00550 case phyCurrentChannel: 00551 mac_mlme_rf_channel_set(rf_mac_setup, value); 00552 break; 00553 case macBeaconPayloadLength: 00554 if (rf_mac_setup->max_beacon_payload_length < value) { 00555 return -1; 00556 } 00557 00558 rf_mac_setup->mac_beacon_payload_size = value; 00559 break; 00560 case macAutoRequestKeyIndex: 00561 rf_mac_setup->mac_auto_request.KeyIndex = value; 00562 break; 00563 00564 case macAutoRequestKeyIdMode: 00565 rf_mac_setup->mac_auto_request.KeyIdMode = value; 00566 break; 00567 00568 case macAutoRequestSecurityLevel: 00569 rf_mac_setup->mac_auto_request.SecurityLevel = value; 00570 break; 00571 case macMaxFrameRetries: 00572 if (value > 7) { 00573 return -1; 00574 } 00575 rf_mac_setup->mac_mlme_retry_max = value; 00576 break; 00577 00578 case macMinBE: 00579 if (value > rf_mac_setup->macMaxBE) { 00580 rf_mac_setup->macMinBE = value; 00581 } 00582 break; 00583 00584 case macMaxBE: 00585 if (value > 8 || value < 3) { 00586 return -1; 00587 } 00588 rf_mac_setup->macMaxBE = value; 00589 break; 00590 00591 case macMaxCSMABackoffs: 00592 if (value > 8 ) { 00593 return -1; 00594 } 00595 rf_mac_setup->macMaxCSMABackoffs = value; 00596 break; 00597 00598 default: 00599 return -1; 00600 } 00601 return 0; 00602 } 00603 00604 static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint32_t value) 00605 { 00606 (void)rf_mac_setup; 00607 (void) value; 00608 switch (attribute) { 00609 case macFrameCounter: 00610 rf_mac_setup->security_frame_counter = value; 00611 break; 00612 00613 default: 00614 return -1; 00615 } 00616 return 0; 00617 } 00618 00619 void mac_extended_mac_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *mac64) 00620 { 00621 if( !mac64 || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ){ 00622 return; 00623 } 00624 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 00625 memcpy(rf_mac_setup->mac64, mac64, 8); //This should be random 00626 if (dev_driver->address_write) { 00627 dev_driver->address_write(PHY_MAC_64BIT, rf_mac_setup->mac64); 00628 } 00629 } 00630 00631 static int8_t mac_mlme_device_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00632 00633 if (set_req->value_size != sizeof(mlme_device_descriptor_t)) { 00634 return -1; 00635 } 00636 00637 return mac_sec_mib_device_description_set(set_req->attr_index,(mlme_device_descriptor_t *) set_req->value_pointer , rf_mac_setup); 00638 } 00639 00640 static int8_t mac_mlme_key_description_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00641 if (set_req->value_size != sizeof(mlme_key_descriptor_entry_t)) { 00642 return -1; 00643 } 00644 00645 return mac_sec_mib_key_description_set(set_req->attr_index,(mlme_key_descriptor_entry_t *) set_req->value_pointer , rf_mac_setup); 00646 } 00647 00648 static int8_t mac_mlme_default_key_source_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) { 00649 if (set_req->value_size != 8) { 00650 return -1; 00651 } 00652 if (set_req->attr == macDefaultKeySource) { 00653 memcpy(rf_mac_setup->mac_default_key_source, (uint8_t *)set_req->value_pointer, 8); 00654 } else { 00655 memcpy(rf_mac_setup->mac_auto_request.Keysource, (uint8_t *)set_req->value_pointer, 8); 00656 } 00657 return 0; 00658 } 00659 00660 static int8_t mac_mlme_beacon_payload_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, const mlme_set_t *set_req) 00661 { 00662 if (set_req->value_size > rf_mac_setup->max_beacon_payload_length) { 00663 return -1; 00664 } 00665 00666 memcpy(rf_mac_setup->mac_beacon_payload, set_req->value_pointer, set_req->value_size); 00667 memset(rf_mac_setup->mac_beacon_payload + set_req->value_size, 0, rf_mac_setup->max_beacon_payload_length - set_req->value_size); 00668 00669 return 0; 00670 } 00671 00672 static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) 00673 { 00674 if (set_req->value_size == 1) { 00675 const bool *pbool = set_req->value_pointer; 00676 //Check first boolean 00677 if (mac_mlme_boolean_set(rf_mac_setup,set_req->attr, *pbool) == 0) { 00678 return 0; 00679 } 00680 const uint8_t *pu8 = set_req->value_pointer; 00681 return mac_mlme_8bit_set(rf_mac_setup,set_req->attr, *pu8); 00682 00683 } else if (set_req->value_size == 2) { 00684 const uint16_t *pu16 = set_req->value_pointer; 00685 return mac_mlme_16bit_set(rf_mac_setup,set_req->attr, *pu16); 00686 } else if (set_req->value_size == 4) { 00687 const uint32_t *pu32 = set_req->value_pointer; 00688 return mac_mlme_32bit_set(rf_mac_setup,set_req->attr, *pu32); 00689 } 00690 return -1; 00691 } 00692 00693 int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup,const mlme_set_t *set_req) 00694 { 00695 if (!set_req || !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ) { 00696 return -1; 00697 } 00698 00699 switch (set_req->attr) { 00700 case macDeviceTable: 00701 return mac_mlme_device_description_set(rf_mac_setup, set_req); 00702 case macKeyTable: 00703 return mac_mlme_key_description_set(rf_mac_setup, set_req); 00704 case macDefaultKeySource: 00705 case macAutoRequestKeySource: 00706 return mac_mlme_default_key_source_set(rf_mac_setup, set_req); 00707 case macBeaconPayload: 00708 return mac_mlme_beacon_payload_set(rf_mac_setup, set_req); 00709 case macLoadBalancingBeaconTx: 00710 return mac_mlme_beacon_tx(rf_mac_setup); 00711 case macCoordExtendedAddress: 00712 if( set_req->value_size == 8) { 00713 memcpy(rf_mac_setup->coord_long_address, set_req->value_pointer, 8); 00714 } 00715 return 0; 00716 default: 00717 return mac_mlme_handle_set_values(rf_mac_setup, set_req); 00718 } 00719 } 00720 00721 int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req) 00722 { 00723 if (!get_req || !rf_mac_setup ) { 00724 return -1; 00725 } 00726 00727 switch (get_req->attr) { 00728 case macDeviceTable: 00729 get_req->value_pointer = mac_sec_mib_device_description_get_attribute_index(rf_mac_setup, get_req->attr_index); 00730 if (get_req->value_pointer) { 00731 get_req->value_size = sizeof(mlme_device_descriptor_t); 00732 } else { 00733 get_req->status = MLME_INVALID_INDEX; 00734 } 00735 break; 00736 00737 case macMaxFrameRetries: 00738 get_req->value_pointer = &rf_mac_setup->mac_mlme_retry_max; 00739 get_req->value_size = 1; 00740 break; 00741 00742 case macFrameCounter: 00743 get_req->value_pointer = &rf_mac_setup->security_frame_counter; 00744 get_req->value_size = 4; 00745 break; 00746 00747 default: 00748 get_req->status = MLME_UNSUPPORTED_ATTRIBUTE; 00749 break; 00750 00751 } 00752 return 0; 00753 } 00754 00755 static void mlme_scan_operation(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00756 { 00757 uint16_t channel; 00758 mlme_scan_conf_t *resp = rf_mac_setup->mac_mlme_scan_resp; 00759 00760 if (rf_mac_setup->scan_type == MAC_ED_SCAN_TYPE) { 00761 resp->ED_values[resp->ResultListSize] = rf_mac_setup->max_ED; 00762 resp->ResultListSize++; 00763 } 00764 00765 channel = mlme_scan_analyze_next_channel(rf_mac_setup); 00766 if (channel > 0xff || rf_mac_setup->mac_mlme_scan_resp->ResultListSize == MLME_MAC_RES_SIZE_MAX) { 00767 resp->status = MLME_SUCCESS; 00768 tr_debug("Scan Complete..Halt MAC"); 00769 platform_enter_critical(); 00770 mac_mlme_mac_radio_disabled(rf_mac_setup); 00771 if (resp->ResultListSize == 0 && rf_mac_setup->scan_type == MAC_ACTIVE_SCAN) { 00772 resp->status = MLME_NO_BEACON; 00773 }else if( resp->ResultListSize == MLME_MAC_RES_SIZE_MAX ){ 00774 resp->status = MLME_LIMIT_REACHED; 00775 } 00776 resp->UnscannedChannels.channel_mask[0] = rf_mac_setup->mac_channel_list.channel_mask[0]; 00777 platform_exit_critical(); 00778 //Scan Confirmation 00779 mac_generic_event_trig(MAC_MLME_SCAN_CONFIRM_HANDLER, rf_mac_setup, false); 00780 tr_debug("Trig confirm"); 00781 rf_mac_setup->scan_active = false; 00782 } else { 00783 mac_mlme_scan_init((uint8_t) channel, rf_mac_setup); 00784 } 00785 } 00786 00787 void mac_frame_src_address_set_from_interface(uint8_t SrcAddrMode,protocol_interface_rf_mac_setup_s *rf_ptr, uint8_t *addressPtr) 00788 { 00789 if( !rf_ptr ){ 00790 return; 00791 } 00792 if (SrcAddrMode == MAC_ADDR_MODE_16_BIT) { 00793 mac_mlme_write_mac16(rf_ptr, addressPtr); 00794 } else if (SrcAddrMode == MAC_ADDR_MODE_64_BIT) { 00795 mac_mlme_write_mac64(rf_ptr, addressPtr); 00796 } 00797 } 00798 00799 void mac_mlme_active_scan_response_timer_start(void *interface) 00800 { 00801 if (interface) { 00802 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s *)interface; 00803 if (rf_mac_setup) { 00804 if (rf_mac_setup->mac_mlme_event == ARM_NWK_MAC_MLME_SCAN) { 00805 eventOS_callback_timer_stop(rf_mac_setup->mlme_timer_id); 00806 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00807 rf_mac_setup->mlme_tick_count = rf_mac_setup->mlme_ED_counter; 00808 00809 eventOS_callback_timer_start(rf_mac_setup->mlme_timer_id, 300); 00810 } 00811 } 00812 } 00813 } 00814 00815 static void mac_mlme_timers_disable(protocol_interface_rf_mac_setup_s *rf_ptr) 00816 { 00817 platform_enter_critical(); 00818 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00819 eventOS_callback_timer_stop(rf_ptr->mlme_timer_id); 00820 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00821 } 00822 timer_mac_stop(rf_ptr); 00823 platform_exit_critical(); 00824 } 00825 00826 void mac_mlme_event_cb(void *mac_ptr) 00827 { 00828 protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*) mac_ptr; 00829 if (!rf_mac_setup) { 00830 return; 00831 } 00832 arm_nwk_mlme_event_type_e event_type; 00833 event_type = rf_mac_setup->mac_mlme_event; 00834 rf_mac_setup->mac_mlme_event = ARM_NWK_MAC_MLME_IDLE; 00835 switch (event_type) { 00836 case ARM_NWK_MAC_MLME_SCAN: 00837 mlme_scan_operation(rf_mac_setup); 00838 break; 00839 00840 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL: 00841 tr_debug("Data poll data wait TO"); 00842 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_NO_DATA); 00843 break; 00844 00845 case ARM_NWK_MAC_MLME_INDIRECT_DATA_POLL_AFTER_DATA: 00846 mac_mlme_poll_process_confirm(rf_mac_setup, MLME_SUCCESS); 00847 break; 00848 00849 default: 00850 break; 00851 } 00852 } 00853 00854 static void mac_mcps_timer_cb(int8_t timer_id, uint16_t slots) 00855 { 00856 00857 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_MCPS_TIMER); 00858 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00859 return; 00860 } 00861 rf_ptr->mac_mcps_timer_event.event_data = slots; 00862 eventOS_event_send(&rf_ptr->mac_mcps_timer_event); 00863 00864 } 00865 00866 00867 static void mac_mlme_timer_cb(int8_t timer_id, uint16_t slots) 00868 { 00869 protocol_interface_rf_mac_setup_s *rf_ptr = get_sw_mac_ptr_by_timer(timer_id, ARM_NWK_MLME_TIMER); 00870 if (!rf_ptr || !rf_ptr->dev_driver || !rf_ptr->dev_driver->phy_driver) { 00871 return; 00872 } 00873 00874 if (rf_ptr->mlme_tick_count == 0) { 00875 if (rf_ptr->mac_mlme_event != ARM_NWK_MAC_MLME_IDLE) { 00876 if (rf_ptr->mac_mlme_event == ARM_NWK_MAC_MLME_ED_ANALYZE) { 00877 if (rf_ptr->mlme_ED_counter > 1) { 00878 uint8_t ed = 0; 00879 phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver; 00880 rf_ptr->mlme_ED_counter--; 00881 if( dev_driver->extension ){ 00882 dev_driver->extension(PHY_EXTENSION_READ_CHANNEL_ENERGY, &ed); 00883 } 00884 if (ed > rf_ptr->max_ED) { 00885 rf_ptr->max_ED = ed; 00886 } 00887 00888 /*96 * 50us = 4.8ms*/ 00889 rf_ptr->mlme_tick_count = 0; 00890 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_ED_ANALYZE; 00891 eventOS_callback_timer_start(timer_id, slots); 00892 } else { 00893 mac_mlme_rf_disable(rf_ptr); 00894 rf_ptr->mac_mlme_event = ARM_NWK_MAC_MLME_SCAN; 00895 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER, rf_ptr, false); 00896 } 00897 } else { 00898 mac_generic_event_trig(MAC_MLME_EVENT_HANDLER,rf_ptr, true); 00899 } 00900 } 00901 } else { 00902 rf_ptr->mlme_tick_count--; 00903 eventOS_callback_timer_start(timer_id, slots); 00904 } 00905 } 00906 00907 static void mac_mlme_free_scan_temporary_data(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00908 { 00909 rf_mac_setup->scan_active = false; 00910 if (rf_mac_setup->mac_mlme_scan_resp) { 00911 mlme_scan_conf_t *r = rf_mac_setup->mac_mlme_scan_resp; 00912 tr_debug("%02x", r->ResultListSize); 00913 if( r->ED_values ){ 00914 ns_dyn_mem_free(r->ED_values); 00915 r->ED_values = NULL; 00916 } 00917 uint8_t i = 0; 00918 while (i < r->ResultListSize) { 00919 if (r->PAN_values[i]) { 00920 tr_debug("Free PAN result"); 00921 ns_dyn_mem_free(r->PAN_values[i]); 00922 } 00923 i++; 00924 } 00925 tr_debug("Free Response"); 00926 ns_dyn_mem_free(rf_mac_setup->mac_mlme_scan_resp); 00927 rf_mac_setup->mac_mlme_scan_resp = NULL; 00928 } 00929 } 00930 00931 void mac_mlme_set_active_state(protocol_interface_rf_mac_setup_s *entry, bool new_state) 00932 { 00933 if( entry ){ 00934 entry->macUpState = new_state; 00935 } 00936 } 00937 00938 void mac_mlme_data_base_deallocate(struct protocol_interface_rf_mac_setup *rf_mac) 00939 { 00940 if (rf_mac) { 00941 if( rf_mac->dev_driver ){ 00942 rf_mac->dev_driver->phy_sap_identifier = NULL; 00943 rf_mac->dev_driver->phy_sap_upper_cb = NULL; 00944 } 00945 00946 eventOS_callback_timer_unregister(rf_mac->mlme_timer_id); 00947 eventOS_callback_timer_unregister(rf_mac->mac_timer_id); 00948 eventOS_callback_timer_unregister(rf_mac->mac_mcps_timer); 00949 00950 ns_dyn_mem_free(rf_mac->dev_driver_tx_buffer.buf); 00951 ns_dyn_mem_free(rf_mac->mac_beacon_payload); 00952 00953 mac_sec_mib_deinit(rf_mac); 00954 ns_dyn_mem_free(rf_mac); 00955 } 00956 } 00957 00958 static uint8_t mac_backoff_ticks_calc(phy_device_driver_s * phy_driver) 00959 { 00960 //Calculate 20 symbol time which is typically 10 bytes 00961 const phy_device_channel_page_s *phy_channel_pages = phy_driver->phy_channel_pages; 00962 uint32_t datarate = dev_get_phy_datarate(phy_driver, phy_channel_pages->channel_page); 00963 if (datarate == 0) { 00964 datarate = 250000; 00965 } 00966 //How many 10us ticks backoff period is, assuming 4 bits per symbol (O-QPSK) 00967 unsigned int ticks = (2000000 / (datarate / 4)); 00968 if (ticks > 255) { 00969 ticks = 255; 00970 tr_warn("Backoff period too slow"); 00971 } 00972 return (uint8_t) ticks; 00973 } 00974 00975 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) 00976 { 00977 uint16_t total_length = 0; 00978 //allocate security 00979 if (!dev_driver || !mac64 || !dev_driver->phy_driver || !storage_sizes) { 00980 return NULL; 00981 } 00982 00983 protocol_interface_rf_mac_setup_s *entry = ns_dyn_mem_alloc(sizeof(protocol_interface_rf_mac_setup_s)); 00984 if (!entry) { 00985 return NULL; 00986 } 00987 //Init everything for 0, NULL or false 00988 memset(entry, 0, sizeof(protocol_interface_rf_mac_setup_s)); 00989 entry->ifs_timer_id = -1; 00990 entry->cca_timer_id = -1; 00991 entry->mlme_timer_id = -1; 00992 entry->mac_timer_id = -1; 00993 entry->bc_timer_id = -1; 00994 entry->mac_interface_id = -1; 00995 entry->dev_driver = dev_driver; 00996 00997 if (mac_sec_mib_init(entry, storage_sizes) != 0) { 00998 mac_mlme_data_base_deallocate(entry); 00999 return NULL; 01000 } 01001 01002 if (!dev_driver->phy_driver->phy_MTU) { 01003 mac_mlme_data_base_deallocate(entry); 01004 return NULL; 01005 } 01006 01007 //Allocate tx buffer by given MTU + header + tail 01008 total_length = dev_driver->phy_driver->phy_MTU; 01009 total_length += (dev_driver->phy_driver->phy_header_length + dev_driver->phy_driver->phy_tail_length); 01010 entry->dev_driver_tx_buffer.buf = ns_dyn_mem_alloc(total_length); 01011 if (!entry->dev_driver_tx_buffer.buf) { 01012 mac_mlme_data_base_deallocate(entry); 01013 return NULL; 01014 } 01015 01016 //allocate Beacon Payload buffer 01017 entry->max_beacon_payload_length = dev_driver->phy_driver->phy_MTU - MAC_IEEE_802_15_4_MAX_BEACON_OVERHEAD; 01018 entry->mac_beacon_payload = ns_dyn_mem_alloc(entry->max_beacon_payload_length); 01019 if (!entry->mac_beacon_payload) { 01020 mac_mlme_data_base_deallocate(entry); 01021 return NULL; 01022 } 01023 01024 entry->mac_tasklet_id = mac_mcps_sap_tasklet_init(); 01025 if (entry->mac_tasklet_id < 0) { 01026 mac_mlme_data_base_deallocate(entry); 01027 return NULL; 01028 } 01029 01030 entry->mlme_timer_id = eventOS_callback_timer_register(mac_mlme_timer_cb); 01031 entry->mac_timer_id = eventOS_callback_timer_register(timer_mac_interrupt); 01032 entry->mac_mcps_timer = eventOS_callback_timer_register(mac_mcps_timer_cb); 01033 if (entry->mlme_timer_id == -1 || entry->mac_timer_id == -1 || entry->mac_mcps_timer == -1) { 01034 mac_mlme_data_base_deallocate(entry); 01035 return NULL; 01036 } 01037 entry->macCapRxOnIdle = true; 01038 entry->macCapSecrutityCapability = true; 01039 entry->pan_id = entry->mac_short_address = 0xffff; 01040 mac_extended_mac_set(entry, mac64); 01041 entry->mac_ack_wait_duration = MAC_ACK_WAIT_DURATION; 01042 entry->mac_mlme_retry_max = MAC_DEFAULT_MAX_FRAME_RETRIES; 01043 memset(entry->mac_default_key_source, 0xff, 8); 01044 memset(entry->mac_auto_request.Keysource, 0xff, 8); 01045 memset(entry->mac_beacon_payload, 0, entry->max_beacon_payload_length); 01046 entry->mac_auto_request.SecurityLevel = 6; 01047 entry->mac_auto_request.KeyIndex = 0xff; 01048 mac_pd_sap_rf_low_level_function_set(entry, entry->dev_driver); 01049 entry->mac_sequence = randLIB_get_8bit(); 01050 entry->mac_bea_sequence = randLIB_get_8bit(); 01051 entry->fhss_api = NULL; 01052 entry->macMinBE = 3; 01053 entry->macMaxBE = 5; 01054 entry->macMaxCSMABackoffs = MAC_CCA_MAX; 01055 entry->mac_mcps_timer_event.priority = ARM_LIB_LOW_PRIORITY_EVENT; 01056 entry->mac_mcps_timer_event.event_type = MAC_MCPS_INDIRECT_TIMER_CB; 01057 entry->mac_mcps_timer_event.data_ptr = entry; 01058 entry->mac_mcps_timer_event.receiver = entry->mac_tasklet_id; 01059 entry->mac_mcps_timer_event.sender = 0; 01060 entry->mac_mcps_timer_event.event_id = 0; 01061 //How many 10us ticks backoff period is for waiting 20symbols which is typically 10 bytes time 01062 entry->backoff_period_in_10us = mac_backoff_ticks_calc(dev_driver->phy_driver); 01063 return entry; 01064 } 01065 01066 uint8_t mac_mlme_set_new_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01067 { 01068 uint8_t ret_val = 0; 01069 01070 if (rf_setup) { 01071 rf_setup->mac_sequence++; 01072 ret_val = rf_setup->mac_sequence; 01073 } 01074 return ret_val; 01075 } 01076 01077 uint8_t mac_mlme_set_new_beacon_sqn(protocol_interface_rf_mac_setup_s *rf_setup) 01078 { 01079 uint8_t ret_val = 0; 01080 01081 if (rf_setup) { 01082 rf_setup->mac_bea_sequence++; 01083 ret_val = rf_setup->mac_bea_sequence; 01084 } 01085 return ret_val; 01086 } 01087 01088 static int8_t mac_mlme_set_panid(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t pan_id) 01089 { 01090 phy_device_driver_s *dev_driver = rf_setup->dev_driver->phy_driver; 01091 if (!dev_driver->address_write) { 01092 if (dev_driver->link_type == PHY_LINK_TUN) { 01093 rf_setup->pan_id = pan_id; 01094 return 0; 01095 } 01096 return -1; 01097 } 01098 01099 uint8_t temp_8[2]; 01100 rf_setup->pan_id = pan_id; 01101 common_write_16_bit(pan_id, temp_8); 01102 01103 return dev_driver->address_write(PHY_MAC_PANID, temp_8); 01104 } 01105 01106 static void mac_mle_write_mac16_to_phy(phy_device_driver_s *dev_driver, uint16_t mac16) 01107 { 01108 uint8_t temp[2]; 01109 common_write_16_bit(mac16, temp); 01110 if (dev_driver->address_write) { 01111 dev_driver->address_write(PHY_MAC_16BIT, temp); 01112 } 01113 } 01114 01115 static int8_t mac_mlme_set_mac16(struct protocol_interface_rf_mac_setup *rf_setup, uint16_t mac16) 01116 { 01117 int8_t ret_val = -1; 01118 if (rf_setup) { 01119 01120 rf_setup->mac_short_address = mac16; 01121 //SET RF 16-bit 01122 if (mac16 > 0xfffd) { 01123 rf_setup->shortAdressValid = false; 01124 } else { 01125 rf_setup->shortAdressValid = true; 01126 } 01127 mac_mle_write_mac16_to_phy(rf_setup->dev_driver->phy_driver, mac16); 01128 ret_val = 0; 01129 } 01130 return ret_val; 01131 } 01132 01133 static void mac_mlme_write_mac64(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01134 { 01135 memcpy(addrPtr, rf_setup->mac64, 8); 01136 } 01137 01138 static void mac_mlme_write_mac16(protocol_interface_rf_mac_setup_s *rf_setup, uint8_t *addrPtr) 01139 { 01140 common_write_16_bit(rf_setup->mac_short_address, addrPtr); 01141 } 01142 01143 uint16_t mac_mlme_get_panid(protocol_interface_rf_mac_setup_s *rf_setup) 01144 { 01145 uint16_t panId = 0xffff; 01146 if (rf_setup) { 01147 panId = rf_setup->pan_id; 01148 } 01149 return panId; 01150 } 01151 01152 static bool add_or_update_beacon(mlme_scan_conf_t* conf, mlme_beacon_ind_t *data, fhss_api_t *fhss_api) 01153 { 01154 bool found = false; 01155 bool update_beacon = false; 01156 for( int i=0; i < conf->ResultListSize; i++){ 01157 mlme_pan_descriptor_t *cur_desc = conf->PAN_values[i]; 01158 if( !cur_desc ){ //Not an active or passive scan 01159 break; 01160 } 01161 /* When FHSS is enabled, logical channel check is not valid 01162 * as the Beacon can be sent on any enabled channel */ 01163 if (fhss_api || (cur_desc->LogicalChannel == data->PANDescriptor.LogicalChannel)) { 01164 if (cur_desc->CoordPANId == data->PANDescriptor.CoordPANId) { 01165 if (cur_desc->LinkQuality < data->PANDescriptor.LinkQuality) { 01166 cur_desc->CoordAddrMode = data->PANDescriptor.CoordAddrMode; 01167 memcpy(cur_desc->CoordAddress, data->PANDescriptor.CoordAddress, 8); 01168 cur_desc->LinkQuality = data->PANDescriptor.LinkQuality; 01169 update_beacon = true; 01170 } 01171 found = true; 01172 } 01173 } 01174 } 01175 if(!found && conf->ResultListSize != MLME_MAC_RES_SIZE_MAX) { 01176 mlme_pan_descriptor_t *desc = ns_dyn_mem_temporary_alloc(sizeof(mlme_pan_descriptor_t)); 01177 if( !desc ){ 01178 return false; 01179 } 01180 memset(desc, 0, sizeof(mlme_pan_descriptor_t)); 01181 mlme_pan_descriptor_t *dat = &data->PANDescriptor; 01182 01183 desc->CoordAddrMode = dat->CoordAddrMode; 01184 desc->CoordPANId = dat->CoordPANId; 01185 memcpy(desc->CoordAddress, dat->CoordAddress, 8); 01186 desc->LogicalChannel = dat->LogicalChannel; 01187 desc->ChannelPage = dat->ChannelPage; 01188 memcpy(desc->SuperframeSpec, dat->SuperframeSpec, 2); 01189 desc->GTSPermit = dat->GTSPermit; 01190 desc->LinkQuality = dat->LinkQuality; 01191 desc->Timestamp = dat->Timestamp; 01192 desc->SecurityFailure = dat->SecurityFailure; 01193 01194 desc->Key.SecurityLevel = dat->Key.SecurityLevel; 01195 desc->Key.KeyIdMode = dat->Key.KeyIdMode; 01196 desc->Key.KeyIndex = dat->Key.KeyIndex; 01197 memcpy(desc->Key.Keysource, dat->Key.Keysource, 8); 01198 01199 conf->PAN_values[conf->ResultListSize] = desc; 01200 conf->ResultListSize++; 01201 update_beacon = true; 01202 } 01203 return update_beacon; 01204 } 01205 01206 int mac_mlme_beacon_notify(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_beacon_ind_t *data) 01207 { 01208 bool update_beacon = true; 01209 bool contains_fhss_synch_info = false; 01210 if( !rf_mac_setup || !data){ 01211 return -1; 01212 } 01213 01214 /* Cut FHSS synchronization info from Beacon payload length. 01215 * Synchronization info is stored later in this function but 01216 * should not be delivered to upper layer as a part of Beacon payload. 01217 */ 01218 if (rf_mac_setup->fhss_api) { 01219 if (data->beacon_data_length > FHSS_SYNCH_INFO_START) { 01220 data->beacon_data_length -= FHSS_SYNCH_INFO_LENGTH; 01221 contains_fhss_synch_info = true; 01222 } else { 01223 // Received single channel Beacon when FHSS enabled. 01224 return 0; 01225 } 01226 } 01227 01228 mac_api_t *mac = get_sw_mac_api(rf_mac_setup); 01229 if (mac && mac->mlme_ind_cb) { 01230 mac->mlme_ind_cb(mac, MLME_BEACON_NOTIFY, data); 01231 } 01232 01233 tr_debug("Beacon Notify: %s", trace_array(data->beacon_data, data->beacon_data_length)); 01234 01235 if (rf_mac_setup->mac_mlme_scan_resp) { 01236 mlme_scan_conf_t* conf = rf_mac_setup->mac_mlme_scan_resp; 01237 update_beacon = add_or_update_beacon(conf, data, rf_mac_setup->fhss_api); 01238 } 01239 if (rf_mac_setup->fhss_api && (update_beacon == true)) { 01240 if (contains_fhss_synch_info == true) { 01241 // Assume synchronization info is found from the end of the Beacon payload 01242 uint8_t *synch_info_start = data->beacon_data + data->beacon_data_length; 01243 rf_mac_setup->fhss_api->receive_frame(rf_mac_setup->fhss_api, data->PANDescriptor.CoordPANId, data->PANDescriptor.CoordAddress, 01244 data->PANDescriptor.Timestamp, synch_info_start, FHSS_SYNCH_FRAME); 01245 } 01246 } 01247 01248 return 0; 01249 } 01250 01251 int8_t mac_mlme_virtual_confirmation_handle(int8_t driver_id, const uint8_t *data_ptr, uint16_t length) 01252 { 01253 (void) length; 01254 protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_driver_id(driver_id); 01255 if (!mac_setup) { 01256 return -1; 01257 } 01258 mlme_primitive primitive = *data_ptr; 01259 if (primitive == MLME_SCAN) { 01260 mlme_scan_conf_t *resp = ns_dyn_mem_temporary_alloc(sizeof(mlme_scan_conf_t)); 01261 if (!resp) { 01262 return -1; 01263 } 01264 memset(resp, 0, sizeof(mlme_scan_conf_t)); 01265 resp->ScanType = MAC_ACTIVE_SCAN; 01266 mac_setup->mac_mlme_scan_resp = resp; 01267 mac_mlme_scan_confirmation_handle(mac_setup); 01268 } 01269 return 0; 01270 } 01271 01272 static void mac_mlme_start_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_start_conf_t *conf) 01273 { 01274 if (rf_ptr->tun_extension_rf_driver) { 01275 virtual_data_req_t start_conf; 01276 uint8_t buf_temp[2]; 01277 uint8_t payload_buf[2]; 01278 // Add some random data as empty payload is not allowed 01279 payload_buf[0] = 0; 01280 payload_buf[1] = 0; 01281 01282 memset(&start_conf, 0, sizeof(virtual_data_req_t)); 01283 buf_temp[0] = NAP_MLME_CONFIRM; 01284 buf_temp[1] = MLME_START; 01285 start_conf.parameters = buf_temp; 01286 start_conf.parameter_length = sizeof(buf_temp); 01287 start_conf.msdu = payload_buf; 01288 start_conf.msduLength = sizeof(payload_buf); 01289 01290 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&start_conf, rf_ptr->tun_extension_rf_driver->id); 01291 } else if (get_sw_mac_api(rf_ptr)) { 01292 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01293 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_START, conf); 01294 } 01295 } 01296 } 01297 01298 static void mac_mlme_scan_confirm_handler(protocol_interface_rf_mac_setup_s *rf_ptr, const mlme_scan_conf_t *conf) 01299 { 01300 if (conf->ScanType == MAC_ACTIVE_SCAN) { 01301 tr_debug("Active Scan Result"); 01302 } else if (conf->ScanType == MAC_ED_SCAN_TYPE) { 01303 tr_debug("ED Scan Result"); 01304 } 01305 if (rf_ptr->tun_extension_rf_driver) { 01306 virtual_data_req_t scan_conf; 01307 uint8_t buf_temp[2]; 01308 uint8_t payload_buf[2]; 01309 // Add some random data as empty payload is not allowed 01310 payload_buf[0] = 0; 01311 payload_buf[1] = 0; 01312 01313 memset(&scan_conf, 0, sizeof(virtual_data_req_t)); 01314 buf_temp[0] = NAP_MLME_CONFIRM; 01315 buf_temp[1] = MLME_SCAN; 01316 scan_conf.parameters = buf_temp; 01317 scan_conf.parameter_length = sizeof(buf_temp); 01318 scan_conf.msdu = payload_buf; 01319 scan_conf.msduLength = sizeof(payload_buf); 01320 01321 rf_ptr->tun_extension_rf_driver->phy_driver->arm_net_virtual_tx_cb(&scan_conf, rf_ptr->tun_extension_rf_driver->id); 01322 } else if (get_sw_mac_api(rf_ptr)) { 01323 if (get_sw_mac_api(rf_ptr)->mlme_conf_cb) { 01324 get_sw_mac_api(rf_ptr)->mlme_conf_cb(get_sw_mac_api(rf_ptr), MLME_SCAN, conf); 01325 } 01326 } 01327 } 01328 01329 void mac_mlme_scan_confirmation_handle(protocol_interface_rf_mac_setup_s *rf_ptr) 01330 { 01331 if( !rf_ptr ){ 01332 return; 01333 } 01334 mlme_scan_conf_t *r = rf_ptr->mac_mlme_scan_resp; 01335 01336 if (r) { 01337 mac_mlme_scan_confirm_handler(rf_ptr, r); 01338 } 01339 mac_mlme_free_scan_temporary_data(rf_ptr); 01340 } 01341 01342 void mac_mlme_mac_radio_disabled(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01343 { 01344 if( !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver ){ 01345 return; 01346 } 01347 platform_enter_critical(); 01348 timer_mac_stop(rf_mac_setup); 01349 mac_mlme_rf_disable(rf_mac_setup); 01350 platform_exit_critical(); 01351 } 01352 01353 void mac_mlme_mac_radio_enable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01354 { 01355 if( !rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver){ 01356 return; 01357 } 01358 platform_enter_critical(); 01359 mac_mlme_rf_receiver_enable(rf_mac_setup); 01360 platform_exit_critical(); 01361 } 01362 01363 static int8_t mac_mlme_rf_disable(protocol_interface_rf_mac_setup_s *rf_mac_setup) 01364 { 01365 int8_t ret_val = 0; 01366 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01367 if (!dev_driver->state_control) { 01368 if (dev_driver->link_type == PHY_LINK_TUN) { 01369 rf_mac_setup->macRfRadioOn = false; 01370 rf_mac_setup->macRfRadioTxActive = false; 01371 return 0; 01372 } 01373 return -1; 01374 } 01375 if (rf_mac_setup->macRfRadioOn) { 01376 ret_val = dev_driver->state_control(PHY_INTERFACE_DOWN, 0); 01377 rf_mac_setup->macRfRadioOn = false; 01378 rf_mac_setup->macRfRadioTxActive = false; 01379 } 01380 01381 return ret_val; 01382 } 01383 01384 static int8_t mac_mlme_rf_receiver_enable(struct protocol_interface_rf_mac_setup *rf_mac_setup) 01385 { 01386 int8_t retval; 01387 01388 phy_device_driver_s *dev_driver = rf_mac_setup->dev_driver->phy_driver; 01389 if (!dev_driver->state_control) { 01390 if (dev_driver->link_type == PHY_LINK_TUN) { 01391 rf_mac_setup->macRfRadioOn = true; 01392 return 0; 01393 } 01394 return -1; 01395 } 01396 01397 if (rf_mac_setup->macRfRadioOn) { 01398 return 0; 01399 } 01400 01401 if (rf_mac_setup->macProminousMode) { 01402 tr_debug("Sniffer mode"); 01403 retval = dev_driver->state_control(PHY_INTERFACE_SNIFFER_STATE, rf_mac_setup->mac_channel); 01404 } else { 01405 retval = dev_driver->state_control(PHY_INTERFACE_UP, rf_mac_setup->mac_channel); 01406 } 01407 rf_mac_setup->macRfRadioOn = true; 01408 //tr_debug("Enable radio with channel %u", rf_mac_setup->mac_channel); 01409 return retval; 01410 } 01411 01412 /** 01413 * Initialize MAC channel selection sequence 01414 * 01415 * TODO: initialize channel select sequence 01416 * in coordinator mode 01417 * 01418 * \param new_channel channel to set 01419 * 01420 * \return 0 success 01421 * \return -1 HW error 01422 */ 01423 static int8_t mac_mlme_rf_channel_set(struct protocol_interface_rf_mac_setup *rf_setup, uint8_t new_channel) 01424 { 01425 if (new_channel == rf_setup->mac_channel) { 01426 return 0; 01427 } 01428 mac_pre_build_frame_t *buf; 01429 01430 //Disable allways 01431 mac_mlme_mac_radio_disabled(rf_setup); 01432 buf = rf_setup->active_pd_data_request; 01433 rf_setup->active_pd_data_request = NULL; 01434 //Set Channel 01435 rf_setup->mac_channel = new_channel; 01436 //Enable Radio 01437 mac_mlme_mac_radio_enable(rf_setup); 01438 if (buf) { 01439 mcps_sap_pd_req_queue_write(rf_setup, buf); 01440 } 01441 01442 return 0; 01443 } 01444 01445 /** 01446 * MAC channel change 01447 * 01448 * \param new_channel channel to set 01449 * 01450 * \return 0 success 01451 * \return -1 error 01452 */ 01453 int8_t mac_mlme_rf_channel_change(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t new_channel) 01454 { 01455 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01456 return -1; 01457 } 01458 01459 if (!rf_mac_setup->dev_driver->phy_driver->extension) { 01460 if (rf_mac_setup->dev_driver->phy_driver->link_type == PHY_LINK_TUN) { 01461 rf_mac_setup->mac_channel = new_channel; 01462 return 0; 01463 } 01464 return -1; 01465 } 01466 if (new_channel == rf_mac_setup->mac_channel) { 01467 return 0; 01468 } 01469 platform_enter_critical(); 01470 rf_mac_setup->mac_channel = new_channel; 01471 rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_SET_CHANNEL, &rf_mac_setup->mac_channel); 01472 platform_exit_critical(); 01473 return 0; 01474 } 01475 01476 void mac_mlme_poll_process_confirm(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t status) 01477 { 01478 if (!rf_mac_setup || !rf_mac_setup->dev_driver || !rf_mac_setup->dev_driver->phy_driver) { 01479 return; 01480 } 01481 01482 //Free active Data buffer 01483 if (rf_mac_setup->active_pd_data_request) { 01484 mcps_sap_prebuild_frame_buffer_free(rf_mac_setup->active_pd_data_request); 01485 rf_mac_setup->active_pd_data_request = NULL; 01486 } 01487 //Disable timer 01488 rf_mac_setup->macWaitingData = false; 01489 rf_mac_setup->macDataPollReq = false; 01490 rf_mac_setup->macRxDataAtPoll = false; 01491 01492 if (!rf_mac_setup->macCapRxOnIdle) { 01493 //Disable Radio If we are RX off at idle device 01494 //tr_debug("disbale by aceptance data"); 01495 if (!rf_mac_setup->macRfRadioTxActive ) { 01496 //Disable radio if no active TX and radio is enabled 01497 //tr_debug("RF disable"); 01498 mac_mlme_mac_radio_disabled(rf_mac_setup); 01499 } 01500 } 01501 01502 mac_api_t *mac_api = get_sw_mac_api(rf_mac_setup); 01503 if( mac_api ) { 01504 mlme_poll_conf_t confirm; 01505 confirm.status = status; 01506 mac_api->mlme_conf_cb(mac_api,MLME_POLL, &confirm); 01507 } 01508 //Trig Packet from queue 01509 mac_mcps_trig_buffer_from_queue(rf_mac_setup); 01510 01511 } 01512 01513 void mac_mlme_poll_req(protocol_interface_rf_mac_setup_s *cur, const mlme_poll_t *poll_req) 01514 { 01515 if( !cur || !poll_req ){ 01516 return; 01517 } 01518 if (cur->macDataPollReq ) { 01519 tr_debug("Poll Active do not start new"); 01520 return; 01521 } 01522 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(0); 01523 if (!buf) { 01524 tr_debug("No mem for data Req"); 01525 //Confirmation call here 01526 return; 01527 } 01528 01529 buf->fcf_dsn.frametype = FC_CMD_FRAME; 01530 buf->fcf_dsn.ackRequested = true; 01531 buf->fcf_dsn.intraPan = true; 01532 01533 buf->DstPANId = poll_req->CoordPANId; 01534 buf->SrcPANId = poll_req->CoordPANId; 01535 buf->fcf_dsn.DstAddrMode = poll_req->CoordAddrMode; 01536 memcpy(buf->DstAddr, poll_req->CoordAddress, 8); 01537 01538 buf->mac_command_id = MAC_DATA_REQ; 01539 buf->mac_payload = &buf->mac_command_id; 01540 buf->mac_payload_length = 1; 01541 buf->mac_header_length_with_security = 3; 01542 01543 mac_header_security_parameter_set(&buf->aux_header, &poll_req->Key); 01544 01545 if (buf->aux_header.securityLevel) { 01546 buf->fcf_dsn.securityEnabled = true; 01547 buf->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006; 01548 01549 } 01550 cur->macDataPollReq = true; 01551 cur->macWaitingData = true; 01552 cur->macRxDataAtPoll = false; 01553 01554 buf->security_mic_len = mac_security_mic_length_get(buf->aux_header.securityLevel); 01555 buf->mac_header_length_with_security += mac_header_security_aux_header_length(buf->aux_header.securityLevel, buf->aux_header.KeyIdMode); 01556 01557 if ( cur->mac_short_address > 0xfffd ) { 01558 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01559 } else { 01560 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01561 } 01562 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, cur, buf->SrcAddr); 01563 buf->mac_header_length_with_security += mac_header_address_length(&buf->fcf_dsn); 01564 buf->priority = MAC_PD_DATA_MEDIUM_PRIORITY; 01565 mcps_sap_pd_req_queue_write(cur, buf); 01566 } 01567 01568 static bool mac_mlme_beacon_at_queue(protocol_interface_rf_mac_setup_s *rf_ptr) { 01569 mac_pre_build_frame_t *buf = rf_ptr->active_pd_data_request; 01570 if (buf && buf->fcf_dsn.frametype == FC_BEACON_FRAME ) { 01571 return true; 01572 } 01573 01574 buf = rf_ptr->pd_data_request_queue_to_go; 01575 01576 while(buf) { 01577 if (buf->fcf_dsn.frametype == FC_BEACON_FRAME ) { 01578 return true; 01579 } 01580 buf = buf->next; 01581 } 01582 return false; 01583 } 01584 01585 int8_t mac_mlme_beacon_tx(protocol_interface_rf_mac_setup_s *rf_ptr) 01586 { 01587 if (!rf_ptr || !rf_ptr->macCapCordinator) { 01588 return -1; 01589 } 01590 01591 //Verify if beacon is already generated to queue 01592 if (mac_mlme_beacon_at_queue(rf_ptr)) { 01593 return -2; 01594 } 01595 01596 uint16_t length = 4; 01597 length += rf_ptr->mac_beacon_payload_size; 01598 // Add more space for FHSS synchronization info 01599 if (rf_ptr->fhss_api) { 01600 length += FHSS_SYNCH_INFO_LENGTH; 01601 } 01602 /* if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01603 length += 2; 01604 }*/ 01605 01606 mac_pre_build_frame_t *buf = mcps_sap_prebuild_frame_buffer_get(length); 01607 if(!buf) { 01608 return -1; 01609 } 01610 uint8_t sf_2 = 0x0f; 01611 01612 buf->fcf_dsn.frametype = FC_BEACON_FRAME; 01613 buf->fcf_dsn.DstAddrMode = MAC_ADDR_MODE_NONE; 01614 01615 if (rf_ptr->beaconSrcAddressModeLong) { 01616 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01617 buf->mac_header_length_with_security = 13; 01618 } else { 01619 if (rf_ptr->shortAdressValid) { 01620 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_16_BIT; 01621 buf->mac_header_length_with_security = 7; 01622 } else { 01623 buf->fcf_dsn.SrcAddrMode = MAC_ADDR_MODE_64_BIT; 01624 buf->mac_header_length_with_security = 13; 01625 } 01626 } 01627 buf->SrcPANId = mac_mlme_get_panid(rf_ptr); 01628 mac_frame_src_address_set_from_interface(buf->fcf_dsn.SrcAddrMode, rf_ptr, buf->SrcAddr); 01629 uint8_t *ptr = buf->mac_payload; 01630 01631 *ptr++ = 0xff;//Superframe disabled 01632 01633 if (rf_ptr->macCapCordinator) { 01634 sf_2 |= 0x40; //Cord 01635 } 01636 01637 if (rf_ptr->macCapBatteryPowered) { 01638 sf_2 |= 0x10; //Battery 01639 } 01640 01641 if (rf_ptr->macCapAssocationPermit) { 01642 sf_2 |= 0x80; //Permit 01643 } 01644 *ptr++ = sf_2; //Superframe desc MSB 01645 ptr = common_write_16_bit(0, ptr); //NO GTS Support 01646 01647 if (rf_ptr->mac_beacon_payload_size) { 01648 memcpy(ptr, rf_ptr->mac_beacon_payload, rf_ptr->mac_beacon_payload_size); 01649 01650 /*if (rf_ptr->beacon_join_priority_tx_cb_ptr) { 01651 uint8_t beacon_join_priority = rf_ptr->beacon_join_priority_tx_cb_ptr(rf_ptr->mac_interface_id); 01652 ptr[PLAIN_BEACON_PAYLOAD_SIZE] = BEACON_OPTION_JOIN_PRIORITY_TYPE_LEN; 01653 ptr[PLAIN_BEACON_PAYLOAD_SIZE + 1] = beacon_join_priority; 01654 ptr += BEACON_OPTION_JOIN_PRIORITY_LEN; 01655 }*/ 01656 } 01657 buf->priority = MAC_PD_DATA_HIGH_PRIOTITY; 01658 01659 tr_debug("BEA tx"); 01660 mcps_sap_pd_req_queue_write(rf_ptr, buf); 01661 sw_mac_stats_update(rf_ptr, STAT_MAC_BEA_TX_COUNT, 0); 01662 return 0; 01663 } 01664
Generated on Tue Jul 12 2022 12:22:03 by
