takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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