/***************************************************************************** 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; }
/***************************************************************************** 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; }
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; }