Exemplo n.º 1
0
/****************************************************************************
  Function:
    BOOL UDPNodeInfoFromIP(IP_ADDR ipAddrRemote, NODE_INFO * pnodeInfo, unsigned int cSecTimeout)

  Description:
    Does an ARP to resolve the MAC address for a give IP Address

  Precondition:
    UDP stack has to be up an running

  Parameters:
    ipAddrRemote    - an IP_ADDR with the IP address of the remote machine you want to
                        discover the MAC address for.
    pnoeInfo        - a pointer to an empty NODE_INFO structure. The IP address and MAC will
                        be loaded into the sturcture
    cSecTimout      - The maximum number of seconds to wait for the arp address to be resolved
                        if it can't be done in this amount of time, return with FALSE as unresolved.

  Returns:
    TRUE if the MAC address was resolved, FALSE if it was not.

  Remarks:
    None
  ***************************************************************************/
static BOOL UDPNodeInfoFromIP(IP_ADDR ipAddrRemote, NODE_INFO * pnodeInfo, unsigned int cSecTimeout) 
{
	DWORD t = 0;
    
    pnodeInfo->IPAddr = ipAddrRemote;

    // if this the broadcast IP address, then set the broadcast mac.
    if(ipAddrRemote.Val == 0xFFFFFFFF)
    {
        memset(&pnodeInfo->MACAddr, 0xFF, sizeof(pnodeInfo->MACAddr));
        return(TRUE);
    }

    // resolve the IP address to get a MAC
    ARPResolve(&ipAddrRemote);
	t = TickGet();
    while( !ARPIsResolved(&ipAddrRemote, &pnodeInfo->MACAddr) )
    {
        if((TickGet() - t) >= (cSecTimeout * TICK_SECOND))
        {
            return(FALSE);
        }

        ChipKITPeriodicTasks();
    }

    return(TRUE);
}
Exemplo n.º 2
0
Arquivo: gnet.c Projeto: draringi/gini
void *GNETHandler(void *outq)
{
	char tmpbuf[MAX_NAME_LEN];
	interface_t *iface;
	uchar mac_addr[6];
	simplequeue_t *outputQ = (simplequeue_t *)outq;
	gpacket_t *in_pkt;
	int inbytes, cached;

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);       // die as soon as cancelled
	while (1)
	{
		verbose(2, "[gnetHandler]:: Reading message from output Queue..");
		if (readQueue(outputQ, (void **)&in_pkt, &inbytes) == EXIT_FAILURE)
			return NULL;
		verbose(2, "[gnetHandler]:: Recvd message pkt ");
		pthread_testcancel();

		if ((iface = findInterface(in_pkt->frame.dst_interface)) == NULL)
		{
			error("[gnetHandler]:: Packet dropped, interface [%d] is invalid ", in_pkt->frame.dst_interface);
			continue;
		} else if (iface->state == INTERFACE_DOWN)
		{
			error("[gnetHandler]:: Packet dropped! Interface not up");
			continue;
		}

		if (!in_pkt->frame.openflow)
		{
			// we have a valid interface handle -- iface.
			COPY_MAC(in_pkt->data.header.src, iface->mac_addr);

			if (in_pkt->frame.arp_valid == TRUE)
				putARPCache(in_pkt->frame.nxth_ip_addr, in_pkt->data.header.dst);
			else if (in_pkt->frame.arp_bcast != TRUE)
			{
				if ((cached = lookupARPCache(in_pkt->frame.nxth_ip_addr,
							     mac_addr)) == TRUE)
					COPY_MAC(in_pkt->data.header.dst, mac_addr);
				else
				{
					ARPResolve(in_pkt);
					continue;
				}
			}
		}

		iface->devdriver->todev((void *)in_pkt);

	}
}
Exemplo n.º 3
0
void ICMPSendPing(DWORD dwRemoteIP)
{
	// Figure out the MAC address to send to
	ICMPRemote.IPAddr.Val = dwRemoteIP;
	ARPResolve(&ICMPRemote.IPAddr);

	// Set up the ping packet
	ICMPHeader.vType = 0x08;	// 0x08: Echo (ping) request
	ICMPHeader.vCode = 0x00;
	ICMPHeader.wvChecksum.Val = 0x0000;
	ICMPHeader.wvIdentifier.Val = 0xEFBE;
	ICMPHeader.wvSequenceNumber.Val++;
	ICMPHeader.wvChecksum.Val = CalcIPChecksum((BYTE*)&ICMPHeader, sizeof(ICMPHeader));

	// Kick off the ICMPGetReply() state machine
	ICMPTimer = TickGet();
	ICMPFlags.bReplyValid = 0;
	ICMPState = SM_ARP_RESOLVE;
}
Exemplo n.º 4
0
/*********************************************************************
 * Function:        void TFTPOpen(IP_ADDR *host)
 *
 * PreCondition:    UDP module is already initialized
 *                  and at least one UDP socket is available.
 *
 * Input:           host        - IP address of remote TFTP server
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Initiates ARP for given host and prepares
 *                  TFTP module for next sequence of function calls.
 *
 * Note:            Use TFTPIsOpened() to check if a connection was
 *                  successfully opened or not.
 *
 ********************************************************************/
void TFTPOpen(IP_ADDR *host)
{
    DEBUG(printf("Opening a connection..."));

    // Remember this address locally.
    MutExVar.group1._hostInfo.IPAddr.Val = host->Val;

    // Initiate ARP resolution.
    ARPResolve(&MutExVar.group1._hostInfo.IPAddr);

    // Wait for ARP to get resolved.
    _tftpState = SM_TFTP_WAIT;

    // Mark this as start tick to detect timeout condition.
    _tftpStartTick = TickGet();

    // Forget about all previous attempts.
    _tftpRetries = 1;

}
Exemplo n.º 5
0
/*
 * Main entry point.
 */
void main(void)
{
    TICK8  tsecWait = 0;           //General purpose wait timer
    TICK16 tsecMsgSent = 0;        //Time last message was sent
    TICK16 tsecBlinker = 0;  
    BYTE main_state;				// what are the inputs
	BYTE main_inputs;				// who has the transmit
    char c;
    NODE_INFO udpServerNode;

    //Initialize AppConfig structure
    appcfgInit();
    
    //Initialize any application specific hardware.
    InitializeBoard();

    //Initialize all stack related components.
    TickInit();

    //Initialize the TCP/IP stack
    StackInit();


    /////////////////////////////////////////////////
    //Initialize UDP socket

    //Initialize remote IP and address with 10.1.0.101. The MAC address is
    //is not intialized yet, but after we receive an ARP responce.
    //Configure for local port 54123 and remote port 54124.
    udpServerNode.IPAddr.v[0] = 255;
    udpServerNode.IPAddr.v[1] = 255;
    udpServerNode.IPAddr.v[2] = 255;
    udpServerNode.IPAddr.v[3] = 255;
    udpSocketUser = UDPOpen(54123, &udpServerNode, 54124);
	//udpSocketUser = UDPOpen(54123, NULL, 54124);
	smUdp = SM_UDP_RESOLVED;
    
    //An error occurred during the UDPOpen() function
    if (udpSocketUser == INVALID_UDP_SOCKET) {
        //Add user code here to take action if required!
    }

    /*
     * Once all items are initialized, go into infinite loop and let stack items execute
     * their tasks. If the application needs to perform its own task, it should be done at
     * the end of while loop. Note that this is a "co-operative mult-tasking" mechanism where
     * every task performs its tasks (whether all in one shot or part of it) and returns so
     * that other tasks can do their job. If a task needs very long time to do its job, it
     * must broken down into smaller pieces so that other tasks can have CPU time.
     */
    while(1)
    {
	    ServiceBoard();
		if (TickGetSecDiff(tsecBlinker) >= (TICK16)1) 
		{
			tsecBlinker = TickGetSec();     //Update with current time
			//Toggle system LED 
#ifdef BLINKTIME
            TRISB_RB6 = 0;
            LATB6 ^= 1;
#endif
		}
        switch (smUdp) {
        case SM_UDP_SEND_ARP:
            if (ARPIsTxReady()) {
                tsecWait = TickGet8bitSec();   //Remember when we sent last request
                
                //Send ARP request for given IP address
                ARPResolve(&udpServerNode.IPAddr);
                
                smUdp = SM_UDP_WAIT_RESOLVE;
            }
            break;
        case SM_UDP_WAIT_RESOLVE:
            //The IP address has been resolved, we now have the MAC address of the
            //node at 10.1.0.101
            if (ARPIsResolved(&udpServerNode.IPAddr, &udpServerNode.MACAddr)) {
                smUdp = SM_UDP_RESOLVED;
            }
            //If not resolved after 2 seconds, send next request
            else {
                if (TickGetDiff8bitSec(tsecWait) >= (TICK8)2) {
                    smUdp = SM_UDP_SEND_ARP;
                }
            }
            break;
        case SM_UDP_RESOLVED:
            if ( 1 || !PORTB_RB0) {
                //Send a message every second for as long as PIC port pin B0 is = 0
                if ((TickGetSecDiff(tsecMsgSent) >= (TICK16)1) ||
					((main_state != old_state) || (main_inputs != old_inputs))) {
                    //Checks if there is a transmit buffer ready for accepting data, and that the given socket
                    //is valid (not equal to INVALID_UDP_SOCKET for example)
                    if (UDPIsPutReady(udpSocketUser)) {
                        tsecMsgSent = TickGetSec();     //Update with current time

                        //Send a UDP Datagram with one byte only indicating the status We are only interrested in the first byte of the message.
                        UDPPut('H');UDPPut('E');UDPPut('L');UDPPut('L');UDPPut('O');
						UDPPut(old_state);
						UDPPut(old_inputs);
						main_state = old_state;
						main_inputs = old_inputs;
                        //Send contents of transmit buffer, and free buffer
                        UDPFlush();
                       	
						//Toggle system LED each time a message is sent
                    	TRISB_RB6 = 0;
                    	LATB6 ^= 1; 
                    }

                    
                }
            }
            break;
        }

        //This task performs normal stack task including checking for incoming packet,
        //type of packet and calling appropriate stack entity to process it.
        StackTask();

        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        // ADD USER CODE HERE
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
Exemplo n.º 6
0
/*****************************************************************************
  Function:
	int sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen)

  Summary:
	This function used to send the data for both connection oriented and connection-less
	sockets.

  Description:
	The sendto function is used to send outgoing data on a socket.
	The destination address is given by to and tolen. Both 
	Datagram and stream sockets are supported.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	buf - application data buffer containing data to transmit.
	len - length of data in bytes.
	flags - message flags. Currently this field is not supported.
	to - Optional pointer to the the sockaddr structure containing the
		destination address.  If NULL, the currently bound remote port and IP 
		address are used as the destination.
	tolen - length of the sockaddr structure.

  Returns:
	On success, sendto returns number of bytes sent. In case of
	error returns SOCKET_ERROR

  Remarks:
	None.
  ***************************************************************************/
int sendto( SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen )
{
	struct BSDSocket *socket;
	int size = SOCKET_ERROR;
	NODE_INFO remoteInfo;
//	static DWORD startTick;		// NOTE: startTick really should be a per socket BSDSocket structure member since other BSD calls can interfere with the ARP cycles
	WORD wRemotePort;
	struct sockaddr_in local;

	if( s >= BSD_SOCKET_COUNT )
		return SOCKET_ERROR;

	socket = &BSDSocketArray[s];

	if(socket->bsdState == SKT_CLOSED)
		return SOCKET_ERROR;

	if(socket->SocketType == SOCK_DGRAM) //UDP
	{
		// Decide the destination IP address and port
		remoteInfo.IPAddr.Val = socket->remoteIP;
		wRemotePort = socket->remotePort;
		if(to)
		{
			if((unsigned int)tolen != sizeof(struct sockaddr_in))
				return SOCKET_ERROR;
			wRemotePort = ((struct sockaddr_in*)to)->sin_port;
			remoteInfo.IPAddr.Val = ((struct sockaddr_in*)to)->sin_addr.s_addr;
			
			// Implicitly bind the socket if it isn't already
			if(socket->bsdState == SKT_CREATED)
			{
				memset(&local, 0x00, sizeof(local));
				if(bind(s, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
					return SOCKET_ERROR;
			}
		}
		if(UDPIsOpened((UDP_SOCKET)s) != TRUE)
			return SOCKET_ERROR;
		
		if(remoteInfo.IPAddr.Val == IP_ADDR_ANY)
			remoteInfo.IPAddr.Val = 0xFFFFFFFFu;

#if 0
		// Set the remote IP and MAC address if it is different from what we already have stored in the UDP socket
		if(UDPSocketInfo[socket->SocketID].remoteNode.IPAddr.Val != remoteInfo.IPAddr.Val)
		{
			if(ARPIsResolved(&remoteInfo.IPAddr, &remoteInfo.MACAddr))
			{
				memcpy((void*)&UDPSocketInfo[socket->SocketID].remoteNode, (void*)&remoteInfo, sizeof(remoteInfo));
			}
			else
			{
				if(TickGet() - startTick > 1*TICK_SECOND)
				{
					ARPResolve(&remoteInfo.IPAddr);
					startTick = TickGet();
				}
				return SOCKET_ERROR;
			}
		}
#endif		
		// Select the UDP socket and see if we can write to it
		if(UDPIsPutReady(socket->SocketID))
		{
			// Set the proper remote port
			UDPSocketInfo[socket->SocketID].remotePort = wRemotePort;

			// Write data and send UDP datagram
			size = UDPPutArray((BYTE*)buf, len);
			UDPFlush();
			return size;
		}
	}
	else if(socket->SocketType == SOCK_STREAM) //TCP will only send to the already established socket.
	{
		if(socket->bsdState != SKT_EST)
			return SOCKET_ERROR;

		if(HandlePossibleTCPDisconnection(s))
			return SOCKET_ERROR;
			
		// Handle special case were 0 return value is okay
		if(len == 0)
			return 0;

		// Write data to the socket. If one or more bytes were written, then 
		// return this value.  Otherwise, fail and return SOCKET_ERROR.
		size = TCPPutArray(socket->SocketID, (BYTE*)buf, len);
		if(size)
			return size;
	}
	return SOCKET_ERROR;
}
Exemplo n.º 7
0
void AutoIPTasks(void)
{
    BYTE i;

    for (i = 0; i < NETWORK_INTERFACES; i++)
    {
        LoadState (i);
        AutoIPClient.flags.bits.bCurrentLinkState = MACIsLinked();
    	if(AutoIPClient.flags.bits.bCurrentLinkState != AutoIPClient.flags.bits.bLastLinkState)
    	{
    		AutoIPClient.flags.bits.bLastLinkState = AutoIPClient.flags.bits.bCurrentLinkState;
    		if(!AutoIPClient.flags.bits.bCurrentLinkState)
    		{
                AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
    			AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
    			AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
    		}
            else
            {
                AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
    	}
    
        #if defined (STACK_USE_DHCP_CLIENT)
        if (DHCPIsBound(i))
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
            AutoIPClient.flags.bits.bLastDHCPState = TRUE;
        }
        else
        {
            if (AutoIPClient.flags.bits.bLastDHCPState == TRUE)
            {
                if (AutoIPClient.flags.bits.bCurrentLinkState)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
            AutoIPClient.flags.bits.bLastDHCPState = FALSE;
        }
        #endif
    
    
        if (AutoIPClient.flags.bits.gDisableAutoIP == TRUE)
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
        }
    
    
        switch (AutoIPClient.smAUTOIPState)
        {
            // Default no-AutoIP case
        	case SM_AUTOIP_DISABLED:

                break;
    
            // Initializes the random number generator with a seed based on the MAC address
            case SM_AUTOIP_INIT_RNG:
                AutoIPRandSeed (((DWORD)AppConfig.MyMACAddr.v[0] + ((DWORD)AppConfig.MyMACAddr.v[1] << 8) + \
                        ((DWORD)AppConfig.MyMACAddr.v[2] << 16) + ((DWORD)AppConfig.MyMACAddr.v[3] << 24) + \
                        ((DWORD)AppConfig.MyMACAddr.v[4]) + ((DWORD)AppConfig.MyMACAddr.v[5] << 8)), i);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
    
            // Check the address to see if it's in use before we write it into AppConfig
            case SM_AUTOIP_CHECK_ADDRESS:
    
                if (AutoIPClient.flags.bits.checkAddress == FALSE)
                {
                    AutoIPClient.flags.bits.checkAddress = TRUE;
    
                    AppConfig.MyMask.Val = 0x00000000;
    
                    // Generate a random IP address (based on the MAC address) to try and claim.
                    // Dynamic link-local addresses can fall within the range:
                    // 169.254.1.0 - 169.254.254.255
                    AutoIPClient.packet.TargetIPAddr.byte.MB = AutoIPRand(i) % 256;
                    AutoIPClient.packet.TargetIPAddr.byte.UB = (AutoIPRand(i) % 254) + 1;
                    AutoIPClient.packet.TargetIPAddr.word.LW = 0xFEA9;
    
                    ARPResolve (&AutoIPClient.packet.TargetIPAddr);
    
                    AutoIPClient.eventTime = TickGet();
                }
                
                if (!ARPIsResolved (&AutoIPClient.packet.TargetIPAddr, &AutoIPClient.packet.TargetMACAddr))
                {
                    if (TickGet() - AutoIPClient.eventTime > TICK_SECOND)
                    {
                        AutoIPClient.smAUTOIPState = SM_AUTOIP_SETUP_MESSAGE;
                    }
                }
                else
                {
                    AutoIPClient.flags.bits.checkAddress = FALSE;
                }
    
                break;
    
            // Set up an ARP packet
            case SM_AUTOIP_SETUP_MESSAGE:
    
                AutoIPClient.flags.bits.checkAddress = FALSE;
    
                // Set the bConfigureAutoIP flag- This flag will cause an AutoIP conflict
                // if a response packet is received from the address we're trying to claim.
                AutoIPClient.flags.bits.bConfigureAutoIP = TRUE;
    
                // Configure the fields for a gratuitous ARP packet
            	AutoIPClient.packet.Operation            = ARP_OPERATION_REQ;
            
            	AutoIPClient.packet.TargetMACAddr.v[0]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[1]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[2]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[3]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[4]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[5]   = 0xff;
    
                AppConfig.MyIPAddr = AutoIPClient.packet.TargetIPAddr;
                AppConfig.MyMask.Val = 0x0000FFFF;
            	memcpy(&AutoIPClient.packet.SenderMACAddr, (void*)&AppConfig.MyMACAddr, sizeof(AutoIPClient.packet.SenderMACAddr));
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
                AutoIPClient.packet.MACAddrLen    = sizeof(MAC_ADDR);
                AutoIPClient.packet.ProtocolLen   = sizeof(IP_ADDR);
                AutoIPClient.packet.SenderIPAddr.Val  = AutoIPClient.packet.TargetIPAddr.Val;
    
                SwapARPPacket(&AutoIPClient.packet);
    
                // Generate a random delay between 0 and 1 second
                AutoIPClient.randomDelay = ((rand() % 20) * TICK_SECOND) / 20;
                // Store the current time
                AutoIPClient.eventTime = TickGet();
    
                // Set the state to send the ARP packet
                AutoIPClient.smAUTOIPState = SM_AUTOIP_GRATUITOUS_ARP1;
    
                break;
    
            // Send a gratuitous ARP packet to try and claim our address
            case SM_AUTOIP_GRATUITOUS_ARP1:
            case SM_AUTOIP_GRATUITOUS_ARP2:
            case SM_AUTOIP_GRATUITOUS_ARP3:
                // Check to ensure we've passed the delay time
                if (TickGet() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                {
                    // Store the new event time
                    AutoIPClient.eventTime = TickGet();
                    // Generate a new random delay between 1 and 2 seconds
                    AutoIPClient.randomDelay = TICK_SECOND + (((rand() % 20) * TICK_SECOND) / 20);
    
                    // Transmit the packet
                	while(!MACIsTxReady());
                	MACSetWritePtr(BASE_TX_ADDR);
    
                    MACPutHeader(&AutoIPClient.packet.TargetMACAddr, MAC_ARP, sizeof(AutoIPClient.packet));
                    MACPutArray((BYTE*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                    MACFlush();
    
                    // Increment the probe iteration or increment to the delay state
                    AutoIPClient.smAUTOIPState++;
                }
                break;
    
            // Delay for 1-2 seconds after sending the third ARP request before
            // entering the configured state
            case SM_AUTOIP_DELAY:
                if (TickGet() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
    
            // Configure the module to limit the rate at which packets are sent
            case SM_AUTOIP_RATE_LIMIT_SET:
                AutoIPClient.eventTime = TickGet();
                AppConfig.MyIPAddr.v[0] = MY_DEFAULT_IP_ADDR_BYTE1;
                AppConfig.MyIPAddr.v[1] = MY_DEFAULT_IP_ADDR_BYTE2;
                AppConfig.MyIPAddr.v[2] = MY_DEFAULT_IP_ADDR_BYTE3;
                AppConfig.MyIPAddr.v[3] = MY_DEFAULT_IP_ADDR_BYTE4;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_RATE_LIMIT_WAIT;
                break;
    
            // Ensure that we don't try more than one address every 60 seconds
            case SM_AUTOIP_RATE_LIMIT_WAIT:
                if (TickGet() - AutoIPClient.eventTime > TICK_SECOND * 60)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
                break;
    
            // Configured state
            case SM_AUTOIP_CONFIGURED:
                AutoIPClient.flags.bits.bConfigureAutoIP = FALSE;
                break;
    
            // Address defense state
            case SM_AUTOIP_DEFEND:
                // Prepare and send an ARP response
                AutoIPClient.packet.Operation     = ARP_OPERATION_RESP;
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
    
                SwapARPPacket(&AutoIPClient.packet);
    
            	while(!MACIsTxReady());
            	MACSetWritePtr(BASE_TX_ADDR);
    
                MACPutHeader(&AutoIPClient.packet.TargetMACAddr, MAC_ARP, sizeof(AutoIPClient.packet));
                MACPutArray((BYTE*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                MACFlush();
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
        }
    }
}
Exemplo n.º 8
0
void lftp_task( void )
{	
	WORD ttt;
	BYTE c;
	BOOL bPreLine;
	BOOL bPostLine;
	
	// Nothing to do if we don't have a link
	if ( !MACIsLinked() ) return;
	
	// check if state machine is stuck somewhere and reset the it after a while if needed :
    if ( ( ftp_state != LFTP_STATE_NONE ) && 
	    	( TickGetDiff( TickGet(), lastActivity) > ( LFTP_TIMEOUT * TICK_SECOND ) ) ) {
		
		// Close ftp client socker if open
		//if ( TCPIsConnected( ftpsocket ) ) {
        	writeRomString2Socket( quit );
        	TCPDisconnect( ftpsocket );
        	ftpsocket = UNKNOWN_SOCKET;
        //}
        
        // Close data socket if open
        TCPDisconnect( datasocket );
        datasocket = UNKNOWN_SOCKET;
		
		// Check if we should try again or if its time
		// to pack it in
        cntBeforeFail++;
        if ( cntBeforeFail > LFTP_MAX_RETRIES ) {
	    	
	    	cntBeforeFail = 0;
	    	ftp_state = LFTP_STATE_NONE;		// Give up...
	    	bftpLoadWork = FALSE;	// Work is done - failed
	    	
	    }
 
        ftp_state = LFTP_STATE_NONE;
    }
		
		
		
	switch( ftp_state ) {
	
		// **
		// Start to work if its time to do so
		
		case LFTP_STATE_NONE:
		
			// Check timer and see if we should fetch
			// data from the server.
			lastActivity = TickGet();
			
			if ( bftpLoadWork ) {
				ftp_state = LFTP_STATE_ARP;	// Must get MAC address for server
				cntBeforeFail = 0;			// Init. failure counter
				DBG_OUT('A');
			}
			break;
			
			
		//**
		// Resolve the MAC address of the ftp server
			
		case LFTP_STATE_ARP:
			
			ftp_nodeinfo.IPAddr.v[ 0 ] = LFTP_SERVER_IP_v0;
			ftp_nodeinfo.IPAddr.v[ 1 ] = LFTP_SERVER_IP_v1;
			ftp_nodeinfo.IPAddr.v[ 2 ] = LFTP_SERVER_IP_v2;
			ftp_nodeinfo.IPAddr.v[ 3 ] = LFTP_SERVER_IP_v3;
			
			if ( ARPIsTxReady() ) {	
				DBG_OUT('B');
				ARPResolve( &ftp_nodeinfo.IPAddr );	// resolve IP adress
				ftp_state = LFTP_STATE_ARP_RESOLVE;
				lastActivity = TickGet();
			}
			break;	
		
			
		// **
		// Check if the ftp MAC address is resolved
			
		case LFTP_STATE_ARP_RESOLVE:	
			if ( ARPIsResolved( &ftp_nodeinfo.IPAddr, &ftp_nodeinfo.MACAddr ) ) {
				DBG_OUT('D');
				ftp_state = LFTP_STATE_CONNECT;
				lastActivity = TickGet();	
			}
			break;			
			
			
			
		// **
		// Connect to ftp server
			
		case LFTP_STATE_CONNECT:				
			
			// Try to connect				
			ftpsocket = TCPConnect( &ftp_nodeinfo, LFTP_PORT );
			if ( INVALID_SOCKET != ftpsocket ) {
				DBG_OUT('E');
				ftp_state = LFTP_STATE_CONNECT_WAIT;
				lastActivity = TickGet();
			}
			break;
		
			
		// **
		// Waiting for ftp connection
		
		case LFTP_STATE_CONNECT_WAIT:
		
			if ( TCPIsConnected( ftpsocket ) ) {
				DBG_OUT('F');
				ftp_state = LFTP_STATE_USER;
				lastActivity = TickGet();	
			}
			break;
				
							
							
		// Here we wait for server connection and send
		// USER command if OK	
		case LFTP_STATE_USER:

			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
					
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "2xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( '2' == c ) {
					DBG_OUT('G');
					writeRomString2Socket( user );
					ftp_state = LFTP_STATE_PASS;
					lastActivity = TickGet();
				}
					
				TCPDiscard( ftpsocket );
				 	
			}
			break;	
			
			
			
			// **
			// Here we wait for response from USER command
			// and send PASS command if OK
			
			case LFTP_STATE_PASS:
				
			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
				
				DBG_OUT('$');
					
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					DBG_OUT(c);
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "3xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( ('3' == c ) || ('2' == c ) ) {
					DBG_OUT('H');
					writeRomString2Socket( pass );
					ftp_state = LFTP_STATE_PASV;	
					lastActivity = TickGet();
				}
					
				TCPDiscard( ftpsocket );
						
			}
			break;
			
			
			
			// **
			// Here we wait for response of PASS command
			// and send PASV command if positive and also
			// creates the data socket
			
			case LFTP_STATE_PASV:
		 
			// Fetch data if we are connected
			if ( TCPIsGetReady( ftpsocket ) ) {
				
				DBG_OUT('!');					
				
				// get first digit
				while( TCPGet( ftpsocket, &c ) ) {
					DBG_OUT(c);
					if ( isdigit( c ) ) break;
				}
					
				// If connected with positive response "2xx - xxxxxxxx..."
				// we send username. If not we just timeout
				if ( '2' == c ) {
					DBG_OUT('I');	
						
					writeRomString2Socket( pasv );
					ftp_state = LFTP_STATE_RETR;
					lastActivity = TickGet();
							
				}
					
				TCPDiscard( ftpsocket );	
				 	
			}
			break;
			
			
			// **
			// Here we wait for the result of PASV command
			// and parse its data
			// if OK we send RETR and go on to the next state
			
			case LFTP_STATE_RETR:
	 				
				// Fetch data if we are connected
				if ( TCPIsGetReady( ftpsocket ) ) {
					
					TCPGet( ftpsocket, &c );
					
					if ( '2' == c ) {
						
						DBG_OUT('J');
						
						// Get pasv parameters
						getPasvParams();
						
						// retrive file
						writeRomString2Socket( retr );
						
						ttt = portdata;
						while ( ttt ) {
							DBG_OUT('0' + (ttt % 10) );
							ttt = ttt / 10;
						} 
						
						ftp_state = LFTP_STATE_DATA_CONNECT;		
					}
					
					TCPDiscard( ftpsocket );					
				}
			break;
		
		
			// **
			// Connect to the data socket
		
			case LFTP_STATE_DATA_CONNECT:
			
				// Try to connect				
				datasocket = TCPConnect( &ftp_nodeinfo, portdata );
				if ( INVALID_SOCKET != datasocket ) {
					DBG_OUT('K');
					ftp_state = LFTP_STATE_WAIT_DATA_CONNECT; 
					lastActivity = TickGet();
				}
			break;
			
			
			// **
			// Wait for the data connection to establish
			
			case LFTP_STATE_WAIT_DATA_CONNECT:
			
				if ( TCPIsConnected( datasocket ) ) {
					DBG_OUT('L');
					//writeRomString2Socket( lftpDataSocket, crlf );
					ftp_state = LFTP_STATE_FETCH_DATA;
					lastActivity = TickGet();
				}
				
				// Check for reply on ftp socket FIX!!!!
				if ( TCPIsGetReady( ftpsocket ) ) {	
					DBG_OUT('?');
					while( TCPGet( ftpsocket, &c ) ) {
						DBG_OUT( c );
					}
					TCPDiscard( ftpsocket );
				}
			break;
		
			
			
			// **
			// Fetch the data and send it out on the
			// serial i/f
			
			case LFTP_STATE_FETCH_DATA:
 
				// Fetch data if we are connected
				if ( TCPIsGetReady( datasocket ) ) {	
					DBG_OUT('M');
					
					// Framework start
					serPutByte( 0x00  );
					serPutByte( 0xff  );
					serPutByte( 0xff  );
					serPutByte( 0x01  );
					serPutByte( 0x01  );
					serPutByte( 0x01  );
					
					bPreLine = FALSE;
					bPostLine = FALSE;
					
					// get data
					while( TCPGet( datasocket, &c ) ) {
						
						if ( 0x0d == c ) {
							// We skip CR
						}
						else if ( 0x0a == c ) {
							// Send end line stuff
							serPutByte( 0xff );
							bPreLine = FALSE;
							bPostLine = TRUE;
						}
						else {
							bPostLine = FALSE;	// no end line codes sent
							if ( !bPreLine ) {
								// Send preline stuff
								bPreLine = TRUE;
								serPutByte( 0x01 );
								serPutByte( 0x03 );
								serPutByte( 0xef );
								serPutByte( 0xb0 );
							}
							serPutByte( c );
						}
					}
					
					// If we end with a row without LF we must send
					// Line end stuff
					if ( !bPostLine ) {
						serPutByte( 0xff );
					}
					
					// Framework end
					serPutByte( 0xff  );
					serPutByte( 0x00  );
					
					ftp_state = LFTP_STATE_END;
					TCPDiscard( datasocket );	
				}
				
				
				// Check for data on ftp socket
				if ( TCPIsGetReady( ftpsocket ) ) {	
					
					while( TCPGet( ftpsocket, &c ) ) {
						DBG_OUT( c );
					}
					TCPDiscard( ftpsocket );
				}
				
			break;
				
				
				
			// **
			// We are done for this time
				
			case LFTP_STATE_END:
				DBG_OUT('*');
				TCPDisconnect( ftpsocket );
				TCPDisconnect( datasocket );
				bftpLoadWork = FALSE;	// Work is done
				ftp_state = LFTP_STATE_NONE;
			break;
	}	
}
Exemplo n.º 9
0
Arquivo: ICMP.c Projeto: CEIT-UQ/RGB
/*********************************************************************
 * Function:        LONG ICMPGetReply(void)
 *
 * PreCondition:    ICMPBeginUsage() returned TRUE and ICMPSendPing() 
 *					was called
 *
 * Input:           None
 *
 * Output:          -3: Could not resolve hostname (DNS timeout or 
 *			    	    hostname invalid)
 *					-2: No response received yet
 *					-1: Operation timed out (longer than ICMP_TIMEOUT) 
 *						has elapsed.
 *					>=0: Number of TICKs that elapsed between 
 *						 initial ICMP transmission and reception of 
 *						 a valid echo.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
LONG ICMPGetReply(void)
{
	ICMP_PACKET ICMPPacket;

	switch(ICMPState)
	{
#if defined(STACK_USE_DNS)
		case SM_DNS_SEND_QUERY:
			// Obtain DNS module ownership
			if(!DNSBeginUsage())
				break;
			
			// Send DNS query
			if(ICMPFlags.bRemoteHostIsROM)
				DNSResolveROM(StaticVars.RemoteHost.szROM, DNS_TYPE_A);
			else
				DNSResolve(StaticVars.RemoteHost.szRAM, DNS_TYPE_A);
			
			ICMPState = SM_DNS_GET_RESPONSE;
			break;
				
		case SM_DNS_GET_RESPONSE:
			// See if DNS is done, and if so, get the remote IP address
			if(!DNSIsResolved(&StaticVars.ICMPRemote.IPAddr))
				break;
			
			// Free the DNS module
			DNSEndUsage();
			
			// Return error code if the DNS query failed
			if(StaticVars.ICMPRemote.IPAddr.Val == 0x00000000ul)
			{
				ICMPState = SM_IDLE;
				return -3;
			}

			ICMPState = SM_ARP_SEND_QUERY;	
			// No break;	
#endif

		case SM_ARP_SEND_QUERY:
			ARPResolve(&StaticVars.ICMPRemote.IPAddr);
			ICMPState = SM_ARP_GET_RESPONSE;
			break;
			
		case SM_ARP_GET_RESPONSE:
			// See if the ARP reponse was successfully received
			if(!ARPIsResolved(&StaticVars.ICMPRemote.IPAddr, &StaticVars.ICMPRemote.MACAddr))
				break;
			
			ICMPState = SM_ICMP_SEND_ECHO_REQUEST;
			// No break; 
		
		case SM_ICMP_SEND_ECHO_REQUEST:
		    if(!IPIsTxReady())
		    	break;

			// Set up the ping packet
			ICMPPacket.vType = 0x08;	// 0x08: Echo (ping) request
			ICMPPacket.vCode = 0x00;
			ICMPPacket.wChecksum = 0x0000;
			ICMPPacket.wIdentifier = 0xEFBE;
			wICMPSequenceNumber++; 
			ICMPPacket.wSequenceNumber = wICMPSequenceNumber;
			ICMPPacket.wData = 0x2860;
			ICMPPacket.wChecksum = CalcIPChecksum((BYTE*)&ICMPPacket, sizeof(ICMPPacket));
		
			// Record the current time.  This will be used as a basis for 
			// finding the echo response time, which exludes the ARP and DNS 
			// steps
			ICMPTimer = TickGet();

			// Position the write pointer for the next IPPutHeader operation
		    MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));
		
			// Create IP header in TX memory
			IPPutHeader(&StaticVars.ICMPRemote, IP_PROT_ICMP, sizeof(ICMPPacket));
			MACPutArray((BYTE*)&ICMPPacket, sizeof(ICMPPacket));
			MACFlush();

			// Echo sent, advance state
			ICMPState = SM_ICMP_GET_ECHO_RESPONSE;
			break;

		case SM_ICMP_GET_ECHO_RESPONSE:
			// See if the echo was successfully received
			if(ICMPFlags.bReplyValid)
				return (LONG)ICMPTimer;
		
			break;
		
		// SM_IDLE or illegal/impossible state:
		default:
			return -1;
	}

	// See if the DNS/ARP/echo request timed out
	if(TickGet() - ICMPTimer > ICMP_TIMEOUT)
	{
		// Free DNS module if we have it in use
		#if defined(STACK_USE_DNS)
			if(ICMPState == SM_DNS_GET_RESPONSE)
				DNSEndUsage();
		#endif
		
		// Stop ICMP echo test and return error to caller
		ICMPState = SM_IDLE;
		return -1;
	}

	// Still working.  No response to report yet.
	return -2;
}
Exemplo n.º 10
0
/******************************************************************************
Function:
	void UDPTask(void)

  Summary:
  	Performs periodic UDP tasks.

  Description:
	This function performs any required periodic UDP tasks.  Each socket's state machine is 
	checked, and any elapsed timeout periods are handled.

  Precondition:
	UDP is initialized.

  Parameters:
	None

  Returns:
	None

******************************************************************************/
void UDPTask(void)
{
	UDP_SOCKET ss;
	
	for ( ss = 0; ss < MAX_UDP_SOCKETS; ss++ )
	{

		// need to put Extra check if UDP has opened or NOT

		if((UDPSocketInfo[ss].smState == UDP_OPENED) ||
			(UDPSocketInfo[ss].smState == UDP_CLOSED))
			continue;
		// A timeout has occured.  Respond to this timeout condition
		// depending on what state this socket is in.
		switch(UDPSocketInfo[ss].smState)
		{
			#if defined(STACK_CLIENT_MODE)
			#if defined(STACK_USE_DNS)
			case UDP_DNS_RESOLVE:
			if(DNSBeginUsage())
			{
				// call DNS Resolve function and move to UDP next State machine
				UDPSocketInfo[ss].smState = UDP_DNS_IS_RESOLVED;
				if(UDPSocketInfo[ss].flags.bRemoteHostIsROM)
					DNSResolveROM((ROM BYTE*)(ROM_PTR_BASE)UDPSocketInfo[ss].remote.remoteHost, DNS_TYPE_A);
				else
					DNSResolve((BYTE*)(PTR_BASE)UDPSocketInfo[ss].remote.remoteHost, DNS_TYPE_A);
			}
			break;				
			case UDP_DNS_IS_RESOLVED:
			{
				IP_ADDR ipResolvedDNSIP;
				// See if DNS resolution has finished.	Note that if the DNS 
				// fails, the &ipResolvedDNSIP will be written with 0x00000000. 
				// MyTCB.remote.dwRemoteHost is unioned with 
				// MyTCB.remote.niRemoteMACIP.IPAddr, so we can't directly write 
				// the DNS result into MyTCB.remote.niRemoteMACIP.IPAddr.  We 
				// must copy it over only if the DNS is resolution step was 
				// successful.
				
				if(DNSIsResolved(&ipResolvedDNSIP))
				{
					if(DNSEndUsage())
					{
						UDPSocketInfo[ss].remote.remoteNode.IPAddr.Val = ipResolvedDNSIP.Val;
						UDPSocketInfo[ss].smState = UDP_GATEWAY_SEND_ARP;
						UDPSocketInfo[ss].retryCount = 0;
						UDPSocketInfo[ss].retryInterval = (TICK_SECOND/4)/256;
					}
					else
					{
						UDPSocketInfo[ss].smState = UDP_DNS_RESOLVE;
					}
				}			
			}
			break;
			#endif // #if defined(STACK_USE_DNS)

			case UDP_GATEWAY_SEND_ARP:
				// Obtain the MAC address associated with the server's IP address 
				//(either direct MAC address on same subnet, or the MAC address of the Gateway machine)
				UDPSocketInfo[ss].eventTime = (WORD)TickGetDiv256();
				ARPResolve(&UDPSocketInfo[ss].remote.remoteNode.IPAddr);
				UDPSocketInfo[ss].smState = UDP_GATEWAY_GET_ARP;
				break;

			case UDP_GATEWAY_GET_ARP:
			if(!ARPIsResolved(&UDPSocketInfo[ss].remote.remoteNode.IPAddr, 
								&UDPSocketInfo[ss].remote.remoteNode.MACAddr))
			{
				// Time out if too much time is spent in this state
				// Note that this will continuously send out ARP 
				// requests for an infinite time if the Gateway 
				// never responds
				if((WORD)TickGetDiv256() - UDPSocketInfo[ss].eventTime> (WORD)UDPSocketInfo[ss].retryInterval)
				{
					// Exponentially increase timeout until we reach 6 attempts then stay constant
					if(UDPSocketInfo[ss].retryCount < 6u)
					{
						UDPSocketInfo[ss].retryCount++;
						UDPSocketInfo[ss].retryInterval <<= 1;
					}
					// Retransmit ARP request
					UDPSocketInfo[ss].smState = UDP_GATEWAY_SEND_ARP;
				}				
			}
			else
			{
				UDPSocketInfo[ss].smState = UDP_OPENED;
			}
			break;
			default:
			case UDP_OPENED:
			case UDP_CLOSED:
			// not used
			break;
#endif // #if defined(STACK_CLIENT_MODE)
		}
	}
} 
Exemplo n.º 11
0
/*********************************************************************
 * Function:        void GenericTCPClient(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void GenericTCPClient(void)
{
	BYTE 				i;
	BYTE 				*StringPtr;
	static TICK			Timer;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static NODE_INFO	Server;
	static enum _GenericTCPExampleState
	{
		SM_HOME = 0,
		SM_NAME_RESOLVE,
		SM_ARP_START_RESOLVE,
		SM_ARP_RESOLVE,
		SM_SOCKET_OBTAIN,
		SM_SOCKET_OBTAINED,
		SM_PROCESS_RESPONSE,
		SM_DISCONNECT,
		SM_DONE
	} GenericTCPExampleState = SM_DONE;

	switch(GenericTCPExampleState)
	{
		case SM_HOME:
			// Obtain ownership of the DNS resolution module
			if(!DNSBeginUsage())
				break;

			// Obtain the IP address associated with the common ServerName
			DNSResolve(ServerName, DNS_TYPE_A);
			GenericTCPExampleState++;
			break;

		case SM_NAME_RESOLVE:
			// Wait for the DNS server to return the requested IP address
			if(!DNSIsResolved(&Server.IPAddr))
				break;

			// Release the DNS module, we no longer need it
			if(!DNSEndUsage())
			{
				// An invalid IP address was returned from the DNS 
				// server.  Quit and fail permanantly if host is not valid.
				GenericTCPExampleState = SM_DONE;
				break;
			}

			GenericTCPExampleState++;

		case SM_ARP_START_RESOLVE:
			// Obtain the MAC address associated with the server's IP address (either direct MAC address on same subnet, or the MAC address of the Gateway machine)
			ARPResolve(&Server.IPAddr);
			Timer = TickGet();
			GenericTCPExampleState++;
			break;

		case SM_ARP_RESOLVE:
			// Wait for the MAC address to finish being obtained
			if(!ARPIsResolved(&Server.IPAddr, &Server.MACAddr))
			{
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 1*TICK_SECOND)
				{
					// Retransmit ARP request
					GenericTCPExampleState--;
				}
				break;
			}
			GenericTCPExampleState++;

		case SM_SOCKET_OBTAIN:
			// Connect a socket to the remote TCP server
			MySocket = TCPConnect(&Server, ServerPort);
			
			// Abort operation if no TCP sockets are available
			// If this ever happens, incrementing MAX_TCP_SOCKETS in 
			// StackTsk.h may help (at the expense of more global memory 
			// resources).
			if(MySocket == INVALID_SOCKET)
				break;

			GenericTCPExampleState++;
			Timer = TickGet();
			break;

		case SM_SOCKET_OBTAINED:
			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 5*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					GenericTCPExampleState--;
				}
				break;
			}

			Timer = TickGet();

			// Make certain the socket can be written to
			if(!TCPIsPutReady(MySocket))
				break;
			
			// Place the application protocol data into the transmit buffer.  For this example, we are connected to an HTTP server, so we'll send an HTTP GET request.
			TCPPutROMString(MySocket, (ROM BYTE*)"GET ");
			TCPPutROMString(MySocket, RemoteURL);
			TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.1\r\nHost: ");
			TCPPutString(MySocket, ServerName);
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\n\r\n");

			// Send the packet
			TCPFlush(MySocket);
			GenericTCPExampleState++;

		case SM_PROCESS_RESPONSE:
			// Check to see if the remote node has disconnected from us or sent us any application data
			// If application data is available, write it to the UART
			if(!TCPIsConnected(MySocket))
			{
				GenericTCPExampleState++;
			}
	
			if(!TCPIsGetReady(MySocket))
				break;
	
			// Obtain the server reply
			while(TCPGet(MySocket, &i))
			{
				while(BusyUART());
				WriteUART(i);
			}
	
			break;
	
		case SM_DISCONNECT:
			// Close the socket so it can be used by other modules
			// For this application, we wish to stay connected, but this state will still get entered if the remote server decides to disconnect
			TCPDisconnect(MySocket);
			MySocket = INVALID_SOCKET;
			GenericTCPExampleState = SM_DONE;
			break;
	
		case SM_DONE:
			// Do nothing unless the user pushes BUTTON1 and wants to restart the whole connection/download process
			if(BUTTON1_IO == 0u)
				GenericTCPExampleState = SM_HOME;
			break;
	}
}
Exemplo n.º 12
0
/*****************************************************************************
  Function:
	void PingDemoTask (void)

  Summary:
	Handles state machine for ping demo processes.
	
  Description:
	This function performs state processing for the ping demo.
	
	This function can be used as a model for applications requiring Ping6 
	capabilities to check if a host is reachable.

  Precondition:
	None.

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void PingDemoTask (void)
{
    switch (pingState)
    {
#if defined (TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_DNS_SEND_QUERY_IPV4:
            if (!DNSBeginUsage(pNetIf))
                return;

            if (DNSResolve((const char *)targetHostName, DNS_TYPE_A) != DNS_RES_OK)
                return;

            pingTimer = SYS_TICK_Get() + (SYS_TICK_ResolutionGet() * TCPIP_PING_DNS_TIMEOUT);
            pingState = STATE_DNS_GET_RESPONSE_IPV4;
            break;
        case STATE_DNS_GET_RESPONSE_IPV4:
            {
                DNS_RESULT res;
                if ((long)(SYS_TICK_Get() - pingTimer) > 0)
                {
                    SYS_OUT_MESSAGE_LINE("Couldn't resolve", 2);
                    DNSEndUsage(pNetIf);
                    pingState = STATE_IDLE;
                    return;
                } 
    
                res = DNSIsResolved((const char *)targetHostName, &targetAddressIPv4);

                switch (res)
                {
                    case DNS_RES_OK:
                        DNSEndUsage(pNetIf);
                        pingState = STATE_RESOLVE_ARP;
                        break;
                    case DNS_RES_PENDING:
                        
                        break;
                    default:
                        SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                        DNSEndUsage(pNetIf);
                        pingState = STATE_IDLE;
                        break;
                }
            }
            break;
		case STATE_RESOLVE_ARP:
            if ((targetAddressIPv4.Val & pNetIf->MyMask.Val) == pNetIf->MyMask.Val)
                firstHopAddress.Val = targetAddressIPv4.Val;
            else
                firstHopAddress.Val = pNetIf->MyGateway.Val;
  			ARPResolve(pNetIf, &firstHopAddress);
			pingTimer = SYS_TICK_Get();
			pingState = STATE_ARP_RESOLVED;
			break;

		case STATE_ARP_RESOLVED:
			if(!ARPIsResolved(pNetIf, &firstHopAddress, &targetMACAddr))
			{
				if(SYS_TICK_Get() - pingTimer > (TCPIP_PING_DNS_TIMEOUT * SYS_TICK_TicksPerSecondGet()))
                {
                    SYS_OUT_MESSAGE_LINE ("Couldn't ARP", 1);
					pingState = STATE_IDLE;
                }
				break;
			}

			pingState = STATE_SEND_ECHO_REQUEST_IPV4;
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_DNS_SEND_QUERY_IPV6:
            if (!DNSBeginUsage(pNetIf))
                return;

            if (DNSResolve((const char *)targetHostName, DNS_TYPE_AAAA) != DNS_RES_OK)
                return;

            pingTimer = SYS_TICK_Get() + (SYS_TICK_ResolutionGet() * TCPIP_PING_DNS_TIMEOUT);
            pingState = STATE_DNS_GET_RESPONSE_IPV6;
            break;
        case STATE_DNS_GET_RESPONSE_IPV6:
            {
                DNS_RESULT res;
                if ((long)(SYS_TICK_Get() - pingTimer) > 0)
                {
                    SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                    DNSEndUsage(pNetIf);
                    pingState = STATE_IDLE;
                    return;
                } 
    
                res = DNSIsResolved((const char *)targetHostName, &targetAddressIPv6);

                switch (res)
                {
                    case DNS_RES_OK:
                        DNSEndUsage(pNetIf);
                        pingState = STATE_SEND_ECHO_REQUEST_IPV6;
                        break;
                    case DNS_RES_PENDING:
                        
                        break;
                    default:
                        SYS_OUT_MESSAGE_LINE ("Couldn't resolve", 1);
                        DNSEndUsage(pNetIf);
                        pingState = STATE_IDLE;
                        break;
                }
            }
            break;
#endif
#if defined(TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_SEND_ECHO_REQUEST_IPV4:
            {
                NODE_INFO info;

                info.IPAddr = targetAddressIPv4;
                memcpy (&info.MACAddr, &targetMACAddr, sizeof (MAC_ADDR));
                ICMPSendEchoRequest (&info, ++wICMPSequenceNumber, 0xBEEF);

    			// Record the current time.  This will be used as a basis for 
    			// finding the echo response time, which exludes the ARP and DNS 
    			// steps
   			    pingTimer = SYS_TICK_Get();
    
                pingCount++;

                SYS_OUT_MESSAGE_LINE ("Pinging...", 1);

    			// Echo sent, advance state
    			pingState = STATE_GET_RESPONSE_IPV4;
            }
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_SEND_ECHO_REQUEST_IPV6:
            {
                IP_PACKET * pkt;
                IPV6_ADDR_STRUCT * localAddress;

                localAddress = TCPIP_IPV6_DAS_SelectSourceAddress (pNetIf, &targetAddressIPv6, NULL);

                if (localAddress == NULL)
                {
                    SYS_OUT_MESSAGE_LINE ("No local addr!", 1);
                    pingState = STATE_IDLE;
                    break;
                }
    
                pkt = TCPIP_ICMPV6_PutHeaderEchoRequest (pNetIf, &localAddress->address, &targetAddressIPv6, ICMPV6_INFO_ECHO_REQUEST, 
                                                    0xEFBE, ++wICMPSequenceNumber);
    
                if (TCPIP_IP_IsTxPutReady(pkt, 4) < 4)
                {
                    TCPIP_IP_FreePacket (pkt);
                    return;
                }
    
                TCPIP_IP_PutArray (pkt, (uint8_t *)&miscData, sizeof (uint32_t));
    
                // Just let the IPv6 module figure out the next hop neighbor and its MAC address
                TCPIP_ICMPV6_Flush (pkt);
    		
    			// Record the current time.  This will be used as a basis for 
    			// finding the echo response time, which exludes the ARP and DNS 
    			// steps
   			    pingTimer = SYS_TICK_Get();
    
                pingCount++;

                SYS_OUT_MESSAGE_LINE ("Pinging...", 1);

    			// Echo sent, advance state
    			pingState = STATE_GET_RESPONSE_IPV6;
            }
            break;
#endif
#if defined (TCPIP_STACK_USE_ICMP_CLIENT)
        case STATE_GET_RESPONSE_IPV4:
            if ((long)(SYS_TICK_Get() - pingTimer) > (SYS_TICK_ResolutionGet() * TCPIP_PING_TIMEOUT))
            {
                SYS_OUT_MESSAGE_LINE("Ping timeout", 1);
                pingState = STATE_IDLE;
            }            
            break;
#endif
#if defined (TCPIP_STACK_USE_IPV6)
        case STATE_GET_RESPONSE_IPV6:
            if ((long)(SYS_TICK_Get() - pingTimer) > (SYS_TICK_ResolutionGet() * TCPIP_PING_TIMEOUT))
            {
                SYS_OUT_MESSAGE_LINE ("Ping timeout", 1);
                pingState = STATE_IDLE;
            }
            break;
#endif
        default:
        case STATE_IDLE:
            break;
        
    }
}
Exemplo n.º 13
0
/*****************************************************************************
  Function:
	int recv( SOCKET s, char* buf, int len, int flags )

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

  Description:
	The recv() function is used to receive incoming data that has
    been queued for a socket. This function can be used with both 
    datagram and stream socket. If the available data is too large
    to fit in the supplied application buffer buf, the data is
    buffered internally so the application can retreive all data
    by multiple calls of recv.

  Precondition:
	connect function should be called for TCP and UDP sockets.
	Server side, accept 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 - no significance in this implementation

  Returns:
	If recv 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. A return value of SOCKET_DISCONNECTED
    indicates the connection no longer exists.

  Remarks:
	None.
  ***************************************************************************/
int recv( SOCKET s, char* buf, int len, int flags )
{
    struct BSDSocket *socket;
    NODE_INFO remoteInfo;
    static DWORD startTick;
    
    if( s >= BSD_SOCKET_COUNT )
        return SOCKET_ERROR;

    socket = &BSDSocketArray[s];

    if( socket->bsdState < SKT_BOUND )
            return SOCKET_ERROR;
   
    if(socket->SocketType == SOCK_STREAM) //TCP
    {
        if(!TCPIsConnected(socket->SocketID))
        {
            return SOCKET_DISCONNECTED;
        }
        
        if(TCPIsGetReady(socket->SocketID))
        {
            return TCPGetArray(socket->SocketID, (BYTE*)buf, len);
        }
    }
    else if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if((socket->bsdState >= SKT_READY) && (socket->bsdState != SKT_EST))//making sure that connect function is called
        {
            if(socket->bsdState != SKT_ARP_VERIFY)
            {
                remoteInfo.IPAddr.Val = socket->remoteIP;
                ARPResolve(&remoteInfo.IPAddr);
                startTick = TickGet();
                socket->bsdState = SKT_ARP_VERIFY;
            }
            else if(socket->bsdState == SKT_ARP_VERIFY)
            {
                // Wait for the MAC address to finish being obtained
                remoteInfo.IPAddr.Val = socket->remoteIP;
                if(!ARPIsResolved(&remoteInfo.IPAddr, &remoteInfo.MACAddr))
                {
                    // Time out if too much time is spent in this state
    			    if(TickGet()- startTick > 1*TICK_SECOND)
    			    {
                        // Retransmit ARP request
                        socket->bsdState = SKT_ARP_RESOLVE;
    			    }
                 }
                 socket->SocketID = UDPOpen(socket->localPort, &remoteInfo, socket->remotePort);
                 socket->bsdState = SKT_EST;
            }
        }
        
        if(socket->bsdState == SKT_EST)
        {
            if(UDPIsGetReady(socket->SocketID) > 0)
            {
                return UDPGetArray((BYTE*)buf, len);
            }
        }
    }
    
    return 0;
}
Exemplo n.º 14
0
/*****************************************************************************
  Function:
	int sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen)

  Summary:
	This function used to send the data for both connection oriented and connection-less
	sockets.

  Description:
	The sendto function is used to send outgoing data on a socket.
    The destination address is given by to and tolen. Both 
    Datagram and stream sockets are supported.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
    buf - application data buffer containing data to transmit.
    len - length of data in bytes.
    flags - message flags. Currently this field is not supported.
    to - pointer to the the sockaddr structure containing the
    destination address.
    tolen - length of the sockaddr structure.
  
  Returns:
	On success, sendto returns number of bytes sent. In case of
    error returns SOCKET_ERROR

  Remarks:
	None.
  ***************************************************************************/
int sendto( SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *addr;
    int size=0;
    NODE_INFO remoteInfo;
    static DWORD startTick;

    socket = &BSDSocketArray[s];
    addr = (struct sockaddr_in *)to;
    socket->remotePort = addr->sin_port;
    socket->remoteIP = addr->sin_addr.s_addr;
    
    if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if(socket->bsdState != SKT_EST)
        {
            if((addr == NULL) || (addr->sin_addr.s_addr == IP_ADDR_ANY) || (tolen == 0)) //broadcast
            {
                socket->SocketID = UDPOpen(socket->localPort, NULL, socket->remotePort);
            }
            else
            {
                if(socket->bsdState != SKT_ARP_VERIFY)
                {
                    remoteInfo.IPAddr.Val = socket->remoteIP;
                    ARPResolve(&remoteInfo.IPAddr);
                    startTick = TickGet();
                    socket->bsdState = SKT_ARP_VERIFY;
                }
                else if(socket->bsdState == SKT_ARP_VERIFY)
                {
                    // Wait for the MAC address to finish being obtained
                    remoteInfo.IPAddr.Val = socket->remoteIP;
                    if(!ARPIsResolved(&remoteInfo.IPAddr, &remoteInfo.MACAddr))
                    {
                        // Time out if too much time is spent in this state
    			        if(TickGet()- startTick > 1*TICK_SECOND)
    			        {
                            // Retransmit ARP request
                            socket->bsdState = SKT_ARP_RESOLVE;
    			        }
                    }
                    socket->SocketID = UDPOpen(socket->localPort, &remoteInfo, socket->remotePort);
                    socket->bsdState = SKT_EST;
                }
            }
        }
        
        if(socket->bsdState == SKT_EST)
        {
            if(UDPIsPutReady(socket->SocketID) > 0)
            {
                size = UDPPutArray((BYTE*)buf, len);
                UDPFlush();
                return size;
            }
        }
    }
    else if(socket->SocketType == SOCK_STREAM) //TCP will send to the already established socket.
    {
        return send(s, buf, len, 0);
    }
    return SOCKET_ERROR;
}
Exemplo n.º 15
0
/*********************************************************************
 * Function:        void SMTP Client State machine(void)
 *
 * PreCondition:    FTPInit() must already be called.
 *
 * Input:           None
 *
 * Output:          Ready to send mail.
 *
 * Side Effects:    None
 *
 * Overview:
 *
 * Note:            This function acts as a task (similar to one in
 *                  RTOS).  This function performs its task in
 *                  co-operative manner.  Main application must call
 *                  this function repeatedly to ensure it can send
 *                  mails when requested. (include in the main loop)
 ********************************************************************/
void SMTPClient(void)
{
    BYTE v;
//    TICK currentTick;

    // check if state machine is stuck somewhere and reset the SM after a while if needed :
    if ((smSMTP != SM_SMTP_STDBY) && (TickGetDiff(TickGet(), lastActivity) > (15 * TICK_SECOND))) {
        if (TCPIsConnected(SMTPSocket))
           TCPDisconnect(SMTPSocket) ;
        if(cptretry--) {						// if not all retries done...
           lastActivity = TickGet();			// re-init delay
           smSMTP = SM_SMTP_STDBY ;   			// force standby state
        } else {
           fsend_mail = FALSE ;					// give up !
           smSMTP = SM_SMTP_STDBY ;   			// -> standby
        }
    }

    // work each state :
    switch(smSMTP)
    {
    case SM_SMTP_STDBY:		// standby: idle, waiting for connection request
        if (fsend_mail) {
           if (TickGetDiff(TickGet(), lastActivity) > (10 * TICK_SECOND)) {
      USARTPut(0xBB) ;

              lastActivity = TickGet();
              ARPResolve(&nodedist.IPAddr) ;	// resolve IP adress
              smSMTP = SM_SMTP_ARP ;   			// -> wait ARP answer
           }
        }
        break ;

    case SM_SMTP_ARP:		// wait ARP to be resolved
        if ( ARPIsResolved(&nodedist.IPAddr, &nodedist.MACAddr)) {
           SMTPSocket = TCPConnect(&nodedist, SMTP_PORT) ;
           if (SMTPSocket == INVALID_SOCKET) {
              fsend_mail = FALSE ;	       		// avorte
           } else {
              smSMTP = SM_SMTP_CONNECT ;   		// -> attente ACK
           }
        }
        break ;

    case SM_SMTP_CONNECT:		// standby: attente ack connexion
        if (TCPIsConnected(SMTPSocket)) {
           smSMTP = SM_SMTP_WELCOME ;   		// -> attente WELCOME

        }
        break ;

    case SM_SMTP_WELCOME:		// attente welcome du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket, &v)) {
              if (v == '2') {		// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_HELO) ;
                 smSMTP = SM_SMTP_HELO ;   		// -> attente reponse au HELO
              }else {
              smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_HELO:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {					// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_FROM) ;
                 smSMTP = SM_SMTP_FROM ;   		// -> attente reponse au FROM
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_FROM:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {		// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_TO) ;
                 smSMTP = SM_SMTP_TO ;   		// -> attente reponse au TO
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_TO:			// attente HELO du serveur
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {					// commence par un 2 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_DATA) ;
                 smSMTP = SM_SMTP_DATA1 ;  		// -> attente reponse au DATA
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_DATA1:			// when OK send message headers
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '3') {		// commence par un 3 ? (220..)
                 TCPDiscard(SMTPSocket) ;
                 ExecuteSMTPCommand(SMTP_CMD_DATA_HEADERS) ;	// send headers
//                 ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ; // message
//                 ExecuteSMTPCommand(SMTP_CMD_DATA_END) ;     // termine

                 smSMTP = SM_SMTP_DATA2;   		// -> send body
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;

    case SM_SMTP_DATA2:			// wait to send message body
        if (TCPIsPutReady(SMTPSocket)) {				// wait for TX buffer free
           ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ;	// message
           smSMTP = SM_SMTP_DATA3 ;   		// -> attente reponse au TO
        } else {
//           USARTPut(0xCC) ;		vérifié qu'il y avait bien besoin d'une attente ici

        }
        break ;

    case SM_SMTP_DATA3:			// wait to send the final "."
        if (TCPIsPutReady(SMTPSocket)) {				// wait for TX buffer free
           ExecuteSMTPCommand(SMTP_CMD_DATA_END) ; 		// termine
           smSMTP = SM_SMTP_QUIT ;						// -> end
        }  else {
//            USARTPut(0xDD) ;		vérifié qu'il y avait bien besoin d'une attente ici

        }
        break ;

    case SM_SMTP_QUIT:		// wait last message before leaving...
        if (TCPIsGetReady(SMTPSocket)) {
           if (TCPGet(SMTPSocket,&v)) {
              if (v == '2') {		// commence par un 2 ? (220..)

                 TCPDiscard(SMTPSocket) ;
                 smSMTP = SM_SMTP_DONE ;   		// -> deconnecte
              }else {
                 smSMTP = SM_SMTP_DONE ;   		// -> disconnect
              }
           }
        }
        break ;


    case SM_SMTP_DONE:			// disconnect Socket :
        if (TCPIsConnected(SMTPSocket) && (TCPIsPutReady(SMTPSocket))) { // wait for TX buff free
           TCPDisconnect(SMTPSocket) ;
        }
        fsend_mail = FALSE ;		// done !
        smSMTP = SM_SMTP_STDBY ;   // -> standby
        break ;
    }
}
Exemplo n.º 16
0
Arquivo: DNS.c Projeto: CEIT-UQ/RGB
/*****************************************************************************
  Function:
	BOOL DNSIsResolved(IP_ADDR* HostIP)

  Summary:
	Determines if the DNS resolution is complete and provides the IP.
	
  Description:
	Call this function to determine if the DNS resolution of an address has
	been completed.  If so, the resolved address will be provided in HostIP.

  Precondition:
	DNSResolve or DNSResolveROM has been called.

  Parameters:
	HostIP - A pointer to an IP_ADDR structure in which to store the 
		resolved IP address once resolution is complete.

  Return Values:
  	TRUE - The DNS client has obtained an IP, or the DNS process
  		has encountered an error.  HostIP will be 0.0.0.0 on error.  Possible 
  		errors include server timeout (i.e. DNS server not available), hostname 
  		not in the DNS, or DNS server errors.
  	FALSE - The resolution process is still in progress.
  ***************************************************************************/
BOOL DNSIsResolved(IP_ADDR* HostIP)
{
	static DWORD		StartTime;
	static WORD_VAL		SentTransactionID __attribute__((persistent));
	static BYTE			vARPAttemptCount;
	static BYTE			vDNSAttemptCount;
	BYTE 				i;
	WORD_VAL			w;
	DNS_HEADER			DNSHeader;
	DNS_ANSWER_HEADER	DNSAnswerHeader;

	switch(smDNS)
	{
		case DNS_START:
			vARPAttemptCount = 0;
			vDNSAttemptCount = 0;
			// No break;

		case DNS_ARP_START_RESOLVE:
			ARPResolve(&AppConfig.PrimaryDNSServer);
			vARPAttemptCount++;
			StartTime = TickGet();
			smDNS = DNS_ARP_RESOLVE;
			break;

		case DNS_ARP_RESOLVE:
			if(!ARPIsResolved(&AppConfig.PrimaryDNSServer, &ResolvedInfo.MACAddr))
			{
				if(TickGet() - StartTime > DNS_TIMEOUT)
					smDNS = (vARPAttemptCount >= 3u) ? DNS_FAIL : DNS_ARP_START_RESOLVE;
				break;
			}
			ResolvedInfo.IPAddr.Val = AppConfig.PrimaryDNSServer.Val;
			smDNS = DNS_OPEN_SOCKET;
			// No break: DNS_OPEN_SOCKET is the correct next state
		
		case DNS_OPEN_SOCKET:
			MySocket = UDPOpen(0, &ResolvedInfo, DNS_PORT);
			if(MySocket == INVALID_UDP_SOCKET)
				break;

			smDNS = DNS_QUERY;
			// No need to break, we can immediately start resolution
			
		case DNS_QUERY:
			if(!UDPIsPutReady(MySocket))
				break;
			
			// Put DNS query here
			SentTransactionID.Val++;
			UDPPut(SentTransactionID.v[1]);// User chosen transaction ID
			UDPPut(SentTransactionID.v[0]);
			UDPPut(0x01);		// Standard query with recursion
			UDPPut(0x00);	
			UDPPut(0x00);		// 0x0001 questions
			UDPPut(0x01);
			UDPPut(0x00);		// 0x0000 answers
			UDPPut(0x00);
			UDPPut(0x00);		// 0x0000 name server resource records
			UDPPut(0x00);
			UDPPut(0x00);		// 0x0000 additional records
			UDPPut(0x00);

			// Put hostname string to resolve
			if(DNSHostName)
				DNSPutString(DNSHostName);
			else
				DNSPutROMString(DNSHostNameROM);

			UDPPut(0x00);		// Type: DNS_TYPE_A A (host address) or DNS_TYPE_MX for mail exchange
			UDPPut(RecordType);
			UDPPut(0x00);		// Class: IN (Internet)
			UDPPut(0x01);

			UDPFlush();
			StartTime = TickGet();
			smDNS = DNS_GET_RESULT;
			break;

		case DNS_GET_RESULT:
			if(!UDPIsGetReady(MySocket))
			{
				if(TickGet() - StartTime > DNS_TIMEOUT)
					smDNS = DNS_FAIL;
				break;
			}

			// Retrieve the DNS header and de-big-endian it
			UDPGet(&DNSHeader.TransactionID.v[1]);
			UDPGet(&DNSHeader.TransactionID.v[0]);

			// Throw this packet away if it isn't in response to our last query
			if(DNSHeader.TransactionID.Val != SentTransactionID.Val)
			{
				UDPDiscard();
				break;
			}

			UDPGet(&DNSHeader.Flags.v[1]);
			UDPGet(&DNSHeader.Flags.v[0]);
			UDPGet(&DNSHeader.Questions.v[1]);
			UDPGet(&DNSHeader.Questions.v[0]);
			UDPGet(&DNSHeader.Answers.v[1]);
			UDPGet(&DNSHeader.Answers.v[0]);
			UDPGet(&DNSHeader.AuthoritativeRecords.v[1]);
			UDPGet(&DNSHeader.AuthoritativeRecords.v[0]);
			UDPGet(&DNSHeader.AdditionalRecords.v[1]);
			UDPGet(&DNSHeader.AdditionalRecords.v[0]);

			// Remove all questions (queries)
			while(DNSHeader.Questions.Val--)
			{
				DNSDiscardName();
				UDPGet(&w.v[1]);		// Question type
				UDPGet(&w.v[0]);
				UDPGet(&w.v[1]);		// Question class
				UDPGet(&w.v[0]);
			}
			
			// Scan through answers
			while(DNSHeader.Answers.Val--)
			{				
				DNSDiscardName();					// Throw away response name
				UDPGet(&DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);

				// Make sure that this is a 4 byte IP address, response type A or MX, class 1
				// Check if this is Type A or MX
				if( DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
					DNSAnswerHeader.ResponseClass.Val	== 0x0001u && // Internet class
					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
				{
					Flags.bits.AddressValid = TRUE;
					UDPGet(&ResolvedInfo.IPAddr.v[0]);
					UDPGet(&ResolvedInfo.IPAddr.v[1]);
					UDPGet(&ResolvedInfo.IPAddr.v[2]);
					UDPGet(&ResolvedInfo.IPAddr.v[3]);
					goto DoneSearchingRecords;
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(&i);
					}
				}
			}

			// Remove all Authoritative Records
			while(DNSHeader.AuthoritativeRecords.Val--)
			{
				DNSDiscardName();					// Throw away response name
				UDPGet(&DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);

				// Make sure that this is a 4 byte IP address, response type A or MX, class 1
				// Check if this is Type A
				if( DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
					DNSAnswerHeader.ResponseClass.Val	== 0x0001u && // Internet class
					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
				{
					Flags.bits.AddressValid = TRUE;
					UDPGet(&ResolvedInfo.IPAddr.v[0]);
					UDPGet(&ResolvedInfo.IPAddr.v[1]);
					UDPGet(&ResolvedInfo.IPAddr.v[2]);
					UDPGet(&ResolvedInfo.IPAddr.v[3]);
					goto DoneSearchingRecords;
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(&i);
					}
				}
			}

			// Remove all Additional Records
			while(DNSHeader.AdditionalRecords.Val--)
			{
				DNSDiscardName();					// Throw away response name
				UDPGet(&DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(&DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);

				// Make sure that this is a 4 byte IP address, response type A or MX, class 1
				// Check if this is Type A
				if( DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
					DNSAnswerHeader.ResponseClass.Val	== 0x0001u && // Internet class
					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
				{
					Flags.bits.AddressValid = TRUE;
					UDPGet(&ResolvedInfo.IPAddr.v[0]);
					UDPGet(&ResolvedInfo.IPAddr.v[1]);
					UDPGet(&ResolvedInfo.IPAddr.v[2]);
					UDPGet(&ResolvedInfo.IPAddr.v[3]);
					goto DoneSearchingRecords;
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(&i);
					}
				}
			}

DoneSearchingRecords:

			UDPDiscard();
			UDPClose(MySocket);
			MySocket = INVALID_UDP_SOCKET;
			smDNS = DNS_DONE;
			// No break, DNS_DONE is the correct step

		case DNS_DONE:
			// Return 0.0.0.0 if DNS resolution failed, otherwise return the 
			// resolved IP address
			if(!Flags.bits.AddressValid)
				ResolvedInfo.IPAddr.Val = 0;
			HostIP->Val = ResolvedInfo.IPAddr.Val;
			return TRUE;

		case DNS_FAIL:
			// If 3 attempts or more, quit
			if(vDNSAttemptCount >= 2u)
			{
				// Return an invalid IP address 0.0.0.0 if we can't finish ARP or DNS query step
				HostIP->Val = 0x00000000;
				return TRUE;
			}
			vDNSAttemptCount++;

			// Swap primary and secondary DNS servers if there is a secondary DNS server programmed
			if(AppConfig.SecondaryDNSServer.Val)
			{
				AppConfig.PrimaryDNSServer.Val ^= AppConfig.SecondaryDNSServer.Val;
				AppConfig.SecondaryDNSServer.Val ^= AppConfig.PrimaryDNSServer.Val;
				AppConfig.PrimaryDNSServer.Val ^= AppConfig.SecondaryDNSServer.Val;

				// Start another ARP resolution for the secondary server (now primary)
				vARPAttemptCount = 0;
				if(MySocket != INVALID_UDP_SOCKET)
				{
					UDPClose(MySocket);
					MySocket = INVALID_UDP_SOCKET;
				}
				smDNS = DNS_ARP_START_RESOLVE;
			}

			break;

	}
	
	return FALSE;
}
Exemplo n.º 17
0
/**
 * Call DNSIsResolved() until the host is resolved.
 * You cannot start two DNS resolution proceedures concurrently.
 * You must not modify *Hostname until DNSIsResolved() returns TRUE.
 *
 * @preCondition        DNSResolve() was called.
 *
 * @param HostIP        4 byte IP address
 */
BOOL DNSIsResolved(IP_ADDR *HostIP)
{
    static UDP_SOCKET   MySocket;
    static NODE_INFO    Remote;
    static TICK         StartTime;
    BYTE                i;
    WORD_VAL            w;
    DNS_HEADER          DNSHeader;
    DNS_ANSWER_HEADER   DNSAnswerHeader;
    IP_ADDR             tmpIpAddr;

    switch(smDNS)
    {
        case DNS_HOME:
            tmpIpAddr.v[0] = MY_DNS_BYTE1;
            tmpIpAddr.v[1] = MY_DNS_BYTE2;
            tmpIpAddr.v[2] = MY_DNS_BYTE3;
            tmpIpAddr.v[3] = MY_DNS_BYTE4;
            ARPResolve(&tmpIpAddr);
            StartTime = TickGet();
            smDNS++;
            break;
        case DNS_RESOLVE_ARP:
            if(!ARPIsResolved(&tmpIpAddr, &Remote.MACAddr))
            {
                if(TickGet() - StartTime > DNS_TIMEOUT)
                {
                    smDNS--;
                }
                break;
            }
            Remote.IPAddr.Val = tmpIpAddr.Val;
            smDNS++;
            // No need to break, we can immediately start resolution

        case DNS_OPEN_SOCKET:
            MySocket = UDPOpen(0, &Remote, DNS_PORT);
            if(MySocket == INVALID_UDP_SOCKET) {
                #if (DEBUG_DNS >= LOG_ERROR)
                debugPutMsg(1); //@mxd:1:Could not open UDP socket
                #endif

                break;
            }

            smDNS++;
            // No need to break, we can immediately start resolution
            
        case DNS_QUERY:
            if(!UDPIsPutReady(MySocket))
                break;
            
            // Put DNS query here
            UDPPut(0x12);        // User chosen ID
            UDPPut(0x34);
            UDPPut(0x01);        // Standard query with recursion
            UDPPut(0x00);    
            UDPPut(0x00);        // 0x0001 questions
            UDPPut(0x01);
            UDPPut(0x00);        // 0x0000 answers
            UDPPut(0x00);
            UDPPut(0x00);        // 0x0000 name server resource records
            UDPPut(0x00);
            UDPPut(0x00);        // 0x0000 additional records
            UDPPut(0x00);

            // Put hostname string to resolve
            DNSPutString(DNSHostName);

            UDPPut(0x00);        // Type: A (host address)
            UDPPut(0x01);
            UDPPut(0x00);        // Class: IN (Internet)
            UDPPut(0x01);

            UDPFlush();
            StartTime = TickGet();
            smDNS++;
            break;

        case DNS_GET_RESULT:
            if(!UDPIsGetReady(MySocket))
            {
                if(TickGet() - StartTime > DNS_TIMEOUT)
                {
                    smDNS--;
                }
                break;
            }

            // Retrieve the DNS header and de-big-endian it
            UDPGet(&DNSHeader.TransactionID.v[1]);
            UDPGet(&DNSHeader.TransactionID.v[0]);
            UDPGet(&DNSHeader.Flags.v[1]);
            UDPGet(&DNSHeader.Flags.v[0]);
            UDPGet(&DNSHeader.Questions.v[1]);
            UDPGet(&DNSHeader.Questions.v[0]);
            UDPGet(&DNSHeader.Answers.v[1]);
            UDPGet(&DNSHeader.Answers.v[0]);
            UDPGet(&DNSHeader.AuthoritativeRecords.v[1]);
            UDPGet(&DNSHeader.AuthoritativeRecords.v[0]);
            UDPGet(&DNSHeader.AdditionalRecords.v[1]);
            UDPGet(&DNSHeader.AdditionalRecords.v[0]);

            // Remove all questions
            while(DNSHeader.Questions.Val--)
            {
                DNSGetString(NULL);
                UDPGet(&w.v[1]);        // Question type
                UDPGet(&w.v[0]);
                UDPGet(&w.v[1]);        // Question class
                UDPGet(&w.v[0]);
            }
            
            // Scan through answers
            while(DNSHeader.Answers.Val--)
            {
                UDPGet(&DNSAnswerHeader.ResponseName.v[1]);        // Response name
                UDPGet(&DNSAnswerHeader.ResponseName.v[0]);
                UDPGet(&DNSAnswerHeader.ResponseType.v[1]);        // Response type
                UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
                UDPGet(&DNSAnswerHeader.ResponseClass.v[1]);    // Response class
                UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
                UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]);        // Time to live
                UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
                UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
                UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
                UDPGet(&DNSAnswerHeader.ResponseLen.v[1]);        // Response length
                UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);

                // Make sure that this is a 4 byte IP address, response type A, class 1
                // Check if this is Type A
                if(    DNSAnswerHeader.ResponseType.Val    == 0x0001u && 
                    DNSAnswerHeader.ResponseClass.Val    == 0x0001u && // Internet class
                    DNSAnswerHeader.ResponseLen.Val        == 0x0004u)
                {
                    UDPGet(&HostIP->v[0]);
                    UDPGet(&HostIP->v[1]);
                    UDPGet(&HostIP->v[2]);
                    UDPGet(&HostIP->v[3]);
                    break;
                }
                else
                {
                    while(DNSAnswerHeader.ResponseLen.Val--)
                    {
                        UDPGet(&i);
                    }
                }
            }

            UDPDiscard();
            UDPClose(MySocket);
            MySocket = INVALID_UDP_SOCKET;
            smDNS++;
            // No need to break, we are done and need to return TRUE

        case DNS_DONE:
            return TRUE;
    }
    
    return FALSE;
}
Exemplo n.º 18
0
void NTPTask(void)
{
   NTP_PACKET         pkt;
   WORD               w;
   
   switch(NTPState)
   {
      case NTP_HOME:
         debug_ntp(debug_putc, "\r\n\nRefreshing Time\r\n");
         // Obtain ownership of the DNS resolution module
         if(!DNSBeginUsage())
            break;

         // Obtain the IP address associated with the server name
         DNSResolveROM((ROM BYTE*)NTP_SERVER, DNS_TYPE_A);
         rtcTimer = time(NULL);
         NTPState = NTP_NAME_RESOLVE;
         break;

      case NTP_NAME_RESOLVE:
         // Wait for DNS resolution to complete
         if(!DNSIsResolved(&Server.IPAddr)) 
         {
            if((time(NULL) - rtcTimer) >= NTP_RESOLVE_TIMEOUT)
            {
               DNSEndUsage();
               rtcTimer = time(NULL);
               NTPState = NTP_SHORT_WAIT;
            }
            break;
         }
         // Obtain DNS resolution result
         if(!DNSEndUsage())
         {
            // No valid IP address was returned from the DNS 
            // server.  Quit and fail for a while if host is not valid.
            rtcTimer = time(NULL);
            NTPState = NTP_SHORT_WAIT;
            break;
         }
         NTPState = NTP_ARP_START_RESOLVE;
         // No need to break

      case NTP_ARP_START_RESOLVE:
      case NTP_ARP_START_RESOLVE2:
      case NTP_ARP_START_RESOLVE3:
         // Obtain the MAC address associated with the server's IP address 
         ARPResolve(&Server.IPAddr);
         rtcTimer = time(NULL);
         NTPState++;
         break;

      case NTP_ARP_RESOLVE:
      case NTP_ARP_RESOLVE2:
      case NTP_ARP_RESOLVE3:
         // Wait for the MAC address to finish being obtained
         if(!ARPIsResolved(&Server.IPAddr, &Server.MACAddr))
         {
            // Time out if too much time is spent in this state
            if(time(NULL) - rtcTimer >= NTP_ARP_TIMEOUT)
            {
               // Retransmit ARP request by going to next SM_ARP_START_RESOLVE state or fail by going to SM_ARP_RESOLVE_FAIL state.
               NTPState++;
            }
            break;
         }
         NTPState = NTP_UDP_SEND;
         break;

      case NTP_ARP_RESOLVE_FAIL:
         // ARP failed after 3 tries, abort and wait for next time query
         rtcTimer = time(NULL);
         NTPState = NTP_SHORT_WAIT;
         break;

      case NTP_UDP_SEND:
         // Open up the sending UDP socket
         MySocket = UDPOpen(NTP_LOCAL_PORT, &Server, NTP_SERVER_PORT);
         if(MySocket == INVALID_UDP_SOCKET)
            break;

         // Make certain the socket can be written to
         if(!UDPIsPutReady(MySocket))
         {
            UDPClose(MySocket);
            break;
         }

         // Transmit a time request packet
         memset(&pkt, 0, sizeof(pkt));
         pkt.flags.versionNumber = 3;   // NTP Version 3
         pkt.flags.mode = 3;            // NTP Client
         pkt.orig_ts_secs = swapl(NTP_EPOCH);
         UDPPutArray((BYTE*) &pkt, sizeof(pkt));   
         UDPFlush();   
         
         //dwTimer = TickGet();
         rtcTimer = time(NULL);
         
         NTPState = NTP_UDP_RECV;      
         break;

      case NTP_UDP_RECV:
         // Look for a response time packet
         if(!UDPIsGetReady(MySocket)) 
         {
            if((time(NULL)) - rtcTimer >= NTP_REPLY_TIMEOUT)
            {
               // Abort the request and wait until the next timeout period
               UDPClose(MySocket);
               rtcTimer = time(NULL);
               NTPState = NTP_SHORT_WAIT;
               break;
            }
            break;
         }
         
         // Get the response time packet
         w = UDPGetArray((BYTE*) &pkt, sizeof(pkt));
         UDPClose(MySocket);
         rtcTimer = time(NULL);

         // Validate packet size
         if(w != sizeof(pkt)) 
         {
            NTPState = NTP_SHORT_WAIT;
            break;   
         }
         
         g_NTPOk = TRUE;
         NTPState = NTP_WAIT;
         
         // Set out local time to match the returned time
         NTPLastUpdate = swapl(pkt.tx_ts_secs) - NTP_EPOCH;
         // Do rounding.  If the partial seconds is > 0.5 then add 1 to the seconds count.
         if(((BYTE*)&pkt.tx_ts_fraq)[0] & 0x80)
            NTPLastUpdate++;
         SetTimeSec(NTPLastUpdate);
         break;

      case NTP_SHORT_WAIT:
         // Attempt to requery the NTP server after a specified NTP_FAST_QUERY_INTERVAL time (ex: 8 seconds) has elapsed.
         g_NTPOk = FALSE;
         if(time(NULL) - rtcTimer >= NTP_WAIT_INTERVAL)
            NTPState = NTP_HOME;   
         break;

      case NTP_WAIT:
         // Requery the NTP server after a specified NTP_QUERY_INTERVAL time (ex: 10 minutes) has elapsed.
         if(time(NULL) - NTPLastUpdate >= NTP_QUERY_INTERVAL)
            NTPState = NTP_HOME;   

         break;
   }
}
Exemplo n.º 19
0
void timeSync(void)
{
	BYTE i;
	signed char j;	
	static TICK			Timer;
	static TICK perodicTick = 0;
	static TICK t = 0;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static NODE_INFO	Server;
	static int arp_tries = 0;
	static int tcp_tries = 0;

	BYTE rcnt=0;
	BYTE ncnt=0;
	char foundData=0;

	if ((tickGet()-t) >= TICK_1S )
    {
		t = tickGet();
		timeNow++;
	}

	switch(smTS)
	{
		case SM_START:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Start!\r\n");
			#endif
			// Set IP adress to connect to.
			Server.IPAddr.v[0]=193;
			Server.IPAddr.v[1]=11;
			Server.IPAddr.v[2]=249;
			Server.IPAddr.v[3]=54;

			arp_tries = 0;
			tcp_tries = 0;

			smTS = SM_ARP_RESOLVE;
		break;
		
		case SM_ARP_RESOLVE:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Resolve..\r\n");
			#endif
			// If ARP is redy..
			if (ARPIsTxReady())
			{
				// Resolve the IP adress..
				ARPResolve(&Server.IPAddr);
				arp_tries++;
				Timer = tickGet();
				smTS = SM_ARP_RESOLVED;
			}
		break;

		case SM_ARP_RESOLVED:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Resolved..\r\n");
			#endif
			// If IP adress is resolved, go to next state
			if (ARPIsResolved(&Server.IPAddr, &Server.MACAddr))
			{
				smTS = SM_CONNECT;
			}
			// If not resolved and spent long time here,
			// Go back to previous state and re-resolve.
			else if (tickGet()-Timer > 1*TICK_1S)
			{
				smTS = SM_ARP_RESOLVE;
			}
			else if (arp_tries>=MAX_ARP_TRIES)
			{
				//Abort
				smTS = SM_ABORT;
			}

		break;

		case SM_CONNECT:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Connect..\r\n");
			#endif
			// We have an sucessfull ARP, connect..
			MySocket = TCPConnect(&Server, ServerPort);
			tcp_tries++;	

			if(MySocket == INVALID_SOCKET)
			{
				// Do something.
			}
		
			Timer = tickGet();
			smTS = SM_CONNECT_WAIT;

		break;

		case SM_CONNECT_WAIT:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Connect wait..\r\n");
			#endif
			// Wait for connection..

			if (TCPIsConnected(MySocket))
			{
				smTS = SM_CONNECTED;
			}
			// If not connected and spent long time here,
			// Go back to previous state and re-connect.
			else if (tickGet()-Timer > 5*TICK_1S)
			{
				TCPDisconnect(MySocket);
				MySocket = INVALID_SOCKET;
				smTS = SM_CONNECT;
			}
			else if (tcp_tries>=MAX_TCP_TRIES)
			{
				//Abort
				TCPDisconnect(MySocket);
				MySocket = INVALID_SOCKET;
				smTS = SM_ABORT;
			}


		break;

		case SM_CONNECTED:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Connected..\r\n");
			#endif
			// Send data.
			Timer = tickGet();

			if(TCPIsPutReady(MySocket))
			{

				TCPPut(MySocket, 'G');
				TCPPut(MySocket, 'E');
				TCPPut(MySocket, 'T');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, '/');
				TCPPut(MySocket, 't');
				TCPPut(MySocket, 'i');
				TCPPut(MySocket, 'm');
				TCPPut(MySocket, 'e');
				TCPPut(MySocket, '.');
				TCPPut(MySocket, 'p');
				TCPPut(MySocket, 'h');
				TCPPut(MySocket, 'p');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, 'H');
				TCPPut(MySocket, 'T');
				TCPPut(MySocket, 'T');
				TCPPut(MySocket, 'P');
				TCPPut(MySocket, '/');
				TCPPut(MySocket, '1');
				TCPPut(MySocket, '.');
				TCPPut(MySocket, '0');
				TCPPut(MySocket, '\r');
				TCPPut(MySocket, '\n');
				TCPPut(MySocket, '\r');
				TCPPut(MySocket, '\n');

				// Send the packet
				TCPFlush(MySocket);
				
				smTS = SM_RECEIVE;
			}

		break;

		case SM_RECEIVE:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Receive..\r\n");
			#endif
			// Client disconnected.
			if(!TCPIsConnected(MySocket))
			{
				smTS = SM_ABORT;
				break;
			}				

			if(TCPIsGetReady(MySocket))
			{
				while(TCPGet(MySocket, &i))
				{
					if (i==CR) rcnt++;
					else if(i==LF) ncnt++;
					else
					{ 
						rcnt=0; 
						ncnt=0; 
					}

					if (foundData==1)
					{
						if (j>=0)
						{	
							timeNow=timeNow+(((DWORD)i)<<(8*j--));
							#if defined(TIMESYNC_DEBUG)
							while(BusyUART()); WriteUART(i);
							#endif
						}
					}

					if(rcnt>1 && ncnt>1) {j=3; timeNow=0; foundData=1;}

					
				}
				smTS = SM_DISCONNECT;	
			}

		break;

		case SM_DISCONNECT:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("\r\nDisconnect\r\n");
			#endif
			foundData=0;
			t = tickGet();
			lastSync = timeNow;
			perodicTick=tickGet();
			TCPDisconnect(MySocket);
			MySocket = INVALID_SOCKET;
			smTS = SM_DONE;
		break;

		case SM_ABORT:
			#if defined(TIMESYNC_DEBUG)
			putrsUART("Abort...\r\n");
			#endif
			smTS = SM_START;
		break;

		case SM_DONE:
			if (tickGet()-perodicTick > SYNC_INTERVAL*TICK_1S)
			{
				#if defined(TIMESYNC_DEBUG)
				putrsUART("GO!\r\n");
				#endif
				smTS = SM_START;
			}
		break;

		default: smTS = SM_START; break;

	}


}
Exemplo n.º 20
0
/*****************************************************************************
  Function:
	void SNTPClient(void)

  Summary:
	Periodically checks the current time from a pool of servers.

  Description:
	This function periodically checks a pool of time servers to obtain the
	current date/time.

  Precondition:
	UDP is initialized.

  Parameters:
	None

  Returns:
  	None
  	
  Remarks:
	This function requires once available UDP socket while processing, but
	frees that socket when the SNTP module is idle.
  ***************************************************************************/
void SNTPClient(void)
{
	NTP_PACKET			pkt;
	WORD		 		w;
//	static NODE_INFO	Server;
	static DWORD		dwTimer;
	static UDP_SOCKET	MySocket = INVALID_UDP_SOCKET;
	static enum
	{
		SM_HOME = 0,
		SM_UDP_IS_OPENED,
		//SM_NAME_RESOLVE,
		//SM_ARP_START_RESOLVE,
		//SM_ARP_RESOLVE,
		//SM_ARP_START_RESOLVE2,
		//SM_ARP_RESOLVE2,
		//SM_ARP_START_RESOLVE3,
		//SM_ARP_RESOLVE3,
		//SM_ARP_RESOLVE_FAIL,
		SM_UDP_SEND,
		SM_UDP_RECV,
		SM_SHORT_WAIT,
		SM_WAIT
	} SNTPState = SM_HOME;


	switch(SNTPState)
	{
		case SM_HOME:
			if(MySocket == INVALID_UDP_SOCKET)
				MySocket = UDPOpenEx((DWORD)(PTR_BASE)NTP_SERVER,UDP_OPEN_ROM_HOST,0,NTP_SERVER_PORT);
			
			SNTPState++;
			break;
			
		case SM_UDP_IS_OPENED:
			if(UDPIsOpened(MySocket) == TRUE)
			{
				SNTPState = SM_UDP_SEND;
			}
		/*	else
			{
				UDPClose(MySocket);
				SNTPState = SM_HOME;
				MySocket = INVALID_UDP_SOCKET;
			}
		*/		
			break;

#if 0			
			// Obtain ownership of the DNS resolution module
			if(!DNSBeginUsage())
				break;

			// Obtain the IP address associated with the server name
			DNSResolveROM((ROM BYTE*)NTP_SERVER, DNS_TYPE_A);
			dwTimer = TickGet();
			SNTPState = SM_NAME_RESOLVE;
			break;

		case SM_NAME_RESOLVE:
			// Wait for DNS resolution to complete
			if(!DNSIsResolved(&Server.IPAddr)) 
			{
				if((TickGet() - dwTimer) > (5 * TICK_SECOND)) 
				{
					DNSEndUsage();
					dwTimer = TickGetDiv64K();
					SNTPState = SM_SHORT_WAIT;
				}
				break;
			}
			
			// Obtain DNS resolution result
			if(!DNSEndUsage())
			{
				// No valid IP address was returned from the DNS 
				// server.  Quit and fail for a while if host is not valid.
				dwTimer = TickGetDiv64K();
				SNTPState = SM_SHORT_WAIT;
				break;
			}
			SNTPState = SM_ARP_START_RESOLVE;
			// No need to break

		case SM_ARP_START_RESOLVE:
		case SM_ARP_START_RESOLVE2:
		case SM_ARP_START_RESOLVE3:
			// Obtain the MAC address associated with the server's IP address 
			ARPResolve(&Server.IPAddr);
			dwTimer = TickGet();
			SNTPState++;
			break;

		case SM_ARP_RESOLVE:
		case SM_ARP_RESOLVE2:
		case SM_ARP_RESOLVE3:
			// Wait for the MAC address to finish being obtained
			if(!ARPIsResolved(&Server.IPAddr, &Server.MACAddr))
			{
				// Time out if too much time is spent in this state
				if(TickGet() - dwTimer > 1*TICK_SECOND)
				{
					// Retransmit ARP request by going to next SM_ARP_START_RESOLVE state or fail by going to SM_ARP_RESOLVE_FAIL state.
					SNTPState++;
				}
				break;
			}
			SNTPState = SM_UDP_SEND;
			break;

		case SM_ARP_RESOLVE_FAIL:
			// ARP failed after 3 tries, abort and wait for next time query
			dwTimer = TickGetDiv64K();
			SNTPState = SM_SHORT_WAIT;
			break;
#endif
// case SM_UDP_IS_OPENED:
		case SM_UDP_SEND:
			// Open up the sending UDP socket
			//MySocket = UDPOpen(0, &Server, NTP_SERVER_PORT);
#if 0

			MySocket = UDPOpenEx(NTP_SERVER,UDP_OPEN_ROM_HOST,0,NTP_SERVER_PORT);
			if(MySocket == INVALID_UDP_SOCKET)
				break;
#endif			

			// Make certain the socket can be written to
			if(!UDPIsPutReady(MySocket))
			{
				UDPClose(MySocket);
				SNTPState = SM_HOME;
				MySocket = INVALID_UDP_SOCKET;
				break;
			}

			// Transmit a time request packet
			memset(&pkt, 0, sizeof(pkt));
			pkt.flags.versionNumber = 3;	// NTP Version 3
			pkt.flags.mode = 3;				// NTP Client
			pkt.orig_ts_secs = swapl(NTP_EPOCH);
			UDPPutArray((BYTE*) &pkt, sizeof(pkt));	
			UDPFlush();	
			
			dwTimer = TickGet();
			SNTPState = SM_UDP_RECV;		
			break;

		case SM_UDP_RECV:
			// Look for a response time packet
			if(!UDPIsGetReady(MySocket)) 
			{
				if((TickGet()) - dwTimer > NTP_REPLY_TIMEOUT)
				{
					// Abort the request and wait until the next timeout period
					UDPClose(MySocket);
					//dwTimer = TickGetDiv64K();
					//SNTPState = SM_SHORT_WAIT;
					SNTPState = SM_HOME;
					MySocket = INVALID_UDP_SOCKET;
					break;
				}
				break;
			}
			
			// Get the response time packet
			w = UDPGetArray((BYTE*) &pkt, sizeof(pkt));
			UDPClose(MySocket);
			dwTimer = TickGetDiv64K();
			SNTPState = SM_WAIT;
			MySocket = INVALID_UDP_SOCKET;
			
			// Validate packet size
			if(w != sizeof(pkt)) 
			{
				break;	
			}
			
			// Set out local time to match the returned time
			dwLastUpdateTick = TickGet();
			dwSNTPSeconds = swapl(pkt.tx_ts_secs) - NTP_EPOCH;
			// Do rounding.  If the partial seconds is > 0.5 then add 1 to the seconds count.
			if(((BYTE*)&pkt.tx_ts_fraq)[0] & 0x80)
				dwSNTPSeconds++;

			#ifdef WIFI_NET_TEST
				wifi_net_test_print("SNTP: current time", dwSNTPSeconds);
			#endif
			break;

		case SM_SHORT_WAIT:
			// Attempt to requery the NTP server after a specified NTP_FAST_QUERY_INTERVAL time (ex: 8 seconds) has elapsed.
			if(TickGetDiv64K() - dwTimer > (NTP_FAST_QUERY_INTERVAL/65536ull))
			{
				SNTPState = SM_HOME;
				MySocket = INVALID_UDP_SOCKET;
			}
			break;

		case SM_WAIT:
			// Requery the NTP server after a specified NTP_QUERY_INTERVAL time (ex: 10 minutes) has elapsed.
			if(TickGetDiv64K() - dwTimer > (NTP_QUERY_INTERVAL/65536ull))
			{
				SNTPState = SM_HOME;
				MySocket = INVALID_UDP_SOCKET;
			}

			break;
	}
}
Exemplo n.º 21
0
void AutoIPTasks(NET_CONFIG* pConfig)
{
//    uint8_t i;
    TCPIP_MAC_HANDLE hMac;

//    for (i = 0; i < NETWORK_INTERFACES; i++)
    {
        LoadState(_TCPIPStackNetIx(pConfig));
        hMac = _TCPIPStackNetToMac(pConfig);
        AutoIPClient.flags.bits.bCurrentLinkState = MACIsLinked(hMac);
    	if(AutoIPClient.flags.bits.bCurrentLinkState != AutoIPClient.flags.bits.bLastLinkState)
    	{
    		AutoIPClient.flags.bits.bLastLinkState = AutoIPClient.flags.bits.bCurrentLinkState;
    		if(!AutoIPClient.flags.bits.bCurrentLinkState)
    		{
                AutoIPClient.flags.bits.bConfigureAutoIP = false;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
    			pConfig->MyIPAddr.Val = pConfig->DefaultIPAddr.Val;
    			pConfig->MyMask.Val = pConfig->DefaultMask.Val;
    		}
            else
            {
                AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
    	}
    
        #if defined (TCPIP_STACK_USE_DHCP_CLIENT)
        if (DHCPIsBound(pConfig))
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = false;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
            AutoIPClient.flags.bits.bLastDHCPState = true;
        }
        else
        {
            if (AutoIPClient.flags.bits.bLastDHCPState == true)
            {
                if (AutoIPClient.flags.bits.bCurrentLinkState)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_INIT_RNG;
            }
            AutoIPClient.flags.bits.bLastDHCPState = false;
        }
        #endif
    
    
        if (AutoIPClient.flags.bits.gDisableAutoIP == true)
        {
            AutoIPClient.flags.bits.bConfigureAutoIP = false;
            AutoIPClient.smAUTOIPState = SM_AUTOIP_DISABLED;
        }
    
    
        switch (AutoIPClient.smAUTOIPState)
        {
            // Default no-AutoIP case
        	case SM_AUTOIP_DISABLED:

                break;
    
            // Initializes the random number generator with a seed based on the MAC address
            case SM_AUTOIP_INIT_RNG:
                AutoIPRandSeed (((uint32_t)pConfig->MyMACAddr.v[0] + ((uint32_t)pConfig->MyMACAddr.v[1] << 8) + \
                        ((uint32_t)pConfig->MyMACAddr.v[2] << 16) + ((uint32_t)pConfig->MyMACAddr.v[3] << 24) + \
                        ((uint32_t)pConfig->MyMACAddr.v[4]) + ((uint32_t)pConfig->MyMACAddr.v[5] << 8)), pConfig);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
    
            // Check the address to see if it's in use before we write it into NetConfig
            case SM_AUTOIP_CHECK_ADDRESS:
    
                if (AutoIPClient.flags.bits.checkAddress == false)
                {
                    AutoIPClient.flags.bits.checkAddress = true;
    
                    pConfig->MyMask.Val = 0x00000000;
    
                    // Generate a random IP address (based on the MAC address) to try and claim.
                    // Dynamic link-local addresses can fall within the range:
                    // 169.254.1.0 - 169.254.254.255
                    AutoIPClient.packet.TargetIPAddr.byte.MB = AutoIPRand(pConfig) % 256;
                    AutoIPClient.packet.TargetIPAddr.byte.UB = (AutoIPRand(pConfig) % 254) + 1;
                    AutoIPClient.packet.TargetIPAddr.word.LW = 0xFEA9;
    
                    ARPResolve (pConfig, &AutoIPClient.packet.TargetIPAddr);
    
                    AutoIPClient.eventTime = SYS_TICK_Get();
                }
                
                if (!ARPIsResolved (pConfig, &AutoIPClient.packet.TargetIPAddr, &AutoIPClient.packet.TargetMACAddr))
                {
                    if (SYS_TICK_Get() - AutoIPClient.eventTime > SYS_TICK_TicksPerSecondGet())
                    {
                        AutoIPClient.smAUTOIPState = SM_AUTOIP_SETUP_MESSAGE;
                    }
                }
                else
                {
                    AutoIPClient.flags.bits.checkAddress = false;
                }
    
                break;
    
            // Set up an ARP packet
            case SM_AUTOIP_SETUP_MESSAGE:
    
                AutoIPClient.flags.bits.checkAddress = false;
    
                // Set the bConfigureAutoIP flag- This flag will cause an AutoIP conflict
                // if a response packet is received from the address we're trying to claim.
                AutoIPClient.flags.bits.bConfigureAutoIP = true;
    
                // Configure the fields for a gratuitous ARP packet
            	AutoIPClient.packet.Operation            = ARP_OPERATION_REQ;
            
            	AutoIPClient.packet.TargetMACAddr.v[0]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[1]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[2]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[3]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[4]   = 0xff;
            	AutoIPClient.packet.TargetMACAddr.v[5]   = 0xff;
    
                pConfig->MyIPAddr = AutoIPClient.packet.TargetIPAddr;
                pConfig->MyMask.Val = 0x0000FFFF;
            	memcpy(&AutoIPClient.packet.SenderMACAddr, (void*)&pConfig->MyMACAddr, sizeof(AutoIPClient.packet.SenderMACAddr));
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
                AutoIPClient.packet.MACAddrLen    = sizeof(MAC_ADDR);
                AutoIPClient.packet.ProtocolLen   = sizeof(IP_ADDR);
                AutoIPClient.packet.SenderIPAddr.Val  = AutoIPClient.packet.TargetIPAddr.Val;
    
                SwapARPPacket(&AutoIPClient.packet);
    
                // Generate a random delay between 0 and 1 second
                AutoIPClient.randomDelay = ((LFSRRand() % 20) * SYS_TICK_TicksPerSecondGet()) / 20;
                // Store the current time
                AutoIPClient.eventTime = SYS_TICK_Get();
    
                // Set the state to send the ARP packet
                AutoIPClient.smAUTOIPState = SM_AUTOIP_GRATUITOUS_ARP1;
    
                break;
    
            // Send a gratuitous ARP packet to try and claim our address
            case SM_AUTOIP_GRATUITOUS_ARP1:
            case SM_AUTOIP_GRATUITOUS_ARP2:
            case SM_AUTOIP_GRATUITOUS_ARP3:
                // Check to ensure we've passed the delay time
                if (SYS_TICK_Get() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                {
                	if(!MACIsTxReady(hMac))
                    {
                        break;
                    }
                    // Store the new event time
                    AutoIPClient.eventTime = SYS_TICK_Get();
                    // Generate a new random delay between 1 and 2 seconds
                    AutoIPClient.randomDelay = SYS_TICK_TicksPerSecondGet() + (((LFSRRand() % 20) * SYS_TICK_TicksPerSecondGet()) / 20);
    
                    // Transmit the packet
                	MACSetWritePtr(hMac, MACGetTxBaseAddr(hMac));
    
                    MACPutHeader(hMac, &AutoIPClient.packet.TargetMACAddr, ETHERTYPE_ARP, sizeof(AutoIPClient.packet));
                    MACPutArray(hMac, (uint8_t*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                    MACFlush(hMac);
    
                    // Increment the probe iteration or increment to the delay state
                    AutoIPClient.smAUTOIPState++;
                }
                break;
    
            // Delay for 1-2 seconds after sending the third ARP request before
            // entering the configured state
            case SM_AUTOIP_DELAY:
                if (SYS_TICK_Get() - AutoIPClient.eventTime > AutoIPClient.randomDelay)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
    
            // Configure the module to limit the rate at which packets are sent
            case SM_AUTOIP_RATE_LIMIT_SET:
                AutoIPClient.eventTime = SYS_TICK_Get();
                pConfig->MyIPAddr.Val = pConfig->DefaultIPAddr.Val;
                AutoIPClient.smAUTOIPState = SM_AUTOIP_RATE_LIMIT_WAIT;
                break;
    
            // Ensure that we don't try more than one address every 60 seconds
            case SM_AUTOIP_RATE_LIMIT_WAIT:
                if (SYS_TICK_Get() - AutoIPClient.eventTime > SYS_TICK_TicksPerSecondGet() * 60)
                    AutoIPClient.smAUTOIPState = SM_AUTOIP_CHECK_ADDRESS;
                break;
    
            // Configured state
            case SM_AUTOIP_CONFIGURED:
                AutoIPClient.flags.bits.bConfigureAutoIP = false;
                break;
    
            // Address defense state
            case SM_AUTOIP_DEFEND:
                // Prepare and send an ARP response
            	if(!MACIsTxReady(hMac))
                {
                    break;
                }
                AutoIPClient.packet.Operation     = ARP_OPERATION_RESP;
                AutoIPClient.packet.HardwareType  = HW_ETHERNET;
                AutoIPClient.packet.Protocol      = ARP_IP;
    
                SwapARPPacket(&AutoIPClient.packet);
    
            	MACSetWritePtr(hMac, MACGetTxBaseAddr(hMac));
    
                MACPutHeader(hMac, &AutoIPClient.packet.TargetMACAddr, ETHERTYPE_ARP, sizeof(AutoIPClient.packet));
                MACPutArray(hMac, (uint8_t*)&AutoIPClient.packet, sizeof(AutoIPClient.packet));
                MACFlush(hMac);
    
                AutoIPClient.smAUTOIPState = SM_AUTOIP_CONFIGURED;
                break;
        }
    }
}