00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include <ubixos/types.h>
00037 
00038 #include "net/debug.h"
00039 #include "net/api.h"
00040 
00041 #include "net/sockets.h"
00042 
00043 #define NUM_SOCKETS 10
00044 
00045 struct lwip_socket {
00046   struct netconn *conn;
00047   struct netbuf *lastdata;
00048   uInt16 lastoffset;
00049 };
00050 
00051 static struct lwip_socket sockets[NUM_SOCKETS];
00052 
00053 
00054 static struct lwip_socket *
00055 get_socket(int s)
00056 {
00057   struct lwip_socket *sock;
00058   
00059   if(s > NUM_SOCKETS) {
00060     
00061     return NULL;
00062   }
00063   
00064   sock = &sockets[s];
00065 
00066   if(sock->conn == NULL) {
00067     
00068     return NULL;
00069   }
00070   return sock;
00071 }
00072 
00073 static int
00074 alloc_socket(struct netconn *newconn)
00075 {
00076   int i;
00077   
00078   
00079   for(i = 0; i < NUM_SOCKETS; ++i) {
00080     if(sockets[i].conn == NULL) {
00081       sockets[i].conn = newconn;
00082       sockets[i].lastdata = NULL;
00083       sockets[i].lastoffset = 0;
00084       return i;
00085     }
00086   }
00087   return -1;
00088 }
00089 
00090 int
00091 lwip_accept(int s, struct sockaddr *addr, int *addrlen)
00092 {
00093   struct lwip_socket *sock;
00094   struct netconn *newconn;
00095   struct ip_addr *naddr;
00096   uInt16 port;
00097   int newsock;
00098 
00099   sock = get_socket(s);
00100   if(sock == NULL) {
00101     return -1;
00102   }
00103   
00104   newconn = netconn_accept(sock->conn);
00105     
00106   
00107   netconn_peer(newconn, &naddr, &port);
00108   
00109   ((struct sockaddr_in *)addr)->sin_addr.s_addr = naddr->addr;
00110   ((struct sockaddr_in *)addr)->sin_port = port;
00111 
00112   newsock = alloc_socket(newconn);
00113   if(newsock == -1) {  
00114     netconn_delete(newconn);
00115     
00116   }
00117   return newsock;
00118 }
00119 
00120 int
00121 lwip_bind(int s, struct sockaddr *name, int namelen)
00122 {
00123   struct lwip_socket *sock;
00124   struct ip_addr remote_addr;
00125   uInt16 remote_port;
00126   err_t err;
00127   
00128   sock = get_socket(s);
00129   if(sock == NULL) {
00130     return -1;
00131   }
00132   
00133   remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
00134   remote_port = ((struct sockaddr_in *)name)->sin_port;
00135   
00136   err = netconn_bind(sock->conn, &remote_addr, ntohs(remote_port));
00137 
00138   if(err != ERR_OK) {
00139     
00140     return -1;
00141   }
00142 
00143   return 0;
00144 }
00145 
00146 int
00147 lwip_close(int s)
00148 {
00149   struct lwip_socket *sock;
00150   
00151   DEBUGF(SOCKETS_DEBUG, ("close: socket %d\n", s));
00152   sock = get_socket(s);
00153   if(sock == NULL) {
00154     return -1;
00155   }
00156   
00157   
00158   netconn_delete(sock->conn);
00159   if(sock->lastdata != NULL) {
00160     netbuf_delete(sock->lastdata);
00161   }
00162   sock->lastdata = NULL;
00163   sock->lastoffset = 0;
00164   sock->conn = NULL;
00165   return 0;
00166 }
00167 
00168 int
00169 lwip_connect(int s, struct sockaddr *name, int namelen)
00170 {
00171   struct lwip_socket *sock;
00172   struct ip_addr remote_addr;
00173   uInt16 remote_port;
00174   err_t err;
00175 
00176   sock = get_socket(s);
00177   if(sock == NULL) {
00178     return -1;
00179   }
00180   
00181   remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
00182   remote_port = ((struct sockaddr_in *)name)->sin_port;
00183   
00184   err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
00185 
00186   if(err != ERR_OK) {
00187     
00188     return -1;
00189   }
00190 
00191   return 0;
00192 }
00193 
00194 int
00195 lwip_listen(int s, int backlog)
00196 {
00197   struct lwip_socket *sock;    
00198   err_t err;
00199   
00200   sock = get_socket(s);
00201   if(sock == NULL) {
00202     return -1;
00203   }
00204  
00205   err = netconn_listen(sock->conn);
00206 
00207   if(err != ERR_OK) {
00208     
00209     return -1;
00210   }
00211 
00212   return 0;
00213 }
00214 
00215 int
00216 lwip_recvfrom(int s, void *mem, int len, unsigned int flags,
00217               struct sockaddr *from, int *fromlen)
00218 {
00219   struct lwip_socket *sock;
00220   struct netbuf *buf;
00221   uInt16 buflen, copylen;
00222   struct ip_addr *addr;
00223   uInt16 port;
00224 
00225   
00226   sock = get_socket(s);
00227   if(sock == NULL) {
00228     return -1;
00229   }
00230 
00231   
00232   if(sock->lastdata != NULL) {    
00233     buf = sock->lastdata;
00234   } else {
00235     
00236 
00237     buf = netconn_recv(sock->conn);
00238     
00239     if(buf == NULL) {
00240       
00241       return 0;
00242     }
00243   }
00244   
00245   buflen = netbuf_len(buf);
00246 
00247   buflen -= sock->lastoffset;
00248   
00249   if(len > buflen) {
00250     copylen = buflen;
00251   } else {
00252     copylen = len;
00253   }
00254   
00255   
00256 
00257   netbuf_copy_partial(buf, mem, copylen, sock->lastoffset);
00258 
00259   
00260 
00261 
00262   if(netconn_type(sock->conn) == NETCONN_TCP && buflen - copylen > 0) {
00263     sock->lastdata = buf;
00264     sock->lastoffset = buflen - copylen;
00265   } else {
00266     sock->lastdata = NULL;
00267     sock->lastoffset = 0;
00268     netbuf_delete(buf);
00269   }
00270 
00271   
00272   if(from != NULL && fromlen != NULL) {
00273     addr = netbuf_fromaddr(buf);
00274     port = htons(netbuf_fromport(buf));  
00275     ((struct sockaddr_in *)from)->sin_addr.s_addr = addr->addr;
00276     ((struct sockaddr_in *)from)->sin_port = port;
00277     *fromlen = sizeof(struct sockaddr_in);
00278   }
00279 
00280   
00281   
00282 
00283 
00284 
00285   if(len > copylen) {
00286     return copylen;
00287   } else {
00288     return len;
00289   }
00290 }
00291 
00292 int
00293 lwip_read(int s, void *mem, int len)
00294 {
00295   return lwip_recv(s, mem, len, 0);
00296 }
00297 
00298 int
00299 lwip_recv(int s, void *mem, int len, unsigned int flags)
00300 {
00301   return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
00302 }
00303 
00304 int
00305 lwip_send(int s, void *data, int size, unsigned int flags)
00306 {
00307   struct lwip_socket *sock;
00308   struct netbuf *buf;
00309   err_t err;
00310 
00311   DEBUGF(SOCKETS_DEBUG, ("send: socket %d, size %d\n", s, size));
00312 
00313   sock = get_socket(s);
00314   if(sock == NULL) {
00315     return -1;
00316   }  
00317   
00318   switch(netconn_type(sock->conn)) {
00319   case NETCONN_UDP:
00320     
00321     buf = netbuf_new();
00322 
00323     if(buf == NULL) {
00324       
00325       return -1;
00326     }
00327     
00328     
00329 
00330     netbuf_ref(buf, data, size);
00331 
00332     
00333     err = netconn_send(sock->conn, buf);
00334 
00335     
00336     netbuf_delete(buf);
00337     break;
00338   case NETCONN_TCP:
00339     err = netconn_write(sock->conn, data, size, NETCONN_COPY);
00340     break;
00341   default:
00342     err = ERR_ARG;
00343     break;
00344   }
00345   if(err != ERR_OK) {
00346     
00347     return -1;    
00348   }
00349     
00350   return size;
00351 }
00352 
00353 int
00354 lwip_sendto(int s, void *data, int size, unsigned int flags,
00355        struct sockaddr *to, int tolen)
00356 {
00357   struct lwip_socket *sock;
00358   struct ip_addr remote_addr, *addr;
00359   uInt16 remote_port, port;
00360   int ret;
00361 
00362   sock = get_socket(s);
00363   if(sock == NULL) {
00364     return -1;
00365   }
00366   
00367   
00368   netconn_peer(sock->conn, &addr, &port);
00369   
00370   remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
00371   remote_port = ((struct sockaddr_in *)to)->sin_port;
00372   netconn_connect(sock->conn, &remote_addr, remote_port);
00373   
00374   ret = lwip_send(s, data, size, flags);
00375 
00376   
00377 
00378   netconn_connect(sock->conn, addr, port);
00379   return ret;
00380 }
00381 
00382 int
00383 lwip_socket(int domain, int type, int protocol)
00384 {
00385   struct netconn *conn;
00386   int i;
00387 
00388   
00389   switch(type) {
00390   case SOCK_DGRAM:
00391     conn = netconn_new(NETCONN_UDP);
00392     break;
00393   case SOCK_STREAM:
00394     conn = netconn_new(NETCONN_TCP);
00395     break;
00396   default:
00397     
00398     return -1;
00399   }
00400 
00401   if(conn == NULL) {
00402     DEBUGF(SOCKETS_DEBUG, ("socket: could not create netconn.\n"));
00403     
00404     return -1;
00405   }
00406 
00407   i = alloc_socket(conn);
00408 
00409   if(i == -1) {
00410     
00411     netconn_delete(conn);
00412   }
00413   return i;
00414 }
00415 
00416 int
00417 lwip_write(int s, void *data, int size)
00418 {
00419   struct lwip_socket *sock;
00420   err_t err;
00421 
00422   DEBUGF(SOCKETS_DEBUG, ("write: socket %d, size %d\n", s, size));
00423 
00424   sock = get_socket(s);
00425   if(sock == NULL) {
00426     return -1;
00427   }
00428     
00429   switch(netconn_type(sock->conn)) {
00430   case NETCONN_UDP:
00431     return lwip_send(s, data, size, 0);
00432 
00433   case NETCONN_TCP:
00434     err = netconn_write(sock->conn, data, size, NETCONN_COPY);
00435     break;
00436   default:
00437     err = ERR_ARG;
00438     break;
00439   }
00440   if(err != ERR_OK) {
00441     
00442     return -1;
00443   }
00444   return size;
00445 }
00446