Porting PicoTCP WIP

This commit is contained in:
2025-10-29 14:29:06 +01:00
parent 6722f42e68
commit 815c2239fe
464 changed files with 235009 additions and 24 deletions

View File

@ -0,0 +1,35 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#define dbg(...) do {} while(0)
/******************/
/*** MACHINE CONFIGURATION ***/
/* Temporary (POSIX) stuff. */
#include <string.h>
#include <unistd.h>
extern volatile uint32_t __str9_tick;
#define pico_native_malloc(x) calloc(x, 1)
#define pico_native_free(x) free(x)
static inline unsigned long PICO_TIME(void)
{
register uint32_t tick = __str9_tick;
return tick / 1000;
}
static inline unsigned long PICO_TIME_MS(void)
{
return __str9_tick;
}
static inline void PICO_IDLE(void)
{
unsigned long tick_now = __str9_tick;
while(tick_now == __str9_tick) ;
}

View File

@ -0,0 +1,61 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
/*** MACHINE CONFIGURATION ***/
/* Temporary (POSIX) stuff. */
#include <string.h>
#include <unistd.h>
/* Temporary debugging stuff. */
#include <stdarg.h>
#include "halUart.h"
#include <stdio.h>
static void print_uart(char *str)
{
int i, len;
len = (int)strlen(str);
for (i = 0; i < len; i++) {
HAL_UartWriteByte(str[i]);
if (HAL_UartTxFull())
HAL_UartFlush();
}
}
static inline void sam_dbg(const char *format, ...)
{
char msg[128] = { 0 };
va_list args;
va_start(args, format);
vsnprintf(msg, 256, format, args);
va_end(args);
print_uart(msg);
}
//#define dbg sam_dbg
#define dbg(...) do { } while(0)
extern volatile uint32_t sam_tick;
#define pico_zalloc(x) calloc(x, 1)
#define pico_free(x) free(x)
static inline unsigned long PICO_TIME(void)
{
register uint32_t tick = sam_tick;
return tick / 1000;
}
static inline unsigned long PICO_TIME_MS(void)
{
return sam_tick;
}
static inline void PICO_IDLE(void)
{
unsigned long tick_now = sam_tick;
while(tick_now == sam_tick) ;
}

View File

@ -0,0 +1,39 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#define dbg(...) do {} while(0)
/* #define dbg printf */
/*************************/
/*** MACHINE CONFIGURATION ***/
/* Temporary (POSIX) stuff. */
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include "pico_mm.h"
extern volatile uint32_t __avr_tick;
#define pico_zalloc(x) calloc(x, 1)
#define pico_free(x) free(x)
static inline unsigned long PICO_TIME(void)
{
register uint32_t tick = __avr_tick;
return tick / 1000;
}
static inline unsigned long PICO_TIME_MS(void)
{
return __avr_tick;
}
static inline void PICO_IDLE(void)
{
unsigned long tick_now = __avr_tick;
while(tick_now == __avr_tick) ;
}

View File

@ -0,0 +1,12 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef _INCLUDE_PICO_CORTEX_M
#define _INCLUDE_PICO_CORTEX_M
#include "pico_generic_gcc.h"
#endif /* PICO_CORTEX_M */

View File

@ -0,0 +1,44 @@
/*
* This is a picoTCP arch file for the DOS 16 bit target using OpenWatcom v1.9
* Copyright (C) 2015 Mateusz Viste
*
* This code is donated to the picoTCP project, and shares the same licensing,
* that is GNU GPLv2.
*
* See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*/
#include <dos.h> /* provides int86() along with the union REGS type */
#ifndef PICO_SUPPORT_DOS_WATCOM
#define PICO_SUPPORT_DOS_WATCOM
#define dbg(...)
#define pico_zalloc(x) calloc(x, 1)
#define pico_free(x) free(x)
static inline unsigned long PICO_TIME_MS(void)
{
union REGS regs;
unsigned long ticks;
regs.h.ah = 0; /* get system time (IBM BIOS call) - INT 1A,0 */
int86(0x1A, &regs, &regs);
ticks = regs.x.cx; /* number of ticks since midnight (high word) */
ticks <<= 16;
ticks |= regs.x.dx; /* number of ticks since midnight (low word) */
return (ticks * 55); /* a tick is 55ms because the i8253 PIT runs at 18.2 Hz */
}
static inline unsigned long PICO_TIME(void)
{
return (PICO_TIME_MS() / 1000);
}
static inline void PICO_IDLE(void)
{
union REGS regs;
int86(0x28, &regs, &regs); /* DOS 2+ IDLE INTERRUPT */
}
#endif /* PICO_SUPPORT_DOS_WATCOM */

View File

@ -0,0 +1,58 @@
/*********************************************************************
PicoTCP. Copyright (c) 2014-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef _INCLUDE_PICO_ESP8266
#define _INCLUDE_PICO_ESP8266
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "pico_constants.h"
/* -------------- DEBUG ------------- */
/* #define dbg(...) */
#define dbg printf
/* -------------- MEMORY ------------- */
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define pico_free vPortFree
static inline void *pico_zalloc(size_t size)
{
void *ptr = (void *)pvPortMalloc(size);
if(ptr)
memset(ptr, 0u, size);
return ptr;
}
/* -------------- TIME ------------- */
extern volatile uint32_t esp_tick;
static inline pico_time PICO_TIME_MS(void)
{
return (pico_time) esp_tick;
}
static inline pico_time PICO_TIME(void)
{
return PICO_TIME_MS() / 1000;
}
static inline void PICO_IDLE(void)
{
uint32_t now = esp_tick;
while (now == esp_tick)
;
}
#endif

View File

@ -0,0 +1,117 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef _INCLUDE_PICO_GCC
#define _INCLUDE_PICO_GCC
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "pico_constants.h"
/* #define TIME_PRESCALE */
/* monotonically increasing tick,
* typically incremented every millisecond in a systick interrupt */
extern volatile unsigned int pico_ms_tick;
#define dbg(...)
#ifdef PICO_SUPPORT_PTHREAD
#define PICO_SUPPORT_MUTEX
#endif
#ifdef PICO_SUPPORT_RTOS
#define PICO_SUPPORT_MUTEX
extern void *pico_mutex_init(void);
extern void pico_mutex_lock(void*);
extern void pico_mutex_unlock(void*);
extern void *pvPortMalloc( size_t xSize );
extern void vPortFree( void *pv );
#define pico_free(x) vPortFree(x)
#define free(x) vPortFree(x)
static inline void *pico_zalloc(size_t size)
{
void *ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0u, size);
return ptr;
}
/* time prescaler */
#ifdef TIME_PRESCALE
extern int32_t prescale_time;
#endif
static inline pico_time PICO_TIME_MS()
{
#ifdef TIME_PRESCALE
return pico_ms_tick << prescale_time;
#else
return pico_ms_tick;
#endif
}
static inline pico_time PICO_TIME()
{
#ifdef TIME_PRESCALE
return (pico_ms_tick / 1000) << prescale_time;
#else
return (pico_ms_tick / 1000);
#endif
}
static inline void PICO_IDLE(void)
{
pico_time now = PICO_TIME_MS();
while(now == PICO_TIME_MS()) ;
}
#else /* NO RTOS SUPPORT */
#ifdef MEM_MEAS
/* These functions should be implemented elsewhere */
extern void *memmeas_zalloc(size_t size);
extern void memmeas_free(void *);
#define pico_free(x) memmeas_free(x)
#define pico_zalloc(x) memmeas_zalloc(x)
#else
/* Use plain C-lib malloc and free */
#define pico_free(x) free(x)
static inline void *pico_zalloc(size_t size)
{
void *ptr = malloc(size);
if(ptr)
memset(ptr, 0u, size);
return ptr;
}
#endif
static inline pico_time PICO_TIME_MS(void)
{
return (pico_time)pico_ms_tick;
}
static inline pico_time PICO_TIME(void)
{
return (pico_time)(PICO_TIME_MS() / 1000);
}
static inline void PICO_IDLE(void)
{
unsigned int now = pico_ms_tick;
while(now == pico_ms_tick) ;
}
#endif /* IFNDEF RTOS */
#endif /* PICO_GCC */

View File

@ -0,0 +1,33 @@
#ifndef PICO_SUPPORT_LINUX
#define PICO_SUPPORT_LINUX
#include "linux/types.h"
#include "linux/mm.h"
#include "linux/slab.h"
#include "linux/jiffies.h"
#define dbg printk
#define pico_zalloc(x) kcalloc(x, 1, GFP_ATOMIC) /* All allocations are GFP_ATOMIC for now */
#define pico_free(x) kfree(x)
static inline unsigned long PICO_TIME(void)
{
return (unsigned long)(jiffies_to_msecs(jiffies) / 1000);
}
static inline unsigned long PICO_TIME_MS(void)
{
return (unsigned long)jiffies_to_msecs(jiffies);
}
static inline void PICO_IDLE(void)
{
unsigned long now = jiffies;
while (now == jiffies) {
;
}
}
#endif

View File

@ -0,0 +1,185 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
File: pico_mbed.h
Author: Toon Peters
*********************************************************************/
#ifndef PICO_SUPPORT_MBED
#define PICO_SUPPORT_MBED
#include <stdio.h>
#include <pico_queue.h>
/* #include "mbed.h" */
/* #include "serial_api.h" */
/* #define TIME_PRESCALE */
/* #define PICO_MEASURE_STACK */
/* #define MEMORY_MEASURE */
/*
Debug needs initialization:
* void serial_init (serial_t *obj, PinName tx, PinName rx);
* void serial_baud (serial_t *obj, int baudrate);
* void serial_format (serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
*/
#define dbg(...)
/*
#define MEMORY_MEASURE
#define JENKINS_DEBUG
*/
/* Intended for Mr. Jenkins endurance test loggings */
#ifdef JENKINS_DEBUG
#include "PicoTerm.h"
#define jenkins_dbg ptm_dbg
#endif
#ifdef PICO_MEASURE_STACK
extern int freeStack;
#define STACK_TOTAL_WORDS 1000u
#define STACK_PATTERN (0xC0CAC01Au)
void stack_fill_pattern(void *ptr);
void stack_count_free_words(void *ptr);
int stack_get_free_words(void);
#else
#define stack_fill_pattern(...) do {} while(0)
#define stack_count_free_words(...) do {} while(0)
#define stack_get_free_words() (0)
#endif
#ifdef MEMORY_MEASURE /* in case, comment out the two defines above me. */
extern uint32_t max_mem;
extern uint32_t cur_mem;
struct mem_chunk_stats {
#ifdef MEMORY_MEASURE_ADV
uint32_t signature;
void *mem;
#endif
uint32_t size;
};
static inline void *pico_zalloc(int x)
{
struct mem_chunk_stats *stats;
if ((cur_mem + x) > (10 * 1024))
return NULL;
stats = (struct mem_chunk_stats *)calloc(x + sizeof(struct mem_chunk_stats), 1);
#ifdef MEMORY_MEASURE_ADV
stats->signature = 0xdeadbeef;
stats->mem = ((uint8_t *)stats) + sizeof(struct mem_chunk_stats);
#endif
stats->size = x;
/* Intended for Mr. Jenkins endurance test loggings */
#ifdef JENKINS_DEBUG
if (!stats) {
jenkins_dbg(">> OUT OF MEM\n");
while(1) ;
;
}
#endif
cur_mem += x;
if (cur_mem > max_mem) {
max_mem = cur_mem;
/* printf("max mem: %lu\n", max_mem); */
}
#ifdef MEMORY_MEASURE_ADV
return (void*)(stats->mem);
#else
return (void*) (((uint8_t *)stats) + sizeof(struct mem_chunk_stats));
#endif
}
static inline void pico_free(void *x)
{
struct mem_chunk_stats *stats = (struct mem_chunk_stats *) ((uint8_t *)x - sizeof(struct mem_chunk_stats));
#ifdef JENKINS_DEBUG
#ifdef MEMORY_MEASURE_ADV
if ((stats->signature != 0xdeadbeef) || (x != stats->mem)) {
jenkins_dbg(">> FREE ERROR: caller is %p\n", __builtin_return_address(0));
while(1) ;
;
}
#endif
#endif
cur_mem -= stats->size;
memset(stats, 0, sizeof(struct mem_chunk_stats));
free(stats);
}
#else
#define pico_zalloc(x) calloc(x, 1)
#define pico_free(x) free(x)
#endif
#define PICO_SUPPORT_MUTEX
extern void *pico_mutex_init(void);
extern void pico_mutex_lock(void*);
extern void pico_mutex_unlock(void*);
extern void pico_mutex_deinit(void*);
extern uint32_t os_time;
extern pico_time local_time;
extern uint32_t last_os_time;
#ifdef TIME_PRESCALE
extern int32_t prescale_time;
#endif
#define UPDATE_LOCAL_TIME() do {local_time = local_time + ((pico_time)os_time - (pico_time)last_os_time);last_os_time = os_time;} while(0)
static inline pico_time PICO_TIME(void)
{
UPDATE_LOCAL_TIME();
#ifdef TIME_PRESCALE
return (prescale_time < 0) ? (pico_time)(local_time / 1000 << (-prescale_time)) : \
(pico_time)(local_time / 1000 >> prescale_time);
#else
return (pico_time)(local_time / 1000);
#endif
}
static inline pico_time PICO_TIME_MS(void)
{
UPDATE_LOCAL_TIME();
#ifdef TIME_PRESCALE
return (prescale_time < 0) ? (pico_time)(local_time << (-prescale_time)) : \
(pico_time)(local_time >> prescale_time);
#else
return (pico_time)local_time;
#endif
}
static inline void PICO_IDLE(void)
{
/* TODO needs implementation */
}
/*
static inline void PICO_DEBUG(const char * formatter, ... )
{
char buffer[256];
char *ptr;
va_list args;
va_start(args, formatter);
vsnprintf(buffer, 256, formatter, args);
ptr = buffer;
while(*ptr != '\0')
serial_putc(serial_t *obj, (int) (*(ptr++)));
va_end(args);
//TODO implement serial_t
}*/
#endif

View File

@ -0,0 +1,26 @@
#ifndef PICO_SUPPORT_MOP2
#define PICO_SUPPORT_MOP2
#include "dlmalloc/malloc.h"
#include "time/time.h"
#include "kprintf.h"
// proc/proc.c
extern uint64_t uptime_ms;
#define dbg kprintf
#define pico_zalloc(x) (dlmalloc((x)))
#define pico_free(x) (dlfree((x)))
static inline unsigned long PICO_TIME(void) {
return uptime_ms / 1000;
}
static inline unsigned long PICO_TIME_MS(void) {
return uptime_ms;
}
static inline void PICO_IDLE(void) {
}
#endif // PICO_SUPPORT_MOP2

View File

@ -0,0 +1,38 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef _INCLUDE_PICO_LPC
#define _INCLUDE_PICO_LPC
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "pico_constants.h"
extern pico_time msp430_time_s(void);
extern pico_time msp430_time_ms(void);
extern void *malloc(size_t);
extern void free(void *);
#define PICO_TIME() msp430_time_s()
#define PICO_TIME_MS() msp430_time_ms()
#define PICO_IDLE() do {} while(0)
#define pico_free(x) free(x)
static inline void *pico_zalloc(size_t size)
{
void *ptr = malloc(size);
if(ptr)
memset(ptr, 0u, size);
return ptr;
}
#define dbg(...)
#endif

View File

@ -0,0 +1,22 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef PICO_SUPPORT_ARCHNONE
#define PICO_SUPPORT_ARCHNONE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#define dbg(...) do {} while(0)
#define pico_zalloc(x) NULL
#define pico_free(x) do {} while(0)
#define PICO_TIME() 666
#define PICO_TIME_MS() 666000
#define PICO_IDLE() do {} while(0)
#endif /* PICO_SUPPORT_ARCHNONE */

View File

@ -0,0 +1,100 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef PICO_SUPPORT_PIC24
#define PICO_SUPPORT_PIC24
#define dbg printf
/* #define dbg(...) */
/*************************/
/*** MACHINE CONFIGURATION ***/
#include <stdio.h>
#include <stdint.h>
/* #include "phalox_development_board.h" */
#ifndef __PIC24F__
#define __PIC24F__
#endif
/*
#ifndef __PIC24FJ256GA106__
#define __PIC24FJ256GA106__
#endif
*/
#ifndef PICO_MAX_SOCKET_FRAMES
#define PICO_MAX_SOCKET_FRAMES 16
#endif
/* Device header file */
#if defined(__PIC24E__)
# include <p24Exxxx.h>
#elif defined(__PIC24F__)
# include <p24Fxxxx.h>
#elif defined(__PIC24H__)
# include <p24Hxxxx.h>
#endif
#define TIMBASE_INT_E IEC0bits.T2IE
#ifdef PICO_SUPPORT_DEBUG_MEMORY
static inline void *pico_zalloc(int len)
{
/* dbg("%s: Alloc object of len %d, caller: %p\n", __FUNCTION__, len, __builtin_return_address(0)); */
return calloc(len, 1);
}
static inline void pico_free(void *tgt)
{
/* dbg("%s: Discarded object @%p, caller: %p\n", __FUNCTION__, tgt, __builtin_return_address(0)); */
free(tgt);
}
#else
# define pico_zalloc(x) calloc(x, 1)
# define pico_free(x) free(x)
#endif
extern void *pvPortMalloc( size_t xWantedSize );
extern volatile pico_time __pic24_tick;
static inline unsigned long PICO_TIME(void)
{
unsigned long tick;
/* Disable timer interrupts */
TIMBASE_INT_E = 0;
tick = __pic24_tick;
/* Enable timer interrupts */
TIMBASE_INT_E = 1;
return tick / 1000;
}
static inline unsigned long PICO_TIME_MS(void)
{
unsigned long tick;
/* Disable timer interrupts */
TIMBASE_INT_E = 0;
tick = __pic24_tick;
/* Enable timer interrupts */
TIMBASE_INT_E = 1;
return tick;
}
static inline void PICO_IDLE(void)
{
unsigned long tick_now;
/* Disable timer interrupts */
TIMBASE_INT_E = 0;
tick_now = (unsigned long)pico_tick;
/* Enable timer interrupts */
TIMBASE_INT_E = 1;
/* Doesn't matter that this call isn't interrupt safe, */
/* we just check for the value to change */
while(tick_now == __pic24_tick) ;
}
#endif

View File

@ -0,0 +1,54 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef _INCLUDE_PICO_PIC32
#define _INCLUDE_PICO_PIC32
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "pico_constants.h"
/* monotonically increasing tick,
* typically incremented every millisecond in a systick interrupt */
extern volatile unsigned int pico_ms_tick;
#ifdef PIC32_NO_PRINTF
#define dbg(...) do {} while(0)
#else
#define dbg printf
#endif
/* Use plain C-lib malloc and free */
#define pico_free(x) free(x)
static inline void *pico_zalloc(size_t size)
{
void *ptr = malloc(size);
if(ptr)
memset(ptr, 0u, size);
return ptr;
}
static inline pico_time PICO_TIME_MS(void)
{
return (pico_time)pico_ms_tick;
}
static inline pico_time PICO_TIME(void)
{
return (pico_time)(PICO_TIME_MS() / 1000);
}
static inline void PICO_IDLE(void)
{
unsigned int now = pico_ms_tick;
while(now == pico_ms_tick) ;
}
#endif /* PICO_PIC32 */

View File

@ -0,0 +1,137 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef PICO_SUPPORT_POSIX
#define PICO_SUPPORT_POSIX
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
/*
#define MEMORY_MEASURE
#define TIME_PRESCALE
#define PICO_SUPPORT_THREADING
*/
#define dbg printf
#define stack_fill_pattern(...) do {} while(0)
#define stack_count_free_words(...) do {} while(0)
#define stack_get_free_words() (0)
/* measure allocated memory */
#ifdef MEMORY_MEASURE
extern uint32_t max_mem;
extern uint32_t cur_mem;
static inline void *pico_zalloc(int x)
{
uint32_t *ptr;
if ((cur_mem + x) > (10 * 1024))
return NULL;
ptr = (uint32_t *)calloc(x + 4, 1);
*ptr = (uint32_t)x;
cur_mem += x;
if (cur_mem > max_mem) {
max_mem = cur_mem;
}
return (void*)(ptr + 1);
}
static inline void pico_free(void *x)
{
uint32_t *ptr = (uint32_t*)(((uint8_t *)x) - 4);
cur_mem -= *ptr;
free(ptr);
}
#else
#define pico_zalloc(x) calloc(x, 1)
#define pico_free(x) free(x)
#endif
/* time prescaler */
#ifdef TIME_PRESCALE
extern int32_t prescale_time;
#endif
#if defined(PICO_SUPPORT_RTOS) || defined (PICO_SUPPORT_PTHREAD)
/* pico_ms_tick must be defined */
extern volatile uint32_t pico_ms_tick;
static inline uint32_t PICO_TIME(void)
{
#ifdef TIME_PRESCALE
return (pico_ms_tick / 1000) << prescale_time;
#else
return (pico_ms_tick / 1000);
#endif
}
static inline uint32_t PICO_TIME_MS(void)
{
#ifdef TIME_PRESCALE
return pico_ms_tick << prescale_time;
#else
return pico_ms_tick;
#endif
}
#else
static inline uint32_t PICO_TIME(void)
{
struct timeval t;
gettimeofday(&t, NULL);
#ifdef TIME_PRESCALE
return (prescale_time < 0) ? (uint32_t)(t.tv_sec / 1000 << (-prescale_time)) : \
(uint32_t)(t.tv_sec / 1000 >> prescale_time);
#else
return (uint32_t)t.tv_sec;
#endif
}
static inline uint32_t PICO_TIME_MS(void)
{
struct timeval t;
gettimeofday(&t, NULL);
#ifdef TIME_PRESCALER
uint32_t tmp = ((t.tv_sec * 1000) + (t.tv_usec / 1000));
return (prescale_time < 0) ? (uint32_t)(tmp / 1000 << (-prescale_time)) : \
(uint32_t)(tmp / 1000 >> prescale_time);
#else
return (uint32_t)((t.tv_sec * 1000) + (t.tv_usec / 1000));
#endif
}
#endif
#ifdef PICO_SUPPORT_THREADING
#define PICO_SUPPORT_MUTEX
/* mutex implementations */
extern void *pico_mutex_init(void);
extern void pico_mutex_lock(void *mux);
extern void pico_mutex_unlock(void *mux);
/* semaphore implementations (only used in wrapper code) */
extern void *pico_sem_init(void);
extern void pico_sem_destroy(void *sem);
extern void pico_sem_post(void *sem);
/* returns -1 on timeout (in ms), else returns 0 */
/* if timeout < 0, the semaphore waits forever */
extern int pico_sem_wait(void *sem, int timeout);
/* thread implementations */
extern void *pico_thread_create(void *(*routine)(void *), void *arg);
#endif /* PICO_SUPPORT_THREADING */
static inline void PICO_IDLE(void)
{
usleep(5000);
}
#endif /* PICO_SUPPORT_POSIX */

View File

@ -0,0 +1,107 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#define MAX_BLOCK_SIZE 1600
#define MAX_BLOCK_COUNT 16
#define DECLARE_HEAP(type, orderby) \
struct heap_ ## type { \
uint32_t size; \
uint32_t n; \
type *top[MAX_BLOCK_COUNT]; \
}; \
typedef struct heap_ ## type heap_ ## type; \
static inline type* heap_get_element(struct heap_ ## type *heap, uint32_t idx) \
{ \
uint32_t elements_per_block = MAX_BLOCK_SIZE/sizeof(type); \
return &heap->top[idx/elements_per_block][idx%elements_per_block];\
} \
static inline int8_t heap_increase_size(struct heap_ ## type *heap) \
{\
type *newTop; \
uint32_t elements_per_block = MAX_BLOCK_SIZE/sizeof(type); \
uint32_t elements = (heap->n + 1)%elements_per_block;\
elements = elements?elements:elements_per_block;\
if (heap->n+1 > elements_per_block * MAX_BLOCK_COUNT){\
return -1;\
}\
newTop = PICO_ZALLOC(elements*sizeof(type)); \
if(!newTop) { \
return -1; \
} \
if (heap->top[heap->n/elements_per_block]) { \
memcpy(newTop, heap->top[heap->n/elements_per_block], (elements - 1) * sizeof(type)); \
PICO_FREE(heap->top[heap->n/elements_per_block]); \
} \
heap->top[heap->n/elements_per_block] = newTop; \
heap->size++; \
return 0; \
}\
static inline int heap_insert(struct heap_ ## type *heap, type * el) \
{ \
type *half; \
uint32_t i; \
if (++heap->n >= heap->size) { \
if (heap_increase_size(heap)){ \
heap->n--; \
return -1; \
} \
} \
if (heap->n == 1) { \
memcpy(heap_get_element(heap, 1), el, sizeof(type)); \
return 0; \
} \
i = heap->n; \
half = heap_get_element(heap, i/2); \
while ( (i > 1) && (half->orderby > el->orderby) ) { \
memcpy(heap_get_element(heap, i), heap_get_element(heap, i / 2), sizeof(type)); \
i /= 2; \
half = heap_get_element(heap, i/2); \
} \
memcpy(heap_get_element(heap, i), el, sizeof(type)); \
return 0; \
} \
static inline int heap_peek(struct heap_ ## type *heap, type * first) \
{ \
type *last; \
type *left_child; \
type *right_child; \
uint32_t i, child; \
if(heap->n == 0) { \
return -1; \
} \
memcpy(first, heap_get_element(heap, 1), sizeof(type)); \
last = heap_get_element(heap, heap->n--); \
for(i = 1; (i * 2u) <= heap->n; i = child) { \
child = 2u * i; \
right_child = heap_get_element(heap, child+1); \
left_child = heap_get_element(heap, child); \
if ((child != heap->n) && \
(right_child->orderby \
< left_child->orderby)) \
child++; \
left_child = heap_get_element(heap, child); \
if (last->orderby > \
left_child->orderby) \
memcpy(heap_get_element(heap,i), heap_get_element(heap,child), \
sizeof(type)); \
else \
break; \
} \
memcpy(heap_get_element(heap, i), last, sizeof(type)); \
return 0; \
} \
static inline type *heap_first(heap_ ## type * heap) \
{ \
if (heap->n == 0) \
return NULL; \
return heap_get_element(heap, 1); \
} \
static inline heap_ ## type *heap_init(void) \
{ \
heap_ ## type * p = (heap_ ## type *)PICO_ZALLOC(sizeof(heap_ ## type)); \
return p; \
} \

View File

@ -0,0 +1,127 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_ADDRESSING
#define INCLUDE_PICO_ADDRESSING
#include "pico_config.h"
#include "pico_constants.h"
PACKED_STRUCT_DEF pico_ip4
{
uint32_t addr;
};
PACKED_STRUCT_DEF pico_ip6
{
uint8_t addr[16];
};
union pico_address
{
struct pico_ip4 ip4;
struct pico_ip6 ip6;
};
/******************************************************************************
* Ethernet Address Definitions
******************************************************************************/
PACKED_STRUCT_DEF pico_eth
{
uint8_t addr[6];
uint8_t padding[2];
};
extern const uint8_t PICO_ETHADDR_ALL[];
/******************************************************************************
* Generic 6LoWPAN Address Definitions
******************************************************************************/
/* 6lowpan supports 16-bit short addresses */
PACKED_STRUCT_DEF pico_6lowpan_short
{
uint16_t addr;
};
/* And also EUI-64 addresses */
PACKED_STRUCT_DEF pico_6lowpan_ext
{
uint8_t addr[8];
};
/* Address memory as either a short 16-bit address or a 64-bit address */
union pico_6lowpan_u
{
uint8_t data[8];
struct pico_6lowpan_short _short;
struct pico_6lowpan_ext _ext;
};
/* Info data structure to pass to pico_device_init by the device driver */
struct pico_6lowpan_info
{
struct pico_6lowpan_short addr_short;
struct pico_6lowpan_ext addr_ext;
struct pico_6lowpan_short pan_id;
};
/* Different addressing modes for IEEE802.15.4 addresses */
#define AM_6LOWPAN_NONE (0u)
#define AM_6LOWPAN_RES (1u)
#define AM_6LOWPAN_SHORT (2u)
#define AM_6LOWPAN_EXT (3u)
#define SIZE_6LOWPAN_SHORT (2u)
#define SIZE_6LOWPAN_EXT (8u)
#define SIZE_6LOWPAN(m) (((m) == 2) ? (2) : (((m) == 3) ? (8) : (0)))
/******************************************************************************
* Generic 6LoWPAN Address Definitions
******************************************************************************/
/* Storage data structure for IEEE802.15.4 addresses */
struct pico_802154
{
union pico_6lowpan_u addr;
uint8_t mode;
};
/******************************************************************************
* Link Layer addresses
******************************************************************************/
#define IID_16(iid) (0 == (iid)[2] && 0xff == (iid)[3] && 0xfe == (iid)[4] && 0 == (iid)[5])
enum pico_ll_mode
{
LL_MODE_ETHERNET = 0,
#ifdef PICO_SUPPORT_802154
LL_MODE_IEEE802154,
#endif
};
union pico_ll_addr
{
struct pico_eth eth;
struct pico_802154 pan;
};
PACKED_STRUCT_DEF pico_trans
{
uint16_t sport;
uint16_t dport;
};
/* Here are some protocols. */
#define PICO_PROTO_IPV4 0
#define PICO_PROTO_ICMP4 1
#define PICO_PROTO_IGMP 2
#define PICO_PROTO_TCP 6
#define PICO_PROTO_UDP 17
#define PICO_PROTO_IPV6 41
#define PICO_PROTO_ICMP6 58
#endif

View File

@ -0,0 +1,245 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#include "pico_defines.h"
#ifndef INCLUDE_PICO_CONFIG
#define INCLUDE_PICO_CONFIG
#ifndef __KERNEL__
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#else
#include <linux/types.h>
#endif
#if defined __IAR_SYSTEMS_ICC__ || defined ATOP
# define PACKED_STRUCT_DEF __packed struct
# define PEDANTIC_STRUCT_DEF __packed struct
# define PACKED_UNION_DEF __packed union
# define PACKED __packed
# define WEAK
#elif defined __WATCOMC__
# define PACKED_STRUCT_DEF _Packed struct
# define PEDANTIC_STRUCT_DEF struct
# define PACKED_UNION_DEF _Packed union
# define WEAK
#else
# define PACKED_STRUCT_DEF struct __attribute__((packed))
# define PEDANTIC_STRUCT_DEF struct
# define PACKED_UNION_DEF union /* Sane compilers do not require packed unions */
# define PACKED __attribute__((packed))
# define WEAK __attribute__((weak))
# ifdef __GNUC__
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# if ((GCC_VERSION >= 40800))
# define BYTESWAP_GCC
# endif
# endif
#endif
#ifdef PICO_BIGENDIAN
# define PICO_IDETH_IPV4 0x0800
# define PICO_IDETH_ARP 0x0806
# define PICO_IDETH_IPV6 0x86DD
# define PICO_ARP_REQUEST 0x0001
# define PICO_ARP_REPLY 0x0002
# define PICO_ARP_HTYPE_ETH 0x0001
#define short_be(x) (x)
#define long_be(x) (x)
#define long_long_be(x) (x)
static inline uint16_t short_from(void *_p)
{
unsigned char *p = (unsigned char *)_p;
uint16_t r, p0, p1;
p0 = p[0];
p1 = p[1];
r = (p0 << 8) + p1;
return r;
}
static inline uint32_t long_from(void *_p)
{
unsigned char *p = (unsigned char *)_p;
uint32_t r, p0, p1, p2, p3;
p0 = p[0];
p1 = p[1];
p2 = p[2];
p3 = p[3];
r = (p0 << 24) + (p1 << 16) + (p2 << 8) + p3;
return r;
}
#else
static inline uint16_t short_from(void *_p)
{
unsigned char *p = (unsigned char *)_p;
uint16_t r, _p0, _p1;
_p0 = p[0];
_p1 = p[1];
r = (uint16_t)((_p1 << 8u) + _p0);
return r;
}
static inline uint32_t long_from(void *_p)
{
unsigned char *p = (unsigned char *)_p;
uint32_t r, _p0, _p1, _p2, _p3;
_p0 = p[0];
_p1 = p[1];
_p2 = p[2];
_p3 = p[3];
r = (_p3 << 24) + (_p2 << 16) + (_p1 << 8) + _p0;
return r;
}
# define PICO_IDETH_IPV4 0x0008
# define PICO_IDETH_ARP 0x0608
# define PICO_IDETH_IPV6 0xDD86
# define PICO_ARP_REQUEST 0x0100
# define PICO_ARP_REPLY 0x0200
# define PICO_ARP_HTYPE_ETH 0x0100
# ifndef BYTESWAP_GCC
static inline uint16_t short_be(uint16_t le)
{
return (uint16_t)(((le & 0xFFu) << 8) | ((le >> 8u) & 0xFFu));
}
static inline uint32_t long_be(uint32_t le)
{
uint8_t *b = (uint8_t *)&le;
uint32_t be = 0;
uint32_t b0, b1, b2;
b0 = b[0];
b1 = b[1];
b2 = b[2];
be = b[3] + (b2 << 8) + (b1 << 16) + (b0 << 24);
return be;
}
static inline uint64_t long_long_be(uint64_t le)
{
uint8_t *b = (uint8_t *)&le;
uint64_t be = 0;
uint64_t b0, b1, b2, b3, b4, b5, b6;
b0 = b[0];
b1 = b[1];
b2 = b[2];
b3 = b[3];
b4 = b[4];
b5 = b[5];
b6 = b[6];
be = b[7] + (b6 << 8) + (b5 << 16) + (b4 << 24) + (b3 << 32) + (b2 << 40) + (b1 << 48) + (b0 << 56);
return be;
}
# else
/*
extern uint32_t __builtin_bswap32(uint32_t);
extern uint16_t __builtin_bswap16(uint16_t);
extern uint64_t __builtin_bswap64(uint64_t);
*/
static inline uint32_t long_be(uint32_t le)
{
return (uint32_t)__builtin_bswap32(le);
}
static inline uint16_t short_be(uint16_t le)
{
return (uint16_t)__builtin_bswap16(le);
}
static inline uint64_t long_long_be(uint64_t le)
{
return (uint64_t)__builtin_bswap64(le);
}
# endif /* BYTESWAP_GCC */
#endif
/* Mockables */
#if defined UNIT_TEST
# define MOCKABLE __attribute__((weak))
#else
# define MOCKABLE
#endif
#include "pico_constants.h"
#include "pico_mm.h"
#define IGNORE_PARAMETER(x) ((void)x)
#define PICO_MEM_DEFAULT_SLAB_SIZE 1600
#define PICO_MEM_PAGE_SIZE 4096
#define PICO_MEM_PAGE_LIFETIME 100
#define PICO_MIN_HEAP_SIZE 600
#define PICO_MIN_SLAB_SIZE 1200
#define PICO_MAX_SLAB_SIZE 1600
#define PICO_MEM_MINIMUM_OBJECT_SIZE 4
/*** *** *** *** *** *** ***
*** PLATFORM SPECIFIC ***
*** *** *** *** *** *** ***/
#if defined PICO_PORT_CUSTOM
# include "pico_port.h"
#elif defined CORTEX_M4_HARDFLOAT
# include "arch/pico_cortex_m.h"
#elif defined CORTEX_M4_SOFTFLOAT
# include "arch/pico_cortex_m.h"
#elif defined CORTEX_M3
# include "arch/pico_cortex_m.h"
#elif defined CORTEX_M0
# include "arch/pico_cortex_m.h"
#elif defined DOS_WATCOM
# include "arch/pico_dos.h"
#elif defined PIC24
# include "arch/pico_pic24.h"
#elif defined PIC32
# include "arch/pico_pic32.h"
#elif defined MSP430
# include "arch/pico_msp430.h"
#elif defined MBED_TEST
# include "arch/pico_mbed.h"
#elif defined AVR
# include "arch/pico_avr.h"
#elif defined ARM9
# include "arch/pico_arm9.h"
#elif defined ESP8266
# include "arch/pico_esp8266.h"
#elif defined ATSAMD21J18
# include "arch/pico_atsamd21j18.h"
#elif defined MT7681
# include "arch/pico_generic_gcc.h"
#elif defined FAULTY
# include "../test/pico_faulty.h"
#elif defined ARCHNONE
# include "arch/pico_none.h"
#elif defined GENERIC
# include "arch/pico_generic_gcc.h"
#elif defined __KERNEL__
# include "arch/pico_linux.h"
/* #elif defined ... */
#elif defined PICO_MOP2
# include "arch/pico_mop2.h"
#else
# include "arch/pico_posix.h"
#endif
#ifdef PICO_SUPPORT_MM
#define PICO_ZALLOC(x) pico_mem_zalloc(x)
#define PICO_FREE(x) pico_mem_free(x)
#else
#define PICO_ZALLOC(x) pico_zalloc(x)
#define PICO_FREE(x) pico_free(x)
#endif /* PICO_SUPPORT_MM */
#endif

View File

@ -0,0 +1,58 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_CONST
#define INCLUDE_PICO_CONST
/* Included from pico_config.h */
/** Non-endian dependant constants */
#define PICO_SIZE_IP4 4
#define PICO_SIZE_IP6 16
#define PICO_SIZE_ETH 6
#define PICO_SIZE_TRANS 8
#define PICO_SIZE_IEEE802154_EXT (8u)
#define PICO_SIZE_IEEE802154_SHORT (2u)
/** Endian-dependant constants **/
typedef uint64_t pico_time;
extern volatile uint64_t pico_tick;
/*** *** *** *** *** *** ***
*** ARP CONFIG ***
*** *** *** *** *** *** ***/
#include "pico_addressing.h"
/* Maximum amount of accepted ARP requests per burst interval */
#define PICO_ARP_MAX_RATE 1
/* Duration of the burst interval in milliseconds */
#define PICO_ARP_INTERVAL 1000
/* Add well-known host numbers here. (bigendian constants only beyond this point) */
#define PICO_IP4_ANY (0x00000000U)
#define PICO_IP4_BCAST (0xffffffffU)
#define PICO_IEEE802154_BCAST (0xffffu)
/* defined in modules/pico_ipv6.c */
#ifdef PICO_SUPPORT_IPV6
extern const uint8_t PICO_IPV6_ANY[PICO_SIZE_IP6];
#endif
static inline uint32_t pico_hash(const void *buf, uint32_t size)
{
uint32_t hash = 5381;
uint32_t i;
const uint8_t *ptr = (const uint8_t *)buf;
for(i = 0; i < size; i++)
hash = ((hash << 5) + hash) + ptr[i]; /* hash * 33 + char */
return hash;
}
/* Debug */
/* #define PICO_SUPPORT_DEBUG_MEMORY */
/* #define PICO_SUPPORT_DEBUG_TOOLS */
#endif

View File

@ -0,0 +1,55 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_DEVICE
#define INCLUDE_PICO_DEVICE
#include "pico_queue.h"
#include "pico_frame.h"
#include "pico_addressing.h"
#include "pico_tree.h"
extern struct pico_tree Device_tree;
#include "pico_ipv6_nd.h"
#define MAX_DEVICE_NAME 16
struct pico_ethdev {
struct pico_eth mac;
};
struct pico_device {
char name[MAX_DEVICE_NAME];
uint32_t hash;
uint32_t overhead;
uint32_t mtu;
struct pico_ethdev *eth; /* Null if non-ethernet */
enum pico_ll_mode mode;
struct pico_queue *q_in;
struct pico_queue *q_out;
int (*link_state)(struct pico_device *self);
int (*send)(struct pico_device *self, void *buf, int len); /* Send function. Return 0 if busy */
int (*poll)(struct pico_device *self, int loop_score);
void (*destroy)(struct pico_device *self);
int (*dsr)(struct pico_device *self, int loop_score);
int __serving_interrupt;
/* used to signal the upper layer the number of events arrived since the last processing */
volatile int eventCnt;
#ifdef PICO_SUPPORT_IPV6
struct pico_nd_hostvars hostvars;
#endif
};
int pico_device_init(struct pico_device *dev, const char *name, const uint8_t *mac);
void pico_device_destroy(struct pico_device *dev);
int pico_devices_loop(int loop_score, int direction);
struct pico_device*pico_get_device(const char*name);
int32_t pico_device_broadcast(struct pico_frame *f);
int pico_device_link_state(struct pico_device *dev);
int pico_device_ipv6_random_ll(struct pico_device *dev);
#ifdef PICO_SUPPORT_IPV6
struct pico_ipv6_link *pico_ipv6_link_add_local(struct pico_device *dev, const struct pico_ip6 *prefix);
#endif
#endif

View File

@ -0,0 +1,21 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_ETH
#define INCLUDE_PICO_ETH
#include "pico_addressing.h"
#include "pico_ipv4.h"
#include "pico_ipv6.h"
PACKED_STRUCT_DEF pico_eth_hdr {
uint8_t daddr[6];
uint8_t saddr[6];
uint16_t proto;
};
#define PICO_SIZE_ETHHDR 14
#endif

View File

@ -0,0 +1,131 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_FRAME
#define INCLUDE_PICO_FRAME
#include "pico_config.h"
#define PICO_FRAME_FLAG_BCAST (0x01)
#define PICO_FRAME_FLAG_EXT_BUFFER (0x02)
#define PICO_FRAME_FLAG_EXT_USAGE_COUNTER (0x04)
#define PICO_FRAME_FLAG_SACKED (0x80)
#define PICO_FRAME_FLAG_LL_SEC (0x40)
#define PICO_FRAME_FLAG_SLP_FRAG (0x20)
#define IS_BCAST(f) ((f->flags & PICO_FRAME_FLAG_BCAST) == PICO_FRAME_FLAG_BCAST)
struct pico_socket;
struct pico_frame {
/* Connector for queues */
struct pico_frame *next;
/* Start of the whole buffer, total frame length. */
unsigned char *buffer;
uint32_t buffer_len;
/* For outgoing packets: this is the meaningful buffer. */
unsigned char *start;
uint32_t len;
/* Pointer to usage counter */
uint32_t *usage_count;
/* Pointer to protocol headers */
uint8_t *datalink_hdr;
uint8_t *net_hdr;
uint16_t net_len;
uint8_t *transport_hdr;
uint16_t transport_len;
uint8_t *app_hdr;
uint16_t app_len;
/* Pointer to the phisical device this packet belongs to.
* Should be valid in both routing directions
*/
struct pico_device *dev;
pico_time timestamp;
/* Failures due to bad datalink addressing. */
uint16_t failure_count;
/* Protocol over IP */
uint8_t proto;
/* PICO_FRAME_FLAG_* */
uint8_t flags;
/* Pointer to payload */
unsigned char *payload;
uint16_t payload_len;
#if defined(PICO_SUPPORT_IPV4FRAG) || defined(PICO_SUPPORT_IPV6FRAG)
/* Payload fragmentation info */
uint16_t frag;
#endif
#if defined(PICO_SUPPORT_6LOWPAN)
uint32_t hash;
union pico_ll_addr src;
union pico_ll_addr dst;
#endif
/* Pointer to socket */
struct pico_socket *sock;
/* Pointer to transport info, used to store remote UDP endpoint (IP + port) */
void *info;
/*Priority. "best-effort" priority, the default value is 0. Priority can be in between -10 and +10*/
int8_t priority;
uint8_t transport_flags_saved;
/* Callback to notify listener when the buffer has been discarded */
void (*notify_free)(uint8_t *);
uint8_t send_ttl; /* Special TTL/HOPS value, 0 = auto assign */
uint8_t send_tos; /* Type of service */
};
/** frame alloc/dealloc/copy **/
void pico_frame_discard(struct pico_frame *f);
struct pico_frame *pico_frame_copy(struct pico_frame *f);
struct pico_frame *pico_frame_deepcopy(struct pico_frame *f);
struct pico_frame *pico_frame_alloc(uint32_t size);
int pico_frame_grow(struct pico_frame *f, uint32_t size);
int pico_frame_grow_head(struct pico_frame *f, uint32_t size);
struct pico_frame *pico_frame_alloc_skeleton(uint32_t size, int ext_buffer);
int pico_frame_skeleton_set_buffer(struct pico_frame *f, void *buf);
uint16_t pico_checksum(void *inbuf, uint32_t len);
uint16_t pico_dualbuffer_checksum(void *b1, uint32_t len1, void *b2, uint32_t len2);
static inline int pico_is_digit(char c)
{
if (c < '0' || c > '9')
return 0;
return 1;
}
static inline int pico_is_hex(char c)
{
if (c >= '0' && c <= '9')
return 1;
if (c >= 'a' && c <= 'f')
return 1;
if (c >= 'A' && c <= 'F')
return 1;
return 0;
}
#endif

View File

@ -0,0 +1,17 @@
/*********************************************************************
* PicoTCP. Copyright (c) 2015-2017 Altran Intelligent Systems. Some rights reserved.
* See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*
* Authors: Daniele Lacamera
* *********************************************************************/
#ifndef PICO_MD5_INCLUDE
#define PICO_MD5_INCLUDE
#include <stdint.h>
#include <stdlib.h>
void pico_md5sum(uint8_t *dst, const uint8_t *src, size_t len);
void pico_register_md5sum(void (*md5)(uint8_t *, const uint8_t *, size_t));
#endif /* PICO_MD5_INCLUDE */

View File

@ -0,0 +1,33 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef PICO_MODULE_IPV4_H
#define PICO_MODULE_IPV4_H
struct pico_arp_entry {
struct eth dest;
#ifdef PICO_CONFIG_IPV4
struct ipv4 addr_ipv4;
#endif
RB_ENTRY(pico_arp_entry) node;
};
/* Configured device */
struct pico_eth_link {
struct pico_device *dev;
struct eth address;
struct eth netmask;
RB_ENTRY(pico_eth_link) node;
};
#ifndef IS_MODULE_ETH
# define _mod extern
#else
# define _mod
#endif
_mod struct pico_module pico_module_eth;
#undef _mod
#endif

View File

@ -0,0 +1,97 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_PROTOCOL
#define INCLUDE_PICO_PROTOCOL
#include "pico_config.h"
#include "pico_queue.h"
#define PICO_LOOP_DIR_IN 1
#define PICO_LOOP_DIR_OUT 2
enum pico_layer {
PICO_LAYER_DATALINK = 2, /* Ethernet only. */
PICO_LAYER_NETWORK = 3, /* IPv4, IPv6, ARP. Arp is there because it communicates with L2 */
PICO_LAYER_TRANSPORT = 4, /* UDP, TCP, ICMP */
PICO_LAYER_SOCKET = 5 /* Socket management */
};
enum pico_err_e {
PICO_ERR_NOERR = 0,
PICO_ERR_EPERM = 1,
PICO_ERR_ENOENT = 2,
/* ... */
PICO_ERR_EINTR = 4,
PICO_ERR_EIO = 5,
PICO_ERR_ENXIO = 6,
/* ... */
PICO_ERR_EAGAIN = 11,
PICO_ERR_ENOMEM = 12,
PICO_ERR_EACCESS = 13,
PICO_ERR_EFAULT = 14,
/* ... */
PICO_ERR_EBUSY = 16,
PICO_ERR_EEXIST = 17,
/* ... */
PICO_ERR_EINVAL = 22,
/* ... */
PICO_ERR_ENONET = 64,
/* ... */
PICO_ERR_EPROTO = 71,
/* ... */
PICO_ERR_ENOPROTOOPT = 92,
PICO_ERR_EPROTONOSUPPORT = 93,
/* ... */
PICO_ERR_EOPNOTSUPP = 95,
PICO_ERR_EADDRINUSE = 98,
PICO_ERR_EADDRNOTAVAIL = 99,
PICO_ERR_ENETDOWN = 100,
PICO_ERR_ENETUNREACH = 101,
/* ... */
PICO_ERR_ECONNRESET = 104,
/* ... */
PICO_ERR_EISCONN = 106,
PICO_ERR_ENOTCONN = 107,
PICO_ERR_ESHUTDOWN = 108,
/* ... */
PICO_ERR_ETIMEDOUT = 110,
PICO_ERR_ECONNREFUSED = 111,
PICO_ERR_EHOSTDOWN = 112,
PICO_ERR_EHOSTUNREACH = 113,
/* ... */
PICO_ERR_EINPROGRESS = 115,
};
typedef enum pico_err_e pico_err_t;
extern volatile pico_err_t pico_err;
#define IS_IPV6(f) (f && f->net_hdr && ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x60))
#define IS_IPV4(f) (f && f->net_hdr && ((((uint8_t *)(f->net_hdr))[0] & 0xf0) == 0x40))
#define MAX_PROTOCOL_NAME 16
struct pico_protocol {
char name[MAX_PROTOCOL_NAME];
uint32_t hash;
enum pico_layer layer;
uint16_t proto_number;
struct pico_queue *q_in;
struct pico_queue *q_out;
struct pico_frame *(*alloc)(struct pico_protocol *self, struct pico_device *dev, uint16_t size); /* Frame allocation. */
int (*push)(struct pico_protocol *self, struct pico_frame *p); /* Push function, for active outgoing pkts from above */
int (*process_out)(struct pico_protocol *self, struct pico_frame *p); /* Send loop. */
int (*process_in)(struct pico_protocol *self, struct pico_frame *p); /* Recv loop. */
uint16_t (*get_mtu)(struct pico_protocol *self);
};
int pico_protocols_loop(int loop_score);
void pico_protocol_init(struct pico_protocol *p);
int pico_protocol_datalink_loop(int loop_score, int direction);
int pico_protocol_network_loop(int loop_score, int direction);
int pico_protocol_transport_loop(int loop_score, int direction);
int pico_protocol_socket_loop(int loop_score, int direction);
#endif

View File

@ -0,0 +1,166 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_QUEUE
#define INCLUDE_PICO_QUEUE
#include "pico_config.h"
#include "pico_frame.h"
#define Q_LIMIT 0
#ifndef NULL
#define NULL ((void *)0)
#endif
void *pico_mutex_init(void);
void pico_mutex_deinit(void *mutex);
void pico_mutex_lock(void *mutex);
int pico_mutex_lock_timeout(void *mutex, int timeout);
void pico_mutex_unlock(void *mutex);
void pico_mutex_unlock_ISR(void *mutex);
struct pico_queue {
uint32_t frames;
uint32_t size;
uint32_t max_frames;
uint32_t max_size;
struct pico_frame *head;
struct pico_frame *tail;
#ifdef PICO_SUPPORT_MUTEX
void *mutex;
#endif
uint8_t shared;
uint16_t overhead;
};
#ifdef PICO_SUPPORT_MUTEX
#define PICOTCP_MUTEX_LOCK(x) { \
if (x == NULL) \
x = pico_mutex_init(); \
pico_mutex_lock(x); \
}
#define PICOTCP_MUTEX_UNLOCK(x) pico_mutex_unlock(x)
#define PICOTCP_MUTEX_DEL(x) pico_mutex_deinit(x)
#else
#define PICOTCP_MUTEX_LOCK(x) do {} while(0)
#define PICOTCP_MUTEX_UNLOCK(x) do {} while(0)
#define PICOTCP_MUTEX_DEL(x) do {} while(0)
#endif
#ifdef PICO_SUPPORT_DEBUG_TOOLS
static void debug_q(struct pico_queue *q)
{
struct pico_frame *p = q->head;
dbg("%d: ", q->frames);
while(p) {
dbg("(%p)-->", p);
p = p->next;
}
dbg("X\n");
}
#else
#define debug_q(x) do {} while(0)
#endif
static inline int32_t pico_enqueue(struct pico_queue *q, struct pico_frame *p)
{
if ((q->max_frames) && (q->max_frames <= q->frames))
return -1;
#if (Q_LIMIT != 0)
if ((Q_LIMIT < p->buffer_len + q->size))
return -1;
#endif
if ((q->max_size) && (q->max_size < (p->buffer_len + q->size)))
return -1;
if (q->shared)
PICOTCP_MUTEX_LOCK(q->mutex);
p->next = NULL;
if (!q->head) {
q->head = p;
q->tail = p;
q->size = 0;
q->frames = 0;
} else {
q->tail->next = p;
q->tail = p;
}
q->size += p->buffer_len + q->overhead;
q->frames++;
debug_q(q);
if (q->shared)
PICOTCP_MUTEX_UNLOCK(q->mutex);
return (int32_t)q->size;
}
static inline struct pico_frame *pico_dequeue(struct pico_queue *q)
{
struct pico_frame *p = q->head;
if (!p)
return NULL;
if (q->frames < 1)
return NULL;
if (q->shared)
PICOTCP_MUTEX_LOCK(q->mutex);
q->head = p->next;
q->frames--;
q->size -= p->buffer_len - q->overhead;
if (q->head == NULL)
q->tail = NULL;
debug_q(q);
p->next = NULL;
if (q->shared)
PICOTCP_MUTEX_UNLOCK(q->mutex);
return p;
}
static inline struct pico_frame *pico_queue_peek(struct pico_queue *q)
{
struct pico_frame *p = q->head;
if (q->frames < 1)
return NULL;
debug_q(q);
return p;
}
static inline void pico_queue_deinit(struct pico_queue *q)
{
if (q->shared) {
PICOTCP_MUTEX_DEL(q->mutex);
}
}
static inline void pico_queue_empty(struct pico_queue *q)
{
struct pico_frame *p = pico_dequeue(q);
while(p) {
pico_frame_discard(p);
p = pico_dequeue(q);
}
}
static inline void pico_queue_protect(struct pico_queue *q)
{
q->shared = 1;
}
#endif

View File

@ -0,0 +1,263 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_SOCKET
#define INCLUDE_PICO_SOCKET
#include "pico_queue.h"
#include "pico_addressing.h"
#include "pico_config.h"
#include "pico_protocol.h"
#include "pico_tree.h"
#ifdef __linux__
#define PICO_DEFAULT_SOCKETQ (16 * 1024) /* Linux host, so we want full throttle */
#else
#define PICO_DEFAULT_SOCKETQ (6 * 1024) /* seems like an acceptable default for small embedded systems */
#endif
#define PICO_SHUT_RD 1
#define PICO_SHUT_WR 2
#define PICO_SHUT_RDWR 3
#ifdef PICO_SUPPORT_IPV4
# define IS_SOCK_IPV4(s) ((s->net == &pico_proto_ipv4))
#else
# define IS_SOCK_IPV4(s) (0)
#endif
#ifdef PICO_SUPPORT_IPV6
# define IS_SOCK_IPV6(s) ((s->net == &pico_proto_ipv6))
#else
# define IS_SOCK_IPV6(s) (0)
#endif
struct pico_sockport
{
struct pico_tree socks; /* how you make the connection ? */
uint16_t number;
uint16_t proto;
};
struct pico_socket {
struct pico_protocol *proto;
struct pico_protocol *net;
union pico_address local_addr;
union pico_address remote_addr;
uint16_t local_port;
uint16_t remote_port;
struct pico_queue q_in;
struct pico_queue q_out;
void (*wakeup)(uint16_t ev, struct pico_socket *s);
#ifdef PICO_SUPPORT_TCP
/* For the TCP backlog queue */
struct pico_socket *backlog;
struct pico_socket *next;
struct pico_socket *parent;
uint16_t max_backlog;
uint16_t number_of_pending_conn;
#endif
#ifdef PICO_SUPPORT_MCAST
struct pico_tree *MCASTListen;
#ifdef PICO_SUPPORT_IPV6
struct pico_tree *MCASTListen_ipv6;
#endif
#endif
uint16_t ev_pending;
struct pico_device *dev;
/* Private field. */
int id;
uint16_t state;
uint16_t opt_flags;
pico_time timestamp;
void *priv;
};
struct pico_remote_endpoint {
union pico_address remote_addr;
uint16_t remote_port;
};
struct pico_ip_mreq {
union pico_address mcast_group_addr;
union pico_address mcast_link_addr;
};
struct pico_ip_mreq_source {
union pico_address mcast_group_addr;
union pico_address mcast_source_addr;
union pico_address mcast_link_addr;
};
#define PICO_SOCKET_STATE_UNDEFINED 0x0000u
#define PICO_SOCKET_STATE_SHUT_LOCAL 0x0001u
#define PICO_SOCKET_STATE_SHUT_REMOTE 0x0002u
#define PICO_SOCKET_STATE_BOUND 0x0004u
#define PICO_SOCKET_STATE_CONNECTED 0x0008u
#define PICO_SOCKET_STATE_CLOSING 0x0010u
#define PICO_SOCKET_STATE_CLOSED 0x0020u
# define PICO_SOCKET_STATE_TCP 0xFF00u
# define PICO_SOCKET_STATE_TCP_UNDEF 0x00FFu
# define PICO_SOCKET_STATE_TCP_CLOSED 0x0100u
# define PICO_SOCKET_STATE_TCP_LISTEN 0x0200u
# define PICO_SOCKET_STATE_TCP_SYN_SENT 0x0300u
# define PICO_SOCKET_STATE_TCP_SYN_RECV 0x0400u
# define PICO_SOCKET_STATE_TCP_ESTABLISHED 0x0500u
# define PICO_SOCKET_STATE_TCP_CLOSE_WAIT 0x0600u
# define PICO_SOCKET_STATE_TCP_LAST_ACK 0x0700u
# define PICO_SOCKET_STATE_TCP_FIN_WAIT1 0x0800u
# define PICO_SOCKET_STATE_TCP_FIN_WAIT2 0x0900u
# define PICO_SOCKET_STATE_TCP_CLOSING 0x0a00u
# define PICO_SOCKET_STATE_TCP_TIME_WAIT 0x0b00u
# define PICO_SOCKET_STATE_TCP_ARRAYSIZ 0x0cu
/* Socket options */
# define PICO_TCP_NODELAY 1
# define PICO_SOCKET_OPT_TCPNODELAY 0x0000u
# define PICO_IP_MULTICAST_EXCLUDE 0
# define PICO_IP_MULTICAST_INCLUDE 1
# define PICO_IP_MULTICAST_IF 32
# define PICO_IP_MULTICAST_TTL 33
# define PICO_IP_MULTICAST_LOOP 34
# define PICO_IP_ADD_MEMBERSHIP 35
# define PICO_IP_DROP_MEMBERSHIP 36
# define PICO_IP_UNBLOCK_SOURCE 37
# define PICO_IP_BLOCK_SOURCE 38
# define PICO_IP_ADD_SOURCE_MEMBERSHIP 39
# define PICO_IP_DROP_SOURCE_MEMBERSHIP 40
# define PICO_SOCKET_OPT_MULTICAST_LOOP 1
# define PICO_SOCKET_OPT_KEEPIDLE 4
# define PICO_SOCKET_OPT_KEEPINTVL 5
# define PICO_SOCKET_OPT_KEEPCNT 6
#define PICO_SOCKET_OPT_LINGER 13
# define PICO_SOCKET_OPT_RCVBUF 52
# define PICO_SOCKET_OPT_SNDBUF 53
/* Constants */
# define PICO_IP_DEFAULT_MULTICAST_TTL 1
# define PICO_IP_DEFAULT_MULTICAST_LOOP 1
#define PICO_SOCKET_TIMEOUT 5000u /* 5 seconds */
#define PICO_SOCKET_LINGER_TIMEOUT 3000u /* 3 seconds */
#define PICO_SOCKET_BOUND_TIMEOUT 30000u /* 30 seconds */
#define PICO_SOCKET_SHUTDOWN_WRITE 0x01u
#define PICO_SOCKET_SHUTDOWN_READ 0x02u
#define TCPSTATE(s) ((s)->state & PICO_SOCKET_STATE_TCP)
#define PICO_SOCK_EV_RD 1u
#define PICO_SOCK_EV_WR 2u
#define PICO_SOCK_EV_CONN 4u
#define PICO_SOCK_EV_CLOSE 8u
#define PICO_SOCK_EV_FIN 0x10u
#define PICO_SOCK_EV_ERR 0x80u
struct pico_msginfo {
struct pico_device *dev;
uint8_t ttl;
uint8_t tos;
};
struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s));
int pico_socket_read(struct pico_socket *s, void *buf, int len);
int pico_socket_write(struct pico_socket *s, const void *buf, int len);
int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port);
int pico_socket_sendto_extended(struct pico_socket *s, const void *buf, const int len,
void *dst, uint16_t remote_port, struct pico_msginfo *msginfo);
int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, void *orig, uint16_t *local_port);
int pico_socket_recvfrom_extended(struct pico_socket *s, void *buf, int len, void *orig,
uint16_t *remote_port, struct pico_msginfo *msginfo);
int pico_socket_send(struct pico_socket *s, const void *buf, int len);
int pico_socket_recv(struct pico_socket *s, void *buf, int len);
int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port);
int pico_socket_getname(struct pico_socket *s, void *local_addr, uint16_t *port, uint16_t *proto);
int pico_socket_getpeername(struct pico_socket *s, void *remote_addr, uint16_t *port, uint16_t *proto);
int pico_socket_connect(struct pico_socket *s, const void *srv_addr, uint16_t remote_port);
int pico_socket_listen(struct pico_socket *s, const int backlog);
struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, uint16_t *port);
int8_t pico_socket_del(struct pico_socket *s);
int pico_socket_setoption(struct pico_socket *s, int option, void *value);
int pico_socket_getoption(struct pico_socket *s, int option, void *value);
int pico_socket_shutdown(struct pico_socket *s, int mode);
int pico_socket_close(struct pico_socket *s);
struct pico_frame *pico_socket_frame_alloc(struct pico_socket *s, struct pico_device *dev, uint16_t len);
struct pico_device *get_sock_dev(struct pico_socket *s);
#ifdef PICO_SUPPORT_IPV4
# define is_sock_ipv4(x) (x->net == &pico_proto_ipv4)
#else
# define is_sock_ipv4(x) (0)
#endif
#ifdef PICO_SUPPORT_IPV6
# define is_sock_ipv6(x) (x->net == &pico_proto_ipv6)
#else
# define is_sock_ipv6(x) (0)
#endif
#ifdef PICO_SUPPORT_UDP
# define is_sock_udp(x) (x->proto == &pico_proto_udp)
#else
# define is_sock_udp(x) (0)
#endif
#ifdef PICO_SUPPORT_TCP
# define is_sock_tcp(x) (x->proto == &pico_proto_tcp)
#else
# define is_sock_tcp(x) (0)
#endif
/* Interface towards transport protocol */
int pico_transport_process_in(struct pico_protocol *self, struct pico_frame *f);
struct pico_socket *pico_socket_clone(struct pico_socket *facsimile);
int8_t pico_socket_add(struct pico_socket *s);
int pico_transport_error(struct pico_frame *f, uint8_t proto, int code);
/* Socket loop */
int pico_sockets_loop(int loop_score);
struct pico_socket*pico_sockets_find(uint16_t local, uint16_t remote);
/* Port check */
int pico_is_port_free(uint16_t proto, uint16_t port, void *addr, void *net);
struct pico_sockport *pico_get_sockport(uint16_t proto, uint16_t port);
uint32_t pico_socket_get_mss(struct pico_socket *s);
int pico_socket_set_family(struct pico_socket *s, uint16_t family);
int pico_count_sockets(uint8_t proto);
#define PICO_SOCKET_SETOPT_EN(socket, index) (socket->opt_flags |= (1 << index))
#define PICO_SOCKET_SETOPT_DIS(socket, index) (socket->opt_flags &= (uint16_t) ~(1 << index))
#define PICO_SOCKET_GETOPT(socket, index) ((socket->opt_flags & (1u << index)) != 0)
#endif

View File

@ -0,0 +1,10 @@
#ifndef PICO_SOCKET_MULTICAST_H
#define PICO_SOCKET_MULTICAST_H
int pico_socket_mcast_filter(struct pico_socket *s, union pico_address *mcast_group, union pico_address *src);
void pico_multicast_delete(struct pico_socket *s);
int pico_setsockopt_mcast(struct pico_socket *s, int option, void *value);
int pico_getsockopt_mcast(struct pico_socket *s, int option, void *value);
int pico_udp_get_mc_ttl(struct pico_socket *s, uint8_t *ttl);
int pico_udp_set_mc_ttl(struct pico_socket *s, void *_ttl);
#endif

View File

@ -0,0 +1,92 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
*********************************************************************/
#ifndef INCLUDE_PICO_STACK
#define INCLUDE_PICO_STACK
#include "pico_config.h"
#include "pico_frame.h"
#include "pico_constants.h"
#define PICO_MAX_TIMERS 20
#define PICO_ETH_MRU (1514u)
#define PICO_IP_MRU (1500u)
/*******************************************************************************
* TRANSPORT LAYER
******************************************************************************/
/* From dev up to socket */
int32_t pico_transport_receive(struct pico_frame *f, uint8_t proto);
/*******************************************************************************
* NETWORK LAYER
******************************************************************************/
/* From socket down to dev */
int32_t pico_network_send(struct pico_frame *f);
/* From dev up to socket */
int32_t pico_network_receive(struct pico_frame *f);
/*******************************************************************************
* DATALINK LAYER
******************************************************************************/
/* From socket down to dev */
int pico_datalink_send(struct pico_frame *f);
/* From dev up to socket */
int pico_datalink_receive(struct pico_frame *f);
/*******************************************************************************
* PHYSICAL LAYER
******************************************************************************/
/* Enqueues the frame in the device-queue. From socket down to dev */
int32_t pico_sendto_dev(struct pico_frame *f);
/* LOWEST LEVEL: interface towards stack from devices */
/* Device driver will call this function which returns immediately.
* Incoming packet will be processed later on in the dev loop.
* The zerocopy version will associate the current buffer to the newly created frame.
* Warning: the buffer used in the zerocopy version MUST have been allocated using PICO_ZALLOC()
*/
int32_t pico_stack_recv(struct pico_device *dev, uint8_t *buffer, uint32_t len);
int32_t pico_stack_recv_zerocopy(struct pico_device *dev, uint8_t *buffer, uint32_t len);
int32_t pico_stack_recv_zerocopy_ext_buffer(struct pico_device *dev, uint8_t *buffer, uint32_t len);
int32_t pico_stack_recv_zerocopy_ext_buffer_notify(struct pico_device *dev, uint8_t *buffer, uint32_t len, void (*notify_free)(uint8_t *buffer));
struct pico_frame *pico_stack_recv_new_frame(struct pico_device *dev, uint8_t *buffer, uint32_t len);
/* ----- Initialization ----- */
int pico_stack_init(void);
/* ----- Loop Function. ----- */
void pico_stack_tick(void);
void pico_stack_loop(void);
/* ---- Notifications for stack errors */
int pico_notify_socket_unreachable(struct pico_frame *f);
int pico_notify_proto_unreachable(struct pico_frame *f);
int pico_notify_dest_unreachable(struct pico_frame *f);
int pico_notify_ttl_expired(struct pico_frame *f);
int pico_notify_frag_expired(struct pico_frame *f);
int pico_notify_pkt_too_big(struct pico_frame *f);
/* Various. */
int pico_source_is_local(struct pico_frame *f);
int pico_frame_dst_is_unicast(struct pico_frame *f);
void pico_store_network_origin(void *src, struct pico_frame *f);
uint32_t pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg);
uint32_t pico_timer_add_hashed(pico_time expire, void (*timer)(pico_time, void *), void *arg, uint32_t hash);
void pico_timer_cancel_hashed(uint32_t hash);
void pico_timer_cancel(uint32_t id);
uint32_t pico_rand(void);
void pico_rand_feed(uint32_t feed);
void pico_to_lowercase(char *str);
int pico_address_compare(union pico_address *a, union pico_address *b, uint16_t proto);
int32_t pico_seq_compare(uint32_t a, uint32_t b);
#endif

View File

@ -0,0 +1,93 @@
/*********************************************************************
PicoTCP. Copyright (c) 2012-2017 Altran Intelligent Systems. Some rights reserved.
See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
Author: Andrei Carp <andrei.carp@tass.be>
*********************************************************************/
#ifndef PICO_RBTREE_H
#define PICO_RBTREE_H
#include "pico_config.h"
/* This is used to declare a new tree, leaf root by default */
#define PICO_TREE_DECLARE(name, compareFunction) \
struct pico_tree name = \
{ \
&LEAF, \
compareFunction \
}
#define USE_PICO_PAGE0_ZALLOC (1)
#define USE_PICO_ZALLOC (2)
struct pico_tree_node
{
void*keyValue; /* generic key */
struct pico_tree_node*parent;
struct pico_tree_node*leftChild;
struct pico_tree_node*rightChild;
uint8_t color;
};
struct pico_tree
{
struct pico_tree_node *root; /* root of the tree */
/* this function directly provides the keys as parameters not the nodes. */
int (*compare)(void*keyA, void*keyB);
};
extern struct pico_tree_node LEAF; /* generic leaf node */
#ifdef PICO_SUPPORT_MM
void *pico_tree_insert_implementation(struct pico_tree *tree, void *key, uint8_t allocator);
void *pico_tree_delete_implementation(struct pico_tree *tree, void *key, uint8_t allocator);
#endif
/*
* Manipulation functions
*/
void *pico_tree_insert(struct pico_tree *tree, void *key);
void *pico_tree_delete(struct pico_tree *tree, void *key);
void *pico_tree_findKey(struct pico_tree *tree, void *key);
void pico_tree_drop(struct pico_tree *tree);
int pico_tree_empty(struct pico_tree *tree);
struct pico_tree_node *pico_tree_findNode(struct pico_tree *tree, void *key);
void *pico_tree_first(struct pico_tree *tree);
void *pico_tree_last(struct pico_tree *tree);
/*
* Traverse functions
*/
struct pico_tree_node *pico_tree_lastNode(struct pico_tree_node *node);
struct pico_tree_node *pico_tree_firstNode(struct pico_tree_node *node);
struct pico_tree_node *pico_tree_next(struct pico_tree_node *node);
struct pico_tree_node *pico_tree_prev(struct pico_tree_node *node);
/*
* For each macros
*/
#define pico_tree_foreach(idx, tree) \
for ((idx) = pico_tree_firstNode((tree)->root); \
(idx) != &LEAF; \
(idx) = pico_tree_next(idx))
#define pico_tree_foreach_reverse(idx, tree) \
for ((idx) = pico_tree_lastNode((tree)->root); \
(idx) != &LEAF; \
(idx) = pico_tree_prev(idx))
#define pico_tree_foreach_safe(idx, tree, idx2) \
for ((idx) = pico_tree_firstNode((tree)->root); \
((idx) != &LEAF) && ((idx2) = pico_tree_next(idx), 1); \
(idx) = (idx2))
#define pico_tree_foreach_reverse_safe(idx, tree, idx2) \
for ((idx) = pico_tree_lastNode((tree)->root); \
((idx) != &LEAF) && ((idx2) = pico_tree_prev(idx), 1); \
(idx) = (idx2))
#endif