Exemple #1
0
int8_t vscp_udpinit( void )
{
    NODE_INFO remote_node;

    remote_node.IPAddr.v[ 0 ] = 0xff;	// Broadcast
    remote_node.IPAddr.v[ 1 ] = 0xff;
    remote_node.IPAddr.v[ 2 ] = 0xff;
    remote_node.IPAddr.v[ 3 ] = 0xff;
    remote_node.MACAddr.v[ 0 ] = 0xff;
    remote_node.MACAddr.v[ 1 ] = 0xff;
    remote_node.MACAddr.v[ 2 ] = 0xff;
    remote_node.MACAddr.v[ 3 ] = 0xff;
    remote_node.MACAddr.v[ 4 ] = 0xff;
    remote_node.MACAddr.v[ 5 ] = 0xff;

    // setup receive socket
    vscp_udp_receivesocket = UDPOpen( VSCP_LEVEL2_UDP_PORT, &remote_node, NULL );
    if ( INVALID_SOCKET == vscp_udp_receivesocket ) return FALSE;

    // Setup transmit socket
    vscp_udp_transmitsocket = UDPOpen( 30200, &remote_node, VSCP_LEVEL2_UDP_PORT );
    if ( INVALID_SOCKET == vscp_udp_transmitsocket ) {
        UDPClose( vscp_udp_receivesocket );
        return FALSE;
    }
}
Exemple #2
0
/***	void UdpServer::resumeListening(void)
**
**	Synopsis:   
**      Resumes listening on a UdpServer that did a StopListening
**
**	Parameters:
**      None
**
**	Return Values:
**      None
**
**	Errors:
**      None
**
**  Notes:
**
**      If StartListening was never called, this does nothing
**      If it is already listening, it does nothing
*/
void UdpServer::resumeListening(void)
{
    if(!_fStarted)
    {
        return;
    }

    // say we want to listen, may fail, but we will pick it up when we can.
    _fListening = true;

    // make sure we have room to to put our handle in
    if(_cPending >= _cPendingMax)
    {
        return;
    }

    // if we need to start listening on a socket
    if(_rghUDP[_cPending] >= INVALID_UDP_SOCKET)
    {
        // do not need to check to see if Ethernet is initialized because I can assign sockets before then
        _rghUDP[_cPending] = UDPOpen(_localPort, NULL, 0); 
    
        if(_rghUDP[_cPending] < INVALID_UDP_SOCKET)
        {
            // As for the iBuff, when we get data on the socket, the last entry 
            // will be where we put pending Client so just use this iBuff as the cache buffer
            ExchangeCacheBuffer(_rghUDP[_cPending], GetBufferLocation(_cPending), GetBufferSize());
        }
    }
}
Exemple #3
0
/****************************************************************************
  Function:
   UDP_SOCKET ChipKITUDPBegin(UDP_PORT localPort)

  Description:
    Implementes the Arduino UDP begin function.
 
  Parameters:
    localPort   - The port to start listening on.

  Returns:
    The socket that was opened, or INVALID_UDP_SOCKET if it couldn't get one

  Remarks:
    Creates a socket and starts listening on the specifed port.
    Note that Arduino never specifies an IP address with this, that
    is done on the individual send packetes.
    If there is not enough space for the socket cache, this API will fail
   
  ***************************************************************************/
UDP_SOCKET ChipKITUDPBegin(UDP_PORT localPort)
{
	UDP_SOCKET hUDP = INVALID_UDP_SOCKET;
    hUDP = UDPOpen(localPort, NULL, 0);

	if(hUDP < MAX_UDP_SOCKETS && rgUDPSocketBuffers[hUDP] == NULL)
	{
		rgUDPSocketBuffers[hUDP] = (UDPSB *) malloc(sizeof(UDPSB));	
		if(rgUDPSocketBuffers[hUDP] != NULL)
		{
			memset(rgUDPSocketBuffers[hUDP], 0, sizeof(sizeof(UDPSB)));
		}

		// no space for the buffer, no socket!
		else
		{
			UDPClose(hUDP);
			hUDP = INVALID_UDP_SOCKET;
		}
	}

    ChipKITPeriodicTasks();

    return(hUDP);
}
Exemple #4
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();
}
Exemple #5
0
//	UDPGenericOpen callback function
int cUDPGenericOpen()
{
	BYTE count = 0;
	UDP_SOCKET tmp_sock = INVALID_UDP_SOCKET;

	udpInt = 0;
	tmp_sock = UDPOpen(xUDPLocalPort, udpIPAddress, xUDPRemotePort);
	if (tmp_sock == INVALID_UDP_SOCKET)
	{
		callbackUdpSocket = 0;
		return 1; // Error;
	}
	else
	{
		numUdpSocket++;
		while (count < MAX_UDP_SOCKETS_FREERTOS)
		{
			if (udpSocket[count] == INVALID_UDP_SOCKET)
			{
				udpSocket[count] = tmp_sock;
				xUDPPort[count] = UDPSocketInfo[tmp_sock].localPort;
				count++;
				callbackUdpSocket = count;
				return 0; // Open succes
			}
			count++;
		}
		callbackUdpSocket = 0;
		return 1; //Error
	}
	
}
Exemple #6
0
/**
 * Initialize SNMP Daemon.
 * This should be called just one time at first time
 *
 * @param none
 * @return none
 */
void SnmpXDaemon_init()
{
	int32 snmpfd = 0;
	int32 fromlen = 0;
	int32 retStatus = 0;

	UNUSED(snmpfd);
	UNUSED(fromlen);
	UNUSED(retStatus);
	
    LOG("\r\n[SNMP : Start SNMP Daemon (Agent)]");
    
    SnmpXInit();
    
    /*
    // Example Codes for SNMP Trap
    {
		dataEntryType enterprise_oid = {8, {0x2b, 6, 1, 4, 1, 0, 0x10, 0}, SNMPDTYPE_OBJ_ID, 8, {"\x2b\x06\x01\x04\x01\x00\x10\x00"},	NULL, NULL};

		dataEntryType trap_oid1 = {8, {0x2b, 6, 1, 4, 1, 0, 11, 0}, SNMPDTYPE_OCTET_STRING, 30, {""}, NULL, NULL};
		dataEntryType trap_oid2 = {8, {0x2b, 6, 1, 4, 1, 0, 12, 0}, SNMPDTYPE_INTEGER, 4, {""}, NULL, NULL};

		strcpy((char *)trap_oid1.u.octetstring, "Alert!!!");
		trap_oid2.u.intval = 123456;
		
		//SnmpXTrapSend("222.98.173.250", "127.0.0.0", "public", enterprise_oid, 1, 0, 0);
		//SnmpXTrapSend("222.98.173.250", "127.0.0.0", "public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2);
		SnmpXTrapSend("192.168.11.250", "192.168.11.251", "public", enterprise_oid, 1, 0, 0);
		SnmpXTrapSend("192.168.11.250", "127.0.0.0", "public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2);
	}
    */
    
    UDPOpen(SOCK_SNMP, 161);
}
Exemple #7
0
void loopback_udp(uint8 ch, uint16 port)
{
    int ret;
    uint32 destip = 0;
    uint16 destport;

    ret = UDPRecv(ch, data_buf, TX_RX_MAX_BUF_SIZE, (uint8*)&destip, &destport);

    if(ret > 0) {				// Received
        ret = UDPSend(ch, data_buf, ret, (uint8*)&destip ,destport);

        if(ret == ERROR_TIME_OUT) {
            ERR("Timeout");
            UDPClose(ch);
            DBG("UDP Socket Close");
        }

    } else if(ret == ERROR_NOT_UDP_SOCKET) {	// Not UDP Socket, It's TCP Socket
        DBG("TCP Socket Close");
        TCPClose(ch);
    } else if(ret == ERROR_CLOSED) {		// Socket Closed
        LOGA("UDP Loop-Back Started - ch(%d)",(uint16)ch);
        UDPOpen(ch, port);
    }
}
/*****************************************************************************
  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);
}
Exemple #9
0
/*********************************************************************
 * Function:        void AnnounceIP(void)
 *
 * Summary:         Transmits an Announce packet.
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        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 MCHPDetect.exe
 *					program.
 *
 * Note:            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;
	
	// Open a UDP socket for outbound broadcast transmission
	MySocket = UDPOpen(2860, NULL, ANNOUNCE_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
	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);
}
Exemple #10
0
void act_nopen_a(int8 type,  int8 save, uint16 sport, uint8 *dip, uint16 dport)
{
	int8 ret, sock, i;

	for(i=ATC_SOCK_NUM_START; i<=ATC_SOCK_NUM_END; i++) {
		if(sockstat[i] != SOCK_STAT_IDLE && sockport[i] == sport) {
			DBGA("src port(%d) is using now by sock(%d)", sport, i);
			MAKE_TCMD_DIGIT(atci.tcmd.arg1, 2);
			CMD_RESP_RET(RET_WRONG_ARG, VAL_NONE);
		}
	}

	if(save == 'S' || save == 'A') {
		
	}

	if(save == 'O' || save == 'A') {
		if(type == 'S') {
			sock = sock_get(SOCK_STAT_TCP_SRV, sport);
			if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
			ret = TCPServerOpen(sock, sport);
			if(ret != RET_OK) CMD_RESP_RET(RET_UNSPECIFIED, VAL_NONE);
			sockwatch_set(sock, WATCH_SOCK_CONN_EVT);
			CMD_RESP_RET(RET_OK, sock);
		} else if(type == 'C') {
			sock = sock_get(SOCK_STAT_TCP_CLT, sport);
			if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
			ret = TCPCltOpenNB(sock, sport, dip, dport);
			if(ret != RET_OK) {
				DBGA("TCPCltOpenNB fail - ret(%d)", ret);
				CMD_RESP_RET(RET_WRONG_ADDR, VAL_NONE);
			}
			sockwatch_set(sock, WATCH_SOCK_CONN_TRY);
			sockbusy[sock] = VAL_TRUE;
			CMD_RESP_RET(RET_ASYNC, sock);
		} else {
			if(dip != NULL) {
				memcpy(udpip[sock], dip, 4);
				udpport[sock] = dport;
			}
			sock = sock_get(SOCK_STAT_UDP, sport);
			if(sock == RET_NOK) CMD_RESP_RET(RET_NO_SOCK, VAL_NONE);
			UDPOpen(sock, sport);
			sockwatch_set(sock, WATCH_SOCK_RECV);
			CMD_RESP_RET(RET_OK, sock);
		}
	}
}
Exemple #11
0
/*********************************************************************
 * Function:        TFTP_RESULT TFTPIsOpened(void)
 *
 * PreCondition:    TFTPOpen() is already called.
 *
 * Input:           None
 *
 * Output:          TFTP_OK if previous call to TFTPOpen is complete
 *
 *                  TFTP_TIMEOUT if remote host did not respond to
 *                          previous ARP request.
 *
 *                  TFTP_NOT_READY if remote has still not responded
 *                          and timeout has not expired.
 *
 * Side Effects:    None
 *
 * Overview:        Waits for ARP reply and opens a UDP socket
 *                  to perform further TFTP operations.
 *
 * Note:            Once opened, application may keep TFTP socket
 *                  open and future TFTP operations.
 *                  If TFTPClose() is called to close the connection
 *                  TFTPOpen() must be called again before performing
 *                  any other TFTP operations.
 ********************************************************************/
TFTP_RESULT TFTPIsOpened(void)
{
    switch(_tftpState)
    {
    default:
        DEBUG(printf("Resolving remote IP...\n"));

        // Check to see if adddress is resolved.
        if ( ARPIsResolved(&MutExVar.group1._hostInfo.IPAddr,
                           &MutExVar.group1._hostInfo.MACAddr) )
        {
            _tftpSocket = UDPOpen(TFTP_CLIENT_PORT,
                                  &MutExVar.group1._hostInfo,
                                  TFTP_SERVER_PORT);

            if( _tftpSocket == INVALID_UDP_SOCKET ) {
                #if (DEBUG_TFTPC >= LOG_ERROR)
                debugPutMsg(1); //@mxd:1:Could not open UDP socket
                #endif
            }

            _tftpState = SM_TFTP_READY;
        }
        else
            break;

    case SM_TFTP_READY:
        // Wait for UDP to be ready.  Immediately after this user will
        // may TFTPGetFile or TFTPPutFile and we have to make sure that
        // UDP is read to transmit.  These functions do not check for
        // UDP to get ready.
        if ( UDPIsPutReady(_tftpSocket) )
            return TFTP_OK;
    }

    // Make sure that we do not do this forever.
    if ( TickGetDiff(TickGet(), _tftpStartTick) >= TFTP_ARP_TIMEOUT_VAL )
    {
        _tftpStartTick = TickGet();

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

        return TFTP_TIMEOUT;
    }

    return TFTP_NOT_READY;
}
Exemple #12
0
/*********************************************************************
 * Function:        void RebootTask(NET_CONFIG* pConfig)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           pConfig   - interface 
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Checks for incomming traffic on port 69.  
 *					Resets the PIC if a 'R' is received.
 *
 * Note:            This module is primarily for use with the 
 *					Ethernet bootloader.  By resetting, the Ethernet 
 *					bootloader can take control for a second and let
 *					a firmware upgrade take place.
 ********************************************************************/
void RebootTask(NET_CONFIG* pConfig)
{
	struct
	{
		uint8_t vMACAddress[6];
		uint32_t dwIPAddress;
		uint16_t wChecksum;
	} BootloaderAddress;
    int netIx;

    netIx = _TCPIPStackNetIx(pConfig);

	
	if(MySocket[netIx] == INVALID_UDP_SOCKET)
    {
        MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,REBOOT_PORT,INVALID_UDP_PORT);

        if(MySocket[netIx] == INVALID_UDP_SOCKET)
        {
            return;
        }
        UDPSocketSetNet(MySocket[netIx], pConfig);
    }

	// Do nothing if no data is waiting
	if(!UDPIsGetReady(MySocket[netIx]))
		return;
    
	#if defined(REBOOT_SAME_SUBNET_ONLY)
		// Respond only to name requests sent to us from nodes on the same subnet
     	if((remoteNode.IPAddr.Val & pConfig->MyMask.Val) != (pConfig->MyIPAddr.Val & pConfig->MyMask.Val))
		{
			UDPDiscard(pConfig);
			return;
		}
	#endif

	// Get our MAC address, IP address, and compute a checksum of them 
	memcpy((void*)&BootloaderAddress.vMACAddress[0], (void*)&pConfig->MyMACAddr.v[0], sizeof(pConfig->MyMACAddr));
	BootloaderAddress.dwIPAddress = pConfig->MyIPAddr.Val;
	BootloaderAddress.wChecksum = CalcIPChecksum((uint8_t*)&BootloaderAddress, sizeof(BootloaderAddress) - sizeof(BootloaderAddress.wChecksum));
	
	// To enter the bootloader, we reset the system
	SYS_OUT_MESSAGE("Bootloader Reset");

	SYS_Reboot();
}
Exemple #13
0
/*****************************************************************************
  Function:
	int bind( SOCKET s, const struct sockaddr* name, int namelen )

  Summary:
	This function assigns a name to the socket descriptor.

  Description:
	The bind function assigns a name to an unnamed socket. The
    name represents the local address of the communication
    endpoint. For sockets of type SOCK_STREAM, the name of the
    remote endpoint is assigned when a connect or accept function
    is executed.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	name - pointer to the sockaddr structure containing the
	local address of the socket.
	namelen - length of the sockaddr structure.

  Returns:
	If bind is successful, a value of 0 is returned. A return
    value of SOCKET_ERROR indicates an error.

  Remarks:
	None.
  ***************************************************************************/
int bind( SOCKET s, const struct sockaddr* name, int namelen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *local_addr;
    WORD lPort;

    if( s >= BSD_SOCKET_COUNT )
        return SOCKET_ERROR;

    socket = &BSDSocketArray[s];

    if( socket->bsdState != SKT_CREATED ) //only work with recently created socket
        return SOCKET_ERROR;

    if( (unsigned int)namelen < sizeof(struct sockaddr_in) )
        return SOCKET_ERROR;

    local_addr = (struct sockaddr_in *)name;

    lPort = local_addr->sin_port;
    if( lPort == 0u ) //pick a port
    {
        lPort = gAutoPortNumber++;
        if(gAutoPortNumber > 5000u) // reset the port numbers
            gAutoPortNumber = 1024;
    }

    if(socket->SocketType == SOCK_DGRAM)
    {
        socket->SocketID = UDPOpen(lPort, NULL, 0);
        if(socket->SocketID == INVALID_UDP_SOCKET)
            return SOCKET_ERROR;
    }

    socket->localPort = lPort;
    socket->bsdState  = SKT_BOUND;
    return 0; //success
}
/*****************************************************************************
  Function:
	int recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen)

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

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

  Precondition:
	socket function should be called.

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

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

  Remarks:
	None.
  ***************************************************************************/
int recvfrom( SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *rem_addr;
    SOCKET_INFO *remoteSockInfo;
    
    socket = &BSDSocketArray[s];
    rem_addr = (struct sockaddr_in *)from;
    
    if(socket->SocketType == SOCK_DGRAM) //UDP
    {
        if(socket->bsdState != SKT_EST)
        {
            socket->SocketID = UDPOpen(socket->localPort, NULL, socket->localPort); //recieve on the same port.
            socket->bsdState = SKT_EST;
        }
        
        if(socket->bsdState == SKT_EST)
        {
            if(UDPIsGetReady(socket->SocketID) > 0)
            {
                return UDPGetArray((BYTE*)buf, len);
            }
        }
    }
    else  //TCP recieve from already connected socket.
    {
        if(from && fromlen && ((unsigned int)*fromlen >= sizeof(struct sockaddr_in)))
        {
            remoteSockInfo = TCPGetRemoteInfo(socket->SocketID);
            rem_addr->sin_addr.S_un.S_addr = remoteSockInfo->remote.IPAddr.Val;
            rem_addr->sin_port = remoteSockInfo->remotePort.Val;
            *fromlen = sizeof(struct sockaddr_in);
        }
        return recv(s, buf, len, 0);
    }
    return 0;
}
Exemple #15
0
/**
 * Initializes "UDP Command Port" and "UDP Event Port". These
 * ports are used for sending and receiving and commands via the UDP port.
 *
 */
void evtInit(void) {
    NODE_INFO udpServerNode;
    activeEventPorts = 0;
    
    //Initialize to idle state
    smEvt = SM_EVT_INIT;

    //Initialize remote IP and MAC address of udpServerNode with 0, seeing that we don't know them for the node
    //that will send us an UDP message. The first time a message is received addressed to this port, the
    //remote IP and MAC addresses are automatically updated with the addresses of the remote node.
    memclr(&udpServerNode, sizeof(udpServerNode));

    //Configure for local port 54124 and remote port INVALID_UDP_PORT. This opens the socket to
    //listen on the given port.
    udpSocketEvt = UDPOpen(EVENT_UDPPORT, &udpServerNode, INVALID_UDP_PORT);
    
    //An error occurred during the UDPOpen() function
    if (udpSocketEvt == INVALID_UDP_SOCKET) {
        #if (DEBUG_CMD >= LOG_ERROR)
        debugPutMsg(17);     //@mxd:17:Could not open UDP event port
        #endif
    }
}
Exemple #16
0
/*****************************************************************************
  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;
}
Exemple #17
0
static void dhcp_run(void)
{
	static bool udp_open_fail = FALSE;

	if(di.state == DHCP_STATE_INIT && di.action != DHCP_ACT_START) {
		DBG("wrong attempt");
		return;
	} else if(GetUDPSocketStatus(di.sock) == SOCKSTAT_CLOSED) {
		if(udp_open_fail == TRUE && !IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY)) 
			goto RET_ALARM;
		ClsNetInfo(NI_IP_ADDR);
		ClsNetInfo(NI_SN_MASK);
		ClsNetInfo(NI_GW_ADDR);
		ClsNetInfo(NI_DNS_ADDR);
		if(UDPOpen(di.sock, DHCP_CLIENT_PORT) == RET_OK) {
			if(dhcp_async) sockwatch_open(di.sock, dhcp_async_cb);
			udp_open_fail = FALSE;
			dhcp_run_tick = wizpf_get_systick();
			dhcp_run_cnt = 0;
		} else {
			ERR("UDPOpen fail");
			udp_open_fail = TRUE;
			dhcp_run_tick = wizpf_get_systick();
			goto RET_ALARM;
		}
	}

	switch(di.state) {
	case DHCP_STATE_INIT:
		if(dhcp_run_cnt==0 && !IS_TIME_PASSED(dhcp_run_tick, DHCP_OPEN_DELAY)) 
			goto RET_ALARM;

		if(dhcp_run_cnt < DHCP_SEND_RETRY_COUNT) {
			dhcp_run_cnt++;
			if(send_discover() == RET_OK) {	// Discover ok
				if(dhcp_async) {
					DBG("DHCP Discovery Send Async");
					sockwatch_set(di.sock, WATCH_SOCK_UDP_SEND);
					return;	// alarm set is not needed
				} else {
					DBG("DHCP Discovery Sent");
					SET_STATE(DHCP_STATE_SEARCHING);
					dhcp_run_tick = wizpf_get_systick();
				}
			} else {
				ERRA("DHCP Discovery SEND fail - (%d)times", dhcp_run_cnt);
				dhcp_run_tick = wizpf_get_systick();
			}
		} else {
			ERRA("DHCP Discovery SEND fail - (%d)times", dhcp_run_cnt);
			dhcp_run_cnt = 0;
			UDPClose(di.sock);
			if(dhcp_async) sockwatch_close(di.sock);
			dhcp_fail();
			return; // alarm set is not needed
		}
		break;
	case DHCP_STATE_SEARCHING:
		if(!IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY)) {
			int8 ret = recv_handler();
			if(ret == DHCP_MSG_OFFER) {
				SET_STATE(DHCP_STATE_SELECTING);
				dhcp_run_tick = wizpf_get_systick();
				dhcp_run_cnt = 0;
			} else if(ret != RET_NOK) DBGCRTCA(TRUE, "recv wrong packet(%d)", ret);
		} else {
			ERRA("DHCP Offer RECV fail - for (%d)msec", DHCP_RETRY_DELAY);
			SET_STATE(DHCP_STATE_INIT);
			dhcp_run_tick = wizpf_get_systick();
		}
		break;
	case DHCP_STATE_SELECTING:
		if(dhcp_run_cnt < DHCP_SEND_RETRY_COUNT) {
			dhcp_run_cnt++;
			if(send_request() == RET_OK) {	// Request ok
				if(dhcp_async) {
					DBG("DHCP Request Send Async");
					sockwatch_set(di.sock, WATCH_SOCK_UDP_SEND);
					return;	// alarm set is not needed
				} else {
					DBG("DHCP Request Sent");
					SET_STATE(DHCP_STATE_REQUESTING);
					dhcp_run_tick = wizpf_get_systick();
				}
			} else {
				ERRA("DHCP Request SEND fail - (%d)times", dhcp_run_cnt);
				dhcp_run_tick = wizpf_get_systick();
			}
		} else {
			ERRA("DHCP Request SEND fail - (%d)times", dhcp_run_cnt);
			dhcp_run_cnt = 0;
			UDPClose(di.sock);
			if(dhcp_async) sockwatch_close(di.sock);
			dhcp_fail();
			return; // alarm set is not needed
		}
		break;
	case DHCP_STATE_REQUESTING:
		if(!IS_TIME_PASSED(dhcp_run_tick, DHCP_RETRY_DELAY)) {
			int8 ret = recv_handler();
			if(ret == DHCP_MSG_ACK) {	// Recv ACK
				LOG("DHCP Success");
				SET_STATE(DHCP_STATE_IP_CHECK);
				dhcp_run_tick = wizpf_get_systick();
				dhcp_run_cnt = 0;
			} else if(ret == DHCP_MSG_NAK) {	// Recv NAK
				if(di.action == DHCP_ACT_START) {
					SET_STATE(DHCP_STATE_INIT);
					dhcp_run_tick = wizpf_get_systick();
				} else {
					SET_STATE(DHCP_STATE_BOUND);
				}
				dhcp_run_cnt = 0;
			} else if(ret != RET_NOK) DBGCRTCA(TRUE, "recv wrong packet(%d)", ret);
		} else {
			ERRA("DHCP ACK RECV fail - for (%d)msec", DHCP_RETRY_DELAY);
			if(di.action == DHCP_ACT_START) {
				SET_STATE(DHCP_STATE_INIT);
				dhcp_run_tick = wizpf_get_systick();
			} else {
				SET_STATE(DHCP_STATE_BOUND);
			}
		}
		break;
	case DHCP_STATE_IP_CHECK:
		//if(send_checker() == RET_OK) {
			SET_STATE(DHCP_STATE_BOUND);
			SetNetInfo(&workinfo);
			if(di.ip_update) di.ip_update();
			LOGA("DHCP ok - New IP (%d.%d.%d.%d)", 
				workinfo.ip[0], workinfo.ip[1], workinfo.ip[2], workinfo.ip[3]);
		//} else {
		//	SET_STATE(DHCP_STATE_INIT);
		//	ERR("IP Addr conflicted - IP(%d.%d.%d.%d)", workinfo.ip[0], workinfo.ip[1], workinfo.ip[2], workinfo.ip[3]);
		//	send_rel_dec(DHCP_MSG_DECLINE);
		//	if(di.ip_conflict) (*di.ip_conflict)();
		//}
		break;
	case DHCP_STATE_BOUND:
		di.action = DHCP_ACT_NONE;
		UDPClose(di.sock);
		if(dhcp_async) sockwatch_close(di.sock);
		return; // alarm set is not needed
	case DHCP_STATE_FAILED:
		return; // alarm set is not needed
	default:
		ERRA("wrong state(%d)", di.state);
		return; // alarm set is not needed
	}

RET_ALARM:
	if(dhcp_alarm) alarm_set(10, dhcp_alarm_cb, 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
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
}
Exemple #19
0
/*****************************************************************************
  Function:
	void DHCPServerTask(NET_CONFIG* pConfig)

  Summary:
	Performs periodic DHCP server tasks.

  Description:
	This function performs any periodic tasks requied by the DHCP server 
	module, such as processing DHCP requests and distributing IP addresses.

  Precondition:
	None

  Parameters:
	pConfig   - interface

  Returns:
  	None
  ***************************************************************************/
void DHCPServerTask(NET_CONFIG* pConfig)
{
	uint8_t 				i;
	uint8_t				Option, Len;
	BOOTP_HEADER		BOOTPHeader;
	uint32_t				dw;
	bool				bAccept;
    int                 netIx;
    UDP_SOCKET          s;
    

#if defined(TCPIP_STACK_USE_DHCP_CLIENT)
	// Make sure we don't clobber anyone else's DHCP server
	if(DHCPIsServerDetected(pConfig))
		return;
#endif

    netIx = _TCPIPStackNetIx(pConfig);
	if(!bDHCPServerEnabled[netIx])
		return;

    s = MySocket[netIx];

	switch(smDHCPServer[netIx])
	{
		case DHCP_OPEN_SOCKET:
			// Obtain a UDP socket to listen/transmit on
			MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,DHCP_SERVER_PORT, DHCP_CLIENT_PORT);
			if(MySocket[netIx] == INVALID_UDP_SOCKET)
				break;

            UDPSocketSetNet(MySocket[netIx], pConfig);
			// Decide which address to lease out
			// Note that this needs to be changed if we are to 
			// support more than one lease
			DHCPNextLease[netIx].Val = (pConfig->MyIPAddr.Val & pConfig->MyMask.Val) + 0x02000000;
			if(DHCPNextLease[netIx].v[3] == 255u)
				DHCPNextLease[netIx].v[3] += 0x03;
			if(DHCPNextLease[netIx].v[3] == 0u)
				DHCPNextLease[netIx].v[3] += 0x02;

			smDHCPServer[netIx]++;

		case DHCP_LISTEN:
			// Check to see if a valid DHCP packet has arrived
			if(UDPIsGetReady(s) < 241u)
				break;

			// Retrieve the BOOTP header
			UDPGetArray(s, (uint8_t*)&BOOTPHeader, sizeof(BOOTPHeader));

			bAccept = (BOOTPHeader.ClientIP.Val == DHCPNextLease[netIx].Val) || (BOOTPHeader.ClientIP.Val == 0x00000000u);

			// Validate first three fields
			if(BOOTPHeader.MessageType != 1u)
				break;
			if(BOOTPHeader.HardwareType != 1u)
				break;
			if(BOOTPHeader.HardwareLen != 6u)
				break;

			// Throw away 10 unused bytes of hardware address,
			// server host name, and boot file name -- unsupported/not needed.
			for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)
				UDPGet(s, &Option);

			// Obtain Magic Cookie and verify
			UDPGetArray(s, (uint8_t*)&dw, sizeof(uint32_t));
			if(dw != 0x63538263ul)
				break;

			// Obtain options
			while(1)
			{
				// Get option type
				if(!UDPGet(s, &Option))
					break;
				if(Option == DHCP_END_OPTION)
					break;

				// Get option length
				UDPGet(s, &Len);
	
				// Process option
				switch(Option)
				{
					case DHCP_MESSAGE_TYPE:
						UDPGet(s, &i);
						switch(i)
						{
							case DHCP_DISCOVER_MESSAGE:
								DHCPReplyToDiscovery(&BOOTPHeader, netIx);
								break;

							case DHCP_REQUEST_MESSAGE:
							// NOTE : This #if section was missing from 5.36
                                #if defined(TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL)
								if ( (BOOTPHeader.ClientIP.Val == 0x00000000u) &&
									 (bLeaseAvailable[netIx] == false) )
								{
									// Lease available only to the current lease holder
									break;
								}
								#endif

								DHCPReplyToRequest(&BOOTPHeader, bAccept, netIx);

							// NOTE : This #if section was missing from 5.36
                                #if defined(TCPIP_STACK_USE_ZEROCONF_LINK_LOCAL)
								bLeaseAvailable[netIx] = false;
								#endif

								break;

							// Need to handle these if supporting more than one DHCP lease
							case DHCP_RELEASE_MESSAGE:
							case DHCP_DECLINE_MESSAGE:
								break;
						}
						break;

					case DHCP_PARAM_REQUEST_IP_ADDRESS:
						if(Len == 4u)
						{
							// Get the requested IP address and see if it is the one we have on offer.
							UDPGetArray(s, (uint8_t*)&dw, 4);
							Len -= 4;
							bAccept = (dw == DHCPNextLease[netIx].Val);
						}
						break;

					case DHCP_END_OPTION:
						UDPDiscard(s);
						return;
				}

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

			UDPDiscard(s);
			break;
	}
}
Exemple #20
0
/*****************************************************************************
  Function:
	void DHCPServerTask(void)

  Summary:
	Performs periodic DHCP server tasks.

  Description:
	This function performs any periodic tasks requied by the DHCP server 
	module, such as processing DHCP requests and distributing IP addresses.

  Precondition:
	None

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void DHCPServerTask(void)
{
	BYTE 				i;
	BYTE				Option, Len;
	BOOTP_HEADER		BOOTPHeader;
	DWORD				dw;
	BOOL				bAccept;
	static enum
	{
		DHCP_OPEN_SOCKET,
		DHCP_LISTEN
	} smDHCPServer = DHCP_OPEN_SOCKET;

#if defined(STACK_USE_DHCP_CLIENT)
	// Make sure we don't clobber anyone else's DHCP server
	if(DHCPFlags.bits.bDHCPServerDetected)
		return;
#endif

	if(!bDHCPServerEnabled)
		return;

	switch(smDHCPServer)
	{
		case DHCP_OPEN_SOCKET:
			// Obtain a UDP socket to listen/transmit on
			MySocket = UDPOpen(DHCP_SERVER_PORT, NULL, DHCP_CLIENT_PORT);
			if(MySocket == INVALID_UDP_SOCKET)
				break;


			// Decide which address to lease out
			// Note that this needs to be changed if we are to 
			// support more than one lease
			DHCPNextLease.Val = (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) + 0x02000000;
			if(DHCPNextLease.v[3] == 255u)
				DHCPNextLease.v[3] += 0x03;
			if(DHCPNextLease.v[3] == 0u)
				DHCPNextLease.v[3] += 0x02;

			smDHCPServer++;

		case DHCP_LISTEN:
			// Check to see if a valid DHCP packet has arrived
			if(UDPIsGetReady(MySocket) < 241u)
				break;

			// Retrieve the BOOTP header
			UDPGetArray((BYTE*)&BOOTPHeader, sizeof(BOOTPHeader));

			bAccept = (BOOTPHeader.ClientIP.Val == DHCPNextLease.Val) || (BOOTPHeader.ClientIP.Val == 0x00000000u);

			// Validate first three fields
			if(BOOTPHeader.MessageType != 1u)
				break;
			if(BOOTPHeader.HardwareType != 1u)
				break;
			if(BOOTPHeader.HardwareLen != 6u)
				break;

			// Throw away 10 unused bytes of hardware address,
			// server host name, and boot file name -- unsupported/not needed.
			for(i = 0; i < 64+128+(16-sizeof(MAC_ADDR)); i++)
				UDPGet(&Option);

			// Obtain Magic Cookie and verify
			UDPGetArray((BYTE*)&dw, sizeof(DWORD));
			if(dw != 0x63538263ul)
				break;

			// Obtain options
			while(1)
			{
				// Get option type
				if(!UDPGet(&Option))
					break;
				if(Option == DHCP_END_OPTION)
					break;

				// Get option length
				UDPGet(&Len);
	
				// Process option
				switch(Option)
				{
					case DHCP_MESSAGE_TYPE:
						UDPGet(&i);
						switch(i)
						{
							case DHCP_DISCOVER_MESSAGE:
								DHCPReplyToDiscovery(&BOOTPHeader);
								break;

							case DHCP_REQUEST_MESSAGE:
								DHCPReplyToRequest(&BOOTPHeader, bAccept);
								break;

							// Need to handle these if supporting more than one DHCP lease
							case DHCP_RELEASE_MESSAGE:
							case DHCP_DECLINE_MESSAGE:
								break;
						}
						break;

					case DHCP_PARAM_REQUEST_IP_ADDRESS:
						if(Len == 4u)
						{
							// Get the requested IP address and see if it is the one we have on offer.
							UDPGetArray((BYTE*)&dw, 4);
							Len -= 4;
							bAccept = (dw == DHCPNextLease.Val);
						}
						break;

					case DHCP_END_OPTION:
						UDPDiscard();
						return;
				}

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

			UDPDiscard();
			break;
	}
}
Exemple #21
0
/*****************************************************************************
  Function:
	void DHCPTask(void)

  Summary:
	Performs periodic DHCP tasks.

  Description:
	This function performs any periodic tasks requied by the DHCP module, 
	such as sending and receiving messages involved with obtaining and
	maintaining a lease.

  Precondition:
	None

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void DHCPTask(void)
{
    static TICK eventTime;

    switch(smDHCPState)
    {
		case SM_DHCP_GET_SOCKET:
			// Open a socket to send and receive broadcast messages on
	        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
			if(DHCPSocket == INVALID_UDP_SOCKET)
				break;

			smDHCPState = SM_DHCP_SEND_DISCOVERY;
			// No break

		case SM_DHCP_SEND_DISCOVERY:
			if(UDPIsPutReady(DHCPSocket) < 300u)
				break;

			// Ensure that we transmit to the broadcast IP and MAC addresses
			// The UDP Socket remembers who it was last talking to
			memset((void*)&UDPSocketInfo[DHCPSocket].remoteNode, 0xFF, sizeof(UDPSocketInfo[DHCPSocket].remoteNode));

		    // Assume default IP Lease time of 60 seconds.
		    // This should be minimum possible to make sure that if
		    // server did not specify lease time, we try again after this minimum time.
		    DHCPLeaseTime.Val = 60;
			ValidValues.Val = 0x00;
			DHCPBindCount = 0;
			DHCPFlags.bits.bIsBound = FALSE;	
			DHCPFlags.bits.bOfferReceived = FALSE;
			
			// Send the DHCP Discover broadcast
			_DHCPSend(DHCP_DISCOVER_MESSAGE, FALSE);
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState = SM_DHCP_GET_OFFER;
	        break;

		case SM_DHCP_GET_OFFER:
			// Check to see if a packet has arrived
			if(UDPIsGetReady(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an offer after 2 seconds
				if(TickGet() - eventTime >= DHCP_TIMEOUT)
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
				break;
			}

			// Let the DHCP server module know that there is a DHCP server 
			// on this network
			DHCPFlags.bits.bDHCPServerDetected = TRUE;

			// Check to see if we received an offer
			if(_DHCPReceive() != DHCP_OFFER_MESSAGE)
				break;

			smDHCPState = SM_DHCP_SEND_REQUEST;
			// No break

		case SM_DHCP_SEND_REQUEST:
			if(UDPIsPutReady(DHCPSocket) < 258u)
				break;

			// Send the DHCP request message
			_DHCPSend(DHCP_REQUEST_MESSAGE, FALSE);
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState = SM_DHCP_GET_REQUEST_ACK;
	        break;

		case SM_DHCP_GET_REQUEST_ACK:
			// Check to see if a packet has arrived
			if(UDPIsGetReady(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
				if(TickGet() - eventTime >= DHCP_TIMEOUT)
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
				break;
			}

			// Check to see if we received an offer
			switch(_DHCPReceive())
			{
				case DHCP_ACK_MESSAGE:
					UDPClose(DHCPSocket);
					DHCPSocket = INVALID_UDP_SOCKET;
					eventTime = TickGet();
					smDHCPState = SM_DHCP_BOUND;

	                DHCPFlags.bits.bIsBound = TRUE;	
	                DHCPBindCount++;
					if(ValidValues.bits.IPAddress)
		                AppConfig.MyIPAddr = tempIPAddress;
					if(ValidValues.bits.Mask)
						AppConfig.MyMask = tempMask;
					if(ValidValues.bits.Gateway)
						AppConfig.MyGateway = tempGateway;
					#if defined(STACK_USE_DNS)
						if(ValidValues.bits.DNS)
							AppConfig.PrimaryDNSServer = tempDNS;
						AppConfig.SecondaryDNSServer.Val = ValidValues.bits.DNS2 ? tempDNS2.Val : 0x00000000ul;
					#endif
//					if(ValidValues.bits.HostName)
//						memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName));

					break;

				case DHCP_NAK_MESSAGE:
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
					break;
			}
			break;

		case SM_DHCP_BOUND:
	        if(TickGet() - eventTime < TICK_SECOND)
				break;

			// Check to see if our lease is still valid, if so, decrement lease 
			// time
			if(DHCPLeaseTime.Val >= 2ul)
			{
				eventTime += TICK_SECOND;
				DHCPLeaseTime.Val--;
				break;
			}
			
			// Open a socket to send and receive DHCP messages on
	        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
			if(DHCPSocket == INVALID_UDP_SOCKET)
				break;
			
			smDHCPState = SM_DHCP_SEND_RENEW;
			// No break

		case SM_DHCP_SEND_RENEW:
		case SM_DHCP_SEND_RENEW2:
		case SM_DHCP_SEND_RENEW3:
			if(UDPIsPutReady(DHCPSocket) < 258u)
				break;

			// Send the DHCP request message
			_DHCPSend(DHCP_REQUEST_MESSAGE, TRUE);
			DHCPFlags.bits.bOfferReceived = FALSE;
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState++;
			break;

		case SM_DHCP_GET_RENEW_ACK:
		case SM_DHCP_GET_RENEW_ACK2:
		case SM_DHCP_GET_RENEW_ACK3:
			// Check to see if a packet has arrived
			if(UDPIsGetReady(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
				if(TickGet() - eventTime >=  DHCP_TIMEOUT)
				{
					if(++smDHCPState > SM_DHCP_GET_RENEW_ACK3)
						smDHCPState = SM_DHCP_SEND_DISCOVERY;
				}
				break;
			}

			// Check to see if we received an offer
			switch(_DHCPReceive())
			{
				case DHCP_ACK_MESSAGE:
					UDPClose(DHCPSocket);
					DHCPSocket = INVALID_UDP_SOCKET;
					eventTime = TickGet();
					DHCPBindCount++;
					smDHCPState = SM_DHCP_BOUND;
					break;

				case DHCP_NAK_MESSAGE:
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
					break;
			}
			break;

		// Handle SM_DHCP_DISABLED state by doing nothing.  Default case needed 
		// to supress compiler diagnostic.
		default:	
			break;
	}
}
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;
	}
}
void Command()
{
	switch (Cmd_Read_Switch)
	{
		case	0	:	if(UDPIsGetReady(socket2))
						{
							SuccesFull_Read = UDPGetArray(Cmd, 0x3);
							if (Cmd[0] == Enter || Cmd[0] == 0 || SuccesFull_Read < 3)
							{
								Cmd_Read_Switch = 0;
								Cmd[0] = 0;
								break;
							}							
							else if (Cmd[2] == Enter)
							{
								Cmd_Read_Switch = 0;
								Command_Exe(Cmd);									
							}
							Cmd_Read_Switch = 0;
							Cmd[0] = 0;
							Cmd[1] = 0;
							Cmd[2] = 0;
							break;
						}
						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
						Cmd_Read_Switch = 21;
						break;
						
		case	21	:	socket2 = UDPOpen(0x6FFF, NULL, 0x6FFF);  //open the socket 
			            
			            if(socket2 == 0xFF) //Invalid socket
			            {
				            break;
				        }
				        else{Cmd_Read_Switch = 0;}
				        
				        Led1=1;
				        Output_Enable = 1; 
				        
				        break;				        
		
		default		:	break;
	}
	
}
Exemple #24
0
/*****************************************************************************
  Function:
	int connect( SOCKET s, struct sockaddr* name, int namelen )

  Summary:
	This function connects to the peer communications end point.

  Description:
	The connect function assigns the address of the peer
	communications endpoint. For stream sockets, connection is
	established between the endpoints. For datagram sockets, an
	address filter is established between the endpoints until
	changed with another connect() function.

  Precondition:
	socket function should be called.

  Parameters:
	s - Socket descriptor returned from a previous call to socket.
	name - pointer to the sockaddr structure containing the
	peer address and port number.
	namelen - length of the sockaddr structure.

  Returns:
	If the connect() function succeeds, it returns 0. Otherwise,
	the value SOCKET_ERROR is returned to indicate an error
	condition. For stream based socket, if the connection is not
	established yet, connect returns SOCKET_CNXN_IN_PROGRESS.

  Remarks:
	None.
  ***************************************************************************/
int connect( SOCKET s, struct sockaddr* name, int namelen )
{
    struct BSDSocket *socket;
    struct sockaddr_in *addr;
    DWORD remoteIP;
    WORD remotePort;
    WORD localPort;

    if( s >= BSD_SOCKET_COUNT )
        return SOCKET_ERROR;

    socket = &BSDSocketArray[s];

    if( socket->bsdState < SKT_CREATED )
        return SOCKET_ERROR;

    if( (unsigned int)namelen < sizeof(struct sockaddr_in))
        return SOCKET_ERROR;

    addr = (struct sockaddr_in *)name;
    remotePort 	= addr->sin_port;
    remoteIP 	= addr->sin_addr.S_un.S_addr;

    if( remoteIP == 0u || remotePort == 0u )
        return SOCKET_ERROR;

    if( socket->SocketType == SOCK_STREAM )
    {
        switch(socket->bsdState)
        {
        case SKT_EST:
            return 0; // already established

        case SKT_IN_PROGRESS:
            if(HandlePossibleTCPDisconnection(s))
                return SOCKET_ERROR;

            if(!TCPIsConnected(socket->SocketID))
                return SOCKET_CNXN_IN_PROGRESS;

            socket->bsdState = SKT_EST;
            return 0; //success

        case SKT_CREATED:
        case SKT_BOUND:
            socket->SocketID = TCPOpen(remoteIP, TCP_OPEN_IP_ADDRESS, remotePort, TCP_PURPOSE_BERKELEY_CLIENT);
            if(socket->SocketID == INVALID_SOCKET)
                return SOCKET_ERROR;

            // Clear the first reset flag
            TCPWasReset(socket->SocketID);

            socket->isServer = FALSE;
            socket->bsdState = SKT_IN_PROGRESS;
            return SOCKET_CNXN_IN_PROGRESS;

        default:
            return SOCKET_ERROR;
        }
    }
    else
    {
        // If not explicitly bound to a local port, implicitly do the binding
        if(socket->bsdState == SKT_CREATED)
        {
            localPort = gAutoPortNumber++;
            if(gAutoPortNumber > 5000u) // reset the port numbers
                gAutoPortNumber = 1024;

            socket->SocketID = UDPOpen(localPort, NULL, remotePort);
            if(socket->SocketID == INVALID_UDP_SOCKET)
                return SOCKET_ERROR;
            socket->bsdState = SKT_BOUND;
        }
        if(socket->bsdState != SKT_BOUND)
            return SOCKET_ERROR;

        // UDP: remote port is used as a filter. Need to call connect when using
        // send/recv calls. No need to call 'connect' if using sendto/recvfrom
        // calls.
        socket->remotePort = remotePort;
        socket->remoteIP = remoteIP;
        return 0; //success
    }
    return SOCKET_ERROR;
}
Exemple #25
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;
   }
}
Exemple #26
0
/*********************************************************************
 * Function:        void ANNOUNCE_Task(void)
 *
 * Summary:         Announce callback task.
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Recurring task used to listen for Discovery
 *                  messages on the specified ANNOUNCE_PORT.  These
 *                  messages can be sent using the TCP/IP
 *                  Discoverer tool. If one is received, this
 *                  function will transmit a reply.
 *
 * Note:            A UDP socket must be available before this 
 *					function is called.  It is freed at the end of 
 *					the function.  UDP_MAX_SOCKETS may need to be 
 *					increased if other modules use UDP sockets.
 ********************************************************************/
void ANNOUNCE_Task(NET_CONFIG * pNetIf)
{
	static enum {
		DISCOVERY_HOME = 0,
		DISCOVERY_LISTEN,
		DISCOVERY_REQUEST_RECEIVED,
		DISCOVERY_DISABLED
	} DiscoverySM[TCPIP_NETWORK_INTERFACES] = {DISCOVERY_HOME};

	static UDP_SOCKET	MySocket[TCPIP_NETWORK_INTERFACES];
	uint8_t 				i;
    int                 netIx;
    UDP_SOCKET          s;

    if(!pNetIf)
    {
        return;
    }
    else
    {
        netIx = _TCPIPStackNetIx(pNetIf);
    }
    
    s = MySocket[netIx];

	switch(DiscoverySM[netIx])
	{
		case DISCOVERY_HOME:
			// Open a UDP socket for inbound and outbound transmission
			// Since we expect to only receive broadcast packets and 
			// only send unicast packets directly to the node we last 
			// received from, the remote NodeInfo parameter can be anything
			MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,ANNOUNCE_PORT, ANNOUNCE_PORT);

			if(MySocket[netIx] == INVALID_UDP_SOCKET)
            {
				return;
            }
			else
            {
                DiscoverySM[netIx]++;
                UDPSocketSetNet(MySocket[netIx], pNetIf);
            }
			break;

		case DISCOVERY_LISTEN:
			// Do nothing if no data is waiting
			if(!UDPIsGetReady(s))
				return;
			
			// See if this is a discovery query or reply
			UDPGet(s, &i);
			UDPDiscard(s);
			if(i != 'D')
				return;

			// We received a discovery request, reply when we can
			DiscoverySM[netIx]++;

			// Change the destination to the unicast address of the last received packet
            TCPIP_IPV4_SetDestAddress(UDPSocketDcpt[s].pTxPkt,remoteNode.IPAddr.Val);
        	memcpy((void*)&UDPSocketDcpt[s].pTxPkt->remoteMACAddr, (const void*)&remoteNode.MACAddr, sizeof(MAC_ADDR));
			
			// No break needed.  If we get down here, we are now ready for the DISCOVERY_REQUEST_RECEIVED state

		case DISCOVERY_REQUEST_RECEIVED:
            ANNOUNCE_Notify (pNetIf, 0, NULL);		
			// Listen for other discovery requests
			DiscoverySM[netIx] = DISCOVERY_LISTEN;
			break;

		case DISCOVERY_DISABLED:
			break;
	}	

}
Exemple #27
0
/*********************************************************************
 * Function:        void NBNSTask(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          Sends responses to NetBIOS name requests
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void NBNSTask(void)
{
	static UDP_SOCKET	MySocket;
	BYTE 				i;
	WORD_VAL			Type, Class;
	NBNS_HEADER			NBNSHeader;
	BYTE				NameString[16];
	static enum
	{
		NBNS_HOME = 0,
		NBNS_OPEN_SOCKET,
		NBNS_LISTEN
	} smNBNS = NBNS_HOME;

	switch(smNBNS)
	{
		case NBNS_HOME:
			smNBNS++;
			break;

		case NBNS_OPEN_SOCKET:
			MySocket = UDPOpen(NBNS_PORT, NULL, NBNS_PORT);
			if(MySocket == INVALID_UDP_SOCKET)
				break;

			smNBNS++;

		case NBNS_LISTEN:
			if(!UDPIsGetReady(MySocket))
				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 & AppConfig.MyMask.Val) != (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val))
			{
				UDPDiscard();
				break;
			}

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

			// Remove all questions
			while(NBNSHeader.Questions.Val--)
			{
				NBNSGetName(NameString);
				UDPGet(&i);				// <??> Trailing character on string
				UDPGet(&Type.v[1]);		// Question type
				UDPGet(&Type.v[0]);
				UDPGet(&Class.v[1]);	// Question class
				UDPGet(&Class.v[0]);
				
				if(Type.Val == 0x0020u && Class.Val == 0x0001u && strcmp((char*)NameString, (char*)AppConfig.NetBIOSName) == 0)
				{
					while(!UDPIsPutReady(MySocket));

					NBNSHeader.Flags.Val = 0x8400;

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

					NBNSPutName(AppConfig.NetBIOSName);
					UDPPut(0x00);	// 0x0020 Type: NetBIOS
					UDPPut(0x20);
					UDPPut(0x00);	// 0x0001 Class: Internet
					UDPPut(0x01);
					UDPPut(0x00);	// 0x00000000 Time To Live
					UDPPut(0x00);
					UDPPut(0x00);
					UDPPut(0x00);

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

					// Change the destination address to the unicast address of the last received packet
		        	memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode));
					UDPFlush();				
				}

			}
			
			UDPDiscard();

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

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

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

                break;
            }

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

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

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

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

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

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

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

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

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

        case DNS_DONE:
            return TRUE;
    }
    
    return FALSE;
}
Exemple #29
0
/*****************************************************************************
  Function:
	void DHCPTask(void)

  Summary:
	Performs periodic DHCP tasks for all interfaces.

  Description:
	This function performs any periodic tasks requied by the DHCP module, 
	such as sending and receiving messages involved with obtaining and
	maintaining a lease.

  Precondition:
	None

  Parameters:
	None

  Returns:
	None
***************************************************************************/
void DHCPTask(void)
{
	BYTE i;
	
	for(i = 0; i < NETWORK_INTERFACES; i++)
	{
		LoadState(i);
		switch(DHCPClient.smState)
		{
			case SM_DHCP_DISABLED:
				// When the module is disabled, do absolutely nothing
				break;
			
			case SM_DHCP_GET_SOCKET:
				// Open a socket to send and receive broadcast messages on
				DHCPClient.hDHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
				if(DHCPClient.hDHCPSocket == INVALID_UDP_SOCKET)
					break;
	
				DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
				// No break
	
			case SM_DHCP_SEND_DISCOVERY:
				// Assume default IP Lease time of 60 seconds.
				// This should be minimum possible to make sure that if the
				// server did not specify lease time, we try again after this 
				// minimum time.
				DHCPClient.dwLeaseTime = 60;
				DHCPClient.validValues.val = 0x00;
				DHCPClient.flags.bits.bIsBound = FALSE;	
				DHCPClient.flags.bits.bOfferReceived = FALSE;
	
				// No point in wasting time transmitting a discovery if we are 
				// unlinked.  No one will see it.  
				if(!MACIsLinked())
					break;
	
				// Ensure transmitter is ready to accept data
				if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 300u)
					break;

				// Toggle the BOOTP Broadcast flag to ensure compatibility with 
				// bad DHCP servers that don't know how to handle broadcast 
				// responses.  This results in the next discovery attempt to be 
				// made using the opposite mode.
				DHCPClient.flags.bits.bUseUnicastMode ^= 1;
	
				// Ensure that we transmit to the broadcast IP and MAC addresses
				// The UDP Socket remembers who it was last talking to
				memset((void*)&UDPSocketInfo[DHCPClient.hDHCPSocket].remoteNode, 0xFF, sizeof(UDPSocketInfo[0].remoteNode));
	
				// Send the DHCP Discover broadcast
				_DHCPSend(DHCP_DISCOVER_MESSAGE, FALSE);
	
				// Start a timer and begin looking for a response
				DHCPClient.dwTimer = TickGet();
				DHCPClient.smState = SM_DHCP_GET_OFFER;
				break;
	
			case SM_DHCP_GET_OFFER:
				// Check to see if a packet has arrived
				if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u)
				{
					// Go back and transmit a new discovery if we didn't get an offer after 2 seconds
					if(TickGet() - DHCPClient.dwTimer >= DHCP_TIMEOUT)
						DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
					break;
				}
	
				// Let the DHCP server module know that there is a DHCP server 
				// on this network
				DHCPClient.flags.bits.bDHCPServerDetected = TRUE;
	
				// Check to see if we received an offer
				if(_DHCPReceive() != DHCP_OFFER_MESSAGE)
					break;
	
				DHCPClient.smState = SM_DHCP_SEND_REQUEST;
				// No break
	
			case SM_DHCP_SEND_REQUEST:
				if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 258u)
					break;

				// Ensure that we transmit to the broadcast IP and MAC addresses
				// The UDP Socket remembers who it was last talking to, so 
				// we must set this back to the broadcast address since the 
				// current socket values are the unicast addresses of the DHCP 
				// server.
				memset((void*)&UDPSocketInfo[DHCPClient.hDHCPSocket].remoteNode, 0xFF, sizeof(UDPSocketInfo[0].remoteNode));
	
				// Send the DHCP request message
				_DHCPSend(DHCP_REQUEST_MESSAGE, FALSE);
	
				// Start a timer and begin looking for a response
				DHCPClient.dwTimer = TickGet();
				DHCPClient.smState = SM_DHCP_GET_REQUEST_ACK;
				break;
	
			case SM_DHCP_GET_REQUEST_ACK:
				// Check to see if a packet has arrived
				if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u)
				{
					// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
					if(TickGet() - DHCPClient.dwTimer >= DHCP_TIMEOUT)
						DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
					break;
				}
	
				// Check to see if we received an offer
				switch(_DHCPReceive())
				{
					case DHCP_ACK_MESSAGE:
						UDPClose(DHCPClient.hDHCPSocket);
						DHCPClient.hDHCPSocket = INVALID_UDP_SOCKET;
						DHCPClient.dwTimer = TickGet();
						DHCPClient.smState = SM_DHCP_BOUND;
						DHCPClient.flags.bits.bEvent = 1;
						DHCPClient.flags.bits.bIsBound = TRUE;	

						if(DHCPClient.validValues.bits.IPAddress)
							AppConfig.MyIPAddr = DHCPClient.tempIPAddress;
						if(DHCPClient.validValues.bits.Mask)
							AppConfig.MyMask = DHCPClient.tempMask;
						if(DHCPClient.validValues.bits.Gateway)
							AppConfig.MyGateway = DHCPClient.tempGateway;
						#if defined(STACK_USE_DNS)
							if(DHCPClient.validValues.bits.DNS)
								AppConfig.PrimaryDNSServer.Val = DHCPClient.tempDNS.Val;
							AppConfig.SecondaryDNSServer.Val = 0x00000000ul;
							if(DHCPClient.validValues.bits.DNS2)
								AppConfig.SecondaryDNSServer.Val = DHCPClient.tempDNS2.Val;
						#endif
						//if(DHCPClient.validValues.bits.HostName)
						//	memcpy(AppConfig.NetBIOSName, (void*)DHCPClient.tempHostName, sizeof(AppConfig.NetBIOSName));
	
						break;
	
					case DHCP_NAK_MESSAGE:
						DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
						break;
				}
				break;
	
			case SM_DHCP_BOUND:
				if(TickGet() - DHCPClient.dwTimer < TICK_SECOND)
					break;
	
				// Check to see if our lease is still valid, if so, decrement lease 
				// time
				if(DHCPClient.dwLeaseTime >= 2ul)
				{
					DHCPClient.dwTimer += TICK_SECOND;
					DHCPClient.dwLeaseTime--;
					break;
				}
	
				// Open a socket to send and receive DHCP messages on
				DHCPClient.hDHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
				if(DHCPClient.hDHCPSocket == INVALID_UDP_SOCKET)
					break;
	
				DHCPClient.smState = SM_DHCP_SEND_RENEW;
				// No break
	
			case SM_DHCP_SEND_RENEW:
			case SM_DHCP_SEND_RENEW2:
			case SM_DHCP_SEND_RENEW3:
				if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 258u)
					break;
	
				// Send the DHCP request message
				_DHCPSend(DHCP_REQUEST_MESSAGE, TRUE);
				DHCPClient.flags.bits.bOfferReceived = FALSE;
	
				// Start a timer and begin looking for a response
				DHCPClient.dwTimer = TickGet();
				DHCPClient.smState++;
				break;
	
			case SM_DHCP_GET_RENEW_ACK:
			case SM_DHCP_GET_RENEW_ACK2:
			case SM_DHCP_GET_RENEW_ACK3:
				// Check to see if a packet has arrived
				if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u)
				{
					// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
					if(TickGet() - DHCPClient.dwTimer >=  DHCP_TIMEOUT)
					{
						if(++DHCPClient.smState > SM_DHCP_GET_RENEW_ACK3)
							DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
					}
					break;
				}
	
				// Check to see if we received an offer
				switch(_DHCPReceive())
				{
					case DHCP_ACK_MESSAGE:
						UDPClose(DHCPClient.hDHCPSocket);
						DHCPClient.hDHCPSocket = INVALID_UDP_SOCKET;
						DHCPClient.dwTimer = TickGet();
						DHCPClient.smState = SM_DHCP_BOUND;
						DHCPClient.flags.bits.bEvent = 1;
						break;
		
					case DHCP_NAK_MESSAGE:
						DHCPClient.smState = SM_DHCP_SEND_DISCOVERY;
						break;
				}
				break;
		}
	}
}
Exemple #30
0
/*********************************************************************
 * Function:        void DiscoveryTask(void)
 *
 * Summary:         Announce callback task.
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Recurring task used to listen for Discovery
 *                  messages on the specified ANNOUNCE_PORT.  These
 *                  messages can be sent using the Microchip Device
 *                  Discoverer tool. If one is received, this
 *                  function will transmit a reply.
 *
 * Note:            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 DiscoveryTask(void)
{
	static enum {
		DISCOVERY_HOME = 0,
		DISCOVERY_LISTEN,
		DISCOVERY_REQUEST_RECEIVED,
		DISCOVERY_DISABLED
	} DiscoverySM = DISCOVERY_HOME;

	static UDP_SOCKET	MySocket;
	BYTE 				i;
	
	switch(DiscoverySM)
	{
		case DISCOVERY_HOME:
			// Open a UDP socket for inbound and outbound transmission
			// Since we expect to only receive broadcast packets and 
			// only send unicast packets directly to the node we last 
			// received from, the remote NodeInfo parameter can be anything
			MySocket = UDPOpen(ANNOUNCE_PORT, NULL, ANNOUNCE_PORT);

			if(MySocket == INVALID_UDP_SOCKET)
				return;
			else
				DiscoverySM++;
			break;

		case DISCOVERY_LISTEN:
			// Do nothing if no data is waiting
			if(!UDPIsGetReady(MySocket))
				return;
			
			// See if this is a discovery query or reply
			UDPGet(&i);
			UDPDiscard();
			if(i != 'D')
				return;

			// We received a discovery request, reply when we can
			DiscoverySM++;

			// Change the destination to the unicast address of the last received packet
        	memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode));
			
			// No break needed.  If we get down here, we are now ready for the DISCOVERY_REQUEST_RECEIVED state

		case DISCOVERY_REQUEST_RECEIVED:
			if(!UDPIsPutReady(MySocket))
				return;

			// 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('-');
			}
			UDPPut('\r');
			UDPPut('\n');

			// Send the packet
			UDPFlush();

			// Listen for other discovery requests
			DiscoverySM = DISCOVERY_LISTEN;
			break;

		case DISCOVERY_DISABLED:
			break;
	}	

}