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_copypartial(struct netbuf
*,void *,u32
,u32
);
93 static void netbuf_ref(struct netbuf
*,const void *,u32
);
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
*);
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
*);
120 static apimsg_decode decode
[APIMSG_MAX
] = {
134 static void apimsg_post(struct api_msg
*);
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 *);
141 static void tmr_callback(void *arg
)
143 void (*functor
)() = (void(*)())arg
;
144 if(functor
) functor();
147 /* low level stuff */
148 static void __dhcpcoarse_timer(void *arg
)
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();
156 static void __dhcpfine_timer(void *arg
)
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();
164 static void __tcp_timer(void *arg
)
167 printf("__tcp_timer(%d,%p,%p)\n",tcp_timer_active
,tcp_active_pcbs
,tcp_tw_pcbs
);
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
);
174 tcp_timer_active
= 0;
175 __lwp_thread_dispatchunnest();
178 static void __arp_timer(void *arg
)
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();
186 void tcp_timer_needed(void)
189 printf("tcp_timer_needed()\n");
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
);
198 static __inline__ u16
netbuf_len(struct netbuf
*buf
)
200 return ((buf
&& buf
->p
)?buf
->p
->tot_len
:0);
203 static __inline__
struct ip_addr
* netbuf_fromaddr(struct netbuf
*buf
)
205 return (buf
?buf
->fromaddr
:NULL
);
208 static __inline__ u16
netbuf_fromport(struct netbuf
*buf
)
210 return (buf
?buf
->fromport
:0);
213 static void netbuf_copypartial(struct netbuf
*buf
,void *dataptr
,u32 len
,u32 offset
)
219 if(buf
==NULL
|| dataptr
==NULL
) return;
221 for(p
=buf
->p
;left
<len
&& p
!=NULL
;p
=p
->next
) {
222 if(offset
!=0 && offset
>=p
->len
)
225 for(i
=offset
;i
<p
->len
;i
++) {
226 ((u8
*)dataptr
)[left
] = ((u8
*)p
->payload
)[i
];
227 if(++left
>=len
) return;
234 static struct netbuf
* netbuf_new()
236 struct netbuf
*buf
= NULL
;
238 buf
= memp_malloc(MEMP_NETBUF
);
246 static void netbuf_delete(struct netbuf
*buf
)
249 if(buf
->p
!=NULL
) pbuf_free(buf
->p
);
250 memp_free(MEMP_NETBUF
,buf
);
254 static void netbuf_ref(struct netbuf
*buf
, const void *dataptr
,u32 size
)
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
;
264 static inline enum netconn_type
netconn_type(struct netconn
*conn
)
269 static struct netconn
* netconn_new_with_callback(enum netconn_type t
,void (*cb
)(struct netconn
*,enum netconn_evt
,u32
))
271 return netconn_new_with_proto_and_callback(t
,0,cb
);
274 static struct netconn
* netconn_new_with_proto_and_callback(enum netconn_type t
,u16 proto
,void (*cb
)(struct netconn
*,enum netconn_evt
,u32
))
277 struct netconn
*conn
;
280 conn
= memp_malloc(MEMP_NETCONN
);
281 if(!conn
) return NULL
;
285 conn
->pcb
.tcp
= NULL
;
287 if(MQ_Init(&conn
->mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
288 memp_free(MEMP_NETCONN
,conn
);
291 if(LWP_SemInit(&conn
->sem
,0,1)==-1) {
292 MQ_Close(conn
->mbox
);
293 memp_free(MEMP_NETCONN
,conn
);
297 conn
->acceptmbox
= SYS_MBOX_NULL
;
298 conn
->recvmbox
= SYS_MBOX_NULL
;
299 conn
->state
= NETCONN_NONE
;
304 msg
= memp_malloc(MEMP_API_MSG
);
306 MQ_Close(conn
->mbox
);
307 memp_free(MEMP_NETCONN
,conn
);
311 msg
->type
= APIMSG_NEWCONN
;
312 msg
->msg
.msg
.bc
.port
= proto
;
313 msg
->msg
.conn
= conn
;
315 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
316 memp_free(MEMP_API_MSG
,msg
);
318 if(conn
->err
!=ERR_OK
) {
319 MQ_Close(conn
->mbox
);
320 memp_free(MEMP_NETCONN
,conn
);
326 static err_t
netconn_delete(struct netconn
*conn
)
333 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_delete(%p)\n", conn
));
335 if(!conn
) return ERR_OK
;
337 msg
= memp_malloc(MEMP_API_MSG
);
338 if(!msg
) return ERR_MEM
;
340 msg
->type
= APIMSG_DELCONN
;
341 msg
->msg
.conn
= conn
;
343 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
344 memp_free(MEMP_API_MSG
,msg
);
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
) {
351 if(conn
->type
==NETCONN_TCP
)
352 pbuf_free((struct pbuf
*)mem
);
354 netbuf_delete((struct netbuf
*)mem
);
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
);
369 MQ_Close(conn
->mbox
);
370 conn
->mbox
= SYS_MBOX_NULL
;
372 LWP_SemDestroy(conn
->sem
);
373 conn
->sem
= SYS_SEM_NULL
;
375 memp_free(MEMP_NETCONN
,conn
);
379 static struct netconn
* netconn_accept(struct netconn
* conn
)
381 struct netconn
*newconn
;
383 if(conn
==NULL
) return NULL
;
385 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_accept(%p)\n", conn
));
386 MQ_Receive(conn
->acceptmbox
,(mqmsg_t
)&newconn
,MQ_MSG_BLOCK
);
388 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,0);
393 static err_t
netconn_peer(struct netconn
*conn
,struct ip_addr
*addr
,u16
*port
)
398 case NETCONN_UDPLITE
:
399 case NETCONN_UDPNOCHKSUM
:
401 if(conn
->pcb
.udp
==NULL
|| ((conn
->pcb
.udp
->flags
&UDP_FLAGS_CONNECTED
)==0))
403 *addr
= conn
->pcb
.udp
->remote_ip
;
404 *port
= conn
->pcb
.udp
->remote_port
;
407 if(conn
->pcb
.tcp
==NULL
)
409 *addr
= conn
->pcb
.tcp
->remote_ip
;
410 *port
= conn
->pcb
.tcp
->remote_port
;
413 return (conn
->err
= ERR_OK
);
416 static err_t
netconn_bind(struct netconn
*conn
,struct ip_addr
*addr
,u16 port
)
421 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_bind(%p)\n", conn
));
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
;
428 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
)
429 return (conn
->err
= ERR_MEM
);
431 msg
->type
= APIMSG_BIND
;
432 msg
->msg
.conn
= conn
;
433 msg
->msg
.msg
.bc
.ipaddr
= addr
;
434 msg
->msg
.msg
.bc
.port
= port
;
436 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
437 memp_free(MEMP_API_MSG
,msg
);
441 static err_t
netconn_listen(struct netconn
*conn
)
446 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_listen(%p)\n", conn
));
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
;
453 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return (conn
->err
= ERR_MEM
);
454 msg
->type
= APIMSG_LISTEN
;
455 msg
->msg
.conn
= conn
;
457 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
458 memp_free(MEMP_API_MSG
,msg
);
462 static struct netbuf
* netconn_recv(struct netconn
*conn
)
470 if(conn
==NULL
) return NULL
;
471 if(conn
->recvmbox
==SYS_MBOX_NULL
) {
472 conn
->err
= ERR_CONN
;
475 if(conn
->err
!=ERR_OK
) return NULL
;
477 if(conn
->type
==NETCONN_TCP
) {
478 if(conn
->pcb
.tcp
->state
==LISTEN
) {
479 conn
->err
= ERR_CONN
;
483 buf
= memp_malloc(MEMP_NETBUF
);
489 MQ_Receive(conn
->recvmbox
,(mqmsg_t
)&p
,MQ_MSG_BLOCK
);
492 conn
->recvavail
-= len
;
497 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,len
);
500 memp_free(MEMP_NETBUF
,buf
);
501 MQ_Close(conn
->recvmbox
);
502 conn
->recvmbox
= SYS_MBOX_NULL
;
509 buf
->fromaddr
= NULL
;
511 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) {
516 msg
->type
= APIMSG_RECV
;
517 msg
->msg
.conn
= conn
;
519 msg
->msg
.msg
.len
= len
;
521 msg
->msg
.msg
.len
= 1;
524 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
525 memp_free(MEMP_API_MSG
,msg
);
527 MQ_Receive(conn
->recvmbox
,(mqmsg_t
)&buf
,MQ_MSG_BLOCK
);
528 conn
->recvavail
-= buf
->p
->tot_len
;
530 (*conn
->callback
)(conn
,NETCONN_EVTRCVMINUS
,buf
->p
->tot_len
);
533 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_recv: received %p (err %d)\n", (void *)buf
, conn
->err
));
537 static err_t
netconn_send(struct netconn
*conn
,struct netbuf
*buf
)
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
);
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
;
551 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
552 memp_free(MEMP_API_MSG
,msg
);
556 static err_t
netconn_write(struct netconn
*conn
,const void *dataptr
,u32 size
,u8 copy
)
563 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write(%d)\n",conn
->err
));
565 if(conn
==NULL
) return ERR_VAL
;
566 if(conn
->err
!=ERR_OK
) return conn
->err
;
568 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return (conn
->err
= ERR_MEM
);
570 msg
->type
= APIMSG_WRITE
;
571 msg
->msg
.conn
= conn
;
572 conn
->state
= NETCONN_WRITE
;
573 while(conn
->err
==ERR_OK
&& size
>0) {
574 msg
->msg
.msg
.w
.dataptr
= (void*)dataptr
;
575 msg
->msg
.msg
.w
.copy
= copy
;
576 if(conn
->type
==NETCONN_TCP
) {
577 while((snd_buf
=tcp_sndbuf(conn
->pcb
.tcp
))==0) {
578 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: tcp_sndbuf = 0,err = %d\n", conn
->err
));
579 LWP_SemWait(conn
->sem
);
580 if(conn
->err
!=ERR_OK
) goto ret
;
589 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write: writing %d bytes (%d)\n", len
, copy
));
590 msg
->msg
.msg
.w
.len
= len
;
592 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
593 if(conn
->err
==ERR_OK
) {
594 LWIP_DEBUGF(API_LIB_DEBUG
, ("netconn_write: %d bytes written\n",len
));
595 dataptr
= (void*)((char*)dataptr
+len
);
597 } else if(conn
->err
==ERR_MEM
) {
598 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: mem err\n"));
600 LWP_SemWait(conn
->sem
);
602 LWIP_DEBUGF(API_LIB_DEBUG
,("netconn_write: err = %d\n", conn
->err
));
607 memp_free(MEMP_API_MSG
,msg
);
608 conn
->state
= NETCONN_NONE
;
613 static err_t
netconn_connect(struct netconn
*conn
,struct ip_addr
*addr
,u16 port
)
618 if(conn
==NULL
) return -1;
619 if(conn
->recvmbox
==SYS_MBOX_NULL
) {
620 if(MQ_Init(&conn
->recvmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return ERR_MEM
;
623 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return ERR_MEM
;
625 msg
->type
= APIMSG_CONNECT
;
626 msg
->msg
.conn
= conn
;
627 msg
->msg
.msg
.bc
.ipaddr
= addr
;
628 msg
->msg
.msg
.bc
.port
= port
;
630 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
631 memp_free(MEMP_API_MSG
,msg
);
635 static err_t
netconn_disconnect(struct netconn
*conn
)
640 if(conn
==NULL
) return ERR_VAL
;
641 if((msg
=memp_malloc(MEMP_API_MSG
))==NULL
) return ERR_MEM
;
643 msg
->type
= APIMSG_DISCONNECT
;
644 msg
->msg
.conn
= conn
;
646 MQ_Receive(conn
->mbox
,(mqmsg_t
)&dummy
,MQ_MSG_BLOCK
);
647 memp_free(MEMP_API_MSG
,msg
);
652 static u8_t
recv_raw(void *arg
,struct raw_pcb
*pcb
,struct pbuf
*p
,struct ip_addr
*addr
)
655 struct netconn
*conn
= (struct netconn
*)arg
;
659 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
660 if((buf
=memp_malloc(MEMP_NETBUF
))==NULL
) return 0;
665 buf
->fromaddr
= addr
;
666 buf
->fromport
= pcb
->protocol
;
668 conn
->recvavail
+= p
->tot_len
;
670 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,p
->tot_len
);
671 MQ_Send(conn
->recvmbox
,&buf
,MQ_MSG_BLOCK
);
676 static void recv_udp(void *arg
,struct udp_pcb
*pcb
,struct pbuf
*p
,struct ip_addr
*addr
,u16 port
)
679 struct netconn
*conn
= (struct netconn
*)arg
;
686 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
687 buf
= memp_malloc(MEMP_NETBUF
);
694 buf
->fromaddr
= addr
;
695 buf
->fromport
= port
;
697 conn
->recvavail
+= p
->tot_len
;
699 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,p
->tot_len
);
701 MQ_Send(conn
->recvmbox
,&buf
,MQ_MSG_BLOCK
);
705 static err_t
recv_tcp(void *arg
,struct tcp_pcb
*pcb
,struct pbuf
*p
,err_t err
)
708 struct netconn
*conn
= (struct netconn
*)arg
;
710 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: recv_tcp(%p,%p,%p,%d)\n",arg
,pcb
,p
,err
));
717 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
721 conn
->recvavail
+= len
;
725 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,len
);
727 MQ_Send(conn
->recvmbox
,&p
,MQ_MSG_BLOCK
);
732 static void err_tcp(void *arg
,err_t err
)
735 struct netconn
*conn
= (struct netconn
*)arg
;
737 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: err_tcp: %d\n",err
));
740 conn
->pcb
.tcp
= NULL
;
741 if(conn
->recvmbox
!=SYS_MBOX_NULL
) {
742 if(conn
->callback
) (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
743 MQ_Send(conn
->recvmbox
,&dummy
,MQ_MSG_BLOCK
);
745 if(conn
->mbox
!=SYS_MBOX_NULL
) {
746 MQ_Send(conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
748 if(conn
->acceptmbox
!=SYS_MBOX_NULL
) {
749 if(conn
->callback
) (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
750 MQ_Send(conn
->acceptmbox
,&dummy
,MQ_MSG_BLOCK
);
752 if(conn
->sem
!=SYS_SEM_NULL
) {
753 LWP_SemPost(conn
->sem
);
758 static err_t
poll_tcp(void *arg
,struct tcp_pcb
*pcb
)
760 struct netconn
*conn
= (struct netconn
*)arg
;
762 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: poll_tcp\n"));
763 if(conn
&& conn
->sem
!=SYS_SEM_NULL
&& (conn
->state
==NETCONN_WRITE
|| conn
->state
==NETCONN_CLOSE
))
764 LWP_SemPost(conn
->sem
);
769 static err_t
sent_tcp(void *arg
,struct tcp_pcb
*pcb
,u16 len
)
771 struct netconn
*conn
= (struct netconn
*)arg
;
773 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: sent_tcp: sent %d bytes\n",len
));
774 if(conn
&& conn
->sem
!=SYS_SEM_NULL
)
775 LWP_SemPost(conn
->sem
);
777 if(conn
&& conn
->callback
) {
778 if(tcp_sndbuf(conn
->pcb
.tcp
)>TCP_SNDLOWAT
)
779 (*conn
->callback
)(conn
,NETCONN_EVTSENDPLUS
,len
);
784 static void setuptcp(struct netconn
*conn
)
786 struct tcp_pcb
*pcb
= conn
->pcb
.tcp
;
789 tcp_recv(pcb
,recv_tcp
);
790 tcp_sent(pcb
,sent_tcp
);
791 tcp_poll(pcb
,poll_tcp
,4);
792 tcp_err(pcb
,err_tcp
);
795 static err_t
accept_func(void *arg
,struct tcp_pcb
*newpcb
,err_t err
)
798 struct netconn
*newconn
,*conn
= (struct netconn
*)arg
;
800 LWIP_DEBUGF(API_LIB_DEBUG
, ("accept_func: %p %p %d\n",arg
,newpcb
,err
));
802 mbox
= conn
->acceptmbox
;
803 newconn
= memp_malloc(MEMP_NETCONN
);
804 if(newconn
==NULL
) return ERR_MEM
;
806 if(MQ_Init(&newconn
->recvmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
807 memp_free(MEMP_NETCONN
,newconn
);
811 if(MQ_Init(&newconn
->mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
812 MQ_Close(newconn
->recvmbox
);
813 memp_free(MEMP_NETCONN
,newconn
);
817 if(LWP_SemInit(&newconn
->sem
,0,1)==-1) {
818 MQ_Close(newconn
->recvmbox
);
819 MQ_Close(newconn
->mbox
);
820 memp_free(MEMP_NETCONN
,newconn
);
824 newconn
->type
= NETCONN_TCP
;
825 newconn
->pcb
.tcp
= newpcb
;
828 newconn
->acceptmbox
= SYS_MBOX_NULL
;
832 (*conn
->callback
)(conn
,NETCONN_EVTRCVPLUS
,0);
834 newconn
->callback
= conn
->callback
;
835 newconn
->socket
= -1;
836 newconn
->recvavail
= 0;
838 MQ_Send(mbox
,&newconn
,MQ_MSG_BLOCK
);
842 static void do_newconn(struct apimsg_msg
*msg
)
846 if(msg
->conn
->pcb
.tcp
) {
847 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
851 msg
->conn
->err
= ERR_OK
;
852 switch(msg
->conn
->type
) {
854 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
855 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
857 case NETCONN_UDPLITE
:
858 msg
->conn
->pcb
.udp
= udp_new();
859 if(!msg
->conn
->pcb
.udp
) {
860 msg
->conn
->err
= ERR_MEM
;
863 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
864 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
866 case NETCONN_UDPNOCHKSUM
:
867 msg
->conn
->pcb
.udp
= udp_new();
868 if(!msg
->conn
->pcb
.udp
) {
869 msg
->conn
->err
= ERR_MEM
;
872 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
873 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
876 msg
->conn
->pcb
.udp
= udp_new();
877 if(!msg
->conn
->pcb
.udp
) {
878 msg
->conn
->err
= ERR_MEM
;
881 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
884 msg
->conn
->pcb
.tcp
= tcp_new();
885 if(!msg
->conn
->pcb
.tcp
) {
886 msg
->conn
->err
= ERR_MEM
;
894 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
897 static void do_delconn(struct apimsg_msg
*msg
)
901 if(msg
->conn
->pcb
.tcp
) {
902 switch(msg
->conn
->type
) {
904 raw_remove(msg
->conn
->pcb
.raw
);
906 case NETCONN_UDPLITE
:
907 case NETCONN_UDPNOCHKSUM
:
909 msg
->conn
->pcb
.udp
->recv_arg
= NULL
;
910 udp_remove(msg
->conn
->pcb
.udp
);
913 if(msg
->conn
->pcb
.tcp
->state
==LISTEN
) {
914 tcp_arg(msg
->conn
->pcb
.tcp
,NULL
);
915 tcp_accept(msg
->conn
->pcb
.tcp
,NULL
);
916 tcp_close(msg
->conn
->pcb
.tcp
);
918 tcp_arg(msg
->conn
->pcb
.tcp
,NULL
);
919 tcp_sent(msg
->conn
->pcb
.tcp
,NULL
);
920 tcp_recv(msg
->conn
->pcb
.tcp
,NULL
);
921 tcp_poll(msg
->conn
->pcb
.tcp
,NULL
,0);
922 tcp_err(msg
->conn
->pcb
.tcp
,NULL
);
923 if(tcp_close(msg
->conn
->pcb
.tcp
)!=ERR_OK
)
924 tcp_abort(msg
->conn
->pcb
.tcp
);
931 if(msg
->conn
->callback
) {
932 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTRCVPLUS
,0);
933 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTSENDPLUS
,0);
935 if(msg
->conn
->mbox
!=SYS_MBOX_NULL
)
936 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
939 static void do_bind(struct apimsg_msg
*msg
)
943 if(msg
->conn
->pcb
.tcp
==NULL
) {
944 switch(msg
->conn
->type
) {
946 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
947 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
949 case NETCONN_UDPLITE
:
950 msg
->conn
->pcb
.udp
= udp_new();
951 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
952 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
954 case NETCONN_UDPNOCHKSUM
:
955 msg
->conn
->pcb
.udp
= udp_new();
956 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
957 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
960 msg
->conn
->pcb
.udp
= udp_new();
961 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
964 msg
->conn
->pcb
.tcp
= tcp_new();
971 switch(msg
->conn
->type
) {
973 msg
->conn
->err
= raw_bind(msg
->conn
->pcb
.raw
,msg
->msg
.bc
.ipaddr
);
975 case NETCONN_UDPLITE
:
976 case NETCONN_UDPNOCHKSUM
:
978 msg
->conn
->err
= udp_bind(msg
->conn
->pcb
.udp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
981 msg
->conn
->err
= tcp_bind(msg
->conn
->pcb
.tcp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
986 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
989 static err_t
do_connected(void *arg
,struct tcp_pcb
*pcb
,err_t err
)
992 struct netconn
*conn
= (struct netconn
*)arg
;
994 if(!conn
) return ERR_VAL
;
997 if(conn
->type
==NETCONN_TCP
&& err
==ERR_OK
) setuptcp(conn
);
999 MQ_Send(conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1003 static void do_connect(struct apimsg_msg
*msg
)
1007 if(!msg
->conn
->pcb
.tcp
) {
1008 switch(msg
->conn
->type
) {
1010 msg
->conn
->pcb
.raw
= raw_new(msg
->msg
.bc
.port
);
1011 raw_recv(msg
->conn
->pcb
.raw
,recv_raw
,msg
->conn
);
1013 case NETCONN_UDPLITE
:
1014 msg
->conn
->pcb
.udp
= udp_new();
1015 if(!msg
->conn
->pcb
.udp
) {
1016 msg
->conn
->err
= ERR_MEM
;
1017 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1020 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_UDPLITE
);
1021 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1023 case NETCONN_UDPNOCHKSUM
:
1024 msg
->conn
->pcb
.udp
= udp_new();
1025 if(!msg
->conn
->pcb
.udp
) {
1026 msg
->conn
->err
= ERR_MEM
;
1027 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1030 udp_setflags(msg
->conn
->pcb
.udp
,UDP_FLAGS_NOCHKSUM
);
1031 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1034 msg
->conn
->pcb
.udp
= udp_new();
1035 if(!msg
->conn
->pcb
.udp
) {
1036 msg
->conn
->err
= ERR_MEM
;
1037 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1040 udp_recv(msg
->conn
->pcb
.udp
,recv_udp
,msg
->conn
);
1043 msg
->conn
->pcb
.tcp
= tcp_new();
1044 if(!msg
->conn
->pcb
.tcp
) {
1045 msg
->conn
->err
= ERR_MEM
;
1046 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1054 switch(msg
->conn
->type
) {
1056 raw_connect(msg
->conn
->pcb
.raw
,msg
->msg
.bc
.ipaddr
);
1057 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1059 case NETCONN_UDPLITE
:
1060 case NETCONN_UDPNOCHKSUM
:
1062 udp_connect(msg
->conn
->pcb
.udp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
);
1063 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1066 setuptcp(msg
->conn
);
1067 tcp_connect(msg
->conn
->pcb
.tcp
,msg
->msg
.bc
.ipaddr
,msg
->msg
.bc
.port
,do_connected
);
1074 static void do_disconnect(struct apimsg_msg
*msg
)
1078 switch(msg
->conn
->type
) {
1081 case NETCONN_UDPLITE
:
1082 case NETCONN_UDPNOCHKSUM
:
1084 udp_disconnect(msg
->conn
->pcb
.udp
);
1089 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1092 static void do_listen(struct apimsg_msg
*msg
)
1096 if(msg
->conn
->pcb
.tcp
!=NULL
) {
1097 switch(msg
->conn
->type
) {
1099 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: listen RAW: cannot listen for RAW.\n"));
1101 case NETCONN_UDPLITE
:
1102 case NETCONN_UDPNOCHKSUM
:
1104 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: listen UDP: cannot listen for UDP.\n"));
1107 msg
->conn
->pcb
.tcp
= tcp_listen(msg
->conn
->pcb
.tcp
);
1108 if(msg
->conn
->pcb
.tcp
==NULL
)
1109 msg
->conn
->err
= ERR_MEM
;
1111 if(msg
->conn
->acceptmbox
==SYS_MBOX_NULL
) {
1112 if(MQ_Init(&msg
->conn
->acceptmbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) {
1113 msg
->conn
->err
= ERR_MEM
;
1117 tcp_arg(msg
->conn
->pcb
.tcp
,msg
->conn
);
1118 tcp_accept(msg
->conn
->pcb
.tcp
,accept_func
);
1125 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1128 static void do_accept(struct apimsg_msg
*msg
)
1130 if(msg
->conn
->pcb
.tcp
) {
1131 switch(msg
->conn
->type
) {
1133 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: accept RAW: cannot accept for RAW.\n"));
1135 case NETCONN_UDPLITE
:
1136 case NETCONN_UDPNOCHKSUM
:
1138 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: accept UDP: cannot accept for UDP.\n"));
1146 static void do_send(struct apimsg_msg
*msg
)
1150 if(msg
->conn
->pcb
.tcp
) {
1151 switch(msg
->conn
->type
) {
1153 raw_send(msg
->conn
->pcb
.raw
,msg
->msg
.p
);
1155 case NETCONN_UDPLITE
:
1156 case NETCONN_UDPNOCHKSUM
:
1158 udp_send(msg
->conn
->pcb
.udp
,msg
->msg
.p
);
1164 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1167 static void do_recv(struct apimsg_msg
*msg
)
1171 if(msg
->conn
->pcb
.tcp
&& msg
->conn
->type
==NETCONN_TCP
) {
1172 tcp_recved(msg
->conn
->pcb
.tcp
,msg
->msg
.len
);
1174 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1177 static void do_write(struct apimsg_msg
*msg
)
1182 if(msg
->conn
->pcb
.tcp
) {
1183 switch(msg
->conn
->type
) {
1185 case NETCONN_UDPLITE
:
1186 case NETCONN_UDPNOCHKSUM
:
1188 msg
->conn
->err
= ERR_VAL
;
1191 err
= tcp_write(msg
->conn
->pcb
.tcp
,msg
->msg
.w
.dataptr
,msg
->msg
.w
.len
,msg
->msg
.w
.copy
);
1192 if(err
==ERR_OK
&& (!msg
->conn
->pcb
.tcp
->unacked
|| (msg
->conn
->pcb
.tcp
->flags
&TF_NODELAY
)
1193 || msg
->conn
->pcb
.tcp
->snd_queuelen
>1)) {
1194 LWIP_DEBUGF(API_MSG_DEBUG
, ("api_msg: TCP write: tcp_output.\n"));
1195 tcp_output(msg
->conn
->pcb
.tcp
);
1197 msg
->conn
->err
= err
;
1198 if(msg
->conn
->callback
) {
1200 if(tcp_sndbuf(msg
->conn
->pcb
.tcp
)<=TCP_SNDLOWAT
)
1201 (*msg
->conn
->callback
)(msg
->conn
,NETCONN_EVTSENDMINUS
,msg
->msg
.w
.len
);
1209 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1212 static void do_close(struct apimsg_msg
*msg
)
1217 if(msg
->conn
->pcb
.tcp
) {
1218 switch(msg
->conn
->type
) {
1220 case NETCONN_UDPLITE
:
1221 case NETCONN_UDPNOCHKSUM
:
1225 if(msg
->conn
->pcb
.tcp
->state
==LISTEN
)
1226 err
= tcp_close(msg
->conn
->pcb
.tcp
);
1227 else if(msg
->conn
->pcb
.tcp
->state
==CLOSE_WAIT
)
1228 err
= tcp_output(msg
->conn
->pcb
.tcp
);
1229 msg
->conn
->err
= err
;
1235 MQ_Send(msg
->conn
->mbox
,&dummy
,MQ_MSG_BLOCK
);
1238 static void apimsg_input(struct api_msg
*msg
)
1240 decode
[msg
->type
](&(msg
->msg
));
1243 static void apimsg_post(struct api_msg
*msg
)
1248 /* tcpip thread part */
1249 static err_t
net_input(struct pbuf
*p
,struct netif
*inp
)
1251 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1253 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_input: %p %p\n", p
,inp
));
1256 LWIP_ERROR(("net_input: msg out of memory.\n"));
1261 msg
->type
= NETMSG_INPUT
;
1263 msg
->msg
.inp
.net
= inp
;
1264 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1268 static void net_apimsg(struct api_msg
*apimsg
)
1270 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1272 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_apimsg: %p\n",apimsg
));
1274 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1275 memp_free(MEMP_API_MSG
,apimsg
);
1279 msg
->type
= NETMSG_API
;
1280 msg
->msg
.apimsg
= apimsg
;
1281 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1284 static err_t
net_callback(void (*f
)(void *),void *ctx
)
1286 struct net_msg
*msg
= memp_malloc(MEMP_TCPIP_MSG
);
1288 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_callback: %p(%p)\n", f
,ctx
));
1291 LWIP_ERROR(("net_apimsg: msg out of memory.\n"));
1295 msg
->type
= NETMSG_CALLBACK
;
1297 msg
->msg
.cb
.ctx
= ctx
;
1298 MQ_Send(netthread_mbox
,&msg
,MQ_MSG_BLOCK
);
1302 static void* net_thread(void *arg
)
1304 struct net_msg
*msg
;
1306 sys_sem sem
= (sys_sem
)arg
;
1314 tb
.tv_sec
= ARP_TMR_INTERVAL
/TB_MSPERSEC
;
1316 net_arp_ticks
= __lwp_wd_calc_ticks(&tb
);
1317 __lwp_wd_initialize(&arp_time_cntrl
,__arp_timer
,ARP_TIMER_ID
,NULL
);
1318 __lwp_wd_insert_ticks(&arp_time_cntrl
,net_arp_ticks
);
1321 tb
.tv_nsec
= TCP_TMR_INTERVAL
*TB_NSPERMS
;
1322 net_tcp_ticks
= __lwp_wd_calc_ticks(&tb
);
1323 __lwp_wd_initialize(&tcp_timer_cntrl
,__tcp_timer
,TCP_TIMER_ID
,NULL
);
1327 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread(%p)\n",arg
));
1330 MQ_Receive(netthread_mbox
,(mqmsg_t
)&msg
,MQ_MSG_BLOCK
);
1333 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: API message %p\n", (void *)msg
));
1334 apimsg_input(msg
->msg
.apimsg
);
1337 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: IP packet %p\n", (void *)msg
));
1338 bba_process(msg
->msg
.inp
.p
,msg
->msg
.inp
.net
);
1340 case NETMSG_CALLBACK
:
1341 LWIP_DEBUGF(TCPIP_DEBUG
, ("net_thread: CALLBACK %p\n", (void *)msg
));
1342 msg
->msg
.cb
.f(msg
->msg
.cb
.ctx
);
1347 memp_free(MEMP_TCPIP_MSG
,msg
);
1353 static s32
alloc_socket(struct netconn
*conn
)
1357 LWP_SemWait(netsocket_sem
);
1359 for(i
=0;i
<NUM_SOCKETS
;i
++) {
1360 if(!sockets
[i
].conn
) {
1361 sockets
[i
].conn
= conn
;
1362 sockets
[i
].lastdata
= NULL
;
1363 sockets
[i
].lastoffset
= 0;
1364 sockets
[i
].rcvevt
= 0;
1365 sockets
[i
].sendevt
= 1;
1366 sockets
[i
].flags
= 0;
1368 LWP_SemPost(netsocket_sem
);
1373 LWP_SemPost(netsocket_sem
);
1377 static struct netsocket
* get_socket(s32 s
)
1379 struct netsocket
*sock
;
1380 if(s
<0 || s
>NUM_SOCKETS
) {
1381 LWIP_DEBUGF(SOCKETS_DEBUG
, ("get_socket(%d): invalid\n", s
));
1386 LWIP_DEBUGF(SOCKETS_DEBUG
, ("get_socket(%d): no active\n", s
));
1393 static void evt_callback(struct netconn
*conn
,enum netconn_evt evt
,u32 len
)
1396 struct netsocket
*sock
;
1397 struct netselect_cb
*scb
;
1402 if(evt
==NETCONN_EVTRCVPLUS
)
1406 sock
= get_socket(s
);
1411 LWP_SemWait(sockselect_sem
);
1413 case NETCONN_EVTRCVPLUS
:
1416 case NETCONN_EVTRCVMINUS
:
1419 case NETCONN_EVTSENDPLUS
:
1422 case NETCONN_EVTSENDMINUS
:
1426 LWP_SemPost(sockselect_sem
);
1429 LWP_SemWait(sockselect_sem
);
1430 for(scb
= selectcb_list
;scb
;scb
= scb
->next
) {
1431 if(scb
->signaled
==0) {
1432 if(scb
->readset
&& FD_ISSET(s
,scb
->readset
))
1433 if(sock
->rcvevt
) break;
1434 if(scb
->writeset
&& FD_ISSET(s
,scb
->writeset
))
1435 if(sock
->sendevt
) break;
1440 LWP_SemPost(sockselect_sem
);
1441 LWP_MutexLock(scb
->cond_lck
);
1442 LWP_CondSignal(scb
->cond
);
1443 LWP_MutexUnlock(scb
->cond_lck
);
1445 LWP_SemPost(sockselect_sem
);
1452 extern const devoptab_t dotab_stdnet
;
1454 s32
if_configex(struct in_addr
*local_ip
,struct in_addr
*netmask
,struct in_addr
*gateway
,boolean use_dhcp
)
1457 struct ip_addr loc_ip
, mask
, gw
;
1462 if(g_netinitiated
) return 0;
1465 AddDevice(&dotab_stdnet
);
1476 // init tcpip thread message box
1477 if(MQ_Init(&netthread_mbox
,MQBOX_SIZE
)!=MQ_ERROR_SUCCESSFUL
) return -1;
1479 // create & setup interface
1485 if(use_dhcp
==FALSE
) {
1486 if( !gateway
|| gateway
->s_addr
==0
1487 || !local_ip
|| local_ip
->s_addr
==0
1488 || !netmask
|| netmask
->s_addr
==0 ) return -1;
1489 loc_ip
.addr
= local_ip
->s_addr
;
1490 mask
.addr
= netmask
->s_addr
;
1491 gw
.addr
= gateway
->s_addr
;
1493 hbba
= bba_create(&g_hNetIF
);
1494 pnet
= netif_add(&g_hNetIF
,&loc_ip
, &mask
, &gw
, hbba
, bba_init
, net_input
);
1497 netif_set_default(pnet
);
1499 if(use_dhcp
==TRUE
) {
1500 //setup coarse timer
1501 tb
.tv_sec
= DHCP_COARSE_TIMER_SECS
;
1503 net_dhcpcoarse_ticks
= __lwp_wd_calc_ticks(&tb
);
1504 __lwp_wd_initialize(&dhcp_coarsetimer_cntrl
,__dhcpcoarse_timer
,DHCPCOARSE_TIMER_ID
,NULL
);
1505 __lwp_wd_insert_ticks(&dhcp_coarsetimer_cntrl
,net_dhcpcoarse_ticks
);
1509 tb
.tv_nsec
= DHCP_FINE_TIMER_MSECS
*TB_NSPERMS
;
1510 net_dhcpfine_ticks
= __lwp_wd_calc_ticks(&tb
);
1511 __lwp_wd_initialize(&dhcp_finetimer_cntrl
,__dhcpfine_timer
,DHCPFINE_TIMER_ID
,NULL
);
1512 __lwp_wd_insert_ticks(&dhcp_finetimer_cntrl
,net_dhcpfine_ticks
);
1514 //now start dhcp client
1521 // setup loopinterface
1522 IP4_ADDR(&loc_ip
, 127,0,0,1);
1523 IP4_ADDR(&mask
, 255,0,0,0);
1524 IP4_ADDR(&gw
, 127,0,0,1);
1525 pnet
= netif_add(&g_hLoopIF
,&loc_ip
,&mask
,&gw
,NULL
,loopif_init
,net_input
);
1527 //last and least start the tcpip layer
1530 if ( ret
== 0 && use_dhcp
== TRUE
) {
1533 // wait for dhcp to bind
1534 while ( g_hNetIF
.dhcp
->state
!= DHCP_BOUND
&& retries
< 20 ) {
1539 if ( retries
< 20 ) {
1540 //copy back network addresses
1541 if ( local_ip
!= NULL
) local_ip
->s_addr
= g_hNetIF
.ip_addr
.addr
;
1542 if ( gateway
!= NULL
) gateway
->s_addr
= g_hNetIF
.gw
.addr
;
1543 if ( netmask
!= NULL
) netmask
->s_addr
= g_hNetIF
.netmask
.addr
;
1552 s32
if_config(char *local_ip
, char *netmask
, char *gateway
,boolean use_dhcp
)
1555 struct in_addr loc_ip
, mask
, gw
;
1561 if ( local_ip
!= NULL
) loc_ip
.s_addr
= inet_addr(local_ip
);
1562 if ( netmask
!= NULL
) mask
.s_addr
= inet_addr(netmask
);
1563 if ( gateway
!= NULL
) gw
.s_addr
= inet_addr(gateway
);
1565 ret
= if_configex( &loc_ip
, &mask
, &gw
, use_dhcp
);
1567 if (ret
<0) return ret
;
1569 if ( use_dhcp
== TRUE
) {
1570 //copy back network addresses
1571 if ( local_ip
!= NULL
) strcpy(local_ip
, inet_ntoa( loc_ip
));
1572 if ( netmask
!= NULL
) strcpy(netmask
, inet_ntoa( mask
));
1573 if ( gateway
!= NULL
) strcpy(gateway
, inet_ntoa( gw
));
1583 if(tcpiplayer_inited
) return 1;
1585 if(LWP_SemInit(&netsocket_sem
,1,1)==-1) return -1;
1586 if(LWP_SemInit(&sockselect_sem
,1,1)==-1) {
1587 LWP_SemDestroy(netsocket_sem
);
1590 if(LWP_SemInit(&sem
,0,1)==-1) {
1591 LWP_SemDestroy(netsocket_sem
);
1592 LWP_SemDestroy(sockselect_sem
);
1596 if(LWP_CreateThread(&hnet_thread
,net_thread
,(void*)sem
,netthread_stack
,STACKSIZE
,220)==-1) {
1597 LWP_SemDestroy(netsocket_sem
);
1598 LWP_SemDestroy(sockselect_sem
);
1599 LWP_SemDestroy(sem
);
1603 LWP_SemDestroy(sem
);
1605 tcpiplayer_inited
= 1;
1610 s32
net_shutdown(s32 s
,u32 how
)
1615 s32
net_fcntl(s32 s
, u32 cmd
, u32 flags
)
1620 s32
net_socket(u32 domain
,u32 type
,u32 protocol
)
1623 struct netconn
*conn
;
1627 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_RAW)\n"));
1628 conn
= netconn_new_with_proto_and_callback(NETCONN_RAW
,protocol
,evt_callback
);
1631 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_DGRAM)\n"));
1632 conn
= netconn_new_with_callback(NETCONN_UDP
,evt_callback
);
1635 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_socket(SOCK_STREAM)\n"));
1636 conn
= netconn_new_with_callback(NETCONN_TCP
,evt_callback
);
1641 if(!conn
) return -1;
1643 i
= alloc_socket(conn
);
1645 netconn_delete(conn
);
1653 s32
net_accept(s32 s
,struct sockaddr
*addr
,socklen_t
*addrlen
)
1655 struct netsocket
*sock
;
1656 struct netconn
*newconn
;
1657 struct ip_addr naddr
= {0};
1660 struct sockaddr_in sin
;
1662 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_accept(%d)\n", s
));
1664 sock
= get_socket(s
);
1665 if(!sock
) return -1;
1667 newconn
= netconn_accept(sock
->conn
);
1668 netconn_peer(newconn
,&naddr
,&port
);
1670 memset(&sin
,0,sizeof(sin
));
1671 sin
.sin_family
= AF_INET
;
1672 sin
.sin_port
= htons(port
);
1673 sin
.sin_addr
.s_addr
= naddr
.addr
;
1675 if(*addrlen
>sizeof(sin
))
1676 *addrlen
= sizeof(sin
);
1677 memcpy(addr
,&sin
,*addrlen
);
1679 newsock
= alloc_socket(newconn
);
1681 netconn_delete(newconn
);
1685 newconn
->callback
= evt_callback
;
1686 sock
= get_socket(newsock
);
1688 LWP_SemWait(netsocket_sem
);
1689 sock
->rcvevt
+= -1 - newconn
->socket
;
1690 newconn
->socket
= newsock
;
1691 LWP_SemPost(netsocket_sem
);
1696 s32
net_bind(s32 s
,struct sockaddr
*name
,socklen_t namelen
)
1698 struct netsocket
*sock
;
1699 struct ip_addr loc_addr
;
1703 sock
= get_socket(s
);
1704 if(!sock
) return -1;
1706 loc_addr
.addr
= ((struct sockaddr_in
*)name
)->sin_addr
.s_addr
;
1707 loc_port
= ((struct sockaddr_in
*)name
)->sin_port
;
1709 err
= netconn_bind(sock
->conn
,&loc_addr
,ntohs(loc_port
));
1710 if(err
!=ERR_OK
) return -1;
1715 s32
net_listen(s32 s
,u32 backlog
)
1717 struct netsocket
*sock
;
1720 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_listen(%d, backlog=%d)\n", s
, backlog
));
1721 sock
= get_socket(s
);
1722 if(!sock
) return -1;
1724 err
= netconn_listen(sock
->conn
);
1726 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_listen(%d) failed, err=%d\n", s
, err
));
1732 s32
net_recvfrom(s32 s
,void *mem
,s32 len
,u32 flags
,struct sockaddr
*from
,socklen_t
*fromlen
)
1734 struct netsocket
*sock
;
1737 struct ip_addr
*addr
;
1740 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d, %p, %d, 0x%x, ..)\n", s
, mem
, len
, flags
));
1741 if(mem
==NULL
|| len
<=0) return -1;
1743 sock
= get_socket(s
);
1744 if(!sock
) return -1;
1747 buf
= sock
->lastdata
;
1749 if(((flags
&MSG_DONTWAIT
) || (sock
->flags
&O_NONBLOCK
)) && !sock
->rcvevt
) {
1750 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): returning EWOULDBLOCK\n", s
));
1753 buf
= netconn_recv(sock
->conn
);
1755 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): buf == NULL!\n", s
));
1760 buflen
= netbuf_len(buf
);
1761 buflen
-= sock
->lastoffset
;
1769 netbuf_copypartial(buf
,mem
,copylen
,sock
->lastoffset
);
1771 if(from
&& fromlen
) {
1772 struct sockaddr_in sin
;
1774 addr
= netbuf_fromaddr(buf
);
1775 port
= netbuf_fromport(buf
);
1777 memset(&sin
,0,sizeof(sin
));
1778 sin
.sin_family
= AF_INET
;
1779 sin
.sin_port
= htons(port
);
1780 sin
.sin_addr
.s_addr
= addr
->addr
;
1782 if(*fromlen
>sizeof(sin
))
1783 *fromlen
= sizeof(sin
);
1785 memcpy(from
,&sin
,*fromlen
);
1787 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_recvfrom(%d): addr=", s
));
1788 ip_addr_debug_print(SOCKETS_DEBUG
, addr
);
1789 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u len=%u\n", port
, copylen
));
1791 if(netconn_type(sock
->conn
)==NETCONN_TCP
&& (buflen
-copylen
)>0) {
1792 sock
->lastdata
= buf
;
1793 sock
->lastoffset
+= copylen
;
1795 sock
->lastdata
= NULL
;
1796 sock
->lastoffset
= 0;
1802 s32
net_read(s32 s
,void *mem
,s32 len
)
1804 return net_recvfrom(s
,mem
,len
,0,NULL
,NULL
);
1807 s32
net_recv(s32 s
,void *mem
,s32 len
,u32 flags
)
1809 return net_recvfrom(s
,mem
,len
,flags
,NULL
,NULL
);
1812 s32
net_sendto(s32 s
,const void *data
,s32 len
,u32 flags
,struct sockaddr
*to
,socklen_t tolen
)
1814 struct netsocket
*sock
;
1815 struct ip_addr remote_addr
, addr
;
1816 u16_t remote_port
, port
= 0;
1819 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_sendto(%d, data=%p, size=%d, flags=0x%x)\n", s
, data
, len
, flags
));
1820 if(data
==NULL
|| len
<=0) return -1;
1822 sock
= get_socket(s
);
1823 if (!sock
) return -1;
1825 /* get the peer if currently connected */
1826 connected
= (netconn_peer(sock
->conn
, &addr
, &port
) == ERR_OK
);
1828 remote_addr
.addr
= ((struct sockaddr_in
*)to
)->sin_addr
.s_addr
;
1829 remote_port
= ((struct sockaddr_in
*)to
)->sin_port
;
1831 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_sendto(%d, data=%p, size=%d, flags=0x%x to=", s
, data
, len
, flags
));
1832 ip_addr_debug_print(SOCKETS_DEBUG
, &remote_addr
);
1833 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u\n", ntohs(remote_port
)));
1835 netconn_connect(sock
->conn
, &remote_addr
, ntohs(remote_port
));
1837 ret
= net_send(s
, data
, len
, flags
);
1839 /* reset the remote address and port number
1840 of the connection */
1842 netconn_connect(sock
->conn
, &addr
, port
);
1844 netconn_disconnect(sock
->conn
);
1848 s32
net_send(s32 s
,const void *data
,s32 len
,u32 flags
)
1850 struct netsocket
*sock
;
1854 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d, data=%p, size=%d, flags=0x%x)\n", s
, data
, len
, flags
));
1855 if(data
==NULL
|| len
<=0) return -1;
1857 sock
= get_socket(s
);
1858 if(!sock
) return -1;
1860 switch(netconn_type(sock
->conn
)) {
1863 case NETCONN_UDPLITE
:
1864 case NETCONN_UDPNOCHKSUM
:
1867 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) ENOBUFS\n", s
));
1870 netbuf_ref(buf
,data
,len
);
1871 err
= netconn_send(sock
->conn
,buf
);
1875 err
= netconn_write(sock
->conn
,data
,len
,NETCONN_COPY
);
1882 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) err=%d\n", s
, err
));
1886 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_send(%d) ok size=%d\n", s
, len
));
1890 s32
net_write(s32 s
,const void *data
,s32 size
)
1892 return net_send(s
,data
,size
,0);
1895 s32
net_connect(s32 s
,struct sockaddr
*name
,socklen_t namelen
)
1897 struct netsocket
*sock
;
1900 sock
= get_socket(s
);
1901 if(!sock
) return -1;
1903 if(((struct sockaddr_in
*)name
)->sin_family
==AF_UNSPEC
) {
1904 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d, AF_UNSPEC)\n", s
));
1905 err
= netconn_disconnect(sock
->conn
);
1907 struct ip_addr remote_addr
;
1910 remote_addr
.addr
= ((struct sockaddr_in
*)name
)->sin_addr
.s_addr
;
1911 remote_port
= ((struct sockaddr_in
*)name
)->sin_port
;
1913 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d, addr=", s
));
1914 ip_addr_debug_print(SOCKETS_DEBUG
, &remote_addr
);
1915 LWIP_DEBUGF(SOCKETS_DEBUG
, (" port=%u)\n", ntohs(remote_port
)));
1917 err
= netconn_connect(sock
->conn
,&remote_addr
,ntohs(remote_port
));
1920 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d) failed, err=%d\n", s
, err
));
1924 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_connect(%d) succeeded\n", s
));
1928 s32
net_close(s32 s
)
1930 struct netsocket
*sock
;
1932 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_close(%d)\n", s
));
1934 LWP_SemWait(netsocket_sem
);
1936 sock
= get_socket(s
);
1938 LWP_SemPost(netsocket_sem
);
1942 netconn_delete(sock
->conn
);
1943 if(sock
->lastdata
) netbuf_delete(sock
->lastdata
);
1945 sock
->lastdata
= NULL
;
1946 sock
->lastoffset
= 0;
1949 LWP_SemPost(netsocket_sem
);
1953 static s32
net_selscan(s32 maxfdp1
,fd_set
*readset
,fd_set
*writeset
,fd_set
*exceptset
)
1956 fd_set lreadset
,lwriteset
,lexceptset
;
1957 struct netsocket
*sock
;
1960 FD_ZERO(&lwriteset
);
1961 FD_ZERO(&lexceptset
);
1963 for(i
=0;i
<maxfdp1
;i
++) {
1964 if(FD_ISSET(i
,readset
)) {
1965 sock
= get_socket(i
);
1966 if(sock
&& (sock
->lastdata
|| sock
->rcvevt
)) {
1967 FD_SET(i
,&lreadset
);
1971 if(FD_ISSET(i
,writeset
)) {
1972 sock
= get_socket(i
);
1973 if(sock
&& sock
->sendevt
) {
1974 FD_SET(i
,&lwriteset
);
1979 *readset
= lreadset
;
1980 *writeset
= lwriteset
;
1986 s32
net_select(s32 maxfdp1
,fd_set
*readset
,fd_set
*writeset
,fd_set
*exceptset
,struct timeval
*timeout
)
1989 fd_set lreadset
,lwriteset
,lexceptset
;
1990 struct timespec tb
,*p_tb
;
1991 struct netselect_cb sel_cb
;
1992 struct netselect_cb
*psel_cb
;
1995 sel_cb
.readset
= readset
;
1996 sel_cb
.writeset
= writeset
;
1997 sel_cb
.exceptset
= exceptset
;
1998 sel_cb
.signaled
= 0;
2000 LWP_SemWait(sockselect_sem
);
2003 lreadset
= *readset
;
2008 lwriteset
= *writeset
;
2010 FD_ZERO(&lwriteset
);
2013 lexceptset
= *exceptset
;
2015 FD_ZERO(&lexceptset
);
2017 nready
= net_selscan(maxfdp1
,&lreadset
,&lwriteset
,&lexceptset
);
2019 if(timeout
&& timeout
->tv_sec
==0 && timeout
->tv_usec
==0) {
2020 LWP_SemPost(sockselect_sem
);
2030 LWP_MutexInit(&sel_cb
.cond_lck
,FALSE
);
2031 LWP_CondInit(&sel_cb
.cond
);
2032 sel_cb
.next
= selectcb_list
;
2033 selectcb_list
= &sel_cb
;
2035 LWP_SemPost(sockselect_sem
);
2039 tb
.tv_sec
= timeout
->tv_sec
;
2040 tb
.tv_nsec
= (timeout
->tv_usec
+500)*TB_NSPERUS
;
2044 LWP_MutexLock(sel_cb
.cond_lck
);
2045 i
= LWP_CondTimedWait(sel_cb
.cond
,sel_cb
.cond_lck
,p_tb
);
2046 LWP_MutexUnlock(sel_cb
.cond_lck
);
2048 LWP_SemWait(sockselect_sem
);
2049 if(selectcb_list
==&sel_cb
)
2050 selectcb_list
= sel_cb
.next
;
2052 for(psel_cb
= selectcb_list
;psel_cb
;psel_cb
= psel_cb
->next
) {
2053 if(psel_cb
->next
==&sel_cb
) {
2054 psel_cb
->next
= sel_cb
.next
;
2059 LWP_CondDestroy(sel_cb
.cond
);
2060 LWP_MutexDestroy(sel_cb
.cond_lck
);
2062 LWP_SemPost(sockselect_sem
);
2075 lreadset
= *readset
;
2080 lwriteset
= *writeset
;
2082 FD_ZERO(&lwriteset
);
2085 lexceptset
= *exceptset
;
2087 FD_ZERO(&lexceptset
);
2089 nready
= net_selscan(maxfdp1
,&lreadset
,&lwriteset
,&lexceptset
);
2091 LWP_SemPost(sockselect_sem
);
2094 *readset
= lreadset
;
2096 *writeset
= lwriteset
;
2098 *exceptset
= lexceptset
;
2103 s32
net_setsockopt(s32 s
,u32 level
,u32 optname
,const void *optval
,socklen_t optlen
)
2106 struct netsocket
*sock
;
2108 sock
= get_socket(s
);
2109 if(sock
==NULL
) return -1;
2110 if(optval
==NULL
) return -1;
2120 if(optlen
<sizeof(u32
)) err
= EINVAL
;
2123 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2134 if(optlen
<sizeof(u32
)) err
= EINVAL
;
2137 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2145 if(optlen
<sizeof(u32
)) {
2149 if(sock
->conn
->type
!=NETCONN_TCP
) return 0;
2156 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s
, optname
));
2163 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s
, level
, optname
));
2166 if(err
!=0) return -1;
2177 sock
->conn
->pcb
.tcp
->so_options
|= optname
;
2179 sock
->conn
->pcb
.tcp
->so_options
&= ~optname
;
2180 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s
, optname
, (*(u32
*)optval
?"on":"off")));
2190 sock
->conn
->pcb
.tcp
->ttl
= (u8
)(*(u32
*)optval
);
2191 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", s
, sock
->conn
->pcb
.tcp
->ttl
));
2194 sock
->conn
->pcb
.tcp
->tos
= (u8
)(*(u32
*)optval
);
2195 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", s
, sock
->conn
->pcb
.tcp
->tos
));
2206 sock
->conn
->pcb
.tcp
->flags
|= TF_NODELAY
;
2208 sock
->conn
->pcb
.tcp
->flags
&= ~TF_NODELAY
;
2209 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", s
, (*(u32
*)optval
)?"on":"off") );
2212 sock
->conn
->pcb
.tcp
->keepalive
= (u32
)(*(u32
*)optval
);
2213 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %u\n", s
, sock
->conn
->pcb
.tcp
->keepalive
));
2221 s32
net_ioctl(s32 s
, u32 cmd
, void *argp
)
2223 struct netsocket
*sock
= get_socket(s
);
2225 if(!sock
) return -1;
2229 if(!argp
) return -1;
2231 *((u16_t
*)argp
) = sock
->conn
->recvavail
;
2233 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, FIONREAD, %p) = %u\n", s
, argp
, *((u16
*)argp
)));
2237 if(argp
&& *(u32
*)argp
)
2238 sock
->flags
|= O_NONBLOCK
;
2240 sock
->flags
&= ~O_NONBLOCK
;
2241 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, FIONBIO, %d)\n", s
, !!(sock
->flags
&O_NONBLOCK
)));
2245 LWIP_DEBUGF(SOCKETS_DEBUG
, ("net_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s
, cmd
, argp
));