takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sw_mac.c Source File

sw_mac.c

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