├── LICENSE.md ├── README.md └── rawket ├── include ├── raw_client_api.h ├── raw_server_api.h ├── ring_buf.h ├── tcp_client_mgr.h ├── tcp_connection.h └── tcp_server_mgr.h ├── raw-api-chinese.txt ├── raw-api-english.txt ├── raw_client_api.c ├── raw_server_api.c ├── rawket_example.c ├── readme.txt ├── ring_buf.c ├── tcp_client_mgr.c ├── tcp_connection.c └── tcp_server_mgr.c /LICENSE.md: -------------------------------------------------------------------------------- 1 | contact 540535649@qq.com. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LwIP-rawket 2 | Raw API for LwIP is too difficult? No, you can use the "rawket" APIs to build your network applications, the rawket gives you socket-like APIs based on LwIP raw API. 3 | 4 | Rawket: 5 | A socket-like API for LwIP based on Raw API. 6 | 7 | Rawket supports: 8 | 1) TCP client APIs, integrated with auto reconnecting and error handling, hardware-independent keep-alive. 9 | Use a socket handler to send and receive data, all APIs are no-blocking APIs. 10 | 2) TCP server APIs, supports 16 servers maximun, and maximun 16 clients per server. 11 | 3) two examples about how to use Rawket to build an echo client and an echo server. 12 | 13 | Usage: 14 | Please refer to raw-api-xxxxx.txt for API details. 15 | 16 | Support & Bug Report: 540535649@qq.com 17 | -------------------------------------------------------------------------------- /rawket/include/raw_client_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : raw_client_api.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | #ifndef __RAW_CLIENT_API_H 16 | #define __RAW_CLIENT_API_H 17 | 18 | #include "tcp_client_mgr.h" 19 | 20 | #define CLIENT_SND_BUF_SIZE (2*TCP_WND) 21 | #define CLIENT_RCV_BUF_SIZE (TCP_WND) 22 | 23 | //only call this once to init/deinit client manager in main 24 | void client_init_manager(void); 25 | void client_deinit_manager(void); 26 | 27 | //client socket api based on raw, only for tcp client operations. 28 | typedef enum cli_status 29 | { 30 | CLI_INIT, 31 | CLI_CONNECTING, 32 | CLI_CONNECTED, 33 | CLI_RECONNECTING, 34 | CLI_CLOSED, 35 | CLI_ERR 36 | }CLI_STATUS; 37 | 38 | s32_t client_connect_to_server(struct ip_addr dst_ip, u16_t dst_port); 39 | CLI_STATUS client_status_check(s32_t sock); 40 | void client_close(s32_t sock); 41 | s32_t client_check_snd_buf(s32_t sock); 42 | s32_t client_check_recv_buf(s32_t sock); 43 | s32_t client_snd_data(s32_t sock, s8_t *buf, s32_t len); 44 | s32_t client_recv_data(s32_t sock, s8_t *buf, s32_t len); 45 | 46 | #endif 47 | 48 | -------------------------------------------------------------------------------- /rawket/include/raw_server_api.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : raw_server_api.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifndef __RAW_SERVER_API_H 17 | #define __RAW_SERVER_API_H 18 | 19 | #include "tcp_server_mgr.h" 20 | 21 | //only call this once to init/deinit server manager in main 22 | void server_init_manager(void); 23 | void server_deinit_manager(void); 24 | 25 | //client socket api based on raw, only for tcp server operations. 26 | typedef enum srv_status 27 | { 28 | SRV_INIT, 29 | SRV_CONNECTED, 30 | SRV_CLOSED, 31 | SRV_ERR 32 | }SRV_STATUS; 33 | 34 | s32_t server_open(u16_t local_port); 35 | s32_t server_check_client(s32_t srv_sock); 36 | void server_close(s32_t srv_sock); //close all client connections on server 37 | 38 | #define CLIENT_SOCK(srv, cli) ((cli<<16) + srv) 39 | //cli_sock should be created by CLIENT_SOCK() 40 | struct ip_addr server_get_client_ip(s32_t cli_sock); 41 | u16_t server_get_client_port(s32_t cli_sock); 42 | void server_close_client(s32_t cli_sock); 43 | SRV_STATUS server_check_client_status(s32_t cli_sock); 44 | 45 | 46 | s32_t server_check_client_snd_buf(s32_t cli_sock); 47 | s32_t server_check_client_recv_buf(s32_t cli_sock); 48 | s32_t server_snd_client_data(s32_t cli_sock, s8_t *buf, s32_t len); 49 | s32_t server_recv_client_data(s32_t cli_sock, s8_t *buf, s32_t len); 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /rawket/include/ring_buf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : ring_buf.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifndef __RING_BUF_H 17 | #define __RING_BUF_H 18 | //#include "system_Include.h" 19 | //#include "stm32f4xx.h" 20 | #include "cc.h" 21 | #include "mem.h" 22 | #include "memp.h" 23 | #include 24 | 25 | #define MAX_RING_BUF (8*1024) 26 | typedef struct ringbuf 27 | { 28 | u32_t start; 29 | u32_t end; 30 | u32_t total; 31 | u8_t * buff; 32 | }RING_BUF; 33 | 34 | s32_t ring_buf_create(RING_BUF *ring, u32_t len); 35 | s32_t ring_buf_used(RING_BUF *ring); 36 | s32_t ring_buf_unused(RING_BUF *ring); 37 | 38 | s32_t ring_buf_take(RING_BUF *ring, s8_t *buf, u32_t buf_len); 39 | s32_t ring_buf_push(RING_BUF *ring, s8_t *buf, u32_t buf_len); 40 | void ring_buf_delete(RING_BUF *ring); 41 | void ring_buf_reset(RING_BUF *ring); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /rawket/include/tcp_client_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_client_mgr.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifndef __TCP_CLIENT_MGR_H 17 | #define __TCP_CLIENT_MGR_H 18 | 19 | #include "ring_buf.h" 20 | #include "tcp_connection.h" 21 | 22 | #define MAX_CLIENT (16) //max is 32!! 23 | typedef struct tcp_cli_struct 24 | { 25 | u32_t cli_mask; 26 | tcp_conn_args * client[MAX_CLIENT]; 27 | }tcp_client_struct; 28 | 29 | void tcp_client_mgr_init(void); 30 | void tcp_client_mgr_destroy(void); 31 | s32_t tcp_client_mgr_get_client_sock(void); 32 | void tcp_client_mgr_set_client_sock(s32_t sock, tcp_conn_args *cli); 33 | void tcp_client_mgr_clear_client_sock(s32_t sock); 34 | tcp_conn_args *tcp_client_mgr_get_conn_arg(s32_t sock); 35 | 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /rawket/include/tcp_connection.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_connection.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifndef __TCP_CONNECTION_H 17 | #define __TCP_CONNECTION_H 18 | 19 | #include "lwip/netif.h" 20 | #include "lwip/ip.h" 21 | #include "lwip/tcp.h" 22 | #include "lwip/init.h" 23 | #include "lwip/pbuf.h" 24 | #include "lwip/inet.h" 25 | 26 | #include "ring_buf.h" 27 | #define CONN_TYPE_CLIENT 0x8000 28 | #define CONN_TYPE_SERVER 0x0000 29 | 30 | #define CONN_CLIENT_INIT (CONN_TYPE_CLIENT + 0x0000) 31 | #define CONN_CLIENT_CONNECTING (CONN_TYPE_CLIENT + 0x0100) 32 | #define CONN_CLIENT_CONNECTED (CONN_TYPE_CLIENT + 0x0200) 33 | #define CONN_CLIENT_RECONNECTING (CONN_TYPE_CLIENT + 0x0400) 34 | #define CONN_CLIENT_CLOSED (CONN_TYPE_CLIENT + 0x0800) 35 | 36 | #define CONN_SERVER_INIT (CONN_TYPE_SERVER + 0x0000) 37 | #define CONN_SERVER_CONNECTED (CONN_TYPE_SERVER + 0x0200) 38 | #define CONN_SERVER_CLOSED (CONN_TYPE_SERVER + 0x0800) 39 | 40 | 41 | typedef struct tcp_conn_arg 42 | { 43 | struct ip_addr dst_ip; //dst ip 44 | u16_t dst_port; //dst port 45 | u16_t conn_status; 46 | struct tcp_pcb *pcb; 47 | RING_BUF snd_buf; 48 | RING_BUF rcv_buf; 49 | }tcp_conn_args; 50 | 51 | //adjust the send buffer and recv buffer according to your application. 52 | tcp_conn_args *tcp_conn_new_arg(u32_t snd_buf_len, u32_t rcv_buf_len); 53 | void tcp_conn_del_arg(tcp_conn_args * arg); 54 | void tcp_conn_client_reconnect(tcp_conn_args * arg); 55 | 56 | void tcp_conn_err(void *arg, err_t err); 57 | err_t tcp_conn_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); 58 | err_t tcp_conn_sent(void *arg, struct tcp_pcb *pcb, u16_t len); 59 | err_t tcp_conn_poll(void *arg, struct tcp_pcb *pcb); 60 | err_t tcp_conn_client_connected(void *arg, struct tcp_pcb *pcb, err_t err); 61 | err_t tcp_conn_server_accept(void *arg, struct tcp_pcb *pcb, err_t err); 62 | s32_t tcp_conn_snd_buf_unused(tcp_conn_args * arg); 63 | s32_t tcp_conn_rcv_buf_used(tcp_conn_args * arg); 64 | s32_t tcp_conn_send_data(tcp_conn_args * arg, s8_t *buf, s32_t len); 65 | s32_t tcp_conn_recv_data(tcp_conn_args * arg, s8_t *buf, s32_t len); 66 | 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /rawket/include/tcp_server_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_server_mgr.h 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifndef __TCP_SERVER_MGR_H 17 | #define __TCP_SERVER_MGR_H 18 | 19 | #include "ring_buf.h" 20 | #include "tcp_connection.h" 21 | 22 | #define MAX_SERVER (8) 23 | #define MAX_CLIENT_PER_SERVER (8) //max is 16!! 24 | #define CLIENT_FLAG_BEGIN (0x0001) 25 | #define SERVER_SOCK_MASK (0x0000FFFF) 26 | #define SERVER_SND_BUF_SIZE (2*TCP_WND) 27 | #define SERVER_RCV_BUF_SIZE (TCP_WND) 28 | 29 | typedef struct tcp_srv_struct 30 | { 31 | u16_t srv_sock; 32 | u16_t cli_mask; 33 | u32_t in_use; 34 | struct tcp_pcb *srv_pcb; 35 | tcp_conn_args * client[MAX_CLIENT_PER_SERVER]; 36 | }tcp_server_struct; 37 | 38 | void tcp_server_mgr_init(void); 39 | void tcp_server_mgr_destroy(void); 40 | s32_t tcp_server_mgr_get_free_sock(void); 41 | void tcp_server_mgr_release_sock(s32_t srv_sock); 42 | tcp_server_struct *tcp_server_mgr_get_struct(s32_t srv_sock); 43 | 44 | 45 | 46 | s32_t tcp_conn_server_get_client_sock(tcp_server_struct *serv); 47 | void tcp_conn_server_set_client_sock(tcp_server_struct *serv, s32_t sock, tcp_conn_args *cli); 48 | void tcp_conn_server_clear_client_sock(tcp_server_struct *serv, s32_t sock); 49 | err_t tcp_conn_server_accept(void *arg, struct tcp_pcb *pcb, err_t err); 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /rawket/raw-api-chinese.txt: -------------------------------------------------------------------------------- 1 | Rawket---基于LwIP Raw API实现的类socket网络编程接口 2 | 作者:老衲五木(540535649@qq.com) 3 | 4 | 客户端操作函数:#include "raw_client_api.h" 5 | 0) client_init_manager(); 6 | 系统启动后,调用一次该函数来初始化客户端管理后台 7 | 1) int client_connect_to_server(ip, port) 8 | 说明:客户端用该函数用来发起向服务器的连接,注意该函数只是分配一个socket号并向服务器发送 9 | 连接请求,函数返回后,并不代表连接成功。函数执行成功,返回分配成功的socket号。 10 | 2) CLI_STATUS client_status_check(int sock) 11 | 说明:该函数用来检查客户端是否于服务器成功建立连接;如果返回CLI_CONNECTED表示连接建立成功,CLI_ERR表示连接未成功或正在重试连接。 12 | 3) client_close(int sock) 13 | 说明:客户端关闭到服务器的连接。当连接关闭后,对sock的任何操作都将返回错误。 14 | 15 | 4)int client_check_snd_buf(int sock) 16 | 说明:获取客户端sock的空余发送缓冲长度,在后续数据发送时,发送长度应该小于该值,否则数据发送将失败。 17 | 5)int client_check_recv_buf(int sock) 18 | 说明:获取客户端sock的接收缓冲长度,这个表示客户端当前接收到的但是还未被应用程序读取的数据。 19 | 6)int client_snd_data(int sock, char *buf, int len) 20 | 说明:客户端数据发送函数,将buf地址处的len个字节发送到服务器。如果len的长度大于socket的空余发送缓冲长度,该函数将返回失败,否则发送成功,数据被写入内部发送缓冲。 21 | 7)int client_recv_data(int sock, char *buf, int len) 22 | 说明:客户端数据接收函数,从socket上接收数据放入用户缓冲buf中,buf的长度为len。如果客户端没接收到任何数据,这个函数返回0,如果收到数据,则返回收到数据的大小。 23 | 24 | 服务器端操作函数:#include "raw_server_api.h" 25 | 0) server_init_manager(); 系统启动后,调用一次该函数来初始化服务器管理后台 26 | 1) int server_open(port) 27 | 说明:服务器开启侦听,若侦听成功,函数返回服务器socket。注意每个服务器支持的最多客户端数在代码中已通过宏MAX_CLIENT_PER_SERVER(该值最大为16)写定,不能动态更改。 28 | 2) int server_check_client(int srv_sock) 29 | 说明:检测服务器sock上的客户端连接情况,该函数返回值为一个32位的位图(仅低16位有效),若第i位为1,则表示一个客户端与服务器建立了连接,且该连接的socket号为(i<<16+srv_sock)。比如该函数返回值为0x0003,表示socket (1<<16+srv_sock) 和socket (2<<16+srv_sock) 连接已经建立。 30 | 3)void server_close(int srv_sock); 31 | 关闭服务器,这将导致该服务器上的所有客户端连接也被关闭。 32 | 33 | 4)ip_addr server_get_client_ip(int cli_sock) 34 | 说明:获得cli_sock上的客户端的IP地址 35 | 5)ip_addr server_get_client_port(int cli_sock) 36 | 说明:获得cli_sock上的客户端的端口号 37 | 6)server_close_client(int cli_sock) 38 | 说明:服务器关闭一个客户端的连接 39 | 40 | 7)int server_check_client_snd_buf(int cli_sock) 41 | 说明:服务器获取一个客户端连接sock的空余发送缓冲长度,在后续数据发送时,发送长度应该小于该值,否则数据发送将失败。 42 | 8)int server_check_client_recv_buf(int cli_sock) 43 | 说明:服务器获取一个客户端连接sock的接收缓冲长度,这个表示服务器在当前连接上接收到的但是还未被应用程序读取的数据。 44 | 9)int server_snd_client_data(int cli_sock, char *buf, int len) 45 | 说明:服务器端数据发送函数,将buf地址处的len个字节发送到客户端。如果len的长度大于socket的空余发送缓冲长度,该函数将返回失败,否则发送成功,数据被写入内部发送缓冲。 46 | 10)int server_recv_client_data(int cli_sock, char *buf, int len) 47 | 说明:服务器端数据接收函数,从socket上接收数据放入用户缓冲buf中,buf的长度为len。如果服务器在连接上没接收到任何数据,这个函数返回0,如果收到数据,则返回收到数据的大小。 48 | 49 | 使用例子 50 | 在rawket_example.c文件里面,我们基于Rawket API分别实现了一个回显客户端和回显服务器。 51 | 把这个文件和API文件一起加入到你的工程中,就可以直接把这两个基于Rawket API的网络应用跑起来了。 52 | 下面是整个代码的初始化以及两个应用程序调用方法: 53 | 54 | #include "raw_client_api.h" 55 | #include "raw_server_api.h" 56 | void main(void) 57 | { 58 | init_lwip(); //LwIP内核初始化,包括添加网卡结构等 59 | 60 | server_init_manager(); //@初始化Rawket服务器管理数据结构 61 | client_init_manager(); //@初始化Rawket客户端管理数据结构 62 | while(1) 63 | { 64 | packet_query_and_input(); //查询读取网卡数据包并交给内核处理 65 | sys_check_timeouts(); //处理内核超时事件 66 | 67 | raw_socket_client_demo(); //@ 基于Rawket的回显客户端 68 | raw_socket_server_demo(); //@ 基于Rawket的回显服务器 69 | } 70 | } -------------------------------------------------------------------------------- /rawket/raw-api-english.txt: -------------------------------------------------------------------------------- 1 | Rawket---A socket-like API for LwIP based on Raw API. 2 | Author: WuMu(540535649@qq.com) 3 | 4 | TCP Client APIs (#include "raw_client_api.h") 5 | 1) client_init_manager(); 6 | In your main function, when lwip initialization finished, call this to start the client manager. This function can only be called once. 7 | 8 | 2) int client_connect_to_server(ip, port) 9 | try to connect to a server, this function just allocate a client socket for the application, a SYN will be sent to server. 10 | 11 | 2) CLI_STATUS client_status_check(int sock) 12 | check whether the client connection is OK, the return value "CLI_CONNECTED" stands for success, and "CLI_ERR" stands for trying connecting or re-connecting. 13 | 14 | 3) client_close(int sock) 15 | close the client socket. 16 | 17 | 4)int client_check_snd_buf(int sock) 18 | check the send buffer length of the connection, application can only send data less than length. 19 | 20 | 5)int client_check_recv_buf(int sock) 21 | check the receiver buffer the connection, the non-zero value stands that there are data arrived, application can read data now. 22 | 23 | 6)int client_snd_data(int sock, char *buf, int len) 24 | send data on the connection, len should be less than the connection remaining send buffer, or else this API will fail. This API just write data to connection buffer. 25 | 26 | 7)int client_recv_data(int sock, char *buf, int len) 27 | receive data on the connection, the return value stands for the data length received. 28 | 29 | TCP server APIs(#include "raw_server_api.h") 30 | 0) server_init_manager(); 31 | In your main function, when lwip initialization finished, call this to start the server manager. This function can only be called once. 32 | 33 | 1) int server_open(port) 34 | open a tcp server, port will be used for listening. MAX_CLIENT_PER_SERVER(no more than 16) is the maximum clients a server can support. 35 | 36 | 2) int server_check_client(int srv_sock) 37 | check the clients that are connected to server. the return value is a 32 bit map, the low 16-bits stands for the connection status of 16 clients. 38 | For example, if the return value is 0x0003, then client 1 and client 2 is connected, the socket number for client 1 is (1<<16+srv_sock), while socket number for client 2 is (2<<16+srv_sock). 39 | 40 | 3)void server_close(int srv_sock); 41 | close server, all the client connections will be closed. 42 | 43 | 4)ip_addr server_get_client_ip(int cli_sock) 44 | get the client IP, the cli_sock is a client socket calculated as 2) 45 | 46 | 5)ip_addr server_get_client_port(int cli_sock) 47 | get the client port, the cli_sock is a client socket calculated as 2) 48 | 49 | 6)server_close_client(int cli_sock) 50 | close the connection to a client, the cli_sock is a client socket calculated as 2) 51 | 52 | 7)int server_check_client_snd_buf(int cli_sock) 53 | check the send buffer length of a client connection, application can only send data less than length. 54 | 55 | 8)int server_check_client_recv_buf(int cli_sock) 56 | check the receiver buffer a client connection, the non-zero value stands that there are data arrived, application can read data now. 57 | 58 | 9)int server_snd_client_data(int cli_sock, char *buf, int len) 59 | send data on a client connection, len should be less than the connection remaining send buffer, or else this API will fail. This API just write data to connection buffer. 60 | 61 | 10)int server_recv_client_data(int cli_sock, char *buf, int len) 62 | receive data on a client connection, the return value stands for the data length received. 63 | 64 | example demos: 65 | we have two examples in rawket_example.c which implemented as an echo client and an echo server. 66 | use them as follows to see how Rawket works. 67 | 68 | #include "raw_client_api.h" 69 | #include "raw_server_api.h" 70 | void main(void) 71 | { 72 | init_lwip(); //Lwip initialization, netif_add 73 | 74 | server_init_manager(); //@init the client manager once 75 | client_init_manager(); //@init the client manager once 76 | while(1) 77 | { 78 | packet_query_and_input(); //read packet from netif and call lwip core to process it 79 | sys_check_timeouts(); //lwip timeouts 80 | 81 | raw_socket_client_demo(); //@ example for Rawket client 82 | raw_socket_server_demo(); //@ example for Rawket server 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /rawket/raw_client_api.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : raw_client_api.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "raw_client_api.h" 18 | void client_init_manager(void) 19 | { 20 | tcp_client_mgr_init(); 21 | } 22 | void client_deinit_manager(void) 23 | { 24 | tcp_client_mgr_destroy(); 25 | } 26 | 27 | s32_t client_connect_to_server(struct ip_addr dst_ip, u16_t dst_port) 28 | { 29 | s32_t sock = -1; 30 | struct tcp_pcb *pcb = NULL; 31 | tcp_conn_args * cli = NULL; 32 | 33 | do 34 | { 35 | sock = tcp_client_mgr_get_client_sock(); 36 | if(sock < 0) 37 | { 38 | sock = -1; 39 | break; 40 | } 41 | 42 | cli = tcp_conn_new_arg(CLIENT_SND_BUF_SIZE, CLIENT_RCV_BUF_SIZE); 43 | if(cli == NULL) 44 | { 45 | sock = -2; 46 | break; 47 | 48 | } 49 | 50 | pcb = tcp_new(); 51 | if(pcb == NULL) 52 | { 53 | tcp_conn_del_arg(cli); 54 | sock = -3; 55 | break; 56 | 57 | } 58 | 59 | if(tcp_connect(pcb, &dst_ip, dst_port, tcp_conn_client_connected) != ERR_OK) 60 | { 61 | tcp_close(pcb); 62 | tcp_conn_del_arg(cli); 63 | sock = -4; 64 | break; 65 | } 66 | 67 | ip_set_option(pcb, SOF_KEEPALIVE); 68 | tcp_err(pcb, tcp_conn_err); 69 | tcp_arg(pcb, (void *)cli); 70 | 71 | cli->conn_status = CONN_CLIENT_CONNECTING; 72 | cli->dst_ip = dst_ip; 73 | cli->dst_port = dst_port; 74 | cli->pcb = pcb; 75 | 76 | tcp_client_mgr_set_client_sock(sock, cli); 77 | return sock; 78 | 79 | }while(0); 80 | 81 | return sock; 82 | } 83 | 84 | CLI_STATUS client_status_check(s32_t sock) 85 | { 86 | CLI_STATUS ret = CLI_ERR; 87 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 88 | if(cli == NULL) 89 | { 90 | return ret; 91 | } 92 | 93 | switch(cli->conn_status) 94 | { 95 | case CONN_CLIENT_CONNECTING: 96 | ret = CLI_CONNECTING; 97 | break; 98 | case CONN_CLIENT_CONNECTED: 99 | ret = CLI_CONNECTED; 100 | break; 101 | case CONN_CLIENT_RECONNECTING: 102 | ret = CLI_RECONNECTING; 103 | break; 104 | case CONN_CLIENT_CLOSED: 105 | ret = CLI_CLOSED; 106 | break; 107 | default: 108 | break; 109 | } 110 | 111 | return ret; 112 | } 113 | void client_close(s32_t sock) 114 | { 115 | struct tcp_pcb *pcb = NULL; 116 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 117 | if(cli == NULL) 118 | { 119 | return; 120 | } 121 | 122 | pcb = cli->pcb; 123 | if(pcb) 124 | { 125 | tcp_close(pcb); 126 | tcp_recv(pcb, NULL); 127 | tcp_sent(pcb, NULL); 128 | tcp_poll(pcb, NULL, 1); 129 | tcp_err(pcb, NULL); 130 | tcp_arg(pcb, NULL); 131 | } 132 | 133 | tcp_conn_del_arg(cli); 134 | tcp_client_mgr_clear_client_sock(sock); 135 | 136 | } 137 | s32_t client_check_snd_buf(s32_t sock) 138 | { 139 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 140 | if(cli == NULL) 141 | { 142 | return -1; 143 | } 144 | 145 | if(cli->conn_status == CONN_CLIENT_CLOSED) 146 | { 147 | return -2; 148 | } 149 | 150 | return tcp_conn_snd_buf_unused(cli); 151 | 152 | } 153 | s32_t client_check_recv_buf(s32_t sock) 154 | { 155 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 156 | if(cli == NULL) 157 | { 158 | return -1; 159 | } 160 | 161 | if(cli->conn_status == CONN_CLIENT_CLOSED) 162 | { 163 | return -2; 164 | } 165 | 166 | return tcp_conn_rcv_buf_used(cli); 167 | } 168 | s32_t client_snd_data(s32_t sock, s8_t *buf, s32_t len) 169 | { 170 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 171 | if(cli == NULL) 172 | { 173 | return -1; 174 | } 175 | 176 | if(cli->conn_status == CONN_CLIENT_CLOSED) 177 | { 178 | return -2; 179 | } 180 | 181 | return tcp_conn_send_data(cli, buf, len); 182 | 183 | } 184 | s32_t client_recv_data(s32_t sock, s8_t *buf, s32_t len) 185 | { 186 | tcp_conn_args *cli = tcp_client_mgr_get_conn_arg(sock); 187 | if(cli == NULL) 188 | { 189 | return -1; 190 | } 191 | 192 | if(cli->conn_status == CONN_CLIENT_CLOSED) 193 | { 194 | return -2; 195 | } 196 | 197 | return tcp_conn_recv_data(cli, buf, len); 198 | } 199 | 200 | #endif //LWIP_TCP 201 | -------------------------------------------------------------------------------- /rawket/raw_server_api.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : raw_server_api.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "raw_server_api.h" 18 | void server_init_manager(void) 19 | { 20 | tcp_server_mgr_init(); 21 | } 22 | void server_deinit_manager(void) 23 | { 24 | tcp_server_mgr_destroy(); 25 | } 26 | 27 | void tcp_srv_err(void *arg, err_t err) 28 | { 29 | tcp_server_struct * srv = (tcp_server_struct *)arg; 30 | srv->srv_pcb = NULL; 31 | server_close(srv->srv_sock); 32 | } 33 | 34 | s32_t server_open(u16_t local_port) 35 | { 36 | struct tcp_pcb *pcb = NULL; 37 | struct tcp_pcb *lpcb = NULL; 38 | s32_t sock = -1; 39 | tcp_server_struct * srv = NULL; 40 | do 41 | { 42 | sock = tcp_server_mgr_get_free_sock(); 43 | if(sock < 0) 44 | { 45 | break; 46 | } 47 | 48 | pcb = tcp_new(); 49 | if(pcb == NULL) 50 | { 51 | sock = -2; 52 | break; 53 | } 54 | 55 | if(tcp_bind(pcb, IP_ADDR_ANY, local_port) != ERR_OK) 56 | { 57 | tcp_close(pcb); 58 | sock = -3; 59 | break; 60 | } 61 | 62 | lpcb = tcp_listen(pcb); 63 | if(lpcb == NULL) 64 | { 65 | tcp_close(pcb); 66 | sock = -4; 67 | break; 68 | } 69 | 70 | tcp_accept(lpcb, tcp_conn_server_accept); 71 | srv = tcp_server_mgr_get_struct(sock); 72 | srv->in_use = 1; 73 | srv->srv_pcb = lpcb; 74 | srv->cli_mask = 0; 75 | srv->srv_sock = sock; 76 | tcp_arg(lpcb, (void *)srv); 77 | //tcp_err(lpcb, tcp_srv_err); //we can not set an error callback for LISTEN pcbs 78 | }while(0); 79 | 80 | return sock; 81 | } 82 | 83 | s32_t server_check_client(s32_t srv_sock) 84 | { 85 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 86 | if(srv == NULL || srv->in_use == 0) 87 | { 88 | return -1; 89 | } 90 | 91 | return srv->cli_mask; 92 | } 93 | 94 | void server_close(s32_t srv_sock) 95 | { 96 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 97 | tcp_conn_args * conn_arg = NULL; 98 | struct tcp_pcb * pcb = NULL; 99 | s32_t i = 0; 100 | if(srv == NULL || srv->in_use == 0) 101 | { 102 | return; 103 | } 104 | 105 | for(i = 0; i < MAX_CLIENT_PER_SERVER; i++) 106 | { 107 | if(((CLIENT_FLAG_BEGIN<cli_mask) == 1) 108 | { 109 | conn_arg = srv->client[i]; 110 | pcb = conn_arg->pcb; 111 | tcp_close(pcb); 112 | tcp_recv(pcb, NULL); 113 | tcp_sent(pcb, NULL); 114 | tcp_poll(pcb, NULL, 1); 115 | tcp_err(pcb, NULL); 116 | tcp_arg(pcb, NULL); 117 | tcp_conn_del_arg(conn_arg); 118 | tcp_conn_server_clear_client_sock(srv, i); 119 | } 120 | } 121 | 122 | if(srv->srv_pcb) 123 | { 124 | tcp_close(srv->srv_pcb); 125 | tcp_accept(srv->srv_pcb, NULL); 126 | srv->srv_pcb = NULL; 127 | } 128 | 129 | srv->cli_mask = 0; 130 | srv->in_use = 0; 131 | 132 | } 133 | 134 | //cli_sock consist of 16bit srv_sock and 16bit client socket 135 | struct ip_addr server_get_client_ip(s32_t cli_sock) 136 | { 137 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 138 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 139 | struct ip_addr ip_zero = {0}; 140 | tcp_conn_args * conn_arg = NULL; 141 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 142 | if(srv == NULL || srv->in_use == 0) 143 | { 144 | return ip_zero; 145 | } 146 | 147 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 148 | { 149 | return ip_zero; 150 | } 151 | 152 | return srv->client[cli]->dst_ip; 153 | 154 | } 155 | u16_t server_get_client_port(s32_t cli_sock) 156 | { 157 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 158 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 159 | 160 | tcp_conn_args * conn_arg = NULL; 161 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 162 | if(srv == NULL || srv->in_use == 0) 163 | { 164 | return -1; 165 | } 166 | 167 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 168 | { 169 | return -1; 170 | } 171 | 172 | return srv->client[cli]->dst_port; 173 | } 174 | void server_close_client(s32_t cli_sock) 175 | { 176 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 177 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 178 | 179 | tcp_conn_args * conn_arg = NULL; 180 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 181 | struct tcp_pcb * pcb = NULL; 182 | 183 | if(srv == NULL || srv->in_use == 0) 184 | { 185 | return; 186 | } 187 | 188 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 189 | { 190 | return; 191 | } 192 | 193 | conn_arg = srv->client[cli]; 194 | pcb = conn_arg->pcb; 195 | if(pcb) 196 | { 197 | tcp_close(pcb); 198 | tcp_recv(pcb, NULL); 199 | tcp_sent(pcb, NULL); 200 | tcp_poll(pcb, NULL, 1); 201 | tcp_err(pcb, NULL); 202 | tcp_arg(pcb, NULL); 203 | } 204 | 205 | tcp_conn_del_arg(conn_arg); 206 | tcp_conn_server_clear_client_sock(srv, cli); 207 | 208 | } 209 | SRV_STATUS server_check_client_status(s32_t cli_sock) 210 | { 211 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 212 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 213 | 214 | tcp_conn_args * conn_arg = NULL; 215 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 216 | if(srv == NULL || srv->in_use == 0) 217 | { 218 | return SRV_ERR; 219 | } 220 | 221 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 222 | { 223 | return SRV_ERR; 224 | } 225 | 226 | conn_arg = srv->client[cli]; 227 | if(conn_arg->conn_status == CONN_SERVER_CONNECTED) 228 | { 229 | return SRV_CONNECTED; 230 | } 231 | else if(conn_arg->conn_status == CONN_SERVER_CLOSED) 232 | { 233 | return SRV_CLOSED; 234 | } 235 | else 236 | { 237 | return SRV_ERR; 238 | } 239 | 240 | } 241 | 242 | 243 | s32_t server_check_client_snd_buf(s32_t cli_sock) 244 | { 245 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 246 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 247 | 248 | tcp_conn_args * conn_arg = NULL; 249 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 250 | if(srv == NULL || srv->in_use == 0) 251 | { 252 | return -1; 253 | } 254 | 255 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 256 | { 257 | return -1; 258 | } 259 | 260 | conn_arg = srv->client[cli]; 261 | 262 | if(conn_arg->conn_status != CONN_SERVER_CONNECTED) 263 | { 264 | return -2; 265 | } 266 | 267 | return tcp_conn_snd_buf_unused(conn_arg); 268 | 269 | } 270 | s32_t server_check_client_recv_buf(s32_t cli_sock) 271 | { 272 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 273 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 274 | 275 | tcp_conn_args * conn_arg = NULL; 276 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 277 | if(srv == NULL || srv->in_use == 0) 278 | { 279 | return -1; 280 | } 281 | 282 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 283 | { 284 | return -1; 285 | } 286 | 287 | conn_arg = srv->client[cli]; 288 | 289 | if(conn_arg->conn_status != CONN_SERVER_CONNECTED) 290 | { 291 | return -2; 292 | } 293 | 294 | return tcp_conn_rcv_buf_used(conn_arg); 295 | 296 | } 297 | s32_t server_snd_client_data(s32_t cli_sock, s8_t *buf, s32_t len) 298 | { 299 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 300 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 301 | 302 | tcp_conn_args * conn_arg = NULL; 303 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 304 | if(srv == NULL || srv->in_use == 0) 305 | { 306 | return -1; 307 | } 308 | 309 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 310 | { 311 | return -1; 312 | } 313 | 314 | conn_arg = srv->client[cli]; 315 | 316 | if(conn_arg->conn_status != CONN_SERVER_CONNECTED) 317 | { 318 | return -2; 319 | } 320 | 321 | return tcp_conn_send_data(conn_arg, buf, len); 322 | } 323 | s32_t server_recv_client_data(s32_t cli_sock, s8_t *buf, s32_t len) 324 | { 325 | s32_t srv_sock = cli_sock & SERVER_SOCK_MASK; 326 | s32_t cli = (cli_sock>>16) & SERVER_SOCK_MASK; 327 | 328 | tcp_conn_args * conn_arg = NULL; 329 | tcp_server_struct * srv = tcp_server_mgr_get_struct(srv_sock); 330 | if(srv == NULL || srv->in_use == 0) 331 | { 332 | return -1; 333 | } 334 | 335 | if(((CLIENT_FLAG_BEGIN<cli_mask)== 0 || srv->client[cli] == NULL) 336 | { 337 | return -1; 338 | } 339 | 340 | conn_arg = srv->client[cli]; 341 | 342 | if(conn_arg->conn_status != CONN_SERVER_CONNECTED) 343 | { 344 | return -2; 345 | } 346 | 347 | return tcp_conn_recv_data(conn_arg, buf, len); 348 | 349 | } 350 | 351 | #endif //LWIP_TCP 352 | -------------------------------------------------------------------------------- /rawket/rawket_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : rawket_example.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | 18 | #include "raw_client_api.h" 19 | #include "raw_server_api.h" 20 | 21 | void raw_socket_client_demo(void) 22 | { 23 | static CLI_STATUS client_status = CLI_INIT; 24 | static int client_sock = -1; 25 | struct ip_addr dst_ip; 26 | #define DALEN 512 27 | char data[DALEN]; 28 | int len = 0; 29 | 30 | if(client_status == CLI_INIT) 31 | { 32 | IP4_ADDR(&dst_ip,192,168,1,11); 33 | client_sock = client_connect_to_server(dst_ip, 8081); 34 | if(client_sock < 0) 35 | { 36 | client_status = CLI_ERR; 37 | } 38 | else 39 | { 40 | client_status = CLI_CONNECTING; 41 | } 42 | } 43 | else if(client_status == CLI_CONNECTING || client_status == CLI_RECONNECTING) 44 | { 45 | client_status = client_status_check(client_sock); 46 | printf("rawket client: 8081 CLI_CONNECTING\n"); 47 | } 48 | else if(client_status == CLI_CONNECTED) 49 | { 50 | len = client_recv_data(client_sock, (s8_t *)data, DALEN); 51 | if(len > 0) 52 | { 53 | client_snd_data(client_sock, (s8_t *)data, len);//echo 54 | } 55 | else 56 | { 57 | client_status = client_status_check(client_sock); 58 | } 59 | } 60 | else if(client_status == CLI_CLOSED) 61 | { 62 | client_close(client_sock); 63 | client_sock = -1; 64 | // stop client. or set to CLI_INIT to restart client 65 | client_status = CLI_ERR; 66 | printf("rawket client: close socket\n"); 67 | } 68 | else 69 | { 70 | printf("rawket client: connect error\n"); 71 | } 72 | 73 | } 74 | void raw_socket_server_demo(void) 75 | { 76 | static int srv = -1; 77 | static int srv_stat = SRV_INIT; 78 | #define DALEN 512 79 | char data[DALEN]; 80 | int len = 0; 81 | int cli_map = 0; 82 | int i = 0; 83 | int cli_sock = 0; 84 | int cli_stat = SRV_INIT; 85 | 86 | if(srv_stat == SRV_INIT) 87 | { 88 | srv = server_open(8888); 89 | srv_stat = (srv < 0)?SRV_ERR : SRV_CONNECTED; 90 | printf("rawket server: server opened\n"); 91 | } 92 | else if(srv_stat == SRV_CONNECTED) 93 | { 94 | cli_map = server_check_client(srv); 95 | if(cli_map < 0) 96 | { 97 | srv_stat = SRV_ERR; 98 | server_close(srv); 99 | } 100 | else if(cli_map == 0) 101 | { 102 | //no client connected 103 | //printf("rawket server: server no connections\n"); 104 | } 105 | else 106 | { 107 | //process all clients 108 | for(i = 0; i < MAX_CLIENT_PER_SERVER; i++) 109 | { 110 | if(((CLIENT_FLAG_BEGIN< 0) 118 | { 119 | server_snd_client_data(cli_sock, (s8_t *)data, len); //echo, ignore the result here? 120 | } 121 | } 122 | else 123 | { 124 | printf("rawket server: server close client\n"); 125 | server_close_client(cli_sock); 126 | } 127 | } 128 | } 129 | 130 | } 131 | 132 | } 133 | else 134 | { 135 | printf("rawket server: server error\n"); 136 | } 137 | } 138 | 139 | #endif //LWIP_TCP 140 | -------------------------------------------------------------------------------- /rawket/readme.txt: -------------------------------------------------------------------------------- 1 | Rawket: 2 | A socket-like API for LwIP based on raw api. 3 | 4 | Rawket supports: 5 | 1) TCP client APIs, integrated with auto reconnecting and error handling, hardware-independent keep-alive. 6 | Use a socket handler to send and receive data, all APIs are no-blocking APIs. 7 | 2) TCP server APIs, supports 16 servers maximun, and maximun 16 clients per server. 8 | 3) two examples about how to use Rawket to build an echo client and an echo server. 9 | 10 | Usage: 11 | Please refer to raw-api-xxxxx.txt for API details. 12 | 13 | Support & Bug Report: 540535649@qq.com -------------------------------------------------------------------------------- /rawket/ring_buf.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : ring_buf.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "ring_buf.h" 18 | #include "mem.h" 19 | 20 | s32_t ring_buf_create(RING_BUF *ring, u32_t len) 21 | { 22 | if(ring == NULL || len == 0 || len > MAX_RING_BUF) 23 | { 24 | return -1; 25 | } 26 | 27 | ring->buff = (u8_t *)mem_malloc((mem_size_t)len); 28 | if(ring->buff == NULL) 29 | { 30 | return -2; 31 | } 32 | 33 | ring->total = len; 34 | ring->start = 0; 35 | ring->end = 0; 36 | return 0; 37 | } 38 | s32_t ring_buf_used(RING_BUF *ring) 39 | { 40 | if(ring->end == ring->start) 41 | { 42 | return 0; 43 | } 44 | 45 | if(ring->end > ring->start) 46 | { 47 | return (ring->end - ring->start); 48 | } 49 | else 50 | { 51 | return ring->end + (ring->total - ring->start); 52 | } 53 | } 54 | 55 | s32_t ring_buf_unused(RING_BUF *ring) 56 | { 57 | if(ring->end == ring->start) 58 | { 59 | return ring->total; 60 | } 61 | 62 | if(ring->end > ring->start) 63 | { 64 | return ring->start + (ring->total - ring->end); 65 | } 66 | else 67 | { 68 | return (ring->start - ring->end); 69 | } 70 | } 71 | 72 | s32_t ring_buf_take(RING_BUF *ring, s8_t *buf, u32_t buf_len) 73 | { 74 | u32_t remain = 0; 75 | u32_t ret = 0; 76 | u32_t i = 0; 77 | if(ring == NULL || buf == NULL || buf_len == 0) 78 | { 79 | //return -1; 80 | return 0; 81 | } 82 | 83 | if(ring->end == ring->start) 84 | { 85 | return 0; 86 | } 87 | 88 | if(buf_len== 0) 89 | { 90 | return 0; 91 | } 92 | 93 | if(ring->end > ring->start) 94 | { 95 | remain = ring->end - ring->start; 96 | } 97 | else 98 | { 99 | remain = ring->end + (ring->total - ring->start); 100 | } 101 | 102 | ret = buf_len < remain?buf_len:remain; 103 | 104 | if(ring->end > ring->start) 105 | { 106 | memcpy(buf, &ring->buff[ring->start], ret); 107 | } 108 | else 109 | { 110 | i = (ring->total - ring->start); 111 | if(i >= ret) 112 | { 113 | memcpy(buf, &ring->buff[ring->start], ret); 114 | } 115 | else 116 | { 117 | memcpy(buf, &ring->buff[ring->start], i); 118 | memcpy(&buf[i], &ring->buff[0], (ret - i)); 119 | } 120 | 121 | } 122 | 123 | ring->start += ret; 124 | ring->start = ring->start%ring->total; 125 | 126 | return ret; 127 | 128 | } 129 | s32_t ring_buf_push(RING_BUF *ring, s8_t *buf, u32_t buf_len) 130 | { 131 | u32_t free = 0; 132 | u32_t i = 0; 133 | if((ring->end + 1)%ring->total == ring->start) 134 | { 135 | //return -1; //full 136 | return 0; 137 | } 138 | 139 | if(ring->end < ring->start) 140 | { 141 | free = ring->start - ring->end; 142 | } 143 | else 144 | { 145 | free = ring->start + (ring->total - ring->end); 146 | } 147 | 148 | if(buf_len > (free - 1)) 149 | { 150 | //return -2; //no enough buffer 151 | return 0; 152 | } 153 | 154 | if(ring->end < ring->start) 155 | { 156 | memcpy(&ring->buff[ring->end], buf, buf_len); 157 | } 158 | else 159 | { 160 | i = (ring->total - ring->end); 161 | if(i >= buf_len) 162 | { 163 | memcpy(&ring->buff[ring->end], buf, buf_len); 164 | } 165 | else 166 | { 167 | memcpy(&ring->buff[ring->end], buf, i); 168 | memcpy(&ring->buff[0], &buf[i], (buf_len - i)); 169 | } 170 | 171 | } 172 | 173 | ring->end += buf_len; 174 | ring->end = ring->end%ring->total; 175 | 176 | return buf_len; 177 | } 178 | void ring_buf_delete(RING_BUF *ring) 179 | { 180 | if(ring == NULL || ring->buff == NULL) 181 | { 182 | return; 183 | } 184 | 185 | mem_free(ring->buff); 186 | ring->buff = NULL; 187 | 188 | ring->total = 0; 189 | ring->start = 0; 190 | ring->end = 0; 191 | } 192 | 193 | void ring_buf_reset(RING_BUF *ring) 194 | { 195 | ring->start = 0; 196 | ring->end = 0; 197 | } 198 | 199 | #endif //LWIP_TCP 200 | -------------------------------------------------------------------------------- /rawket/tcp_client_mgr.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_client_mgr.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "tcp_client_mgr.h" 18 | 19 | tcp_client_struct *client_mgr = NULL; 20 | 21 | void tcp_client_mgr_init(void) 22 | { 23 | 24 | client_mgr = (tcp_client_struct *)mem_malloc(sizeof(tcp_client_struct)); 25 | if(client_mgr == NULL) 26 | { 27 | return; 28 | } 29 | 30 | memset((void *)client_mgr, 0, sizeof(tcp_client_struct)); 31 | } 32 | void tcp_client_mgr_destroy(void) 33 | { 34 | if(client_mgr != NULL) 35 | { 36 | mem_free(client_mgr); 37 | client_mgr = NULL; 38 | } 39 | } 40 | 41 | s32_t tcp_client_mgr_get_client_sock(void) 42 | { 43 | s32_t i = 0; 44 | 45 | for(i = 0; i < MAX_CLIENT; i++) 46 | { 47 | if(((0x0001<cli_mask) == 0) 48 | { 49 | return i; 50 | } 51 | } 52 | 53 | return -1; 54 | } 55 | 56 | void tcp_client_mgr_set_client_sock(s32_t sock, tcp_conn_args *cli) 57 | { 58 | if(sock >= MAX_CLIENT || cli == NULL) 59 | { 60 | return; 61 | } 62 | 63 | client_mgr->cli_mask |= (0x0001<client[sock] = cli; 66 | 67 | return; 68 | } 69 | void tcp_client_mgr_clear_client_sock(s32_t sock) 70 | { 71 | if(sock < 0 || sock >= MAX_CLIENT) 72 | { 73 | return; 74 | } 75 | 76 | client_mgr->cli_mask &= ~(0x0001<client[sock] = NULL; 79 | 80 | return; 81 | } 82 | 83 | tcp_conn_args *tcp_client_mgr_get_conn_arg(s32_t sock) 84 | { 85 | if(sock < 0 || sock >= MAX_CLIENT) 86 | { 87 | return NULL; 88 | } 89 | 90 | return client_mgr->client[sock]; 91 | } 92 | 93 | #endif //LWIP_TCP 94 | -------------------------------------------------------------------------------- /rawket/tcp_connection.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_connection.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "tcp_connection.h" 18 | 19 | tcp_conn_args *tcp_conn_new_arg(u32_t snd_buf_len, u32_t rcv_buf_len) 20 | { 21 | tcp_conn_args *ret = NULL; 22 | ret = (tcp_conn_args *)mem_malloc(sizeof(tcp_conn_args)); 23 | if(ret == NULL) 24 | { 25 | return NULL; 26 | } 27 | 28 | do 29 | { 30 | if(ring_buf_create(&ret->snd_buf, snd_buf_len) < 0) 31 | { 32 | mem_free(ret); 33 | ret = NULL; 34 | break; 35 | } 36 | 37 | if(ring_buf_create(&ret->rcv_buf, rcv_buf_len) < 0) 38 | { 39 | ring_buf_delete(&ret->snd_buf); 40 | mem_free(ret); 41 | ret = NULL; 42 | break; 43 | } 44 | 45 | return ret; 46 | }while(0); 47 | 48 | return NULL; 49 | } 50 | void tcp_conn_del_arg(tcp_conn_args * arg) 51 | { 52 | if(arg == NULL) 53 | { 54 | return; 55 | } 56 | 57 | ring_buf_delete(&arg->snd_buf); 58 | ring_buf_delete(&arg->rcv_buf); 59 | mem_free(arg); 60 | } 61 | 62 | void tcp_conn_client_reconnect(tcp_conn_args * arg) 63 | { 64 | struct tcp_pcb *pcb = NULL; 65 | struct ip_addr server_ip; 66 | 67 | pcb = tcp_new(); 68 | if(pcb == NULL) 69 | { 70 | arg->conn_status = CONN_CLIENT_CLOSED; 71 | return; 72 | } 73 | 74 | if(tcp_connect(pcb, &arg->dst_ip, arg->dst_port, tcp_conn_client_connected) != ERR_OK) 75 | { 76 | memp_free(MEMP_TCP_PCB, pcb); 77 | arg->conn_status = CONN_CLIENT_CLOSED; 78 | return; 79 | } 80 | 81 | //ip_set_option(pcb, SOF_KEEPALIVE); 82 | tcp_err(pcb, tcp_conn_err); 83 | tcp_arg(pcb, (void *)arg); 84 | arg->conn_status = CONN_CLIENT_RECONNECTING; 85 | arg->pcb = pcb; 86 | ring_buf_reset(&arg->rcv_buf); 87 | ring_buf_reset(&arg->snd_buf); //keep all data in send buffer 88 | } 89 | 90 | 91 | void tcp_conn_err(void *arg, err_t err) 92 | { 93 | tcp_conn_args * args = (tcp_conn_args *)arg; 94 | if(args == NULL) 95 | { 96 | return; 97 | } 98 | 99 | if(args->conn_status & CONN_TYPE_CLIENT) 100 | { 101 | 102 | args->pcb = NULL; 103 | //don't reconnect when there is RST error from server, to avoid multiple reconnecting clients. 104 | if(err != ERR_RST) 105 | { 106 | tcp_conn_client_reconnect(args); 107 | } 108 | else 109 | { 110 | args->conn_status = CONN_CLIENT_CLOSED; 111 | } 112 | } 113 | else 114 | { 115 | args->pcb = NULL; 116 | args->conn_status = CONN_SERVER_CLOSED; 117 | } 118 | 119 | if(args->conn_status == CONN_CLIENT_CLOSED || args->conn_status == CONN_SERVER_CLOSED) 120 | { 121 | ring_buf_delete(&args->snd_buf); 122 | ring_buf_delete(&args->rcv_buf); 123 | 124 | } 125 | 126 | return; 127 | } 128 | 129 | 130 | err_t tcp_conn_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 131 | { 132 | s32_t close_flag = 0; 133 | struct pbuf *q = NULL; 134 | tcp_conn_args * args = (tcp_conn_args *)arg; 135 | 136 | if(p != NULL) 137 | { 138 | //tcp_recved(pcb, p->tot_len); 139 | q = p; 140 | while(q != NULL) 141 | { 142 | if(ring_buf_push(&args->rcv_buf, (s8_t *)q->payload, q->len) < 0) 143 | { 144 | close_flag = 1; 145 | break; 146 | } 147 | 148 | q = q->next; 149 | } 150 | 151 | pbuf_free(p); 152 | 153 | } 154 | else if (err == ERR_OK) 155 | {//closed by peer 156 | close_flag = 1; 157 | } 158 | 159 | if(close_flag == 1) 160 | { 161 | tcp_poll(pcb, NULL, 0); 162 | tcp_close(pcb); 163 | tcp_conn_err((void *)args, ERR_OK); 164 | } 165 | 166 | return ERR_OK; 167 | } 168 | err_t tcp_conn_try_send(struct tcp_pcb *pcb, tcp_conn_args * arg) 169 | { 170 | err_t ret = ERR_OK; 171 | u16_t buf_len = 0; 172 | u32_t len = 0; 173 | s8_t * send_buffer = NULL; 174 | u16_t remain = tcp_sndbuf(pcb); 175 | 176 | if(remain == 0) 177 | { 178 | return ret; 179 | } 180 | 181 | buf_len = remain > TCP_MSS?TCP_MSS:remain; 182 | send_buffer = (s8_t *)mem_malloc(buf_len); 183 | if(send_buffer == NULL) 184 | { 185 | return ERR_MEM; 186 | } 187 | 188 | len = ring_buf_take(&arg->snd_buf, send_buffer, buf_len); 189 | if(len > 0) 190 | { 191 | ret = tcp_write(pcb, send_buffer, len, 1); 192 | tcp_output(pcb); 193 | } 194 | 195 | mem_free(send_buffer); 196 | return ret; 197 | } 198 | 199 | err_t tcp_conn_sent(void *arg, struct tcp_pcb *pcb, u16_t len) 200 | { 201 | //add your code here 202 | 203 | return tcp_conn_poll(arg, pcb); 204 | } 205 | err_t tcp_conn_poll(void *arg, struct tcp_pcb *pcb) 206 | { 207 | err_t ret = ERR_OK; 208 | 209 | ret = tcp_conn_try_send(pcb, arg); 210 | if(ret != ERR_OK && ret != ERR_MEM) 211 | { 212 | tcp_poll(pcb, NULL, 0); 213 | tcp_close(pcb); 214 | tcp_conn_err((void *)arg, ERR_OK); 215 | } 216 | 217 | return ERR_OK; 218 | } 219 | err_t tcp_conn_client_connected(void *arg, struct tcp_pcb *pcb, err_t err) 220 | { 221 | tcp_conn_args * cli = (tcp_conn_args *)arg; 222 | 223 | cli->conn_status = CONN_CLIENT_CONNECTED; 224 | ip_set_option(pcb, SOF_KEEPALIVE); 225 | tcp_recv(pcb, tcp_conn_recv); 226 | tcp_sent(pcb, tcp_conn_sent); 227 | tcp_poll(pcb, tcp_conn_poll, 1); 228 | 229 | return tcp_conn_poll(arg, pcb); 230 | } 231 | 232 | s32_t tcp_conn_snd_buf_unused(tcp_conn_args * arg) 233 | { 234 | return ring_buf_unused(&arg->snd_buf); 235 | } 236 | 237 | s32_t tcp_conn_rcv_buf_used(tcp_conn_args * arg) 238 | { 239 | return ring_buf_used(&arg->rcv_buf); 240 | } 241 | 242 | s32_t tcp_conn_send_data(tcp_conn_args * arg, s8_t *buf, s32_t len) 243 | { 244 | //return ring_buf_push(&arg->snd_buf, buf, len); 245 | s32_t ret = ring_buf_push(&arg->snd_buf, buf, len); 246 | tcp_conn_try_send(arg->pcb, arg); 247 | 248 | return ret; 249 | } 250 | 251 | s32_t tcp_conn_recv_data(tcp_conn_args * arg, s8_t *buf, s32_t len) 252 | { 253 | s32_t ret = ring_buf_take(&arg->rcv_buf, buf, len); 254 | if(ret > 0) 255 | { 256 | tcp_recved(arg->pcb, (u16_t)ret); 257 | } 258 | 259 | return ret; 260 | } 261 | 262 | #endif //LWIP_TCP 263 | -------------------------------------------------------------------------------- /rawket/tcp_server_mgr.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * lwIP TCP/IP Stack & Rawket 4 | * a socket-like API based on LwIP raw API 5 | * 6 | * File : tcp_server_mgr.c 7 | * 8 | * Author : WuMu (forrest) 9 | * 10 | * Contact: 540535649@qq.com 11 | * 12 | * easynetworking.cn, Nanjing, P.R.China, <2017.01> 13 | ********************************************************************************************************* 14 | */ 15 | 16 | #ifdef RAWKET 17 | #include "tcp_server_mgr.h" 18 | 19 | tcp_server_struct *server_mgr = NULL; 20 | void tcp_server_mgr_init(void) 21 | { 22 | server_mgr = (tcp_server_struct *)mem_malloc(sizeof(tcp_server_struct)*MAX_SERVER); 23 | if(server_mgr == NULL) 24 | { 25 | return; 26 | } 27 | 28 | memset((void *)server_mgr, 0, sizeof(tcp_server_struct)*MAX_SERVER); 29 | } 30 | void tcp_server_mgr_destroy(void) 31 | { 32 | if(server_mgr != NULL) 33 | { 34 | mem_free(server_mgr); 35 | server_mgr = NULL; 36 | } 37 | } 38 | 39 | s32_t tcp_server_mgr_get_free_sock(void) 40 | { 41 | s32_t i = 0; 42 | for(i = 0; i < MAX_SERVER; i++) 43 | { 44 | if(server_mgr[i].in_use == 0) 45 | { 46 | return i; 47 | } 48 | } 49 | 50 | return -1; 51 | } 52 | 53 | void tcp_server_mgr_release_sock(s32_t srv_sock) 54 | { 55 | server_mgr[srv_sock].in_use = 0; 56 | } 57 | 58 | tcp_server_struct *tcp_server_mgr_get_struct(s32_t srv_sock) 59 | { 60 | 61 | s32_t i = srv_sock&SERVER_SOCK_MASK; 62 | 63 | if(i < 0 || i >= MAX_SERVER) 64 | { 65 | return NULL; 66 | } 67 | 68 | if(server_mgr == NULL) 69 | { 70 | return NULL; 71 | } 72 | 73 | return &server_mgr[i]; 74 | } 75 | 76 | 77 | s32_t tcp_conn_server_get_client_sock(tcp_server_struct *serv) 78 | { 79 | s32_t i = 0; 80 | 81 | if(serv == NULL) 82 | { 83 | return -1; 84 | } 85 | 86 | for(i = 0; i < MAX_CLIENT_PER_SERVER; i++) 87 | { 88 | if(((0x0001<cli_mask) == 0) 89 | { 90 | return i; 91 | } 92 | } 93 | 94 | return -1; 95 | } 96 | 97 | void tcp_conn_server_set_client_sock(tcp_server_struct *serv, s32_t sock, tcp_conn_args *cli) 98 | { 99 | if(serv == NULL || sock >= MAX_CLIENT_PER_SERVER || cli == NULL) 100 | { 101 | return; 102 | } 103 | 104 | serv->cli_mask |= (0x0001<client[sock] = cli; 107 | 108 | return; 109 | } 110 | void tcp_conn_server_clear_client_sock(tcp_server_struct *serv, s32_t sock) 111 | { 112 | if(serv == NULL || sock >= MAX_CLIENT_PER_SERVER) 113 | { 114 | return; 115 | } 116 | 117 | serv->cli_mask &= ~(0x0001<client[sock] = NULL; 120 | 121 | return; 122 | } 123 | 124 | err_t tcp_conn_server_accept(void *arg, struct tcp_pcb *pcb, err_t err) 125 | { 126 | tcp_server_struct *serv = (tcp_server_struct *)arg; 127 | s32_t cli_sock = 0; 128 | tcp_conn_args *cli = NULL; 129 | do 130 | { 131 | if(serv == NULL) 132 | { 133 | break; 134 | } 135 | 136 | cli_sock = tcp_conn_server_get_client_sock(serv); 137 | if(cli_sock < 0) 138 | { 139 | break; 140 | } 141 | 142 | cli = tcp_conn_new_arg(SERVER_SND_BUF_SIZE, SERVER_RCV_BUF_SIZE); 143 | if(cli == NULL) 144 | { 145 | break; 146 | } 147 | 148 | cli->conn_status = CONN_SERVER_CONNECTED; 149 | cli->dst_ip = pcb->remote_ip; 150 | cli->dst_port = pcb->remote_port; 151 | cli->pcb = pcb; 152 | 153 | tcp_recv(pcb, tcp_conn_recv); 154 | tcp_sent(pcb, tcp_conn_sent); 155 | tcp_poll(pcb, tcp_conn_poll, 1); 156 | tcp_arg(pcb, (void *)cli); 157 | tcp_err(pcb, tcp_conn_err); 158 | 159 | tcp_conn_poll((void *)cli, pcb); 160 | 161 | tcp_conn_server_set_client_sock(serv, cli_sock, cli); 162 | 163 | return ERR_OK; 164 | 165 | }while(0); 166 | 167 | tcp_close(pcb); 168 | return ERR_MEM; 169 | 170 | } 171 | 172 | 173 | #endif //LWIP_TCP 174 | --------------------------------------------------------------------------------