Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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