1 #include <time.h>
2 #include <errno.h>
3 #include <unistd.h>
4 #include <ogcsys.h>
5 #include <lwp.h>
6 #include <video.h>
7 #include <message.h>
8 #include <mutex.h>
9 #include <cond.h>
10 #include <semaphore.h>
11 #include <processor.h>
12 #include <lwp_threads.h>
13 #include <lwp_watchdog.h>
14 #include <lwip/debug.h>
15 #include <lwip/opt.h>
16 #include <lwip/mem.h>
17 #include <lwip/memp.h>
18 #include <lwip/sys.h>
19 #include <lwip/stats.h>
20 #include <lwip/ip.h>
21 #include <lwip/raw.h>
22 #include <lwip/udp.h>
23 #include <lwip/tcp.h>
24 #include <lwip/dhcp.h>
25 #include <lwip/api.h>
26 #include <lwip/api_msg.h>
27 #include <lwip/tcpip.h>
28 #include <netif/etharp.h>
29 #include <netif/loopif.h>
30 #include <netif/gcif/gcif.h>
31
32 #include <sys/iosupport.h>
33
34 #include "network.h"
35
36 //#define _NET_DEBUG
37 #define ARP_TIMER_ID 0x00070041
38 #define TCP_TIMER_ID 0x00070042
39 #define DHCPCOARSE_TIMER_ID 0x00070043
40 #define DHCPFINE_TIMER_ID 0x00070044
41
42 #define STACKSIZE 32768
43 #define MQBOX_SIZE 256
44 #define NUM_SOCKETS MEMP_NUM_NETCONN
45
46 struct netsocket {
47 struct netconn *conn;
48 struct netbuf *lastdata;
49 u16 lastoffset,rcvevt,sendevt,flags;
50 s32 err;
51 };
52
53 struct netselect_cb {
54 struct netselect_cb *next;
55 fd_set *readset;
56 fd_set *writeset;
57 fd_set *exceptset;
58 u32 signaled;
59 mutex_t cond_lck;
60 cond_t cond;
61 };
62
63 typedef void (*apimsg_decode)(struct apimsg_msg *);
64
65 static u32 g_netinitiated = 0;
66 static u32 tcpiplayer_inited = 0;
67 static u64 net_tcp_ticks = 0;
68 static u64 net_dhcpcoarse_ticks = 0;
69 static u64 net_dhcpfine_ticks = 0;
70 static u64 net_arp_ticks = 0;
71 static wd_cntrl arp_time_cntrl;
72 static wd_cntrl tcp_timer_cntrl;
73 static wd_cntrl dhcp_coarsetimer_cntrl;
74 static wd_cntrl dhcp_finetimer_cntrl;
75
76 static struct netif g_hNetIF;
77 static struct netif g_hLoopIF;
78 static struct netsocket sockets[NUM_SOCKETS];
79 static struct netselect_cb *selectcb_list = NULL;
80
81 static sys_sem netsocket_sem;
82 static sys_sem sockselect_sem;
83 static sys_mbox netthread_mbox;
84
85 static sys_thread hnet_thread;
86 static u8 netthread_stack[STACKSIZE];
87
88 static u32 tcp_timer_active = 0;
89
90 static struct netbuf* netbuf_new();
91 static void netbuf_delete(struct netbuf *);
92 static void netbuf_copypartial(struct netbuf *,void *,u32,u32);
93 static void netbuf_ref(struct netbuf *,const void *,u32);
94
95 static struct netconn* netconn_new_with_callback(enum netconn_type,void (*)(struct netconn *,enum netconn_evt,u32));
96 static struct netconn* netconn_new_with_proto_and_callback(enum netconn_type,u16,void (*)(struct netconn *,enum netconn_evt,u32));
97 static err_t netconn_delete(struct netconn *);
98 static struct netconn* netconn_accept(struct netconn* );
99 static err_t netconn_peer(struct netconn *,struct ip_addr *,u16 *);
100 static err_t netconn_bind(struct netconn *,struct ip_addr *,u16);
101 static err_t netconn_listen(struct netconn *);
102 static struct netbuf* netconn_recv(struct netconn *);
103 static err_t netconn_send(struct netconn *,struct netbuf *);
104 static err_t netconn_write(struct netconn *,const void *,u32,u8);
105 static err_t netconn_connect(struct netconn *,struct ip_addr *,u16);
106 static err_t netconn_disconnect(struct netconn *);
107
108 static void do_newconn(struct apimsg_msg *);
109 static void do_delconn(struct apimsg_msg *);
110 static void do_bind(struct apimsg_msg *);
111 static void do_listen(struct apimsg_msg *);
112 static void do_connect(struct apimsg_msg *);
113 static void do_disconnect(struct apimsg_msg *);
114 static void do_accept(struct apimsg_msg *);
115 static void do_send(struct apimsg_msg *);
116 static void do_recv(struct apimsg_msg *);
117 static void do_write(struct apimsg_msg *);
118 static void do_close(struct apimsg_msg *);
119
120 static apimsg_decode decode[APIMSG_MAX] = {
121 do_newconn,
122 do_delconn,
123 do_bind,
124 do_connect,
125 do_disconnect,
126 do_listen,
127 do_accept,
128 do_send,
129 do_recv,
130 do_write,
131 do_close
132 };
133
134 static void apimsg_post(struct api_msg *);
135
136 static err_t net_input(struct pbuf *,struct netif *);
137 static void net_apimsg(struct api_msg *);
138 static err_t net_callback(void (*)(void *),void *);
139 static void* net_thread(void *);
140
tmr_callback(void * arg)141 static void tmr_callback(void *arg)
142 {
143 void (*functor)() = (void(*)())arg;
144 if(functor) functor();
145 }
146
147 /* low level stuff */
__dhcpcoarse_timer(void * arg)148 static void __dhcpcoarse_timer(void *arg)
149 {
150 __lwp_thread_dispatchdisable();
151 net_callback(tmr_callback,(void*)dhcp_coarse_tmr);
152 __lwp_wd_insert_ticks(&dhcp_coarsetimer_cntrl,net_dhcpcoarse_ticks);
153 __lwp_thread_dispatchunnest();
154 }
155
__dhcpfine_timer(void * arg)156 static void __dhcpfine_timer(void *arg)
157 {
158 __lwp_thread_dispatchdisable();
159 net_callback(tmr_callback,(void*)dhcp_fine_tmr);
160 __lwp_wd_insert_ticks(&dhcp_finetimer_cntrl,net_dhcpfine_ticks);
161 __lwp_thread_dispatchunnest();
162 }
163
__tcp_timer(void * arg)164 static void __tcp_timer(void *arg)
165 {
166 #ifdef _NET_DEBUG
167 printf("__tcp_timer(%d,%p,%p)\n",tcp_timer_active,tcp_active_pcbs,tcp_tw_pcbs);
168 #endif
169 __lwp_thread_dispatchdisable();
170 net_callback(tmr_callback,(void*)tcp_tmr);
171 if (tcp_active_pcbs || tcp_tw_pcbs) {
172 __lwp_wd_insert_ticks(&tcp_timer_cntrl,net_tcp_ticks);
173 } else
174 tcp_timer_active = 0;
175 __lwp_thread_dispatchunnest();
176 }
177
__arp_timer(void * arg)178 static void __arp_timer(void *arg)
179 {
180 __lwp_thread_dispatchdisable();
181 net_callback(tmr_callback,(void*)etharp_tmr);
182 __lwp_wd_insert_ticks(&arp_time_cntrl,net_arp_ticks);
183 __lwp_thread_dispatchunnest();
184 }
185
tcp_timer_needed(void)186 void tcp_timer_needed(void)
187 {
188 #ifdef _NET_DEBUG
189 printf("tcp_timer_needed()\n");
190 #endif
191 if(!tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
192 tcp_timer_active = 1;
193 __lwp_wd_insert_ticks(&tcp_timer_cntrl,net_tcp_ticks);
194 }
195 }
196
197 /* netbuf part */
netbuf_len(struct netbuf * buf)198 static __inline__ u16 netbuf_len(struct netbuf *buf)
199 {
200 return ((buf && buf->p)?buf->p->tot_len:0);
201 }
202
netbuf_fromaddr(struct netbuf * buf)203 static __inline__ struct ip_addr* netbuf_fromaddr(struct netbuf *buf)
204 {
205 return (buf?buf->fromaddr:NULL);
206 }
207
netbuf_fromport(struct netbuf * buf)208 static __inline__ u16 netbuf_fromport(struct netbuf *buf)
209 {
210 return (buf?buf->fromport:0);
211 }
212
netbuf_copypartial(struct netbuf * buf,void * dataptr,u32 len,u32 offset)213 static void netbuf_copypartial(struct netbuf *buf,void *dataptr,u32 len,u32 offset)
214 {
215 struct pbuf *p;
216 u16 i,left;
217
218 left = 0;
219 if(buf==NULL || dataptr==NULL) return;
220
221 for(p=buf->p;left<len && p!=NULL;p=p->next) {
222 if(offset!=0 && offset>=p->len)
223 offset -= p->len;
224 else {
225 for(i=offset;i<p->len;i++) {
226 ((u8*)dataptr)[left] = ((u8*)p->payload)[i];
227 if(++left>=len) return;
228 }
229 offset = 0;
230 }
231 }
232 }
233
netbuf_new()234 static struct netbuf* netbuf_new()
235 {
236 struct netbuf *buf = NULL;
237
238 buf = memp_malloc(MEMP_NETBUF);
239 if(buf) {
240 buf->p = NULL;
241 buf->ptr = NULL;
242 }
243 return buf;
244 }
245
netbuf_delete(struct netbuf * buf)246 static void netbuf_delete(struct netbuf *buf)
247 {
248 if(buf!=NULL) {
249 if(buf->p!=NULL) pbuf_free(buf->p);
250 memp_free(MEMP_NETBUF,buf);
251 }
252 }
253
netbuf_ref(struct netbuf * buf,const void * dataptr,u32 size)254 static void netbuf_ref(struct netbuf *buf, const void *dataptr,u32 size)
255 {
256 if(buf->p!=NULL) pbuf_free(buf->p);
257 buf->p = pbuf_alloc(PBUF_TRANSPORT,0,PBUF_REF);
258 buf->p->payload = (void*)dataptr;
259 buf->p->len = buf->p->tot_len = size;
260 buf->ptr = buf->p;
261 }
262
263 /* netconn part */
netconn_type(struct netconn * conn)264 static inline enum netconn_type netconn_type(struct netconn *conn)
265 {
266 return conn->type;
267 }
268
netconn_new_with_callback(enum netconn_type t,void (* cb)(struct netconn *,enum netconn_evt,u32))269 static struct netconn* netconn_new_with_callback(enum netconn_type t,void (*cb)(struct netconn*,enum netconn_evt,u32))
270 {
271 return netconn_new_with_proto_and_callback(t,0,cb);
272 }
273
netconn_new_with_proto_and_callback(enum netconn_type t,u16 proto,void (* cb)(struct netconn *,enum netconn_evt,u32))274 static struct netconn* netconn_new_with_proto_and_callback(enum netconn_type t,u16 proto,void (*cb)(struct netconn *,enum netconn_evt,u32))
275 {
276 u32 dummy = 0;
277 struct netconn *conn;
278 struct api_msg *msg;
279
280 conn = memp_malloc(MEMP_NETCONN);
281 if(!conn) return NULL;
282
283 conn->err = ERR_OK;
284 conn->type = t;
285 conn->pcb.tcp = NULL;
286
287 if(MQ_Init(&conn->mbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) {
288 memp_free(MEMP_NETCONN,conn);
289 return NULL;
290 }
291 if(LWP_SemInit(&conn->sem,0,1)==-1) {
292 MQ_Close(conn->mbox);
293 memp_free(MEMP_NETCONN,conn);
294 return NULL;
295 }
296
297 conn->acceptmbox = SYS_MBOX_NULL;
298 conn->recvmbox = SYS_MBOX_NULL;
299 conn->state = NETCONN_NONE;
300 conn->socket = 0;
301 conn->callback = cb;
302 conn->recvavail = 0;
303
304 msg = memp_malloc(MEMP_API_MSG);
305 if(!msg) {
306 MQ_Close(conn->mbox);
307 memp_free(MEMP_NETCONN,conn);
308 return NULL;
309 }
310
311 msg->type = APIMSG_NEWCONN;
312 msg->msg.msg.bc.port = proto;
313 msg->msg.conn = conn;
314 apimsg_post(msg);
315 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
316 memp_free(MEMP_API_MSG,msg);
317
318 if(conn->err!=ERR_OK) {
319 MQ_Close(conn->mbox);
320 memp_free(MEMP_NETCONN,conn);
321 return NULL;
322 }
323 return conn;
324 }
325
netconn_delete(struct netconn * conn)326 static err_t netconn_delete(struct netconn *conn)
327 {
328 u32 dummy = 0;
329 struct api_msg *msg;
330 sys_mbox mbox;
331 void *mem;
332
333 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_delete(%p)\n", conn));
334
335 if(!conn) return ERR_OK;
336
337 msg = memp_malloc(MEMP_API_MSG);
338 if(!msg) return ERR_MEM;
339
340 msg->type = APIMSG_DELCONN;
341 msg->msg.conn = conn;
342 apimsg_post(msg);
343 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
344 memp_free(MEMP_API_MSG,msg);
345
346 mbox = conn->recvmbox;
347 conn->recvmbox = SYS_MBOX_NULL;
348 if(mbox!=SYS_MBOX_NULL) {
349 while(MQ_Receive(mbox,(mqmsg_t)&mem,MQ_MSG_NOBLOCK)==TRUE) {
350 if(mem!=NULL) {
351 if(conn->type==NETCONN_TCP)
352 pbuf_free((struct pbuf*)mem);
353 else
354 netbuf_delete((struct netbuf*)mem);
355 }
356 }
357 MQ_Close(mbox);
358 }
359
360 mbox = conn->acceptmbox;
361 conn->acceptmbox = SYS_MBOX_NULL;
362 if(mbox!=SYS_MBOX_NULL) {
363 while(MQ_Receive(mbox,(mqmsg_t)&mem,MQ_MSG_NOBLOCK)==TRUE) {
364 if(mem!=NULL) netconn_delete((struct netconn*)mem);
365 }
366 MQ_Close(mbox);
367 }
368
369 MQ_Close(conn->mbox);
370 conn->mbox = SYS_MBOX_NULL;
371
372 LWP_SemDestroy(conn->sem);
373 conn->sem = SYS_SEM_NULL;
374
375 memp_free(MEMP_NETCONN,conn);
376 return ERR_OK;
377 }
378
netconn_accept(struct netconn * conn)379 static struct netconn* netconn_accept(struct netconn* conn)
380 {
381 struct netconn *newconn;
382
383 if(conn==NULL) return NULL;
384
385 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_accept(%p)\n", conn));
386 MQ_Receive(conn->acceptmbox,(mqmsg_t)&newconn,MQ_MSG_BLOCK);
387 if(conn->callback)
388 (*conn->callback)(conn,NETCONN_EVTRCVMINUS,0);
389
390 return newconn;
391 }
392
netconn_peer(struct netconn * conn,struct ip_addr * addr,u16 * port)393 static err_t netconn_peer(struct netconn *conn,struct ip_addr *addr,u16 *port)
394 {
395 switch(conn->type) {
396 case NETCONN_RAW:
397 return ERR_CONN;
398 case NETCONN_UDPLITE:
399 case NETCONN_UDPNOCHKSUM:
400 case NETCONN_UDP:
401 if(conn->pcb.udp==NULL || ((conn->pcb.udp->flags&UDP_FLAGS_CONNECTED)==0))
402 return ERR_CONN;
403 *addr = conn->pcb.udp->remote_ip;
404 *port = conn->pcb.udp->remote_port;
405 break;
406 case NETCONN_TCP:
407 if(conn->pcb.tcp==NULL)
408 return ERR_CONN;
409 *addr = conn->pcb.tcp->remote_ip;
410 *port = conn->pcb.tcp->remote_port;
411 break;
412 }
413 return (conn->err = ERR_OK);
414 }
415
netconn_bind(struct netconn * conn,struct ip_addr * addr,u16 port)416 static err_t netconn_bind(struct netconn *conn,struct ip_addr *addr,u16 port)
417 {
418 u32 dummy = 0;
419 struct api_msg *msg;
420
421 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_bind(%p)\n", conn));
422
423 if(conn==NULL) return ERR_VAL;
424 if(conn->type!=NETCONN_TCP && conn->recvmbox==SYS_MBOX_NULL) {
425 if(MQ_Init(&conn->recvmbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) return ERR_MEM;
426 }
427
428 if((msg=memp_malloc(MEMP_API_MSG))==NULL)
429 return (conn->err = ERR_MEM);
430
431 msg->type = APIMSG_BIND;
432 msg->msg.conn = conn;
433 msg->msg.msg.bc.ipaddr = addr;
434 msg->msg.msg.bc.port = port;
435 apimsg_post(msg);
436 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
437 memp_free(MEMP_API_MSG,msg);
438 return conn->err;
439 }
440
netconn_listen(struct netconn * conn)441 static err_t netconn_listen(struct netconn *conn)
442 {
443 u32 dummy = 0;
444 struct api_msg *msg;
445
446 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_listen(%p)\n", conn));
447
448 if(conn==NULL) return -1;
449 if(conn->acceptmbox==SYS_MBOX_NULL) {
450 if(MQ_Init(&conn->acceptmbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) return ERR_MEM;
451 }
452
453 if((msg=memp_malloc(MEMP_API_MSG))==NULL) return (conn->err = ERR_MEM);
454 msg->type = APIMSG_LISTEN;
455 msg->msg.conn = conn;
456 apimsg_post(msg);
457 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
458 memp_free(MEMP_API_MSG,msg);
459 return conn->err;
460 }
461
netconn_recv(struct netconn * conn)462 static struct netbuf* netconn_recv(struct netconn *conn)
463 {
464 u32 dummy = 0;
465 struct api_msg *msg;
466 struct netbuf *buf;
467 struct pbuf *p;
468 u16 len;
469
470 if(conn==NULL) return NULL;
471 if(conn->recvmbox==SYS_MBOX_NULL) {
472 conn->err = ERR_CONN;
473 return NULL;
474 }
475 if(conn->err!=ERR_OK) return NULL;
476
477 if(conn->type==NETCONN_TCP) {
478 if(conn->pcb.tcp->state==LISTEN) {
479 conn->err = ERR_CONN;
480 return NULL;
481 }
482
483 buf = memp_malloc(MEMP_NETBUF);
484 if(buf==NULL) {
485 conn->err = ERR_MEM;
486 return NULL;
487 }
488
489 MQ_Receive(conn->recvmbox,(mqmsg_t)&p,MQ_MSG_BLOCK);
490 if(p!=NULL) {
491 len = p->tot_len;
492 conn->recvavail -= len;
493 } else
494 len = 0;
495
496 if(conn->callback)
497 (*conn->callback)(conn,NETCONN_EVTRCVMINUS,len);
498
499 if(p==NULL) {
500 memp_free(MEMP_NETBUF,buf);
501 MQ_Close(conn->recvmbox);
502 conn->recvmbox = SYS_MBOX_NULL;
503 return NULL;
504 }
505
506 buf->p = p;
507 buf->ptr = p;
508 buf->fromport = 0;
509 buf->fromaddr = NULL;
510
511 if((msg=memp_malloc(MEMP_API_MSG))==NULL) {
512 conn->err = ERR_MEM;
513 return buf;
514 }
515
516 msg->type = APIMSG_RECV;
517 msg->msg.conn = conn;
518 if(buf!=NULL)
519 msg->msg.msg.len = len;
520 else
521 msg->msg.msg.len = 1;
522
523 apimsg_post(msg);
524 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
525 memp_free(MEMP_API_MSG,msg);
526 } else {
527 MQ_Receive(conn->recvmbox,(mqmsg_t)&buf,MQ_MSG_BLOCK);
528 conn->recvavail -= buf->p->tot_len;
529 if(conn->callback)
530 (*conn->callback)(conn,NETCONN_EVTRCVMINUS,buf->p->tot_len);
531 }
532
533 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
534 return buf;
535 }
536
netconn_send(struct netconn * conn,struct netbuf * buf)537 static err_t netconn_send(struct netconn *conn,struct netbuf *buf)
538 {
539 u32 dummy = 0;
540 struct api_msg *msg;
541
542 if(conn==NULL) return ERR_VAL;
543 if(conn->err!=ERR_OK) return conn->err;
544 if((msg=memp_malloc(MEMP_API_MSG))==NULL) return (conn->err = ERR_MEM);
545
546 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
547 msg->type = APIMSG_SEND;
548 msg->msg.conn = conn;
549 msg->msg.msg.p = buf->p;
550 apimsg_post(msg);
551 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
552 memp_free(MEMP_API_MSG,msg);
553 return conn->err;
554 }
555
netconn_write(struct netconn * conn,const void * dataptr,u32 size,u8 copy)556 static err_t netconn_write(struct netconn *conn,const void *dataptr,u32 size,u8 copy)
557 {
558 u32 dummy = 0;
559 struct api_msg *msg;
560 u16 len,snd_buf;
561
562 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write(%d)\n",conn->err));
563
564 if(conn==NULL) return ERR_VAL;
565 if(conn->err!=ERR_OK) return conn->err;
566
567 if((msg=memp_malloc(MEMP_API_MSG))==NULL) return (conn->err = ERR_MEM);
568
569 msg->type = APIMSG_WRITE;
570 msg->msg.conn = conn;
571 conn->state = NETCONN_WRITE;
572 while(conn->err==ERR_OK && size>0) {
573 msg->msg.msg.w.dataptr = (void*)dataptr;
574 msg->msg.msg.w.copy = copy;
575 if(conn->type==NETCONN_TCP) {
576 while((snd_buf=tcp_sndbuf(conn->pcb.tcp))==0) {
577 LWIP_DEBUGF(API_LIB_DEBUG,("netconn_write: tcp_sndbuf = 0,err = %d\n", conn->err));
578 LWP_SemWait(conn->sem);
579 if(conn->err!=ERR_OK) goto ret;
580 }
581 if(size>snd_buf)
582 len = snd_buf;
583 else
584 len = size;
585 } else
586 len = size;
587
588 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
589 msg->msg.msg.w.len = len;
590 apimsg_post(msg);
591 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
592 if(conn->err==ERR_OK) {
593 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: %d bytes written\n",len));
594 dataptr = (void*)((char*)dataptr+len);
595 size -= len;
596 } else if(conn->err==ERR_MEM) {
597 LWIP_DEBUGF(API_LIB_DEBUG,("netconn_write: mem err\n"));
598 conn->err = ERR_OK;
599 LWP_SemWait(conn->sem);
600 } else {
601 LWIP_DEBUGF(API_LIB_DEBUG,("netconn_write: err = %d\n", conn->err));
602 break;
603 }
604 }
605 ret:
606 memp_free(MEMP_API_MSG,msg);
607 conn->state = NETCONN_NONE;
608
609 return conn->err;
610 }
611
netconn_connect(struct netconn * conn,struct ip_addr * addr,u16 port)612 static err_t netconn_connect(struct netconn *conn,struct ip_addr *addr,u16 port)
613 {
614 u32 dummy = 0;
615 struct api_msg *msg;
616
617 if(conn==NULL) return -1;
618 if(conn->recvmbox==SYS_MBOX_NULL) {
619 if(MQ_Init(&conn->recvmbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) return ERR_MEM;
620 }
621
622 if((msg=memp_malloc(MEMP_API_MSG))==NULL) return ERR_MEM;
623
624 msg->type = APIMSG_CONNECT;
625 msg->msg.conn = conn;
626 msg->msg.msg.bc.ipaddr = addr;
627 msg->msg.msg.bc.port = port;
628 apimsg_post(msg);
629 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
630 memp_free(MEMP_API_MSG,msg);
631 return conn->err;
632 }
633
netconn_disconnect(struct netconn * conn)634 static err_t netconn_disconnect(struct netconn *conn)
635 {
636 u32 dummy = 0;
637 struct api_msg *msg;
638
639 if(conn==NULL) return ERR_VAL;
640 if((msg=memp_malloc(MEMP_API_MSG))==NULL) return ERR_MEM;
641
642 msg->type = APIMSG_DISCONNECT;
643 msg->msg.conn = conn;
644 apimsg_post(msg);
645 MQ_Receive(conn->mbox,(mqmsg_t)&dummy,MQ_MSG_BLOCK);
646 memp_free(MEMP_API_MSG,msg);
647 return conn->err;
648 }
649
650 /* api msg part */
recv_raw(void * arg,struct raw_pcb * pcb,struct pbuf * p,struct ip_addr * addr)651 static u8_t recv_raw(void *arg,struct raw_pcb *pcb,struct pbuf *p,struct ip_addr *addr)
652 {
653 struct netbuf *buf;
654 struct netconn *conn = (struct netconn*)arg;
655
656 if(!conn) return 0;
657
658 if(conn->recvmbox!=SYS_MBOX_NULL) {
659 if((buf=memp_malloc(MEMP_NETBUF))==NULL) return 0;
660
661 pbuf_ref(p);
662 buf->p = p;
663 buf->ptr = p;
664 buf->fromaddr = addr;
665 buf->fromport = pcb->protocol;
666
667 conn->recvavail += p->tot_len;
668 if(conn->callback)
669 (*conn->callback)(conn,NETCONN_EVTRCVPLUS,p->tot_len);
670 MQ_Send(conn->recvmbox,buf,MQ_MSG_BLOCK);
671 }
672 return 0;
673 }
674
recv_udp(void * arg,struct udp_pcb * pcb,struct pbuf * p,struct ip_addr * addr,u16 port)675 static void recv_udp(void *arg,struct udp_pcb *pcb,struct pbuf *p,struct ip_addr *addr,u16 port)
676 {
677 struct netbuf *buf;
678 struct netconn *conn = (struct netconn*)arg;
679
680 if(!conn) {
681 pbuf_free(p);
682 return;
683 }
684
685 if(conn->recvmbox!=SYS_MBOX_NULL) {
686 buf = memp_malloc(MEMP_NETBUF);
687 if(!buf) {
688 pbuf_free(p);
689 return;
690 }
691 buf->p = p;
692 buf->ptr = p;
693 buf->fromaddr = addr;
694 buf->fromport = port;
695
696 conn->recvavail += p->tot_len;
697 if(conn->callback)
698 (*conn->callback)(conn,NETCONN_EVTRCVPLUS,p->tot_len);
699
700 MQ_Send(conn->recvmbox,buf,MQ_MSG_BLOCK);
701 }
702 }
703
recv_tcp(void * arg,struct tcp_pcb * pcb,struct pbuf * p,err_t err)704 static err_t recv_tcp(void *arg,struct tcp_pcb *pcb,struct pbuf *p,err_t err)
705 {
706 u16 len;
707 struct netconn *conn = (struct netconn*)arg;
708
709 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: recv_tcp(%p,%p,%p,%d)\n",arg,pcb,p,err));
710
711 if(conn==NULL) {
712 pbuf_free(p);
713 return ERR_VAL;
714 }
715
716 if(conn->recvmbox!=SYS_MBOX_NULL) {
717 conn->err = err;
718 if(p!=NULL) {
719 len = p->tot_len;
720 conn->recvavail += len;
721 } else len = 0;
722
723 if(conn->callback)
724 (*conn->callback)(conn,NETCONN_EVTRCVPLUS,len);
725
726 MQ_Send(conn->recvmbox,p,MQ_MSG_BLOCK);
727 }
728 return ERR_OK;
729 }
730
err_tcp(void * arg,err_t err)731 static void err_tcp(void *arg,err_t err)
732 {
733 u32 dummy = 0;
734 struct netconn *conn = (struct netconn*)arg;
735
736 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: err_tcp: %d\n",err));
737 if(conn) {
738 conn->err = err;
739 conn->pcb.tcp = NULL;
740 if(conn->recvmbox!=SYS_MBOX_NULL) {
741 if(conn->callback) (*conn->callback)(conn,NETCONN_EVTRCVPLUS,0);
742 MQ_Send(conn->recvmbox,&dummy,MQ_MSG_BLOCK);
743 }
744 if(conn->mbox!=SYS_MBOX_NULL) {
745 MQ_Send(conn->mbox,&dummy,MQ_MSG_BLOCK);
746 }
747 if(conn->acceptmbox!=SYS_MBOX_NULL) {
748 if(conn->callback) (*conn->callback)(conn,NETCONN_EVTRCVPLUS,0);
749 MQ_Send(conn->acceptmbox,&dummy,MQ_MSG_BLOCK);
750 }
751 if(conn->sem!=SYS_SEM_NULL) {
752 LWP_SemPost(conn->sem);
753 }
754 }
755 }
756
poll_tcp(void * arg,struct tcp_pcb * pcb)757 static err_t poll_tcp(void *arg,struct tcp_pcb *pcb)
758 {
759 struct netconn *conn = (struct netconn*)arg;
760
761 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: poll_tcp\n"));
762 if(conn && conn->sem!=SYS_SEM_NULL && (conn->state==NETCONN_WRITE || conn->state==NETCONN_CLOSE))
763 LWP_SemPost(conn->sem);
764
765 return ERR_OK;
766 }
767
sent_tcp(void * arg,struct tcp_pcb * pcb,u16 len)768 static err_t sent_tcp(void *arg,struct tcp_pcb *pcb,u16 len)
769 {
770 struct netconn *conn = (struct netconn*)arg;
771
772 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: sent_tcp: sent %d bytes\n",len));
773 if(conn && conn->sem!=SYS_SEM_NULL)
774 LWP_SemPost(conn->sem);
775
776 if(conn && conn->callback) {
777 if(tcp_sndbuf(conn->pcb.tcp)>TCP_SNDLOWAT)
778 (*conn->callback)(conn,NETCONN_EVTSENDPLUS,len);
779 }
780 return ERR_OK;
781 }
782
setuptcp(struct netconn * conn)783 static void setuptcp(struct netconn *conn)
784 {
785 struct tcp_pcb *pcb = conn->pcb.tcp;
786
787 tcp_arg(pcb,conn);
788 tcp_recv(pcb,recv_tcp);
789 tcp_sent(pcb,sent_tcp);
790 tcp_poll(pcb,poll_tcp,4);
791 tcp_err(pcb,err_tcp);
792 }
793
accept_func(void * arg,struct tcp_pcb * newpcb,err_t err)794 static err_t accept_func(void *arg,struct tcp_pcb *newpcb,err_t err)
795 {
796 sys_mbox mbox;
797 struct netconn *newconn,*conn = (struct netconn*)arg;
798
799 LWIP_DEBUGF(API_LIB_DEBUG, ("accept_func: %p %p %d\n",arg,newpcb,err));
800
801 mbox = conn->acceptmbox;
802 newconn = memp_malloc(MEMP_NETCONN);
803 if(newconn==NULL) return ERR_MEM;
804
805 if(MQ_Init(&newconn->recvmbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) {
806 memp_free(MEMP_NETCONN,newconn);
807 return ERR_MEM;
808 }
809
810 if(MQ_Init(&newconn->mbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) {
811 MQ_Close(newconn->recvmbox);
812 memp_free(MEMP_NETCONN,newconn);
813 return ERR_MEM;
814 }
815
816 if(LWP_SemInit(&newconn->sem,0,1)==-1) {
817 MQ_Close(newconn->recvmbox);
818 MQ_Close(newconn->mbox);
819 memp_free(MEMP_NETCONN,newconn);
820 return ERR_MEM;
821 }
822
823 newconn->type = NETCONN_TCP;
824 newconn->pcb.tcp = newpcb;
825 setuptcp(newconn);
826
827 newconn->acceptmbox = SYS_MBOX_NULL;
828 newconn->err = err;
829
830 if(conn->callback) {
831 (*conn->callback)(conn,NETCONN_EVTRCVPLUS,0);
832 }
833 newconn->callback = conn->callback;
834 newconn->socket = -1;
835 newconn->recvavail = 0;
836
837 MQ_Send(mbox,newconn,MQ_MSG_BLOCK);
838 return ERR_OK;
839 }
840
do_newconn(struct apimsg_msg * msg)841 static void do_newconn(struct apimsg_msg *msg)
842 {
843 u32 dummy = 0;
844
845 if(msg->conn->pcb.tcp) {
846 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
847 return;
848 }
849
850 msg->conn->err = ERR_OK;
851 switch(msg->conn->type) {
852 case NETCONN_RAW:
853 msg->conn->pcb.raw = raw_new(msg->msg.bc.port);
854 raw_recv(msg->conn->pcb.raw,recv_raw,msg->conn);
855 break;
856 case NETCONN_UDPLITE:
857 msg->conn->pcb.udp = udp_new();
858 if(!msg->conn->pcb.udp) {
859 msg->conn->err = ERR_MEM;
860 break;
861 }
862 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_UDPLITE);
863 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
864 break;
865 case NETCONN_UDPNOCHKSUM:
866 msg->conn->pcb.udp = udp_new();
867 if(!msg->conn->pcb.udp) {
868 msg->conn->err = ERR_MEM;
869 break;
870 }
871 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_NOCHKSUM);
872 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
873 break;
874 case NETCONN_UDP:
875 msg->conn->pcb.udp = udp_new();
876 if(!msg->conn->pcb.udp) {
877 msg->conn->err = ERR_MEM;
878 break;
879 }
880 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
881 break;
882 case NETCONN_TCP:
883 msg->conn->pcb.tcp = tcp_new();
884 if(!msg->conn->pcb.tcp) {
885 msg->conn->err = ERR_MEM;
886 break;
887 }
888 setuptcp(msg->conn);
889 break;
890 default:
891 break;
892 }
893 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
894 }
895
do_delconn(struct apimsg_msg * msg)896 static void do_delconn(struct apimsg_msg *msg)
897 {
898 u32 dummy = 0;
899
900 if(msg->conn->pcb.tcp) {
901 switch(msg->conn->type) {
902 case NETCONN_RAW:
903 raw_remove(msg->conn->pcb.raw);
904 break;
905 case NETCONN_UDPLITE:
906 case NETCONN_UDPNOCHKSUM:
907 case NETCONN_UDP:
908 msg->conn->pcb.udp->recv_arg = NULL;
909 udp_remove(msg->conn->pcb.udp);
910 break;
911 case NETCONN_TCP:
912 if(msg->conn->pcb.tcp->state==LISTEN) {
913 tcp_arg(msg->conn->pcb.tcp,NULL);
914 tcp_accept(msg->conn->pcb.tcp,NULL);
915 tcp_close(msg->conn->pcb.tcp);
916 } else {
917 tcp_arg(msg->conn->pcb.tcp,NULL);
918 tcp_sent(msg->conn->pcb.tcp,NULL);
919 tcp_recv(msg->conn->pcb.tcp,NULL);
920 tcp_poll(msg->conn->pcb.tcp,NULL,0);
921 tcp_err(msg->conn->pcb.tcp,NULL);
922 if(tcp_close(msg->conn->pcb.tcp)!=ERR_OK)
923 tcp_abort(msg->conn->pcb.tcp);
924 }
925 break;
926 default:
927 break;
928 }
929 }
930 if(msg->conn->callback) {
931 (*msg->conn->callback)(msg->conn,NETCONN_EVTRCVPLUS,0);
932 (*msg->conn->callback)(msg->conn,NETCONN_EVTSENDPLUS,0);
933 }
934 if(msg->conn->mbox!=SYS_MBOX_NULL)
935 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
936 }
937
do_bind(struct apimsg_msg * msg)938 static void do_bind(struct apimsg_msg *msg)
939 {
940 u32 dummy = 0;
941
942 if(msg->conn->pcb.tcp==NULL) {
943 switch(msg->conn->type) {
944 case NETCONN_RAW:
945 msg->conn->pcb.raw = raw_new(msg->msg.bc.port);
946 raw_recv(msg->conn->pcb.raw,recv_raw,msg->conn);
947 break;
948 case NETCONN_UDPLITE:
949 msg->conn->pcb.udp = udp_new();
950 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_UDPLITE);
951 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
952 break;
953 case NETCONN_UDPNOCHKSUM:
954 msg->conn->pcb.udp = udp_new();
955 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_NOCHKSUM);
956 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
957 break;
958 case NETCONN_UDP:
959 msg->conn->pcb.udp = udp_new();
960 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
961 break;
962 case NETCONN_TCP:
963 msg->conn->pcb.tcp = tcp_new();
964 setuptcp(msg->conn);
965 break;
966 default:
967 break;
968 }
969 }
970 switch(msg->conn->type) {
971 case NETCONN_RAW:
972 msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);
973 break;
974 case NETCONN_UDPLITE:
975 case NETCONN_UDPNOCHKSUM:
976 case NETCONN_UDP:
977 msg->conn->err = udp_bind(msg->conn->pcb.udp,msg->msg.bc.ipaddr,msg->msg.bc.port);
978 break;
979 case NETCONN_TCP:
980 msg->conn->err = tcp_bind(msg->conn->pcb.tcp,msg->msg.bc.ipaddr,msg->msg.bc.port);
981 break;
982 default:
983 break;
984 }
985 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
986 }
987
do_connected(void * arg,struct tcp_pcb * pcb,err_t err)988 static err_t do_connected(void *arg,struct tcp_pcb *pcb,err_t err)
989 {
990 u32 dummy = 0;
991 struct netconn *conn = (struct netconn*)arg;
992
993 if(!conn) return ERR_VAL;
994
995 conn->err = err;
996 if(conn->type==NETCONN_TCP && err==ERR_OK) setuptcp(conn);
997
998 MQ_Send(conn->mbox,&dummy,MQ_MSG_BLOCK);
999 return ERR_OK;
1000 }
1001
do_connect(struct apimsg_msg * msg)1002 static void do_connect(struct apimsg_msg *msg)
1003 {
1004 u32 dummy = 0;
1005
1006 if(!msg->conn->pcb.tcp) {
1007 switch(msg->conn->type) {
1008 case NETCONN_RAW:
1009 msg->conn->pcb.raw = raw_new(msg->msg.bc.port);
1010 raw_recv(msg->conn->pcb.raw,recv_raw,msg->conn);
1011 break;
1012 case NETCONN_UDPLITE:
1013 msg->conn->pcb.udp = udp_new();
1014 if(!msg->conn->pcb.udp) {
1015 msg->conn->err = ERR_MEM;
1016 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1017 return;
1018 }
1019 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_UDPLITE);
1020 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
1021 break;
1022 case NETCONN_UDPNOCHKSUM:
1023 msg->conn->pcb.udp = udp_new();
1024 if(!msg->conn->pcb.udp) {
1025 msg->conn->err = ERR_MEM;
1026 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1027 return;
1028 }
1029 udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_NOCHKSUM);
1030 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
1031 break;
1032 case NETCONN_UDP:
1033 msg->conn->pcb.udp = udp_new();
1034 if(!msg->conn->pcb.udp) {
1035 msg->conn->err = ERR_MEM;
1036 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1037 return;
1038 }
1039 udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
1040 break;
1041 case NETCONN_TCP:
1042 msg->conn->pcb.tcp = tcp_new();
1043 if(!msg->conn->pcb.tcp) {
1044 msg->conn->err = ERR_MEM;
1045 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1046 return;
1047 }
1048 break;
1049 default:
1050 break;
1051 }
1052 }
1053 switch(msg->conn->type) {
1054 case NETCONN_RAW:
1055 raw_connect(msg->conn->pcb.raw,msg->msg.bc.ipaddr);
1056 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1057 break;
1058 case NETCONN_UDPLITE:
1059 case NETCONN_UDPNOCHKSUM:
1060 case NETCONN_UDP:
1061 udp_connect(msg->conn->pcb.udp,msg->msg.bc.ipaddr,msg->msg.bc.port);
1062 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1063 break;
1064 case NETCONN_TCP:
1065 setuptcp(msg->conn);
1066 tcp_connect(msg->conn->pcb.tcp,msg->msg.bc.ipaddr,msg->msg.bc.port,do_connected);
1067 break;
1068 default:
1069 break;
1070 }
1071 }
1072
do_disconnect(struct apimsg_msg * msg)1073 static void do_disconnect(struct apimsg_msg *msg)
1074 {
1075 u32 dummy = 0;
1076
1077 switch(msg->conn->type) {
1078 case NETCONN_RAW:
1079 break;
1080 case NETCONN_UDPLITE:
1081 case NETCONN_UDPNOCHKSUM:
1082 case NETCONN_UDP:
1083 udp_disconnect(msg->conn->pcb.udp);
1084 break;
1085 case NETCONN_TCP:
1086 break;
1087 }
1088 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1089 }
1090
do_listen(struct apimsg_msg * msg)1091 static void do_listen(struct apimsg_msg *msg)
1092 {
1093 u32 dummy = 0;
1094
1095 if(msg->conn->pcb.tcp!=NULL) {
1096 switch(msg->conn->type) {
1097 case NETCONN_RAW:
1098 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen RAW: cannot listen for RAW.\n"));
1099 break;
1100 case NETCONN_UDPLITE:
1101 case NETCONN_UDPNOCHKSUM:
1102 case NETCONN_UDP:
1103 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
1104 break;
1105 case NETCONN_TCP:
1106 msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
1107 if(msg->conn->pcb.tcp==NULL)
1108 msg->conn->err = ERR_MEM;
1109 else {
1110 if(msg->conn->acceptmbox==SYS_MBOX_NULL) {
1111 if(MQ_Init(&msg->conn->acceptmbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) {
1112 msg->conn->err = ERR_MEM;
1113 break;
1114 }
1115 }
1116 tcp_arg(msg->conn->pcb.tcp,msg->conn);
1117 tcp_accept(msg->conn->pcb.tcp,accept_func);
1118 }
1119 break;
1120 default:
1121 break;
1122 }
1123 }
1124 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1125 }
1126
do_accept(struct apimsg_msg * msg)1127 static void do_accept(struct apimsg_msg *msg)
1128 {
1129 if(msg->conn->pcb.tcp) {
1130 switch(msg->conn->type) {
1131 case NETCONN_RAW:
1132 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept RAW: cannot accept for RAW.\n"));
1133 break;
1134 case NETCONN_UDPLITE:
1135 case NETCONN_UDPNOCHKSUM:
1136 case NETCONN_UDP:
1137 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
1138 break;
1139 case NETCONN_TCP:
1140 break;
1141 }
1142 }
1143 }
1144
do_send(struct apimsg_msg * msg)1145 static void do_send(struct apimsg_msg *msg)
1146 {
1147 u32 dummy = 0;
1148
1149 if(msg->conn->pcb.tcp) {
1150 switch(msg->conn->type) {
1151 case NETCONN_RAW:
1152 raw_send(msg->conn->pcb.raw,msg->msg.p);
1153 break;
1154 case NETCONN_UDPLITE:
1155 case NETCONN_UDPNOCHKSUM:
1156 case NETCONN_UDP:
1157 udp_send(msg->conn->pcb.udp,msg->msg.p);
1158 break;
1159 case NETCONN_TCP:
1160 break;
1161 }
1162 }
1163 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1164 }
1165
do_recv(struct apimsg_msg * msg)1166 static void do_recv(struct apimsg_msg *msg)
1167 {
1168 u32 dummy = 0;
1169
1170 if(msg->conn->pcb.tcp && msg->conn->type==NETCONN_TCP) {
1171 tcp_recved(msg->conn->pcb.tcp,msg->msg.len);
1172 }
1173 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1174 }
1175
do_write(struct apimsg_msg * msg)1176 static void do_write(struct apimsg_msg *msg)
1177 {
1178 err_t err;
1179 u32 dummy = 0;
1180
1181 if(msg->conn->pcb.tcp) {
1182 switch(msg->conn->type) {
1183 case NETCONN_RAW:
1184 case NETCONN_UDPLITE:
1185 case NETCONN_UDPNOCHKSUM:
1186 case NETCONN_UDP:
1187 msg->conn->err = ERR_VAL;
1188 break;
1189 case NETCONN_TCP:
1190 err = tcp_write(msg->conn->pcb.tcp,msg->msg.w.dataptr,msg->msg.w.len,msg->msg.w.copy);
1191 if(err==ERR_OK && (!msg->conn->pcb.tcp->unacked || (msg->conn->pcb.tcp->flags&TF_NODELAY)
1192 || msg->conn->pcb.tcp->snd_queuelen>1)) {
1193 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: TCP write: tcp_output.\n"));
1194 tcp_output(msg->conn->pcb.tcp);
1195 }
1196 msg->conn->err = err;
1197 if(msg->conn->callback) {
1198 if(err==ERR_OK) {
1199 if(tcp_sndbuf(msg->conn->pcb.tcp)<=TCP_SNDLOWAT)
1200 (*msg->conn->callback)(msg->conn,NETCONN_EVTSENDMINUS,msg->msg.w.len);
1201 }
1202 }
1203 break;
1204 default:
1205 break;
1206 }
1207 }
1208 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1209 }
1210
do_close(struct apimsg_msg * msg)1211 static void do_close(struct apimsg_msg *msg)
1212 {
1213 u32 dummy = 0;
1214 err_t err = ERR_OK;
1215
1216 if(msg->conn->pcb.tcp) {
1217 switch(msg->conn->type) {
1218 case NETCONN_RAW:
1219 case NETCONN_UDPLITE:
1220 case NETCONN_UDPNOCHKSUM:
1221 case NETCONN_UDP:
1222 break;
1223 case NETCONN_TCP:
1224 if(msg->conn->pcb.tcp->state==LISTEN)
1225 err = tcp_close(msg->conn->pcb.tcp);
1226 else if(msg->conn->pcb.tcp->state==CLOSE_WAIT)
1227 err = tcp_output(msg->conn->pcb.tcp);
1228 msg->conn->err = err;
1229 break;
1230 default:
1231 break;
1232 }
1233 }
1234 MQ_Send(msg->conn->mbox,&dummy,MQ_MSG_BLOCK);
1235 }
1236
apimsg_input(struct api_msg * msg)1237 static void apimsg_input(struct api_msg *msg)
1238 {
1239 decode[msg->type](&(msg->msg));
1240 }
1241
apimsg_post(struct api_msg * msg)1242 static void apimsg_post(struct api_msg *msg)
1243 {
1244 net_apimsg(msg);
1245 }
1246
1247 /* tcpip thread part */
net_input(struct pbuf * p,struct netif * inp)1248 static err_t net_input(struct pbuf *p,struct netif *inp)
1249 {
1250 struct net_msg *msg = memp_malloc(MEMP_TCPIP_MSG);
1251
1252 LWIP_DEBUGF(TCPIP_DEBUG, ("net_input: %p %p\n", p,inp));
1253
1254 if(msg==NULL) {
1255 LWIP_ERROR(("net_input: msg out of memory.\n"));
1256 pbuf_free(p);
1257 return ERR_MEM;
1258 }
1259
1260 msg->type = NETMSG_INPUT;
1261 msg->msg.inp.p = p;
1262 msg->msg.inp.net = inp;
1263 MQ_Send(netthread_mbox,msg,MQ_MSG_BLOCK);
1264 return ERR_OK;
1265 }
1266
net_apimsg(struct api_msg * apimsg)1267 static void net_apimsg(struct api_msg *apimsg)
1268 {
1269 struct net_msg *msg = memp_malloc(MEMP_TCPIP_MSG);
1270
1271 LWIP_DEBUGF(TCPIP_DEBUG, ("net_apimsg: %p\n",apimsg));
1272 if(msg==NULL) {
1273 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1274 memp_free(MEMP_API_MSG,apimsg);
1275 return;
1276 }
1277
1278 msg->type = NETMSG_API;
1279 msg->msg.apimsg = apimsg;
1280 MQ_Send(netthread_mbox,msg,MQ_MSG_BLOCK);
1281 }
1282
net_callback(void (* f)(void *),void * ctx)1283 static err_t net_callback(void (*f)(void *),void *ctx)
1284 {
1285 struct net_msg *msg = memp_malloc(MEMP_TCPIP_MSG);
1286
1287 LWIP_DEBUGF(TCPIP_DEBUG, ("net_callback: %p(%p)\n", f,ctx));
1288
1289 if(msg==NULL) {
1290 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1291 return ERR_MEM;
1292 }
1293
1294 msg->type = NETMSG_CALLBACK;
1295 msg->msg.cb.f = f;
1296 msg->msg.cb.ctx = ctx;
1297 MQ_Send(netthread_mbox,msg,MQ_MSG_BLOCK);
1298 return ERR_OK;
1299 }
1300
net_thread(void * arg)1301 static void* net_thread(void *arg)
1302 {
1303 struct net_msg *msg;
1304 struct timespec tb;
1305 sys_sem sem = (sys_sem)arg;
1306
1307 etharp_init();
1308 ip_init();
1309 udp_init();
1310 tcp_init();
1311
1312 tb.tv_sec = ARP_TMR_INTERVAL/TB_MSPERSEC;
1313 tb.tv_nsec = 0;
1314 net_arp_ticks = __lwp_wd_calc_ticks(&tb);
1315 __lwp_wd_initialize(&arp_time_cntrl,__arp_timer,ARP_TIMER_ID,NULL);
1316 __lwp_wd_insert_ticks(&arp_time_cntrl,net_arp_ticks);
1317
1318 tb.tv_sec = 0;
1319 tb.tv_nsec = TCP_TMR_INTERVAL*TB_NSPERMS;
1320 net_tcp_ticks = __lwp_wd_calc_ticks(&tb);
1321 __lwp_wd_initialize(&tcp_timer_cntrl,__tcp_timer,TCP_TIMER_ID,NULL);
1322
1323 LWP_SemPost(sem);
1324
1325 LWIP_DEBUGF(TCPIP_DEBUG, ("net_thread(%p)\n",arg));
1326
1327 while(1) {
1328 MQ_Receive(netthread_mbox,(mqmsg_t)&msg,MQ_MSG_BLOCK);
1329 switch(msg->type) {
1330 case NETMSG_API:
1331 LWIP_DEBUGF(TCPIP_DEBUG, ("net_thread: API message %p\n", (void *)msg));
1332 apimsg_input(msg->msg.apimsg);
1333 break;
1334 case NETMSG_INPUT:
1335 LWIP_DEBUGF(TCPIP_DEBUG, ("net_thread: IP packet %p\n", (void *)msg));
1336 bba_process(msg->msg.inp.p,msg->msg.inp.net);
1337 break;
1338 case NETMSG_CALLBACK:
1339 LWIP_DEBUGF(TCPIP_DEBUG, ("net_thread: CALLBACK %p\n", (void *)msg));
1340 msg->msg.cb.f(msg->msg.cb.ctx);
1341 break;
1342 default:
1343 break;
1344 }
1345 memp_free(MEMP_TCPIP_MSG,msg);
1346 }
1347 return NULL;
1348 }
1349
1350 /* sockets part */
alloc_socket(struct netconn * conn)1351 static s32 alloc_socket(struct netconn *conn)
1352 {
1353 s32 i;
1354
1355 LWP_SemWait(netsocket_sem);
1356
1357 for(i=0;i<NUM_SOCKETS;i++) {
1358 if(!sockets[i].conn) {
1359 sockets[i].conn = conn;
1360 sockets[i].lastdata = NULL;
1361 sockets[i].lastoffset = 0;
1362 sockets[i].rcvevt = 0;
1363 sockets[i].sendevt = 1;
1364 sockets[i].flags = 0;
1365 sockets[i].err = 0;
1366 LWP_SemPost(netsocket_sem);
1367 return i;
1368 }
1369 }
1370
1371 LWP_SemPost(netsocket_sem);
1372 return -1;
1373 }
1374
get_socket(s32 s)1375 static struct netsocket* get_socket(s32 s)
1376 {
1377 struct netsocket *sock;
1378 if(s<0 || s>NUM_SOCKETS) {
1379 LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s));
1380 return NULL;
1381 }
1382 sock = &sockets[s];
1383 if(!sock->conn) {
1384 LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): no active\n", s));
1385 return NULL;
1386 }
1387
1388 return sock;
1389 }
1390
evt_callback(struct netconn * conn,enum netconn_evt evt,u32 len)1391 static void evt_callback(struct netconn *conn,enum netconn_evt evt,u32 len)
1392 {
1393 s32 s;
1394 struct netsocket *sock;
1395 struct netselect_cb *scb;
1396
1397 if(conn) {
1398 s = conn->socket;
1399 if(s<0) {
1400 if(evt==NETCONN_EVTRCVPLUS)
1401 conn->socket--;
1402 return;
1403 }
1404 sock = get_socket(s);
1405 if(!sock) return;
1406 } else
1407 return;
1408
1409 LWP_SemWait(sockselect_sem);
1410 switch(evt) {
1411 case NETCONN_EVTRCVPLUS:
1412 sock->rcvevt++;
1413 break;
1414 case NETCONN_EVTRCVMINUS:
1415 sock->rcvevt--;
1416 break;
1417 case NETCONN_EVTSENDPLUS:
1418 sock->sendevt = 1;
1419 break;
1420 case NETCONN_EVTSENDMINUS:
1421 sock->sendevt = 0;
1422 break;
1423 }
1424 LWP_SemPost(sockselect_sem);
1425
1426 while(1) {
1427 LWP_SemWait(sockselect_sem);
1428 for(scb = selectcb_list;scb;scb = scb->next) {
1429 if(scb->signaled==0) {
1430 if(scb->readset && FD_ISSET(s,scb->readset))
1431 if(sock->rcvevt) break;
1432 if(scb->writeset && FD_ISSET(s,scb->writeset))
1433 if(sock->sendevt) break;
1434 }
1435 }
1436 if(scb) {
1437 scb->signaled = 1;
1438 LWP_SemPost(sockselect_sem);
1439 LWP_MutexLock(scb->cond_lck);
1440 LWP_CondSignal(scb->cond);
1441 LWP_MutexUnlock(scb->cond_lck);
1442 } else {
1443 LWP_SemPost(sockselect_sem);
1444 break;
1445 }
1446 }
1447
1448 }
1449
1450 extern const devoptab_t dotab_stdnet;
1451
if_configex(struct in_addr * local_ip,struct in_addr * netmask,struct in_addr * gateway,bool use_dhcp,int max_retries)1452 s32 if_configex(struct in_addr *local_ip,struct in_addr *netmask,struct in_addr *gateway,bool use_dhcp, int max_retries)
1453 {
1454 s32 ret = 0;
1455 struct ip_addr loc_ip, mask, gw;
1456 struct netif *pnet;
1457 struct timespec tb;
1458 dev_s hbba = NULL;
1459
1460 if(g_netinitiated) return 0;
1461 g_netinitiated = 1;
1462
1463 // AddDevice(&dotab_stdnet);
1464 #ifdef STATS
1465 stats_init();
1466 #endif /* STATS */
1467
1468 sys_init();
1469 mem_init();
1470 memp_init();
1471 pbuf_init();
1472 netif_init();
1473
1474 // init tcpip thread message box
1475 if(MQ_Init(&netthread_mbox,MQBOX_SIZE)!=MQ_ERROR_SUCCESSFUL) return -1;
1476
1477 // create & setup interface
1478 loc_ip.addr = 0;
1479 mask.addr = 0;
1480 gw.addr = 0;
1481
1482 if(use_dhcp==FALSE) {
1483 if( !gateway || gateway->s_addr==0
1484 || !local_ip || local_ip->s_addr==0
1485 || !netmask || netmask->s_addr==0 ) return -EINVAL;
1486 loc_ip.addr = local_ip->s_addr;
1487 mask.addr = netmask->s_addr;
1488 gw.addr = gateway->s_addr;
1489 }
1490 hbba = bba_create(&g_hNetIF);
1491 pnet = netif_add(&g_hNetIF,&loc_ip, &mask, &gw, hbba, bba_init, net_input);
1492 if(pnet) {
1493 netif_set_up(pnet);
1494 netif_set_default(pnet);
1495 #if (LWIP_DHCP)
1496 if(use_dhcp==TRUE) {
1497 //setup coarse timer
1498 tb.tv_sec = DHCP_COARSE_TIMER_SECS;
1499 tb.tv_nsec = 0;
1500 net_dhcpcoarse_ticks = __lwp_wd_calc_ticks(&tb);
1501 __lwp_wd_initialize(&dhcp_coarsetimer_cntrl, __dhcpcoarse_timer, DHCPCOARSE_TIMER_ID, NULL);
1502 __lwp_wd_insert_ticks(&dhcp_coarsetimer_cntrl, net_dhcpcoarse_ticks);
1503
1504 //setup fine timer
1505 tb.tv_sec = 0;
1506 tb.tv_nsec = DHCP_FINE_TIMER_MSECS * TB_NSPERMS;
1507 net_dhcpfine_ticks = __lwp_wd_calc_ticks(&tb);
1508 __lwp_wd_initialize(&dhcp_finetimer_cntrl, __dhcpfine_timer, DHCPFINE_TIMER_ID, NULL);
1509 __lwp_wd_insert_ticks(&dhcp_finetimer_cntrl, net_dhcpfine_ticks);
1510
1511 //now start dhcp client
1512 dhcp_start(pnet);
1513 }
1514 #endif
1515 } else
1516 return -ENXIO;
1517
1518 // setup loopinterface
1519 IP4_ADDR(&loc_ip, 127, 0, 0, 1);
1520 IP4_ADDR(&mask, 255, 0, 0, 0);
1521 IP4_ADDR(&gw, 127, 0, 0, 1);
1522 pnet = netif_add(&g_hLoopIF, &loc_ip, &mask, &gw, NULL, loopif_init, net_input);
1523
1524 //last and least start the tcpip layer
1525 ret = net_init();
1526
1527 if ( ret == 0 && use_dhcp == TRUE ) {
1528
1529 int retries = max_retries;
1530 // wait for dhcp to bind
1531 while ( g_hNetIF.dhcp->state != DHCP_BOUND && retries > 0 ) {
1532 retries--;
1533 usleep(500000);
1534 }
1535
1536 if ( retries > 0 ) {
1537 //copy back network addresses
1538 if ( local_ip != NULL ) local_ip->s_addr = g_hNetIF.ip_addr.addr;
1539 if ( gateway != NULL ) gateway->s_addr = g_hNetIF.gw.addr;
1540 if ( netmask != NULL ) netmask->s_addr = g_hNetIF.netmask.addr;
1541 } else {
1542 ret = -ETIMEDOUT;
1543 }
1544 }
1545
1546 return ret;
1547 }
1548
if_config(char * local_ip,char * netmask,char * gateway,bool use_dhcp,int max_retries)1549 s32 if_config(char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries)
1550 {
1551 s32 ret = 0;
1552 struct in_addr loc_ip, mask, gw;
1553
1554 loc_ip.s_addr = 0;
1555 mask.s_addr = 0;
1556 gw.s_addr = 0;
1557
1558 if ( local_ip != NULL ) loc_ip.s_addr = inet_addr(local_ip);
1559 if ( netmask != NULL ) mask.s_addr = inet_addr(netmask);
1560 if ( gateway != NULL ) gw.s_addr = inet_addr(gateway);
1561
1562 ret = if_configex( &loc_ip, &mask, &gw, use_dhcp, max_retries);
1563
1564 if (ret<0) return ret;
1565
1566 if ( use_dhcp == TRUE ) {
1567 //copy back network addresses
1568 if ( local_ip != NULL ) strcpy(local_ip, inet_ntoa( loc_ip ));
1569 if ( netmask != NULL ) strcpy(netmask, inet_ntoa( mask));
1570 if ( gateway != NULL ) strcpy(gateway, inet_ntoa( gw ));
1571 }
1572 return ret;
1573 }
1574
net_init()1575 s32 net_init()
1576 {
1577 sys_sem sem;
1578
1579 if(tcpiplayer_inited) return 1;
1580
1581 if(LWP_SemInit(&netsocket_sem,1,1)==-1) return -1;
1582 if(LWP_SemInit(&sockselect_sem,1,1)==-1) {
1583 LWP_SemDestroy(netsocket_sem);
1584 return -1;
1585 }
1586 if(LWP_SemInit(&sem,0,1)==-1) {
1587 LWP_SemDestroy(netsocket_sem);
1588 LWP_SemDestroy(sockselect_sem);
1589 return -1;
1590 }
1591
1592 if(LWP_CreateThread(&hnet_thread,net_thread,(void*)sem,netthread_stack,STACKSIZE,220)==-1) {
1593 LWP_SemDestroy(netsocket_sem);
1594 LWP_SemDestroy(sockselect_sem);
1595 LWP_SemDestroy(sem);
1596 return -1;
1597 }
1598 LWP_SemWait(sem);
1599 LWP_SemDestroy(sem);
1600
1601 tcpiplayer_inited = 1;
1602
1603 return 0;
1604 }
1605
net_shutdown(s32 s,u32 how)1606 s32 net_shutdown(s32 s,u32 how)
1607 {
1608 return -1;
1609 }
1610
net_fcntl(s32 s,u32 cmd,u32 flags)1611 s32 net_fcntl(s32 s, u32 cmd, u32 flags)
1612 {
1613 return -1;
1614 }
1615
net_socket(u32 domain,u32 type,u32 protocol)1616 s32 net_socket(u32 domain,u32 type,u32 protocol)
1617 {
1618 s32 i;
1619 struct netconn *conn;
1620
1621 switch(type) {
1622 case SOCK_RAW:
1623 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_socket(SOCK_RAW)\n"));
1624 conn = netconn_new_with_proto_and_callback(NETCONN_RAW,protocol,evt_callback);
1625 break;
1626 case SOCK_DGRAM:
1627 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_socket(SOCK_DGRAM)\n"));
1628 conn = netconn_new_with_callback(NETCONN_UDP,evt_callback);
1629 break;
1630 case SOCK_STREAM:
1631 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_socket(SOCK_STREAM)\n"));
1632 conn = netconn_new_with_callback(NETCONN_TCP,evt_callback);
1633 break;
1634 default:
1635 return -1;
1636 }
1637 if(!conn) return -1;
1638
1639 i = alloc_socket(conn);
1640 if(i==-1) {
1641 netconn_delete(conn);
1642 return -1;
1643 }
1644
1645 conn->socket = i;
1646 return i;
1647 }
1648
net_accept(s32 s,struct sockaddr * addr,socklen_t * addrlen)1649 s32 net_accept(s32 s,struct sockaddr *addr,socklen_t *addrlen)
1650 {
1651 struct netsocket *sock;
1652 struct netconn *newconn;
1653 struct ip_addr naddr = {0};
1654 u16 port = 0;
1655 s32 newsock;
1656 struct sockaddr_in sin;
1657
1658 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_accept(%d)\n", s));
1659
1660 sock = get_socket(s);
1661 if(!sock) return -ENOTSOCK;
1662
1663 newconn = netconn_accept(sock->conn);
1664 netconn_peer(newconn,&naddr,&port);
1665
1666 memset(&sin,0,sizeof(sin));
1667 sin.sin_family = AF_INET;
1668 sin.sin_port = htons(port);
1669 sin.sin_addr.s_addr = naddr.addr;
1670
1671 if(*addrlen>sizeof(sin))
1672 *addrlen = sizeof(sin);
1673 memcpy(addr,&sin,*addrlen);
1674
1675 newsock = alloc_socket(newconn);
1676 if(newsock==-1) {
1677 netconn_delete(newconn);
1678 return -1;
1679 }
1680
1681 newconn->callback = evt_callback;
1682 sock = get_socket(newsock);
1683
1684 LWP_SemWait(netsocket_sem);
1685 sock->rcvevt += -1 - newconn->socket;
1686 newconn->socket = newsock;
1687 LWP_SemPost(netsocket_sem);
1688
1689 return newsock;
1690 }
1691
net_bind(s32 s,struct sockaddr * name,socklen_t namelen)1692 s32 net_bind(s32 s,struct sockaddr *name,socklen_t namelen)
1693 {
1694 struct netsocket *sock;
1695 struct ip_addr loc_addr;
1696 u16 loc_port;
1697 err_t err;
1698
1699 sock = get_socket(s);
1700 if(!sock) return -ENOTSOCK;
1701
1702 loc_addr.addr = ((struct sockaddr_in*)name)->sin_addr.s_addr;
1703 loc_port = ((struct sockaddr_in*)name)->sin_port;
1704
1705 err = netconn_bind(sock->conn,&loc_addr,ntohs(loc_port));
1706 if(err!=ERR_OK) return -1;
1707
1708 return 0;
1709 }
1710
net_listen(s32 s,u32 backlog)1711 s32 net_listen(s32 s,u32 backlog)
1712 {
1713 struct netsocket *sock;
1714 err_t err;
1715
1716 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_listen(%d, backlog=%d)\n", s, backlog));
1717 sock = get_socket(s);
1718 if(!sock) return -ENOTSOCK;
1719
1720 err = netconn_listen(sock->conn);
1721 if(err!=ERR_OK) {
1722 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_listen(%d) failed, err=%d\n", s, err));
1723 return -1;
1724 }
1725 return 0;
1726 }
1727
net_recvfrom(s32 s,void * mem,s32 len,u32 flags,struct sockaddr * from,socklen_t * fromlen)1728 s32 net_recvfrom(s32 s,void *mem,s32 len,u32 flags,struct sockaddr *from,socklen_t *fromlen)
1729 {
1730 struct netsocket *sock;
1731 struct netbuf *buf;
1732 u16 buflen,copylen;
1733 struct ip_addr *addr;
1734 u16 port;
1735
1736 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags));
1737 if(mem==NULL || len<=0) return -EINVAL;
1738
1739 sock = get_socket(s);
1740 if(!sock) return -ENOTSOCK;
1741
1742 if(sock->lastdata)
1743 buf = sock->lastdata;
1744 else {
1745 if(((flags&MSG_DONTWAIT) || (sock->flags&O_NONBLOCK)) && !sock->rcvevt) {
1746 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_recvfrom(%d): returning EWOULDBLOCK\n", s));
1747 return -EAGAIN;
1748 }
1749 buf = netconn_recv(sock->conn);
1750 if(!buf) {
1751 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_recvfrom(%d): buf == NULL!\n", s));
1752 return 0;
1753 }
1754 }
1755
1756 buflen = netbuf_len(buf);
1757 buflen -= sock->lastoffset;
1758 if(buflen<=0)
1759 return 0;
1760 if(len>buflen)
1761 copylen = buflen;
1762 else
1763 copylen = len;
1764
1765 netbuf_copypartial(buf,mem,copylen,sock->lastoffset);
1766
1767 if(from && fromlen) {
1768 struct sockaddr_in sin;
1769
1770 addr = netbuf_fromaddr(buf);
1771 port = netbuf_fromport(buf);
1772
1773 memset(&sin,0,sizeof(sin));
1774 sin.sin_family = AF_INET;
1775 sin.sin_port = htons(port);
1776 sin.sin_addr.s_addr = addr->addr;
1777
1778 if(*fromlen>sizeof(sin))
1779 *fromlen = sizeof(sin);
1780
1781 memcpy(from,&sin,*fromlen);
1782
1783 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_recvfrom(%d): addr=", s));
1784 ip_addr_debug_print(SOCKETS_DEBUG, addr);
1785 LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, copylen));
1786 }
1787 if(netconn_type(sock->conn)==NETCONN_TCP && (buflen-copylen)>0) {
1788 sock->lastdata = buf;
1789 sock->lastoffset += copylen;
1790 } else {
1791 sock->lastdata = NULL;
1792 sock->lastoffset = 0;
1793 netbuf_delete(buf);
1794 }
1795 return copylen;
1796 }
1797
net_read(s32 s,void * mem,s32 len)1798 s32 net_read(s32 s,void *mem,s32 len)
1799 {
1800 return net_recvfrom(s,mem,len,0,NULL,NULL);
1801 }
1802
net_recv(s32 s,void * mem,s32 len,u32 flags)1803 s32 net_recv(s32 s,void *mem,s32 len,u32 flags)
1804 {
1805 return net_recvfrom(s,mem,len,flags,NULL,NULL);
1806 }
1807
net_sendto(s32 s,const void * data,s32 len,u32 flags,struct sockaddr * to,socklen_t tolen)1808 s32 net_sendto(s32 s,const void *data,s32 len,u32 flags,struct sockaddr *to,socklen_t tolen)
1809 {
1810 struct netsocket *sock;
1811 struct ip_addr remote_addr, addr;
1812 u16_t remote_port, port = 0;
1813 s32 ret,connected;
1814
1815 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_sendto(%d, data=%p, size=%d, flags=0x%x)\n", s, data, len, flags));
1816 if(data==NULL || len<=0) return -EINVAL;
1817
1818 sock = get_socket(s);
1819 if (!sock) return -ENOTSOCK;
1820
1821 /* get the peer if currently connected */
1822 connected = (netconn_peer(sock->conn, &addr, &port) == ERR_OK);
1823
1824 remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
1825 remote_port = ((struct sockaddr_in *)to)->sin_port;
1826
1827 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_sendto(%d, data=%p, size=%d, flags=0x%x to=", s, data, len, flags));
1828 ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
1829 LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", ntohs(remote_port)));
1830
1831 netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
1832
1833 ret = net_send(s, data, len, flags);
1834
1835 /* reset the remote address and port number
1836 of the connection */
1837 if (connected)
1838 netconn_connect(sock->conn, &addr, port);
1839 else
1840 netconn_disconnect(sock->conn);
1841 return ret;
1842 }
1843
net_send(s32 s,const void * data,s32 len,u32 flags)1844 s32 net_send(s32 s,const void *data,s32 len,u32 flags)
1845 {
1846 struct netsocket *sock;
1847 struct netbuf *buf;
1848 err_t err;
1849
1850 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, len, flags));
1851 if(data==NULL || len<=0) return -EINVAL;
1852
1853 sock = get_socket(s);
1854 if(!sock) return -ENOTSOCK;
1855
1856 switch(netconn_type(sock->conn)) {
1857 case NETCONN_RAW:
1858 case NETCONN_UDP:
1859 case NETCONN_UDPLITE:
1860 case NETCONN_UDPNOCHKSUM:
1861 buf = netbuf_new();
1862 if(!buf) {
1863 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_send(%d) ENOBUFS\n", s));
1864 return -ENOBUFS;
1865 }
1866 netbuf_ref(buf,data,len);
1867 err = netconn_send(sock->conn,buf);
1868 netbuf_delete(buf);
1869 break;
1870 case NETCONN_TCP:
1871 err = netconn_write(sock->conn,data,len,NETCONN_COPY);
1872 break;
1873 default:
1874 err = ERR_ARG;
1875 break;
1876 }
1877 if(err!=ERR_OK) {
1878 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_send(%d) err=%d\n", s, err));
1879 return -1;
1880 }
1881
1882 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_send(%d) ok size=%d\n", s, len));
1883 return len;
1884 }
1885
net_write(s32 s,const void * data,s32 size)1886 s32 net_write(s32 s,const void *data,s32 size)
1887 {
1888 return net_send(s,data,size,0);
1889 }
1890
net_connect(s32 s,struct sockaddr * name,socklen_t namelen)1891 s32 net_connect(s32 s,struct sockaddr *name,socklen_t namelen)
1892 {
1893 struct netsocket *sock;
1894 err_t err;
1895
1896 sock = get_socket(s);
1897 if(!sock) return -ENOTSOCK;
1898
1899 if(((struct sockaddr_in*)name)->sin_family==AF_UNSPEC) {
1900 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_connect(%d, AF_UNSPEC)\n", s));
1901 err = netconn_disconnect(sock->conn);
1902 } else {
1903 struct ip_addr remote_addr;
1904 u16 remote_port;
1905
1906 remote_addr.addr = ((struct sockaddr_in*)name)->sin_addr.s_addr;
1907 remote_port = ((struct sockaddr_in*)name)->sin_port;
1908
1909 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_connect(%d, addr=", s));
1910 ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
1911 LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port)));
1912
1913 err = netconn_connect(sock->conn,&remote_addr,ntohs(remote_port));
1914 }
1915 if(err!=ERR_OK) {
1916 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_connect(%d) failed, err=%d\n", s, err));
1917 return -1;
1918 }
1919
1920 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_connect(%d) succeeded\n", s));
1921 return -EISCONN;
1922 }
1923
net_close(s32 s)1924 s32 net_close(s32 s)
1925 {
1926 struct netsocket *sock;
1927
1928 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_close(%d)\n", s));
1929
1930 LWP_SemWait(netsocket_sem);
1931
1932 sock = get_socket(s);
1933 if(!sock) {
1934 LWP_SemPost(netsocket_sem);
1935 return -ENOTSOCK;
1936 }
1937
1938 netconn_delete(sock->conn);
1939 if(sock->lastdata) netbuf_delete(sock->lastdata);
1940
1941 sock->lastdata = NULL;
1942 sock->lastoffset = 0;
1943 sock->conn = NULL;
1944
1945 LWP_SemPost(netsocket_sem);
1946 return 0;
1947 }
1948
net_selscan(s32 maxfdp1,fd_set * readset,fd_set * writeset,fd_set * exceptset)1949 static s32 net_selscan(s32 maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset)
1950 {
1951 s32 i,nready = 0;
1952 fd_set lreadset,lwriteset,lexceptset;
1953 struct netsocket *sock;
1954
1955 FD_ZERO(&lreadset);
1956 FD_ZERO(&lwriteset);
1957 FD_ZERO(&lexceptset);
1958
1959 for(i=0;i<maxfdp1;i++) {
1960 if(FD_ISSET(i,readset)) {
1961 sock = get_socket(i);
1962 if(sock && (sock->lastdata || sock->rcvevt)) {
1963 FD_SET(i,&lreadset);
1964 nready++;
1965 }
1966 }
1967 if(FD_ISSET(i,writeset)) {
1968 sock = get_socket(i);
1969 if(sock && sock->sendevt) {
1970 FD_SET(i,&lwriteset);
1971 nready++;
1972 }
1973 }
1974 }
1975 *readset = lreadset;
1976 *writeset = lwriteset;
1977 FD_ZERO(exceptset);
1978
1979 return nready;
1980 }
1981
net_select(s32 maxfdp1,fd_set * readset,fd_set * writeset,fd_set * exceptset,struct timeval * timeout)1982 s32 net_select(s32 maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,struct timeval *timeout)
1983 {
1984 s32 i,nready;
1985 fd_set lreadset,lwriteset,lexceptset;
1986 struct timespec tb,*p_tb;
1987 struct netselect_cb sel_cb;
1988 struct netselect_cb *psel_cb;
1989
1990 sel_cb.next = NULL;
1991 sel_cb.readset = readset;
1992 sel_cb.writeset = writeset;
1993 sel_cb.exceptset = exceptset;
1994 sel_cb.signaled = 0;
1995
1996 LWP_SemWait(sockselect_sem);
1997
1998 if(readset)
1999 lreadset = *readset;
2000 else
2001 FD_ZERO(&lreadset);
2002
2003 if(writeset)
2004 lwriteset = *writeset;
2005 else
2006 FD_ZERO(&lwriteset);
2007
2008 if(exceptset)
2009 lexceptset = *exceptset;
2010 else
2011 FD_ZERO(&lexceptset);
2012
2013 nready = net_selscan(maxfdp1,&lreadset,&lwriteset,&lexceptset);
2014 if(!nready) {
2015 if(timeout && timeout->tv_sec==0 && timeout->tv_usec==0) {
2016 LWP_SemPost(sockselect_sem);
2017 if(readset)
2018 FD_ZERO(readset);
2019 if(writeset)
2020 FD_ZERO(writeset);
2021 if(exceptset)
2022 FD_ZERO(exceptset);
2023 return 0;
2024 }
2025
2026 LWP_MutexInit(&sel_cb.cond_lck,FALSE);
2027 LWP_CondInit(&sel_cb.cond);
2028 sel_cb.next = selectcb_list;
2029 selectcb_list = &sel_cb;
2030
2031 LWP_SemPost(sockselect_sem);
2032 if(timeout==NULL)
2033 p_tb = NULL;
2034 else {
2035 tb.tv_sec = timeout->tv_sec;
2036 tb.tv_nsec = (timeout->tv_usec+500)*TB_NSPERUS;
2037 p_tb = &tb;
2038 }
2039
2040 LWP_MutexLock(sel_cb.cond_lck);
2041 i = LWP_CondTimedWait(sel_cb.cond,sel_cb.cond_lck,p_tb);
2042 LWP_MutexUnlock(sel_cb.cond_lck);
2043
2044 LWP_SemWait(sockselect_sem);
2045 if(selectcb_list==&sel_cb)
2046 selectcb_list = sel_cb.next;
2047 else {
2048 for(psel_cb = selectcb_list;psel_cb;psel_cb = psel_cb->next) {
2049 if(psel_cb->next==&sel_cb) {
2050 psel_cb->next = sel_cb.next;
2051 break;
2052 }
2053 }
2054 }
2055 LWP_CondDestroy(sel_cb.cond);
2056 LWP_MutexDestroy(sel_cb.cond_lck);
2057
2058 LWP_SemPost(sockselect_sem);
2059
2060 if(i==ETIMEDOUT) {
2061 if(readset)
2062 FD_ZERO(readset);
2063 if(writeset)
2064 FD_ZERO(writeset);
2065 if(exceptset)
2066 FD_ZERO(exceptset);
2067 return 0;
2068 }
2069
2070 if(readset)
2071 lreadset = *readset;
2072 else
2073 FD_ZERO(&lreadset);
2074
2075 if(writeset)
2076 lwriteset = *writeset;
2077 else
2078 FD_ZERO(&lwriteset);
2079
2080 if(exceptset)
2081 lexceptset = *exceptset;
2082 else
2083 FD_ZERO(&lexceptset);
2084
2085 nready = net_selscan(maxfdp1,&lreadset,&lwriteset,&lexceptset);
2086 } else
2087 LWP_SemPost(sockselect_sem);
2088
2089 if(readset)
2090 *readset = lreadset;
2091 if(writeset)
2092 *writeset = lwriteset;
2093 if(exceptset)
2094 *exceptset = lexceptset;
2095
2096 return nready;
2097 }
2098
net_setsockopt(s32 s,u32 level,u32 optname,const void * optval,socklen_t optlen)2099 s32 net_setsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen)
2100 {
2101 s32 err = 0;
2102 struct netsocket *sock;
2103
2104 sock = get_socket(s);
2105 if(sock==NULL) return -ENOTSOCK;
2106 if(optval==NULL) return -EINVAL;
2107
2108 switch(level) {
2109 case SOL_SOCKET:
2110 {
2111 switch(optname) {
2112 case SO_BROADCAST:
2113 case SO_KEEPALIVE:
2114 case SO_REUSEADDR:
2115 case SO_REUSEPORT:
2116 if(optlen<sizeof(u32)) err = EINVAL;
2117 break;
2118 default:
2119 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
2120 err = ENOPROTOOPT;
2121 }
2122 }
2123 break;
2124
2125 case IPPROTO_IP:
2126 {
2127 switch(optname) {
2128 case IP_TTL:
2129 case IP_TOS:
2130 if(optlen<sizeof(u32)) err = EINVAL;
2131 break;
2132 default:
2133 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
2134 err = ENOPROTOOPT;
2135 }
2136 }
2137 break;
2138
2139 case IPPROTO_TCP:
2140 {
2141 if(optlen<sizeof(u32)) {
2142 err = EINVAL;
2143 break;
2144 }
2145 if(sock->conn->type!=NETCONN_TCP) return 0;
2146
2147 switch(optname) {
2148 case TCP_NODELAY:
2149 case TCP_KEEPALIVE:
2150 break;
2151 default:
2152 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
2153 err = ENOPROTOOPT;
2154 }
2155 }
2156 break;
2157
2158 default:
2159 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
2160 err = ENOPROTOOPT;
2161 }
2162 if(err!=0) return -1;
2163
2164 switch(level) {
2165 case SOL_SOCKET:
2166 {
2167 switch(optname) {
2168 case SO_BROADCAST:
2169 case SO_KEEPALIVE:
2170 case SO_REUSEADDR:
2171 case SO_REUSEPORT:
2172 if(*(u32*)optval)
2173 sock->conn->pcb.tcp->so_options |= optname;
2174 else
2175 sock->conn->pcb.tcp->so_options &= ~optname;
2176 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(u32*)optval?"on":"off")));
2177 break;
2178 }
2179 }
2180 break;
2181
2182 case IPPROTO_IP:
2183 {
2184 switch(optname) {
2185 case IP_TTL:
2186 sock->conn->pcb.tcp->ttl = (u8)(*(u32*)optval);
2187 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s, sock->conn->pcb.tcp->ttl));
2188 break;
2189 case IP_TOS:
2190 sock->conn->pcb.tcp->tos = (u8)(*(u32*)optval);
2191 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s, sock->conn->pcb.tcp->tos));
2192 break;
2193 }
2194 }
2195 break;
2196
2197 case IPPROTO_TCP:
2198 {
2199 switch(optname) {
2200 case TCP_NODELAY:
2201 if(*(u32*)optval)
2202 sock->conn->pcb.tcp->flags |= TF_NODELAY;
2203 else
2204 sock->conn->pcb.tcp->flags &= ~TF_NODELAY;
2205 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s, (*(u32*)optval)?"on":"off") );
2206 break;
2207 case TCP_KEEPALIVE:
2208 sock->conn->pcb.tcp->keepalive = (u32)(*(u32*)optval);
2209 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %u\n", s, sock->conn->pcb.tcp->keepalive));
2210 break;
2211 }
2212 }
2213 }
2214 return err?-1:0;
2215 }
2216
net_ioctl(s32 s,u32 cmd,void * argp)2217 s32 net_ioctl(s32 s, u32 cmd, void *argp)
2218 {
2219 struct netsocket *sock = get_socket(s);
2220
2221 if(!sock) return -ENOTSOCK;
2222
2223 switch (cmd) {
2224 case FIONREAD:
2225 if(!argp) return -EINVAL;
2226
2227 *((u16_t*)argp) = sock->conn->recvavail;
2228
2229 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16*)argp)));
2230 return 0;
2231
2232 case FIONBIO:
2233 if(argp && *(u32*)argp)
2234 sock->flags |= O_NONBLOCK;
2235 else
2236 sock->flags &= ~O_NONBLOCK;
2237 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags&O_NONBLOCK)));
2238 return 0;
2239
2240 default:
2241 LWIP_DEBUGF(SOCKETS_DEBUG, ("net_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp));
2242 return -EINVAL;
2243 }
2244 }
2245