Example #1
0
/**
 * A ICMP packet is created and put on MAC.
 *
 * @preCondition ICMPIsTxReady() == TRUE
 *
 * @param remote    Remote node info
 * @param code      ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST
 * @param data      Data bytes
 * @param len       Number of bytes to send
 * @param id        ICMP identifier
 * @param seq       ICMP sequence number
 */
void ICMPPut(NODE_INFO *remote,
             ICMP_CODE code,
             BYTE *data,
             BYTE len,
             WORD id,
             WORD seq)
{
    ICMP_PACKET    packet;
    WORD ICMPLen;
    BUFFER MyTxBuffer;
    MyTxBuffer = MACGetTxBuffer(TRUE);

    // Abort if there is no where in the Ethernet controller to 
    // store this packet.
    if(MyTxBuffer == INVALID_BUFFER)
        return;

    IPSetTxBuffer(MyTxBuffer, 0);


    ICMPLen = ICMP_HEADER_SIZE + (WORD)len;

    packet.Code             = 0;
    packet.Type             = code;
    packet.Checksum         = 0;
    packet.Identifier       = id;
    packet.SequenceNumber   = seq;

    memcpy((void*)packet.Data, (void*)data, len);

    SwapICMPPacket(&packet);

#if defined(NON_MCHP_MAC)   //This is NOT a Microchip MAC
    packet.Checksum         = CalcIPChecksum((BYTE*)&packet,
                                    ICMPLen);
#endif

    IPPutHeader(remote,
                IP_PROT_ICMP,
                (WORD)(ICMP_HEADER_SIZE + len));

    IPPutArray((BYTE*)&packet, ICMPLen);

#if !defined(NON_MCHP_MAC)  //This is a Microchip MAC
    // Calculate and write the ICMP checksum using the Microchip MAC's DMA
    packet.Checksum = MACCalcTxChecksum(sizeof(IP_HEADER), ICMPLen);
    IPSetTxBuffer(MyTxBuffer, 2);
    MACPutArray((BYTE*)&packet.Checksum, 2);
#endif


    MACFlush();
}
Example #2
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 #3
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 #4
0
/*********************************************************************
 * Function:        BOOL UDPFlush(void)
 *
 * PreCondition:    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * Input:           None
 *
 * Output:          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            This function transmit all data from
 *                  an active UDP socket.
 ********************************************************************/
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    /*
     * When using SLIP (USART), packet transmission takes some time
     * and hence before sending another packet, we must make sure
     * that, last packet is transmitted.
     * When using ethernet controller, transmission occurs very fast
     * and by the time next packet is transmitted, previous is
     * transmitted and we do not need to check for last packet.
     */
    //while( !IPIsTxReady() );

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort        = swaps(p->localPort);
    h.DestinationPort   = swaps(p->remotePort);
    h.Length            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum          = 0x00;

    IPSetTxBuffer(p->TxBuffer, 0);

    /*
     * Load IP header.
     */
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length );


    // Now swap h.Length.
    h.Length            = swaps(h.Length);

    /*
     * Now load UDP header.
     */
    IPPutArray((BYTE*)&h, sizeof(h));

    /*
     * Update checksum.
     * TO BE IMPLEMENTED
     */

    MACFlush();

    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Example #5
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 #6
0
/**
 * This function transmit all data from the active UDP socket.
 *
 * @preCondition    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * @return          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 */
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    // Wait for TX hardware to become available (finish transmitting 
    // any previous packet)
    while( !IPIsTxReady(TRUE) ) FAST_USER_PROCESS();

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort.Val        = swaps(p->localPort);
    h.DestinationPort.Val   = swaps(p->remotePort);
    h.Length.Val            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum.Val      = 0x00;

    //Makes the given TX Buffer active, and set's the pointer to the first byte after the IP
    //header. This is the first byte of the UDP header. The UDP header follows the IP header.
    IPSetTxBuffer(p->TxBuffer, 0);

    //Load IP header.
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length.Val );


    //Now swap h.Length.Val
    h.Length.Val        = swaps(h.Length.Val);

    //Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

    //Update checksum. !!!!!!!!!!!!!!! TO BE IMPLEMENTED !!!!!!!!!!!!!!!!!!!

    //Send data contained in TX Buffer via MAC
    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately 
    // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Example #7
0
/*********************************************************************
 * Function:        BOOL UDPFlush(void)
 *
 * PreCondition:    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * Input:           None
 *
 * Output:          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            This function transmit all data from
 *                  an active UDP socket.
 ********************************************************************/
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;

    // Wait for TX hardware to become available (finish transmitting
    // any previous packet)
    while( !IPIsTxReady(TRUE) );

    p = &UDPSocketInfo[activeUDPSocket];

    debug_udp("\r\nUDP FLUSH - Sok:%U TxC:%LU SP:%LU DP:%LU ",
         activeUDPSocket,
         p->TxCount,
         p->localPort,
         p->remotePort
      );
    debug_udp("MAC-%X:%X:%X:%X:%X:%X",
         p->remoteNode.MACAddr.v[0],
         p->remoteNode.MACAddr.v[1],
         p->remoteNode.MACAddr.v[2],
         p->remoteNode.MACAddr.v[3],
         p->remoteNode.MACAddr.v[4],
         p->remoteNode.MACAddr.v[5]
      );


    h.SourcePort        = swaps(p->localPort);
    h.DestinationPort   = swaps(p->remotePort);
    h.Length            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum          = 0x0000;

    IPSetTxBuffer(p->TxBuffer, 0);

    /*
     * Load IP header.
     */

    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length );


    // Now swap h.Length.
    h.Length            = swaps(h.Length);

    // Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

     // Update checksum.
     // TO BE IMPLEMENTED

    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately
   // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Example #8
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 #9
0
/*****************************************************************************
  Function:
	void UDPSetTxBuffer(WORD wOffset)

  Summary:
	Moves the pointer within the TX buffer.
	
  Description:
	This function allows the write location within the TX buffer to be 
	specified.  Future calls to UDPPut, UDPPutArray, UDPPutString, etc will
	write data from the indicated location.

  Precondition:
	UDPInit() must have been previously called and a socket is currently 
	active.

  Parameters:
	wOffset - Offset from beginning of UDP packet data payload to place the
		write pointer.

  Returns:
  	None
  ***************************************************************************/
void UDPSetTxBuffer(WORD wOffset)
{
	IPSetTxBuffer(wOffset+sizeof(UDP_HEADER));
	wPutOffset = wOffset;
}
Example #10
0
/**
 * This function transmit all data from the active UDP socket.
 *
 * @preCondition    UDPPut() is already called and desired UDP socket
 *                  is set as an active socket by calling
 *                  UDPIsPutReady().
 *
 * @return          All and any data associated with active UDP socket
 *                  buffer is marked as ready for transmission.
 *
 */
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;
    WORD csLength;
	DWORD_VAL csChecksum;
    // Wait for TX hardware to become available (finish transmitting 
    // any previous packet)
    while( !IPIsTxReady(TRUE) ) FAST_USER_PROCESS();

    p = &UDPSocketInfo[activeUDPSocket];

    h.SourcePort.Val        = swaps(p->localPort);
    h.DestinationPort.Val   = swaps(p->remotePort);
    h.Length.Val            = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
    // Do not swap h.Length yet.  It is needed in IPPutHeader.
    h.Checksum.Val      = 0x00;

    //Makes the given TX Buffer active, and set's the pointer to the first byte after the IP
    //header. This is the first byte of the UDP header. The UDP header follows the IP header.
    IPSetTxBuffer(p->TxBuffer, 0);

    //Load IP header.
    IPPutHeader( &p->remoteNode,
                 IP_PROT_UDP,
                 h.Length.Val );

    // save length before swap for checksum calculation
    csLength			= p->TxCount;

    //Now swap h.Length.Val
    h.Length.Val        = swaps(h.Length.Val);

    //Now load UDP header.
    IPPutArray((BYTE*)&h, sizeof(h));

    //Update checksum. !!!!!!!!!!!!!!! TO BE IMPLEMENTED !!!!!!!!!!!!!!!!!!!
	// Update checksum.
    
	// start the checksum with value for UDP protocol & length from pseudo header (and in the actual packet)
	csChecksum.Val = (WORD)IP_PROT_UDP + (WORD)csLength + sizeof(UDP_HEADER);
	// add in my address and the remoteNode address
	csChecksum.Val += ((WORD)MY_IP_BYTE1 << 8) + MY_IP_BYTE2;
	csChecksum.Val += ((WORD)MY_IP_BYTE3 << 8) + MY_IP_BYTE4;
	csChecksum.Val += ((WORD)p->remoteNode.IPAddr.v[0] << 8) +  ((WORD)p->remoteNode.IPAddr.v[1] ) +
					  ((WORD)p->remoteNode.IPAddr.v[2] << 8) +  ((WORD)p->remoteNode.IPAddr.v[3] );
			

    // set mac pointer to the ip_addr of the source, so all of pseudo header but length is included.
    // length of pseudo header is already included in previous instruction.
    //MACSetRxBuffer( sizeof(IP_HEADER)+sizeof(UDP_HEADER) );
	

	csChecksum.Val += (WORD)p->localPort;
	csChecksum.Val += (WORD)p->remotePort;
	csChecksum.Val += (WORD)csLength + sizeof(UDP_HEADER);

	//IPSetRxBuffer(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) - ( sizeof(IP_ADDR) * 2 ) );
	
    // handled in UdpPut routines
	csChecksum.Val += udpChecksum;

	// add any carry over to the last word
	while((DWORD)csChecksum.word.MSW) {
		csChecksum.Val = (DWORD)csChecksum.word.LSW + (DWORD)csChecksum.word.MSW;
	}	
	// add any carry over from adding the carry over
	//csChecksum.Val = (DWORD)csChecksum.word.LSW + (DWORD)csChecksum.word.MSW;
	
	// invert
	csChecksum.Val = ~csChecksum.Val;
	
	// set write pointer to location of checksum in packet
	//MACSetWritePtr( sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER) - 2 );
	IPSetTxBuffer(p->TxBuffer,   sizeof(UDP_HEADER) - 2);
	// write the swapped checksum to the packet
	
	
	//MACPut(	csChecksum.v[1] );
	//MACPut(	csChecksum.v[0] );
	MACPut(0);
	MACPut(0);
    //Send data contained in TX Buffer via MAC
    MACFlush();

    // The buffer was reserved with AutoFree, so we can immediately 
    // discard it.  The MAC layer will free it after transmission.
    p->TxBuffer         = INVALID_BUFFER;
    p->TxCount          = 0;

}
Example #11
0
/*****************************************************************************
  Function:
    void UDPSetTxBuffer(uint16_t wOffset)

  Summary:
    Moves the pointer within the TX buffer.

  Description:
    This function allows the write location within the TX buffer to be
    specified.  Future calls to UDPPut, UDPPutArray, UDPPutString, etc will
    write data from the indicated location.

  Precondition:
    UDPInit() must have been previously called and a socket is currently
    active.

  Parameters:
    wOffset - Offset from beginning of UDP packet data payload to place the
        write pointer.

  Returns:
    None
  ***************************************************************************/
void UDPSetTxBuffer(uint16_t wOffset)
{
    IPSetTxBuffer(wOffset+sizeof(UDP_HEADER));
    wPutOffset = wOffset;
}