📄 sockets.c
字号:
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 + -