|  | #ifndef _ROS_PBUF_H_ | 
|  | #define _ROS_PBUF_H_ | 
|  | #include <kmalloc.h> | 
|  | #include <slab.h> | 
|  | #include <kref.h> | 
|  | #include <sys/queue.h> | 
|  | #include <atomic.h> | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /** Currently, the pbuf_custom code is only needed for one specific configuration | 
|  | * of IP_FRAG */ | 
|  | #define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) | 
|  | /* Ensure IP address are 32-bit aligned on 32bit systems, and thus improving the speed of processing | 
|  | * for regularly accessed fields such as IP addresses | 
|  | */ | 
|  | #define ETH_PAD_SIZE 2      // padding to ensure ip packet is longword aligned. | 
|  | #define PBUF_TRANSPORT_HLEN 20 | 
|  | #define PBUF_IP_HLEN        20 | 
|  | #define PBUF_LINK_HLEN      14 + ETH_PAD_SIZE // Padding | 
|  |  | 
|  | /** indicates this packet's data should be immediately passed to the application */ | 
|  | #define PBUF_FLAG_PUSH      0x01U | 
|  | /** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a | 
|  | a pbuf differently */ | 
|  | #define PBUF_FLAG_IS_CUSTOM 0x02U | 
|  | /** indicates this pbuf is UDP multicast to be looped back */ | 
|  | #define PBUF_FLAG_MCASTLOOP 0x04U | 
|  |  | 
|  | typedef enum { | 
|  | PBUF_TRANSPORT, | 
|  | PBUF_IP, | 
|  | PBUF_LINK, | 
|  | PBUF_RAW | 
|  | } pbuf_layer; | 
|  |  | 
|  | typedef enum { | 
|  | PBUF_RAM, /* pbuf data is stored in RAM */ | 
|  | PBUF_ROM, /* pbuf data is stored in ROM */ | 
|  | PBUF_REF, /* pbuf comes from the pbuf pool */ | 
|  | PBUF_POOL, /* pbuf payload refers to RAM */ | 
|  | PBUF_MTU  /* pbuf with a fixed MTU size */ | 
|  | } pbuf_type; | 
|  |  | 
|  |  | 
|  | /** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a | 
|  | a pbuf differently */ | 
|  | #define PBUF_FLAG_IS_CUSTOM 0x02U | 
|  | struct pbuf; | 
|  | STAILQ_HEAD(pbuf_tailq, pbuf); | 
|  |  | 
|  | struct pbuf { | 
|  | /* Several reasons to roll own version of STAIL queue here | 
|  | * pbuf chain exists without a queue | 
|  | * also pbuf chain need to be moved entirely onto a socket queue | 
|  | */ | 
|  | STAILQ_ENTRY(pbuf) next; | 
|  | // struct pbuf *next; | 
|  |  | 
|  | /** pointer to the actual data in the buffer */ | 
|  | void *payload; | 
|  |  | 
|  | uint16_t tot_len; | 
|  |  | 
|  | /** length of this buffer */ | 
|  | uint16_t len; | 
|  |  | 
|  | uint16_t alloc_len; | 
|  |  | 
|  | /** pbuf_type as u8_t instead of enum to save space */ | 
|  | uint8_t type; | 
|  |  | 
|  | /** misc flags */ | 
|  | uint8_t flags; | 
|  |  | 
|  | struct kref bufref; | 
|  | }; | 
|  |  | 
|  | struct pbuf_head { | 
|  | struct pbuf_tailq pbuf_fifo; | 
|  | uint32_t qlen; | 
|  | spinlock_t lock; | 
|  | }; | 
|  |  | 
|  | static inline void pbuf_head_init(struct pbuf_head *ph) { | 
|  | STAILQ_INIT(&ph->pbuf_fifo); | 
|  | ph->qlen = 0; | 
|  | spinlock_init(&ph->lock); | 
|  | } | 
|  | extern struct kmem_cache *pbuf_kcache; | 
|  | /* Initializes the pbuf module. This call is empty for now, but may not be in future. */ | 
|  | void pbuf_init(void); | 
|  | void pbuf_cat(struct pbuf *head, struct pbuf *tail); | 
|  | void pbuf_chain(struct pbuf *head, struct pbuf *tail); | 
|  | void pbuf_ref(struct pbuf *p); | 
|  | bool pbuf_deref(struct pbuf *p); | 
|  | int pbuf_header(struct pbuf *p, int header_size); | 
|  | struct pbuf *pbuf_alloc(pbuf_layer layer, uint16_t length, pbuf_type type); | 
|  | int pbuf_copy_out(struct pbuf *buf, void *dataptr, size_t len, uint16_t offset); | 
|  | void print_pbuf(struct pbuf *p); | 
|  | bool pbuf_free(struct pbuf *p); | 
|  |  | 
|  | void attach_pbuf(struct pbuf *p, struct pbuf_head *buf_head); | 
|  | struct pbuf* detach_pbuf(struct pbuf_head *buf_head); | 
|  | uint8_t pbuf_clen(struct pbuf *p); | 
|  | void pbuf_realloc(struct pbuf *p, uint16_t size); | 
|  | // end | 
|  | #if 0 | 
|  | struct pbuf *pbuf_dechain(struct pbuf *p); | 
|  | err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); | 
|  | err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); | 
|  | struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); | 
|  | #if LWIP_CHECKSUM_ON_COPY | 
|  | err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, | 
|  | u16_t len, u16_t *chksum); | 
|  | #endif /* LWIP_CHECKSUM_ON_COPY */ | 
|  |  | 
|  | u8_t pbuf_get_at(struct pbuf* p, u16_t offset); | 
|  | u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); | 
|  | u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); | 
|  | u16_t pbuf_strstr(struct pbuf* p, const char* substr); | 
|  |  | 
|  | #endif | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #endif /* __LWIP_PBUF_H__ */ |