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

📄 sockets.c

📁 由smsc公司改进的lwip2.1.1基于嵌入式系统的TCP/ip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:

	SMSC_ASSERT(socket->mResponseCode!=RESPONSE_UNDEFINED);
	if(socket->mResponseCode==RESPONSE_SUCCESSFUL) {
		result=socket->mRequestParameters.mSendParams.mSize;
	} else {
		if(socket->mResponseCode==RESPONSE_CONNECTION_RESET) {
			result=-ECONNRESET;
		} else if (socket->mResponseCode==RESPONSE_MEMORY_ERROR) {
			result=-ENOBUFS;
		} else {
			SMSC_WARNING(SOCKETS_DEBUG,("SocketRequest_Send: unexpected response code = %d",socket->mResponseCode));
			result=-EIO;
		}
	}
#if TCP_ENABLED
UNLOCK:
#endif
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}

static err_t SocketRequest_GetPeer(struct SOCKET * socket,PIP_ADDRESS ipAddress, u16_t * port)
{
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	switch(socket->mType)
	{
#if RAW_ENABLED
	case SOCKET_TYPE_RAW:
		return ERR_CONN;
#endif
#if UDP_ENABLED
	case SOCKET_TYPE_UDP:
		if((socket->mControlBlock.mUdp==NULL) ||
			(((Udp_GetFlags(socket->mControlBlock.mUdp))&UDP_FLAGS_CONNECTED)==0))
		{
			return ERR_CONN;
		}
		IP_ADDRESS_COPY(ipAddress,Udp_GetRemoteAddress(socket->mControlBlock.mUdp));
		(*port)=Udp_GetRemotePort(socket->mControlBlock.mUdp);
		break;
#endif
#if TCP_ENABLED
	case SOCKET_TYPE_TCP:
		if(socket->mControlBlock.mTcp==NULL) {
			return ERR_CONN;
		}
		IP_ADDRESS_COPY(ipAddress,Tcp_GetRemoteAddress(socket->mControlBlock.mTcp));
		(*port)=Tcp_GetRemotePort(socket->mControlBlock.mTcp);
		break;
#endif
	default:
		return ERR_CONN;	
	}
	return ERR_OK;
}

static int SocketRequest_Bind(struct SOCKET * socket, 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_BIND;
	IP_ADDRESS_COPY(&(socket->mRequestParameters.mBindParams.mIpAddress),ipAddress);
	socket->mRequestParameters.mBindParams.mPort=port;

	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=-1;
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}

static err_t SocketRequest_Connect(struct SOCKET * socket, PIP_ADDRESS ipAddress, u16_t port)
{
	err_t result=ERR_OK;
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	smsc_semaphore_wait(&(socket->mRequestLock));
	SMSC_ASSERT(socket->mRequestCode==REQUEST_UNDEFINED);

	socket->mRequestCode=REQUEST_CONNECT;
	IP_ADDRESS_COPY(&(socket->mRequestParameters.mConnectParams.mIpAddress),ipAddress);
	socket->mRequestParameters.mConnectParams.mPort=port;

	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=ERR_VAL;
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}

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

	socket->mRequestCode=REQUEST_DISCONNECT;

	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=ERR_VAL;
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}

#if UDP_ENABLED
static int SocketRequest_CreateUdpControlBlock(
	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_CREATE_UDP_CONTROL_BLOCK;
	socket->mRequestParameters.mCreateUdpParams.mUseUdpLite=0;

	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=-1;
	} else {
		SMSC_ASSERT(socket->mControlBlock.mUdp!=NULL);
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}
#endif /* UDP_ENABLED */

#if TCP_ENABLED
static int SocketRequest_CreateTcpControlBlock(
	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_CREATE_TCP_CONTROL_BLOCK;
	
	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=-1;
	} else {
		SMSC_ASSERT(socket->mControlBlock.mTcp!=NULL);
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;
}
#endif /* TCP_ENABLED */

#if TCP_ENABLED
static err_t SocketRequest_Listen(struct SOCKET * socket)
{
	err_t result=ERR_OK;
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	smsc_semaphore_wait(&(socket->mRequestLock));
	SMSC_ASSERT(socket->mRequestCode==REQUEST_UNDEFINED);
	
	socket->mRequestCode=REQUEST_LISTEN;
	
	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=ERR_MEM;
		/* NOTE this may not be the most appropriate error code 
			but the important thing is that it is not ERR_OK */
	}
	socket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(socket->mRequestLock));
	return result;	
}

static int SocketRequest_AcceptTcpControlBlock(
	struct SOCKET * listenerSocket,
	struct SOCKET * acceptedSocket,
	PIP_ADDRESS fromIpAddress,
	u16_t * fromPort)
{
	int result=0;
	SMSC_ASSERT(listenerSocket!=NULL);
	CHECK_SIGNATURE(listenerSocket,SOCKET_SIGNATURE);
	SMSC_ASSERT(acceptedSocket!=NULL);
	CHECK_SIGNATURE(acceptedSocket,SOCKET_SIGNATURE);

	smsc_semaphore_wait(&(listenerSocket->mRequestLock));
	SMSC_ASSERT(listenerSocket->mRequestCode==REQUEST_UNDEFINED);

	listenerSocket->mRequestCode=REQUEST_ACCEPT;
	listenerSocket->mRequestParameters.mAcceptParams.mNewSocket=acceptedSocket;

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

	SMSC_ASSERT(listenerSocket->mResponseCode!=RESPONSE_UNDEFINED);
	if(listenerSocket->mResponseCode!=RESPONSE_SUCCESSFUL) {
		result=ERR_MEM;
		/* NOTE this may not be the most appropriate error code 
			but the important thing is that it is not ERR_OK */
	} else {
		SMSC_ASSERT(acceptedSocket->mType==SOCKET_TYPE_TCP);
		SMSC_ASSERT(acceptedSocket->mControlBlock.mTcp!=NULL);
		if(fromIpAddress!=NULL) {
			IP_ADDRESS_COPY(fromIpAddress,&(listenerSocket->mRequestParameters.mAcceptParams.mFromIpAddress));
		}
		if(fromPort!=NULL) {
			(*fromPort)=listenerSocket->mRequestParameters.mAcceptParams.mFromPort;
		}
	}
	listenerSocket->mRequestCode=REQUEST_UNDEFINED;
	smsc_semaphore_signal(&(listenerSocket->mRequestLock));
	
	return result;
}
#endif /* TCP_ENABLED */

static void SocketsInternal_FreeControlBlock(struct SOCKET * socket)
{
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	switch(socket->mType) {
	case SOCKET_TYPE_UNDEFINED:
		SMSC_ASSERT(socket->mControlBlock.mPointer==NULL);
		break;
#if RAW_ENABLED
	case SOCKET_TYPE_RAW:
		SMSC_ERROR(("SocketsInternal_FreeControlBlock: Raw sockets are not implemented"));
		break;
#endif
#if UDP_ENABLED
	case SOCKET_TYPE_UDP:
		SMSC_ASSERT(socket->mControlBlock.mUdp!=NULL);
		Udp_FreeControlBlock(socket->mControlBlock.mUdp);
		socket->mControlBlock.mUdp=NULL;		
		break;
#endif
#if TCP_ENABLED
	case SOCKET_TYPE_TCP:
		SMSC_ASSERT(socket->mControlBlock.mTcp!=NULL);
		Tcp_FreeControlBlock(socket->mControlBlock.mTcp);
		socket->mControlBlock.mTcp=NULL;
		break;
#endif
	default:
		SMSC_ERROR(("SocketsInternal_FreeControlBlock: unknown socket type = %"U16_F,((u16_t)(socket->mType)) ));
		break;
	}
	socket->mType=SOCKET_TYPE_UNDEFINED;
}
#if UDP_ENABLED
static void SocketsInternal_PrependSocketData(struct PACKET_BUFFER * packetBuffer,PIP_ADDRESS ipAddress,u16_t port)
{
	SMSC_ASSERT(packetBuffer!=NULL);
	SMSC_ASSERT(ipAddress!=NULL);
	/* Use header space to store port number */
	if(PacketBuffer_MoveStartPoint(packetBuffer,-MEMORY_ALIGNED_SIZE(sizeof(u16_t)))!=ERR_OK) {
		SMSC_ERROR(("SocketsInternal_PrependSocketData: Failed to reserve space for port number"));
	}
	(*((u16_t *)(PacketBuffer_GetStartPoint(packetBuffer))))=port;
	
	/* Use header space to store ip address */
	if(PacketBuffer_MoveStartPoint(packetBuffer,-MEMORY_ALIGNED_SIZE(sizeof(IP_ADDRESS)))!=ERR_OK) {
		SMSC_ERROR(("SocketsInternal_PrependSocketData: Failed to reserve space for ip address"));
	}
	IP_ADDRESS_COPY(((PIP_ADDRESS)PacketBuffer_GetStartPoint(packetBuffer)),ipAddress);
}

static void SocketsInternal_ExtractSocketData(struct PACKET_BUFFER * packetBuffer,PIP_ADDRESS ipAddress,u16_t *port)
{
	SMSC_ASSERT(packetBuffer!=NULL);
	SMSC_ASSERT(ipAddress!=NULL);
	SMSC_ASSERT(port!=NULL);
	
	IP_ADDRESS_COPY(ipAddress,((PIP_ADDRESS)PacketBuffer_GetStartPoint(packetBuffer)));
	if(PacketBuffer_MoveStartPoint(packetBuffer,MEMORY_ALIGNED_SIZE(sizeof(IP_ADDRESS)))!=ERR_OK) {
		SMSC_ERROR(("SocketsInternal_ExtractSocketData: Failed to extract ip address"));
	}
	
	(*port)=(*((u16_t *)(PacketBuffer_GetStartPoint(packetBuffer))));
	if(PacketBuffer_MoveStartPoint(packetBuffer,MEMORY_ALIGNED_SIZE(sizeof(u16_t)))!=ERR_OK) {
		SMSC_ERROR(("SocketsInternal_ExtractSocketData: Failed to extract port number"));
	}
}
#endif /* UDP_ENABLED */

static void SocketsInternal_DoReceiveCopy(struct SOCKET * socket)
{
	SMSC_ASSERT(socket!=NULL);
	CHECK_SIGNATURE(socket,SOCKET_SIGNATURE);
	SMSC_ASSERT(socket->mRequestCode==REQUEST_RECEIVE);

#if UDP_ENABLED||TCP_ENABLED
	if(
#if UDP_ENABLED
		(socket->mType==SOCKET_TYPE_UDP)
#endif
#if UDP_ENABLED&&TCP_ENABLED
		||
#endif
#if TCP_ENABLED
		(socket->mType==SOCKET_TYPE_TCP)
#endif
	) {
		struct PACKET_BUFFER * packetBuffer;
		s32_t size=(u32_t)(socket->mRequestParameters.mReceiveParams.mSize);
		u8_t * data=((u8_t *)(socket->mRequestParameters.mReceiveParams.mData));
		#if UDP_ENABLED
		IP_ADDRESS originalSourceAddress;
		u16_t originalSourcePort;
		IP_ADDRESS nextAddress;
		u16_t nextPort;
		int isUdp=0;
		if(socket->mType==SOCKET_TYPE_UDP) {
			isUdp=1;
		}
		#endif
		SMSC_ASSERT(data!=NULL);

		packetBuffer=SocketPacketQueue_Pop(&(socket->mReceiveQueue));
		#if UDP_ENABLED
		if((packetBuffer!=NULL)&&(isUdp)) {
			SocketsInternal_ExtractSocketData(packetBuffer,&originalSourceAddress,&originalSourcePort);
		}
		#endif

		/* Copy all packets whose total length will fit in the receive buffer */
		while( (packetBuffer!=NULL) &&
			((PacketBuffer_GetTotalLength(packetBuffer))<=size) )
		{
			do {
				struct PACKET_BUFFER * nextBuffer=PacketBuffer_GetNextPointer(packetBuffer);
				u16_t thisLength=PacketBuffer_GetThisLength(packetBuffer);
				SMSC_ASSERT(size>=thisLength);
				memcpy(data,PacketBuffer_GetStartPoint(packetBuffer),thisLength);
				data+=thisLength;
				size-=thisLength;
				PacketBuffer_SetTotalLength(packetBuffer,thisLength);
				PacketBuffer_SetNextPointer(packetBuffer,NULL);
				PacketBuffer_DecreaseReference(packetBuffer);
				packetBuffer=nextBuffer;
			} while(packetBuffer!=NULL);
			
			packetBuffer=SocketPacketQueue_Pop(&(socket->mReceiveQueue));
			#if UDP_ENABLED
			if((packetBuffer!=NULL)&&(isUdp)) {
				SocketsInternal_ExtractSocketData(packetBuffer,&nextAddress,&nextPort);
				if((nextPort!=originalSourcePort)||(!IP_ADDRESS_COMPARE(&nextAddress,&originalSourceAddress)))
				{
					SocketsInternal_PrependSocketData(packetBuffer,&nextAddress,nextPort);
					SocketPacketQueue_UnPop(&(socket->mReceiveQueue),packetBuffer);
					packetBuffer=NULL;
				}
			}
			#endif
		}
		
		/* Copy all packet buffers whose full buffer length will fit in receive buffer */
		while( (packetBuffer!=NULL) &&
			((PacketBuffer_GetThisLength(packetBuffer))<=size) )
		{
			struct PACKET_BUFFER * nextBuffer=PacketBuffer_GetNextPointer(packetBuffer);
			u16_t thisLength=PacketBuffer_GetThisLength(packetBuffer);
			memcpy(data,PacketBuffer_GetStartPoint(packetBuffer),thisLength);
			data+=thisLength;
			size-=thisLength;
			PacketBuffer_SetTotalLength(packetBuffer,thisLength);
			PacketBuffer_SetNextPointer(packetBuffer,NULL);
			PacketBuffer_DecreaseReference(packetBuffer);
			packetBuffer=nextBuffer;
		}
		
		/* Copy part of the last buffer into the remaining size of receive buffer */
		if(packetBuffer!=NULL) {
			if(size>0) {
				SMSC_ASSERT(PacketBuffer_GetThisLength(packetBuffer)>size);
				memcpy(data,PacketBuffer_GetStartPoint(packetBuffer),(s16_t)size);
				PacketBuffer_MoveStartPoint(packetBuffer,(s16_t)size);
				data+=size;
				size=0;
			}
			#if UDP_ENABLED
			if(isUdp) {
				SocketsInternal_PrependSocketData(packetBuffer,&originalSourceAddress,originalSourcePort);
			}
			#endif
			SocketPacketQueue_UnPop(&(socket->mReceiveQueue),packetBuffer);
		}
		socket->mRequestParameters.mReceiveParams.mSize-=(int)size;

⌨️ 快捷键说明

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