Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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
Generated on Tue Jul 12 2022 13:54:49 by
