?? socketfile.c
字號:
/** * Socket Device Filesystem Driver * * @file socketfile.c * @author <a href="mailto:c_graham@hinge.mistral.co.uk>Craig Graham</a> * @ingroup fsdevices * @{ */#include <config.h>#include <file.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <file.h>#include <debug.h>#include <adl.h>#include <ls588.h>#include <semaphore.h>#include <interupt.h>#include <sys/socket.h>#include <malloc.h>//#include "netconf.h"//#include "net.h"#include "netdebug.h"#include "netbuf.h"#include "netppp.h"#include "nettcp.h"#include "netudp.h"static int socket_chdir(const char *dir);static int socket_mkdir(const char *dir);static void *socket_open(const char *name,int mode);static int socket_close(void *sdata);static long socket_read(void *sdata, unsigned char *buf, long l);static long socket_write(void *sdata, const unsigned char *buf, long l);static long socket_lseek(void *sdata, long offset, int whence);static int socket_fdelete(const char *name);static long socket_ioctl(void *sdata,UI32 ioctlValue,void *data);static long socket_poll(void *sdata);/** * Internal socket information */typedef struct { int domain; int type; int protocol; int id;} SOCKET_FS_DATA;/** * Exported driver interface for Socket Filesystem */FS_DRIVER socketfs={ /** Device Name */ "SocketFS", /** chdir */ socket_chdir, /** mkdir */ socket_mkdir, /** open */ socket_open, /** close */ socket_close, /** read */ socket_read, /** write */ socket_write, /** lseek */ socket_lseek, /** fdelete */ socket_fdelete, /** ioctl */ socket_ioctl, /** poll */ socket_poll};/** * stub for chdir */static int socket_chdir(const char *dir){ return 0;}/** * stub for mkdir */static int socket_mkdir(const char *dir){ return 0;}/** * Open the socket device */static void *socket_open(const char *name,int mode){ SOCKET_FS_DATA *sdata; //GENERAL_DEBUG(("socket_open:'%s'\n",name)); sdata=(SOCKET_FS_DATA*)malloc(sizeof(SOCKET_FS_DATA)); if(sdata==NULL) return NULL; sdata->id=-1; sdata->domain=AF_UNSPEC; sdata->type=SOCK_STREAM; sdata->protocol=0; return (void*)sdata;}/** * Close the socket device */static int socket_close(void *sdata){ //GENERAL_DEBUG(("socket_close\n")); switch(((SOCKET_FS_DATA*)sdata)->protocol) { case IPPROTO_TCP: tcpClose(((SOCKET_FS_DATA*)sdata)->id); //tcpWait(((SOCKET_FS_DATA*)sdata)->id); break; case IPPROTO_UDP: udpClose(((SOCKET_FS_DATA*)sdata)->id); break; } return 0;}/** * Read data from the socket device */static long socket_read(void *sdata, unsigned char *buf, long l){ int rtn; //GENERAL_DEBUG(("socket_read: len=%ld\n",l));// printf("socket_read: l=%ld\n",l); switch(((SOCKET_FS_DATA*)sdata)->protocol) { case IPPROTO_TCP: rtn=tcpRead(((SOCKET_FS_DATA*)sdata)->id,buf,l); break; case IPPROTO_UDP: rtn=udpRead(((SOCKET_FS_DATA*)sdata)->id,buf,l); break; } return rtn;}/** * Write data to the socket device */static long socket_write(void *sdata, const unsigned char *buf, long l){ int rtn;// printf("socket_write: l=%ld\n",l); switch(((SOCKET_FS_DATA*)sdata)->protocol) { case IPPROTO_TCP: rtn=tcpWrite(((SOCKET_FS_DATA*)sdata)->id,buf,l); break; case IPPROTO_UDP: rtn=udpWrite(((SOCKET_FS_DATA*)sdata)->id,buf,l); break; default: printf("socket_write: unknown protocol\n"); break; } return rtn;}/** * stub for lseek */static long socket_lseek(void *sdata, long offset, int whence){ return 0;}/** * stub for fdelete */static int socket_fdelete(const char *name){ return 0;}/** * stub for ioctl */static long socket_ioctl(void *sdata,UI32 ioctlValue,void *data){ long rtn; switch(ioctlValue) { case IOCTL_DEVCAPS: rtn=IOCTL_DEVCAPS|IOCTL_PENDINGDATALENGTH|IOCTL_SOCKDOMAIN|IOCTL_SOCKTYPE|IOCTL_SOCKPROTOCOL; break; case IOCTL_PENDINGDATALENGTH: //GENERAL_DEBUG(("should return amount of data available here\n")); rtn=0; break; case IOCTL_SOCKDOMAIN: if(data) ((SOCKET_FS_DATA*)sdata)->domain=*(int*)data; rtn=((SOCKET_FS_DATA*)sdata)->domain; break; case IOCTL_SOCKTYPE: if(data) ((SOCKET_FS_DATA*)sdata)->type=*(int*)data; rtn=((SOCKET_FS_DATA*)sdata)->type; break; case IOCTL_SOCKPROTOCOL: if((data)&&(((SOCKET_FS_DATA*)sdata)->id==-1)) { ((SOCKET_FS_DATA*)sdata)->protocol=*(int*)data; switch(((SOCKET_FS_DATA*)sdata)->protocol) { case IPPROTO_UDP: ((SOCKET_FS_DATA*)sdata)->id=udpOpen(); printf("socket_ioctl: protocol=udp, ucIP ID=%d\n",((SOCKET_FS_DATA*)sdata)->id); break; case IPPROTO_TCP: ((SOCKET_FS_DATA*)sdata)->id=tcpOpen(); printf("socket_ioctl: protocol=tcp, ucIP ID=%d\n",((SOCKET_FS_DATA*)sdata)->id);// {// int inCnt=10;// tcpIOCtl(((SOCKET_FS_DATA*)sdata)->id, TCPCTLS_KEEPALIVE, &inCnt);// } break; default: //GENERAL_DEBUG(("socket_ioctl:IOCTL_SOCKPROTOCOL: unsupported protocol %d\n",((SOCKET_FS_DATA*)sdata)->protocol)); ((SOCKET_FS_DATA*)sdata)->protocol=-1; break; } } rtn=((SOCKET_FS_DATA*)sdata)->protocol; break; default: rtn=-1; break; } return rtn;}static long socket_poll(void *sdata){ long rtn; switch(((SOCKET_FS_DATA*)sdata)->protocol) { case IPPROTO_UDP: rtn=udpPoll(((SOCKET_FS_DATA*)sdata)->id); break; case IPPROTO_TCP: rtn=tcpPoll(((SOCKET_FS_DATA*)sdata)->id); break; } return rtn;}/** * Helper function - standard Unix way of creating a socket */int socket(int domain, int type, int protocol){ int fd; fd=open("/dev/socket/0",O_RDWR); if(fd>=0) { printf("socket: socket fd=%d\n",fd); ioctl(fd,IOCTL_SOCKDOMAIN,&domain); ioctl(fd,IOCTL_SOCKTYPE,&type); if(protocol==0) protocol=(type==SOCK_STREAM)?IPPROTO_TCP:IPPROTO_UDP; ioctl(fd,IOCTL_SOCKPROTOCOL,&protocol); }else{ while(1); printf("socket: cann't open /dev/socket/0\n"); } return fd;}/** * Helper function - standard Unix way of connecting a socket to a server. */int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen){ FILE *sf; int rtn; sf=fdopen(sockfd, "rw"); printf("connect:socket fd=%d\n",sockfd); if(sf==NULL) { printf("connect: invalid socket handle\n"); return -1; } switch(serv_addr->na_family) { case AF_INET: switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: rtn=tcpConnect(((SOCKET_FS_DATA*)sf->driverData)->id, (const struct sockaddr_in*)serv_addr, 0); printf("tcpConnect returned %d\n",rtn); break; case IPPROTO_UDP: rtn=udpConnect(((SOCKET_FS_DATA*)sf->driverData)->id, (const struct sockaddr_in*)serv_addr, 0); printf("udpConnect returned %d\n",rtn); break; default: printf("connect: unsupported protocol %ld\n",((SOCKET_FS_DATA*)sf->driverData)->protocol); break; } break; case AF_UNSPEC: switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: rtn=tcpDisconnect(((SOCKET_FS_DATA*)sf->driverData)->id); break; case IPPROTO_UDP: //rtn=udpDisconnect(((SOCKET_FS_DATA*)sf->driverData)->id); break; default: printf("connect: unsupported protocol %ld\n",((SOCKET_FS_DATA*)sf->driverData)->protocol); break; } break; default: printf("connect: unsupported address family %ld\n",serv_addr->na_family); rtn=-1; break; } return rtn;}int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){ FILE *sf; int remoteId,remoteFD; sf=fdopen(sockfd, "rw"); if(sf==NULL) { printf("accept: invalid socket handle\n"); return -1; } switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: remoteId=tcpAccept(((SOCKET_FS_DATA*)sf->driverData)->id, (struct sockaddr_in *)addr); if(remoteId>=0) { FILE *r_sf; remoteFD=open("/dev/socket/0",O_RDWR); if(remoteFD>=0) { r_sf=fdopen(remoteFD,"rw"); printf("accept: remoteFD=%d\n",remoteFD); ((SOCKET_FS_DATA*)r_sf->driverData)->protocol=IPPROTO_TCP; ((SOCKET_FS_DATA*)r_sf->driverData)->id=remoteId; return remoteFD; }else{ printf("accept: couldn't open /dev/socket/0\n"); tcpClose(remoteId); } }else{ printf("accept: uC/IP returned error code %d\n",remoteId); } break; default: printf("accept: cann't accept() on this class of socket\n"); break; } return -1;}int listen(int sockfd, int backlog){ FILE *sf; int rtn=0; sf=fdopen(sockfd, "rw"); if(sf==NULL) { printf("listen: cann't get FILE for fd=%d\n",sockfd); return -1; } switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: printf("calling tcpListen(%d,%d)\n",((SOCKET_FS_DATA*)sf->driverData)->id,backlog); rtn=tcpListen(((SOCKET_FS_DATA*)sf->driverData)->id, backlog); if(rtn<0) { setErrno(rtn); rtn=-1; }else{ rtn=0; } break; case IPPROTO_UDP: printf("calling udpListen(%d,%d)\n",((SOCKET_FS_DATA*)sf->driverData)->id,backlog); rtn=udpListen(((SOCKET_FS_DATA*)sf->driverData)->id, backlog); break; default: printf("listen: unknown protocol\n"); rtn=-1; break; } return rtn;}int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen){ FILE *sf; int rtn; //GENERAL_DEBUG(("bind: sockfd=%d\n",sockfd)); printf("bind: socket fd=%d\n",sockfd); sf=fdopen(sockfd, "rw"); if(sf==NULL) { printf("bind: cann't get FILE for fd=%d\n",sockfd); return -1; } switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: //GENERAL_DEBUG(("calling tcpBind()\n")); rtn=tcpBind(((SOCKET_FS_DATA*)sf->driverData)->id, (struct sockaddr_in*)addr); printf(" - using tcp\n"); break; case IPPROTO_UDP: //GENERAL_DEBUG(("calling udpBind()\n")); rtn=udpBind(((SOCKET_FS_DATA*)sf->driverData)->id, (struct sockaddr_in*)addr); printf(" - using udp\n"); break; default: printf("bind: unknown protocol\n"); rtn=-1; break; } return rtn;}long recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen){ FILE *sf; int rtn; //GENERAL_DEBUG(("recvfrom()\n")); sf=fdopen(sockfd, "rw"); if(sf==NULL) return -1; switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: rtn=tcpRead(((SOCKET_FS_DATA*)sf->driverData)->id,buf,len); break; case IPPROTO_UDP: //GENERAL_DEBUG(("calling udpRecvFrom()\n")); rtn=udpRecvFrom(((SOCKET_FS_DATA*)sf->driverData)->id, buf, len, (struct sockaddr_in*)from); break; } if(fromlen) *fromlen=sizeof(struct sockaddr_in); return rtn;}long sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen){ FILE *sf; int rtn; //GENERAL_DEBUG(("sendto()\n")); sf=fdopen(sockfd, "rw"); if(sf==NULL) return -1; switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: tcpDisconnect(((SOCKET_FS_DATA*)sf->driverData)->id); rtn=tcpConnect(((SOCKET_FS_DATA*)sf->driverData)->id, (const struct sockaddr_in*)to, 0); if(rtn<0) break; rtn=tcpWrite(((SOCKET_FS_DATA*)sf->driverData)->id,buf,len); break; case IPPROTO_UDP: //GENERAL_DEBUG(("calling udpSendTo()\n")); rtn=udpSendTo(((SOCKET_FS_DATA*)sf->driverData)->id, buf, len, (const struct sockaddr_in*)to); break; } return rtn;}void unblock(int sockfd){ FILE *sf; sf=fdopen(sockfd, "rw"); if(sf==NULL) return; switch(((SOCKET_FS_DATA*)sf->driverData)->protocol) { case IPPROTO_TCP: break; case IPPROTO_UDP: //GENERAL_DEBUG(("calling udpUnblockRead()\n")); udpUnblockRead(((SOCKET_FS_DATA*)sf->driverData)->id); break; }}int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen){ // stub for setsockopt}int send(int s, const void *msg, size_t len, int flags){ FILE *sf; sf=fdopen(s, "rw"); if(sf==NULL) { printf("send: error getting FILE from descriptor %d\n",s); return -1; } return socket_write(sf->driverData, (const unsigned char*)msg, len);}int recv(int s, void *buf, size_t len, int flags){ FILE *sf; sf=fdopen(s, "rw"); if(sf==NULL) { printf("recv: error getting FILE from descriptor %d\n",s); return -1; } socket_read(sf->driverData, (unsigned char*)buf, len);}/** @} */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -