fix while() stall. (shagkur)
[libogc.git] / libdb / tcpip.c
blob66a4889553c0c75710d104d1405db2e6c104e521
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
5 #include "asm.h"
6 #include "processor.h"
8 #include "uIP/bba.h"
9 #include "uIP/memr.h"
10 #include "uIP/memb.h"
11 #include "uIP/uip_ip.h"
12 #include "uIP/uip_arp.h"
13 #include "uIP/uip_tcp.h"
14 #include "uIP/uip_pbuf.h"
15 #include "uIP/uip_netif.h"
17 #include "tcpip.h"
18 #include "debug_if.h"
20 #if UIP_LOGGING == 1
21 #include <stdio.h>
22 #define UIP_LOG(m) uip_log(__FILE__,__LINE__,m)
23 #else
24 #define UIP_LOG(m)
25 #endif /* UIP_LOGGING == 1 */
27 #if UIP_STATISTICS == 1
28 struct uip_stats uip_stat;
29 #define UIP_STAT(s) s
30 #else
31 #define UIP_STAT(s)
32 #endif /* UIP_STATISTICS == 1 */
34 const char *tcp_localip __attribute__ ((weak)) = "";
35 const char *tcp_netmask __attribute__ ((weak)) = "";
36 const char *tcp_gateway __attribute__ ((weak)) = "";
38 struct tcpip_sock {
39 struct tcpip_sock *next;
40 struct uip_tcp_pcb *pcb;
41 struct uip_pbuf *lastdata;
42 s32 lastoffset,recvevt,sendevt,flags;
43 s32 err,socket;
44 } tcpip_socks[UIP_TCPIP_SOCKS];
46 static s64 tcpip_time = 0;
47 static s32 listensock = -1;
48 static struct uip_netif netif;
49 static struct dbginterface netif_device;
50 static struct tcpip_sock *tcpip_accepted_sockets = NULL;
52 extern s64 gettime();
53 extern u32 diff_msec(s64 start,s64 end);
55 static s32_t tcpip_allocsocket(struct uip_tcp_pcb *pcb)
57 s32_t i;
59 for(i=0;i<UIP_TCPIP_SOCKS;i++) {
60 if(tcpip_socks[i].pcb==NULL) {
61 tcpip_socks[i].pcb = pcb;
62 tcpip_socks[i].lastdata = NULL;
63 tcpip_socks[i].lastoffset = 0;
64 tcpip_socks[i].recvevt = 0;
65 tcpip_socks[i].sendevt = 1;
66 tcpip_socks[i].flags = 0;
67 tcpip_socks[i].socket = i;
68 tcpip_socks[i].err = UIP_ERR_OK;
69 return i;
72 return -1;
75 static struct tcpip_sock* tcpip_getsocket(s32_t s)
77 struct tcpip_sock *sock;
79 if(s<0 || s>=UIP_TCPIP_SOCKS) return NULL;
81 sock = &tcpip_socks[s];
82 if(!sock->pcb) return NULL;
84 return sock;
87 //device callbacks
88 static int opentcpip(struct dbginterface *device)
90 if(listensock>=0 && (device->fhndl<0 ))
91 device->fhndl = tcpip_accept(listensock);
93 if(device->fhndl<0)
94 return -1;
95 else
96 tcpip_starttimer(device->fhndl);
98 return 0;
101 static int closetcpip(struct dbginterface *device)
103 tcpip_stoptimer(device->fhndl);
104 tcpip_close(device->fhndl);
105 device->fhndl = -1;
106 return 0;
109 static int waittcpip(struct dbginterface *device)
111 tcpip_stoptimer(device->fhndl);
112 return 0;
115 static int readtcpip(struct dbginterface *device,void *buffer,int size)
117 if(device->fhndl>=0)
118 return tcpip_read(device->fhndl,buffer,size);
120 return 0;
123 static int writetcpip(struct dbginterface *device,const void *buffer,int size)
125 if(device->fhndl>=0)
126 return tcpip_write(device->fhndl,buffer,size);
128 return 0;
131 static void tcpip_err(void *arg,s8_t err)
133 // printf("tcpip_err: err_code(%d)\n",err);
136 static s8_t tcpip_poll(void *arg,struct uip_tcp_pcb *pcb)
138 UIP_LOG("tcpip_poll()");
139 return UIP_ERR_OK;
142 static s8_t tcpip_sent(void *arg,struct uip_tcp_pcb *pcb,u16_t space)
144 // printf("tcpip_sent(%d)\n",space);
145 return UIP_ERR_OK;
148 //static u32 qcnt = 0;
150 static s8_t tcpip_recved(void *arg,struct uip_tcp_pcb *pcb,struct uip_pbuf *p,s8_t err)
152 u16_t len;
153 struct tcpip_sock *sock = (struct tcpip_sock*)arg;
155 //printf("tcpip_recved(%s (%d/%d))\n",(u8_t*)p->payload,p->len,p->tot_len);
156 if(!sock) {
157 uip_pbuf_free(p);
158 return UIP_ERR_VAL;
161 if(p) {
162 len = p->tot_len;
163 if(sock->lastdata==NULL) {
164 sock->lastdata = p;
165 } else {
167 qcnt++;
168 printf("tcpip_recved(queuing %d)\n",qcnt);
170 uip_pbuf_queue(sock->lastdata,p);
172 } else
173 len = 1;
175 uip_tcp_recved(pcb,len);
176 return UIP_ERR_OK;
180 static s8_t tcpip_accept_func(void *arg,struct uip_tcp_pcb *newpcb,s8_t err)
182 s32_t s;
183 struct tcpip_sock *ptr,*newsock = NULL;
184 struct tcpip_sock *sock = (struct tcpip_sock*)arg;
186 UIP_LOG("tcpip_accept_func()");
187 if(!sock) return UIP_ERR_ABRT;
189 s = tcpip_allocsocket(newpcb);
190 if(s<0) {
191 uip_tcp_close(newpcb);
192 return UIP_ERR_ABRT;
195 newsock = tcpip_getsocket(s);
196 newsock->pcb->flags |= UIP_TF_NODELAY;
198 ptr = tcpip_accepted_sockets;
199 while(ptr && ptr->next) ptr = ptr->next;
200 if(!ptr) tcpip_accepted_sockets = newsock;
201 else ptr->next = newsock;
203 uip_tcp_arg(newpcb,newsock);
204 uip_tcp_recv(newpcb,tcpip_recved);
205 uip_tcp_sent(newpcb,tcpip_sent);
206 uip_tcp_err(newpcb,tcpip_err);
207 uip_tcp_poll(newpcb,tcpip_poll,4);
209 return UIP_ERR_OK;
212 static void __tcpip_poll()
214 u32 diff;
215 s64 now;
217 if(uip_netif_default==NULL) return;
219 uip_bba_poll(uip_netif_default);
221 if(tcpip_time && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) {
222 now = gettime();
223 diff = diff_msec(tcpip_time,now);
224 if(diff>=UIP_TCP_TMR_INTERVAL) {
225 uip_tcp_tmr();
226 tcpip_time = gettime();
228 } else
229 tcpip_time = 0;
232 void tcpip_tmr_needed()
234 if(!tcpip_time && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) {
235 tcpip_time = gettime();
239 struct dbginterface* tcpip_init(struct uip_ip_addr *localip,struct uip_ip_addr *netmask,struct uip_ip_addr *gateway,u16 port)
241 uipdev_s hbba;
242 struct uip_netif *pnet ;
243 struct sockaddr_in name;
244 socklen_t namelen = sizeof(struct sockaddr);
246 memr_init();
247 uip_ipinit();
248 uip_pbuf_init();
249 uip_netif_init();
250 uip_tcp_init();
252 UIP_MEMSET(tcpip_socks,0,(UIP_TCPIP_SOCKS*sizeof(struct tcpip_sock)));
254 hbba = uip_bba_create(&netif);
255 pnet = uip_netif_add(&netif,localip,netmask,gateway,hbba,uip_bba_init,uip_ipinput);
256 if(pnet) {
257 uip_netif_setdefault(pnet);
259 listensock = tcpip_socket();
260 if(listensock<0) return NULL;
262 name.sin_addr.s_addr = INADDR_ANY;
263 name.sin_port = htons(port);
264 name.sin_family = AF_INET;
266 if(tcpip_bind(listensock,(struct sockaddr*)&name,&namelen)<0){
267 tcpip_close(listensock);
268 listensock = -1;
269 return NULL;
271 if(tcpip_listen(listensock,1)<0) {
272 tcpip_close(listensock);
273 listensock = -1;
274 return NULL;
277 netif_device.fhndl = -1;
278 netif_device.wait = waittcpip;
279 netif_device.open = opentcpip;
280 netif_device.close = closetcpip;
281 netif_device.read = readtcpip;
282 netif_device.write = writetcpip;
284 return &netif_device;
286 return NULL;
289 s32_t tcpip_socket()
291 s32_t s;
292 struct tcpip_sock *sock;
293 struct uip_tcp_pcb *pcb;
295 pcb = uip_tcp_new();
296 if(!pcb) return -1;
298 s = tcpip_allocsocket(pcb);
299 if(s<0) {
300 uip_tcp_close(pcb);
301 return -1;
304 sock = tcpip_getsocket(s);
305 uip_tcp_arg(pcb,sock);
307 return s;
310 s32_t tcpip_bind(s32_t s,struct sockaddr *name,socklen_t *namelen)
312 struct tcpip_sock *sock;
313 struct uip_ip_addr local_ip;
314 u16_t local_port;
315 s8_t err;
317 sock = tcpip_getsocket(s);
318 if(!sock) return -1;
320 local_ip.addr = ((struct sockaddr_in*)name)->sin_addr.s_addr;
321 local_port = ((struct sockaddr_in*)name)->sin_port;
323 err = uip_tcp_bind(sock->pcb,&local_ip,local_port);
325 return (s32_t)err;
328 s32_t tcpip_listen(s32_t s,u32_t backlog)
330 struct tcpip_sock *sock;
332 sock = tcpip_getsocket(s);
333 if(!sock) return -1;
335 sock->pcb = uip_tcp_listen(sock->pcb);
336 if(sock->pcb==NULL) return -1;
338 uip_tcp_accept(sock->pcb,tcpip_accept_func);
340 return 0;
343 s32_t tcpip_accept(s32_t s)
345 s32_t newsock = -1;
346 struct tcpip_sock *sock;
348 sock = tcpip_getsocket(s);
349 if(sock==NULL) return -1;
351 do {
352 __tcpip_poll();
353 } while(!tcpip_accepted_sockets);
355 newsock = tcpip_accepted_sockets->socket;
356 tcpip_accepted_sockets = tcpip_accepted_sockets->next;
358 return newsock;
361 s32_t tcpip_read(s32_t s,void *buffer,u32_t len)
363 u32_t off,copy;
364 u8_t *ptr;
365 struct uip_pbuf *p;
366 struct tcpip_sock *sock;
368 sock = tcpip_getsocket(s);
369 if(!sock) return -1;
371 do {
372 __tcpip_poll();
373 } while(sock->lastdata==NULL);
375 if(sock->lastdata) {
376 off = 0;
377 ptr = buffer;
378 while(len>0 && sock->lastdata) {
379 p = sock->lastdata;
381 if(len>p->len-sock->lastoffset) copy = (p->len-sock->lastoffset);
382 else copy = len;
384 UIP_MEMCPY(ptr+off,(u8_t*)p->payload+sock->lastoffset,copy);
386 off += copy;
387 len -= copy;
388 sock->lastoffset += copy;
390 if(sock->lastoffset>=p->len) {
391 sock->lastoffset = 0;
392 sock->lastdata = uip_pbuf_dequeue(p);
393 uip_pbuf_free(p);
395 if(qcnt>0) {
396 printf("tcpip_read(dequeuing %d)\n",--qcnt);
401 return off;
403 return -1;
406 s32_t tcpip_write(s32_t s,const void *buffer,u32_t len)
408 s8_t err;
409 u16_t snd_buf,copy;
410 struct tcpip_sock *sock;
412 sock = tcpip_getsocket(s);
413 if(!sock) return -1;
415 // printf("tcpip_write()\n");
416 while(len>0) {
417 do {
418 __tcpip_poll();
419 } while((snd_buf=uip_tcp_sndbuf(sock->pcb))==0);
421 if(len>snd_buf) copy = snd_buf;
422 else copy = len;
424 err = uip_tcp_write(sock->pcb,buffer,copy,1);
425 if(err==UIP_ERR_OK && (!sock->pcb->unacked || sock->pcb->flags&UIP_TF_NODELAY || sock->pcb->snd_queuelen>1))
426 uip_tcpoutput(sock->pcb);
428 buffer = buffer+copy;
429 len -= copy;
431 return UIP_ERR_OK;
434 void tcpip_close(s32_t s)
436 struct tcpip_sock *sock;
438 sock = tcpip_getsocket(s);
439 if(sock==NULL) return;
441 uip_tcp_close(sock->pcb);
442 sock->pcb = NULL;
445 // does basically only stop the tcpip timer
446 void tcpip_stoptimer(s32_t s)
448 struct tcpip_sock *sock;
450 sock = tcpip_getsocket(s);
451 if(!sock) return;
453 if(tcpip_time && sock->pcb && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) tcpip_time = 0;
456 // does basically only restart the tcpip timer
457 void tcpip_starttimer(s32_t s)
459 struct tcpip_sock *sock;
461 sock = tcpip_getsocket(s);
462 if(!sock) return;
464 if(tcpip_time==0 && sock->pcb && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) tcpip_time = gettime();