Example #1
0
/*****************************************************************************
  Function:
	int recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)

  Summary:
	The recvfrom() function is used to receive incoming data that
	has been queued for a socket.

  Description:
	The recvfrom() function is used to receive incoming data that
	has been queued for a socket. This function can be used with
	both datagram and stream type sockets. If the available data
	is too large to fit in the supplied application buffer buf,
	excess bytes are discarded in case of SOCK_DGRAM type
	sockets. For SOCK_STREAM types, the data is buffered
	internally so the application can retreive all data by
	multiple calls of recvfrom.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	buf - application data receive buffer.
	len - buffer length in bytes.
	flags - message flags. Currently this is not supported.
	from - pointer to the sockaddr structure that will be
	filled in with the destination address.
	fromlen - size of buffer pointed by from.

  Returns:
	If recvfrom is successful, the number of bytes copied to
	application buffer buf is returned. A value of zero indicates
	no data available. A return value of SOCKET_ERROR (-1)
	indicates an error condition.

  Remarks:
	None.
  ***************************************************************************/
int recvfrom( SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *rem_addr;
    SOCKET_INFO *remoteSockInfo;

    socket = &BSDSocketArray[s];
    rem_addr = (struct sockaddr_in *)from;

    if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        // If this BSD socket doesn't have a Microchip UDP socket associated
        // with it yet, then no data can be received and we must not use the
        // socket->SocketID parameter, which isn't set yet.
        if(socket->bsdState != SKT_BOUND)
            return 0;

        if(UDPIsGetReady(socket->SocketID))
        {
            // Capture sender information (can change packet to packet)
            if(from && fromlen)
            {
                if((unsigned int)*fromlen >= sizeof(struct sockaddr_in))
                {
                    remoteSockInfo = TCPGetRemoteInfo(socket->SocketID);
                    rem_addr->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
                    rem_addr->sin_port = remoteSockInfo->remotePort.Val;
                    *fromlen = sizeof(struct sockaddr_in);
                }
            }

            return UDPGetArray((BYTE*)buf, len);
        }
    }
    else  //TCP recieve from already connected socket.
    {
        if(from && fromlen)
        {
            // Capture sender information (will always match socket connection information)
            if((unsigned int)*fromlen >= sizeof(struct sockaddr_in))
            {
                remoteSockInfo = TCPGetRemoteInfo(socket->SocketID);
                rem_addr->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
                rem_addr->sin_port = remoteSockInfo->remotePort.Val;
                *fromlen = sizeof(struct sockaddr_in);
            }
        }
        return recv(s, buf, len, 0);
    }
    return 0;
}
/// @cond debug
//****************************************************************************
//	TCPRemote callback function
//****************************************************************************
int cTCPRemote()
{
	SOCKET_INFO* remote_sock;
	remote_sock = TCPGetRemoteInfo(xSocket);
	xNode = remote_sock -> remote;
	return 0;
}
Example #3
0
/*****************************************************************************
  Function:
	SOCKET accept(SOCKET s, struct sockaddr* addr, int* addrlen)

  Summary:
	This function accepts connection requests queued for a listening socket.

  Description:
	The accept function is used to accept connection requests
	queued for a listening socket. If a connection request is
	pending, accept removes the request from the queue, and a new
	socket is created for the connection. The original listening
	socket remains open and continues to queue new connection
	requests. The socket must be a SOCK_STREAM type socket.

  Precondition:
	listen function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to
	socket. must be bound to a local name and in listening mode.
	addr - Optional pointer to a buffer that receives the address
	of the connecting entity.
	addrlen - Optional pointer to an integer that contains the
	length of the address addr

  Returns:
	If the accept function succeeds, it returns a non-negative
	integer that is a descriptor for the accepted socket.
	Otherwise, the value INVALID_SOCKET is returned.

  Remarks:
	None.
  ***************************************************************************/
SOCKET accept(SOCKET s, struct sockaddr* addr, int* addrlen)
{
	struct BSDSocket *pListenSock;
	SOCKET_INFO *remoteSockInfo;
	struct sockaddr_in *addrRemote;
	unsigned int sockCount;
	TCP_SOCKET hTCP;

	if( s >= BSD_SOCKET_COUNT )
		return INVALID_SOCKET;

	pListenSock = &BSDSocketArray[s]; /* Get the pointer to listening server socket */

	if ( pListenSock->bsdState != SKT_BSD_LISTEN )
		return INVALID_SOCKET;
	if ( pListenSock->SocketType != SOCK_STREAM )
		return INVALID_SOCKET;

	for(sockCount = 0; sockCount < BSD_SOCKET_COUNT; sockCount++)
	{
		if(BSDSocketArray[sockCount].bsdState != SKT_LISTEN)
			continue;

		if(BSDSocketArray[sockCount].localPort != pListenSock->localPort)
			continue;

		hTCP = BSDSocketArray[sockCount].SocketID;
		
		// We don't care about connections and disconnections before we can 
		// process them, so clear the reset flag
		TCPWasReset(hTCP);	
		
		if(TCPIsConnected(hTCP))
		{
			remoteSockInfo = TCPGetRemoteInfo(hTCP);
			if(addr)
			{
				if(addrlen)
				{
					if((unsigned int)*addrlen < sizeof(struct sockaddr_in))
						return INVALID_SOCKET;
					addrRemote = (struct sockaddr_in *)addr;
					addrRemote->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
					addrRemote->sin_port = remoteSockInfo->remotePort.Val;
					*addrlen = sizeof(struct sockaddr_in);
				}
			}
			BSDSocketArray[sockCount].remotePort = remoteSockInfo->remotePort.Val;
			BSDSocketArray[sockCount].remoteIP   = remoteSockInfo->remote.IPAddr.Val;
			BSDSocketArray[sockCount].bsdState = SKT_EST;
			return sockCount;
		}
	}

	return INVALID_SOCKET;
}
/*****************************************************************************
  Function:
	SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen )

  Summary:
	This function accepts connection requests queued for a listening socket.

  Description:
	The accept function is used to accept connection requests
	queued for a listening socket. If a connection request is
    pending, accept removes the request from the queue, and a new
    socket is created for the connection. The original listening
    socket remains open and continues to queue new connection
    requests. The socket must be a SOCK_STREAM type socket.

  Precondition:
	listen function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to
    socket. must be bound to a local name and in listening mode.
    addr - Optional pointer to a buffer that receives the address
    of the connecting entity.
    addrlen - Optional pointer to an integer that contains the
    length of the address addr
    
  Returns:
	If the accept function succeeds, it returns a non-negative
    integer that is a descriptor for the accepted socket.
    Otherwise, the value INVALID_SOCKET is returned.

  Remarks:
	None.
  ***************************************************************************/
SOCKET accept( SOCKET s,
               struct sockaddr* addr,
               int* addrlen )
{
    struct BSDSocket *pListenSock;
    SOCKET_INFO *remoteSockInfo;
    struct sockaddr_in *addrRemote;
    unsigned int sockCount;
   
    if( s >= BSD_SOCKET_COUNT )
        return INVALID_SOCKET;

    pListenSock = &BSDSocketArray[s]; /* Get the pointer to listening server socket */

    if ( pListenSock->bsdState < SKT_LISTEN )
        return INVALID_SOCKET;

    for(sockCount = 0; sockCount < BSD_SOCKET_COUNT; sockCount++)
    {
        if((BSDSocketArray[sockCount].bsdState == SKT_LISTEN) && (BSDSocketArray[sockCount].isServer == TRUE))
        {
            if(TCPIsConnected(BSDSocketArray[sockCount].SocketID))
            {
                remoteSockInfo = TCPGetRemoteInfo(BSDSocketArray[sockCount].SocketID);
                addrRemote = (struct sockaddr_in *)addr;
                addrRemote->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
                addrRemote->sin_port = remoteSockInfo->remotePort.Val;
                *addrlen = sizeof(struct sockaddr_in);
                BSDSocketArray[sockCount].remotePort = addrRemote->sin_port;
                BSDSocketArray[sockCount].remoteIP   = addrRemote->sin_addr.S_un.S_addr;
                BSDSocketArray[sockCount].bsdState = SKT_EST;
                return sockCount;
            }
            
        }
    }

    return INVALID_SOCKET;
}
/*****************************************************************************
  Function:
	int recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)

  Summary:
	The recvfrom() function is used to receive incoming data that
    has been queued for a socket.

  Description:
	The recvfrom() function is used to receive incoming data that
    has been queued for a socket. This function can be used with
    both datagram and stream type sockets. If the available data
    is too large to fit in the supplied application buffer buf,
    excess bytes are discarded in case of SOCK_DGRAM type
    sockets. For SOCK_STREAM types, the data is buffered
    internally so the application can retreive all data by
    multiple calls of recvfrom.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
    buf - application data receive buffer.
    len - buffer length in bytes.
    flags - message flags. Currently this is not supported.
    from - pointer to the sockaddr structure that will be
    filled in with the destination address.
    fromlen - size of buffer pointed by from.

  Returns:
	If recvfrom is successful, the number of bytes copied to
    application buffer buf is returned. A value of zero indicates
    no data available. A return value of SOCKET_ERROR (-1)
    indicates an error condition.

  Remarks:
	None.
  ***************************************************************************/
int recvfrom( SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *rem_addr;
    SOCKET_INFO *remoteSockInfo;
    
    socket = &BSDSocketArray[s];
    rem_addr = (struct sockaddr_in *)from;
    
    if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if(socket->bsdState != SKT_EST)
        {
            socket->SocketID = UDPOpen(socket->localPort, NULL, socket->localPort); //recieve on the same port.
            socket->bsdState = SKT_EST;
        }
        
        if(socket->bsdState == SKT_EST)
        {
            if(UDPIsGetReady(socket->SocketID) > 0)
            {
                return UDPGetArray((BYTE*)buf, len);
            }
        }
    }
    else  //TCP recieve from already connected socket.
    {
        if(from && fromlen && ((unsigned int)*fromlen >= sizeof(struct sockaddr_in)))
        {
            remoteSockInfo = TCPGetRemoteInfo(socket->SocketID);
            rem_addr->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
            rem_addr->sin_port = remoteSockInfo->remotePort.Val;
            *fromlen = sizeof(struct sockaddr_in);
        }
        return recv(s, buf, len, 0);
    }
    return 0;
}
Example #6
0
static BOOL PutFile(void)
{
    BYTE v;


    switch(smFTPCommand)
    {
    case SM_FTP_CMD_IDLE:
        if ( !FTPFlags.Bits.bLoggedIn )
        {
            FTPResponse     = FTP_RESP_LOGIN;
            return TRUE;
        }
        else
        {
			FTPResponse     = FTP_RESP_DATA_OPEN;
            FTPDataSocket   = TCPOpen((PTR_BASE)&TCPGetRemoteInfo(FTPSocket)->remote, TCP_OPEN_NODE_INFO, FTPDataPort.Val, TCP_PURPOSE_FTP_DATA);

			// Make sure that a valid socket was available and returned
			// If not, return with an error
			if(FTPDataSocket == INVALID_SOCKET)
			{
	            FTPResponse = FTP_RESP_DATA_NO_SOCKET;
	            return TRUE;
			}
			
			smFTPCommand = SM_FTP_CMD_WAIT;
        }
        break;

    case SM_FTP_CMD_WAIT:
        if ( TCPIsConnected(FTPDataSocket) )
        {
#if defined(FTP_PUT_ENABLED)
			FTPFileHandle   = MPFSFormat();
#endif

			smFTPCommand    = SM_FTP_CMD_RECEIVE;
        }
        break;

    case SM_FTP_CMD_RECEIVE:
        if ( TCPIsGetReady(FTPDataSocket) )
        {
            // Reload timeout timer.
            lastActivity    = TickGet();
            MPFSPutBegin(FTPFileHandle);
            while( TCPGet(FTPDataSocket, &v) )
            {
#if defined(FTP_PUT_ENABLED)
                MPFSPut(v);
#endif
            }
            FTPFileHandle = MPFSPutEnd();

        }
        else if ( !TCPIsConnected(FTPDataSocket) )
        {
#if defined(FTP_PUT_ENABLED)
            MPFSClose();
#endif
            TCPDisconnect(FTPDataSocket);
            FTPDataSocket   = INVALID_SOCKET;
            FTPResponse     = FTP_RESP_DATA_CLOSE;
            return TRUE;
        }
    }
    return FALSE;
}