source: rtems/c/src/lib/libbsp/arm/nds/dswifi/arm9/source/sgIP_sockets.c @ 311dfa6

4.104.114.95
Last change on this file since 311dfa6 was 311dfa6, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/08 at 18:37:33

2008-04-16 Matthieu Bucchianeri <mbucchia@…>

  • ChangeLog?, Makefile.am, README, bsp_specs, configure.ac, mk_libnds.sh, patch.libnds, preinstall.am, block/block.c, clock/clock.c, console/console.c, coproc/coproc.S, coproc/coproc.c, coproc/coproc.ld, dswifi/dswifi_license.txt, dswifi/makefile, dswifi/arm7/makefile, dswifi/arm7/source/wifi_arm7.c, dswifi/arm7/source/wifi_arm7.h, dswifi/arm9/makefile, dswifi/arm9/source/sgIP.c, dswifi/arm9/source/sgIP.h, dswifi/arm9/source/sgIP_ARP.c, dswifi/arm9/source/sgIP_ARP.h, dswifi/arm9/source/sgIP_Config.h, dswifi/arm9/source/sgIP_DHCP.c, dswifi/arm9/source/sgIP_DHCP.h, dswifi/arm9/source/sgIP_DNS.c, dswifi/arm9/source/sgIP_DNS.h, dswifi/arm9/source/sgIP_Hub.c, dswifi/arm9/source/sgIP_Hub.h, dswifi/arm9/source/sgIP_ICMP.c, dswifi/arm9/source/sgIP_ICMP.h, dswifi/arm9/source/sgIP_IP.c, dswifi/arm9/source/sgIP_IP.h, dswifi/arm9/source/sgIP_TCP.c, dswifi/arm9/source/sgIP_TCP.h, dswifi/arm9/source/sgIP_UDP.c, dswifi/arm9/source/sgIP_UDP.h, dswifi/arm9/source/sgIP_memblock.c, dswifi/arm9/source/sgIP_memblock.h, dswifi/arm9/source/sgIP_sockets.c, dswifi/arm9/source/sgIP_sockets.h, dswifi/arm9/source/wifi_arm9.c, dswifi/arm9/source/wifi_arm9.h, dswifi/common/source/dsregs.h, dswifi/common/source/spinlock.h, dswifi/common/source/spinlock.s, dswifi/common/source/wifi_shared.h, dswifi/include/dswifi7.h, dswifi/include/dswifi9.h, dswifi/include/dswifi_version.h, dswifi/include/netdb.h, dswifi/include/sgIP_errno.h, dswifi/include/netinet/in.h, fb/fb.c, fb/fb.h, include/bsp.h, include/my_ipc.h, include/tm27.h, include/types.h, include/sys/iosupport.h, irq/irq.c, irq/irq.h, libfat/gba/include/fat.h, libfat/include/fat.h, libfat/nds/include/fat.h, libfat/source/bit_ops.h, libfat/source/cache.c, libfat/source/cache.h, libfat/source/common.h, libfat/source/directory.c, libfat/source/directory.h, libfat/source/fatdir.c, libfat/source/fatdir.h, libfat/source/fatfile.c, libfat/source/fatfile.h, libfat/source/file_allocation_table.c, libfat/source/file_allocation_table.h, libfat/source/filetime.c, libfat/source/filetime.h, libfat/source/libfat.c, libfat/source/mem_allocate.h, libfat/source/partition.c, libfat/source/partition.h, libfat/source/disc_io/disc.c, libfat/source/disc_io/disc.h, libfat/source/disc_io/disc_io.h, libfat/source/disc_io/io_cf_common.c, libfat/source/disc_io/io_cf_common.h, libfat/source/disc_io/io_dldi.h, libfat/source/disc_io/io_dldi.s, libfat/source/disc_io/io_efa2.c, libfat/source/disc_io/io_efa2.h, libfat/source/disc_io/io_fcsr.c, libfat/source/disc_io/io_fcsr.h, libfat/source/disc_io/io_m3_common.c, libfat/source/disc_io/io_m3_common.h, libfat/source/disc_io/io_m3cf.c, libfat/source/disc_io/io_m3cf.h, libfat/source/disc_io/io_m3sd.c, libfat/source/disc_io/io_m3sd.h, libfat/source/disc_io/io_mpcf.c, libfat/source/disc_io/io_mpcf.h, libfat/source/disc_io/io_njsd.c, libfat/source/disc_io/io_njsd.h, libfat/source/disc_io/io_nmmc.c, libfat/source/disc_io/io_nmmc.h, libfat/source/disc_io/io_sc_common.c, libfat/source/disc_io/io_sc_common.h, libfat/source/disc_io/io_sccf.c, libfat/source/disc_io/io_sccf.h, libfat/source/disc_io/io_scsd.c, libfat/source/disc_io/io_scsd.h, libfat/source/disc_io/io_scsd_s.s, libfat/source/disc_io/io_sd_common.c, libfat/source/disc_io/io_sd_common.h, libnds/Makefile.arm7, libnds/Makefile.arm9, libnds/libnds_license.txt, libnds/basicARM7/source/defaultARM7.c, libnds/include/default_font_bin.h, libnds/include/gbfs.h, libnds/include/nds.h, libnds/include/nds/bios.h, libnds/include/nds/card.h, libnds/include/nds/dma.h, libnds/include/nds/interrupts.h, libnds/include/nds/ipc.h, libnds/include/nds/jtypes.h, libnds/include/nds/memory.h, libnds/include/nds/registers_alt.h, libnds/include/nds/reload.h, libnds/include/nds/system.h, libnds/include/nds/timers.h, libnds/include/nds/arm7/audio.h, libnds/include/nds/arm7/clock.h, libnds/include/nds/arm7/serial.h, libnds/include/nds/arm7/touch.h, libnds/include/nds/arm9/background.h, libnds/include/nds/arm9/boxtest.h, libnds/include/nds/arm9/cache.h, libnds/include/nds/arm9/console.h, libnds/include/nds/arm9/exceptions.h, libnds/include/nds/arm9/image.h, libnds/include/nds/arm9/input.h, libnds/include/nds/arm9/math.h, libnds/include/nds/arm9/ndsmotion.h, libnds/include/nds/arm9/pcx.h, libnds/include/nds/arm9/postest.h, libnds/include/nds/arm9/rumble.h, libnds/include/nds/arm9/sound.h, libnds/include/nds/arm9/sprite.h, libnds/include/nds/arm9/trig_lut.h, libnds/include/nds/arm9/video.h, libnds/include/nds/arm9/videoGL.h, libnds/source/arm7/audio.c, libnds/source/arm7/clock.c, libnds/source/arm7/microphone.c, libnds/source/arm7/spi.c, libnds/source/arm7/touch.c, libnds/source/arm7/userSettings.c, libnds/source/arm9/COS.bin, libnds/source/arm9/COS.s, libnds/source/arm9/SIN.bin, libnds/source/arm9/SIN.s, libnds/source/arm9/TAN.bin, libnds/source/arm9/TAN.s, libnds/source/arm9/boxtest.c, libnds/source/arm9/console.c, libnds/source/arm9/dcache.s, libnds/source/arm9/default_font.bin, libnds/source/arm9/default_font.s, libnds/source/arm9/exceptionHandler.S, libnds/source/arm9/exceptionHandler.s, libnds/source/arm9/exceptions.c, libnds/source/arm9/gurumeditation.c, libnds/source/arm9/icache.s, libnds/source/arm9/image.c, libnds/source/arm9/initSystem.c, libnds/source/arm9/keys.c, libnds/source/arm9/ndsmotion.c, libnds/source/arm9/pcx.c, libnds/source/arm9/rumble.c, libnds/source/arm9/sound.c, libnds/source/arm9/system.c, libnds/source/arm9/touch.c, libnds/source/arm9/video.c, libnds/source/arm9/videoGL.c, libnds/source/common/biosCalls.s, libnds/source/common/card.c, libnds/source/common/gbfs.c, libnds/source/common/interruptDispatcher.s, libnds/source/common/interrupts.c, rtc/rtc.c, sound/sound.c, sound/sound.h, start/start.S, startup/linkcmds, startup/start.c, timer/timer.c, tools/Makefile.am, tools/bin2s, tools/bin2s.c, tools/configure.ac, tools/runtest, tools/ndstool/include/arm7_sha1_homebrew.h, tools/ndstool/include/arm7_sha1_nintendo.h, tools/ndstool/include/banner.h, tools/ndstool/include/bigint.h, tools/ndstool/include/crc.h, tools/ndstool/include/default_icon.h, tools/ndstool/include/encryption.h, tools/ndstool/include/header.h, tools/ndstool/include/hook.h, tools/ndstool/include/little.h, tools/ndstool/include/loadme.h, tools/ndstool/include/logo.h, tools/ndstool/include/ndscreate.h, tools/ndstool/include/ndsextract.h, tools/ndstool/include/ndstool.h, tools/ndstool/include/ndstree.h, tools/ndstool/include/overlay.h, tools/ndstool/include/passme.h, tools/ndstool/include/passme_sram.h, tools/ndstool/include/passme_vhd1.h, tools/ndstool/include/passme_vhd2.h, tools/ndstool/include/raster.h, tools/ndstool/include/sha1.h, tools/ndstool/include/types.h, tools/ndstool/source/arm7_sha1_homebrew.c, tools/ndstool/source/arm7_sha1_nintendo.c, tools/ndstool/source/banner.cpp, tools/ndstool/source/bigint.cpp, tools/ndstool/source/compile_date.c, tools/ndstool/source/crc.cpp, tools/ndstool/source/default_icon.c, tools/ndstool/source/encryption.cpp, tools/ndstool/source/header.cpp, tools/ndstool/source/hook.cpp, tools/ndstool/source/loadme.c, tools/ndstool/source/logo.cpp, tools/ndstool/source/ndscodes.cpp, tools/ndstool/source/ndscreate.cpp, tools/ndstool/source/ndsextract.cpp, tools/ndstool/source/ndstool.cpp, tools/ndstool/source/ndstree.cpp, tools/ndstool/source/passme.cpp, tools/ndstool/source/passme_sram.c, tools/ndstool/source/raster.cpp, tools/ndstool/source/sha1.cpp, touchscreen/README.reco, touchscreen/parser.c, touchscreen/reco.c, touchscreen/reco.h, touchscreen/touchscreen.c, touchscreen/touchscreen.h, wifi/compat.c, wifi/compat.h, wifi/wifi.c: New files.
  • Property mode set to 100644
File size: 18.0 KB
Line 
1// DSWifi Project - sgIP Internet Protocol Stack Implementation
2// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
3/******************************************************************************
4DSWifi Lib and test materials are licenced under the MIT open source licence:
5Copyright (c) 2005-2006 Stephen Stair
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of
8this software and associated documentation files (the "Software"), to deal in
9the Software without restriction, including without limitation the rights to
10use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11of the Software, and to permit persons to whom the Software is furnished to do
12so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24******************************************************************************/
25
26#include "sgIP_sockets.h"
27#include "sgIP_TCP.h"
28#include "sgIP_UDP.h"
29#include "sgIP_ICMP.h"
30#include "sgIP_DNS.h"
31
32
33sgIP_socket_data socketlist[SGIP_SOCKET_MAXSOCKETS];
34extern unsigned long sgIP_timems;
35
36
37void sgIP_sockets_Init() {
38        int i;
39        for(i=0;i<SGIP_SOCKET_MAXSOCKETS;i++) {
40                socketlist[i].conn_ptr=0;
41                socketlist[i].flags = 0;
42        }
43}
44
45 // spawn/kill socket for internal use ONLY.
46int spawn_socket(int flags) {
47   int s;
48   SGIP_INTR_PROTECT();
49   for(s=0;s<SGIP_SOCKET_MAXSOCKETS;s++) if(!(socketlist[s].flags&SGIP_SOCKET_FLAG_ACTIVE)) break;
50   if(s==SGIP_SOCKET_MAXSOCKETS) {
51      SGIP_INTR_UNPROTECT();
52      return SGIP_ERROR(ENOMEM);
53   }
54   socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | flags;
55   socketlist[s].conn_ptr=0;
56   SGIP_INTR_UNPROTECT();
57   return s+1;
58}
59int kill_socket(int s) {
60   if(s<1 || s>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
61   SGIP_INTR_PROTECT();
62   s--;
63   socketlist[s].conn_ptr=0;
64   socketlist[s].flags=0;
65   SGIP_INTR_UNPROTECT();
66   return 0;
67}
68
69int socket(int domain, int type, int protocol) {
70        int s;
71        if(domain!=AF_INET) return SGIP_ERROR(EINVAL);
72        if(protocol!=0) return SGIP_ERROR(EINVAL);
73        if(type!=SOCK_DGRAM && type!=SOCK_STREAM) return SGIP_ERROR(EINVAL);
74        SGIP_INTR_PROTECT();
75        for(s=0;s<SGIP_SOCKET_MAXSOCKETS;s++) if(!(socketlist[s].flags&SGIP_SOCKET_FLAG_ACTIVE)) break;
76   if(s==SGIP_SOCKET_MAXSOCKETS) {
77      SGIP_INTR_UNPROTECT();
78      return SGIP_ERROR(ENOMEM);
79   }
80        if(type==SOCK_STREAM) {
81                socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_TCP;
82                socketlist[s].conn_ptr=sgIP_TCP_AllocRecord();
83        } else if(type==SOCK_DGRAM) {
84                socketlist[s].flags=SGIP_SOCKET_FLAG_ACTIVE | SGIP_SOCKET_FLAG_TYPE_UDP;
85                socketlist[s].conn_ptr=sgIP_UDP_AllocRecord();         
86        } else {
87                SGIP_INTR_UNPROTECT();
88                return SGIP_ERROR(EINVAL);
89        }
90#ifdef SGIP_SOCKET_DEFAULT_NONBLOCK
91        socketlist[s].flags|=SGIP_SOCKET_FLAG_NONBLOCKING;
92#endif
93        SGIP_INTR_UNPROTECT();
94        return s+1;
95}
96
97
98int closesocket(int socket) {
99        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
100        SGIP_INTR_PROTECT();
101        socket--;
102        if(!(socketlist[socket].flags&SGIP_SOCKET_FLAG_ACTIVE)) { SGIP_INTR_UNPROTECT(); return 0; }
103        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
104                sgIP_TCP_FreeRecord((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
105        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
106                sgIP_UDP_FreeRecord((sgIP_Record_UDP *)socketlist[socket].conn_ptr);
107        }
108        socketlist[socket].conn_ptr=0;
109        socketlist[socket].flags=0;
110        SGIP_INTR_UNPROTECT();
111        return 0;
112}
113
114int bind(int socket, const struct sockaddr * addr, int addr_len) {
115        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
116   if(addr_len!=sizeof(struct sockaddr_in)) return SGIP_ERROR(EINVAL);
117        SGIP_INTR_PROTECT();
118        int retval=SGIP_ERROR(EINVAL);
119        socket--;
120        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
121      retval=sgIP_TCP_Bind((sgIP_Record_TCP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_port,((struct sockaddr_in *)addr)->sin_addr.s_addr);
122        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
123                retval=sgIP_UDP_Bind((sgIP_Record_UDP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_port,((struct sockaddr_in *)addr)->sin_addr.s_addr);
124        }
125        SGIP_INTR_UNPROTECT();
126        return retval;
127}
128int connect(int socket, const struct sockaddr * addr, int addr_len) {
129   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
130   if(addr_len!=sizeof(struct sockaddr_in)) return SGIP_ERROR(EINVAL);
131   SGIP_INTR_PROTECT();
132   int i;
133   int retval=SGIP_ERROR(EINVAL);
134   socket--;
135   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
136      retval=sgIP_TCP_Connect((sgIP_Record_TCP *)socketlist[socket].conn_ptr,((struct sockaddr_in *)addr)->sin_addr.s_addr,((struct sockaddr_in *)addr)->sin_port);
137          if(retval==0) {
138                do {
139                        i=((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->tcpstate;
140                        if(i==SGIP_TCP_STATE_ESTABLISHED || i==SGIP_TCP_STATE_CLOSE_WAIT) {retval=0; break;}
141                        if(i==SGIP_TCP_STATE_CLOSED || i==SGIP_TCP_STATE_UNUSED || i==SGIP_TCP_STATE_LISTEN || i==SGIP_TCP_STATE_NODATA)
142                        {       retval=SGIP_ERROR(((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->errorcode); break; }
143                        if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
144                        SGIP_INTR_UNPROTECT();
145                        SGIP_WAITEVENT();
146                        SGIP_INTR_REPROTECT();
147                } while(1);
148          }
149   }
150   SGIP_INTR_UNPROTECT();
151   return retval;
152}
153int send(int socket, const void * data, int sendlength, int flags) {
154   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
155   SGIP_INTR_PROTECT();
156   int retval=SGIP_ERROR(EINVAL);
157   socket--;
158   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
159       do {
160           retval=sgIP_TCP_Send((sgIP_Record_TCP *)socketlist[socket].conn_ptr,data,sendlength,flags);
161           if(retval!=-1) break;
162           if(errno!=EWOULDBLOCK) break;
163           if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
164           SGIP_INTR_UNPROTECT();
165           SGIP_WAITEVENT();
166           SGIP_INTR_REPROTECT();
167       } while(1);
168   }
169   SGIP_INTR_UNPROTECT();
170   return retval;
171}
172int recv(int socket, void * data, int recvlength, int flags) {
173   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
174   SGIP_INTR_PROTECT();
175   int retval=SGIP_ERROR(EINVAL);
176   socket--;
177   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
178      do {
179         retval=sgIP_TCP_Recv((sgIP_Record_TCP *)socketlist[socket].conn_ptr,data,recvlength,flags);
180         if(retval!=-1) break;
181         if(errno!=EWOULDBLOCK) break;
182         if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
183         SGIP_INTR_UNPROTECT();
184         SGIP_WAITEVENT();
185         SGIP_INTR_REPROTECT();
186      } while(1);
187   }
188   SGIP_INTR_UNPROTECT();
189   return retval;
190}
191int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len) {
192        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
193        if(!addr) return -1;
194        SGIP_INTR_PROTECT();
195        int retval=SGIP_ERROR(EINVAL);
196        socket--;
197        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
198        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
199                retval=sgIP_UDP_SendTo((sgIP_Record_UDP *)socketlist[socket].conn_ptr,data,sendlength,flags,((struct sockaddr_in *)addr)->sin_addr.s_addr,((struct sockaddr_in *)addr)->sin_port);
200        }
201        SGIP_INTR_UNPROTECT();
202        return retval;
203}
204int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len) {
205        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return -1;
206        if(!addr) return -1;
207        SGIP_INTR_PROTECT();
208        int retval=SGIP_ERROR(EINVAL);
209        socket--;
210        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
211        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
212      do {
213         retval=sgIP_UDP_RecvFrom((sgIP_Record_UDP *)socketlist[socket].conn_ptr,data,recvlength,flags,&(((struct sockaddr_in *)addr)->sin_addr.s_addr),&(((struct sockaddr_in *)addr)->sin_port));
214         if(retval!=-1) break;
215         if(errno!=EWOULDBLOCK) break;
216         if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
217         SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
218         SGIP_WAITEVENT(); // don't just try again immediately
219         SGIP_INTR_REPROTECT();
220      } while(1);
221                *addr_len = sizeof(struct sockaddr_in);
222        }
223        SGIP_INTR_UNPROTECT();
224        return retval;
225}
226int listen(int socket, int max_connections) {
227   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
228   SGIP_INTR_PROTECT();
229   int retval=SGIP_ERROR(EINVAL);
230   socket--;
231   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
232      retval=sgIP_TCP_Listen((sgIP_Record_TCP *)socketlist[socket].conn_ptr,max_connections);
233   }
234   SGIP_INTR_UNPROTECT();
235   return retval;
236}
237int accept(int socket, struct sockaddr * addr, int * addr_len) {
238   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS || !addr || !addr_len) return SGIP_ERROR(EINVAL);
239   SGIP_INTR_PROTECT();
240   sgIP_Record_TCP * ret;
241   int retval,s;
242   retval=SGIP_ERROR0(EINVAL);
243   ret=0;
244   socket--;
245   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
246      s=spawn_socket((socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) | SGIP_SOCKET_FLAG_TYPE_TCP);
247      if(s>0) {
248         do {
249            ret=sgIP_TCP_Accept((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
250            if(ret!=0) break;
251            if(errno!=EWOULDBLOCK) break;
252            if(socketlist[socket].flags&SGIP_SOCKET_FLAG_NONBLOCKING) break;
253            SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
254            SGIP_WAITEVENT(); // don't just try again immediately
255            SGIP_INTR_REPROTECT();
256         } while(1);
257      }
258      if(ret==0) {
259         kill_socket(s);
260         retval=-1;
261      } else {
262                 *addr_len=sizeof(struct sockaddr_in);
263                 ((struct sockaddr_in *)addr)->sin_family=AF_INET;
264                 ((struct sockaddr_in *)addr)->sin_port=ret->destport;
265                 ((struct sockaddr_in *)addr)->sin_addr.s_addr=ret->destip;
266         socketlist[s-1].conn_ptr=ret;
267         retval=s;
268      }
269   }
270   SGIP_INTR_UNPROTECT();
271   return retval;
272}
273int shutdown(int socket, int shutdown_type) {
274   if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EINVAL);
275   SGIP_INTR_PROTECT();
276   int retval=SGIP_ERROR(EINVAL);
277   socket--;
278   if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
279           retval=sgIP_TCP_Close((sgIP_Record_TCP *)socketlist[socket].conn_ptr);
280   }
281   SGIP_INTR_UNPROTECT();
282   return retval;
283}
284
285int ioctl(int socket, long cmd, void * arg) {
286        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
287        socket--;
288        int retval,i;
289        retval=0;
290        SGIP_INTR_PROTECT();
291        switch(cmd) {
292        case FIONBIO:
293                if(!arg){
294                        retval=SGIP_ERROR(EINVAL);
295                } else {
296                        socketlist[socket].flags &= ~SGIP_SOCKET_FLAG_NONBLOCKING;
297                        if(*((unsigned long *)arg)) socketlist[socket].flags |= SGIP_SOCKET_FLAG_NONBLOCKING;
298                }
299                break;
300        case FIONREAD:
301                if(!arg) {
302                        retval=SGIP_ERROR(EINVAL);
303                } else {
304                        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
305                                i=((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->buf_rx_out-((sgIP_Record_TCP *)socketlist[socket].conn_ptr)->buf_rx_in;
306                                if(i<0) i+=SGIP_TCP_RECEIVEBUFFERLENGTH;
307                                *((int *)arg)=i;
308                        } else {
309                                retval=SGIP_ERROR(EINVAL);
310                        }
311                }
312        }
313        SGIP_INTR_UNPROTECT();
314        return retval;
315}
316
317int setsockopt(int socket, int level, int option_name, const void * data, int data_len) {
318   return 0;
319}
320int getsockopt(int socket, int level, int option_name, void * data, int * data_len) {
321   return 0;
322}
323
324int getpeername(int socket, struct sockaddr *addr, int * addr_len) {
325        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
326        if(!addr || !addr_len) return SGIP_ERROR(EFAULT);
327        if(*addr_len<sizeof(struct sockaddr_in)) return SGIP_ERROR(EFAULT);
328        socket--;
329        SGIP_INTR_PROTECT();
330        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
331                {
332                        struct sockaddr_in * sain = (struct sockaddr_in *)addr;
333                        sgIP_Record_TCP * rec = (sgIP_Record_TCP *)socketlist[socket].conn_ptr;
334                        if(rec->tcpstate!=SGIP_TCP_STATE_ESTABLISHED) {
335                                SGIP_INTR_UNPROTECT();
336                                return SGIP_ERROR(ENOTCONN);
337                        } else {
338                                sain->sin_addr.s_addr=rec->destip;
339                                sain->sin_family=AF_INET;
340                                sain->sin_port=rec->destport;
341                                *addr_len=sizeof(struct sockaddr_in);
342                        }
343                }
344        } else {
345                SGIP_INTR_UNPROTECT();
346                return SGIP_ERROR(EOPNOTSUPP);
347        }
348        SGIP_INTR_UNPROTECT();
349        return 0;
350}
351int getsockname(int socket, struct sockaddr *addr, int * addr_len) {
352        if(socket<1 || socket>SGIP_SOCKET_MAXSOCKETS) return SGIP_ERROR(EBADF);
353        if(!addr || !addr_len) return SGIP_ERROR(EFAULT);
354        if(*addr_len<sizeof(struct sockaddr_in)) return SGIP_ERROR(EFAULT);
355        socket--;
356        SGIP_INTR_PROTECT();
357        if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
358                {
359                        struct sockaddr_in * sain = (struct sockaddr_in *)addr;
360                        sgIP_Record_TCP * rec = (sgIP_Record_TCP *)socketlist[socket].conn_ptr;
361                        if(rec->tcpstate==SGIP_TCP_STATE_UNUSED || rec->tcpstate==SGIP_TCP_STATE_CLOSED) {
362                                SGIP_INTR_UNPROTECT();
363                                return SGIP_ERROR(EINVAL);
364                        } else {
365                                sain->sin_addr.s_addr=rec->srcip;
366                                sain->sin_family=AF_INET;
367                                sain->sin_port=rec->srcport;
368                                *addr_len=sizeof(struct sockaddr_in);
369                        }
370                }
371        } else if((socketlist[socket].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
372        {
373            struct sockaddr_in * sain = (struct sockaddr_in *)addr;
374            sgIP_Record_UDP * rec = (sgIP_Record_UDP *)socketlist[socket].conn_ptr;
375            if(rec->state==SGIP_UDP_STATE_UNUSED) {
376                SGIP_INTR_UNPROTECT();
377                return SGIP_ERROR(EINVAL);
378            } else {
379                sain->sin_addr.s_addr=rec->srcip;
380                sain->sin_family=AF_INET;
381                sain->sin_port=rec->srcport;
382                *addr_len=sizeof(struct sockaddr_in);
383            }
384        }
385        } else {
386                SGIP_INTR_UNPROTECT();
387                return SGIP_ERROR(EOPNOTSUPP);
388        }
389        SGIP_INTR_UNPROTECT();
390        return 0;
391}
392
393
394struct hostent * gethostbyname(const char * name) {
395   return (struct hostent *)sgIP_DNS_gethostbyname(name);
396};
397
398
399extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout) {
400        // 31 days = 2678400 seconds
401        unsigned long timeout_ms, lasttime, temp;
402        sgIP_Record_TCP * rec;
403        sgIP_Record_UDP * urec;
404        lasttime=sgIP_timems;
405        if(!timeout) timeout_ms=2678400000UL;
406        else {
407                if(timeout->tv_sec>=2678400) {
408                        timeout_ms=2678400000UL;
409                } else {
410                        timeout_ms=timeout->tv_sec*1000 + (timeout->tv_usec/1000);
411                }
412        }
413        SGIP_INTR_PROTECT();
414        nfds=SGIP_SOCKET_MAXSOCKETS;
415
416        int i,j,retval;
417        while(timeout_ms>0) { // check all fd sets
418                // readfds
419                if(readfds) {
420                        for(i=0;i<nfds;i++) {
421                                if(FD_ISSET(i+1,readfds)) {
422                                        if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
423                                                rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
424                                                if(rec->buf_rx_in!=rec->buf_rx_out) { timeout_ms=0; break; }
425                                        } else if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
426                                                urec = (sgIP_Record_UDP *)socketlist[i].conn_ptr;
427                                                if(urec->incoming_queue) { timeout_ms=0; break; }
428                                        }
429                                }
430                        }
431                        if(timeout_ms==0) break;
432                }
433                if(writefds) {
434                        // writefds
435                        for(i=0;i<nfds;i++) {
436                                if(FD_ISSET(i+1,writefds)) {
437                                        if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
438                                                rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
439                                                j=rec->buf_tx_in-1;
440                                                if(j<0) j=SGIP_TCP_TRANSMITBUFFERLENGTH-1;
441                                                if(rec->buf_tx_in!=j) { timeout_ms=0; break; }
442                                        }
443                                }
444                        }
445                        if(timeout_ms==0) break;
446                }
447                // errorfds
448                // ignore errorfds for now.
449
450                temp=sgIP_timems-lasttime;
451                if(timeout_ms<temp) timeout_ms=0; else timeout_ms -= temp;
452                lasttime+=temp;
453                SGIP_INTR_UNPROTECT(); // give interrupts a chance to occur.
454                SGIP_WAITEVENT(); // don't just try again immediately
455                SGIP_INTR_REPROTECT();
456        }
457        // markup fd sets and return
458        // readfds
459        retval=0;
460        if(readfds) {
461                for(i=0;i<nfds;i++) {
462                        if(FD_ISSET(i+1,readfds)) {
463                                if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
464                                        rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
465                                        if(rec->buf_rx_in==rec->buf_rx_out) { FD_CLR(i+1,readfds);} else retval++;
466                                } else if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_UDP) {
467                                        urec = (sgIP_Record_UDP *)socketlist[i].conn_ptr;
468                                        if(!urec->incoming_queue) { FD_CLR(i+1,readfds);} else retval++;
469                                }
470                        }
471                }
472        }
473
474        // writefds
475        if(writefds) {
476                for(i=0;i<nfds;i++) {
477                        if(FD_ISSET(i+1,writefds)) {
478                                if((socketlist[i].flags&SGIP_SOCKET_FLAG_TYPEMASK)==SGIP_SOCKET_FLAG_TYPE_TCP) {
479                                        rec = (sgIP_Record_TCP *)socketlist[i].conn_ptr;
480                                        j=rec->buf_tx_in-1;
481                                        if(j<0) j=SGIP_TCP_TRANSMITBUFFERLENGTH-1;
482                                        if(rec->buf_tx_in==j) { FD_CLR(i+1,writefds); } else retval++;
483                                }
484                        }
485                }
486        }
487
488        if(errorfds) { FD_ZERO(errorfds); }
489
490        SGIP_INTR_UNPROTECT();
491        return retval;
492}
493
494
495/*
496extern void FD_CLR(int fd, fd_set * fdset) {
497        if(fd<1 || fd>FD_SETSIZE || !fdset) return;
498        fd--;
499        fdset->fdbits[fd>>5] &= ~(1<<(fd&31));
500}
501extern int FD_ISSET(int fd, fd_set * fdset) {
502        if(fd<1 || fd>FD_SETSIZE || !fdset) return 0;
503        fd--;
504        return (fdset->fdbits[fd>>5] & 1<<(fd&31))?1:0;
505}
506extern void FD_SET(int fd, fd_set * fdset) {
507        if(fd<1 || fd>FD_SETSIZE || !fdset) return;
508        fd--;
509        fdset->fdbits[fd>>5] |= 1<<(fd&31);
510}
511extern void FD_ZERO(fd_set * fdset) {
512        int i;
513        if(!fdset) return;
514        for(i=0;i<(FD_SETSIZE+31)/32;i++) {
515                fdset->fdbits[i]=0;
516        }
517}
518*/
519
520
Note: See TracBrowser for help on using the repository browser.