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.
Fork of OmniWheels by
serial_mac_api.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 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 if(!serial_mac_store.mac_api || serial_mac_store.mac_api != api){ 00076 return -1; 00077 } 00078 00079 if (!data_ptr || !data_length) { 00080 return -2; 00081 } 00082 00083 virtual_data_req_t data; 00084 data.parameter_length = 0; 00085 data.parameters = NULL; 00086 data.msdu = data_ptr; 00087 data.msduLength = data_length; 00088 00089 return generic_data_request(&serial_mac_store, &data, SERIAL_MAC_DATA_FLOW_TYPE); 00090 } 00091 00092 00093 static int8_t serial_mac_virtual_init(const serial_mac_api_t *api, int8_t driver_id) { 00094 arm_device_driver_list_s *virtual_driver = arm_net_phy_driver_pointer(driver_id); 00095 00096 if(!serial_mac_store.mac_api || serial_mac_store.mac_api != api || !virtual_driver){ 00097 return -1; 00098 } 00099 00100 if (!virtual_driver->phy_driver->arm_net_virtual_rx_cb) { 00101 return -1; 00102 } 00103 00104 serial_mac_store.virtual_driver = virtual_driver; 00105 virtual_driver->phy_driver->arm_net_virtual_tx_cb = &serial_mac_virtual_data_request; 00106 return 0; 00107 00108 } 00109 00110 serial_mac_api_t *serial_mac_create(int8_t serial_driver_id) 00111 { 00112 //TODO: Refactor this away, Drivers should be stored in MAC layer in future 00113 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(serial_driver_id); 00114 if( !driver || !driver->phy_driver){ 00115 return NULL; 00116 } 00117 00118 serial_mac_api_t *this = ns_dyn_mem_alloc(sizeof(serial_mac_api_t)); 00119 if( !this ){ 00120 return NULL; 00121 } 00122 memset(this, 0, sizeof(serial_mac_api_t)); 00123 this->mac_initialize = &serial_mac_api_init; 00124 this->virtual_initilize = &serial_mac_virtual_init; 00125 this->data_request_cb = &serial_mac_data_request; 00126 serial_mac_store.active_tx_buf = NULL; 00127 serial_mac_store.mac_api = this; 00128 serial_mac_store.dev_driver = driver; 00129 serial_mac_store.tasklet_id = eventOS_event_handler_create(&serial_mac_tasklet, SERIAL_INIT_EVENT); 00130 arm_net_phy_init(driver->phy_driver, &serial_mac_net_phy_rx, &serial_mac_net_phy_tx_done); 00131 return this; 00132 } 00133 00134 00135 static int8_t serial_mac_virtual_data_request(const virtual_data_req_t *data, int8_t driver_id){ 00136 00137 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00138 if( !driver || serial_mac_store.virtual_driver != driver){ 00139 return -1; 00140 } 00141 00142 return generic_data_request(&serial_mac_store, data, SERIAL_MAC_VIRTUAL_FLOW_TYPE); 00143 } 00144 00145 static serial_mac_buf_t * serial_mac_buffer_get(const virtual_data_req_t *b, uint8_t data_type) 00146 { 00147 if (!b || !b->msdu || !b->msduLength) { 00148 return NULL; 00149 } 00150 00151 if (b->parameter_length && !b->parameters) { 00152 return NULL; 00153 } 00154 00155 uint16_t length = b->msduLength + b->parameter_length + 1; //Allocate 1 byte from Serial mac 00156 00157 serial_mac_buf_t *buffer = ns_dyn_mem_temporary_alloc(sizeof(serial_mac_buf_t) + length); 00158 00159 if (buffer) { 00160 uint8_t *ptr = &(buffer)->buf[0]; 00161 memset(buffer, 0, sizeof(serial_mac_buf_t)); 00162 *ptr++ = data_type; 00163 if (b->parameter_length) { 00164 memcpy(ptr, b->parameters , b->parameter_length); 00165 ptr += b->parameter_length; 00166 } 00167 memcpy(ptr, b->msdu, b->msduLength); 00168 buffer->length = length; 00169 } 00170 return buffer; 00171 } 00172 00173 static void serial_mac_buffer_queue_free(serial_mac_buf_t *buf){ 00174 serial_mac_buf_t *cur; 00175 while (buf) { 00176 cur = buf; 00177 buf = cur->next; 00178 ns_dyn_mem_free(cur); 00179 } 00180 } 00181 00182 static serial_mac_buf_t *arm_driver_queue_read(serial_mac_internal_t *mac) 00183 { 00184 serial_mac_buf_t *b = NULL; 00185 if (mac->tx_queue) { 00186 b = mac->tx_queue; 00187 mac->tx_queue = b->next; 00188 b->next = NULL; 00189 } 00190 return b; 00191 } 00192 00193 static int serial_mac_tx_buf_from_queue(serial_mac_internal_t *mac) 00194 { 00195 if( mac->active_tx_buf ){ 00196 return 0; 00197 } 00198 serial_mac_buf_t *b = arm_driver_queue_read(mac); 00199 00200 if (!b) { 00201 return 0; 00202 } 00203 00204 mac->active_tx_buf = b; 00205 if (mac->dev_driver->phy_driver->tx(&(b)->buf[0], b->length, 1, b->type) == 0) { 00206 return 0; 00207 } 00208 //This should be tx busy/failed event and when needed error status should be included in an event 00209 arm_event_s event = { 00210 .receiver = serial_mac_store.tasklet_id, 00211 .sender = 0, 00212 .event_id = 0, 00213 .data_ptr = NULL, 00214 .event_type = SERIAL_DATA_CNF_EVENT, 00215 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00216 }; 00217 00218 return eventOS_event_send(&event); 00219 } 00220 00221 static void serial_mac_queue_push(serial_mac_internal_t *mac, serial_mac_buf_t *b) 00222 { 00223 if (mac->tx_queue) { 00224 serial_mac_buf_t *temp_buf = mac->tx_queue; 00225 while (temp_buf->next) { 00226 temp_buf = temp_buf->next; 00227 } 00228 temp_buf->next = b; 00229 } else { 00230 mac->tx_queue = b; 00231 } 00232 00233 } 00234 00235 static void serial_mac_tasklet(arm_event_s *event) 00236 { 00237 uint8_t event_type = event->event_type; 00238 00239 switch (event_type) { 00240 case SERIAL_DATA_IND_EVENT:{ 00241 00242 if (!event->data_ptr) { 00243 return; 00244 } 00245 00246 serial_data_ind_t *data_ind = (serial_data_ind_t*)event->data_ptr; 00247 uint8_t *ptr = data_ind->msdu; 00248 uint8_t data_type = *ptr++; 00249 if (data_type == SERIAL_MAC_DATA_FLOW_TYPE && serial_mac_store.mac_api->data_ind_cb) { 00250 serial_mac_store.mac_api->data_ind_cb(serial_mac_store.mac_api, ptr, data_ind->msduLength - 1); 00251 00252 } else if (data_type == SERIAL_MAC_VIRTUAL_FLOW_TYPE && serial_mac_store.virtual_driver) { 00253 arm_device_driver_list_s *driver = serial_mac_store.virtual_driver; 00254 if (driver->phy_driver && driver->phy_driver->arm_net_virtual_rx_cb) { 00255 driver->phy_driver->arm_net_virtual_rx_cb(ptr, data_ind->msduLength - 1, driver->id); 00256 } 00257 00258 } 00259 ns_dyn_mem_free(((serial_data_ind_t*)event->data_ptr)->msdu); 00260 ns_dyn_mem_free(event->data_ptr); 00261 break; 00262 } 00263 case SERIAL_DATA_CNF_EVENT:{ 00264 00265 if (serial_mac_store.active_tx_buf) { 00266 serial_mac_buffer_queue_free(serial_mac_store.active_tx_buf); 00267 serial_mac_store.active_tx_buf = NULL; 00268 serial_mac_tx_buf_from_queue(&serial_mac_store); 00269 } 00270 break; 00271 } 00272 case SERIAL_INIT_EVENT: 00273 default:{ 00274 break; 00275 } 00276 } 00277 } 00278 00279 static int8_t serial_mac_api_init( serial_mac_api_t *api, data_indication *ind_cb) 00280 { 00281 if( serial_mac_store.mac_api != api ){ 00282 return -1; 00283 } 00284 serial_mac_store.mac_api->data_ind_cb = ind_cb; 00285 00286 return 0; 00287 } 00288 00289 00290 static int8_t generic_data_request(serial_mac_internal_t *mac, const virtual_data_req_t *data, uint8_t data_flow_type) { 00291 serial_mac_buf_t *buf = serial_mac_buffer_get(data, data_flow_type); 00292 if (!buf) { 00293 return -1; 00294 } 00295 00296 serial_mac_queue_push(mac, buf); 00297 00298 serial_mac_tx_buf_from_queue(mac); 00299 00300 return 0; 00301 00302 } 00303 00304 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) 00305 { 00306 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00307 00308 if (!driver || driver != serial_mac_store.dev_driver || !data_ptr ) { 00309 return -1; 00310 } 00311 00312 (void)link_quality; 00313 (void) dbm; 00314 00315 serial_data_ind_t *data_ind = ns_dyn_mem_temporary_alloc(sizeof(serial_data_ind_t)); 00316 if (!data_ind){ 00317 return -1; 00318 } 00319 data_ind->msdu = ns_dyn_mem_temporary_alloc(data_len); 00320 if(!data_ind->msdu){ 00321 ns_dyn_mem_free(data_ind); 00322 return -1; 00323 } 00324 memcpy(data_ind->msdu, data_ptr, data_len); 00325 data_ind->msduLength = data_len; 00326 00327 arm_event_s event = { 00328 .receiver = serial_mac_store.tasklet_id, 00329 .sender = 0, 00330 .event_id = 0, 00331 .data_ptr = data_ind, 00332 .event_type = SERIAL_DATA_IND_EVENT, 00333 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00334 }; 00335 00336 return eventOS_event_send(&event); 00337 } 00338 00339 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) 00340 { 00341 (void)tx_handle; 00342 (void)cca_retry; 00343 (void)tx_retry; 00344 (void)status; 00345 arm_device_driver_list_s *driver = arm_net_phy_driver_pointer(driver_id); 00346 if (!driver || driver != serial_mac_store.dev_driver || !serial_mac_store.active_tx_buf) { 00347 return -1; 00348 } 00349 arm_event_s event = { 00350 .receiver = serial_mac_store.tasklet_id, 00351 .sender = 0, 00352 .event_id = 0, 00353 .data_ptr = NULL, 00354 .event_type = SERIAL_DATA_CNF_EVENT, 00355 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00356 }; 00357 00358 return eventOS_event_send(&event); 00359 } 00360
Generated on Fri Jul 22 2022 04:54:00 by
 1.7.2
 1.7.2 
    