Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers serial_mac_api.c Source File

serial_mac_api.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 
00018 #include "nsconfig.h"
00019 #include <string.h>
00020 #include "serial_mac_api.h"
00021 #include "eventOS_event.h"
00022 #include "nsdynmemLIB.h"
00023 #include "common_functions.h"
00024 #include "ns_trace.h"
00025 #include "MAC/rf_driver_storage.h"
00026 
00027 #define TRACE_GROUP "seMa"
00028 
00029 #define SERIAL_MAC_DATA_FLOW_TYPE 0
00030 #define SERIAL_MAC_VIRTUAL_FLOW_TYPE 1
00031 
00032 typedef struct serial_mac_buf {
00033     struct serial_mac_buf *next;
00034     data_protocol_e type;
00035     uint16_t length;
00036     uint8_t buf[];
00037 } serial_mac_buf_t;
00038 
00039 
00040 typedef struct serial_mac_internal_s {
00041     serial_mac_api_t *mac_api;
00042     arm_device_driver_list_s *dev_driver;
00043     arm_device_driver_list_s *virtual_driver;
00044     serial_mac_buf_t *active_tx_buf;
00045     serial_mac_buf_t *tx_queue;
00046     int8_t tasklet_id;
00047     //linked list link
00048 } serial_mac_internal_t;
00049 
00050 typedef struct serial_data_ind_s {
00051     uint16_t msduLength;
00052     uint8_t *msdu;
00053 } serial_data_ind_t;
00054 
00055 static serial_mac_internal_t serial_mac_store; //Hack only at this point, later put into linked list
00056 
00057 #define SERIAL_INIT_EVENT 100
00058 #define SERIAL_DATA_IND_EVENT 101
00059 #define SERIAL_DATA_CNF_EVENT 102
00060 
00061 static int8_t serial_mac_api_init(serial_mac_api_t *api, data_indication *ind_cb);
00062 static int8_t serial_mac_virtual_data_request(const virtual_data_req_t *data, int8_t driver_id);
00063 static int8_t serial_mac_data_request(const serial_mac_api_t *api, const uint8_t *data_ptr, uint16_t data_legth);
00064 
00065 static int8_t generic_data_request(serial_mac_internal_t *mac, const virtual_data_req_t *data, uint8_t data_flow_type);
00066 
00067 static int8_t serial_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id);
00068 static int8_t serial_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);
00069 static void serial_mac_tasklet(arm_event_s *event);
00070 
00071 static serial_mac_buf_t *serial_mac_buffer_get(const virtual_data_req_t *b, uint8_t data_type);
00072 
00073 static int8_t serial_mac_data_request(const serial_mac_api_t *api, const uint8_t *data_ptr, uint16_t data_length)
00074 {
00075 
00076     if (!serial_mac_store.mac_api || serial_mac_store.mac_api != api) {
00077         return -1;
00078     }
00079 
00080     if (!data_ptr || !data_length) {
00081         return -2;
00082     }
00083 
00084     virtual_data_req_t data;
00085     data.parameter_length = 0;
00086     data.parameters = NULL;
00087     data.msdu = data_ptr;
00088     data.msduLength = data_length;
00089 
00090     return generic_data_request(&serial_mac_store, &data, SERIAL_MAC_DATA_FLOW_TYPE);
00091 }
00092 
00093 
00094 static int8_t serial_mac_virtual_init(const serial_mac_api_t *api, int8_t driver_id)
00095 {
00096     arm_device_driver_list_s *virtual_driver = arm_net_phy_driver_pointer(driver_id);
00097 
00098     if (!serial_mac_store.mac_api || serial_mac_store.mac_api != api || !virtual_driver) {
00099         return -1;
00100     }
00101 
00102     if (!virtual_driver->phy_driver->arm_net_virtual_rx_cb) {
00103         return -1;
00104     }
00105 
00106     serial_mac_store.virtual_driver = virtual_driver;
00107     virtual_driver->phy_driver->arm_net_virtual_tx_cb = &serial_mac_virtual_data_request;
00108     return 0;
00109 
00110 }
00111 
00112 serial_mac_api_t *serial_mac_create(int8_t serial_driver_id)
00113 {
00114     //TODO: Refactor this away, Drivers should be stored in MAC layer in future
00115     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(serial_driver_id);
00116     if (!driver || !driver->phy_driver) {
00117         return NULL;
00118     }
00119 
00120     serial_mac_api_t *this = ns_dyn_mem_alloc(sizeof(serial_mac_api_t));
00121     if (!this) {
00122         return NULL;
00123     }
00124     memset(this, 0, sizeof(serial_mac_api_t));
00125     this->mac_initialize = &serial_mac_api_init;
00126     this->virtual_initilize = &serial_mac_virtual_init;
00127     this->data_request_cb = &serial_mac_data_request;
00128     serial_mac_store.active_tx_buf = NULL;
00129     serial_mac_store.mac_api = this;
00130     serial_mac_store.dev_driver = driver;
00131     serial_mac_store.tasklet_id = eventOS_event_handler_create(&serial_mac_tasklet, SERIAL_INIT_EVENT);
00132     arm_net_phy_init(driver->phy_driver, &serial_mac_net_phy_rx, &serial_mac_net_phy_tx_done);
00133     return this;
00134 }
00135 
00136 
00137 static int8_t serial_mac_virtual_data_request(const virtual_data_req_t *data, int8_t driver_id)
00138 {
00139 
00140     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00141     if (!driver || serial_mac_store.virtual_driver != driver) {
00142         return -1;
00143     }
00144 
00145     return generic_data_request(&serial_mac_store, data, SERIAL_MAC_VIRTUAL_FLOW_TYPE);
00146 }
00147 
00148 static serial_mac_buf_t *serial_mac_buffer_get(const virtual_data_req_t *b, uint8_t data_type)
00149 {
00150     if (!b || !b->msdu || !b->msduLength) {
00151         return NULL;
00152     }
00153 
00154     if (b->parameter_length && !b->parameters) {
00155         return NULL;
00156     }
00157 
00158     uint16_t length = b->msduLength + b->parameter_length + 1; //Allocate 1 byte from Serial mac
00159 
00160     serial_mac_buf_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(serial_mac_buf_t) + length);
00161 
00162     if (buffer) {
00163         uint8_t *ptr = &(buffer)->buf[0];
00164         memset(buffer, 0, sizeof(serial_mac_buf_t));
00165         *ptr++ = data_type;
00166         if (b->parameter_length) {
00167             memcpy(ptr, b->parameters, b->parameter_length);
00168             ptr += b->parameter_length;
00169         }
00170         memcpy(ptr, b->msdu, b->msduLength);
00171         buffer->length = length;
00172     }
00173     return buffer;
00174 }
00175 
00176 static void serial_mac_buffer_queue_free(serial_mac_buf_t *buf)
00177 {
00178     serial_mac_buf_t *cur;
00179     while (buf) {
00180         cur = buf;
00181         buf = cur->next;
00182         ns_dyn_mem_free(cur);
00183     }
00184 }
00185 
00186 static serial_mac_buf_t *arm_driver_queue_read(serial_mac_internal_t *mac)
00187 {
00188     serial_mac_buf_t *b = NULL;
00189     if (mac->tx_queue) {
00190         b = mac->tx_queue;
00191         mac->tx_queue = b->next;
00192         b->next = NULL;
00193     }
00194     return b;
00195 }
00196 
00197 static int serial_mac_tx_buf_from_queue(serial_mac_internal_t *mac)
00198 {
00199     if (mac->active_tx_buf) {
00200         return 0;
00201     }
00202     serial_mac_buf_t *b = arm_driver_queue_read(mac);
00203 
00204     if (!b) {
00205         return 0;
00206     }
00207 
00208     mac->active_tx_buf = b;
00209     if (mac->dev_driver->phy_driver->tx(&(b)->buf[0], b->length, 1, b->type) == 0) {
00210         return 0;
00211     }
00212     //This should be tx busy/failed event and when needed error status should be included in an event
00213     arm_event_s event = {
00214         .receiver = serial_mac_store.tasklet_id,
00215         .sender = 0,
00216         .event_id = 0,
00217         .data_ptr = NULL,
00218         .event_type = SERIAL_DATA_CNF_EVENT,
00219         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
00220     };
00221 
00222     return eventOS_event_send(&event);
00223 }
00224 
00225 static void serial_mac_queue_push(serial_mac_internal_t *mac, serial_mac_buf_t *b)
00226 {
00227     if (mac->tx_queue) {
00228         serial_mac_buf_t *temp_buf = mac->tx_queue;
00229         while (temp_buf->next) {
00230             temp_buf = temp_buf->next;
00231         }
00232         temp_buf->next = b;
00233     } else {
00234         mac->tx_queue = b;
00235     }
00236 
00237 }
00238 
00239 static void serial_mac_tasklet(arm_event_s *event)
00240 {
00241     uint8_t event_type = event->event_type;
00242 
00243     switch (event_type) {
00244         case SERIAL_DATA_IND_EVENT: {
00245 
00246             if (!event->data_ptr) {
00247                 return;
00248             }
00249 
00250             serial_data_ind_t *data_ind = (serial_data_ind_t *)event->data_ptr;
00251             uint8_t *ptr = data_ind->msdu;
00252             uint8_t data_type = *ptr++;
00253             if (data_type == SERIAL_MAC_DATA_FLOW_TYPE && serial_mac_store.mac_api->data_ind_cb) {
00254                 serial_mac_store.mac_api->data_ind_cb(serial_mac_store.mac_api, ptr, data_ind->msduLength - 1);
00255 
00256             } else if (data_type == SERIAL_MAC_VIRTUAL_FLOW_TYPE && serial_mac_store.virtual_driver) {
00257                 arm_device_driver_list_s *driver = serial_mac_store.virtual_driver;
00258                 if (driver->phy_driver && driver->phy_driver->arm_net_virtual_rx_cb) {
00259                     driver->phy_driver->arm_net_virtual_rx_cb(ptr, data_ind->msduLength - 1, driver->id);
00260                 }
00261 
00262             }
00263             ns_dyn_mem_free(((serial_data_ind_t *)event->data_ptr)->msdu);
00264             ns_dyn_mem_free(event->data_ptr);
00265             break;
00266         }
00267         case SERIAL_DATA_CNF_EVENT: {
00268 
00269             if (serial_mac_store.active_tx_buf) {
00270                 serial_mac_buffer_queue_free(serial_mac_store.active_tx_buf);
00271                 serial_mac_store.active_tx_buf = NULL;
00272                 serial_mac_tx_buf_from_queue(&serial_mac_store);
00273             }
00274             break;
00275         }
00276         case SERIAL_INIT_EVENT:
00277         default: {
00278             break;
00279         }
00280     }
00281 }
00282 
00283 static int8_t serial_mac_api_init(serial_mac_api_t *api, data_indication *ind_cb)
00284 {
00285     if (serial_mac_store.mac_api != api) {
00286         return -1;
00287     }
00288     serial_mac_store.mac_api->data_ind_cb = ind_cb;
00289 
00290     return 0;
00291 }
00292 
00293 
00294 static int8_t generic_data_request(serial_mac_internal_t *mac, const virtual_data_req_t *data, uint8_t data_flow_type)
00295 {
00296     serial_mac_buf_t *buf = serial_mac_buffer_get(data, data_flow_type);
00297     if (!buf) {
00298         return -1;
00299     }
00300 
00301     serial_mac_queue_push(mac, buf);
00302 
00303     serial_mac_tx_buf_from_queue(mac);
00304 
00305     return 0;
00306 
00307 }
00308 
00309 static int8_t serial_mac_net_phy_rx(const uint8_t *data_ptr, uint16_t data_len, uint8_t link_quality, int8_t dbm, int8_t driver_id)
00310 {
00311     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00312 
00313     if (!driver || driver != serial_mac_store.dev_driver || !data_ptr) {
00314         return -1;
00315     }
00316 
00317     (void)link_quality;
00318     (void) dbm;
00319 
00320     serial_data_ind_t *data_ind = ns_dyn_mem_temporary_alloc(sizeof(serial_data_ind_t));
00321     if (!data_ind) {
00322         return -1;
00323     }
00324     data_ind->msdu = ns_dyn_mem_temporary_alloc(data_len);
00325     if (!data_ind->msdu) {
00326         ns_dyn_mem_free(data_ind);
00327         return -1;
00328     }
00329     memcpy(data_ind->msdu, data_ptr, data_len);
00330     data_ind->msduLength = data_len;
00331 
00332     arm_event_s event = {
00333         .receiver = serial_mac_store.tasklet_id,
00334         .sender = 0,
00335         .event_id = 0,
00336         .data_ptr = data_ind,
00337         .event_type = SERIAL_DATA_IND_EVENT,
00338         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
00339     };
00340 
00341     return eventOS_event_send(&event);
00342 }
00343 
00344 static int8_t serial_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)
00345 {
00346     (void)tx_handle;
00347     (void)cca_retry;
00348     (void)tx_retry;
00349     (void)status;
00350     arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id);
00351     if (!driver || driver != serial_mac_store.dev_driver || !serial_mac_store.active_tx_buf) {
00352         return -1;
00353     }
00354     arm_event_s event = {
00355         .receiver = serial_mac_store.tasklet_id,
00356         .sender = 0,
00357         .event_id = 0,
00358         .data_ptr = NULL,
00359         .event_type = SERIAL_DATA_CNF_EVENT,
00360         .priority = ARM_LIB_HIGH_PRIORITY_EVENT,
00361     };
00362 
00363     return eventOS_event_send(&event);
00364 }
00365