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