32 #define DEBUG DEBUG_NONE 37 #include "contiki-net.h" 41 #include "tcp-socket.h" 45 static void relisten(
struct tcp_socket *s);
49 PROCESS(tcp_socket_process,
"TCP socket process");
52 call_event(
struct tcp_socket *s, tcp_socket_event_t event)
54 if(s != NULL && s->event_callback != NULL) {
55 s->event_callback(s, s->ptr, event);
60 senddata(
struct tcp_socket *s)
62 int len = MIN(s->output_data_max_seg,
uip_mss());
64 if(s->output_senddata_len > 0) {
65 len = MIN(s->output_senddata_len, len);
66 s->output_data_send_nxt = len;
72 acked(
struct tcp_socket *s)
74 if(s->output_senddata_len > 0) {
78 if(s->output_data_send_nxt > 0) {
79 memmove(&s->output_data_ptr[0],
80 &s->output_data_ptr[s->output_data_send_nxt],
81 s->output_data_maxlen - s->output_data_send_nxt);
83 if(s->output_data_len < s->output_data_send_nxt) {
84 PRINTF(
"tcp: acked assertion failed s->output_data_len (%d) < s->output_data_send_nxt (%d)\n",
86 s->output_data_send_nxt);
89 call_event(s, TCP_SOCKET_ABORTED);
93 s->output_data_len -= s->output_data_send_nxt;
94 s->output_senddata_len = s->output_data_len;
95 s->output_data_send_nxt = 0;
97 call_event(s, TCP_SOCKET_DATA_SENT);
104 uint16_t len, copylen, bytesleft;
116 copylen = MIN(len, s->input_data_maxlen);
117 memcpy(s->input_data_ptr, dataptr, copylen);
118 if(s->input_callback) {
119 bytesleft = s->input_callback(s, s->ptr,
120 s->input_data_ptr, copylen);
125 PRINTF(
"tcp: newdata, bytesleft > 0 (%d) not implemented\n", bytesleft);
134 relisten(
struct tcp_socket *s)
136 if(s != NULL && s->listen_port != 0) {
137 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
144 struct tcp_socket *s = state;
146 if(s != NULL && s->c != NULL && s->c !=
uip_conn) {
161 if((s->flags & TCP_SOCKET_FLAGS_LISTENING) != 0 &&
162 s->listen_port != 0 &&
164 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
165 s->output_data_max_seg =
uip_mss();
167 call_event(s, TCP_SOCKET_CONNECTED);
172 s->output_data_max_seg =
uip_mss();
173 call_event(s, TCP_SOCKET_CONNECTED);
188 call_event(s, TCP_SOCKET_TIMEDOUT);
194 call_event(s, TCP_SOCKET_ABORTED);
219 if(s->output_data_len == 0 && s->flags & TCP_SOCKET_FLAGS_CLOSING) {
220 s->flags &= ~TCP_SOCKET_FLAGS_CLOSING;
232 call_event(s, TCP_SOCKET_CLOSED);
253 static uint8_t inited = 0;
262 tcp_socket_register(
struct tcp_socket *s,
void *ptr,
263 uint8_t *input_databuf,
int input_databuf_len,
264 uint8_t *output_databuf,
int output_databuf_len,
265 tcp_socket_data_callback_t input_callback,
266 tcp_socket_event_callback_t event_callback)
275 s->input_data_ptr = input_databuf;
276 s->input_data_maxlen = input_databuf_len;
277 s->output_data_len = 0;
278 s->output_data_ptr = output_databuf;
279 s->output_data_maxlen = output_databuf_len;
280 s->input_callback = input_callback;
281 s->event_callback = event_callback;
285 s->flags = TCP_SOCKET_FLAGS_NONE;
290 tcp_socket_connect(
struct tcp_socket *s,
291 const uip_ipaddr_t *
ipaddr,
298 tcp_markconn(s->c, NULL);
311 tcp_socket_listen(
struct tcp_socket *s,
318 s->listen_port = port;
322 s->flags |= TCP_SOCKET_FLAGS_LISTENING;
327 tcp_socket_unlisten(
struct tcp_socket *s)
337 s->flags &= ~TCP_SOCKET_FLAGS_LISTENING;
342 tcp_socket_send(
struct tcp_socket *s,
343 const uint8_t *data,
int datalen)
351 len = MIN(datalen, s->output_data_maxlen - s->output_data_len);
353 memmove(&s->output_data_ptr[s->output_data_len], data, len);
354 s->output_data_len += len;
356 if(s->output_senddata_len == 0) {
357 s->output_senddata_len = s->output_data_len;
366 tcp_socket_send_str(
struct tcp_socket *s,
369 return tcp_socket_send(s, (
const uint8_t *)str, strlen(str));
373 tcp_socket_close(
struct tcp_socket *s)
379 s->flags |= TCP_SOCKET_FLAGS_CLOSING;
384 tcp_socket_unregister(
struct tcp_socket *s)
390 tcp_socket_unlisten(s);
399 tcp_socket_max_sendlen(
struct tcp_socket *s)
401 return s->output_data_maxlen - s->output_data_len;
405 tcp_socket_queuelen(
struct tcp_socket *s)
407 return s->output_data_len;
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define PROCESS(name, strname)
Declare a process.
#define uip_close()
Close the current connection.
Representation of a uIP TCP connection.
#define PROCESS_CONTEXT_END(p)
End a context switch.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define uip_connected()
Has the connection just been connected?
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
process_event_t tcpip_event
The uIP event.
void tcp_attach(struct uip_conn *conn, void *appstate)
Attach a TCP connection to the current process.
void tcpip_poll_tcp(struct uip_conn *conn)
Cause a specified TCP connection to be polled.
#define uip_mss()
Get the current maximum segment size that can be sent on the current connection.
A set of debugging macros for the IP stack
static void newdata(void)
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
void tcp_unlisten(uint16_t port)
Close a listening TCP port.
#define uip_abort()
Abort the current connection.
#define uip_newdata()
Is new incoming data available?
Linked list manipulation routines.
void * list_head(list_t list)
Get a pointer to the first element of a list.
uint16_t lport
The local TCP port, in network byte order.
#define uip_acked()
Has previously sent data been acknowledged?
void list_add(list_t list, void *item)
Add an item at the end of a list.
#define uip_aborted()
Has the connection been aborted by the other end?
void list_init(list_t list)
Initialize a list.
void uip_send(const void *data, int len)
Send data on the current connection.
#define LIST(name)
Declare a linked list.
#define PROCESS_CONTEXT_BEGIN(p)
Switch context to another process.
void tcp_listen(uint16_t port)
Open a TCP port.
#define uip_timedout()
Has the connection timed out?
#define uip_rexmit()
Do we need to retransmit previously data?
#define uip_closed()
Has the connection been closed by the other end?
Default definitions of C compiler quirk work-arounds.
#define uip_poll()
Is the connection being polled by uIP?
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
void * list_item_next(void *item)
Get the next item following this item.
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.
void * uip_appdata
Pointer to the application data in the packet buffer.
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
void process_start(struct process *p, process_data_t data)
Start a process.