]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - support/sdk/c/blip/libtcp/tcplib.h
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / support / sdk / c / blip / libtcp / tcplib.h
diff --git a/support/sdk/c/blip/libtcp/tcplib.h b/support/sdk/c/blip/libtcp/tcplib.h
new file mode 100644 (file)
index 0000000..71c235b
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * "Copyright (c) 2008, 2009 The Regents of the University  of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+#ifndef TCPLIB_H_
+#define TCPLIB_H_
+
+/* 
+ * tcplib: a simple tcp implemented in a library
+ * @author Stephen Dawson-Haggerty <stevedh@eecs.berkeley.edu>
+ *
+ *
+ */
+
+// #include <netinet/in.h>
+#include "ip.h"
+
+#define min(X,Y) (((X) > (Y)) ? (Y) : (X))
+#ifndef PC
+#define printf(X, args ...) dbg("stdout", X, ## args)
+#define fprintf(X, Y, args ...) dbg("fprintf", Y, ## args)
+#endif
+
+typedef enum {
+  TCP_CLOSED = 0,
+  TCP_LISTEN,
+  TCP_SYN_RCVD,
+  TCP_SYN_SENT,
+  TCP_ESTABLISHED,
+  TCP_CLOSE_WAIT,
+  TCP_LAST_ACK,
+  TCP_FIN_WAIT_1,
+  TCP_FIN_WAIT_2,
+  TCP_CLOSING,
+  TCP_TIME_WAIT,
+} tcplib_sock_state_t;
+
+enum {
+  TCP_ACKPENDING  = 0x3,
+  TCP_DUPACKS     = 0x3c,
+  TCP_DUPACKS_OFF = 2,
+  TCP_ACKSENT     = 0x80,
+};
+
+enum {
+  /* how many timer tics to stay in TIME_WAIT */
+  TCPLIB_TIMEWAIT_LEN = 1,
+  TCPLIB_2MSL = 4,
+  /* how many un-acked retransmissions before we give up the connection */
+  TCPLIB_GIVEUP = 6,
+};
+
+#define GET_ACK_COUNT(X)    (((X) & TCP_DUPACKS) >> TCP_DUPACKS_OFF)
+#define UNSET_ACK_COUNT(X)  ((X) &= ~TCP_DUPACKS)
+#define INCR_ACK_COUNT(X)   ((X) += 1 << TCP_DUPACKS_OFF)
+
+struct tcplib_sock {
+  uint8_t flags;
+  
+  /* local and remote endpoints */
+  struct sockaddr_in6 l_ep;
+  struct sockaddr_in6 r_ep;
+
+  /* current connection state */
+  tcplib_sock_state_t state;
+
+  void    *tx_buf;
+  uint16_t tx_buf_len;
+
+  /* max segment size, or default if
+     we didn't bother to pull it out
+     of the options field */
+  uint16_t mss;
+
+  uint16_t my_wind;
+  /* the window the other end is
+     reporting */
+  uint16_t r_wind;
+  uint16_t cwnd;
+  uint16_t ssthresh;
+
+  // the current next sequence number for ourgoing data.
+  uint32_t seqno;
+  // and the index of the last byte we've ACKed
+  uint32_t ackno;
+
+  struct {
+    int8_t retx;
+  } timer;
+
+  /* retransmission counter */
+  uint16_t retxcnt;
+
+  /* callbacks for this connection */
+/*   struct { */
+/*     /\* a previous connection request has finished *\/ */
+/*     void (*connect_done)(struct tcplib_sock *sock, int error); */
+
+/*     /\* a callback to signal new data is ready *\/ */
+/*     void (*recvfrom)(struct tcplib_sock *sock, void *data, int len); */
+
+/*     /\* the connection was closed by the other party *\/ */
+/*     void (*closed)(struct tcplib_sock *sock); */
+
+/*     /\* you called close(); we've finished closing the socket. *\/ */
+/*     void (*close_done)(struct tcplib_sock *sock); */
+/*   } ops; */
+
+  /* this needs to be at the end so
+     we can call init() on a socket
+     without blowing away the linked
+     list */
+  struct tcplib_sock *next;
+};
+
+/* EVENTS 
+ * ------------------------------------------------------------ 
+ *
+ * calls generated by tcplib that must be dealt with elsewhere in the
+ * program.
+ */
+
+
+/* called when a new connection request is recieved on a socket which
+ * is LISTENing.
+ *
+ *
+ * return 0 if it wants to accept the connection and allocated a
+ * buffer for it; -1 otherwise.
+ */
+struct tcplib_sock *tcplib_accept(struct tcplib_sock *conn,
+                                  struct sockaddr_in6 *from);
+
+/* a call-out point for tcplib to send a message */
+void tcplib_send_out(struct split_ip_msg *msg, struct tcp_hdr *tcph);
+
+/* upcall for new data; may be dispatched all the way out to a
+ * handler. 
+ *
+ * Returns: 0 on success,
+ * -1 otherwise.  The error may be safely ignored.
+ */
+int tcplib_process(struct ip6_hdr *ip_packet, void *payload);  
+
+/*
+ * should be called every 500ms to increment all the tcp timers
+ */
+int tcplib_timer_process();
+
+/* Just fill in the fields of the socket.
+ *
+ * If you perform a send on a socket in this state, an ephemeral port
+ * will be allocated to it.
+ *
+ * This must be called once on any socket that might be sent on, or
+ * might have bind() called.
+ */
+int tcplib_init_sock(struct tcplib_sock *sock);
+
+/* bind the socket to a local address */
+int tcplib_bind(struct tcplib_sock *sock,
+                struct sockaddr_in6 *addr);
+
+/* connect the socket to a remote endpoint */
+int tcplib_connect(struct tcplib_sock *sock,
+                   struct sockaddr_in6 *serv_addr);
+
+
+/* send data on an open socket.
+ *
+ * returns: 0 on success
+ *   other errors
+ *     - no local buffer is available,
+ *     
+ */
+int tcplib_send(struct tcplib_sock *sock,
+                 void *data, int len);
+
+int tcplib_close(struct tcplib_sock *sock);
+
+/* abort a connection 
+ *
+ * This will send a RST segment if the connection has been opened and
+ * immediately return the socket to the CLOSED, uninitialized state,
+ * although buffer pointers are maintained.
+ *
+ */
+int tcplib_abort(struct tcplib_sock *sock);
+#endif