10 #include <semaphore.h>
11 #include <processor.h>
12 #include <lwp_threads.h>
13 #include <lwp_watchdog.h>
14 #include <lwip/debug.h>
17 #include <lwip/memp.h>
19 #include <lwip/stats.h>
24 #include <lwip/dhcp.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>
32 #include <sys/iosupport.h>
37 #define ARP_TIMER_ID 0x00070041
38 #define TCP_TIMER_ID 0x00070042
39 #define DHCPCOARSE_TIMER_ID 0x00070043
40 #define DHCPFINE_TIMER_ID 0x00070044
42 #define STACKSIZE 32768
43 #define MQBOX_SIZE 256
44 #define NUM_SOCKETS MEMP_NUM_NETCONN
48 struct netbuf
*lastdata
;
49 u16 lastoffset
,rcvevt
,sendevt
,flags
;
54 struct netselect_cb
*next
;
63 typedef void (*apimsg_decode
)(struct apimsg_msg
*);
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
;
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
;
81 static sys_sem netsocket_sem
;
82 static sys_sem sockselect_sem
;
83 static sys_mbox netthread_mbox
;
85 static sys_thread hnet_thread
;
86 static u8 netthread_stack
[STACKSIZE
];
88 static u32 tcp_timer_active
= 0;
90 static struct netbuf
* netbuf_new();
91 static void netbuf_delete(struct netbuf
*);
92 static void* netbuf_alloc(struct netbuf
*,u32
);
93 static void netbuf_free(struct netbuf
*);
94 static void netbuf_copypartial(struct netbuf
*,void *,u32
,u32
);
95 static void netbuf_ref(struct netbuf
*,const void *,u32
);
97 static struct netconn
* netconn_new_with_callback(enum netconn_type
,void (*)(struct netconn
*,enum netconn_evt
,u32
));
98 static struct netconn
* netconn_new_with_proto_and_callback(enum netconn_type
,u16
,void (*)(struct netconn
*,enum netconn_evt
,u32
));
99 static err_t
netconn_delete(struct netconn
*);
100 static struct netconn
* netconn_accept(struct netconn
* );
101 static err_t
netconn_peer(struct netconn
*,struct ip_addr
*,u16
*);
102 static err_t
netconn_bind(struct netconn
*,struct ip_addr
*,u16
);
103 static err_t
netconn_listen(struct netconn
*);
104 static struct netbuf
* netconn_recv(struct netconn
*);
105 static err_t
netconn_send(struct netconn
*,struct netbuf
*);
106 static err_t
netconn_write(struct netconn
*,const void *,u32
,u8
);
107 static err_t
netconn_connect(struct netconn
*,struct ip_addr
*,u16
);
108 static err_t
netconn_disconnect(struct netconn
*);
110 static void do_newconn(struct apimsg_msg
*);
111 static void do_delconn(struct apimsg_msg
*);
112 static void do_bind(struct apimsg_msg
*);
113 static void do_listen(struct apimsg_msg
*);
114 static void do_connect(struct apimsg_msg
*);
115 static void do_disconnect(struct apimsg_msg
*);
116 static void do_accept(struct apimsg_msg
*);
117 static void do_send(struct apimsg_msg
*);
118 static void do_recv(struct apimsg_msg
*);
119 static void do_write(struct apimsg_msg
*);
120 static void do_close(struct apimsg_msg
*);
122 static apimsg_decode decode
[APIMSG_MAX
] = {
136 static void apimsg_post(struct api_msg
*);
138 static err_t
net_input(struct pbuf
*,struct netif
*);
139 static void net_apimsg(struct api_msg
*);
140 static err_t
net_callback(void (*)(void *),void *);
141 static void* net_thread(void *);
143 static void tmr_callback(void *arg
)
145 void (*functor
)() = (void(*)())arg
;
146 if(functor
) functor();
149 /* low level stuff */
150 static void __dhcpcoarse_timer(void *arg
)
152 __lwp_thread_dispatchdisable();
153 net_callback(tmr_callback
,(void*)dhcp_coarse_tmr
);
154 __lwp_wd_insert_ticks(&dhcp_coarsetimer_cntrl
,net_dhcpcoarse_ticks
);
155 __lwp_thread_dispatchunnest();
158 static void __dhcpfine_timer(void *arg
)
160 __lwp_thread_dispatchdisable();
161 net_callback(tmr_callback
,(void*)dhcp_fine_tmr
);
162 __lwp_wd_insert_ticks(&dhcp_finetimer_cntrl
,net_dhcpfine_ticks
);
163 __lwp_thread_dispatchunnest();
166 static void __tcp_timer(void *arg
)
169 printf("__tcp_timer(%d,%p,%p)\n",tcp_timer_active
,tcp_active_pcbs
,tcp_tw_pcbs
);
171 __lwp_thread_dispatchdisable();
172 net_callback(tmr_callback
,(void*)tcp_tmr
);
173 if (tcp_active_pcbs
|| tcp_tw_pcbs
) {
174 __lwp_wd_insert_ticks(&tcp_timer_cntrl
,net_tcp_ticks
);
176 tcp_timer_active
= 0;
177 __lwp_thread_dispatchunnest();
180 static void __arp_timer(void *arg
)
182 __lwp_thread_dispatchdisable();
183 net_callback(tmr_callback
,(void*)etharp_tmr
);
184 __lwp_wd_insert_ticks(&arp_time_cntrl
,net_arp_ticks
);
185 __lwp_thread_dispatchunnest();
188 void tcp_timer_needed(void)
191 printf("tcp_timer_needed()\n");
193 if(!tcp_timer_active
&& (tcp_active_pcbs
|| tcp_tw_pcbs
)) {
194 tcp_timer_active
= 1;
195 __lwp_wd_insert_ticks(&tcp_timer_cntrl
,net_tcp_ticks
);
200 static __inline__ u16
netbuf_len(struct netbuf
*buf
)
202 return ((buf
&& buf
->p
)?buf
->p
->tot_len
:0);
205 static __inline__
struct ip_addr
* netbuf_fromaddr(struct netbuf
*buf
)
207 return (buf
?buf
->fromaddr
:NULL
);
210 static __inline__ u16
netbuf_fromport(struct netbuf
*buf
)
212 return (buf
?buf
->fromport
:0);
215 static void netbuf_copypartial(struct netbuf
*buf
,void *dataptr
,u32 len
,u32 offset
)
221 if(buf
==NULL
|| dataptr
==NULL
) return;
223 for(p
=buf
->p
;left
<len
&& p
!=NULL
;p
=p
->next
) {
224 if(offset
!=0 && offset
>=p
->len
)
227 for(i
=offset
;i
<p
->len
;i
++) {
228 ((u8
*)dataptr
)[left
] = ((u8
*)p
->payload
)[i
];
229 if(++left
>=len
) return;
236 static struct netbuf
* netbuf_new()
238 struct netbuf
*buf
= NULL
;
240 buf
= memp_malloc(MEMP_NETBUF
);
248 static void netbuf_delete(struct netbuf
*buf
)
251 if(buf
->p
!=NULL
) pbuf_free(buf
->p
);
252 memp_free(MEMP_NETBUF
,buf
);
256 static void* netbuf_alloc(struct netbuf
*buf
,u32 size
)
258 if(buf
->p
!=NULL
) pbuf_free(buf
->p
);
260 buf
->p
= pbuf_alloc(PBUF_TRANSPORT
,size
,PBUF_RAM
);
261 if(buf
->p
==NULL
) return NULL
;
264 return buf
->p
->payload
;
267 static void netbuf_free(struct netbuf
*buf
)
269 if(buf
->p
!=NULL
) pbuf_free(buf
->p
);
270 buf
->p
= buf
->ptr
= NULL
;
273 static void netbuf_ref(struct netbuf
*buf
, const void *dataptr
,u32 size
)
275 if(buf
->p
!=NULL
) pbuf_free(buf
->p
);
276 buf
->p
= pbuf_alloc(PBUF_TRANSPORT
,0,PBUF_REF
);
277 buf
->p
->payload
= (void*)dataptr
;
278 buf
->p
->len
= buf
->p
->tot_len
= size
;
283 static inline enum netconn_type
netconn_type(struct netconn
*conn
)
288 static struct netconn
* netconn_new_with_callback(enum netconn_type t
,void (*cb
)(struct netconn
*,enum netconn_evt
,u32
))
290 return netconn_new_with_proto_and_callback(t
,0,cb
);
293 static struct netconn
* netconn_new_with_proto_and_callback(enum netconn_type t
,u16 proto
,void (*cb
)(struct netconn
*,enum netconn_evt
,u32
))
296 struct netconn
*conn
;
299 conn
= memp_malloc(MEMP_NETCONN
);
300 if(!conn
) return NULL
;
304 conn
->pcb
.tcp
= NULL
;
306 if(MQ_Init(&conn
->mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
307 memp_free(MEMP_NETCONN
,conn
);
310 if(LWP_SemInit(&conn
->sem
,0,1)==-1) {
311 MQ_Close(conn
->mbox
);
312 memp_free(MEMP_NETCONN
,conn
);
316 conn
->acceptmbox
= SYS_MBOX_NULL
;
317 conn
->recvmbox
= SYS_MBOX_NULL
;
318 conn
->state
= NETCONN_NONE
;
323 msg
= memp_malloc(MEMP_API_MSG
);
325 MQ_Close(conn
->mbox
);
326 memp_free(MEMP_NETCONN
,conn
);
330 msg
->type
= APIMSG_NEWCONN
;
331 msg
->msg
.msg
.bc
.port
= proto
;
332 msg
->msg
.conn
= conn
;
334 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
335 memp_free(MEMP_API_MSG
,msg
);
337 if(conn
->err
!=ERR_OK
) {
338 MQ_Close(conn
->mbox
);
339 memp_free(MEMP_NETCONN
,conn
);
345 static err_t
netconn_delete(struct netconn
*conn
)
352 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_delete(%p)\n", conn
));
354 if(!conn
) return ERR_OK
;
356 msg
= memp_malloc(MEMP_API_MSG
);
357 if(!msg
) return ERR_MEM
;
359 msg
->type
= APIMSG_DELCONN
;
360 msg
->msg
.conn
= conn
;
362 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
363 memp_free(MEMP_API_MSG
,msg
);
365 mbox
= conn
->recvmbox
;
366 conn
->recvmbox
= SYS_MBOX_NULL
;
367 if(mbox
!=SYS_MBOX_NULL
) {
368 while(MQ_Receive(mbox
,(mqmsg_t
)&mem
,MQ_MSG_NOBLOCK
)==TRUE
) {
370 if(conn
->type
==NETCONN_TCP
)
371 pbuf_free((struct pbuf
*)mem
);
373 netbuf_delete((struct netbuf
*)mem
);
379 mbox
= conn
->acceptmbox
;
380 conn
->acceptmbox
= SYS_MBOX_NULL
;
381 if(mbox
!=SYS_MBOX_NULL
) {
382 while(MQ_Receive(mbox
,(mqmsg_t
)&mem
,MQ_MSG_NOBLOCK
)==TRUE
) {
383 if(mem
!=NULL
) netconn_delete((struct netconn
*)mem
);
388 MQ_Close(conn
->mbox
);
389 conn
->mbox
= SYS_MBOX_NULL
;
391 LWP_SemDestroy(conn
->sem
);
392 conn
->sem
= SYS_SEM_NULL
;
394 memp_free(MEMP_NETCONN
,conn
);
398 static struct netconn
* netconn_accept(struct netconn
* conn
)
400 struct netconn
*newconn
;
402 if(conn
==NULL
) return NULL
;
404 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_accept(%p)\n", conn
));
405 MQ_Receive(conn
->acceptmbox
,(mqmsg_t
)&newconn
,MQ_MSG_BLOCK
);
407 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,0);
412 static err_t
netconn_peer(struct netconn
*conn
,struct ip_addr
*addr
,u16
*port
)
417 case NETCONN_UDPLITE
:
418 case NETCONN_UDPNOCHKSUM
:
420 if(conn
->pcb
.udp
==NULL
|| ((conn
->pcb
.udp
->flags
&UDP_FLAGS_CONNECTED
)==0))
422 *addr
= conn
->pcb
.udp
->remote_ip
;
423 *port
= conn
->pcb
.udp
->remote_port
;
426 if(conn
->pcb
.tcp
==NULL
)
428 *addr
= conn
->pcb
.tcp
->remote_ip
;
429 *port
= conn
->pcb
.tcp
->remote_port
;
432 return (conn
->err
= ERR_OK
);
435 static err_t
netconn_bind(struct netconn
*conn
,struct ip_addr
*addr
,u16 port
)
440 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_bind(%p)\n", conn
));
442 if(conn
==NULL
) return ERR_VAL
;
443 if(conn
->type
!=NETCONN_TCP
&& conn
->recvmbox
==SYS_MBOX_NULL
) {
444 if(MQ_Init(&conn
->recvmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return ERR_MEM
;
447 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
)
448 return (conn
->err
= ERR_MEM
);
450 msg
->type
= APIMSG_BIND
;
451 msg
->msg
.conn
= conn
;
452 msg
->msg
.msg
.bc
.ipaddr
= addr
;
453 msg
->msg
.msg
.bc
.port
= port
;
455 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
456 memp_free(MEMP_API_MSG
,msg
);
460 static err_t
netconn_listen(struct netconn
*conn
)
465 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_listen(%p)\n", conn
));
467 if(conn
==NULL
) return -1;
468 if(conn
->acceptmbox
==SYS_MBOX_NULL
) {
469 if(MQ_Init(&conn
->acceptmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return ERR_MEM
;
472 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return (conn
->err
= ERR_MEM
);
473 msg
->type
= APIMSG_LISTEN
;
474 msg
->msg
.conn
= conn
;
476 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
477 memp_free(MEMP_API_MSG
,msg
);
481 static struct netbuf
* netconn_recv(struct netconn
*conn
)
489 if(conn
==NULL
) return NULL
;
490 if(conn
->recvmbox
==SYS_MBOX_NULL
) {
491 conn
->err
= ERR_CONN
;
494 if(conn
->err
!=ERR_OK
) return NULL
;
496 if(conn
->type
==NETCONN_TCP
) {
497 if(conn
->pcb
.tcp
->state
==LISTEN
) {
498 conn
->err
= ERR_CONN
;
502 buf
= memp_malloc(MEMP_NETBUF
);
508 MQ_Receive(conn
->recvmbox
,(mqmsg_t
)&p
,MQ_MSG_BLOCK
);
511 conn
->recvavail
-= len
;
516 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,len
);
519 memp_free(MEMP_NETBUF
,buf
);
520 MQ_Close(conn
->recvmbox
);
521 conn
->recvmbox
= SYS_MBOX_NULL
;
528 buf
->fromaddr
= NULL
;
530 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) {
535 msg
->type
= APIMSG_RECV
;
536 msg
->msg
.conn
= conn
;
538 msg
->msg
.msg
.len
= len
;
540 msg
->msg
.msg
.len
= 1;
543 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
544 memp_free(MEMP_API_MSG
,msg
);
546 MQ_Receive(conn
->recvmbox
,(mqmsg_t
)&buf
,MQ_MSG_BLOCK
);
547 conn
->recvavail
-= buf
->p
->tot_len
;
549 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,buf
->p
->tot_len
);
552 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_recv: received %p (err %d)\n", (void *)buf
, conn
->err
));
556 static err_t
netconn_send(struct netconn
*conn
,struct netbuf
*buf
)
561 if(conn
==NULL
) return ERR_VAL
;
562 if(conn
->err
!=ERR_OK
) return conn
->err
;
563 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return (conn
->err
= ERR_MEM
);
565 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_send: sending %d bytes\n", buf
->p
->tot_len
));
566 msg
->type
= APIMSG_SEND
;
567 msg
->msg
.conn
= conn
;
568 msg
->msg
.msg
.p
= buf
->p
;
570 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
571 memp_free(MEMP_API_MSG
,msg
);
575 static err_t
netconn_write(struct netconn
*conn
,const void *dataptr
,u32 size
,u8 copy
)
582 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write(%d)\n",conn
->err
));
584 if(conn
==NULL
) return ERR_VAL
;
585 if(conn
->err
!=ERR_OK
) return conn
->err
;
587 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return (conn
->err
= ERR_MEM
);
589 msg
->type
= APIMSG_WRITE
;
590 msg
->msg
.conn
= conn
;
591 conn
->state
= NETCONN_WRITE
;
592 while(conn
->err
==ERR_OK
&& size
>0) {
593 msg
->msg
.msg
.w
.dataptr
= (void*)dataptr
;
594 msg
->msg
.msg
.w
.copy
= copy
;
595 if(conn
->type
==NETCONN_TCP
) {
596 while((snd_buf
=tcp_sndbuf(conn
->pcb
.tcp
))==0) {
597 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: tcp_sndbuf = 0,err = %d\n", conn
->err
));
598 LWP_SemWait(conn
->sem
);
599 if(conn
->err
!=ERR_OK
) goto ret
;
608 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write: writing %d bytes (%d)\n", len
, copy
));
609 msg
->msg
.msg
.w
.len
= len
;
611 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
612 if(conn
->err
==ERR_OK
) {
613 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write: %d bytes written\n",len
));
614 dataptr
= (void*)((char*)dataptr
+len
);
616 } else if(conn
->err
==ERR_MEM
) {
617 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: mem err\n"));
619 LWP_SemWait(conn
->sem
);
621 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: err = %d\n", conn
->err
));
626 memp_free(MEMP_API_MSG
,msg
);
627 conn
->state
= NETCONN_NONE
;
632 static err_t
netconn_connect(struct netconn
*conn
,struct ip_addr
*addr
,u16 port
)
637 if(conn
==NULL
) return -1;
638 if(conn
->recvmbox
==SYS_MBOX_NULL
) {
639 if(MQ_Init(&conn
->recvmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return ERR_MEM
;
642 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return ERR_MEM
;
644 msg
->type
= APIMSG_CONNECT
;
645 msg
->msg
.conn
= conn
;
646 msg
->msg
.msg
.bc
.ipaddr
= addr
;
647 msg
->msg
.msg
.bc
.port
= port
;
649 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
650 memp_free(MEMP_API_MSG
,msg
);
654 static err_t
netconn_disconnect(struct netconn
*conn
)
659 if(conn
==NULL
) return ERR_VAL
;
660 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return ERR_MEM
;
662 msg
->type
= APIMSG_DISCONNECT
;
663 msg
->msg
.conn
= conn
;
665 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
666 memp_free(MEMP_API_MSG
,msg
);
671 static u8_t
recv_raw(void *arg
,struct raw_pcb
*pcb
,struct pbuf
*p
,struct ip_addr
*addr
)
674 struct netconn
*conn
= (struct netconn
*)arg
;
678 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
679 if((buf
=memp_malloc(MEMP_NETBUF
))==NULL
) return 0;
684 buf
->fromaddr
= addr
;
685 buf
->fromport
= pcb
->protocol
;
687 conn
->recvavail
+= p
->tot_len
;
689 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,p
->tot_len
);
690 MQ_Send(conn
->recvmbox
,&buf
,MQ_MSG_BLOCK
);
695 static void recv_udp(void *arg
,struct udp_pcb
*pcb
,struct pbuf
*p
,struct ip_addr
*addr
,u16 port
)
698 struct netconn
*conn
= (struct netconn
*)arg
;
705 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
706 buf
= memp_malloc(MEMP_NETBUF
);
713 buf
->fromaddr
= addr
;
714 buf
->fromport
= port
;
716 conn
->recvavail
+= p
->tot_len
;
718 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,p
->tot_len
);
720 MQ_Send(conn
->recvmbox
,&buf
,MQ_MSG_BLOCK
);
724 static err_t
recv_tcp(void *arg
,struct tcp_pcb
*pcb
,struct pbuf
*p
,err_t err
)
727 struct netconn
*conn
= (struct netconn
*)arg
;
729 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: recv_tcp(%p,%p,%p,%d)\n",arg
,pcb
,p
,err
));
736 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
740 conn
->recvavail
+= len
;
744 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,len
);
746 MQ_Send(conn
->recvmbox
,&p
,MQ_MSG_BLOCK
);
751 static void err_tcp(void *arg
,err_t err
)
754 struct netconn
*conn
= (struct netconn
*)arg
;
756 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: err_tcp: %d\n",err
));
759 conn
->pcb
.tcp
= NULL
;
760 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
761 if(conn
->callback
) (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
762 MQ_Send(conn
->recvmbox
,&dummy
,MQ_MSG_BLOCK
);
764 if(conn
->mbox
!=SYS_MBOX_NULL
) {
765 MQ_Send(conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
767 if(conn
->acceptmbox
!=SYS_MBOX_NULL
) {
768 if(conn
->callback
) (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
769 MQ_Send(conn
->acceptmbox
,&dummy
,MQ_MSG_BLOCK
);
771 if(conn
->sem
!=SYS_SEM_NULL
) {
772 LWP_SemPost(conn
->sem
);
777 static err_t
poll_tcp(void *arg
,struct tcp_pcb
*pcb
)
779 struct netconn
*conn
= (struct netconn
*)arg
;
781 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: poll_tcp\n"));
782 if(conn
&& conn
->sem
!=SYS_SEM_NULL
&& (conn
->state
==NETCONN_WRITE
|| conn
->state
==NETCONN_CLOSE
))
783 LWP_SemPost(conn
->sem
);
788 static err_t
sent_tcp(void *arg
,struct tcp_pcb
*pcb
,u16 len
)
790 struct netconn
*conn
= (struct netconn
*)arg
;
792 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: sent_tcp: sent %d bytes\n",len
));
793 if(conn
&& conn
->sem
!=SYS_SEM_NULL
)
794 LWP_SemPost(conn
->sem
);
796 if(conn
&& conn
->callback
) {
797 if(tcp_sndbuf(conn
->pcb
.tcp
)>TCP_SNDLOWAT
)
798 (*conn
->callback
)(conn
,NETCONN_EVTSENDPLUS
,len
);
803 static void setuptcp(struct netconn
*conn
)
805 struct tcp_pcb
*pcb
= conn
->pcb
.tcp
;
808 tcp_recv(pcb
,recv_tcp
);
809 tcp_sent(pcb
,sent_tcp
);
810 tcp_poll(pcb
,poll_tcp
,4);
811 tcp_err(pcb
,err_tcp
);
814 static err_t
accept_func(void *arg
,struct tcp_pcb
*newpcb
,err_t err
)
817 struct netconn
*newconn
,*conn
= (struct netconn
*)arg
;
819 LWIP_DEBUGF(API_LIB_DEBUG
, ("accept_func: %p %p %d\n",arg
,newpcb
,err
));
821 mbox
= conn
->acceptmbox
;
822 newconn
= memp_malloc(MEMP_NETCONN
);
823 if(newconn
==NULL
) return ERR_MEM
;
825 if(MQ_Init(&newconn
->recvmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
826 memp_free(MEMP_NETCONN
,newconn
);
830 if(MQ_Init(&newconn
->mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
831 MQ_Close(newconn
->recvmbox
);
832 memp_free(MEMP_NETCONN
,newconn
);
836 if(LWP_SemInit(&newconn
->sem
,0,1)==-1) {
837 MQ_Close(newconn
->recvmbox
);
838 MQ_Close(newconn
->mbox
);
839 memp_free(MEMP_NETCONN
,newconn
);
843 newconn
->type
= NETCONN_TCP
;
844 newconn
->pcb
.tcp
= newpcb
;
847 newconn
->acceptmbox
= SYS_MBOX_NULL
;
851 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
853 newconn
->callback
= conn
->callback
;
854 newconn
->socket
= -1;
855 newconn
->recvavail
= 0;
857 MQ_Send(mbox
,&newconn
,MQ_MSG_BLOCK
);
861 static void do_newconn(struct apimsg_msg
*msg
)
865 if(msg
->conn
->pcb
.tcp
) {
866 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
870 msg
->conn
->err
= ERR_OK
;
871 switch(msg
->conn
->type
) {
873 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
874 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
876 case NETCONN_UDPLITE
:
877 msg
->conn
->pcb
.udp
= udp_new();
878 if(!msg
->conn
->pcb
.udp
) {
879 msg
->conn
->err
= ERR_MEM
;
882 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
883 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
885 case NETCONN_UDPNOCHKSUM
:
886 msg
->conn
->pcb
.udp
= udp_new();
887 if(!msg
->conn
->pcb
.udp
) {
888 msg
->conn
->err
= ERR_MEM
;
891 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
892 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
895 msg
->conn
->pcb
.udp
= udp_new();
896 if(!msg
->conn
->pcb
.udp
) {
897 msg
->conn
->err
= ERR_MEM
;
900 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
903 msg
->conn
->pcb
.tcp
= tcp_new();
904 if(!msg
->conn
->pcb
.tcp
) {
905 msg
->conn
->err
= ERR_MEM
;
913 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
916 static void do_delconn(struct apimsg_msg
*msg
)
920 if(msg
->conn
->pcb
.tcp
) {
921 switch(msg
->conn
->type
) {
923 raw_remove(msg
->conn
->pcb
.raw
);
925 case NETCONN_UDPLITE
:
926 case NETCONN_UDPNOCHKSUM
:
928 msg
->conn
->pcb
.udp
->recv_arg
= NULL
;
929 udp_remove(msg
->conn
->pcb
.udp
);
932 if(msg
->conn
->pcb
.tcp
->state
==LISTEN
) {
933 tcp_arg(msg
->conn
->pcb
.tcp
,NULL
);
934 tcp_accept(msg
->conn
->pcb
.tcp
,NULL
);
935 tcp_close(msg
->conn
->pcb
.tcp
);
937 tcp_arg(msg
->conn
->pcb
.tcp
,NULL
);
938 tcp_sent(msg
->conn
->pcb
.tcp
,NULL
);
939 tcp_recv(msg
->conn
->pcb
.tcp
,NULL
);
940 tcp_poll(msg
->conn
->pcb
.tcp
,NULL
,0);
941 tcp_err(msg
->conn
->pcb
.tcp
,NULL
);
942 if(tcp_close(msg
->conn
->pcb
.tcp
)!=ERR_OK
)
943 tcp_abort(msg
->conn
->pcb
.tcp
);
950 if(msg
->conn
->callback
) {
951 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTRCVPLUS
,0);
952 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTSENDPLUS
,0);
954 if(msg
->conn
->mbox
!=SYS_MBOX_NULL
)
955 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
958 static void do_bind(struct apimsg_msg
*msg
)
962 if(msg
->conn
->pcb
.tcp
==NULL
) {
963 switch(msg
->conn
->type
) {
965 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
966 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
968 case NETCONN_UDPLITE
:
969 msg
->conn
->pcb
.udp
= udp_new();
970 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
971 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
973 case NETCONN_UDPNOCHKSUM
:
974 msg
->conn
->pcb
.udp
= udp_new();
975 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
976 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
979 msg
->conn
->pcb
.udp
= udp_new();
980 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
983 msg
->conn
->pcb
.tcp
= tcp_new();
990 switch(msg
->conn
->type
) {
992 msg
->conn
->err
= raw_bind(msg
->conn
->pcb
.raw
,msg
->msg
.bc
.ipaddr
);
994 case NETCONN_UDPLITE
:
995 case NETCONN_UDPNOCHKSUM
:
997 msg
->conn
->err
= udp_bind(msg
->conn
->pcb
.udp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
1000 msg
->conn
->err
= tcp_bind(msg
->conn
->pcb
.tcp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
1005 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1008 static err_t
do_connected(void *arg
,struct tcp_pcb
*pcb
,err_t err
)
1011 struct netconn
*conn
= (struct netconn
*)arg
;
1013 if(!conn
) return ERR_VAL
;
1016 if(conn
->type
==NETCONN_TCP
&& err
==ERR_OK
) setuptcp(conn
);
1018 MQ_Send(conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1022 static void do_connect(struct apimsg_msg
*msg
)
1026 if(!msg
->conn
->pcb
.tcp
) {
1027 switch(msg
->conn
->type
) {
1029 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
1030 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
1032 case NETCONN_UDPLITE
:
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
);
1039 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
1040 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1042 case NETCONN_UDPNOCHKSUM
:
1043 msg
->conn
->pcb
.udp
= udp_new();
1044 if(!msg
->conn
->pcb
.udp
) {
1045 msg
->conn
->err
= ERR_MEM
;
1046 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1049 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
1050 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1053 msg
->conn
->pcb
.udp
= udp_new();
1054 if(!msg
->conn
->pcb
.udp
) {
1055 msg
->conn
->err
= ERR_MEM
;
1056 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1059 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1062 msg
->conn
->pcb
.tcp
= tcp_new();
1063 if(!msg
->conn
->pcb
.tcp
) {
1064 msg
->conn
->err
= ERR_MEM
;
1065 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1073 switch(msg
->conn
->type
) {
1075 raw_connect(msg
->conn
->pcb
.raw
,msg
->msg
.bc
.ipaddr
);
1076 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1078 case NETCONN_UDPLITE
:
1079 case NETCONN_UDPNOCHKSUM
:
1081 udp_connect(msg
->conn
->pcb
.udp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
1082 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1085 setuptcp(msg
->conn
);
1086 tcp_connect(msg
->conn
->pcb
.tcp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
,do_connected
);
1093 static void do_disconnect(struct apimsg_msg
*msg
)
1097 switch(msg
->conn
->type
) {
1100 case NETCONN_UDPLITE
:
1101 case NETCONN_UDPNOCHKSUM
:
1103 udp_disconnect(msg
->conn
->pcb
.udp
);
1108 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1111 static void do_listen(struct apimsg_msg
*msg
)
1115 if(msg
->conn
->pcb
.tcp
!=NULL
) {
1116 switch(msg
->conn
->type
) {
1118 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: listen RAW: cannot listen for RAW.\n"));
1120 case NETCONN_UDPLITE
:
1121 case NETCONN_UDPNOCHKSUM
:
1123 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: listen UDP: cannot listen for UDP.\n"));
1126 msg
->conn
->pcb
.tcp
= tcp_listen(msg
->conn
->pcb
.tcp
);
1127 if(msg
->conn
->pcb
.tcp
==NULL
)
1128 msg
->conn
->err
= ERR_MEM
;
1130 if(msg
->conn
->acceptmbox
==SYS_MBOX_NULL
) {
1131 if(MQ_Init(&msg
->conn
->acceptmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
1132 msg
->conn
->err
= ERR_MEM
;
1136 tcp_arg(msg
->conn
->pcb
.tcp
,msg
->conn
);
1137 tcp_accept(msg
->conn
->pcb
.tcp
,accept_func
);
1144 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1147 static void do_accept(struct apimsg_msg
*msg
)
1149 if(msg
->conn
->pcb
.tcp
) {
1150 switch(msg
->conn
->type
) {
1152 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: accept RAW: cannot accept for RAW.\n"));
1154 case NETCONN_UDPLITE
:
1155 case NETCONN_UDPNOCHKSUM
:
1157 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: accept UDP: cannot accept for UDP.\n"));
1165 static void do_send(struct apimsg_msg
*msg
)
1169 if(msg
->conn
->pcb
.tcp
) {
1170 switch(msg
->conn
->type
) {
1172 raw_send(msg
->conn
->pcb
.raw
,msg
->msg
.p
);
1174 case NETCONN_UDPLITE
:
1175 case NETCONN_UDPNOCHKSUM
:
1177 udp_send(msg
->conn
->pcb
.udp
,msg
->msg
.p
);
1183 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1186 static void do_recv(struct apimsg_msg
*msg
)
1190 if(msg
->conn
->pcb
.tcp
&& msg
->conn
->type
==NETCONN_TCP
) {
1191 tcp_recved(msg
->conn
->pcb
.tcp
,msg
->msg
.len
);
1193 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1196 static void do_write(struct apimsg_msg
*msg
)
1201 if(msg
->conn
->pcb
.tcp
) {
1202 switch(msg
->conn
->type
) {
1204 case NETCONN_UDPLITE
:
1205 case NETCONN_UDPNOCHKSUM
:
1207 msg
->conn
->err
= ERR_VAL
;
1210 err
= tcp_write(msg
->conn
->pcb
.tcp
,msg
->msg
.w
.dataptr
,msg
->msg
.w
.len
,msg
->msg
.w
.copy
);
1211 if(err
==ERR_OK
&& (!msg
->conn
->pcb
.tcp
->unacked
|| (msg
->conn
->pcb
.tcp
->flags
&TF_NODELAY
)
1212 || msg
->conn
->pcb
.tcp
->snd_queuelen
>1)) {
1213 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: TCP write: tcp_output.\n"));
1214 tcp_output(msg
->conn
->pcb
.tcp
);
1216 msg
->conn
->err
= err
;
1217 if(msg
->conn
->callback
) {
1219 if(tcp_sndbuf(msg
->conn
->pcb
.tcp
)<=TCP_SNDLOWAT
)
1220 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTSENDMINUS
,msg
->msg
.w
.len
);
1228 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1231 static void do_close(struct apimsg_msg
*msg
)
1236 if(msg
->conn
->pcb
.tcp
) {
1237 switch(msg
->conn
->type
) {
1239 case NETCONN_UDPLITE
:
1240 case NETCONN_UDPNOCHKSUM
:
1244 if(msg
->conn
->pcb
.tcp
->state
==LISTEN
)
1245 err
= tcp_close(msg
->conn
->pcb
.tcp
);
1246 else if(msg
->conn
->pcb
.tcp
->state
==CLOSE_WAIT
)
1247 err
= tcp_output(msg
->conn
->pcb
.tcp
);
1248 msg
->conn
->err
= err
;
1254 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1257 static void apimsg_input(struct api_msg
*msg
)
1259 decode
[msg
->type
](&(msg
->msg
));
1262 static void apimsg_post(struct api_msg
*msg
)
1267 /* tcpip thread part */
1268 static err_t
net_input(struct pbuf
*p
,struct netif
*inp
)
1270 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1272 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_input: %p %p\n", p
,inp
));
1275 LWIP_ERROR(("net_input: msg out of memory.\n"));
1280 msg
->type
= NETMSG_INPUT
;
1282 msg
->msg
.inp
.net
= inp
;
1283 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1287 static void net_apimsg(struct api_msg
*apimsg
)
1289 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1291 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_apimsg: %p\n",apimsg
));
1293 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1294 memp_free(MEMP_API_MSG
,apimsg
);
1298 msg
->type
= NETMSG_API
;
1299 msg
->msg
.apimsg
= apimsg
;
1300 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1303 static err_t
net_callback(void (*f
)(void *),void *ctx
)
1305 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1307 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_callback: %p(%p)\n", f
,ctx
));
1310 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1314 msg
->type
= NETMSG_CALLBACK
;
1316 msg
->msg
.cb
.ctx
= ctx
;
1317 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1321 static void* net_thread(void *arg
)
1323 struct net_msg
*msg
;
1325 sys_sem sem
= (sys_sem
)arg
;
1333 tb
.tv_sec
= ARP_TMR_INTERVAL
/TB_MSPERSEC
;
1335 net_arp_ticks
= __lwp_wd_calc_ticks(&tb
);
1336 __lwp_wd_initialize(&arp_time_cntrl
,__arp_timer
,ARP_TIMER_ID
,NULL
);
1337 __lwp_wd_insert_ticks(&arp_time_cntrl
,net_arp_ticks
);
1340 tb
.tv_nsec
= TCP_TMR_INTERVAL
*TB_NSPERMS
;
1341 net_tcp_ticks
= __lwp_wd_calc_ticks(&tb
);
1342 __lwp_wd_initialize(&tcp_timer_cntrl
,__tcp_timer
,TCP_TIMER_ID
,NULL
);
1346 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread(%p)\n",arg
));
1349 MQ_Receive(netthread_mbox
,(mqmsg_t
)&msg
,MQ_MSG_BLOCK
);
1352 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: API message %p\n", (void *)msg
));
1353 apimsg_input(msg
->msg
.apimsg
);
1356 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: IP packet %p\n", (void *)msg
));
1357 bba_process(msg
->msg
.inp
.p
,msg
->msg
.inp
.net
);
1359 case NETMSG_CALLBACK
:
1360 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: CALLBACK %p\n", (void *)msg
));
1361 msg
->msg
.cb
.f(msg
->msg
.cb
.ctx
);
1366 memp_free(MEMP_TCPIP_MSG
,msg
);
1371 static s32
alloc_socket(struct netconn
*conn
)
1375 LWP_SemWait(netsocket_sem
);
1377 for(i
=0;i
<NUM_SOCKETS
;i
++) {
1378 if(!sockets
[i
].conn
) {
1379 sockets
[i
].conn
= conn
;
1380 sockets
[i
].lastdata
= NULL
;
1381 sockets
[i
].lastoffset
= 0;
1382 sockets
[i
].rcvevt
= 0;
1383 sockets
[i
].sendevt
= 1;
1384 sockets
[i
].flags
= 0;
1386 LWP_SemPost(netsocket_sem
);
1391 LWP_SemPost(netsocket_sem
);
1395 static struct netsocket
* get_socket(s32 s
)
1397 struct netsocket
*sock
;
1398 if(s
<0 || s
>NUM_SOCKETS
) {
1399 LWIP_DEBUGF(SOCKETS_DEBUG
, ("get_socket(%d): invalid\n", s
));
1404 LWIP_DEBUGF(SOCKETS_DEBUG
, ("get_socket(%d): no active\n", s
));
1411 static void evt_callback(struct netconn
*conn
,enum netconn_evt evt
,u32 len
)
1414 struct netsocket
*sock
;
1415 struct netselect_cb
*scb
;
1420 if(evt
==NETCONN_EVTRCVPLUS
)
1424 sock
= get_socket(s
);
1429 LWP_SemWait(sockselect_sem
);
1431 case NETCONN_EVTRCVPLUS
:
1434 case NETCONN_EVTRCVMINUS
:
1437 case NETCONN_EVTSENDPLUS
:
1440 case NETCONN_EVTSENDMINUS
:
1444 LWP_SemPost(sockselect_sem
);
1447 LWP_SemWait(sockselect_sem
);
1448 for(scb
= selectcb_list
;scb
;scb
= scb
->next
) {
1449 if(scb
->signaled
==0) {
1450 if(scb
->readset
&& FD_ISSET(s
,scb
->readset
))
1451 if(sock
->rcvevt
) break;
1452 if(scb
->writeset
&& FD_ISSET(s
,scb
->writeset
))
1453 if(sock
->sendevt
) break;
1458 LWP_SemPost(sockselect_sem
);
1459 LWP_MutexLock(scb
->cond_lck
);
1460 LWP_CondSignal(scb
->cond
);
1461 LWP_MutexUnlock(scb
->cond_lck
);
1463 LWP_SemPost(sockselect_sem
);
1470 extern const devoptab_t dotab_stdnet
;
1472 s32
if_configex(struct in_addr
*local_ip
,struct in_addr
*netmask
,struct in_addr
*gateway
,boolean use_dhcp
)
1475 struct ip_addr loc_ip
, mask
, gw
;
1480 if(g_netinitiated
) return 0;
1483 AddDevice(&dotab_stdnet
);
1494 // init tcpip thread message box
1495 if(MQ_Init(&netthread_mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return -1;
1497 // create & setup interface
1503 if(use_dhcp
==FALSE
) {
1504 if( !gateway
|| gateway
->s_addr
==0
1505 || !local_ip
|| local_ip
->s_addr
==0
1506 || !netmask
|| netmask
->s_addr
==0 ) return -1;
1507 loc_ip
.addr
= local_ip
->s_addr
;
1508 mask
.addr
= netmask
->s_addr
;
1509 gw
.addr
= gateway
->s_addr
;
1511 hbba
= bba_create(&g_hNetIF
);
1512 pnet
= netif_add(&g_hNetIF
,&loc_ip
, &mask
, &gw
, hbba
, bba_init
, net_input
);
1515 netif_set_default(pnet
);
1517 if(use_dhcp
==TRUE
) {
1518 //setup coarse timer
1519 tb
.tv_sec
= DHCP_COARSE_TIMER_SECS
;
1521 net_dhcpcoarse_ticks
= __lwp_wd_calc_ticks(&tb
);
1522 __lwp_wd_initialize(&dhcp_coarsetimer_cntrl
,__dhcpcoarse_timer
,DHCPCOARSE_TIMER_ID
,NULL
);
1523 __lwp_wd_insert_ticks(&dhcp_coarsetimer_cntrl
,net_dhcpcoarse_ticks
);
1527 tb
.tv_nsec
= DHCP_FINE_TIMER_MSECS
*TB_NSPERMS
;
1528 net_dhcpfine_ticks
= __lwp_wd_calc_ticks(&tb
);
1529 __lwp_wd_initialize(&dhcp_finetimer_cntrl
,__dhcpfine_timer
,DHCPFINE_TIMER_ID
,NULL
);
1530 __lwp_wd_insert_ticks(&dhcp_finetimer_cntrl
,net_dhcpfine_ticks
);
1532 //now start dhcp client
1539 // setup loopinterface
1540 IP4_ADDR(&loc_ip
, 127,0,0,1);
1541 IP4_ADDR(&mask
, 255,0,0,0);
1542 IP4_ADDR(&gw
, 127,0,0,1);
1543 pnet
= netif_add(&g_hLoopIF
,&loc_ip
,&mask
,&gw
,NULL
,loopif_init
,net_input
);
1545 //last and least start the tcpip layer
1548 if ( ret
== 0 && use_dhcp
== TRUE
) {
1551 // wait for dhcp to bind
1552 while ( g_hNetIF
.dhcp
->state
!= DHCP_BOUND
&& retries
< 20 ) {
1557 if ( retries
< 20 ) {
1558 //copy back network addresses
1559 if ( local_ip
!= NULL
) local_ip
->s_addr
= g_hNetIF
.ip_addr
.addr
;
1560 if ( gateway
!= NULL
) gateway
->s_addr
= g_hNetIF
.gw
.addr
;
1561 if ( netmask
!= NULL
) netmask
->s_addr
= g_hNetIF
.netmask
.addr
;
1570 s32
if_config(char *local_ip
, char *netmask
, char *gateway
,boolean use_dhcp
)
1573 struct in_addr loc_ip
, mask
, gw
;
1579 if ( local_ip
!= NULL
) loc_ip
.s_addr
= inet_addr(local_ip
);
1580 if ( netmask
!= NULL
) mask
.s_addr
= inet_addr(netmask
);
1581 if ( gateway
!= NULL
) gw
.s_addr
= inet_addr(gateway
);
1583 ret
= if_configex( &loc_ip
, &mask
, &gw
, use_dhcp
);
1585 if (ret
<0) return ret
;
1587 if ( use_dhcp
== TRUE
) {
1588 //copy back network addresses
1589 if ( local_ip
!= NULL
) strcpy(local_ip
, inet_ntoa( loc_ip
));
1590 if ( netmask
!= NULL
) strcpy(netmask
, inet_ntoa( mask
));
1591 if ( gateway
!= NULL
) strcpy(gateway
, inet_ntoa( gw
));
1601 if(tcpiplayer_inited
) return 1;
1603 if(LWP_SemInit(&netsocket_sem
,1,1)==-1) return -1;
1604 if(LWP_SemInit(&sockselect_sem
,1,1)==-1) {
1605 LWP_SemDestroy(netsocket_sem
);
1608 if(LWP_SemInit(&sem
,0,1)==-1) {
1609 LWP_SemDestroy(netsocket_sem
);
1610 LWP_SemDestroy(sockselect_sem
);
1614 if(LWP_CreateThread(&hnet_thread
,net_thread
,(void*)sem
,netthread_stack
,STACKSIZE
,220)==-1) {
1615 LWP_SemDestroy(netsocket_sem
);
1616 LWP_SemDestroy(sockselect_sem
);
1617 LWP_SemDestroy(sem
);
1621 LWP_SemDestroy(sem
);
1623 tcpiplayer_inited
= 1;
1628 s32
net_shutdown(s32 s
,u32 how
)
1633 s32
net_fcntl(s32 s
, u32 cmd
, u32 flags
)
1638 s32
net_socket(u32 domain
,u32 type
,u32 protocol
)
1641 struct netconn
*conn
;
1645 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_RAW)\n"));
1646 conn
= netconn_new_with_proto_and_callback(NETCONN_RAW
,protocol
,evt_callback
);
1649 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_DGRAM)\n"));
1650 conn
= netconn_new_with_callback(NETCONN_UDP
,evt_callback
);
1653 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_STREAM)\n"));
1654 conn
= netconn_new_with_callback(NETCONN_TCP
,evt_callback
);
1659 if(!conn
) return -1;
1661 i
= alloc_socket(conn
);
1663 netconn_delete(conn
);
1671 s32
net_accept(s32 s
,struct sockaddr
*addr
,socklen_t
*addrlen
)
1673 struct netsocket
*sock
;
1674 struct netconn
*newconn
;
1675 struct ip_addr naddr
= {0};
1678 struct sockaddr_in sin
;
1680 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_accept(%d)\n", s
));
1682 sock
= get_socket(s
);
1683 if(!sock
) return -1;
1685 newconn
= netconn_accept(sock
->conn
);
1686 netconn_peer(newconn
,&naddr
,&port
);
1688 memset(&sin
,0,sizeof(sin
));
1689 sin
.sin_family
= AF_INET
;
1690 sin
.sin_port
= htons(port
);
1691 sin
.sin_addr
.s_addr
= naddr
.addr
;
1693 if(*addrlen
>sizeof(sin
))
1694 *addrlen
= sizeof(sin
);
1695 memcpy(addr
,&sin
,*addrlen
);
1697 newsock
= alloc_socket(newconn
);
1699 netconn_delete(newconn
);
1703 newconn
->callback
= evt_callback
;
1704 sock
= get_socket(newsock
);
1706 LWP_SemWait(netsocket_sem
);
1707 sock
->rcvevt
+= -1 - newconn
->socket
;
1708 newconn
->socket
= newsock
;
1709 LWP_SemPost(netsocket_sem
);
1714 s32
net_bind(s32 s
,struct sockaddr
*name
,socklen_t namelen
)
1716 struct netsocket
*sock
;
1717 struct ip_addr loc_addr
;
1721 sock
= get_socket(s
);
1722 if(!sock
) return -1;
1724 loc_addr
.addr
= ((struct sockaddr_in
*)name
)->sin_addr
.s_addr
;
1725 loc_port
= ((struct sockaddr_in
*)name
)->sin_port
;
1727 err
= netconn_bind(sock
->conn
,&loc_addr
,ntohs(loc_port
));
1728 if(err
!=ERR_OK
) return -1;
1733 s32
net_listen(s32 s
,u32 backlog
)
1735 struct netsocket
*sock
;
1738 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_listen(%d, backlog=%d)\n", s
, backlog
));
1739 sock
= get_socket(s
);
1740 if(!sock
) return -1;
1742 err
= netconn_listen(sock
->conn
);
1744 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_listen(%d) failed, err=%d\n", s
, err
));
1750 s32
net_recvfrom(s32 s
,void *mem
,s32 len
,u32 flags
,struct sockaddr
*from
,socklen_t
*fromlen
)
1752 struct netsocket
*sock
;
1755 struct ip_addr
*addr
;
1758 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d, %p, %d, 0x%x, ..)\n", s
, mem
, len
, flags
));
1759 if(mem
==NULL
|| len
<=0) return -1;
1761 sock
= get_socket(s
);
1762 if(!sock
) return -1;
1765 buf
= sock
->lastdata
;
1767 if(((flags
&MSG_DONTWAIT
) || (sock
->flags
&O_NONBLOCK
)) && !sock
->rcvevt
) {
1768 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): returning EWOULDBLOCK\n", s
));
1771 buf
= netconn_recv(sock
->conn
);
1773 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): buf == NULL!\n", s
));
1778 buflen
= netbuf_len(buf
);
1779 buflen
-= sock
->lastoffset
;
1787 netbuf_copypartial(buf
,mem
,copylen
,sock
->lastoffset
);
1789 if(from
&& fromlen
) {
1790 struct sockaddr_in sin
;
1792 addr
= netbuf_fromaddr(buf
);
1793 port
= netbuf_fromport(buf
);
1795 memset(&sin
,0,sizeof(sin
));
1796 sin
.sin_family
= AF_INET
;
1797 sin
.sin_port
= htons(port
);
1798 sin
.sin_addr
.s_addr
= addr
->addr
;
1800 if(*fromlen
>sizeof(sin
))
1801 *fromlen
= sizeof(sin
);
1803 memcpy(from
,&sin
,*fromlen
);
1805 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): addr=", s
));
1806 ip_addr_debug_print(SOCKETS_DEBUG
, addr
);
1807 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u len=%u\n", port
, copylen
));
1809 if(netconn_type(sock
->conn
)==NETCONN_TCP
&& (buflen
-copylen
)>0) {
1810 sock
->lastdata
= buf
;
1811 sock
->lastoffset
+= copylen
;
1813 sock
->lastdata
= NULL
;
1814 sock
->lastoffset
= 0;
1820 s32
net_read(s32 s
,void *mem
,s32 len
)
1822 return net_recvfrom(s
,mem
,len
,0,NULL
,NULL
);
1825 s32
net_recv(s32 s
,void *mem
,s32 len
,u32 flags
)
1827 return net_recvfrom(s
,mem
,len
,flags
,NULL
,NULL
);
1830 s32
net_sendto(s32 s
,const void *data
,s32 len
,u32 flags
,struct sockaddr
*to
,socklen_t tolen
)
1832 struct netsocket
*sock
;
1833 struct ip_addr remote_addr
, addr
;
1834 u16_t remote_port
, port
= 0;
1837 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_sendto(%d, data=%p, size=%d, flags=0x%x)\n", s
, data
, len
, flags
));
1838 if(data
==NULL
|| len
<=0) return -1;
1840 sock
= get_socket(s
);
1841 if (!sock
) return -1;
1843 /* get the peer if currently connected */
1844 connected
= (netconn_peer(sock
->conn
, &addr
, &port
) == ERR_OK
);
1846 remote_addr
.addr
= ((struct sockaddr_in
*)to
)->sin_addr
.s_addr
;
1847 remote_port
= ((struct sockaddr_in
*)to
)->sin_port
;
1849 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_sendto(%d, data=%p, size=%d, flags=0x%x to=", s
, data
, len
, flags
));
1850 ip_addr_debug_print(SOCKETS_DEBUG
, &remote_addr
);
1851 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u\n", ntohs(remote_port
)));
1853 netconn_connect(sock
->conn
, &remote_addr
, ntohs(remote_port
));
1855 ret
= net_send(s
, data
, len
, flags
);
1857 /* reset the remote address and port number
1858 of the connection */
1860 netconn_connect(sock
->conn
, &addr
, port
);
1862 netconn_disconnect(sock
->conn
);
1866 s32
net_send(s32 s
,const void *data
,s32 len
,u32 flags
)
1868 struct netsocket
*sock
;
1872 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d, data=%p, size=%d, flags=0x%x)\n", s
, data
, len
, flags
));
1873 if(data
==NULL
|| len
<=0) return -1;
1875 sock
= get_socket(s
);
1876 if(!sock
) return -1;
1878 switch(netconn_type(sock
->conn
)) {
1881 case NETCONN_UDPLITE
:
1882 case NETCONN_UDPNOCHKSUM
:
1885 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) ENOBUFS\n", s
));
1888 netbuf_ref(buf
,data
,len
);
1889 err
= netconn_send(sock
->conn
,buf
);
1893 err
= netconn_write(sock
->conn
,data
,len
,NETCONN_COPY
);
1900 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) err=%d\n", s
, err
));
1904 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) ok size=%d\n", s
, len
));
1908 s32
net_write(s32 s
,const void *data
,s32 size
)
1910 return net_send(s
,data
,size
,0);
1913 s32
net_connect(s32 s
,struct sockaddr
*name
,socklen_t namelen
)
1915 struct netsocket
*sock
;
1918 sock
= get_socket(s
);
1919 if(!sock
) return -1;
1921 if(((struct sockaddr_in
*)name
)->sin_family
==AF_UNSPEC
) {
1922 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d, AF_UNSPEC)\n", s
));
1923 err
= netconn_disconnect(sock
->conn
);
1925 struct ip_addr remote_addr
;
1928 remote_addr
.addr
= ((struct sockaddr_in
*)name
)->sin_addr
.s_addr
;
1929 remote_port
= ((struct sockaddr_in
*)name
)->sin_port
;
1931 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d, addr=", s
));
1932 ip_addr_debug_print(SOCKETS_DEBUG
, &remote_addr
);
1933 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u)\n", ntohs(remote_port
)));
1935 err
= netconn_connect(sock
->conn
,&remote_addr
,ntohs(remote_port
));
1938 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d) failed, err=%d\n", s
, err
));
1942 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d) succeeded\n", s
));
1946 s32
net_close(s32 s
)
1948 struct netsocket
*sock
;
1950 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_close(%d)\n", s
));
1952 LWP_SemWait(netsocket_sem
);
1954 sock
= get_socket(s
);
1956 LWP_SemPost(netsocket_sem
);
1960 netconn_delete(sock
->conn
);
1961 if(sock
->lastdata
) netbuf_delete(sock
->lastdata
);
1963 sock
->lastdata
= NULL
;
1964 sock
->lastoffset
= 0;
1967 LWP_SemPost(netsocket_sem
);
1971 static s32
net_selscan(s32 maxfdp1
,fd_set
*readset
,fd_set
*writeset
,fd_set
*exceptset
)
1974 fd_set lreadset
,lwriteset
,lexceptset
;
1975 struct netsocket
*sock
;
1978 FD_ZERO(&lwriteset
);
1979 FD_ZERO(&lexceptset
);
1981 for(i
=0;i
<maxfdp1
;i
++) {
1982 if(FD_ISSET(i
,readset
)) {
1983 sock
= get_socket(i
);
1984 if(sock
&& (sock
->lastdata
|| sock
->rcvevt
)) {
1985 FD_SET(i
,&lreadset
);
1989 if(FD_ISSET(i
,writeset
)) {
1990 sock
= get_socket(i
);
1991 if(sock
&& sock
->sendevt
) {
1992 FD_SET(i
,&lwriteset
);
1997 *readset
= lreadset
;
1998 *writeset
= lwriteset
;
2004 s32
net_select(s32 maxfdp1
,fd_set
*readset
,fd_set
*writeset
,fd_set
*exceptset
,struct timeval
*timeout
)
2007 fd_set lreadset
,lwriteset
,lexceptset
;
2008 struct timespec tb
,*p_tb
;
2009 struct netselect_cb sel_cb
;
2010 struct netselect_cb
*psel_cb
;
2013 sel_cb
.readset
= readset
;
2014 sel_cb
.writeset
= writeset
;
2015 sel_cb
.exceptset
= exceptset
;
2016 sel_cb
.signaled
= 0;
2018 LWP_SemWait(sockselect_sem
);
2021 lreadset
= *readset
;
2026 lwriteset
= *writeset
;
2028 FD_ZERO(&lwriteset
);
2031 lexceptset
= *exceptset
;
2033 FD_ZERO(&lexceptset
);
2035 nready
= net_selscan(maxfdp1
,&lreadset
,&lwriteset
,&lexceptset
);
2037 if(timeout
&& timeout
->tv_sec
==0 && timeout
->tv_usec
==0) {
2038 LWP_SemPost(sockselect_sem
);
2048 LWP_MutexInit(&sel_cb
.cond_lck
,FALSE
);
2049 LWP_CondInit(&sel_cb
.cond
);
2050 sel_cb
.next
= selectcb_list
;
2051 selectcb_list
= &sel_cb
;
2053 LWP_SemPost(sockselect_sem
);
2057 tb
.tv_sec
= timeout
->tv_sec
;
2058 tb
.tv_nsec
= (timeout
->tv_usec
+500)*TB_NSPERUS
;
2062 LWP_MutexLock(sel_cb
.cond_lck
);
2063 i
= LWP_CondTimedWait(sel_cb
.cond
,sel_cb
.cond_lck
,p_tb
);
2064 LWP_MutexUnlock(sel_cb
.cond_lck
);
2066 LWP_SemWait(sockselect_sem
);
2067 if(selectcb_list
==&sel_cb
)
2068 selectcb_list
= sel_cb
.next
;
2070 for(psel_cb
= selectcb_list
;psel_cb
;psel_cb
= psel_cb
->next
) {
2071 if(psel_cb
->next
==&sel_cb
) {
2072 psel_cb
->next
= sel_cb
.next
;
2077 LWP_CondDestroy(sel_cb
.cond
);
2078 LWP_MutexDestroy(sel_cb
.cond_lck
);
2080 LWP_SemPost(sockselect_sem
);
2093 lreadset
= *readset
;
2098 lwriteset
= *writeset
;
2100 FD_ZERO(&lwriteset
);
2103 lexceptset
= *exceptset
;
2105 FD_ZERO(&lexceptset
);
2107 nready
= net_selscan(maxfdp1
,&lreadset
,&lwriteset
,&lexceptset
);
2109 LWP_SemPost(sockselect_sem
);
2112 *readset
= lreadset
;
2114 *writeset
= lwriteset
;
2116 *exceptset
= lexceptset
;
2121 s32
net_setsockopt(s32 s
,u32 level
,u32 optname
,const void *optval
,socklen_t optlen
)
2124 struct netsocket
*sock
;
2126 sock
= get_socket(s
);
2127 if(sock
==NULL
) return -1;
2128 if(optval
==NULL
) return -1;
2138 if(optlen
<sizeof(u32
)) err
= EINVAL
;
2141 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2152 if(optlen
<sizeof(u32
)) err
= EINVAL
;
2155 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2163 if(optlen
<sizeof(u32
)) {
2167 if(sock
->conn
->type
!=NETCONN_TCP
) return 0;
2174 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2181 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s
, level
, optname
));
2184 if(err
!=0) return -1;
2195 sock
->conn
->pcb
.tcp
->so_options
|= optname
;
2197 sock
->conn
->pcb
.tcp
->so_options
&= ~optname
;
2198 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s
, optname
, (*(u32
*)optval
?"on":"off")));
2208 sock
->conn
->pcb
.tcp
->ttl
= (u8
)(*(u32
*)optval
);
2209 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s
, sock
->conn
->pcb
.tcp
->ttl
));
2212 sock
->conn
->pcb
.tcp
->tos
= (u8
)(*(u32
*)optval
);
2213 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s
, sock
->conn
->pcb
.tcp
->tos
));
2224 sock
->conn
->pcb
.tcp
->flags
|= TF_NODELAY
;
2226 sock
->conn
->pcb
.tcp
->flags
&= ~TF_NODELAY
;
2227 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s
, (*(u32
*)optval
)?"on":"off") );
2230 sock
->conn
->pcb
.tcp
->keepalive
= (u32
)(*(u32
*)optval
);
2231 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %u\n", s
, sock
->conn
->pcb
.tcp
->keepalive
));
2239 s32
net_ioctl(s32 s
, u32 cmd
, void *argp
)
2241 struct netsocket
*sock
= get_socket(s
);
2243 if(!sock
) return -1;
2247 if(!argp
) return -1;
2249 *((u16_t
*)argp
) = sock
->conn
->recvavail
;
2251 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, FIONREAD, %p) = %u\n", s
, argp
, *((u16
*)argp
)));
2255 if(argp
&& *(u32
*)argp
)
2256 sock
->flags
|= O_NONBLOCK
;
2258 sock
->flags
&= ~O_NONBLOCK
;
2259 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, FIONBIO, %d)\n", s
, !!(sock
->flags
&O_NONBLOCK
)));
2263 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s
, cmd
, argp
));