00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "contiki-conf.h"
00037 #include "contiki-net.h"
00038
00039 #include "net/packet-service.h"
00040 #include "net/uip-split.h"
00041
00042 #include <string.h>
00043
00044 process_event_t tcpip_event;
00045
00046
00047
00048
00049 struct listenport {
00050 u16_t port;
00051 struct process *p;
00052 };
00053
00054
00055
00056 static struct etimer periodic;
00057
00058 static struct internal_state {
00059 struct listenport listenports[UIP_LISTENPORTS];
00060 struct process *p;
00061 } s;
00062
00063 enum {
00064 TCP_POLL,
00065 UDP_POLL,
00066 PACKET_INPUT
00067 };
00068
00069 static unsigned char forwarding = 0;
00070
00071 PROCESS(tcpip_process, "TCP/IP stack");
00072
00073
00074 void
00075 tcpip_set_forwarding(unsigned char f)
00076 {
00077 forwarding = f;
00078 }
00079
00080 static void
00081 packet_input(void)
00082 {
00083 if(uip_len > 0) {
00084 if(forwarding) {
00085 if(uip_fw_forward() == 0) {
00086 uip_input();
00087 if(uip_len > 0) {
00088 #if UIP_CONF_TCP_SPLIT
00089 uip_split_output();
00090 #else
00091 tcpip_output();
00092 #endif
00093 }
00094 }
00095 } else {
00096 uip_input();
00097 if(uip_len > 0) {
00098 #if UIP_CONF_TCP_SPLIT
00099 uip_split_output();
00100 #else
00101 tcpip_output();
00102 #endif
00103 }
00104 }
00105 }
00106 }
00107
00108 void
00109 tcpip_output(void)
00110 {
00111 SERVICE_CALL(packet_service, output());
00112 }
00113
00114 struct uip_conn *
00115 tcp_connect(u16_t *ripaddr, u16_t port, void *appstate)
00116 {
00117 struct uip_conn *c;
00118
00119 c = uip_connect((uip_ipaddr_t *)ripaddr, port);
00120 if(c == NULL) {
00121 return NULL;
00122 }
00123
00124 c->appstate.p = PROCESS_CURRENT();
00125 c->appstate.state = appstate;
00126
00127 tcpip_poll_tcp(c);
00128
00129 return c;
00130 }
00131
00132 void
00133 tcp_unlisten(u16_t port)
00134 {
00135 static unsigned char i;
00136 struct listenport *l;
00137
00138 l = s.listenports;
00139 for(i = 0; i < UIP_LISTENPORTS; ++i) {
00140 if(l->port == port &&
00141 l->p == PROCESS_CURRENT()) {
00142 l->port = 0;
00143 uip_unlisten(port);
00144 break;
00145 }
00146 ++l;
00147 }
00148 }
00149
00150 void
00151 tcp_listen(u16_t port)
00152 {
00153 static unsigned char i;
00154 struct listenport *l;
00155
00156 l = s.listenports;
00157 for(i = 0; i < UIP_LISTENPORTS; ++i) {
00158 if(l->port == 0) {
00159 l->port = port;
00160 l->p = PROCESS_CURRENT();
00161 uip_listen(port);
00162 break;
00163 }
00164 ++l;
00165 }
00166 }
00167
00168 void
00169 tcp_attach(struct uip_conn *conn,
00170 void *appstate)
00171 {
00172 register uip_tcp_appstate_t *s;
00173
00174 s = &conn->appstate;
00175 s->p = PROCESS_CURRENT();
00176 s->state = appstate;
00177 }
00178
00179 void
00180 udp_attach(struct uip_udp_conn *conn,
00181 void *appstate)
00182 {
00183 register uip_udp_appstate_t *s;
00184
00185 s = &conn->appstate;
00186 s->p = PROCESS_CURRENT();
00187 s->state = appstate;
00188 }
00189
00190 struct uip_udp_conn *
00191 udp_new(u16_t *ripaddr, u16_t port, void *appstate)
00192 {
00193 struct uip_udp_conn *c;
00194 uip_udp_appstate_t *s;
00195
00196 c = uip_udp_new((uip_ipaddr_t *)ripaddr, port);
00197 if(c == NULL) {
00198 return NULL;
00199 }
00200
00201 s = &c->appstate;
00202 s->p = PROCESS_CURRENT();
00203 s->state = appstate;
00204
00205 return c;
00206 }
00207
00208 struct uip_udp_conn *
00209 udp_broadcast_new(u16_t port, void *appstate)
00210 {
00211 uip_ipaddr_t addr;
00212 struct uip_udp_conn *conn;
00213
00214 uip_ipaddr(addr, 255,255,255,255);
00215 conn = udp_new(addr, port, appstate);
00216 if(conn != NULL) {
00217 udp_bind(conn, port);
00218 }
00219 return conn;
00220 }
00221
00222 static void
00223 eventhandler(process_event_t ev, process_data_t data)
00224 {
00225 static unsigned char i;
00226 register struct listenport *l;
00227 struct process *p;
00228
00229 switch(ev) {
00230 case PROCESS_EVENT_EXITED:
00231
00232
00233
00234
00235 p = (struct process *)data;
00236 l = s.listenports;
00237 for(i = 0; i < UIP_LISTENPORTS; ++i) {
00238 if(l->p == p) {
00239 uip_unlisten(l->port);
00240 l->port = 0;
00241 l->p = PROCESS_NONE;
00242 }
00243 ++l;
00244 }
00245
00246 {
00247 register struct uip_conn *cptr;
00248
00249 for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) {
00250 if(cptr->appstate.p == p) {
00251 cptr->appstate.p = PROCESS_NONE;
00252 cptr->tcpstateflags = UIP_CLOSED;
00253 }
00254
00255 }
00256
00257 }
00258 #if UIP_UDP
00259 {
00260 register struct uip_udp_conn *cptr;
00261 for(cptr = &uip_udp_conns[0];
00262 cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) {
00263 if(cptr->appstate.p == p) {
00264 cptr->lport = 0;
00265 }
00266 }
00267
00268 }
00269 #endif
00270 break;
00271
00272 case PROCESS_EVENT_TIMER:
00273
00274 {
00275 static unsigned char i;
00276
00277
00278
00279 if(etimer_expired(&periodic)) {
00280 for(i = 0; i < UIP_CONNS; ++i) {
00281 if(uip_conn_active(i)) {
00282
00283
00284 etimer_restart(&periodic);
00285 uip_periodic(i);
00286 if(uip_len > 0) {
00287 tcpip_output();
00288 }
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 uip_fw_periodic();
00299 }
00300 }
00301 break;
00302
00303 case TCP_POLL:
00304 if(data != NULL) {
00305 uip_poll_conn(data);
00306 if(uip_len > 0) {
00307 tcpip_output();
00308 }
00309
00310
00311 if(etimer_expired(&periodic)) {
00312 etimer_restart(&periodic);
00313 }
00314
00315 }
00316 break;
00317 case UDP_POLL:
00318 if(data != NULL) {
00319 uip_udp_periodic_conn(data);
00320 if(uip_len > 0) {
00321 tcpip_output();
00322 }
00323 }
00324 break;
00325
00326 case PACKET_INPUT:
00327 packet_input();
00328 break;
00329 };
00330 }
00331
00332 void
00333 tcpip_input(void)
00334 {
00335 process_post_synch(&tcpip_process, PACKET_INPUT, NULL);
00336 uip_len = 0;
00337 }
00338
00339 void
00340 tcpip_poll_udp(struct uip_udp_conn *conn)
00341 {
00342 process_post(&tcpip_process, UDP_POLL, conn);
00343 }
00344
00345 void
00346 tcpip_poll_tcp(struct uip_conn *conn)
00347 {
00348 process_post(&tcpip_process, TCP_POLL, conn);
00349 }
00350
00351 void
00352 tcpip_uipcall(void)
00353 {
00354 register uip_udp_appstate_t *ts;
00355 static unsigned char i;
00356 register struct listenport *l;
00357
00358 if(uip_conn != NULL) {
00359 ts = &uip_conn->appstate;
00360 } else {
00361 ts = &uip_udp_conn->appstate;
00362 }
00363
00364
00365
00366 if(uip_connected()) {
00367 l = &s.listenports[0];
00368 for(i = 0; i < UIP_LISTENPORTS; ++i) {
00369 if(l->port == uip_conn->lport &&
00370 l->p != PROCESS_NONE) {
00371 ts->p = l->p;
00372 ts->state = NULL;
00373 break;
00374 }
00375 ++l;
00376 }
00377
00378
00379 if(etimer_expired(&periodic)) {
00380 etimer_restart(&periodic);
00381 }
00382 }
00383
00384 if(ts->p != NULL) {
00385 process_post_synch(ts->p, tcpip_event, ts->state);
00386 }
00387 }
00388
00389 PROCESS_THREAD(tcpip_process, ev, data)
00390 {
00391 int i;
00392
00393 PROCESS_BEGIN();
00394
00395 for(i = 0; i < UIP_LISTENPORTS; ++i) {
00396 s.listenports[i].port = 0;
00397 }
00398 s.p = PROCESS_CURRENT();
00399 tcpip_event = process_alloc_event();
00400 etimer_set(&periodic, CLOCK_SECOND/2);
00401
00402 uip_init();
00403
00404 while(1) {
00405 PROCESS_YIELD();
00406
00407 eventhandler(ev, data);
00408 }
00409
00410 PROCESS_END();
00411 }