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

📄 sockets.c

📁 由smsc公司改进的lwip2.1.1基于嵌入式系统的TCP/ip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
	sockets[socketIndex].mIsActive=0;
	ASSIGN_SIGNATURE(&(sockets[socketIndex]),0);
	smsc_semaphore_signal(&gSocketsLock);
}

static struct SOCKET * get_socket(int socketIndex)
{
	struct SOCKET * socket=NULL;
	SMSC_ASSERT(socketIndex>=0);
	SMSC_ASSERT(socketIndex<MAXIMUM_NUMBER_OF_SOCKETS);
	socket=&(sockets[socketIndex]);
	SMSC_ASSERT(socket->mIsActive);
	return socket;
}

int smsc_socket(int domain, int type, int protocol)
{
	int socketIndex=-1;
	struct SOCKET * socket=NULL;

	socketIndex=alloc_socket();

	if (socketIndex == -1) {
		set_errno(ENOBUFS);
		goto ERROR;
	}
	
	socket=get_socket(socketIndex);

	switch(type) {
	case SOCK_RAW:
		SMSC_ERROR(("smsc_socket: Raw sockets are not supported"));
		set_errno(EINVAL);
		goto ERROR;
#if UDP_ENABLED
	case SOCK_DGRAM:
		if(SocketRequest_CreateUdpControlBlock(socket)!=0) {
			set_errno(ENOBUFS);
			goto ERROR;
		}
		break;
#endif
#if TCP_ENABLED
	case SOCK_STREAM:
		if(SocketRequest_CreateTcpControlBlock(socket)!=0) {
			set_errno(ENOBUFS);
			goto ERROR;
		}
		break;
#endif
	default:
		SMSC_ERROR(("smsc_socket: unsupported type = %d",type));
		set_errno(EINVAL);
		goto ERROR;
	}
	set_errno(0);
	return socketIndex;
ERROR:
	if(socketIndex>=0) {
		free_socket(socketIndex);
		socketIndex=-1;
	}
	return -1;
}

int smsc_accept(int socketIndex, struct sockaddr * addr, socklen_t * addrlen)
{
#if TCP_ENABLED
	int newSocketIndex=-1;
	struct SOCKET * newSocket=NULL;
    struct SOCKET * socket=NULL;
    IP_ADDRESS ipAddress;
    u16_t port;

    socket=get_socket(socketIndex);

	newSocketIndex=alloc_socket();

	if (newSocketIndex == -1) {
		set_errno(ENOBUFS);
		goto ERROR;
	}

	newSocket=get_socket(newSocketIndex);
    
    /* only TCP sockets can use the accept call */
	SMSC_ASSERT(socket->mType==SOCKET_TYPE_TCP);
	
	if(SocketRequest_AcceptTcpControlBlock(socket,newSocket,&ipAddress,&port)!=0) {
		SMSC_ERROR(("smsc_accept: failed to accept tcp control block"));
		set_errno(ENOBUFS);
		goto ERROR;
	}
	if((addr!=NULL)&&(addrlen!=NULL)&&((*addrlen)>=sizeof(struct sockaddr_in)))
	{
		SMSC_ASSERT(IP_ADDRESS_IS_IPV4(&ipAddress));
		((struct sockaddr_in *)addr)->sin_len=sizeof(struct sockaddr_in);
		((struct sockaddr_in *)addr)->sin_family=AF_INET;
		IPV4_ADDRESS_COPY_FROM_IP_ADDRESS(&(((struct sockaddr_in *)addr)->sin_addr.s_addr),&ipAddress);
		((struct sockaddr_in *)addr)->sin_port=ntohs(port);
	}
	set_errno(0);
	return newSocketIndex;
ERROR:
	if(newSocketIndex>=0) {
		free_socket(newSocketIndex);
		newSocketIndex=-1;
	}
#endif /* TCP_ENABLED */
	return -1;
}

int smsc_bind(int socketIndex, struct sockaddr *name, socklen_t namelen)
{
	struct SOCKET * socket;
	IP_ADDRESS local_addr;
	u16_t local_port;
	err_t error;

	socket = get_socket(socketIndex);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}

	SMSC_ASSERT(name->sa_family==AF_INET);
	IP_ADDRESS_COPY_FROM_IPV4_ADDRESS(&local_addr,&(((struct sockaddr_in *)name)->sin_addr.s_addr));
	local_port = ((struct sockaddr_in *)name)->sin_port;

	#if SMSC_TRACE_ENABLED
	{
		char addressString[IP_ADDRESS_STRING_SIZE];
		SMSC_TRACE(SOCKETS_DEBUG, ("smsc_bind(%d, addr=%s port=%u)",
			socketIndex,IP_ADDRESS_TO_STRING(addressString,&local_addr),
			ntohs(local_port)));
	}
	#endif

	error = SocketRequest_Bind(socket, &local_addr, ntohs(local_port));

	if (error != ERR_OK) {
		SMSC_WARNING(SOCKETS_DEBUG, ("smsc_bind(%d) failed, error=%d", socketIndex, error));
		sock_set_errno(socket, err_to_errno(error));
		return -1;
	}

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_bind(%d) succeeded", socketIndex));
	sock_set_errno(socket, 0);
	return 0;
}

int smsc_close(int s)
{
	struct SOCKET * socket;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_close(%d)", s));

	/* We cannot allow multiple closes of the same socket. */
	smsc_semaphore_wait(&gSocketsLock);

	socket = get_socket(s);
	if (!socket) {
		smsc_semaphore_signal(&gSocketsLock);
		set_errno(EBADF);
		return -1;
	}

	SocketRequest_Close(socket);

	ASSIGN_SIGNATURE(socket,0);
	socket->mIsActive=0;

	smsc_semaphore_signal(&gSocketsLock);
	sock_set_errno(socket, 0);
	return 0;
}

int smsc_connect(int s, struct sockaddr *name, socklen_t namelen)
{
	struct SOCKET *socket;
	err_t err;

	socket = get_socket(s);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}

	if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) {
		SMSC_NOTICE(SOCKETS_DEBUG, ("smsc_connect(%d, AF_UNSPEC)", s));
		err = SocketRequest_Disconnect(socket);
	} else {
		IP_ADDRESS remote_addr;
		u16_t remote_port;

		SMSC_ASSERT(name->sa_family==AF_INET);/* only Ipv4 is currently supported */
		IP_ADDRESS_COPY_FROM_IPV4_ADDRESS(&remote_addr,&(((struct sockaddr_in *)name)->sin_addr.s_addr));
		remote_port = ((struct sockaddr_in *)name)->sin_port;

		#if SMSC_TRACE_ENABLED
		{
			char addressString[IP_ADDRESS_STRING_SIZE];
			SMSC_TRACE(SOCKETS_DEBUG, ("smsc_connect(%d, addr=%s port=%u)", s,
				IP_ADDRESS_TO_STRING(addressString,&remote_addr),ntohs(remote_port)));
		}
		#endif

		err= SocketRequest_Connect(socket, &remote_addr, ntohs(remote_port));
	}

	if (err != ERR_OK) {
		SMSC_NOTICE(SOCKETS_DEBUG, ("smsc_connect(%d) failed, err=%d", s, err));
		sock_set_errno(socket, err_to_errno(err));
		return -1;
	}

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_connect(%d) succeeded", s));
	sock_set_errno(socket, 0);
	return 0;
}

int smsc_listen(int s, int backlog)
{
#if TCP_ENABLED
	struct SOCKET * socket;
	err_t err;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_listen(%d, backlog=%d)", s, backlog));
	socket = get_socket(s);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}
	if(backlog>SOCKET_MAXIMUM_BACKLOG) {
		set_errno(EINVAL);
		return -1;
	}
	socket->mListenBackLog=backlog;
	err=SocketRequest_Listen(socket);
	
	if(err!=ERR_OK) {
		SMSC_TRACE(SOCKETS_DEBUG, ("smsc_listen(%d) failed, err=%d", s, err));
		sock_set_errno(socket, err_to_errno(err));
		return -1;
	}

	sock_set_errno(socket, 0);
	return 0;
#else
	set_errno(EINVAL);
	return -1;
#endif
}

int smsc_recvfrom(int s, void *mem, int len, unsigned int flags,
	struct sockaddr *from, socklen_t *fromlen)
{
	struct SOCKET *socket;
	int result=-1;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_recvfrom(%d, %p, %d, 0x%x, ..)", s, mem, len, flags));
	socket = get_socket(s);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}

	/* If this is non-blocking call, then check first */
	if (((flags & MSG_DONTWAIT) || (socket->mFlags & O_NONBLOCK))
		&& ((!(SocketPacketQueue_IsEmpty(&(socket->mReceiveQueue))))||(socket->mReceiveFinishedFlag)) )
	{
		SMSC_TRACE(SOCKETS_DEBUG, ("smsc_recvfrom(%d): returning EWOULDBLOCK", s));
		sock_set_errno(socket, EWOULDBLOCK);
		return -1;
	}
	
	{
		IP_ADDRESS ipAddress;
		u16_t port;
		result=SocketRequest_Receive(socket,mem,len,&ipAddress,&port);
		
		#if SMSC_TRACE_ENABLED
		{
			char addressString[IP_ADDRESS_STRING_SIZE];
			SMSC_TRACE(SOCKETS_DEBUG, ("smsc_recvfrom(%d): addr=%s port=%u, size=%d", s,
				IP_ADDRESS_TO_STRING(addressString,&ipAddress),port,result));
		}
		#endif
		if (from && fromlen) {
			struct sockaddr_in sin;

			SMSC_ASSERT(IP_ADDRESS_IS_IPV4(&ipAddress));

			memset(&sin, 0, sizeof(sin));
			sin.sin_len = sizeof(sin);
			sin.sin_family = AF_INET;
			sin.sin_port = htons(port);
			
			IPV4_ADDRESS_COPY_FROM_IP_ADDRESS(
				&(sin.sin_addr.s_addr),&ipAddress);

			if (*fromlen > sizeof(sin))
				*fromlen = sizeof(sin);

			memcpy(from, &sin, *fromlen);
		}
	}
	if(result>=0) {
		sock_set_errno(socket, 0);
	} else {
		sock_set_errno(socket, ECONNRESET);
	}
	return result;
}

int smsc_recv(int s, void *mem, int len, unsigned int flags)
{
	return smsc_recvfrom(s, mem, len, flags, NULL, NULL);
}

int smsc_send(int s, void *data, int size, unsigned int flags)
{
	struct SOCKET * socket;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_send(%d, data=%p, size=%d, flags=0x%x)", s, data, size, flags));

	socket = get_socket(s);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}

	size=SocketRequest_Send(socket,data,size,flags);
	if(size<0) {
		SMSC_TRACE(SOCKETS_DEBUG, ("smsc_send(%d) err=%d", s, size));
		set_errno(-size);
		return -1;
	}

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_send(%d) ok size=%d", s, size));
	sock_set_errno(socket, 0);
	return size;
}

int smsc_sendto(int s, void *data, int size, unsigned int flags,
	struct sockaddr *to, socklen_t tolen)
{
	struct SOCKET * socket;
	IP_ADDRESS remote_addr, addr;
	u16_t remote_port, port;
	int ret,connected;

	socket = get_socket(s);
	if (!socket) {
		set_errno(EBADF);
		return -1;
	}

	/* get the peer if currently connected */
	connected = (SocketRequest_GetPeer(socket, &addr, &port) == ERR_OK);

	SMSC_ASSERT(to!=NULL);
	SMSC_ASSERT(to->sa_family==AF_INET);/* Only Ipv4 is suppored currently */
	
	IP_ADDRESS_COPY_FROM_IPV4_ADDRESS(&remote_addr,&((struct sockaddr_in *)to)->sin_addr.s_addr);
	remote_port = ((struct sockaddr_in *)to)->sin_port;

	#if SMSC_TRACE_ENABLED
	{
		char addressString[IP_ADDRESS_STRING_SIZE];
		SMSC_TRACE(SOCKETS_DEBUG, ("smsc_sendto(%d, data=%p, size=%d, flags=0x%x to=%s port=%u", s, data, size, flags,
			IP_ADDRESS_TO_STRING(addressString,&remote_addr),ntohs(remote_port)));
	}
	#endif

	SocketRequest_Connect(socket, &remote_addr, ntohs(remote_port));

	ret = smsc_send(s, data, size, flags);

	/* reset the remote address and port number
		of the connection */
	if (connected)
		SocketRequest_Connect(socket, &addr, port);
	else
		SocketRequest_Disconnect(socket);
	return ret;
}

static int smsc_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
{
	int i, nready = 0;
	fd_set lreadset, lwriteset, lexceptset;
	struct SOCKET *p_sock;

	FD_ZERO(&lreadset);
	FD_ZERO(&lwriteset);
	FD_ZERO(&lexceptset);

	/* Go through each socket in each list to count number of sockets which
		currently match */
	for(i = 0; i < maxfdp1; i++)
	{
		if (FD_ISSET(i, readset))
		{
			/* See if netconn of this socket is ready for read */
			p_sock = get_socket(i);
			if (p_sock && (!SocketPacketQueue_IsEmpty(&(p_sock->mReceiveQueue))))
			{
				FD_SET(i, &lreadset);
				SMSC_TRACE(SOCKETS_DEBUG, ("smsc_selscan: fd=%d ready for reading", i));
				nready++;
			}
		}
		if (FD_ISSET(i, writeset))
		{
			/* See if netconn of this socket is ready for write */
			p_sock = get_socket(i);
			if (p_sock && (p_sock->mIsWritable))
			{
				FD_SET(i, &lwriteset);
				SMSC_TRACE(SOCKETS_DEBUG, ("smsc_selscan: fd=%d ready for writing", i));
				nready++;
			}
		}
	}
	*readset = lreadset;
	*writeset = lwriteset;
	FD_ZERO(exceptset);

	return nready;
}


int smsc_select(
	int maxfdp1,
	fd_set *readset,
	fd_set *writeset,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -