#ifndef __LWIP_SERVER_SOCKET_H__ #define __LWIP_SERVER_SOCKET_H__ #include #include #include "inet_config.h" #include "proto.h" #define SOCK_TYPE_IP 0 #define SOCK_TYPE_TCP 1 #define SOCK_TYPE_UDP 2 #define SOCK_TYPES 3 struct socket; typedef void (* sock_op_t)(struct socket *, message *); typedef int (* sock_op_open_t)(struct socket *, message *); struct sock_ops { sock_op_open_t open; sock_op_t close; sock_op_t read; sock_op_t write; sock_op_t ioctl; sock_op_t select; sock_op_t select_reply; }; struct recv_q { struct recv_q * next; void * data; }; #define SOCK_FLG_OP_PENDING 0x1 #define SOCK_FLG_OP_REVIVING 0x2 #define SOCK_FLG_OP_SUSPENDED 0x4 /* set when processing a suspended op */ #define SOCK_FLG_OP_LISTENING 0x100 /* tcp socket is in a listening mode */ #define SOCK_FLG_OP_CONNECTING 0x200 /* set when waiting for a connect */ #define SOCK_FLG_OP_READING 0x400 /* reading operation in progress */ #define SOCK_FLG_OP_WRITING 0x800 /* writing operation in progress */ #define SOCK_FLG_CLOSED 0x1000 /* tcp socket has been closed do not expect any more data */ /* select() flags - they say what action do we monitor */ #define SOCK_FLG_SEL_WRITE 0x100000 #define SOCK_FLG_SEL_READ 0x200000 #define SOCK_FLG_SEL_ERROR 0x400000 #define SOCK_FLG_SEL_CHECK 0x800000 /* select satisfied, go and check it */ #define sock_select_set(sock) ((sock)->flags & (SOCK_FLG_SEL_WRITE | \ SOCK_FLG_SEL_READ | SOCK_FLG_SEL_ERROR)) #define sock_select_read_set(sock) ((sock)->flags & SOCK_FLG_SEL_READ) #define sock_select_write_set(sock) ((sock)->flags & SOCK_FLG_SEL_WRITE) #define sock_select_rw_set(sock) ((sock)->flags & (SOCK_FLG_SEL_READ | \ SOCK_FLG_SEL_WRITE)) #define sock_select_error_set(sock) ((sock)->flags & SOCK_FLG_SEL_ERROR) #define sock_select_check_set(sock) ((sock)->flags & SOCK_FLG_SEL_CHECK) #define sock_clear_select(sock) do { \ (sock)->flags &= ~(SOCK_FLG_SEL_READ | SOCK_FLG_SEL_WRITE | \ SOCK_FLG_SEL_ERROR | SOCK_FLG_SEL_CHECK); \ } while (0) struct socket { int type; u32_t flags; unsigned long usr_flags; void * pcb; struct sock_ops * ops; void * buf; size_t buf_size; message mess; /* store the message which initiated the last operation on this socket in case we have to suspend the operation */ endpoint_t select_ep; struct recv_q * recv_head; struct recv_q * recv_tail; unsigned recv_data_size; /* sum of data enqueued */ void * data; }; extern struct sock_ops sock_udp_ops; extern struct sock_ops sock_tcp_ops; extern struct sock_ops sock_raw_ip_ops; #define get_sock_num(x) ((long int) ((x) - socket)) #define is_valid_sock_num(x) (x < MAX_SOCKETS) #define get_sock(x) &socket[x] #define MAX_SOCKETS 255 /* FIXME as log as the sockets are identified by the minor device number 255 is ok */ #define MAX_DEVS 5 #define RESERVED (SOCK_TYPES + MAX_DEVS) /* rounded to 8 */ extern struct socket socket[MAX_SOCKETS]; void socket_request(message * m); void mq_process(void); struct socket * get_unused_sock(void); struct socket * get_nic_sock(unsigned dev); void send_reply(message * m, int status); void sock_reply(struct socket * sock, int status); void sock_revive(struct socket * sock, int status); typedef void (* recv_data_free_fn)(void *); int sock_enqueue_data(struct socket * sock, void * data, unsigned size); void * sock_dequeue_data(struct socket * sock); void sock_dequeue_data_all(struct socket * sock, recv_data_free_fn data_free); void sock_select_notify(struct socket * sock); static inline void * debug_malloc(size_t s) { void * ret; ret = malloc(s); // printf("allocated %p size %d\n", ret, s); return ret; } #define debug_free(x) do { \ if (0) \ printf("free called from %s:%d %s freeing %p\n", __FILE__, \ __LINE__, __func__, (x)); \ free(x); \ } while(0) void generic_op_select(struct socket * sock, message * m); void generic_op_select_reply(struct socket * sock, message * m); #endif /* __LWIP_SERVER_SOCKET_H__ */