⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketfile.c

📁 UCOS下添加TCP/IP和PPP协议,实现TCP,UDP点到点等功能.
💻 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 + -