📄 sockets.c
字号:
#if UDP_ENABLED
if(isUdp) {
IP_ADDRESS_COPY(&(socket->mRequestParameters.mReceiveParams.mIpAddress),&originalSourceAddress);
socket->mRequestParameters.mReceiveParams.mPort=originalSourcePort;
} else
#endif
{
#if TCP_ENABLED
SMSC_ASSERT(socket->mControlBlock.mTcp!=NULL);
Tcp_AcknowledgeReceivedData(
socket->mControlBlock.mTcp,
socket->mRequestParameters.mReceiveParams.mSize);
IP_ADDRESS_COPY(&(socket->mRequestParameters.mReceiveParams.mIpAddress),
Tcp_GetRemoteAddress(socket->mControlBlock.mTcp));
socket->mRequestParameters.mReceiveParams.mPort=
Tcp_GetRemotePort(socket->mControlBlock.mTcp);
#endif /* TCP_ENABLED */
}
} else
#endif /* UDP_ENABLED||TCP_ENABLED */
{
SMSC_ERROR(("SocketsInternal_DoReceiveCopy: Unexpected socket type"));
}
}
#if UDP_ENABLED
static void SocketsInternal_UdpReceiveFunction(void * param,
struct UDP_CONTROL_BLOCK * udpControlBlock,
struct PACKET_BUFFER * packetBuffer,
PIP_ADDRESS sourceAddress,
u16_t sourcePort)
{
struct SOCKET * socket=(struct SOCKET *)param;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_ASSERT(packetBuffer!=NULL);
SMSC_ASSERT(sourceAddress!=NULL);
SocketsInternal_PrependSocketData(packetBuffer,sourceAddress,sourcePort);
SocketPacketQueue_Push(&(socket->mReceiveQueue),packetBuffer);
if((socket->mResponseCode==RESPONSE_PENDING)&&
(socket->mRequestCode==REQUEST_RECEIVE))
{
SocketsInternal_DoReceiveCopy(socket);
socket->mResponseCode=RESPONSE_SUCCESSFUL;
smsc_semaphore_signal(&(socket->mResponseSignal));
}
}
#endif /* UDP_ENABLED */
#if UDP_ENABLED
static void SocketsInternal_DoCreateUdpControlBlock(struct SOCKET * socket)
{
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
if(socket->mType!=SOCKET_TYPE_UNDEFINED) {
SocketsInternal_FreeControlBlock(socket);
SMSC_ASSERT(socket->mType==SOCKET_TYPE_UNDEFINED);
}
SMSC_ASSERT(socket->mControlBlock.mUdp==NULL);
socket->mControlBlock.mUdp=Udp_CreateControlBlock();
if(socket->mControlBlock.mUdp!=NULL) {
socket->mType=SOCKET_TYPE_UDP;
if(socket->mRequestParameters.mCreateUdpParams.mUseUdpLite) {
Udp_SetFlags(socket->mControlBlock.mUdp,UDP_FLAGS_UDPLITE);
}
Udp_SetReceiverCallBack(
socket->mControlBlock.mUdp,
SocketsInternal_UdpReceiveFunction,(void *)socket);
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_MEMORY_ERROR;
}
}
#endif /* UDP_ENABLED */
static void SocketsInternal_SignalWaitingThreads(struct SOCKET * socket)
{
struct smsc_select_cb * scb;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
while (1)
{
smsc_semaphore_wait(&gSelectLock);
for (scb = gSelectList; scb; scb = scb->next)
{
if (scb->sem_signalled == 0)
{
/* Test this select call for our socket */
if (scb->readset && FD_ISSET(socket->mSocketIndex, scb->readset))
if ((!SocketPacketQueue_IsEmpty(&(socket->mReceiveQueue)))||
(socket->mReceiveFinishedFlag)
#if TCP_ENABLED
||(socket->mAcceptListSize>0)
||(socket->mConnectionWasReset)
#endif
)
break;
if (scb->writeset && FD_ISSET(socket->mSocketIndex, scb->writeset))
if ((socket->mIsWritable)
#if TCP_ENABLED
||(socket->mConnectionWasReset)
#endif
)
break;
}
}
if (scb)
{
scb->sem_signalled = 1;
smsc_semaphore_signal(&gSelectLock);
smsc_semaphore_signal(scb->sem);
} else {
smsc_semaphore_signal(&gSelectLock);
break;
}
}
}
#if TCP_ENABLED
/* Function to be called when more send buffer space is available. */
static err_t SocketsInternal_TcpSentCallBack(void *arg, struct TCP_CONTROL_BLOCK * tcpControlBlock, u16_t space)
{
struct SOCKET * socket=(struct SOCKET *)arg;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_ASSERT(socket->mType==SOCKET_TYPE_TCP);
if(Tcp_GetAvailableSendSpace(socket->mControlBlock.mTcp)>TCP_SENDABLE_THRESHOLD) {
socket->mIsWritable=1;
SocketsInternal_SignalWaitingThreads(socket);
}
return ERR_OK;
}
/* Function to be called when (in-sequence) data has arrived. */
static err_t SocketsInternal_TcpReceiveCallBack(void *arg, struct TCP_CONTROL_BLOCK * tcpControlBlock, struct PACKET_BUFFER * packetBuffer, err_t err)
{
struct SOCKET * socket=(struct SOCKET *)arg;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_TRACE(SOCKETS_DEBUG,("SocketsInternal_TcpReceiveCallBack:"));
if(packetBuffer!=NULL) {
/* we should not receive more data after receiving end of data */
SMSC_ASSERT(socket->mReceiveFinishedFlag==0);
while(packetBuffer!=NULL) {
struct PACKET_BUFFER * next=PacketBuffer_GetSetNext(packetBuffer,NULL);
SocketPacketQueue_Push(&(socket->mReceiveQueue),packetBuffer);
packetBuffer=next;
}
} else {
socket->mReceiveFinishedFlag=1;
}
if((socket->mResponseCode==RESPONSE_PENDING)&&
(socket->mRequestCode==REQUEST_RECEIVE))
{
SocketsInternal_DoReceiveCopy(socket);
socket->mResponseCode=RESPONSE_SUCCESSFUL;
smsc_semaphore_signal(&(socket->mResponseSignal));
}
if((!SocketPacketQueue_IsEmpty(&(socket->mReceiveQueue)))||
(socket->mReceiveFinishedFlag))
{
SocketsInternal_SignalWaitingThreads(socket);
}
return ERR_OK;
}
/* called to queue the packets when the new control block is not yet associated to new socket. */
static err_t SocketsInternal_PreTcpReceiveCallBack(void *arg, struct TCP_CONTROL_BLOCK * tcpControlBlock, struct PACKET_BUFFER * packetBuffer, err_t err)
{
struct PACKET_BUFFER * tmpbuf=(struct PACKET_BUFFER *)arg;
SMSC_TRACE(SOCKETS_DEBUG,("SocketsInternal_PreTcpReceiveCallBack:"));
/* link the packetBuffers and hold it through tcpControlBlock->mCallbackArgument */
if (tmpbuf!=NULL) {
/* chain it up */
while(PacketBuffer_GetNext(tmpbuf) != NULL)
tmpbuf=PacketBuffer_GetNext(tmpbuf);
PacketBuffer_SetNext(tmpbuf,packetBuffer);
} else {
Tcp_SetCallBackArgument(tcpControlBlock,packetBuffer);
}
return ERR_OK;
}
/* Function to be called when a connection has been set up. */
static err_t SocketsInternal_TcpConnectedCallBack(void *arg, struct TCP_CONTROL_BLOCK * tcpControlBlock, err_t err)
{
struct SOCKET * socket=(struct SOCKET *)arg;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_ASSERT(socket->mType==SOCKET_TYPE_TCP);
SMSC_ASSERT(socket->mRequestCode==REQUEST_CONNECT);
SMSC_ASSERT(socket->mResponseCode==RESPONSE_PENDING);
socket->mErrorCode=err;
if(err==ERR_OK) {
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_UNSUCCESSFUL;
}
smsc_semaphore_signal(&(socket->mResponseSignal));
return ERR_OK;
}
static void SocketsInternal_AcceptNewTcpControlBlock(
struct SOCKET * socket);
/* Function to call when a listener has been connected. */
static err_t SocketsInternal_TcpAcceptCallBack(void *arg, struct TCP_CONTROL_BLOCK * newControlBlock, err_t err)
{
struct SOCKET * socket=(struct SOCKET *)arg;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_ASSERT(newControlBlock!=NULL);
if(socket->mAcceptListSize<socket->mListenBackLog) {
SMSC_ASSERT(socket->mAcceptListSize<SOCKET_MAXIMUM_BACKLOG);
/*Tcp_SetCallBackArgument(socket->mRequestParameters.mAcceptParams.mNewSocket->mControlBlock.mTcp,
socket->mRequestParameters.mAcceptParams.mNewSocket);
Tcp_SetErrorCallBack(socket->mRequestParameters.mAcceptParams.mNewSocket->mControlBlock.mTcp,SocketsInternal_TcpErrorCallBack);
Tcp_SetReceiveCallBack(socket->mRequestParameters.mAcceptParams.mNewSocket->mControlBlock.mTcp,SocketsInternal_TcpReceiveCallBack);
Tcp_SetSentCallBack(socket->mRequestParameters.mAcceptParams.mNewSocket->mControlBlock.mTcp,SocketsInternal_TcpSentCallBack);
*/
/* Initialize temporary receive callback, to receive packets when the application not yet called accept() */
Tcp_SetReceiveCallBack(newControlBlock,SocketsInternal_PreTcpReceiveCallBack);
Tcp_SetCallBackArgument(newControlBlock,NULL);
socket->mAcceptList[socket->mAcceptListSize]=newControlBlock;
socket->mAcceptListSize++;
if((socket->mResponseCode==RESPONSE_PENDING)&&
(socket->mRequestCode==REQUEST_ACCEPT))
{
SocketsInternal_AcceptNewTcpControlBlock(socket);
smsc_semaphore_signal(&(socket->mResponseSignal));
}
if(socket->mAcceptListSize>0) {
SocketsInternal_SignalWaitingThreads(socket);
}
} else {
SMSC_NOTICE(SOCKETS_DEBUG,("SocketsInternal_TcpAcceptCallBack: Unable to accept connection"));
SMSC_NOTICE(SOCKETS_DEBUG,(" Too many connection on backlog"));
return ERR_ABRT;
}
return ERR_OK;
}
/* Function to be called whenever a fatal error occurs. */
static void SocketsInternal_TcpErrorCallBack(void *arg, err_t err)
{
struct SOCKET * socket=(struct SOCKET *)arg;
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
SMSC_ASSERT(socket->mType==SOCKET_TYPE_TCP);
if(err==ERR_RST) {
SMSC_NOTICE(SOCKETS_DEBUG,("SocketsInternal_TcpErrorCallBack: RESET detected"));
socket->mConnectionWasReset=1;
if(socket->mResponseCode==RESPONSE_PENDING) {
if(socket->mRequestCode==REQUEST_RECEIVE) {
SocketsInternal_DoReceiveCopy(socket);
socket->mResponseCode=RESPONSE_CONNECTION_RESET;
smsc_semaphore_signal(&(socket->mResponseSignal));
}
}
SocketsInternal_SignalWaitingThreads(socket);
} else {
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_TcpErrorCallBack: Unhandled error, err=%d",err));
}
}
static void SocketsInternal_DoCreateTcpControlBlock(struct SOCKET * socket)
{
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
if(socket->mType!=SOCKET_TYPE_UNDEFINED) {
SocketsInternal_FreeControlBlock(socket);
SMSC_ASSERT(socket->mType==SOCKET_TYPE_UNDEFINED);
}
SMSC_ASSERT(socket->mControlBlock.mTcp==NULL);
socket->mControlBlock.mTcp=Tcp_NewControlBlock();
if(socket->mControlBlock.mTcp!=NULL) {
socket->mType=SOCKET_TYPE_TCP;
Tcp_SetCallBackArgument(socket->mControlBlock.mTcp,socket);
Tcp_SetErrorCallBack(socket->mControlBlock.mTcp,SocketsInternal_TcpErrorCallBack);
Tcp_SetReceiveCallBack(socket->mControlBlock.mTcp,SocketsInternal_TcpReceiveCallBack);
Tcp_SetSentCallBack(socket->mControlBlock.mTcp,SocketsInternal_TcpSentCallBack);
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_MEMORY_ERROR;
}
}
#endif /* TCP_ENABLED */
static void SocketsInternal_DoBind(struct SOCKET * socket)
{
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
if (socket->mControlBlock.mPointer == NULL) {
/* Need to create a control block first
in other words smsc_socket must complete successfully */
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoBind: Illegal Operation"));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
return;
}
switch (socket->mType) {
#if RAW_ENABLED
case SOCKET_TYPE_RAW:
/*msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);*/
SMSC_ERROR(("SocketsInternal_DoBind: Raw sockets not implemented"));
break;
#endif
#if UDP_ENABLED
case SOCKET_TYPE_UDP:
if(Udp_Bind(
socket->mControlBlock.mUdp,
&(socket->mRequestParameters.mBindParams.mIpAddress),
socket->mRequestParameters.mBindParams.mPort)==ERR_OK)
{
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_UNSUCCESSFUL;
}
break;
#endif
#if TCP_ENABLED
case SOCKET_TYPE_TCP:
if(Tcp_Bind(socket->mControlBlock.mTcp,
&(socket->mRequestParameters.mBindParams.mIpAddress),
socket->mRequestParameters.mBindParams.mPort)==ERR_OK)
{
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_UNSUCCESSFUL;
}
break;
#endif
default:
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoBind: Unknown Socket Type=%"U16_F,(u16_t)(socket->mType)));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
break;
}
}
static void SocketsInternal_DoConnect(struct SOCKET * socket)
{
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
if (socket->mControlBlock.mPointer == NULL) {
/* Need to create a control block first
in other words smsc_socket must complete successfully */
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoConnect: Illegal Operation"));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
return;
}
switch (socket->mType) {
#if RAW_ENABLED
case SOCKET_TYPE_RAW:
/*raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);*/
SMSC_ERROR(("SocketsInternal_DoConnect: Raw sockets not implemented"));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
break;
#endif
#if UDP_ENABLED
case SOCKET_TYPE_UDP:
if(Udp_Connect(socket->mControlBlock.mUdp,
&(socket->mRequestParameters.mConnectParams.mIpAddress),
socket->mRequestParameters.mConnectParams.mPort)==ERR_OK)
{
socket->mResponseCode=RESPONSE_SUCCESSFUL;
} else {
socket->mResponseCode=RESPONSE_UNSUCCESSFUL;
}
break;
#endif
#if TCP_ENABLED
case SOCKET_TYPE_TCP:
Tcp_Connect(socket->mControlBlock.mTcp,
&(socket->mRequestParameters.mConnectParams.mIpAddress),
socket->mRequestParameters.mConnectParams.mPort,
SocketsInternal_TcpConnectedCallBack);
socket->mReceiveFinishedFlag=0;
socket->mResponseCode=RESPONSE_PENDING;
break;
#endif
default:
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoConnect: Unknown Socket Type=%"U16_F,(u16_t)(socket->mType)));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
break;
}
}
static void SocketsInternal_DoDisconnect(struct SOCKET * socket)
{
SMSC_ASSERT(socket!=NULL);
CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
socket->mResponseCode=RESPONSE_SUCCESSFUL;
if (socket->mControlBlock.mPointer == NULL) {
/* Need to create a control block first
in other words smsc_socket must complete successfully */
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoDisconnect: Illegal Operation"));
socket->mResponseCode=RESPONSE_ILLEGAL_OPERATION;
return;
}
switch (socket->mType) {
#if RAW_ENABLED
case SOCKET_TYPE_RAW:
/*raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);*/
SMSC_NOTICE(SOCKETS_DEBUG,("SocketsInternal_DoDisconnect: Raw sockets need not disconnect"));
break;
#endif
#if UDP_ENABLED
case SOCKET_TYPE_UDP:
Udp_Disconnect(socket->mControlBlock.mUdp);
break;
#endif
#if TCP_ENABLED
case SOCKET_TYPE_TCP:
SMSC_NOTICE(SOCKETS_DEBUG,("SocketsInternal_DoDisconnect: TCP sockets need not disconnect, close instead"));
break;
#endif
default:
SMSC_WARNING(SOCKETS_DEBUG,("SocketsInternal_DoDisconnect: Unknown Socket Type=%"U16_F,(u16_t)(socket->mType)));
socket->mResponseCode=R
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -