34 #include "contiki-net.h"
38 #include "tcp-socket.h"
44 static void relisten(
struct tcp_socket *s);
48 PROCESS(tcp_socket_process,
"TCP socket process");
51 call_event(
struct tcp_socket *s, tcp_socket_event_t event)
53 if(s !=
NULL && s->event_callback !=
NULL) {
54 s->event_callback(s, s->ptr, event);
59 senddata(
struct tcp_socket *s)
61 int len = MIN(s->output_data_max_seg,
uip_mss());
63 if(s->output_senddata_len > 0) {
64 len = MIN(s->output_senddata_len, len);
65 s->output_data_send_nxt = len;
71 acked(
struct tcp_socket *s)
73 if(s->output_senddata_len > 0) {
77 if(s->output_data_send_nxt > 0) {
78 memcpy(&s->output_data_ptr[0],
79 &s->output_data_ptr[s->output_data_send_nxt],
80 s->output_data_maxlen - s->output_data_send_nxt);
82 if(s->output_data_len < s->output_data_send_nxt) {
83 printf(
"tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n",
85 s->output_data_send_nxt);
88 call_event(s, TCP_SOCKET_ABORTED);
92 s->output_data_len -= s->output_data_send_nxt;
93 s->output_senddata_len = s->output_data_len;
94 s->output_data_send_nxt = 0;
96 call_event(s, TCP_SOCKET_DATA_SENT);
103 uint16_t len, copylen, bytesleft;
115 copylen = MIN(len, s->input_data_maxlen);
116 memcpy(s->input_data_ptr, dataptr, copylen);
117 if(s->input_callback) {
118 bytesleft = s->input_callback(s, s->ptr,
119 s->input_data_ptr, copylen);
124 printf(
"tcp: newdata, bytesleft > 0 (%d) not implemented\n", bytesleft);
133 relisten(
struct tcp_socket *s)
135 if(s !=
NULL && s->listen_port != 0) {
136 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
143 struct tcp_socket *s = state;
160 if((s->flags & TCP_SOCKET_FLAGS_LISTENING) != 0 &&
161 s->listen_port != 0 &&
163 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
164 s->output_data_max_seg =
uip_mss();
166 call_event(s, TCP_SOCKET_CONNECTED);
171 s->output_data_max_seg =
uip_mss();
172 call_event(s, TCP_SOCKET_CONNECTED);
187 call_event(s, TCP_SOCKET_TIMEDOUT);
193 call_event(s, TCP_SOCKET_ABORTED);
218 if(s->output_data_len == 0 && s->flags & TCP_SOCKET_FLAGS_CLOSING) {
219 s->flags &= ~TCP_SOCKET_FLAGS_CLOSING;
231 call_event(s, TCP_SOCKET_CLOSED);
252 static uint8_t inited = 0;
261 tcp_socket_register(
struct tcp_socket *s,
void *ptr,
262 uint8_t *input_databuf,
int input_databuf_len,
263 uint8_t *output_databuf,
int output_databuf_len,
264 tcp_socket_data_callback_t input_callback,
265 tcp_socket_event_callback_t event_callback)
274 s->input_data_ptr = input_databuf;
275 s->input_data_maxlen = input_databuf_len;
276 s->output_data_len = 0;
277 s->output_data_ptr = output_databuf;
278 s->output_data_maxlen = output_databuf_len;
279 s->input_callback = input_callback;
280 s->event_callback = event_callback;
284 s->flags = TCP_SOCKET_FLAGS_NONE;
289 tcp_socket_connect(
struct tcp_socket *s,
290 const uip_ipaddr_t *
ipaddr,
297 tcp_markconn(s->c,
NULL);
310 tcp_socket_listen(
struct tcp_socket *s,
317 s->listen_port = port;
321 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
326 tcp_socket_unlisten(
struct tcp_socket *s)
336 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
341 tcp_socket_send(
struct tcp_socket *s,
342 const uint8_t *data,
int datalen)
350 len = MIN(datalen, s->output_data_maxlen - s->output_data_len);
352 memcpy(&s->output_data_ptr[s->output_data_len], data, len);
353 s->output_data_len += len;
355 if(s->output_senddata_len == 0) {
356 s->output_senddata_len = s->output_data_len;
363 tcp_socket_send_str(
struct tcp_socket *s,
366 return tcp_socket_send(s, (
const uint8_t *)str, strlen(str));
370 tcp_socket_close(
struct tcp_socket *s)
376 s->flags |= TCP_SOCKET_FLAGS_CLOSING;
381 tcp_socket_unregister(
struct tcp_socket *s)
387 tcp_socket_unlisten(s);
396 tcp_socket_max_sendlen(
struct tcp_socket *s)
398 return s->output_data_maxlen - s->output_data_len;
#define uip_acked()
Has previously sent data been acknowledged?
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
Representation of a uIP TCP connection.
#define uip_abort()
Abort the current connection.
#define LIST(name)
Declare a linked list.
static void newdata(void)
process_event_t tcpip_event
The uIP event.
CCIF struct uip_conn * tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Open a TCP connection to the specified IP address and port.
#define PROCESS_CONTEXT_END(p)
End a context switch.
Default definitions of C compiler quirk work-arounds.
#define uip_closed()
Has the connection been closed by the other end?
#define PROCESS_END()
Define the end of a process.
#define PROCESS(name, strname)
Declare a process.
void tcp_listen(uint16_t port)
Open a TCP port.
void * list_item_next(void *item)
Get the next item following this item.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
uip_appdata
Pointer to the application data in the packet buffer.
#define uip_aborted()
Has the connection been aborted by the other end?
void list_init(list_t list)
Initialize a list.
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
#define PROCESS_CONTEXT_BEGIN(p)
Switch context to another process.
void * list_head(list_t list)
Get a pointer to the first element of a list.
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
#define NULL
The null pointer.
CCIF void uip_send(const void *data, int len)
Send data on the current connection.
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
uint16_t lport
The local TCP port, in network byte order.
#define uip_mss()
Get the current maximum segment size that can be sent on the current connection.
#define uip_connected()
Has the connection just been connected?
void list_add(list_t list, void *item)
Add an item at the end of a list.
Linked list manipulation routines.
void process_start(struct process *p, process_data_t data)
Start a process.
#define uip_rexmit()
Do we need to retransmit previously data?
#define uip_close()
Close the current connection.
#define uip_poll()
Is the connection being polled by uIP?
#define uip_timedout()
Has the connection timed out?
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define uip_newdata()
Is new incoming data available?
CCIF uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
#define PROCESS_BEGIN()
Define the beginning of a process.