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
ppp_service_if.cpp
00001 /* 00002 * Copyright (c) 2019 ARM Limited 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 <stdlib.h> 00019 #include <stdio.h> 00020 #include "mbed_interface.h" 00021 #include "mbed_trace.h" 00022 #include "netsocket/nsapi_types.h" 00023 #include "mbed_shared_queues.h" 00024 #include "mbed_poll.h" 00025 #include "ip4string.h" 00026 #include "ip6string.h" 00027 #include "ppp_service.h" 00028 #include "ppp_impl.h" 00029 00030 #if PPP_SUPPORT 00031 00032 #define TRACE_GROUP "ppp_serv_if" 00033 00034 typedef void (*ppp_sys_timeout_handler)(void *arg); 00035 00036 // Number of timers running simultaneous 00037 #define PPP_TIMER_NUM 5 00038 // Number of simultaneous memory buffers 00039 #define PPP_PBUF_HANDLE_NUM 10 00040 00041 typedef struct { 00042 ppp_service *ppp_drv; 00043 ppp_sys_timeout_handler handler; 00044 void *arg; 00045 int equeue_id; 00046 uint8_t id; 00047 } ppp_sys_timeout_t; 00048 00049 static ppp_sys_timeout_t *timeout[PPP_TIMER_NUM]; 00050 static SingletonPtr<PlatformMutex> ppp_service_if_mutex; 00051 static uint8_t ppp_service_sys_timeout_id = 0; 00052 static pbuf pbuf_handles[PPP_PBUF_HANDLE_NUM]; 00053 00054 #if PPP_TRACE_ENABLE 00055 #define OUTPUT_BUFFER 0 00056 #define INPUT_BUFFER 1 00057 00058 #define BUFFER_SIZE 5000 00059 00060 typedef struct { 00061 char buffer[BUFFER_SIZE]; 00062 int buffer_index = 0; 00063 int line_len = 0; 00064 } trace_buf_t; 00065 00066 static trace_buf_t output_trace_buffer; 00067 static trace_buf_t input_trace_buffer; 00068 00069 #if PPP_TRACE_BUFFER_SIZE > 0 00070 static char cont_trace_buffer[PPP_TRACE_BUFFER_SIZE]; 00071 static int cont_trace_buffer_index = 0; 00072 #endif 00073 #endif 00074 00075 #if BYTE_ORDER == LITTLE_ENDIAN 00076 #if !defined(ppp_htons) 00077 /** 00078 * Convert an u16_t from host- to network byte order. 00079 * 00080 * @param n u16_t in host byte order 00081 * @return n in network byte order 00082 */ 00083 uint16_t ppp_htons(uint16_t n) 00084 { 00085 return PP_HTONS(n); 00086 } 00087 #endif /* ppp_htons */ 00088 00089 #if !defined(ppp_htonl) 00090 /** 00091 * Convert an u32_t from host- to network byte order. 00092 * 00093 * @param n u32_t in host byte order 00094 * @return n in network byte order 00095 */ 00096 uint32_t ppp_htonl(uint32_t n) 00097 { 00098 return PP_HTONL(n); 00099 } 00100 #endif /* ppp_htonl */ 00101 00102 #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 00103 00104 extern "C" { 00105 00106 void ppp_ip4_addr_set(nsapi_addr_t *addr, uint32_t *src) 00107 { 00108 memset(addr->bytes, 0, NSAPI_IP_BYTES); 00109 memcpy(addr->bytes, src, 4); 00110 addr->version = NSAPI_IPv4 ; 00111 } 00112 00113 struct netif *ppp_netif_add(struct netif *netif, void *state, netif_init_fn init) 00114 { 00115 #if PPP_IPV4_SUPPORT 00116 netif->output = NULL; 00117 netif->ipv4_up = false; 00118 #endif /* PPP_IPV4_SUPPORT */ 00119 #if PPP_IPV6_SUPPORT 00120 netif->output_ip6 = NULL; 00121 netif->ipv6_up = false; 00122 #endif 00123 netif->mtu = 0; 00124 netif->input = NULL; 00125 netif->state = state; 00126 00127 /* call user specified initialization function for netif */ 00128 if (init(netif) != ERR_OK) { 00129 return NULL; 00130 } 00131 00132 return netif; 00133 } 00134 00135 err_t ppp_ip_input(struct pbuf *p, struct netif *inp) 00136 { 00137 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(inp->service_ptr); 00138 void *buffer = ppp_memory_buffer_convert_from(p); 00139 ppp_service_ptr->link_input(static_cast<net_stack_mem_buf_t *>(buffer)); 00140 return ERR_OK; 00141 } 00142 00143 void ppp_set_link_up(struct netif *netif) 00144 { 00145 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(netif->service_ptr); 00146 ppp_service_ptr->link_state(true); 00147 } 00148 00149 void ppp_set_link_down(struct netif *netif) 00150 { 00151 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(netif->service_ptr); 00152 ppp_service_ptr->link_state(false); 00153 } 00154 00155 err_t ppp_call_callback(void *service_ptr, ppp_service_cb callback, void *arg) 00156 { 00157 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(service_ptr); 00158 00159 int unique_id = ppp_service_ptr->event_queue_get()->call(mbed::callback(callback, arg)); 00160 if (unique_id == 0) { 00161 return ERR_MEM; 00162 } 00163 00164 return ERR_OK; 00165 } 00166 00167 pbuf *ppp_memory_buffer_allocate(void *memory_manager, uint16_t size, ppp_buf_type_e type) 00168 { 00169 ppp_service_if_mutex->lock(); 00170 00171 int8_t free_index = -1; 00172 for (int8_t index = 0; index < PPP_PBUF_HANDLE_NUM; index++) { 00173 if (pbuf_handles[index].buffer == NULL) { 00174 free_index = index; 00175 break; 00176 } 00177 } 00178 00179 if (free_index < 0) { 00180 ppp_service_if_mutex->unlock(); 00181 return NULL; 00182 } 00183 00184 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(memory_manager); 00185 00186 void *buffer; 00187 if (type == PPP_BUF_HEAP) { 00188 buffer = mem_mngr->alloc_heap(size, 0); 00189 } else { 00190 buffer = mem_mngr->alloc_pool(size, 0); 00191 } 00192 00193 if (!buffer) { 00194 ppp_service_if_mutex->unlock(); 00195 return NULL; 00196 } 00197 00198 // Must be continuous buffer from pool on alloc 00199 if (mem_mngr->get_next(buffer) != NULL) { 00200 mem_mngr->free(buffer); 00201 ppp_service_if_mutex->unlock(); 00202 return NULL; 00203 } 00204 00205 pbuf_handles[free_index].next = NULL; 00206 pbuf_handles[free_index].buffer = buffer; 00207 pbuf_handles[free_index].memory_manager = memory_manager; 00208 pbuf_handles[free_index].payload = static_cast<uint8_t *>(mem_mngr->get_ptr(buffer)); 00209 pbuf_handles[free_index].len = size; 00210 pbuf_handles[free_index].tot_len = size; 00211 pbuf_handles[free_index].payload_start = pbuf_handles[free_index].payload; 00212 00213 ppp_service_if_mutex->unlock(); 00214 00215 return &pbuf_handles[free_index]; 00216 } 00217 00218 void ppp_memory_buffer_free(pbuf *buffer) 00219 { 00220 ppp_service_if_mutex->lock(); 00221 00222 int8_t buffer_index = -1; 00223 for (int8_t index = 0; index < PPP_PBUF_HANDLE_NUM; index++) { 00224 if (&pbuf_handles[index] == buffer) { 00225 buffer_index = index; 00226 break; 00227 } 00228 } 00229 00230 if (buffer_index < 0) { 00231 ppp_service_if_mutex->unlock(); 00232 return; 00233 } 00234 00235 if (pbuf_handles[buffer_index].buffer != NULL) { 00236 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(pbuf_handles[buffer_index].memory_manager); 00237 mem_mngr->free(pbuf_handles[buffer_index].buffer); 00238 } 00239 00240 memset(&pbuf_handles[buffer_index], 0, sizeof(pbuf)); 00241 00242 ppp_service_if_mutex->unlock(); 00243 } 00244 00245 uint16_t ppp_memory_buffer_pool_alloc_unit_get(void *memory_manager) 00246 { 00247 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(memory_manager); 00248 return mem_mngr->get_pool_alloc_unit(0); 00249 } 00250 00251 void ppp_memory_buffer_cat(void *memory_manager, pbuf *to_buf, pbuf *cat_buf) 00252 { 00253 for (struct pbuf *buf = to_buf; buf != NULL; buf = buf->next) { 00254 if (buf->next == NULL) { 00255 buf->next = cat_buf; 00256 break; 00257 } 00258 } 00259 } 00260 00261 void ppp_memory_buffer_set_len(void *memory_manager, pbuf *buf, uint16_t len) 00262 { 00263 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(memory_manager); 00264 mem_mngr->set_len(buf->buffer, len); 00265 } 00266 00267 struct pbuf *ppp_memory_buffer_convert_to(void *memory_manager, net_stack_mem_buf_t *mem_buf) 00268 { 00269 ppp_service_if_mutex->lock(); 00270 00271 int8_t free_index = -1; 00272 for (int8_t index = 0; index < PPP_PBUF_HANDLE_NUM; index++) { 00273 if (pbuf_handles[index].buffer == NULL) { 00274 free_index = index; 00275 break; 00276 } 00277 } 00278 00279 if (free_index < 0) { 00280 ppp_service_if_mutex->unlock(); 00281 return NULL; 00282 } 00283 00284 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(memory_manager); 00285 00286 pbuf_handles[free_index].buffer = mem_buf; 00287 pbuf_handles[free_index].memory_manager = memory_manager; 00288 pbuf_handles[free_index].payload = mem_mngr->get_ptr(mem_buf); 00289 pbuf_handles[free_index].len = mem_mngr->get_len(mem_buf); 00290 pbuf_handles[free_index].tot_len = mem_mngr->get_total_len(mem_buf); 00291 pbuf_handles[free_index].payload_start = pbuf_handles[free_index].payload; 00292 00293 ppp_service_if_mutex->unlock(); 00294 00295 return &pbuf_handles[free_index]; 00296 } 00297 00298 net_stack_mem_buf_t *ppp_memory_buffer_convert_from(struct pbuf *p) 00299 { 00300 NetStackMemoryManager *mem_mngr = static_cast<NetStackMemoryManager *>(p->memory_manager); 00301 00302 net_stack_mem_buf_t *first_buffer = p->buffer; 00303 00304 struct pbuf *buf_next; 00305 for (struct pbuf *buf = p; buf != NULL; buf = buf_next) { 00306 00307 // Set actual memory buffer length 00308 mem_mngr->set_len(buf->buffer, buf->len); 00309 00310 // Trim the headroom away from buffer if set 00311 if (buf->payload_start < buf->payload) { 00312 memmove(buf->payload_start, buf->payload, buf->len); 00313 } 00314 00315 buf_next = buf->next; 00316 00317 // If not first buffer cat to first buffer and free 00318 if (buf->buffer != first_buffer) { 00319 mem_mngr->cat(first_buffer, buf->buffer); 00320 buf->buffer = NULL; 00321 ppp_memory_buffer_free(buf); 00322 } 00323 } 00324 00325 // Going to upper levels, do not deallocate the actual buffer 00326 p->buffer = NULL; 00327 ppp_memory_buffer_free(p); 00328 00329 return first_buffer; 00330 } 00331 00332 uint8_t ppp_memory_buffer_remove_header(pbuf *buffer, uint16_t header_len) 00333 { 00334 uint8_t *payload = static_cast<uint8_t *>(buffer->payload); 00335 payload += header_len; 00336 buffer->payload = payload; 00337 buffer->len -= header_len; 00338 return 0; 00339 } 00340 00341 uint8_t ppp_memory_buffer_add_header(struct pbuf *buffer, uint16_t header_len) 00342 { 00343 uint32_t payload_headroom_len = static_cast<uint8_t *>(buffer->payload) - static_cast<uint8_t *>(buffer->payload_start); 00344 00345 if (payload_headroom_len < header_len) { 00346 return 1; // failure 00347 } 00348 00349 buffer->payload = static_cast<uint8_t *>(buffer->payload) - header_len; 00350 buffer->len += header_len; 00351 00352 return 0; 00353 } 00354 00355 uint32_t ppp_sys_now(void) 00356 { 00357 return osKernelGetTickCount(); 00358 } 00359 00360 uint32_t ppp_sys_jiffies(void) 00361 { 00362 return ppp_sys_now(); 00363 } 00364 00365 sys_prot_t ppp_sys_arch_protect(void *service_ptr) 00366 { 00367 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(service_ptr); 00368 ppp_service_ptr->resource_lock(); 00369 00370 return (sys_prot_t) 1; 00371 } 00372 00373 void ppp_sys_arch_unprotect(void *service_ptr, sys_prot_t p) 00374 { 00375 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(service_ptr); 00376 ppp_service_ptr->resource_unlock(); 00377 } 00378 00379 #if PPP_TRACE_ENABLE 00380 void ppp_trace_to_ascii_hex_dump(int buffer, int len, char *data) 00381 { 00382 char prefix[10]; 00383 trace_buf_t *trace_buffer = NULL; 00384 if (buffer == OUTPUT_BUFFER) { 00385 strcpy(prefix, "O:"); 00386 trace_buffer = &output_trace_buffer; 00387 } else if (buffer == INPUT_BUFFER) { 00388 strcpy(prefix, "I:"); 00389 trace_buffer = &input_trace_buffer; 00390 } 00391 00392 static char line[100]; 00393 memset(line, 0, 100); 00394 int index = 0; 00395 00396 bool add_prefix = false; 00397 if (trace_buffer->buffer_index == 0) { 00398 index += sprintf(&line[index], "\n %" PRIi32 " len: %i buffer index %i line len %i \n", ppp_sys_now(), len, trace_buffer->buffer_index, trace_buffer->line_len); 00399 add_prefix = true; 00400 } 00401 00402 for (int i = 0; i < len; i++) { 00403 if ((trace_buffer->line_len % 16) == 0) { 00404 if (trace_buffer->line_len != 0) { 00405 index += sprintf(&line[index], "\n"); 00406 trace_buffer->buffer_index += sprintf(&trace_buffer->buffer[trace_buffer->buffer_index], "%s", line); 00407 index = 0; 00408 } 00409 00410 bool add_ppp_flag = false; 00411 if (add_prefix) { 00412 if (data[i] == 0xff || (data[i] == 0x57 && (data[i + 1] == 0x60 || data[i + 1] == 0x6a))) { 00413 add_ppp_flag = true; 00414 } 00415 } 00416 00417 index += sprintf(&line[index], "%s %06x%s%s", prefix, trace_buffer->line_len, add_prefix ? " 00 00 88 81" : "", add_ppp_flag ? " 7e" : ""); 00418 if (add_prefix) { 00419 trace_buffer->line_len += 4; 00420 } 00421 if (add_ppp_flag) { 00422 trace_buffer->line_len += 1; 00423 } 00424 add_prefix = false; 00425 } 00426 trace_buffer->line_len++; 00427 index += sprintf(&line[index], " %02x", data[i]); 00428 } 00429 00430 trace_buffer->buffer_index += sprintf(&trace_buffer->buffer[trace_buffer->buffer_index], "%s", line); 00431 } 00432 00433 void ppp_trace_to_ascii_hex_dump_print(int buffer) 00434 { 00435 trace_buf_t *trace_buffer = NULL; 00436 if (buffer == OUTPUT_BUFFER) { 00437 trace_buffer = &output_trace_buffer; 00438 } else if (buffer == INPUT_BUFFER) { 00439 trace_buffer = &input_trace_buffer; 00440 } 00441 00442 #if PPP_TRACE_BUFFER_SIZE == 0 00443 tr_info("%s", trace_buffer->buffer); 00444 #endif 00445 00446 #if PPP_TRACE_BUFFER_SIZE > 0 00447 cont_trace_buffer_index += sprintf(&cont_trace_buffer[cont_trace_buffer_index], "%s", trace_buffer->buffer); 00448 memset(trace_buffer->buffer, 0, BUFFER_SIZE); 00449 00450 if (cont_trace_buffer_index > (PPP_TRACE_BUFFER_SIZE - PPP_TRACE_BUFFER_SIZE / 5)) { 00451 cont_trace_buffer_index = 0; 00452 } 00453 #endif 00454 00455 trace_buffer->buffer_index = 0; 00456 trace_buffer->line_len = 0; 00457 } 00458 00459 #endif 00460 00461 void ppp_sys_timeout_callback(void *cb_ptr) 00462 { 00463 ppp_service_if_mutex->lock(); 00464 00465 int id = reinterpret_cast<int>(cb_ptr); 00466 00467 ppp_sys_timeout_handler handler = NULL; 00468 void *arg = NULL; 00469 00470 for (int8_t i = 0; i < PPP_TIMER_NUM; i++) { 00471 if (timeout[i] && timeout[i]->id == id) { 00472 handler = timeout[i]->handler; 00473 arg = timeout[i]->arg; 00474 free(timeout[i]); 00475 timeout[i] = NULL; 00476 //tr_info("sys timer timeout, i: %i h/a: %p %p, id: %i", i, handler, arg, timeout[i]->equeue_id); 00477 } 00478 } 00479 00480 ppp_service_if_mutex->unlock(); 00481 00482 if (handler) { 00483 handler(arg); 00484 } else { 00485 tr_error("Cancelled timeout"); 00486 } 00487 } 00488 00489 void ppp_sys_timeout(void *service_ptr, u32_t msecs, ppp_sys_timeout_handler handler, void *arg) 00490 { 00491 ppp_service *ppp_service_ptr = static_cast<ppp_service *>(service_ptr); 00492 00493 ppp_service_if_mutex->lock(); 00494 00495 int8_t free_index = -1; 00496 00497 for (int8_t i = 0; i < PPP_TIMER_NUM; i++) { 00498 if (timeout[i] == NULL && free_index < 0) { 00499 free_index = i; 00500 } else if (timeout[i] != NULL && timeout[i]->handler == handler && timeout[i]->arg == arg) { 00501 tr_error("Timeout already set"); 00502 ppp_service_if_mutex->unlock(); 00503 return; 00504 } 00505 } 00506 00507 if (free_index < 0) { 00508 tr_error("No free timeouts"); 00509 ppp_service_if_mutex->unlock(); 00510 } 00511 00512 timeout[free_index] = static_cast<ppp_sys_timeout_t *>(malloc(sizeof(ppp_sys_timeout_t))); 00513 if (!timeout[free_index]) { 00514 tr_error("No free memory for timeout"); 00515 ppp_service_if_mutex->unlock(); 00516 return; 00517 } 00518 00519 void *cb_ptr = reinterpret_cast<void *>(ppp_service_sys_timeout_id); 00520 int unique_id = ppp_service_ptr->event_queue_get()->call_in(msecs, mbed::callback(ppp_sys_timeout_callback, cb_ptr)); 00521 if (unique_id == 0) { 00522 tr_error("No free memory for timeout equeue"); 00523 ppp_service_if_mutex->unlock(); 00524 return; 00525 } 00526 00527 timeout[free_index]->ppp_drv = ppp_service_ptr; 00528 timeout[free_index]->handler = handler; 00529 timeout[free_index]->arg = arg; 00530 timeout[free_index]->equeue_id = unique_id; 00531 timeout[free_index]->id = ppp_service_sys_timeout_id++; 00532 00533 //tr_info("sys timer start, i: %i h/a: %p %p, t: %" PRIx32 " id: %i", free_index, handler, arg, msecs, unique_id); 00534 00535 ppp_service_if_mutex->unlock(); 00536 } 00537 00538 void ppp_sys_untimeout(ppp_sys_timeout_handler handler, void *arg) 00539 { 00540 ppp_service_if_mutex->lock(); 00541 00542 for (int8_t i = 0; i < PPP_TIMER_NUM; i++) { 00543 if (timeout[i] != NULL && timeout[i]->handler == handler && timeout[i]->arg == arg) { 00544 int unique_id = timeout[i]->equeue_id; 00545 timeout[i]->ppp_drv->event_queue_get()->cancel(unique_id); 00546 //tr_info("sys timer cancel, i: %i h/a: %p %p, id: %i", i, timeout[i]->handler, timeout[i]->arg, unique_id); 00547 free(timeout[i]); 00548 timeout[i] = NULL; 00549 } 00550 } 00551 00552 ppp_service_if_mutex->unlock(); 00553 } 00554 00555 } // extern "C" 00556 00557 #if PPP_TRACE_ENABLE && PPP_TRACE_BUFFER_SIZE > 0 00558 void ppp_trace_to_ascii_hex_dump_print_final(void) 00559 { 00560 int start_i = 0; 00561 00562 for (int i = 0; i < PPP_TRACE_BUFFER_SIZE; i++) { 00563 if (cont_trace_buffer[i] == '\n' || cont_trace_buffer[i] == '\0') { 00564 memcpy(output_trace_buffer.buffer, &cont_trace_buffer[start_i], i - start_i); 00565 output_trace_buffer.buffer[i - start_i] = 0; 00566 00567 tr_info("%s", output_trace_buffer.buffer); 00568 00569 if (cont_trace_buffer[i] == '\0') { 00570 break; 00571 } 00572 00573 start_i = i + 1; 00574 } 00575 } 00576 } 00577 #endif 00578 00579 #endif
Generated on Tue Jul 12 2022 13:54:42 by
