33 #include "contiki-net.h"
37 #include "tcp-socket.h"
42 #define MIN(a, b) ((a) < (b) ? (a) : (b))
46 PROCESS(tcp_socket_process,
"TCP socket process");
49 call_event(
struct tcp_socket *s, tcp_socket_event_t event)
51 if(s !=
NULL && s->event_callback !=
NULL) {
52 s->event_callback(s, s->ptr, event);
57 senddata(
struct tcp_socket *s)
61 if(s->output_data_len > 0) {
62 len = MIN(s->output_data_len,
uip_mss());
63 s->output_data_send_nxt = len;
69 acked(
struct tcp_socket *s)
71 if(s->output_data_len > 0) {
75 if(s->output_data_send_nxt > 0) {
76 memcpy(&s->output_data_ptr[0],
77 &s->output_data_ptr[s->output_data_send_nxt],
78 s->output_data_maxlen - s->output_data_send_nxt);
80 if(s->output_data_len < s->output_data_send_nxt) {
81 printf(
"tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n",
83 s->output_data_send_nxt);
85 s->output_data_len -= s->output_data_send_nxt;
86 s->output_data_send_nxt = 0;
88 call_event(s, TCP_SOCKET_DATA_SENT);
93 newdata(
struct tcp_socket *s)
95 uint16_t len, copylen, bytesleft;
107 copylen = MIN(len, s->input_data_maxlen);
108 memcpy(s->input_data_ptr, dataptr, copylen);
109 if(s->input_callback) {
110 bytesleft = s->input_callback(s, s->ptr,
111 s->input_data_ptr, copylen);
116 printf(
"tcp: newdata, bytesleft > 0 (%d) not implemented\n", bytesleft);
125 relisten(
struct tcp_socket *s)
127 if(s !=
NULL && s->listen_port != 0) {
128 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
135 struct tcp_socket *s = state;
147 if((s->flags & TCP_SOCKET_FLAGS_LISTENING) != 0 &&
148 s->listen_port != 0 &&
150 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
152 call_event(s, TCP_SOCKET_CONNECTED);
157 call_event(s, TCP_SOCKET_CONNECTED);
172 call_event(s, TCP_SOCKET_TIMEDOUT);
177 call_event(s, TCP_SOCKET_ABORTED);
201 if(s->output_data_len == 0 && s->flags & TCP_SOCKET_FLAGS_CLOSING) {
202 s->flags &= ~TCP_SOCKET_FLAGS_CLOSING;
205 call_event(s, TCP_SOCKET_CLOSED);
211 call_event(s, TCP_SOCKET_CLOSED);
232 static uint8_t inited = 0;
241 tcp_socket_register(
struct tcp_socket *s,
void *ptr,
242 uint8_t *input_databuf,
int input_databuf_len,
243 uint8_t *output_databuf,
int output_databuf_len,
244 tcp_socket_data_callback_t input_callback,
245 tcp_socket_event_callback_t event_callback)
254 s->input_data_ptr = input_databuf;
255 s->input_data_maxlen = input_databuf_len;
256 s->output_data_ptr = output_databuf;
257 s->output_data_maxlen = output_databuf_len;
258 s->input_callback = input_callback;
259 s->event_callback = event_callback;
263 s->flags = TCP_SOCKET_FLAGS_NONE;
268 tcp_socket_connect(
struct tcp_socket *s,
269 uip_ipaddr_t *ipaddr,
286 tcp_socket_listen(
struct tcp_socket *s,
293 s->listen_port = port;
297 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
302 tcp_socket_unlisten(
struct tcp_socket *s)
312 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
317 tcp_socket_send(
struct tcp_socket *s,
318 const uint8_t *data,
int datalen)
326 len = MIN(datalen, s->output_data_maxlen - s->output_data_len);
328 memcpy(&s->output_data_ptr[s->output_data_len], data, len);
329 s->output_data_len += len;
334 tcp_socket_send_str(
struct tcp_socket *s,
337 return tcp_socket_send(s, (
const uint8_t *)str, strlen(str));
341 tcp_socket_close(
struct tcp_socket *s)
347 s->flags |= TCP_SOCKET_FLAGS_CLOSING;
352 tcp_socket_unregister(
struct tcp_socket *s)
358 tcp_socket_unlisten(s);
Linked list manipulation routines.
#define PROCESS_BEGIN()
Define the beginning of a process.
Representation of a uIP TCP connection.
CCIF struct uip_conn * tcp_connect(uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
CCIF void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
#define uip_aborted()
Has the connection been aborted by the other end?
CCIF void uip_send(const void *data, int len)
Send data on the current connection.
#define uip_newdata()
Is new incoming data available?
void * list_item_next(void *item)
Get the next item following this item.
#define uip_mss()
Get the current maximum segment size that can be sent on the current connection.
uint16_t lport
The local TCP port, in network byte order.
#define NULL
The null pointer.
#define uip_poll()
Is the connection being polled by uIP?
void list_remove(list_t list, void *item)
Remove a specific element from a list.
CCIF void tcp_unlisten(uint16_t port)
Close a listening TCP port.
#define uip_acked()
Has previously sent data been acknowledged?
#define uip_connected()
Has the connection just been connected?
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
#define uip_abort()
Abort the current connection.
void list_init(list_t list)
Initialize a list.
void * list_head(list_t list)
Get a pointer to the first element of a list.
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
void list_add(list_t list, void *item)
Add an item at the end of a list.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define PROCESS(name, strname)
Declare a process.
#define LIST(name)
Declare a linked list.
#define uip_close()
Close the current connection.
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
process_event_t tcpip_event
The uIP event.
#define uip_timedout()
Has the connection timed out?
void process_start(struct process *p, process_data_t data)
Start a process.
CCIF void tcp_listen(uint16_t port)
Open a TCP port.
#define PROCESS_CONTEXT_BEGIN(p)
Switch context to another process.
#define uip_closed()
Has the connection been closed by the other end?
uip_appdata
Pointer to the application data in the packet buffer.
#define PROCESS_CONTEXT_END(p)
End a context switch.
#define uip_rexmit()
Do we need to retransmit previously data?