Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sw_mac.c Source File

sw_mac.c

00001 /*
00002  * Copyright (c) 2016-2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #include "nsconfig.h"
00018 #include <string.h>
00019 #include "nsdynmemLIB.h"
00020 #include "mac_api.h"
00021 #include "fhss_api.h "
00022 #include "sw_mac.h"
00023 #include "MAC/IEEE802_15_4/sw_mac_internal.h"
00024 #include "MAC/IEEE802_15_4/mac_mlme.h"
00025 #include "MAC/IEEE802_15_4/mac_defines.h"
00026 #include "MAC/IEEE802_15_4/mac_mcps_sap.h"
00027 #include "MAC/IEEE802_15_4/mac_pd_sap.h"
00028 #include "MAC/rf_driver_storage.h"
00029 #include "MAC/virtual_rf/virtual_rf_defines.h"
00030 #include "mac_fhss_callbacks.h"
00031 #include "eventOS_callback_timer.h"
00032 #include "common_functions.h"
00033 
00034 //TODO: create linked list of created MACs
00035 
00036 typedef struct mac_internal_s {
00037     mac_api_t *mac_api;
00038     arm_device_driver_list_s *dev_driver;
00039     arm_device_driver_list_s *virtual_driver;
00040     //Move define inside MAC (now in protocol_abstract.h)
00041     struct protocol_interface_rf_mac_setup *setup;
00042     uint8_t device_table_size;
00043     uint8_t key_description_size;
00044     //linked list link
00045 }mac_internal_t;
00046 
00047 static mac_internal_t mac_store; //Hack only at this point, later put into linked list
00048 
00049 static int8_t ns_sw_mac_initialize(mac_api_t *api, mcps_data_confirm *mcps_data_conf_cb,
00050                                    mcps_data_indication *mcps_data_ind_cb, mcps_purge_confirm *purge_conf_cb,
00051                                    mlme_confirm *mlme_conf_callback, mlme_indication *mlme_ind_callback, int8_t parent_id);
00052 
00053 static void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data);
00054 static void mcps_req(const mac_api_t* api, const mcps_data_req_t *data);
00055 static void purge_req(const mac_api_t* api, const mcps_purge_t *data);
00056 static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64);
00057 static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf);
00058 
00059 static int8_t sw_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id);
00060 static int8_t sw_mac_net_phy_tx_done(int8_t driver_id, uint8_t tx_handle, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry);
00061 static int8_t sw_mac_net_phy_config_parser(int8_t driver_id, const uint8_t *data, uint16_t length);
00062 static int8_t sw_mac_storage_decription_sizes_get(const mac_api_t* api, mac_description_storage_size_t *buffer);
00063 
00064 static int8_t sw_mac_storage_decription_sizes_get(const mac_api_t* api, mac_description_storage_size_t *buffer)
00065 {
00066     if( !api || !buffer || api != mac_store.mac_api ){
00067         return -1;
00068     }
00069 
00070     buffer->device_decription_table_size = mac_store.setup->device_description_table_size;
00071     buffer->key_description_table_size = mac_store.setup->key_description_table_size;
00072     buffer->key_lookup_size = mac_store.setup->key_lookup_list_size;
00073     buffer->key_usage_size = mac_store.setup->key_usage_list_size;
00074     return 0;
00075 }
00076 
00077 mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t *storage_sizes)
00078 {
00079     //TODO: Refactor this away, Drivers should be stored in MAC layer in future
00080     if (!storage_sizes || !storage_sizes->device_decription_table_size || !storage_sizes->key_description_table_size || !storage_sizes->key_lookup_size || !storage_sizes->key_usage_size) {
00081         return NULL;
00082     }
00083 
00084     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(rf_driver_id);
00085 
00086     if( !driver || !driver->phy_driver){
00087         return NULL;
00088     }
00089     mac_api_t *this = ns_dyn_mem_alloc(sizeof(mac_api_t));
00090     if( !this ){
00091         return NULL;
00092     }
00093     memset(this, 0, sizeof(mac_api_t));
00094     this->parent_id = -1;
00095     mac_store.dev_driver = driver;
00096     mac_store.setup = mac_mlme_data_base_allocate(mac_store.dev_driver->phy_driver->PHY_MAC, mac_store.dev_driver, storage_sizes);
00097 
00098     if( !mac_store.setup ){
00099         ns_dyn_mem_free(this);
00100         return NULL;
00101     }
00102 
00103     arm_net_phy_init(driver->phy_driver, &sw_mac_net_phy_rx, &sw_mac_net_phy_tx_done);
00104     arm_net_virtual_config_rx_cb_set(driver->phy_driver, &sw_mac_net_phy_config_parser);
00105     arm_net_virtual_confirmation_rx_cb_set(driver->phy_driver, &mac_mlme_virtual_confirmation_handle);
00106 
00107     this->mac_initialize = &ns_sw_mac_initialize;
00108     this->mlme_req = &mlme_req;
00109     this->mcps_data_req = &mcps_req;
00110     this->mcps_purge_req = &purge_req;
00111     this->mac64_get = &macext_mac64_address_get;
00112     this->mac64_set = &macext_mac64_address_set;
00113     this->mac_storage_sizes_get =&sw_mac_storage_decription_sizes_get;
00114     this->phyMTU = driver->phy_driver->phy_MTU;
00115 
00116     mac_store.mac_api = this;
00117 
00118     mac_store.virtual_driver = NULL;
00119     return this;
00120 }
00121 
00122 int8_t ns_sw_mac_virtual_client_register(mac_api_t *api, int8_t virtual_driver_id)
00123 {
00124     if( !api || api != mac_store.mac_api ){
00125         return -1;
00126     }
00127     arm_device_driver_list_s *virtual_driver = arm_net_phy_driver_pointer(virtual_driver_id);
00128     if (!virtual_driver) {
00129         return -1;
00130     }
00131     mac_store.virtual_driver = virtual_driver;
00132     mac_store.setup->tun_extension_rf_driver = virtual_driver;
00133     //Driver setup
00134     virtual_driver->phy_sap_identifier = mac_store.setup;
00135     virtual_driver->phy_sap_upper_cb = mac_virtual_sap_data_cb;
00136     return 0;
00137 }
00138 
00139 int8_t ns_sw_mac_virtual_client_unregister(mac_api_t *api)
00140 {
00141     if(!api || api != mac_store.mac_api ){
00142         return -1;
00143     }
00144 
00145     if (mac_store.virtual_driver) {
00146         mac_store.setup->tun_extension_rf_driver = NULL;
00147         mac_store.virtual_driver->phy_sap_identifier = NULL;
00148         mac_store.virtual_driver->phy_sap_upper_cb = NULL;
00149         mac_store.virtual_driver = NULL;
00150     }
00151     return 0;
00152 }
00153 
00154 int ns_sw_mac_fhss_register(mac_api_t *mac_api, fhss_api_t *fhss_api)
00155 {
00156     if (!mac_api || !fhss_api) {
00157         return -1;
00158     }
00159     // Get a pointer to MAC setup structure
00160     protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_mac_api(mac_api);
00161     if (!mac_setup) {
00162         return -2;
00163     }
00164     // Assign FHSS API
00165     mac_setup->fhss_api = fhss_api;
00166     // Pass MAC functions to FHSS
00167     fhss_callback_t callbacks;
00168     callbacks.read_tx_queue_size = &mac_read_tx_queue_sizes;
00169     callbacks.read_datarate = &mac_read_phy_datarate;
00170     callbacks.read_mac_address = &mac_read_64bit_mac_address;
00171     callbacks.change_channel = &mac_set_channel;
00172     callbacks.send_fhss_frame = &mac_fhss_frame_tx;
00173     callbacks.synch_lost_notification = &mac_synch_lost;
00174     callbacks.tx_poll = &mac_poll_tx_queue;
00175     callbacks.broadcast_notify = &mac_broadcast_notification;
00176     callbacks.read_coord_mac_address = &mac_get_coordinator_mac_address;
00177     mac_setup->fhss_api->init_callbacks(mac_setup->fhss_api, &callbacks);
00178     return 0;
00179 }
00180 
00181 int ns_sw_mac_statistics_start(struct mac_api_s *mac_api, struct mac_statistics_s *mac_statistics)
00182 {
00183     if (!mac_api || !mac_statistics) {
00184         return -1;
00185     }
00186     protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_mac_api(mac_api);
00187     if (!mac_setup) {
00188         return -1;
00189     }
00190     mac_setup->mac_statistics = mac_statistics;
00191     return 0;
00192 }
00193 
00194 static int8_t ns_sw_mac_initialize(mac_api_t *api, mcps_data_confirm *mcps_data_conf_cb,
00195                                    mcps_data_indication *mcps_data_ind_cb, mcps_purge_confirm *mcps_purge_conf_cb,
00196                                    mlme_confirm *mlme_conf_callback, mlme_indication *mlme_ind_callback, int8_t parent_id)
00197 {
00198     //TODO: Find from linked list instead
00199     if(api != mac_store.mac_api ){
00200         return -1;
00201     }
00202     mac_api_t *cur = mac_store.mac_api;
00203     //TODO: Check validity of callbacks
00204     cur->data_conf_cb = mcps_data_conf_cb;
00205     cur->data_ind_cb = mcps_data_ind_cb;
00206     cur->purge_conf_cb = mcps_purge_conf_cb;
00207     cur->mlme_conf_cb = mlme_conf_callback;
00208     cur->mlme_ind_cb = mlme_ind_callback;
00209     cur->parent_id = parent_id;
00210 
00211     mac_store.setup->mac_interface_id = parent_id;
00212 
00213     return 0;
00214 }
00215 
00216 mac_api_t *get_sw_mac_api(protocol_interface_rf_mac_setup_s *setup)
00217 {
00218     if (!mac_store.mac_api || mac_store.mac_api->parent_id == -1 || mac_store.setup != setup) {
00219         return NULL;
00220     }
00221     return mac_store.mac_api;
00222 
00223 }
00224 
00225 protocol_interface_rf_mac_setup_s *get_sw_mac_ptr_by_mac_api(mac_api_t *api)
00226 {
00227     if (mac_store.mac_api == api) {
00228         return mac_store.setup;
00229     }
00230     return NULL;
00231 }
00232 
00233 protocol_interface_rf_mac_setup_s *get_sw_mac_ptr_by_fhss_api(const fhss_api_t *api)
00234 {
00235     if (mac_store.setup->fhss_api == api) {
00236         return mac_store.setup;
00237     }
00238     return NULL;
00239 }
00240 
00241 protocol_interface_rf_mac_setup_s *get_sw_mac_ptr_by_timer(int8_t id, arm_nwk_timer_id_e type)
00242 {
00243 
00244     if (!mac_store.mac_api || mac_store.mac_api->parent_id == -1 ) {
00245         return NULL;
00246     }
00247     protocol_interface_rf_mac_setup_s *rf_ptr = mac_store.setup;
00248 
00249     switch (type) {
00250         case ARM_NWK_MLME_TIMER:
00251             if (rf_ptr->mlme_timer_id == id) {
00252                 return rf_ptr;
00253             }
00254             break;
00255         case ARM_NWK_MAC_TIMER:
00256             if (rf_ptr->mac_timer_id == id) {
00257                 return rf_ptr;
00258             }
00259             break;
00260         case ARM_NWK_CCA_TIMER:
00261             if (rf_ptr->cca_timer_id == id) {
00262                 return rf_ptr;
00263             }
00264             break;
00265         case ARM_NWK_BC_TIMER:
00266             if (rf_ptr->bc_timer_id == id) {
00267                 return rf_ptr;
00268             }
00269             break;
00270         case ARM_MCPS_TIMER:
00271             if (rf_ptr->mac_mcps_timer == id) {
00272                 return rf_ptr;
00273             }
00274             break;
00275         default: /* ARM_NWK_IFS_TIMER */
00276         if (rf_ptr->ifs_timer_id == id) {
00277             return rf_ptr;
00278         }
00279         break;
00280     }
00281 
00282     return NULL;
00283 }
00284 
00285 protocol_interface_rf_mac_setup_s *get_sw_mac_ptr_by_driver_id(int8_t id)
00286 {
00287     if (mac_store.mac_api && mac_store.setup) {
00288         if (mac_store.setup->dev_driver && mac_store.setup->dev_driver->id == id) {
00289             return mac_store.setup;
00290         }
00291     }
00292     return NULL;
00293 }
00294 
00295 static int8_t build_virtual_scan_request(const mlme_scan_t *scan_request, uint8_t *scan_req_ptr)
00296 {
00297     if (scan_request && scan_req_ptr) {
00298         *scan_req_ptr++ = scan_request->ScanType;
00299         *scan_req_ptr++ = scan_request->ScanChannels.channel_page;
00300         memcpy(scan_req_ptr, scan_request->ScanChannels.channel_mask, 32);
00301         scan_req_ptr += 32;
00302         *scan_req_ptr++ = scan_request->ScanDuration;
00303         *scan_req_ptr++ = scan_request->ChannelPage;
00304         *scan_req_ptr++ = scan_request->Key.SecurityLevel;
00305         *scan_req_ptr++ = scan_request->Key.KeyIdMode;
00306         *scan_req_ptr++ = scan_request->Key.KeyIndex;
00307         memcpy(scan_req_ptr, scan_request->Key.Keysource, 8);
00308         scan_req_ptr += 8;
00309         return 0;
00310     }
00311     return -1;
00312 }
00313 
00314 static int8_t build_virtual_start_request(const mlme_start_t *start_request, uint8_t *start_req_ptr)
00315 {
00316     if (start_request && start_req_ptr) {
00317         start_req_ptr = common_write_16_bit(start_request->PANId, start_req_ptr);
00318         *start_req_ptr++ = start_request->LogicalChannel;
00319         start_req_ptr = common_write_32_bit(start_request->StartTime, start_req_ptr);
00320         *start_req_ptr++ = start_request->BeaconOrder;
00321         *start_req_ptr++ = start_request->SuperframeOrder;
00322         *start_req_ptr++ = start_request->PANCoordinator;
00323         *start_req_ptr++ = start_request->BatteryLifeExtension;
00324         *start_req_ptr++ = start_request->CoordRealignment;
00325         *start_req_ptr++ = start_request->CoordRealignKey.SecurityLevel;
00326         *start_req_ptr++ = start_request->CoordRealignKey.KeyIdMode;
00327         *start_req_ptr++ = start_request->CoordRealignKey.KeyIndex;
00328         memcpy(start_req_ptr, start_request->CoordRealignKey.Keysource, 8);
00329         start_req_ptr += 8;
00330         *start_req_ptr++ = start_request->BeaconRealignKey.SecurityLevel;
00331         *start_req_ptr++ = start_request->BeaconRealignKey.KeyIdMode;
00332         *start_req_ptr++ = start_request->BeaconRealignKey.KeyIndex;
00333         memcpy(start_req_ptr, start_request->BeaconRealignKey.Keysource, 8);
00334         start_req_ptr += 8;
00335         return 0;
00336     }
00337     return -1;
00338 }
00339 
00340 void mlme_req(const mac_api_t* api, mlme_primitive id, const void *data)
00341 {
00342     if( mac_store.mac_api != api ){
00343         return;
00344     }
00345     //TODO: cast & handle
00346     switch(id){
00347         case MLME_ASSOCIATE:{
00348             break;
00349         }
00350         case MLME_DISASSOCIATE:{
00351             break;
00352         }
00353         case MLME_GET:{
00354             mlme_get_conf_t get_confirm;
00355             const mlme_get_t *dat = (const mlme_get_t *)data;
00356             memset(&get_confirm, 0, sizeof(mlme_get_conf_t));
00357             get_confirm.attr = dat->attr;
00358             get_confirm.attr_index = dat->attr_index;
00359 
00360             if (mac_mlme_get_req(mac_store.setup, &get_confirm) == 0) {
00361                 //call configured confirmation
00362                 api->mlme_conf_cb(api, MLME_GET, &get_confirm);
00363             }
00364 
00365             break;
00366         }
00367         case MLME_GTS:{
00368             //Unsupported
00369             break;
00370         }
00371         case MLME_RESET:{
00372             const mlme_reset_t *dat = (const mlme_reset_t*)data;
00373             mac_mlme_reset(mac_store.setup, dat);
00374             break;
00375         }
00376         case MLME_RX_ENABLE:{
00377             break;
00378         }
00379         case MLME_SCAN:{
00380             const mlme_scan_t *dat = (const mlme_scan_t*)data;
00381             if (mac_store.dev_driver->phy_driver->arm_net_virtual_tx_cb) {
00382                 virtual_data_req_t scan_req;
00383                 uint8_t buf_temp[2];
00384                 uint8_t scan_req_temp[47];
00385 
00386                 build_virtual_scan_request(dat, scan_req_temp);
00387                 memset(&scan_req, 0, sizeof(virtual_data_req_t));
00388                 buf_temp[0] = NAP_MLME_REQUEST;
00389                 buf_temp[1] = MLME_SCAN;
00390                 scan_req.parameters = buf_temp;
00391                 scan_req.parameter_length = sizeof(buf_temp);
00392                 scan_req.msdu = scan_req_temp;
00393                 scan_req.msduLength = sizeof(scan_req_temp);
00394                 mac_store.dev_driver->phy_driver->arm_net_virtual_tx_cb(&scan_req, mac_store.dev_driver->id);
00395             } else {
00396                 mac_mlme_scan_request(dat, mac_store.setup);
00397             }
00398             break;
00399         }
00400         case MLME_SET:{
00401             const mlme_set_t *dat = (const mlme_set_t*)data;
00402             if (dat->attr == macLoadBalancingBeaconTx && mac_store.dev_driver->mlme_observer_cb) {
00403                 mac_store.dev_driver->mlme_observer_cb(dat);
00404             } else {
00405                 if (mac_mlme_set_req(mac_store.setup, dat) == 0) {
00406                     if (mac_store.dev_driver->mlme_observer_cb) {
00407                         mac_store.dev_driver->mlme_observer_cb(dat);
00408                     }
00409                 }
00410             }
00411             break;
00412         }
00413         case MLME_START:{
00414             const mlme_start_t *dat = (mlme_start_t*)data;
00415             //TODO: Populate linked list when present
00416             mac_mlme_start_req(dat, mac_store.setup);
00417             if (mac_store.dev_driver->phy_driver->arm_net_virtual_tx_cb) {
00418                 virtual_data_req_t start_req;
00419                 uint8_t buf_temp[2];
00420                 uint8_t start_req_temp[34];
00421 
00422                 build_virtual_start_request(dat, start_req_temp);
00423                 memset(&start_req, 0, sizeof(virtual_data_req_t));
00424                 buf_temp[0] = NAP_MLME_REQUEST;
00425                 buf_temp[1] = MLME_START;
00426                 start_req.parameters = buf_temp;
00427                 start_req.parameter_length = sizeof(buf_temp);
00428                 start_req.msdu = start_req_temp;
00429                 start_req.msduLength = sizeof(start_req_temp);
00430                 mac_store.dev_driver->phy_driver->arm_net_virtual_tx_cb(&start_req, mac_store.dev_driver->id);
00431             }
00432             break;
00433         }
00434         case MLME_SYNC:{
00435             break;
00436         }
00437         case MLME_POLL:{
00438             const mlme_poll_t *dat = (mlme_poll_t*)data;
00439             mac_mlme_poll_req(mac_store.setup, dat);
00440             break;
00441         }
00442         default:
00443             break;
00444     }
00445 }
00446 
00447 void mcps_req(const mac_api_t* api, const mcps_data_req_t *data)
00448 {
00449     //TODO: Populate linked list when present
00450     if (mac_store.mac_api == api) {
00451         mcps_sap_data_req_handler(mac_store.setup , data );
00452     }
00453 }
00454 
00455 static void purge_req(const mac_api_t* api, const mcps_purge_t *data)
00456 {
00457     if (mac_store.mac_api == api) {
00458         mcps_sap_purge_reg_handler(mac_store.setup , data );
00459     }
00460 }
00461 
00462 static int8_t macext_mac64_address_set( const mac_api_t* api, const uint8_t *mac64)
00463 {
00464     if(!mac64 || !api || mac_store.mac_api != api ){
00465         return -1;
00466     }
00467 
00468     mac_extended_mac_set(mac_store.setup, mac64);
00469     return 0;
00470 
00471 }
00472 
00473 
00474 static int8_t macext_mac64_address_get( const mac_api_t* api, mac_extended_address_type type, uint8_t *mac64_buf)
00475 {
00476     if(!mac64_buf || !api || mac_store.mac_api != api ){
00477         return -1;
00478     }
00479     uint8_t *ptr;
00480     switch (type) {
00481         case MAC_EXTENDED_READ_ONLY:
00482             ptr = mac_store.setup->dev_driver->phy_driver->PHY_MAC;
00483             break;
00484         case MAC_EXTENDED_DYNAMIC:
00485             ptr = mac_store.setup->mac64;
00486             break;
00487         default:
00488             return -1;
00489     }
00490     memcpy(mac64_buf, ptr, 8);
00491     return 0;
00492 }
00493 
00494 //void mlme_assoc_resp(const mac_api_t* api, mlme_associate_resp_t *data)
00495 //{
00496 //    //TODO:
00497 //}
00498 
00499 static int8_t sw_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id)
00500 {
00501     arm_phy_sap_msg_t phy_msg;
00502     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00503     if (!driver || driver != mac_store.dev_driver) {
00504         return -1;
00505     }
00506 
00507     //TODO: event might need mac_api if we ever decide to support more than 1 ethernet MAC!
00508 
00509     phy_msg.message.generic_data_ind.data_len = data_len;
00510     phy_msg.message.generic_data_ind.data_ptr = data_ptr;
00511     phy_msg.message.generic_data_ind.dbm = dbm;
00512     phy_msg.message.generic_data_ind.link_quality = link_quality;
00513 
00514     phy_msg.id = MAC15_4_PD_SAP_DATA_IND;
00515     mac_pd_sap_data_cb(driver->phy_sap_identifier, &phy_msg);
00516 
00517     return 0;
00518 }
00519 
00520 static int8_t sw_mac_net_phy_tx_done(int8_t driver_id, uint8_t tx_handle, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry)
00521 {
00522     arm_phy_sap_msg_t phy_msg;
00523     (void)tx_handle;
00524     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00525     if (!driver) {
00526         return -1;
00527     }
00528     phy_msg.id = MAC15_4_PD_SAP_DATA_TX_CONFIRM;
00529     phy_msg.message.mac15_4_pd_sap_confirm.status = status;
00530     phy_msg.message.mac15_4_pd_sap_confirm.cca_retry = cca_retry;
00531     phy_msg.message.mac15_4_pd_sap_confirm.tx_retry = tx_retry;
00532 
00533     mac_pd_sap_data_cb(driver->phy_sap_identifier, &phy_msg);
00534     return 0;
00535 }
00536 
00537 static void bc_enable_timer_cb(int8_t timer_id, uint16_t slots)
00538 {
00539     (void)slots;
00540     protocol_interface_rf_mac_setup_s *mac_setup = get_sw_mac_ptr_by_timer(timer_id, ARM_NWK_BC_TIMER);
00541     if (mac_setup) {
00542         mac_setup->macBroadcastDisabled = true;
00543     }
00544 }
00545 
00546 static int8_t sw_mac_net_phy_config_parser(int8_t driver_id, const uint8_t *data, uint16_t length)
00547 {
00548     (void)length;
00549     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00550     if (!driver) {
00551         return -1;
00552     }
00553     protocol_interface_rf_mac_setup_s *mac_setup = (protocol_interface_rf_mac_setup_s*)driver->phy_sap_identifier;
00554     if (!mac_setup) {
00555         return -2;
00556     }
00557     uint8_t config_type = *data++;
00558     switch (config_type) {
00559         case MAC_BROADCAST_EVENT:
00560             // If timer is not registered do it here
00561             if (mac_setup->bc_timer_id == -1) {
00562                 mac_setup->bc_timer_id = eventOS_callback_timer_register(bc_enable_timer_cb);
00563             }
00564             if (mac_setup->bc_timer_id != -1) {
00565                 uint32_t broadcast_time = common_read_32_bit(data);
00566                 // Time is given as 50us slots
00567                 eventOS_callback_timer_start(mac_setup->bc_timer_id, broadcast_time/50);
00568                 mac_setup->macBroadcastDisabled = false;
00569                 // Trig TX queue poll to send queued broadcast frames
00570                 mcps_sap_trig_tx(mac_setup);
00571             }
00572             break;
00573         default:
00574             break;
00575     }
00576     return 0;
00577 }
00578 
00579 
00580 void sw_mac_stats_update(protocol_interface_rf_mac_setup_s *setup, mac_stats_type_t type, uint32_t update_val)
00581 {
00582     if (setup->mac_statistics) {
00583         switch (type) {
00584             case STAT_MAC_TX_QUEUE:
00585                 setup->mac_statistics->mac_tx_queue_size = update_val;
00586                 if (setup->mac_statistics->mac_tx_queue_size > setup->mac_statistics->mac_tx_queue_peak) {
00587                     setup->mac_statistics->mac_tx_queue_peak = setup->mac_statistics->mac_tx_queue_size;
00588                 }
00589                 break;
00590             case STAT_MAC_RX_COUNT:
00591                 setup->mac_statistics->mac_rx_count++;
00592                 setup->mac_statistics->mac_rx_bytes += update_val;
00593                 break;
00594             case STAT_MAC_TX_COUNT:
00595                 setup->mac_statistics->mac_tx_count++;
00596                 setup->mac_statistics->mac_tx_bytes += update_val;
00597                 break;
00598             case STAT_MAC_BC_RX_COUNT:
00599                 setup->mac_statistics->mac_bc_rx_count++;
00600                 break;
00601             case STAT_MAC_BC_TX_COUNT:
00602                 setup->mac_statistics->mac_bc_tx_count++;
00603                 break;
00604             case STAT_MAC_BEA_RX_COUNT:
00605                 setup->mac_statistics->mac_beacon_rx_count++;
00606                 break;
00607             case STAT_MAC_BEA_TX_COUNT:
00608                 setup->mac_statistics->mac_beacon_tx_count++;
00609                 break;
00610             case STAT_MAC_RX_DROP:
00611                 setup->mac_statistics->mac_rx_drop_count++;
00612                 break;
00613             case STAT_MAC_TX_FAIL:
00614                 setup->mac_statistics->mac_tx_failed_count++;
00615                 break;
00616             case STAT_MAC_TX_RETRY:
00617                 setup->mac_statistics->mac_retry_count += update_val;
00618                 break;
00619             case STAT_MAC_TX_CCA_ATT:
00620                 setup->mac_statistics->mac_cca_attempts_count += update_val;
00621                 break;
00622             case STAT_MAC_TX_CCA_FAIL:
00623                 setup->mac_statistics->mac_failed_cca_count++;
00624                 break;
00625         }
00626     }
00627 }