Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_mlme.c Source File

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