Fixed frame buffer allocation for AA modes
[libogc.git] / libdb / tcpip.c
blob791f04c60466e995dd1956d5cff8c2ac1242883e
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 */
35 struct tcpip_sock {
36 struct tcpip_sock *next;
37 struct uip_tcp_pcb *pcb;
38 struct uip_pbuf *lastdata;
39 s32 lastoffset,recvevt,sendevt,flags;
40 s32 err,socket;
41 } tcpip_socks[UIP_TCPIP_SOCKS];
43 static s64 tcpip_time = 0;
44 static s32 listensock = -1;
45 static struct uip_netif netif;
46 static struct dbginterface netif_device;
47 static struct tcpip_sock *tcpip_accepted_sockets = NULL;
49 extern s64 gettime();
50 extern u32 diff_msec(s64 start,s64 end);
52 const char *tcp_localip = "";
53 const char *tcp_netmask = "";
54 const char *tcp_gateway = "";
56 static s32_t tcpip_allocsocket(struct uip_tcp_pcb *pcb)
58 s32_t i;
60 for(i=0;i<UIP_TCPIP_SOCKS;i++) {
61 if(tcpip_socks[i].pcb==NULL) {
62 tcpip_socks[i].pcb = pcb;
63 tcpip_socks[i].lastdata = NULL;
64 tcpip_socks[i].lastoffset = 0;
65 tcpip_socks[i].recvevt = 0;
66 tcpip_socks[i].sendevt = 1;
67 tcpip_socks[i].flags = 0;
68 tcpip_socks[i].socket = i;
69 tcpip_socks[i].err = UIP_ERR_OK;
70 return i;
73 return -1;
76 static struct tcpip_sock* tcpip_getsocket(s32_t s)
78 struct tcpip_sock *sock;
80 if(s<0 || s>=UIP_TCPIP_SOCKS) return NULL;
82 sock = &tcpip_socks[s];
83 if(!sock->pcb) return NULL;
85 return sock;
88 //device callbacks
89 static int opentcpip(struct dbginterface *device)
91 if(listensock>=0 && (device->fhndl<0 ))
92 device->fhndl = tcpip_accept(listensock);
94 if(device->fhndl<0)
95 return -1;
96 else
97 tcpip_starttimer(device->fhndl);
99 return 0;
102 static int closetcpip(struct dbginterface *device)
104 tcpip_stoptimer(device->fhndl);
105 tcpip_close(device->fhndl);
106 device->fhndl = -1;
107 return 0;
110 static int waittcpip(struct dbginterface *device)
112 tcpip_stoptimer(device->fhndl);
113 return 0;
116 static int readtcpip(struct dbginterface *device,void *buffer,int size)
118 if(device->fhndl>=0)
119 return tcpip_read(device->fhndl,buffer,size);
121 return 0;
124 static int writetcpip(struct dbginterface *device,const void *buffer,int size)
126 if(device->fhndl>=0)
127 return tcpip_write(device->fhndl,buffer,size);
129 return 0;
132 static void tcpip_err(void *arg,s8_t err)
134 // printf("tcpip_err: err_code(%d)\n",err);
137 static s8_t tcpip_poll(void *arg,struct uip_tcp_pcb *pcb)
139 UIP_LOG("tcpip_poll()");
140 return UIP_ERR_OK;
143 static s8_t tcpip_sent(void *arg,struct uip_tcp_pcb *pcb,u16_t space)
145 // printf("tcpip_sent(%d)\n",space);
146 return UIP_ERR_OK;
149 //static u32 qcnt = 0;
151 static s8_t tcpip_recved(void *arg,struct uip_tcp_pcb *pcb,struct uip_pbuf *p,s8_t err)
153 u16_t len;
154 struct tcpip_sock *sock = (struct tcpip_sock*)arg;
156 //printf("tcpip_recved(%s (%d/%d))\n",(u8_t*)p->payload,p->len,p->tot_len);
157 if(!sock) {
158 uip_pbuf_free(p);
159 return UIP_ERR_VAL;
162 if(p) {
163 len = p->tot_len;
164 if(sock->lastdata==NULL) {
165 sock->lastdata = p;
166 } else {
168 qcnt++;
169 printf("tcpip_recved(queuing %d)\n",qcnt);
171 uip_pbuf_queue(sock->lastdata,p);
173 } else
174 len = 1;
176 uip_tcp_recved(pcb,len);
177 return UIP_ERR_OK;
181 static s8_t tcpip_accept_func(void *arg,struct uip_tcp_pcb *newpcb,s8_t err)
183 s32_t s;
184 struct tcpip_sock *ptr,*newsock = NULL;
185 struct tcpip_sock *sock = (struct tcpip_sock*)arg;
187 UIP_LOG("tcpip_accept_func()");
188 if(!sock) return UIP_ERR_ABRT;
190 s = tcpip_allocsocket(newpcb);
191 if(s<0) {
192 uip_tcp_close(newpcb);
193 return UIP_ERR_ABRT;
196 newsock = tcpip_getsocket(s);
197 newsock->pcb->flags |= UIP_TF_NODELAY;
199 ptr = tcpip_accepted_sockets;
200 while(ptr && ptr->next) ptr = ptr->next;
201 if(!ptr) tcpip_accepted_sockets = newsock;
202 else ptr->next = newsock;
204 uip_tcp_arg(newpcb,newsock);
205 uip_tcp_recv(newpcb,tcpip_recved);
206 uip_tcp_sent(newpcb,tcpip_sent);
207 uip_tcp_err(newpcb,tcpip_err);
208 uip_tcp_poll(newpcb,tcpip_poll,4);
210 return UIP_ERR_OK;
213 static void __tcpip_poll()
215 u32 diff;
216 s64 now;
218 if(uip_netif_default==NULL) return;
220 uip_bba_poll(uip_netif_default);
222 if(tcpip_time && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) {
223 now = gettime();
224 diff = diff_msec(tcpip_time,now);
225 if(diff>=UIP_TCP_TMR_INTERVAL) {
226 uip_tcp_tmr();
227 tcpip_time = gettime();
229 } else
230 tcpip_time = 0;
233 void tcpip_tmr_needed()
235 if(!tcpip_time && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) {
236 tcpip_time = gettime();
240 struct dbginterface* tcpip_init(struct uip_ip_addr *localip,struct uip_ip_addr *netmask,struct uip_ip_addr *gateway,u16 port)
242 uipdev_s hbba;
243 struct uip_netif *pnet ;
244 struct sockaddr_in name;
245 socklen_t namelen = sizeof(struct sockaddr);
247 memr_init();
248 uip_ipinit();
249 uip_pbuf_init();
250 uip_netif_init();
251 uip_tcp_init();
253 UIP_MEMSET(tcpip_socks,0,(UIP_TCPIP_SOCKS*sizeof(struct tcpip_sock)));
255 hbba = uip_bba_create(&netif);
256 pnet = uip_netif_add(&netif,localip,netmask,gateway,hbba,uip_bba_init,uip_ipinput);
257 if(pnet) {
258 uip_netif_setdefault(pnet);
260 listensock = tcpip_socket();
261 if(listensock<0) return NULL;
263 name.sin_addr.s_addr = INADDR_ANY;
264 name.sin_port = htons(port);
265 name.sin_family = AF_INET;
267 if(tcpip_bind(listensock,(struct sockaddr*)&name,&namelen)<0){
268 tcpip_close(listensock);
269 listensock = -1;
270 return NULL;
272 if(tcpip_listen(listensock,1)<0) {
273 tcpip_close(listensock);
274 listensock = -1;
275 return NULL;
278 netif_device.fhndl = -1;
279 netif_device.wait = waittcpip;
280 netif_device.open = opentcpip;
281 netif_device.close = closetcpip;
282 netif_device.read = readtcpip;
283 netif_device.write = writetcpip;
285 return &netif_device;
287 return NULL;
290 s32_t tcpip_socket()
292 s32_t s;
293 struct tcpip_sock *sock;
294 struct uip_tcp_pcb *pcb;
296 pcb = uip_tcp_new();
297 if(!pcb) return -1;
299 s = tcpip_allocsocket(pcb);
300 if(s<0) {
301 uip_tcp_close(pcb);
302 return -1;
305 sock = tcpip_getsocket(s);
306 uip_tcp_arg(pcb,sock);
308 return s;
311 s32_t tcpip_bind(s32_t s,struct sockaddr *name,socklen_t *namelen)
313 struct tcpip_sock *sock;
314 struct uip_ip_addr local_ip;
315 u16_t local_port;
316 s8_t err;
318 sock = tcpip_getsocket(s);
319 if(!sock) return -1;
321 local_ip.addr = ((struct sockaddr_in*)name)->sin_addr.s_addr;
322 local_port = ((struct sockaddr_in*)name)->sin_port;
324 err = uip_tcp_bind(sock->pcb,&local_ip,local_port);
326 return (s32_t)err;
329 s32_t tcpip_listen(s32_t s,u32_t backlog)
331 struct tcpip_sock *sock;
333 sock = tcpip_getsocket(s);
334 if(!sock) return -1;
336 sock->pcb = uip_tcp_listen(sock->pcb);
337 if(sock->pcb==NULL) return -1;
339 uip_tcp_accept(sock->pcb,tcpip_accept_func);
341 return 0;
344 s32_t tcpip_accept(s32_t s)
346 s32_t newsock = -1;
347 struct tcpip_sock *sock;
349 sock = tcpip_getsocket(s);
350 if(sock==NULL) return -1;
352 do {
353 __tcpip_poll();
354 } while(!tcpip_accepted_sockets);
356 newsock = tcpip_accepted_sockets->socket;
357 tcpip_accepted_sockets = tcpip_accepted_sockets->next;
359 return newsock;
362 s32_t tcpip_read(s32_t s,void *buffer,u32_t len)
364 u32_t off,copy;
365 u8_t *ptr;
366 struct uip_pbuf *p;
367 struct tcpip_sock *sock;
369 sock = tcpip_getsocket(s);
370 if(!sock) return -1;
372 do {
373 __tcpip_poll();
374 } while(sock->lastdata==NULL);
376 if(sock->lastdata) {
377 off = 0;
378 ptr = buffer;
379 while(len>0 && sock->lastdata) {
380 p = sock->lastdata;
382 if(len>p->len-sock->lastoffset) copy = (p->len-sock->lastoffset);
383 else copy = len;
385 UIP_MEMCPY(ptr+off,(u8_t*)p->payload+sock->lastoffset,copy);
387 off += copy;
388 len -= copy;
389 sock->lastoffset += copy;
391 if(sock->lastoffset>=p->len) {
392 sock->lastoffset = 0;
393 sock->lastdata = uip_pbuf_dequeue(p);
394 uip_pbuf_free(p);
396 if(qcnt>0) {
397 printf("tcpip_read(dequeuing %d)\n",--qcnt);
402 return off;
404 return -1;
407 s32_t tcpip_write(s32_t s,const void *buffer,u32_t len)
409 s8_t err;
410 u16_t snd_buf,copy;
411 struct tcpip_sock *sock;
413 sock = tcpip_getsocket(s);
414 if(!sock) return -1;
416 // printf("tcpip_write()\n");
417 while(len>0) {
418 do {
419 __tcpip_poll();
420 } while((snd_buf=uip_tcp_sndbuf(sock->pcb))==0);
422 if(len>snd_buf) copy = snd_buf;
423 else copy = len;
425 err = uip_tcp_write(sock->pcb,buffer,copy,1);
426 if(err==UIP_ERR_OK && (!sock->pcb->unacked || sock->pcb->flags&UIP_TF_NODELAY || sock->pcb->snd_queuelen>1))
427 uip_tcpoutput(sock->pcb);
429 buffer = buffer+copy;
430 len -= copy;
432 return UIP_ERR_OK;
435 void tcpip_close(s32_t s)
437 struct tcpip_sock *sock;
439 sock = tcpip_getsocket(s);
440 if(sock==NULL) return;
442 uip_tcp_close(sock->pcb);
443 sock->pcb = NULL;
446 // does basically only stop the tcpip timer
447 void tcpip_stoptimer(s32_t s)
449 struct tcpip_sock *sock;
451 sock = tcpip_getsocket(s);
452 if(!sock) return;
454 if(tcpip_time && sock->pcb && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) tcpip_time = 0;
457 // does basically only restart the tcpip timer
458 void tcpip_starttimer(s32_t s)
460 struct tcpip_sock *sock;
462 sock = tcpip_getsocket(s);
463 if(!sock) return;
465 if(tcpip_time==0 && sock->pcb && (uip_tcp_active_pcbs || uip_tcp_tw_pcbs)) tcpip_time = gettime();