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

📄 sockets.c

📁 由smsc公司改进的lwip2.1.1基于嵌入式系统的TCP/ip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
	fd_set *exceptset,
	struct timeval *timeout)
{
	u32_t i;
	int nready;
	fd_set lreadset, lwriteset, lexceptset;
	u32_t msectimeout;
	struct smsc_select_cb select_cb;
	struct smsc_select_cb *p_selcb;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)",
		maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
		timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L));

	select_cb.next = 0;
	select_cb.readset = readset;
	select_cb.writeset = writeset;
	select_cb.exceptset = exceptset;
	select_cb.sem_signalled = 0;

	/* Protect ourselves searching through the list */
	smsc_semaphore_wait(&gSelectLock);

	if (readset)
		lreadset = *readset;
	else
		FD_ZERO(&lreadset);
	if (writeset)
		lwriteset = *writeset;
	else
		FD_ZERO(&lwriteset);
	if (exceptset)
		lexceptset = *exceptset;
	else
		FD_ZERO(&lexceptset);

	/* Go through each socket in each list to count number of sockets which
	currently match */
	nready = smsc_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);

	/* If we don't have any current events, then suspend if we are supposed to */
	if (!nready)
	{
		if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0)
		{
			smsc_semaphore_signal(&gSelectLock);
			if (readset)
				FD_ZERO(readset);
			if (writeset)
				FD_ZERO(writeset);
			if (exceptset)
				FD_ZERO(exceptset);

			SMSC_TRACE(SOCKETS_DEBUG, ("smsc_select: no timeout, returning 0"));
			set_errno(0);

			return 0;
		}

		/* add our semaphore to list */
		/* We don't actually need any dynamic memory. Our entry on the
		* list is only valid while we are in this function, so it's ok
		* to use local variables */

		select_cb.sem = smsc_semaphore_create(0);
		
		/* Note that we are still protected */
		/* Put this select_cb on top of list */
		select_cb.next = gSelectList;
		gSelectList = &select_cb;

		/* Now we can safely unprotect */
		smsc_semaphore_signal(&gSelectLock);

		/* Now just wait to be woken */
		if (timeout == 0) {
			/* Wait forever */
			i=SMSC_TIMEOUT-1;/* set i to something other that SMSC_TIMEOUT */
			smsc_semaphore_wait(select_cb.sem);
		} else {
			msectimeout =  ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000));
			i = smsc_semaphore_wait_timeout(select_cb.sem, msectimeout);
		}

		/* Take us off the list */
		smsc_semaphore_wait(&gSelectLock);
		if (gSelectList == &select_cb)
			gSelectList = select_cb.next;
		else for (p_selcb = gSelectList; p_selcb; p_selcb = p_selcb->next) {
			if (p_selcb->next == &select_cb)
			{
				p_selcb->next = select_cb.next;
				break;
			}
		}

		smsc_semaphore_signal(&gSelectLock);

		smsc_semaphore_free(select_cb.sem);
		if (i == SMSC_TIMEOUT)             /* Timeout */
		{
			if (readset)
				FD_ZERO(readset);
			if (writeset)
				FD_ZERO(writeset);
			if (exceptset)
				FD_ZERO(exceptset);

			SMSC_TRACE(SOCKETS_DEBUG, ("smsc_select: timeout expired"));
			set_errno(0);

			return 0;
		}

		if (readset)
			lreadset = *readset;
		else
			FD_ZERO(&lreadset);
		if (writeset)
			lwriteset = *writeset;
		else
			FD_ZERO(&lwriteset);
		if (exceptset)
			lexceptset = *exceptset;
		else
			FD_ZERO(&lexceptset);

		/* See what's set */
		nready = smsc_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
	} else {
		smsc_semaphore_signal(&gSelectLock);
	}

	if (readset)
		*readset = lreadset;
	if (writeset)
		*writeset = lwriteset;
	if (exceptset)
		*exceptset = lexceptset;

	SMSC_TRACE(SOCKETS_DEBUG, ("smsc_select: nready=%d", nready));
	set_errno(0);

	return nready;
}

int smsc_shutdown(int s, int how)
{
	SMSC_WARNING(SOCKETS_DEBUG, ("smsc_shutdown(%d, how=%d)", s, how));
	return smsc_close(s); /* XXX temporary hack until proper implementation */
}

int smsc_getpeername (int s, struct sockaddr *name, socklen_t *namelen)
{
	SMSC_ERROR(("smsc_getpeername: not implemented"));
	return 0;
}

int smsc_getsockname (int s, struct sockaddr *name, socklen_t *namelen)
{
	SMSC_ERROR(("smsc_getsockname: not implemented"));
	return 0;
}

int smsc_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen)
{
	SMSC_ERROR(("smsc_getsockopt: not implemented"));
	return 0;
}

int smsc_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen)
{
	SMSC_ERROR(("smsc_setsockopt: not implemented"));
	return 0;
}

int smsc_read(int s, void *mem, int len)
{
	return smsc_recvfrom(s, mem, len, 0, NULL, NULL);
}

int smsc_write(int s, void *dataptr, int size)
{
	return smsc_send(s, dataptr, size, 0);
}

int smsc_ioctl(int s, long cmd, void *argp)
{
	SMSC_ERROR(("smsc_ioctl: not implemented"));
	return 0;
}

#define in_range(c, lo, up)  ((u8_t)c >= lo && (u8_t)c <= up)  
#if 1 /* Bryan agreed to change all the defs to different name (SMSC_isprint an example) otherwise it would conflict with glibc include ctype.h file */
#define isprint(c)           in_range(c, 0x20, 0x7f)
#define isdigit(c)           in_range(c, '0', '9')
#define isxdigit(c)          (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c)           in_range(c, 'a', 'z')
#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
#endif
/*
 * Ascii internet address interpretation routine.
 * The value returned is in network order.
 */
u32_t inet_addr(const char *cp)
{
	struct in_addr val;

	if (inet_aton(cp, &val)) {
		return (val.s_addr);
	}
	return (u32_t)(0xFFFFFFFF);
}

/*
 * Check whether "cp" is a valid ascii representation
 * of an Internet address and convert to a binary address.
 * Returns 1 if the address is valid, 0 if not.
 * This replaces inet_addr, the return value from which
 * cannot distinguish between failure and a local broadcast address.
 */
int inet_aton(const char *cp, struct in_addr *addr)
{
	u32_t val;
	int base, n, c;
	u32_t parts[4];
	u32_t *pp = parts;

	c = *cp;
	for (;;) {
		/*
		* Collect number up to ``.''.
		* Values are specified as for C:
		* 0x=hex, 0=octal, 1-9=decimal.
		*/
		if (!isdigit(c))
			return (0);
		val = 0;
		base = 10;
		if (c == '0') {
			c = *++cp;
			if (c == 'x' || c == 'X') {
				base = 16;
				c = *++cp;
			} else
				base = 8;
		}
		for (;;) {
			if (isdigit(c)) {
				val = (val * base) + (int)(c - '0');
				c = *++cp;
			} else if (base == 16 && isxdigit(c)) {
				val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
				c = *++cp;
			} else
				break;
		}
		if (c == '.') {
			/*
			* Internet format:
			*  a.b.c.d
			*  a.b.c   (with c treated as 16 bits)
			*  a.b (with b treated as 24 bits)
			*/
			if (pp >= parts + 3)
				return (0);
			*pp++ = val;
			c = *++cp;
		} else
			break;
	}
	/*
	* Check for trailing characters.
	*/
	if (c != '\0' && (!isprint(c) || !isspace(c)))
		return (0);
	/*
	* Concoct the address according to
	* the number of parts specified.
	*/
	n = pp - parts + 1;
	switch (n) {

	case 0:
		return (0);       /* initial nondigit */

	case 1:             /* a -- 32 bits */
		break;

	case 2:             /* a.b -- 8.24 bits */
		if (val > 0xffffff)
			return (0);
		val |= parts[0] << 24;
		break;

	case 3:             /* a.b.c -- 8.8.16 bits */
		if (val > 0xffff)
			return (0);
		val |= (parts[0] << 24) | (parts[1] << 16);
		break;

	case 4:             /* a.b.c.d -- 8.8.8.8 bits */
		if (val > 0xff)
			return (0);
		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
		break;
	}
	if (addr)
		addr->s_addr = htonl(val);
	return (1);
}

/* Convert numeric IP address into decimal dotted ASCII representation.
 * returns ptr to static buffer; not reentrant!
 */
char * inet_ntoa(struct in_addr addr)
{
	static char str[16];
	u32_t s_addr = addr.s_addr;
	char inv[3];
	char *rp;
	u8_t *ap;
	u8_t rem;
	u8_t n;
	u8_t i;

	rp = str;
	ap = (u8_t *)&s_addr;
	for(n = 0; n < 4; n++) {
		i = 0;
		do {
			rem = *ap % (u8_t)10;
			*ap /= (u8_t)10;
			inv[i++] = '0' + rem;
		} while(*ap);
		while(i--)
			*rp++ = inv[i];
		*rp++ = '.';
		ap++;
	}
	*--rp = 0;
	return str;
}

static int SocketRequest_Close(
	struct SOCKET * socket)
{
	int result=0;
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	smsc_semaphore_wait(&(socket->mRequestLock));
	SMSC_ASSERT(socket->mRequestCode==REQUEST_UNDEFINED);

	socket->mRequestCode=REQUEST_CLOSE;

	socket->mResponseCode=RESPONSE_UNDEFINED;
	Sockets_PushRequest(socket);
	TaskManager_InterruptActivation(gSocketTask);
	smsc_semaphore_wait(&(socket->mResponseSignal));

	SMSC_ASSERT(socket->mResponseCode!=RESPONSE_UNDEFINED);
	if(socket->mResponseCode==RESPONSE_SUCCESSFUL) {
		result=0;
	} else {
		result=-1;
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}	

static int SocketRequest_Receive(
	struct SOCKET * socket,
	void * data,
	int size,
	PIP_ADDRESS ipAddress,
	u16_t * port)
{
	int result=0;
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	smsc_semaphore_wait(&(socket->mRequestLock));
	SMSC_ASSERT(socket->mRequestCode==REQUEST_UNDEFINED);

	socket->mRequestCode=REQUEST_RECEIVE;
	socket->mRequestParameters.mReceiveParams.mData=data;
	socket->mRequestParameters.mReceiveParams.mSize=size;

	socket->mResponseCode=RESPONSE_UNDEFINED;
	Sockets_PushRequest(socket);
	TaskManager_InterruptActivation(gSocketTask);
	smsc_semaphore_wait(&(socket->mResponseSignal));

	SMSC_ASSERT(socket->mResponseCode!=RESPONSE_UNDEFINED);
	if(socket->mResponseCode==RESPONSE_SUCCESSFUL) {
		result=socket->mRequestParameters.mReceiveParams.mSize;
		if(ipAddress!=NULL) {
			IP_ADDRESS_COPY(ipAddress,&(socket->mRequestParameters.mReceiveParams.mIpAddress));
		}
		if(port!=NULL) {
			(*port)=socket->mRequestParameters.mReceiveParams.mPort;
		}
	} else {
		if(socket->mResponseCode!=RESPONSE_CONNECTION_RESET) {
			/* the caller of this function expects that a result of -1 means connection reset */
			SMSC_WARNING(SOCKETS_DEBUG,("Unexpected response code = %d",socket->mResponseCode));
		}
		result=-1;
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}

static int SocketRequest_Send(struct SOCKET * socket, void *data, int size, unsigned int flags)
{
	int result=0;
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	smsc_semaphore_wait(&(socket->mRequestLock));
	SMSC_ASSERT(socket->mRequestCode==REQUEST_UNDEFINED);
	#if TCP_ENABLED
	if(socket->mConnectionWasReset) {
		result=-ECONNRESET;
		goto UNLOCK;
	}
	#endif

	socket->mRequestCode=REQUEST_SEND;
	socket->mRequestParameters.mSendParams.mData=data;
	socket->mRequestParameters.mSendParams.mSize=size;
	socket->mRequestParameters.mSendParams.mFlags=flags;

	socket->mResponseCode=RESPONSE_UNDEFINED;
	Sockets_PushRequest(socket);
	TaskManager_InterruptActivation(gSocketTask);
	smsc_semaphore_wait(&(socket->mResponseSignal));

⌨️ 快捷键说明

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