Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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