Example #1
0
/***	int UdpClient::writeDatagram(const byte *rgbWrite, size_t cbWrite)
**
**
**	Synopsis:   
**      Writes the buffer out as a datagram and sends it to the instances remote endpoint
**
**	Parameters:
**      rgbWrite     A pointer to an array of bytes that composes the datagram
**
**      cbWrite     The number of bytes in the datagram.
**
**	Return Values:
**      The number of bytes actually written. 0 is returned if no bytes were written or an error occured.
**
**	Errors:
**
**  Notes:
**
**      Because Udp is a datagram protocol, this always transmits the buffer immediately
**      as a complete datagram.
**
*/
long int UdpClient::writeDatagram(const byte *rgbWrite, size_t cbWrite)
{
    int cbMax = 0;
    // isDNETcK::EndPointResolved will call periodic tasks
    if(isEndPointResolved(DNETcK::msImmediate))
    {
        cbMax = (int) ((unsigned int) UDPIsPutReady(_hUDP));

        if(cbMax >= cbWrite)
        {
            // write the datagram out and flush it
            cbMax = UDPPutArray(rgbWrite, cbWrite);
            UDPFlush();
            return(cbMax);
        }

        // our output buffer is not big enough
        else
        {
            return(-cbMax);
        }      
    }

    // endpoint not resolved
    else
    {
        return(0);
    }

    EthernetPeriodicTasks();
}
Example #2
0
/*********************************************************************
 * Function:        void TFTPPut(BYTE c)
 *
 * PreCondition:    TFTPOpenFile() is called with TFTP_FILE_MODE_WRITE
 *                  and TFTPIsPutReady() = TRUE
 *
 * Input:           c       - Data byte that is to be written
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Puts given data byte into TFTP socket.
 *                  If end of data block is reached, it
 *                  transmits entire block.
 *
 * Note:            Use this function to write file to server.
 ********************************************************************/
void TFTPPut(BYTE c)
{
    // Put given byte directly to UDP
    UDPPut(c);

    // One more byte in data block.
    ++MutExVar.group2._tftpBlockLength.Val;

    // Check to see if data block is full.
    if ( MutExVar.group2._tftpBlockLength.byte.MSB == TFTP_BLOCK_SIZE_MSB )
    {
        // If it is, then transmit this block.
        UDPFlush();

        // Remember that current block is already flushed.
        _tftpFlags.bits.bIsFlushed = TRUE;

        // Prepare for next block.
        MutExVar.group2._tftpBlockLength.Val = 0;

        // Need to wait for ACK from server before putting
        // next block of data.
        _tftpState = SM_TFTP_WAIT_FOR_ACK;
    }
}
Example #3
0
static void _TFTPSendFileName(TFTP_OPCODE opcode, char *fileName)
{
    BYTE c;

    // Write opCode
    UDPPut(0);
    UDPPut(opcode);

    // write file name, including NULL.
    do
    {
        c = *fileName++;
        UDPPut(c);
    } while ( c != '\0' );

    // Write mode - always use octet or binay mode to transmit files.
    UDPPut('o');
    UDPPut('c');
    UDPPut('t');
    UDPPut('e');
    UDPPut('t');
    UDPPut(0);

    // Transmit it.
    UDPFlush();

    // Reset data block length.
    MutExVar.group2._tftpBlockLength.Val = 0;

}
Example #4
0
static void _TFTPSendROMFileName(TFTP_OPCODE opcode, ROM BYTE *fileName)
{
    BYTE c;

	// Select the proper UDP socket and wait until we can write to it
	while(!UDPIsPutReady(_tftpSocket));

    // Write opCode
    UDPPut(0);
    UDPPut(opcode);

    // write file name, including NULL.
    do
    {
        c = *fileName++;
        UDPPut(c);
    } while ( c != '\0' );

    // Write mode - always use octet or binay mode to transmit files.
    UDPPut('o');
    UDPPut('c');
    UDPPut('t');
    UDPPut('e');
    UDPPut('t');
    UDPPut(0);

    // Transmit it.
    UDPFlush();

    // Reset data block length.
    MutExVar.group2._tftpBlockLength.Val = 0;
}
Example #5
0
void sendToLocalListeners() {
	int i, len;
	char *b;

	/* Only transmit if at least one listener has registered */
	if (!listenerActive) {
		return;
	}
	
	if(s == INVALID_UDP_SOCKET) {
		s = UDPOpen(localPort, &remote, localPort);
	}
	if(s == INVALID_UDP_SOCKET) {
		return;
	}

	if (!UDPIsPutReady(s)) {
		return;
	}
	b = LMContent();
	len = strlen(b);
	for(i=0; i<len; ++i) {
		UDPPut(b[i]);
	}
	UDPFlush();
}
Example #6
0
/****************************************************************************
  Function:
     WORD UDPSendPacket(UDP_SOCKET hUDP, BYTE * rgbBuf, WORD cbBuff, IP_ADDR ipAddr, WORD port, unsigned int cSecTimeout)

  Description:
    This is the core UDP send API, it will adjust the socket to the remote address we want to send to
    and then blast the data out.

  Precondition:
    UDP stack has to be up an running

  Parameters:
    hUDP        - An opened UDP socket to use to send on

    rgbBuf      - pointer to an array of bytes to send
                        
    cbBuff      - number of bytes in the buffer to send

    ipAddr      - the remote ip address to write to

    port        - the remote port to write to.
                       
    cSecTimout  - The maximum number of seconds to wait for the arp or write to take
                    before just returning with the number of bytes actually written, which could be 0.

  Returns:
    The number of bytes actually written to the remote target

  Remarks:
    UDP does not guarantee success, this could just go out on the wire to deaf ears.
  ***************************************************************************/
static WORD UDPSendPacket(UDP_SOCKET hUDP, BYTE * rgbBuf, WORD cbBuff, IP_ADDR ipAddr, WORD port, unsigned int cSecTimeout)
{

    WORD cbReady = 0;
    WORD cbSent = 0;
	DWORD t = 0;
 	
    if(!UDPAdjustSocketToMe(hUDP, ipAddr, port, cSecTimeout))
    {
        return(0);
    }

    t = TickGet();
    while(cbSent < cbBuff) 
    {
        if((cbReady = UDPIsPutReady(hUDP)) > 0)
        {
			WORD cb = cbBuff - cbSent;

			cb = cb < cbReady ? cb : cbReady;
            cbSent += UDPPutArray(&rgbBuf[cbSent], cb);
            UDPFlush();
 
            t = TickGet();
        }
        else if((TickGet() - t) >= (cSecTimeout * TICK_SECOND))
        {
            break;
        }

        ChipKITPeriodicTasks();
    }

    return(cbSent);
}
Example #7
0
/*********************************************************************
 * Function:        BOOL UDPPut(BYTE v)
 *
 * PreCondition:    UDPIsPutReady() == TRUE with desired UDP socket
 *                  that is to be loaded.
 *
 * Input:           v       - Data byte to loaded into transmit buffer
 *
 * Output:          TRUE if transmit buffer is still ready to accept
 *                  more data bytes
 *
 *                  FALSE if transmit buffer can no longer accept
 *                  any more data byte.
 *
 * Side Effects:    None
 *
 * Overview:        Given data byte is put into UDP transmit buffer
 *                  and active UDP socket buffer length is incremented
 *                  by one.
 *                  If buffer has become full, FALSE is returned.
 *                  Or else TRUE is returned.
 *
 * Note:            This function loads data into an active UDP socket
 *                  as determined by previous call to UDPIsPutReady()
 ********************************************************************/
BOOL UDPPut(BYTE v)
{
    UDP_SOCKET_INFO *p;
    WORD temp;

    p = &UDPSocketInfo[activeUDPSocket];

    if ( p->TxCount == 0 )
    {
        /*
         * This is the very first byte that is loaded in UDP buffer.
         * Remember what transmit buffer we are loading, and
         * start loading this and next bytes in data area of UDP
         * packet.
         */
        p->TxBuffer = MACGetTxBuffer();

        IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER));

        p->TxOffset = 0;
    }

    /*
     * Load it.
     */
    MACPut(v);

    if ( p->TxOffset++ >= p->TxCount )
        p->TxCount++;

#if 0
    /*
     * Keep track of number of bytes loaded.
     * If total bytes fill up buffer, transmit it.
     */
    p->TxCount++;
#endif

#define SIZEOF_MAC_HEADER       (14)

    /*
     * Depending on what communication media is used, allowable UDP
     * data length will vary.
     */
#if !defined(STACK_USE_SLIP)
#define MAX_UDP_DATA  (MAC_TX_BUFFER_SIZE - SIZEOF_MAC_HEADER - sizeof(IP_HEADER) - sizeof(UDP_HEADER))
#else
#define MAX_UDP_DATA  (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) )
#endif

    temp = p->TxCount;
    if ( temp >= MAX_UDP_DATA )
    {
        UDPFlush();
    }
#undef MAX_UDP_DATA

    return TRUE;
}
Example #8
0
/**
 * Given number of data bytes from the given array are put into the UDP transmit buffer
 * and active UDP socket buffer length is incremented by number of bytes. The data is
 * NOT sent yet, and the UDPFlush() function must be called to send all data contained
 * in the transmit buffer.
 *
 * If there is not enough space in the transmit buffer for all the data, the contents of
 * the transmit buffer will be sent, and this function will return the actual amount of
 * bytes that were sent. In this case, it is VERY IMPORTANT to call the UDPIsPutReady()
 * function again before calling the UDPPut() or UDPPutArray() functions! This will however
 * only happen if the transmit buffer fills up. The transmit buffer for UDP data is
 * = (MAC_TX_BUFFER_SIZE - 42), which is usually 982 bytes. If writing less then this to
 * the transmit buffer before calling UDPFlush(), then this function will always return the
 * requested number of bytes!
 *
 * Note: This function loads data into an active UDP socket as determined by previous
 * call to UDPIsPutReady().
 *
 * @preCondition    UDPIsPutReady() == TRUE with desired UDP socket
 *                  that is to be loaded.
 *
 * @param[in] buffer Buffer containing data that has to be sent.
 * @param count     Number of bytes to send
 *
 * @return          Number of bytes added to the transmit buffer.<br>
 *                  !!!!! IMPORTANT !!!!!<br>
 *                  If this value is less then the number of bytes we requested to send, then 
 *                  UDPIsPutReady() must be called again before calling the UDPPut() or
 *                  UDPPutArray() functions!
 */
WORD UDPPutArray(BYTE *buffer, WORD count)
{
    UDP_SOCKET_INFO *p;
    WORD temp;
	WORD ckCount = 0;
    p = &UDPSocketInfo[activeUDPSocket];

    //This UDP Socket does not contain any unsent data, and currently does not own a TX Buffer!
    //Assign it the next available TX Buffer
    if ( p->TxCount == 0 )
    {
        //Get handle to next available TX Buffer. The UDPIsPutReady() function that has to be called
        //prior to this function will determine if there is an available TX Buffer.
        p->TxBuffer = MACGetTxBuffer(TRUE);

        // Make sure that we received a TX buffer
        if(p->TxBuffer == INVALID_BUFFER)
            return FALSE;

        //This sets the current TX Buffer pointer to the given offset after the IP header.
        //We give the size of the UDP header here as a parameter. This causes the current
        //write pointer to be set to firt byte after the UDP header, which is the UDP data
        //area.
        IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER));
    }
    
    //This function request more bytes to be written to the TX Buffer then there is space 
    if ((p->TxCount + count) > UDPGetMaxDataLength()) {
        //Update count with maximum number of bytes that there is place for in the TX Buffer
        count = UDPGetMaxDataLength() - p->TxCount;
    }

    //Write buffer
    MACPutArray(buffer, count);
	while (ckCount <= count) {
		if (p->TxCount+ckCount & 1) {
			udpChecksum += *(buffer+ckCount);
			} else
		{
			udpChecksum += ((WORD)*(buffer+ckCount) << 8);
		}
		ckCount++;
	}	
	

    //Keep track of number of bytes loaded.
    //If total bytes fill up buffer, transmit it.
    p->TxCount +=  count;

    if ( p->TxCount >= UDPGetMaxDataLength() )
    {
        UDPFlush();
    }
    
    return count;   //Return actual number of bytes sent
}
Example #9
0
/****************************************************************************************************
  Function:
            void AnnounceIP(void)
    
  Summary:
    Transmits an Announce packet.
  Conditions:
    Stack is initialized()
  Return:
    None
  Side Effects:
    None
  Description:
    AnnounceIP opens a UDP socket and transmits a broadcast packet to port
    \30303. If a computer is on the same subnet and a utility is looking
    for packets on the UDP port, it will receive the broadcast. For this
    application, it is used to announce the change of this board's IP
    address. The messages can be viewed with the TCP/IP Discoverer
    software tool.
  Remarks:
    A UDP socket must be available before this function is called. It is
    freed at the end of the function. MAX_UDP_SOCKETS may need to be
    increased if other modules use UDP sockets.                                                      
  ****************************************************************************************************/
void AnnounceIP(void)
{
	UDP_SOCKET	MySocket;
	BYTE 		i;

	if(!MACIsLinked())  // Check for link before blindly opening and transmitting (similar to DHCP case)
		return;

	// Open a UDP socket for outbound broadcast transmission
	//MySocket = UDPOpen(2860, NULL, ANNOUNCE_PORT);
	MySocket = UDPOpenEx(0,UDP_OPEN_SERVER,2860, ANNOUNCE_PORT);
            LED1_IO = 0;

	// Abort operation if no UDP sockets are available
	// If this ever happens, incrementing MAX_UDP_SOCKETS in 
	// StackTsk.h may help (at the expense of more global memory 
	// resources).
	if(MySocket == INVALID_UDP_SOCKET)
		return;
	
	// Make certain the socket can be written to
	while(!UDPIsPutReady(MySocket));
	
	// Begin sending our MAC address in human readable form.
	// The MAC address theoretically could be obtained from the 
	// packet header when the computer receives our UDP packet, 
	// however, in practice, the OS will abstract away the useful
	// information and it would be difficult to obtain.  It also 
	// would be lost if this broadcast packet were forwarded by a
	// router to a different portion of the network (note that 
	// broadcasts are normally not forwarded by routers).
	UDPPutArray((BYTE*)AppConfig.NetBIOSName, sizeof(AppConfig.NetBIOSName)-1);
	UDPPut('\r');
	UDPPut('\n');

	// Convert the MAC address bytes to hex (text) and then send it
	i = 0;
	while(1)
	{
		UDPPut(btohexa_high(AppConfig.MyMACAddr.v[i]));
	    UDPPut(btohexa_low(AppConfig.MyMACAddr.v[i]));
	    if(++i == 6u)
	    	break;
	    UDPPut('-');
	}

	// Send some other human readable information.
	UDPPutROMString((ROM BYTE*)"\r\nDHCP/Power event occurred");

	// Send the packet
	UDPFlush();
	
	// Close the socket so it can be used by other modules
	UDPClose(MySocket);
}
Example #10
0
void EthernetTransmit(BYTE *data, WORD dataLen)
{
	// If a remote server socket exists and the local socket is allowing new data, send it.
	if (remoteServerSocket != INVALID_UDP_SOCKET) {
		if (UDPIsPutReady(remoteServerSocket) >= dataLen) {
			if (UDPPutArray(data, dataLen) < dataLen) {
				FATAL_ERROR();
			}
			UDPFlush();
		}
	}
}
/*****************************************************************************
  Function:
	void UDPPerformanceTask(void)

  Summary:
	Tests the transmit performance of the UDP module.

  Description:
	This function tests the transmit performance of the UDP module.  At boot,
	this module will transmit 1024 large UDP broadcast packets of 1024 bytes
	each.  Using a packet sniffer, one can determine how long this process 
	takes and calculate the transmit rate of the stack.  This function tests 
	true UDP performance in that it will open a socket, transmit one packet, 
	and close the socket for each loop.  After this initial transmission, the
	module can be re-enabled by holding button 3.
	
	This function is particularly useful after development to determine the
	impact of your application code on the stack's performance.  A before and
	after comparison will indicate if your application is unacceptably
	blocking the processor or taking too long to execute.

  Precondition:
	UDP is initialized.

  Parameters:
	None

  Returns:
	None
  ***************************************************************************/
void UDPPerformanceTask(void)
{
	UDP_SOCKET	MySocket;
	NODE_INFO	Remote;
	WORD		wTemp;
	static DWORD dwCounter = 1;

	if((BUTTON3_IO) && (dwCounter > 1024))
		return;

	// Suppress transmissions if we don't have an Ethernet link so our counter starts correctly at 0x00000001
	if(!MACIsLinked())
		return;
	
	// Set the socket's destination to be a broadcast over our IP 
	// subnet
	// Set the MAC destination to be a broadcast
	memset(&Remote, 0xFF, sizeof(Remote));
	
	// Open a UDP socket for outbound transmission
	MySocket = UDPOpen(0, &Remote, PERFORMANCE_PORT);
	
	// Abort operation if no UDP sockets are available
	// If this ever happens, incrementing MAX_UDP_SOCKETS in 
	// StackTsk.h may help (at the expense of more global memory 
	// resources).
	if(MySocket == INVALID_UDP_SOCKET)
		return;
	
	// Make certain the socket can be written to
	if(!UDPIsPutReady(MySocket))
	{
		UDPClose(MySocket);
		return;
	}
	
	// Put counter value into first 4 bytes of the packet
	UDPPutArray((BYTE*)&dwCounter, sizeof(dwCounter));
	dwCounter++;
	
	wTemp = UDPPutROMArray((ROM BYTE*)
			"The quick brown fox tried to jump over the yellow dog.  Unfortunately, the yellow dog stood up while the fox was in mid-jump.  As a result, the two collided.  Then, the dog, being the omnivore that it is, ate the quick brown fox.  This line is 256 bytes.\r\n"
			"The quick brown fox tried to jump over the yellow dog.  Unfortunately, the yellow dog stood up while the fox was in mid-jump.  As a result, the two collided.  Then, the dog, being the omnivore that it is, ate the quick brown fox.  This line is 256 bytes.\r\n"
			"The quick brown fox tried to jump over the yellow dog.  Unfortunately, the yellow dog stood up while the fox was in mid-jump.  As a result, the two collided.  Then, the dog, being the omnivore that it is, ate the quick brown fox.  This line is 256 bytes.\r\n"
			"The quick brown fox tried to jump over the yellow dog.  Unfortunately, the yellow dog stood up while the fox was in mid-jump.  As a result, the two collided.  Then, the dog, being the omnivore that it is, ate the quick brown fox.  This line is 252b. \r\n", 1020);

	// Send the packet
	UDPFlush();
	
	// Close the socket so it can be used by other modules
	UDPClose(MySocket);
}
Example #12
0
/// @cond debug
int cUDPWrite()
{
	//reads udp data and adds in ring buffer
	if ( UDPIsPutReady(udpSocket[callbackUdpSocket-1]) )
	{
		udpWord = UDPPutArray(udpByte,udpInt);
		UDPFlush();
		return 0;
	} else {
		udpWord = 0;
		return 1; //error
	}
}
Example #13
0
static void _TFTPSendAck(WORD_VAL blockNumber)
{
    // Write opCode.
    UDPPut(0);
    UDPPut(TFTP_OPCODE_ACK);

    // Write block number for this ack.
    UDPPut(blockNumber.byte.MSB);
    UDPPut(blockNumber.byte.LSB);

    // Transmit it.
    UDPFlush();
}
Example #14
0
/*********************************************************************
 * Function:        void TFTPCloseFile(void)
 *
 * Summary:         Sends file closing messages.
 *
 * PreCondition:    TFTPOpenFile() was called and TFTPIsFileOpened()
 *                  had returned with TFTP_OK.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        If file is opened in read mode, it makes sure
 *                  that last ACK is sent to server
 *                  If file is opened in write mode, it makes sure
 *                  that last block is sent out to server and
 *                  waits for server to respond with ACK.
 *
 * Note:            TFTPIsFileClosed() must be called to confirm
 *                  if file was really closed.
 ********************************************************************/
void TFTPCloseFile(void)
{
    // If a file was opened for read, we can close it immediately.
    if ( _tftpFlags.bits.bIsReading )
    {
        // If this was premature close, make sure that we discard
        // current block.
        if ( !_tftpFlags.bits.bIsFlushed )
        {
            _tftpFlags.bits.bIsFlushed = TRUE;
            UDPIsGetReady(_tftpSocket);
            UDPDiscard();
        }

        if ( _tftpFlags.bits.bIsAcked )
        {
            _tftpFlags.bits.bIsClosed = TRUE;
            _tftpFlags.bits.bIsClosing = FALSE;
            return;
        }

        else
        {
            _tftpState = SM_TFTP_SEND_LAST_ACK;
            _tftpFlags.bits.bIsClosing = TRUE;
        }
        return;
    }

    // For write mode, if we have not flushed last block, do it now.
    if ( !_tftpFlags.bits.bIsFlushed )
    {
        _tftpFlags.bits.bIsFlushed = TRUE;
        UDPIsPutReady(_tftpSocket);
        UDPFlush();
    }

    // For write mode, if our last block was ack'ed by remote server,
    // file is said to be closed.
    if ( _tftpFlags.bits.bIsAcked )
    {
        _tftpFlags.bits.bIsClosed = TRUE;
        _tftpFlags.bits.bIsClosing = FALSE;
        return;
    }

    _tftpState = SM_TFTP_WAIT_FOR_ACK;
    _tftpFlags.bits.bIsClosing =  TRUE;

}
Example #15
0
/**
 * Given data byte is put into the UDP transmit buffer and active UDP socket buffer
 * length is incremented. The data is NOT sent yet, and the UDPFlush() function must
 * be called to send all data contained in the transmit buffer.
 *
 * If the transmit buffer filled up, the contents of the transmit buffer will be sent,
 * and this function will return FALSE. In this case, it is VERY IMPORTANT to call the
 * UDPIsPutReady() function again before calling the UDPPut() or UDPPutArray() functions!
 *
 * Note: This function loads data into an active UDP socket as determined by previous
 * call to UDPIsPutReady().
 *
 * @preCondition    UDPIsPutReady() == TRUE with desired UDP socket
 *                  that is to be loaded.
 *
 * @param v       - Data byte to loaded into transmit buffer
 *
 * @return          TRUE if transmit buffer is still ready to accept more data bytes <br>
 *                  FALSE if transmit buffer can no longer accept any more data byte.<br>
 *                  If FALSE is returned, then UDPIsPutReady() has to be called again before
 *                  calling the UDPPut() or UDPPutArray() functions!
 */
BOOL UDPPut(BYTE v)
{
    UDP_SOCKET_INFO *p;

    p = &UDPSocketInfo[activeUDPSocket];

    //This UDP Socket does not contain any unsent data, and currently does not own a TX Buffer!
    //Assign it the next available TX Buffer
    if ( p->TxCount == 0 )
    {
        // This is the very first byte that is loaded in UDP buffer.
        // Remember what transmit buffer we are loading, and
        // start loading this and next bytes in data area of UDP packet.
        p->TxBuffer = MACGetTxBuffer(TRUE);

        // Make sure that we received a TX buffer
        if(p->TxBuffer == INVALID_BUFFER)
            return FALSE;

        //This sets the current TX Buffer pointer to the given offset after the IP header.
        //We give the size of the UDP header here as a parameter. This causes the current
        //write pointer to be set to firt byte after the UDP header, which is the UDP data area.
        IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER));
	    udpChecksum = 0;
        //p->TxOffset = 0;  /* TxOffset is not required! */
    }

    //Load it.
    MACPut(v);
	if (p->TxCount & 1) {
		udpChecksum += v;
		} else
		{
		udpChecksum += ((WORD)v << 8);
		}
    //Keep track of number of bytes loaded.
    //If total bytes fill up buffer, transmit it.
    p->TxCount++;

    if ( p->TxCount >= UDPGetMaxDataLength() )
    {
        UDPFlush();
		udpChecksum = 0;
    }
    
    return TRUE;
}
Example #16
0
ssize_t microchip_udp_write(UDP_SOCKET socket, const uint8_t* buf, size_t len, uint32_t addr, uint16_t port) {
    NODE_INFO remoteInfo;
    ssize_t size;
    uint32_t addrNetworkOrder;
#if NABTO_LOG_CHECK(NABTO_LOG_SEVERITY_TRACE)
    UDP_SOCKET_INFO* debug;
    uint32_t sourceIp;
#endif

    if (addr == 0 || port == 0) {
        return 0;
    }
    
    WRITE_U32(&addrNetworkOrder, addr);

    if (unabto_microchip_arp_resolve(addrNetworkOrder, &remoteInfo.MACAddr)) {
        remoteInfo.IPAddr.Val = addrNetworkOrder;
        memcpy((void*) &UDPSocketInfo[socket].remote.remoteNode, (void*) &remoteInfo, sizeof (NODE_INFO));
    } else {
        if (UDPSocketInfo[socket].remote.remoteNode.IPAddr.Val != addrNetworkOrder) {
            return 0;
        }
        // the arp resolve is not finished but the socket already knows
        // a mac address, lets just use it.
    }
    if (UDPIsPutReady(socket) >= len) {
#if NABTO_LOG_CHECK(NABTO_LOG_SEVERITY_TRACE)
        debug = &UDPSocketInfo[socket];
        READ_U32(sourceIp, &debug->remote.remoteNode.IPAddr.Val);
#endif

        UDPSocketInfo[socket].remotePort = port;
        size = (ssize_t) UDPPutArray((BYTE*) buf, len);
        UDPFlush();
        NABTO_LOG_TRACE(("UDP write length: %i, %" PRIu16 " -> " PRIip ":%" PRIu16, size, debug->localPort, MAKE_IP_PRINTABLE(sourceIp), debug->remotePort));

        NABTO_LOG_BUFFER(NABTO_LOG_SEVERITY_TRACE, ("UDP out datagram"), buf, len);

        return size;
    } else {
        NABTO_LOG_TRACE(("Socket was not put ready %i", socket));
    }

    return 0;
}
Example #17
0
int8_t vscp_sendUDPEvent( PVSCPMSG pmsg )
{
    int i;

    if ( UDPIsPutReady( vscp_udp_transmitsocket ) ) {

        pmsg->crc = crcSlow( (unsigned char *)pmsg, sizeof( vscpMsg ) - 2  );

        UDPPut( pmsg->head );

        UDPPut( ( pmsg->vscp_class >> 8 ) & 0xff );
        UDPPut( pmsg->vscp_class & 0xff );

        UDPPut( ( pmsg->vscp_type >> 8 ) & 0xff );
        UDPPut( pmsg->vscp_type & 0xff );

        for ( i=0; i<16; i++ ) {
            UDPPut( vscp_getGUID( i ) );
        }

        UDPPut( ( pmsg->sizeData >> 8 ) & 0xff );
        UDPPut( pmsg->sizeData & 0xff );

        for ( i=0; i<pmsg->sizeData; i++ ) {
            UDPPut( pmsg->data[ i ] );
        }

        UDPPut( ( pmsg->crc >> 8 ) & 0xff );
        UDPPut( pmsg->crc & 0xff );

        UDPFlush();
        return TRUE;
    }

    return FALSE;
}
Example #18
0
/*****************************************************************************
  Function:
	static void DHCPReplyToDiscovery(BOOTP_HEADER *Header, int netIx)

  Summary:
	Replies to a DHCP Discover message.

  Description:
	This function replies to a DHCP Discover message by sending out a 
	DHCP Offer message.

  Precondition:
	None

  Parameters:
	Header - the BootP header this is in response to.
    netIx   - interface index

  Returns:
  	None
  ***************************************************************************/
static void DHCPReplyToDiscovery(BOOTP_HEADER *Header, int netIx)
{
	uint8_t         i;
    NET_CONFIG*     pConfig;
    UDP_SOCKET      s;
    
	// Set the correct socket to active and ensure that 
	// enough space is available to generate the DHCP response
    s = MySocket[netIx];
    if(UDPIsPutReady(s) < 300u)
		return;

    pConfig = UDPSocketGetNet(s);

	// Begin putting the BOOTP Header and DHCP options
	UDPPut(s, BOOT_REPLY);			// Message Type: 2 (BOOTP Reply)
	// Reply with the same Hardware Type, Hardware Address Length, Hops, and Transaction ID fields
	UDPPutArray(s, (uint8_t*)&(Header->HardwareType), 7);
	UDPPut(s, 0x00);				// Seconds Elapsed: 0 (Not used)
	UDPPut(s, 0x00);				// Seconds Elapsed: 0 (Not used)
	UDPPutArray(s, (uint8_t*)&(Header->BootpFlags), sizeof(Header->BootpFlags));
	UDPPut(s, 0x00);				// Your (client) IP Address: 0.0.0.0 (none yet assigned)
	UDPPut(s, 0x00);				// Your (client) IP Address: 0.0.0.0 (none yet assigned)
	UDPPut(s, 0x00);				// Your (client) IP Address: 0.0.0.0 (none yet assigned)
	UDPPut(s, 0x00);				// Your (client) IP Address: 0.0.0.0 (none yet assigned)
	UDPPutArray(s, (uint8_t*)&DHCPNextLease[netIx], sizeof(IP_ADDR));	// Lease IP address to give out
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPutArray(s, (uint8_t*)&(Header->ClientMAC), sizeof(MAC_ADDR));	// Client MAC address: Same as given by client
	for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)	// Remaining 10 bytes of client hardware address, server host name: Null string (not used)
		UDPPut(s, 0x00);									// Boot filename: Null string (not used)
	UDPPut(s, 0x63);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x82);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x53);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x63);				// Magic Cookie: 0x63538263
	
	// Options: DHCP Offer
	UDPPut(s, DHCP_MESSAGE_TYPE);	
	UDPPut(s, 1);
	UDPPut(s, DHCP_OFFER_MESSAGE);

	// Option: Subnet Mask
	UDPPut(s, DHCP_SUBNET_MASK);
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyMask, sizeof(IP_ADDR));

	// Option: Lease duration
	UDPPut(s, DHCP_IP_LEASE_TIME);
	UDPPut(s, 4);
	UDPPut(s, (DHCP_LEASE_DURATION>>24) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION>>16) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION>>8) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION) & 0xFF);

	// Option: Server identifier
	UDPPut(s, DHCP_SERVER_IDENTIFIER);	
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// Option: Router/Gateway address
	UDPPut(s, DHCP_ROUTER);		
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// Option: DNS server address
	UDPPut(s, DHCP_DNS);
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// No more options, mark ending
	UDPPut(s, DHCP_END_OPTION);

	// Add zero padding to ensure compatibility with old BOOTP relays that discard small packets (<300 UDP octets)
	while(UDPGetTxCount(s) < 300u)
		UDPPut(s, 0); 

	// Force remote destination address to be the broadcast address, regardless 
	// of what the node's source IP address was (to ensure we don't try to 
	// unicast to 0.0.0.0).
	memset((void*)&UDPSocketDcpt[s].remoteNode, 0xFF, sizeof(NODE_INFO));

	// Transmit the packet
	UDPFlush(s);
}
Example #19
0
/*****************************************************************************
  Function:
	void DNSClientTask(void)

  Summary:
	DNS client state machine
	
  Description:
    Process the DNS client state machine
  
  Precondition:
	DNSClientInit has been called.

  Parameters:
    None
    
  Return Values:
    None

  ***************************************************************************/
void DNSClientTask(void)
{
	uint8_t 				i;
	TCPIP_UINT16_VAL			w;
	DNS_HEADER			DNSHeader;
	DNS_ANSWER_HEADER	DNSAnswerHeader;
    

    switch(smDNS)
	{
		case DNS_IDLE:
            break;  // nothing to do

		case DNS_START:
            smDNS = DNSRetry(DNS_START);
            stateStartTime = 0;  // flag the first Open try
			break;

		case DNS_OPEN_SOCKET:
            DNSSocket = UDPOpenClient(IP_ADDRESS_TYPE_IPV4, DNS_CLIENT_PORT, (IP_MULTI_ADDRESS*)(DNSServers + vDNSServerIx));
			if(DNSSocket == INVALID_UDP_SOCKET)
            {
                if(stateStartTime == 0)
                {
                    stateStartTime = SYS_TICK_Get();
                }
                else if(SYS_TICK_Get() - stateStartTime > (DNS_CLIENT_OPEN_TMO * SYS_TICK_TicksPerSecondGet()))
                {
					smDNS = DNS_FAIL_OPEN_TMO;
                }
                
                break;
            }
            
            // got a valid UDP socket
            UDPSocketSetNet(DNSSocket, pDNSNet);
            stateStartTime = SYS_TICK_Get();
            smDNS = DNS_QUERY;
            // no break, start sending the query;

		case DNS_QUERY:
            if(!UDPIsOpened(DNSSocket) || (UDPIsTxPutReady(DNSSocket, 18 + strlen (DNSHostName)) < (18 + strlen (DNSHostName))))
            {
                if(SYS_TICK_Get() - stateStartTime > (DNS_CLIENT_OPEN_TMO * SYS_TICK_TicksPerSecondGet()))
                {
					smDNS = DNS_FAIL_OPEN_TMO;
                }
                
				break;  // wait some more
            }
			
			// Put DNS query here
			SentTransactionID.Val = (uint16_t)rand();
			UDPPut(DNSSocket, SentTransactionID.v[1]);// User chosen transaction ID
			UDPPut(DNSSocket, SentTransactionID.v[0]);
			UDPPut(DNSSocket, 0x01);		// Standard query with recursion
			UDPPut(DNSSocket, 0x00);	
			UDPPut(DNSSocket, 0x00);		// 0x0001 questions
			UDPPut(DNSSocket, 0x01);
			UDPPut(DNSSocket, 0x00);		// 0x0000 answers
			UDPPut(DNSSocket, 0x00);
			UDPPut(DNSSocket, 0x00);		// 0x0000 name server resource records
			UDPPut(DNSSocket, 0x00);
			UDPPut(DNSSocket, 0x00);		// 0x0000 additional records
			UDPPut(DNSSocket, 0x00);

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

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

			UDPFlush(DNSSocket);
			stateStartTime = SYS_TICK_Get();
			smDNS = DNS_GET_RESULT;
			break;

		case DNS_GET_RESULT:
			if(!UDPIsGetReady(DNSSocket))
			{
				if(SYS_TICK_Get() - stateStartTime > (DNS_CLIENT_SERVER_TMO * SYS_TICK_TicksPerSecondGet()))
                {
					smDNS = DNS_FAIL_SERVER;
                }
				break;
			}


			// Retrieve the DNS header and de-big-endian it
			UDPGet(DNSSocket, &DNSHeader.TransactionID.v[1]);
			UDPGet(DNSSocket, &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(DNSSocket);
				break;
			}

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

			// Remove all questions (queries)
			while(DNSHeader.Questions.Val--)
			{
				DNSDiscardName(DNSSocket);
				UDPGet(DNSSocket, &w.v[1]);		// Question type
				UDPGet(DNSSocket, &w.v[0]);
				UDPGet(DNSSocket, &w.v[1]);		// Question class
				UDPGet(DNSSocket, &w.v[0]);
			}
			
			// Scan through answers
			while(DNSHeader.Answers.Val--)
			{				
				DNSDiscardName(DNSSocket);					// Throw away response name
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(DNSSocket, &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, MX, or AAAA
				if( DNSAnswerHeader.ResponseClass.Val	== 0x0001u) // Internet class
				{
                    if (DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
    					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
                    {
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV4;
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[0]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[1]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[2]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[3]);
    					goto DoneSearchingRecords;
                    }
                    else if (DNSAnswerHeader.ResponseType.Val == 0x001Cu &&
    					        DNSAnswerHeader.ResponseLen.Val	== 0x0010u)
                    {
                        if (RecordType != DNS_TYPE_AAAA)
                        {
        					while(DNSAnswerHeader.ResponseLen.Val--)
        					{
        						UDPGet(DNSSocket, &i);
        					}
                            break;
                        }
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV6;
                        UDPGetArray (DNSSocket, (void *)&ResolvedAddress.ipv6Address, sizeof (IPV6_ADDR));
    					goto DoneSearchingRecords;                        
                    }
                    else
                    {
    					while(DNSAnswerHeader.ResponseLen.Val--)
    					{
    						UDPGet(DNSSocket, &i);
    					}
                    }
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(DNSSocket, &i);
					}
				}
			}

			// Remove all Authoritative Records
			while(DNSHeader.AuthoritativeRecords.Val--)
			{
				DNSDiscardName(DNSSocket);					// Throw away response name
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(DNSSocket, &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.ResponseClass.Val	== 0x0001u) // Internet class
				{
                    if (DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
    					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
                    {
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV4;
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[0]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[1]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[2]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[3]);
    					goto DoneSearchingRecords;
                    }
                    else if (DNSAnswerHeader.ResponseType.Val == 0x001Cu &&
    					        DNSAnswerHeader.ResponseLen.Val	== 0x0010u)
                    {
                        if (RecordType != DNS_TYPE_AAAA)
                        {
        					while(DNSAnswerHeader.ResponseLen.Val--)
        					{
        						UDPGet(DNSSocket, &i);
        					}
                            break;
                        }
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV6;
                        UDPGetArray (DNSSocket, (void *)&ResolvedAddress.ipv6Address, sizeof (IPV6_ADDR));
    					goto DoneSearchingRecords;                        
                    }
                    else
                    {
    					while(DNSAnswerHeader.ResponseLen.Val--)
    					{
    						UDPGet(DNSSocket, &i);
    					}
                    }
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(DNSSocket, &i);
					}
				}
			}

			// Remove all Additional Records
			while(DNSHeader.AdditionalRecords.Val--)
			{
				DNSDiscardName(DNSSocket);					// Throw away response name
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[1]);		// Response type
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseType.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[1]);	// Response class
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseClass.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[3]);		// Time to live
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[2]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[1]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseTTL.v[0]);
				UDPGet(DNSSocket, &DNSAnswerHeader.ResponseLen.v[1]);		// Response length
				UDPGet(DNSSocket, &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.ResponseClass.Val	== 0x0001u) // Internet class
				{
                    if (DNSAnswerHeader.ResponseType.Val	== 0x0001u &&
    					DNSAnswerHeader.ResponseLen.Val		== 0x0004u)
                    {
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV4;
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[0]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[1]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[2]);
    					UDPGet(DNSSocket, &ResolvedAddress.ipv4Address.v[3]);
    					goto DoneSearchingRecords;
                    }
                    else if (DNSAnswerHeader.ResponseType.Val == 0x001Cu &&
    					        DNSAnswerHeader.ResponseLen.Val	== 0x0010u)
                    {
                        if (RecordType != DNS_TYPE_AAAA)
                        {
        					while(DNSAnswerHeader.ResponseLen.Val--)
        					{
        						UDPGet(DNSSocket, &i);
        					}
                            break;
                        }
    					Flags.bits.AddressValid = true;
                        Flags.bits.AddressType = IP_ADDRESS_TYPE_IPV6;
                        UDPGetArray (DNSSocket, (void *)&ResolvedAddress.ipv6Address, sizeof (IPV6_ADDR));
    					goto DoneSearchingRecords;                        
                    }
                    else
                    {
    					while(DNSAnswerHeader.ResponseLen.Val--)
    					{
    						UDPGet(DNSSocket, &i);
    					}
                    }
				}
				else
				{
					while(DNSAnswerHeader.ResponseLen.Val--)
					{
						UDPGet(DNSSocket, &i);
					}
				}
			}

DoneSearchingRecords:

			UDPDiscard(DNSSocket);
            _DNSReleaseSocket();
			if(Flags.bits.AddressValid)
            {
                smDNS = DNS_DONE;
            }
            else
            {
                smDNS = DNSRetry(DNS_FAIL_SERVER);
            }
            break;  // done
            
		case DNS_FAIL_ARP:
            // see if there is other server we may try
            smDNS = DNSRetry(DNS_FAIL_ARP);
            break;

		case DNS_FAIL_SERVER:
            smDNS = DNSRetry(DNS_FAIL_SERVER);
			break;

        default:    // DNS_DONE, DNS_FAIL_ARP_TMO, DNS_FAIL_OPEN_TMO, DNS_FAIL_SERVER_TMO  
            // either done or some error state
            break;
	}
    
#if DNS_CLIENT_VERSION_NO >= 2
    dnsTickPending = 0;
#endif  // DNS_CLIENT_VERSION_NO >= 2
}
Example #20
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;
   }
}
Example #21
0
/*********************************************************************
 * Function:        BOOL UDPPut(BYTE v)
 *
 * PreCondition:    UDPIsPutReady() == TRUE with desired UDP socket
 *                  that is to be loaded.
 *
 * Input:           v       - Data byte to loaded into transmit buffer
 *
 * Output:          TRUE if transmit buffer is still ready to accept
 *                  more data bytes
 *
 *                  FALSE if transmit buffer can no longer accept
 *                  any more data byte.
 *
 * Side Effects:    None
 *
 * Overview:        Given data byte is put into UDP transmit buffer
 *                  and active UDP socket buffer length is incremented
 *                  by one.
 *                  If buffer has become full, FALSE is returned.
 *                  Or else TRUE is returned.
 *
 * Note:            This function loads data into an active UDP socket
 *                  as determined by previous call to UDPIsPutReady()
 ********************************************************************/
BOOL UDPPut(BYTE v)
{
    UDP_SOCKET_INFO *p;
    WORD temp;
    WORD tempOffset;
    WORD tempCount;

    p = &UDPSocketInfo[activeUDPSocket];

    tempCount=p->TxCount;

    if ( tempCount == 0 )
    {
        // This is the very first byte that is loaded in UDP buffer.
        // Remember what transmit buffer we are loading, and
        // start loading this and next bytes in data area of UDP packet.
        p->TxBuffer = MACGetTxBuffer(TRUE);

      // Make sure that we received a TX buffer
      if(p->TxBuffer == INVALID_BUFFER)
         return FALSE;

        IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER));

        p->TxOffset = 0;
    }

    tempOffset=p->TxOffset;

   /*if (v>=0x20)
      debug_udp("-%c", v);
   else
      debug_udp("-0x%X", v);*/
      
    // Load it.
    MACPut(v);

    // Keep track of number of bytes loaded.
    // If total bytes fill up buffer, transmit it.
    if (tempOffset >= tempCount)
    {
      tempCount++;
    }
    tempOffset++;

    /* //broken in ccs?
    if ( p->TxOffset++ >= p->TxCount )
    {
        p->TxCount++;
        debug_udp("!");
    }
    */



#define SIZEOF_MAC_HEADER       (14)

    // Depending on what communication media is used, allowable UDP
    // data length will vary.
#if STACK_USE_SLIP
#define MAX_UDP_DATA  (MAC_TX_BUFFER_SIZE - SIZEOF_MAC_HEADER - sizeof(IP_HEADER) - sizeof(UDP_HEADER))
#else
#define MAX_UDP_DATA  (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) )
#endif

   p->TxOffset = tempOffset;

    //temp = p->TxCount;
    //if ( temp >= MAX_UDP_DATA )
    p->TxCount = tempCount;
    if (tempCount >= MAX_UDP_DATA)
    {
        UDPFlush();
    }
#undef MAX_UDP_DATA


    return TRUE;
}
Example #22
0
File: DNS.c Project: 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;
}
Example #23
0
//
// Main application entry point.
//
int main(void)
{

#if defined(HOST_CM_TEST)
    DWORD t1 = 0;
    char st[80];
    BOOL host_scan = FALSE;
    UINT16 scan_count = 0;
#endif

    static IPV4_ADDR dwLastIP[sizeof (TCPIP_HOSTS_CONFIGURATION) / sizeof (*TCPIP_HOSTS_CONFIGURATION)];
    int i, nNets;

#if defined(SYS_USERIO_ENABLE)    
    static SYS_TICK startTick = 0;
    int32_t LEDstate=SYS_USERIO_LED_DEASSERTED;
#endif  // defined(SYS_USERIO_ENABLE)

    TCPIP_NET_HANDLE netH;
    const char  *netName=0;
    const char  *netBiosName;

#if defined (TCPIP_STACK_USE_ZEROCONF_MDNS_SD)
    char mDNSServiceName[] = "MyWebServiceNameX ";     // base name of the service Must not exceed 16 bytes long
                                                       // the last digit will be incremented by interface
#endif  // defined (TCPIP_STACK_USE_ZEROCONF_MDNS_SD)

    // perform system initialization
    if(!SYS_Initialize())
    {
        return 0;
    }


    SYS_CONSOLE_MESSAGE("\r\n\n\n ---  TCPIP Demo Starts!  --- \r\n");
    SYS_OUT_MESSAGE("TCPIPStack " TCPIP_STACK_VERSION "  ""                ");

    // Initialize the TCPIP stack
    if (!TCPIP_STACK_Init(TCPIP_HOSTS_CONFIGURATION, sizeof (TCPIP_HOSTS_CONFIGURATION) / sizeof (*TCPIP_HOSTS_CONFIGURATION),
            TCPIP_STACK_MODULE_CONFIG_TBL, sizeof (TCPIP_STACK_MODULE_CONFIG_TBL) / sizeof (*TCPIP_STACK_MODULE_CONFIG_TBL)))
    {
        return 0;
    }

    // Display the names associated with each interface
    // Perform mDNS registration if mDNS is enabled
    nNets = TCPIP_STACK_NetworksNo();
    for(i = 0; i < nNets; i++)
    {
        netH = TCPIP_STACK_IxToNet(i);
        netName = TCPIP_STACK_NetName(netH);
        netBiosName = TCPIP_STACK_NetBIOSName(netH);

#if defined(TCPIP_STACK_USE_NBNS)
        SYS_CONSOLE_PRINT("    Interface %s on host %s - NBNS enabled\r\n", netName, netBiosName);
#else
        SYS_CONSOLE_PRINT("    Interface %s on host %s - NBNS disabled\r\n", netName, netBiosName);
#endif  // defined(TCPIP_STACK_USE_NBNS)

#if defined (TCPIP_STACK_USE_ZEROCONF_MDNS_SD)
        mDNSServiceName[sizeof(mDNSServiceName) - 2] = '1' + i;
        mDNSServiceRegister( netH
            , mDNSServiceName                   // name of the service
            ,"_http._tcp.local"                 // type of the service
            ,80                                 // TCP or UDP port, at which this service is available
            ,((const BYTE *)"path=/index.htm")  // TXT info
            ,1                                  // auto rename the service when if needed
            ,NULL                               // no callback function
            ,NULL);                             // no application context
#endif //TCPIP_STACK_USE_ZEROCONF_MDNS_SD
    }

#if defined (TCPIP_STACK_USE_IPV6)
    TCPIP_ICMPV6_RegisterCallback(ICMPv6Callback);
#endif

#if defined(TCPIP_STACK_USE_ICMP_CLIENT)
    ICMPRegisterCallback(PingProcessIPv4);
#endif


#if defined(TCPIP_STACK_USE_EVENT_NOTIFICATION)
    TCPIP_NET_HANDLE hWiFi = TCPIP_STACK_NetHandle("MRF24W");
    if (hWiFi)
    {
       TCPIP_STACK_RegisterHandler(hWiFi, TCPIP_EV_RX_ALL | TCPIP_EV_TX_ALL | TCPIP_EV_RXTX_ERRORS, StackNotification, 0);
    }
#endif  // defined(TCPIP_STACK_USE_EVENT_NOTIFICATION)

#if defined(WF_UPDATE_FIRMWARE_UART_24G)
    extern bool    WF_FirmwareUpdate_Uart_24G(void);
    WF_FirmwareUpdate_Uart_24G();
#endif

  

    // Now that all items are initialized, begin the co-operative
    // multitasking loop.  This infinite loop will continuously
    // execute all stack-related tasks, as well as your own
    // application's functions.  Custom functions should be added
    // at the end of this 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 be broken
    // down into smaller pieces so that other tasks can have CPU time.
    while (1)
    {
        SYS_Tasks();

       
#if defined(SYS_USERIO_ENABLE)    
        // Blink LED0 (right most one) every second.
        if (SYS_TICK_Get() - startTick >= SYS_TICK_TicksPerSecondGet() / 2ul)
        {
            startTick = SYS_TICK_Get();
            LEDstate ^= SYS_USERIO_LED_ASSERTED;
            SYS_USERIO_SetLED(SYS_USERIO_LED_0, LEDstate);
        }
#endif  // defined(SYS_USERIO_ENABLE)   

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

        // Process application specific tasks here.
        // For this demo app, this will include the Generic TCP
        // client and servers, and the SNMP, Ping, and SNMP Trap
        // demos.  Following that, we will process any IO from
        // the inputs on the board itself.
        // Any custom modules or processing you need to do should
        // go here.
#if defined(TCPIP_STACK_USE_TCP) && defined(APP_USE_FTP_CLIENT_DEMO)
        FTPClient();
#endif        
#if defined(TCPIP_STACK_USE_TCP) && defined(APP_USE_GENERIC_TCP_CLIENT_DEMO)
        GenericTCPClient();
#endif

#if defined(TCPIP_STACK_USE_TCP) && defined(APP_USE_GENERIC_TCP_SERVER_DEMO)
        GenericTCPServer();
#endif

#if defined(TCPIP_STACK_USE_SMTP_CLIENT) && defined(APP_USE_SMTP_CLIENT_DEMO)
        SMTPDemo();
#endif

#if (defined(TCPIP_STACK_USE_ICMP_CLIENT) || defined (TCPIP_STACK_USE_IPV6)) && defined(APP_USE_PING_DEMO)
        // use ping on the default interface
        PingDemoTask();
#endif

#if defined(TCPIP_STACK_USE_SNMP_SERVER) && !defined(SNMP_TRAP_DISABLED)

        // User should use one of the following SNMP demo
        // This routine demonstrates V1 or V2 trap formats with one variable binding.

        //SNMPTrapDemo(); //This function sends the both SNMP trap version1 and 2 type of notifications

        #if defined(SNMP_STACK_USE_V2_TRAP) || defined(SNMP_V1_V2_TRAP_WITH_SNMPV3)
        //This routine provides V2 format notifications with multiple (3) variable bindings
        //User should modify this routine to send v2 trap format notifications with the required varbinds.
            SNMPV2TrapDemo(); //This function sends the SNMP trap version 2 type of notifications
        #endif

         /*
         SNMPSendTrap() is used to send trap notification to previously configured ip address if trap notification is enabled.
         There are different trap notification code. The current implementation sends trap for authentication failure (4).
           PreCondition: If application defined event occurs to send the trap. Declare a notification flag and update as the event occurs.
           Uncomment the below function if the application requires.

         if(notification flag is updated by the application as a predefined event occured)
        {
            SNMPSendTrap();
        }

        */

#endif 


#if defined(TCPIP_STACK_USE_BERKELEY_API) && defined(APP_USE_BERKELEY_API_DEMO)
        BerkeleyTCPClientDemo();
        BerkeleyTCPServerDemo();
        BerkeleyUDPClientDemo(0);
#endif

        // If the local IP address has changed (ex: due to DHCP lease change)
        // write the new IP address to the console display, UART, and Announce
        // service
        // We use the default interface
        for (i = 0; i < sizeof (TCPIP_HOSTS_CONFIGURATION) / sizeof (*TCPIP_HOSTS_CONFIGURATION); i++)
        {
            netH = TCPIP_STACK_NetHandle(TCPIP_HOSTS_CONFIGURATION[i].interface);
            if ((uint32_t) dwLastIP[i].Val != TCPIP_STACK_NetAddress(netH))
            {
                dwLastIP[i].Val = TCPIP_STACK_NetAddress(netH);

                SYS_CONSOLE_PRINT("Interface Name is: %s\r\n", TCPIP_HOSTS_CONFIGURATION[i].interface);
                SYS_CONSOLE_MESSAGE("New IP Address is: "); DisplayIPValue(dwLastIP[i]);
                SYS_CONSOLE_MESSAGE("\r\n");
            }
        }

#if defined(TCPIP_STACK_USE_EVENT_NOTIFICATION)
        if (stackNotifyCnt)
        {
            stackNotifyCnt = 0;
            ProcessNotification(stackNotifyHandle);
        }
#endif  // defined(TCPIP_STACK_USE_EVENT_NOTIFICATION)

#if defined(WF_UPDATE_FIRMWARE_TCPCLIENT_24G)
    void WF_FirmwareUpdate_TcpClient_24G(void);
    WF_FirmwareUpdate_TcpClient_24G();
#endif //defined(WF_UPDATE_FIRMWARE_TCPCLIENT_24G)

#if defined(HOST_CM_TEST)
       switch (g_event)
        {
            case WF_EVENT_CONNECTION_PERMANENTLY_LOST:
            case WF_EVENT_CONNECTION_FAILED:
                g_event = 0xff;             // clear current event
                // if host scan is active, it can be forced inactive by connection/re-connection process
                // so just reset host scan state to inactive.
                host_scan = FALSE;          // host scan inactive
                SYS_CONSOLE_MESSAGE("Reconnecting....\r\n");
                WF_Connect();
                break;
            case WF_EVENT_CONNECTION_SUCCESSFUL:
                g_event = 0xff;             // clear current event
                // if host scan is active, it can be forced inactive by connection/re-connection process
                // so just reset host scan state to inactive.
                host_scan = FALSE;          // host scan inactive
                break;
            case WF_EVENT_SCAN_RESULTS_READY:
                g_event = 0xff;             // clear current event
                host_scan = FALSE;          // host scan inactive
                // Scan results are valid - OK to retrieve
                if (SCANCXT.numScanResults > 0)
                {
                    SCAN_SET_DISPLAY(SCANCXT.scanState);
                    SCANCXT.displayIdx = 0;
                    while (IS_SCAN_STATE_DISPLAY(SCANCXT.scanState))
                         WFDisplayScanMgr();
                }
                break;
           case WF_EVENT_CONNECTION_TEMPORARILY_LOST:
                // This event can happened when CM in module is enabled.
                g_event = 0xff;         // clear current event
                // if host scan is active, it can be forced inactive by connection/re-connection process
                // so just reset host scan state to inactive.
                host_scan = FALSE;      // host scan inactive
                break;
            default:
                //sprintf(st,"skip event = %d\r\n",g_event);
                //SYS_CONSOLE_MESSAGE(st);
                break;
        }

       if (g_DhcpSuccessful)
       {

       /* Send and Receive UDP packets */
        if(UDPIsOpened(socket1))
        {
            // UDP TX every 10 msec
            if(SYS_TICK_Get() - timeudp >= SYS_TICK_TicksPerSecondGet() / 100)
            {
                timeudp = SYS_TICK_Get();
                tx_number++;
                LED0_IO ^= 1;
                sprintf(str,"rem=%12lu",tx_number);
                for(cntstr=16;cntstr<999;cntstr++)
                    str[cntstr]=cntstr;
                str[999]=0;
                // Send tx_number (formatted in a string)
                if(UDPIsTxPutReady(socket1,1000)!=0)
                {
                    UDPPutString(socket1,(BYTE *)str);
                    UDPFlush(socket1);
                    SYS_CONSOLE_MESSAGE(".");
                }
            }

            // UDP RX tx_number of remote board
            if(UDPIsGetReady(socket1)!=0)
            {
                LED1_IO ^= 1;
                UDPGetArray(socket1,(BYTE *)str,1000);
                str[16]=0;
                //sprintf((char*)LCDText,"%sloc=%12lu",str,tx_number); // Write on EXP16 LCD local and remote TX number
                //strcpypgm2ram(LCDText,str);
                //LCDUpdate();
                SYS_CONSOLE_MESSAGE("Rx");

            }
        }

        // Do host scan
         if((SYS_TICK_Get() - t1) >= SYS_TICK_TicksPerSecondGet() * 20)
        {
            t1 = SYS_TICK_Get();
            if (!host_scan)             // allow host scan if currently inactive
            {
                sprintf(st,"%d Scanning ..... event = %d\r\n",++scan_count, g_event);
                SYS_CONSOLE_MESSAGE(st);
                host_scan = TRUE;       // host scan active
                WF_Scan(0xff);          // scan on all channels
            }
        }
       } // DHCP status
       
#endif  //HOST_CM_TEST


    }
}
void Diagnostic(void)
{
	switch (Diag_Comm2)
	{
		case	0	:	Pcomm_List = &Comm_List[0][0];			//Init pointers 1 time
						Pcomm_List2 = &Comm_List[0][0];
						Diag_Comm2 = 20;
						break;
						
		case	1	:	Pcomm_List2 = &Comm_List[0][0];
						if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[0]);
	            				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 2;
								break;
				   			}		
						}
						break;
						
		case	2	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[1]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 3;
								break;
		        			}		
							
						}
						break;
						
		case	3	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[2]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 4;
								break;
		        			}		
							
						}
						break;
		
		case	4	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[3]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 5;
								break;
		        			}		
							
						}
						break;
						
		case	5	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[4]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 6;
								break;
		        			}		
							
						}
						break;
						
		case	6	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[5]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 7;
								break;
		        			}		
							
						}
						break;
						
		case	7	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[6]);
		        				UDPFlush();
		        				Pcomm_List2+=4;
								Diag_Comm2 = 8;
								break;
		        			}		
							
						}
						break;
						
						
		case	8	:	if (Pcomm_List2 != Pcomm_List)
						{
							if(UDPIsPutReady(socket1))
            				{
	            				UDPPutString(Comm_List[7]);
		        				UDPFlush();
		        				Pcomm_List2 = &Comm_List[0][0];	// point to Comm_List[0]
								Diag_Comm2 = 1;
		        			}									
						}
						break; 
						
		case	20	:	if(!MACIsLinked())
						{
							return;
						}
						
						#if defined(STACK_USE_DHCP_CLIENT)
						{
							static DWORD dwTimer = 0;
							
							// Wait until DHCP module is finished
							if(!DHCPIsBound(0))
							{
								dwTimer = TickGet();
								return;
							}
					
							// Wait an additional half second after DHCP is finished to let the announce module and any other stack state machines to reach normal operation
							if(TickGet() - dwTimer < TICK_SECOND/2)
								return;
						}
						#endif
						Diag_Comm2 = 21;
						break;
						
		case	21	:	if (MAC_IP_READY == True)
						{
							TestTarget.MACAddr.v[0] = MACPC[0];//0x00;
							TestTarget.MACAddr.v[1] = MACPC[1];//0x0E;
							TestTarget.MACAddr.v[2] = MACPC[2];//0x0C;
							TestTarget.MACAddr.v[3] = MACPC[3];//0x74;
							TestTarget.MACAddr.v[4] = MACPC[4];//0xCC;
							TestTarget.MACAddr.v[5] = MACPC[5];//0x08;
							
							TestTarget.IPAddr.v[0] = IPPC[0];//192;
							TestTarget.IPAddr.v[1] = IPPC[1];//168; 
							TestTarget.IPAddr.v[2] = IPPC[2];//1;
							TestTarget.IPAddr.v[3] = IPPC[3];//24;
							
				            socket1 = UDPOpen(0x7000, &TestTarget, 0x7000);  //open the socket 
			            
				            if(socket1 == 0xFF) //Invalid socket
				            {
					            break;
					        }
					        else{Diag_Comm2 = 1;}
					 	}	      
				        break;
				        
		case	22	:	break;
						
		default		:	break;
	}
}
Example #25
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
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
Example #26
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;
	}
}
Example #27
0
/*********************************************************************
 * Function:        void DNSServerTask(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends dummy responses that point to ourself for DNS requests
 *
 * Note:            None
 ********************************************************************/
void DNSServerTask(void)
{
	static UDP_SOCKET	MySocket = INVALID_UDP_SOCKET;
	struct
	{
		WORD wTransactionID;
		WORD wFlags;
		WORD wQuestions;
		WORD wAnswerRRs;
		WORD wAuthorityRRs;
		WORD wAdditionalRRs;
	} DNSHeader;


	// Create a socket to listen on if this is the first time calling this function
	if(MySocket == INVALID_UDP_SOCKET)
	{
		//MySocket = UDPOpen(DNS_PORT, NULL, 0);
		
		MySocket = UDPOpenEx(0,UDP_OPEN_SERVER,DNS_PORT,0);
		return;
	}

	// See if a DNS query packet has arrived
	if(UDPIsGetReady(MySocket) < sizeof(DNSHeader))
		return;

	// Read DNS header
	UDPGetArray((BYTE*)&DNSHeader, sizeof(DNSHeader));

	// Ignore this packet if it isn't a query
	if((DNSHeader.wFlags & 0x8000) == 0x8000u)
		return;

	// Ignore this packet if there are no questions in it
	if(DNSHeader.wQuestions == 0u)
		return;

	// Block until we can transmit a DNS response packet
	while(!UDPIsPutReady(MySocket));

	// Write DNS response packet
	UDPPutArray((BYTE*)&DNSHeader.wTransactionID, 2);	// 2 byte Transaction ID
	if(DNSHeader.wFlags & 0x0100)
		UDPPut(0x81);	// Message is a response with recursion desired
	else
		UDPPut(0x80);	// Message is a response without recursion desired flag set
	UDPPut(0x80);	// Recursion available
	UDPPut(0x00);	// 0x0000 Questions
	UDPPut(0x00);
	UDPPut(0x00);	// 0x0001 Answers RRs
	UDPPut(0x01);
	UDPPut(0x00);	// 0x0000 Authority RRs
	UDPPut(0x00);
	UDPPut(0x00);	// 0x0000 Additional RRs
	UDPPut(0x00);
	DNSCopyRXNameToTX();	// Copy hostname of first question over to TX packet
	UDPPut(0x00);	// Type A Host address
	UDPPut(0x01);
	UDPPut(0x00);	// Class INternet
	UDPPut(0x01);
	UDPPut(0x00);	// Time to Live 10 seconds
	UDPPut(0x00);
	UDPPut(0x00);
	UDPPut(0x0A);
	UDPPut(0x00);	// Data Length 4 bytes
	UDPPut(0x04);
	UDPPutArray((BYTE*)&AppConfig.MyIPAddr.Val, 4);	// Our IP address
	#warning tim had added extra code here
	UDPFlush();
}
Example #28
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;
}
Example #29
0
bool NBNSTask(TCPIP_NET_IF* pNetIf)
{
	uint8_t 			i;
	TCPIP_UINT16_VAL    Type, Class;
	NBNS_HEADER			NBNSHeader;
	uint8_t				NameString[16];
    UDP_SOCKET          s;
    int                 nbnsRxSize;
    int                 nbnsTxSize;

    s = nbnsDcpt.uSkt;

	switch(nbnsDcpt.sm)
    {
        case NBNS_HOME:
            nbnsDcpt.sm++;
            break;

        case NBNS_OPEN_SOCKET:
            s = UDPOpenServer(IP_ADDRESS_TYPE_IPV4, NBNS_PORT, 0);
            if(s == INVALID_UDP_SOCKET)
                break;

            if(!UDPRemoteBind(s, IP_ADDRESS_TYPE_IPV4, NBNS_PORT,  0))
            {
                UDPClose(s);
                break;
            }

            nbnsDcpt.uSkt = s;
            nbnsDcpt.sm++;

        case NBNS_LISTEN:
            //if(!UDPIsGetReady(s))
            nbnsRxSize = UDPIsGetReady(s);
            if(!nbnsRxSize)
            {
                break;
            }


            // Respond only to name requests sent to us from nodes on the same subnet
            // This prevents us from sending out the wrong IP address information if 
            // we haven't gotten a DHCP lease yet.
            if((remoteNode.IPAddr.Val & pNetIf->netMask.Val) != (pNetIf->netIPAddr.Val & pNetIf->netMask.Val))
            {
                UDPDiscard(s);
                break;
            }

#ifdef _NBNS_DEBUG
            nbnsRxOks++;
            if(nbnsRxSize > nbnsRxMaxSize)
            {
                nbnsRxMaxSize = nbnsRxSize;
            }
#endif  // _NBNS_DEBUG
            // Retrieve the NBNS header and de-big-endian it
            UDPGet(s, &NBNSHeader.TransactionID.v[1]);
            UDPGet(s, &NBNSHeader.TransactionID.v[0]);
            UDPGet(s, &NBNSHeader.Flags.v[1]);
            UDPGet(s, &NBNSHeader.Flags.v[0]);
            UDPGet(s, &NBNSHeader.Questions.v[1]);
            UDPGet(s, &NBNSHeader.Questions.v[0]);
            UDPGet(s, &NBNSHeader.Answers.v[1]);
            UDPGet(s, &NBNSHeader.Answers.v[0]);
            UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[1]);
            UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[0]);
            UDPGet(s, &NBNSHeader.AdditionalRecords.v[1]);
            UDPGet(s, &NBNSHeader.AdditionalRecords.v[0]);

            // Remove all questions
            while(NBNSHeader.Questions.Val--)
            {
                NBNSGetName(s, NameString);
                UDPGet(s, &i);				// <??> Trailing character on string
                UDPGet(s, &Type.v[1]);		// Question type
                UDPGet(s, &Type.v[0]);
                UDPGet(s, &Class.v[1]);	// Question class
                UDPGet(s, &Class.v[0]);

                if(Type.Val == 0x0020u && Class.Val == 0x0001u)
                {
                    int nIfs, nIx;
                    TCPIP_NET_IF*   pIf;
                    const char*     netbName;

                    nIfs = TCPIP_STACK_NetworksNo();
                    for(nIx = 0; nIx < nIfs; nIx++)
                    { 
                        pIf = (TCPIP_NET_IF*)TCPIP_STACK_IxToNet(nIx); 
                        netbName = TCPIP_STACK_NetBIOSName(pIf);    // this checks the IF is up!
                        if(memcmp((void*)NameString, netbName, sizeof(pIf->NetBIOSName)) == 0)
                        {   // one of our interfaces has this name
                            nbnsTxSize = UDPIsTxPutReady(s, 64);
                            if(nbnsTxSize)
                            {   
#ifdef _NBNS_DEBUG
                                nbnsTxOks++;    
                                if(nbnsTxSize > nbnsTxMaxSize)
                                {
                                    nbnsTxMaxSize = nbnsTxSize;
                                }
#endif  // _NBNS_DEBUG

                                NBNSHeader.Flags.Val = 0x8400;

                                UDPPut(s, NBNSHeader.TransactionID.v[1]);
                                UDPPut(s, NBNSHeader.TransactionID.v[0]);
                                UDPPut(s, NBNSHeader.Flags.v[1]);
                                UDPPut(s, NBNSHeader.Flags.v[0]);
                                UDPPut(s, 0x00);	// 0x0000 Questions
                                UDPPut(s, 0x00);
                                UDPPut(s, 0x00);	// 0x0001 Answers
                                UDPPut(s, 0x01);
                                UDPPut(s, 0x00);	// 0x0000 Athoritative records
                                UDPPut(s, 0x00);
                                UDPPut(s, 0x00);	// 0x0000 Additional records
                                UDPPut(s, 0x00);

                                NBNSPutName(s, netbName);
                                UDPPut(s, 0x00);	// 0x0020 Type: NetBIOS
                                UDPPut(s, 0x20);
                                UDPPut(s, 0x00);	// 0x0001 Class: Internet
                                UDPPut(s, 0x01);
                                UDPPut(s, 0x00);	// 0x00000000 Time To Live
                                UDPPut(s, 0x00);
                                UDPPut(s, 0x00);
                                UDPPut(s, 0x00);

                                UDPPut(s, 0x00);	// 0x0006 Data length
                                UDPPut(s, 0x06);	
                                UDPPut(s, 0x60);	// 0x6000 Flags: H-node, Unique
                                UDPPut(s, 0x00);
                                UDPPut(s, pIf->netIPAddr.v[0]);	// Put out IP address
                                UDPPut(s, pIf->netIPAddr.v[1]);
                                UDPPut(s, pIf->netIPAddr.v[2]);
                                UDPPut(s, pIf->netIPAddr.v[3]);

                                // Change the destination address to the unicast address of the last received packet
                                UDPSetDestinationIPAddress(s, IP_ADDRESS_TYPE_IPV4, (IP_MULTI_ADDRESS*)&remoteNode.IPAddr);
                                memcpy((void*)&((IPV4_PACKET*)UDPSocketDcpt[s].pTxPkt)->remoteMACAddr, (const void*)&remoteNode.MACAddr, sizeof(remoteNode.MACAddr));
                                UDPFlush(s);				
                            }
#ifdef _NBNS_DEBUG
                            else
                            {
                                nbnsTxFails++;
                            }
#endif  // _NBNS_DEBUG
                            break;
                        }
                    }
                }
            }

            UDPDiscard(s);

            break;
    }

    return true;
}
Example #30
0
/*****************************************************************************
  Function:
	static void DHCPReplyToRequest(BOOTP_HEADER *Header, bool bAccept, int netIx)

  Summary:
	Replies to a DHCP Request message.

  Description:
	This function replies to a DHCP Request message by sending out a 
	DHCP Acknowledge message.

  Precondition:
	None

  Parameters:
	Header - the BootP header this is in response to.
	bAccept - whether or not we've accepted this request
    netIx   - interface index

  Returns:
  	None
  
  Internal:
	Needs to support more than one simultaneous lease in the future.
  ***************************************************************************/
static void DHCPReplyToRequest(BOOTP_HEADER *Header, bool bAccept, int netIx)
{
	uint8_t         i;
    NET_CONFIG*     pConfig;
    UDP_SOCKET      s;
    
	// Set the correct socket to active and ensure that 
	// enough space is available to generate the DHCP response
    s = MySocket[netIx];
    if(UDPIsPutReady(s) < 300u)
		return;
    
    pConfig = UDPSocketGetNet(s);

	// Search through all remaining options and look for the Requested IP address field
	// Obtain options
	while(UDPIsGetReady(s))
	{
		uint8_t Option, Len;
		uint32_t dw;

		// Get option type
		if(!UDPGet(s, &Option))
			break;
		if(Option == DHCP_END_OPTION)
			break;

		// Get option length
		UDPGet(s, &Len);

		// Process option
		if((Option == DHCP_PARAM_REQUEST_IP_ADDRESS) && (Len == 4u))
		{
			// Get the requested IP address and see if it is the one we have on offer.  If not, we should send back a NAK, but since there could be some other DHCP server offering this address, we'll just silently ignore this request.
			UDPGetArray(s, (uint8_t*)&dw, 4);
			Len -= 4;
			if(dw != DHCPNextLease[netIx].Val)
			{
				bAccept = false;
			}
			break;
		}

		// Remove the unprocessed bytes that we don't care about
		while(Len--)
		{
			UDPGet(s, &i);
		}
	}			

	// Begin putting the BOOTP Header and DHCP options
	UDPPut(s, BOOT_REPLY);			// Message Type: 2 (BOOTP Reply)
	// Reply with the same Hardware Type, Hardware Address Length, Hops, and Transaction ID fields
	UDPPutArray(s, (uint8_t*)&(Header->HardwareType), 7);
	UDPPut(s, 0x00);				// Seconds Elapsed: 0 (Not used)
	UDPPut(s, 0x00);				// Seconds Elapsed: 0 (Not used)
	UDPPutArray(s, (uint8_t*)&(Header->BootpFlags), sizeof(Header->BootpFlags));
	UDPPutArray(s, (uint8_t*)&(Header->ClientIP), sizeof(IP_ADDR));// Your (client) IP Address:
	UDPPutArray(s, (uint8_t*)&DHCPNextLease[netIx], sizeof(IP_ADDR));	// Lease IP address to give out
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Next Server IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPut(s, 0x00);				// Relay Agent IP Address: 0.0.0.0 (not used)
	UDPPutArray(s, (uint8_t*)&(Header->ClientMAC), sizeof(MAC_ADDR));	// Client MAC address: Same as given by client
	for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)	// Remaining 10 bytes of client hardware address, server host name: Null string (not used)
		UDPPut(s, 0x00);									// Boot filename: Null string (not used)
	UDPPut(s, 0x63);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x82);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x53);				// Magic Cookie: 0x63538263
	UDPPut(s, 0x63);				// Magic Cookie: 0x63538263
	
	// Options: DHCP lease ACKnowledge
	if(bAccept)
	{
		UDPPut(s, DHCP_OPTION_ACK_MESSAGE);	
		UDPPut(s, 1);
		UDPPut(s, DHCP_ACK_MESSAGE);
	}
	else	// Send a NACK
	{
		UDPPut(s, DHCP_OPTION_ACK_MESSAGE);	
		UDPPut(s, 1);
		UDPPut(s, DHCP_NAK_MESSAGE);
	}

	// Option: Lease duration
	UDPPut(s, DHCP_IP_LEASE_TIME);
	UDPPut(s, 4);
	UDPPut(s, (DHCP_LEASE_DURATION>>24) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION>>16) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION>>8) & 0xFF);
	UDPPut(s, (DHCP_LEASE_DURATION) & 0xFF);

	// Option: Server identifier
	UDPPut(s, DHCP_SERVER_IDENTIFIER);	
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// Option: Subnet Mask
	UDPPut(s, DHCP_SUBNET_MASK);
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyMask, sizeof(IP_ADDR));

	// Option: Router/Gateway address
	UDPPut(s, DHCP_ROUTER);		
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// Option: DNS server address
	UDPPut(s, DHCP_DNS);
	UDPPut(s, sizeof(IP_ADDR));
	UDPPutArray(s, (uint8_t*)&pConfig->MyIPAddr, sizeof(IP_ADDR));

	// No more options, mark ending
	UDPPut(s, DHCP_END_OPTION);

	// Add zero padding to ensure compatibility with old BOOTP relays that discard small packets (<300 UDP octets)
	while(UDPGetTxCount(s) < 300u)
		UDPPut(s, 0); 

	// Force remote destination address to be the broadcast address, regardless 
	// of what the node's source IP address was (to ensure we don't try to 
	// unicast to 0.0.0.0).
	memset((void*)&UDPSocketDcpt[s].remoteNode, 0xFF, sizeof(NODE_INFO));

	// Transmit the packet
	UDPFlush(s);
}