/** * This FSM checks for new incoming packets, and routes it to appropriate * stack components. It also performs timed operations. * * This function must be called periodically called * to make sure that timely response. * * @preCondition StackInit() is already called. * * side affect: Stack FSM is executed. */ void StackTask(void) { static WORD dataCount; #if defined(STACK_USE_ICMP) static BYTE data[MAX_ICMP_DATA_LEN]; static WORD ICMPId; static WORD ICMPSeq; #endif IP_ADDR destIP; //Is filled with the Destination IP address contained in the IP header union { BYTE MACFrameType; BYTE IPFrameType; ICMP_CODE ICMPCode; } type; BOOL lbContinue; do { lbContinue = FALSE; switch(smStack) { case SM_STACK_IDLE: case SM_STACK_MAC: //debugPutGenRomStr(2, (ROM char*)"1"); //@mxd:2:%s //Check if the MAC RX Buffer has any data, and if it does, read the header. //Get the next header from the NIC. The node who sent it's address will be copied to //'remoteNode.MACAddr'. //Header was NOT read if MACGetHeader returned FALSE if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) ) { //debugPutGenRomStr(2, (ROM char*)"2"); //@mxd:2:%s //MODIFIED DHCP BEGIN // ADDED #if defined(STACK_USE_DHCP) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if(STACK_IS_DHCP_ENABLED) { if(!MACIsLinked()) { AppConfig.MyIPAddr.v[0] = MY_DEFAULT_IP_ADDR_BYTE1; AppConfig.MyIPAddr.v[1] = MY_DEFAULT_IP_ADDR_BYTE2; AppConfig.MyIPAddr.v[2] = MY_DEFAULT_IP_ADDR_BYTE3; AppConfig.MyIPAddr.v[3] = MY_DEFAULT_IP_ADDR_BYTE4; AppConfig.MyMask.v[0] = MY_DEFAULT_MASK_BYTE1; AppConfig.MyMask.v[1] = MY_DEFAULT_MASK_BYTE2; AppConfig.MyMask.v[2] = MY_DEFAULT_MASK_BYTE3; AppConfig.MyMask.v[3] = MY_DEFAULT_MASK_BYTE4; DHCPFlags.bits.bDHCPServerDetected = FALSE; stackFlags.bits.bInConfigMode = TRUE; DHCPReset(); } // DHCP must be called all the time even after IP configuration is // discovered. // DHCP has to account lease expiration time and renew the configuration // time. DHCPTask(); if(DHCPIsBound()) stackFlags.bits.bInConfigMode = FALSE; } #endif //MODIFIED DHCP END //MODIFIED DHCP BEGIN // Removed /* #if defined(STACK_USE_DHCP) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. //Set our IP to 0.0.0.0 if all the following are TRUE: // - DHCP is enabled // - MAC is not linked yet (or cable is unplugged) if (STACK_IS_DHCP_ENABLED) { if ( !MACIsLinked() ) { //debugPutGenRomStr(2, (ROM char*)"3"); //@mxd:2:%s #if (DEBUG_STACKTSK >= LOG_INFO) //debugPutMsg(1); //@mxd:1:DHCP Enabled but MAC not linked yet - set IP to 0.0.0.0 #endif //if (stackFlags.bits.bInConfigMode) { //IP address must be 0.0.0.0 before DHCP has obtained a valid IP address MY_IP_BYTE1 = 0; MY_IP_BYTE2 = 0; MY_IP_BYTE3 = 0; MY_IP_BYTE4 = 0; //} stackFlags.bits.bInConfigMode = TRUE; DHCPReset(); } } #endif */ //MODIFIED DHCP END break; //case SM_STACK_IDLE: AND case SM_STACK_MAC: } //debugPutGenRomStr(2, (ROM char*)"4"); //@mxd:2:%s lbContinue = TRUE; if ( type.MACFrameType == MAC_IP ) { smStack = SM_STACK_IP; #if (DEBUG_STACKTSK >= LOG_DEBUG) debugPutMsg(2); //@mxd:2:Reading MAC IP header #endif } else if ( type.MACFrameType == MAC_ARP ) { smStack = SM_STACK_ARP; #if (DEBUG_STACKTSK >= LOG_DEBUG) debugPutMsg(3); //@mxd:3:Reading MAC ARP header #endif } else { MACDiscardRx(); //Discard the contents of the current RX buffer #if (DEBUG_STACKTSK >= LOG_WARN) debugPutMsg(4); //@mxd:4:Unknown MAC header read, MAC Frame Type = 0x%x debugPutByteHex(type.MACFrameType); #endif } break; //case SM_STACK_IDLE: AND case SM_STACK_MAC: case SM_STACK_ARP: if ( ARPProcess() ) smStack = SM_STACK_IDLE; //lbContinue = FALSE; //Removed in latest Microchip TCP/IP stack break; case SM_STACK_IP: if ( IPGetHeader(&destIP, /* Get Destination IP Address as received in IP header */ &remoteNode, &type.IPFrameType, &dataCount) ) { lbContinue = TRUE; if ( type.IPFrameType == IP_PROT_ICMP ) { smStack = SM_STACK_ICMP; #if defined(STACK_USE_IP_GLEANING) if(stackFlags.bits.bInConfigMode && STACK_IS_DHCP_ENABLED) { // Accoriding to "IP Gleaning" procedure, // when we receive an ICMP packet with a valid // IP address while we are still in configuration // mode, accept that address as ours and conclude // configuration mode. if ( destIP.Val != 0xffffffff ) { stackFlags.bits.bInConfigMode = FALSE; MY_IP_BYTE1 = destIP.v[0]; MY_IP_BYTE2 = destIP.v[1]; MY_IP_BYTE3 = destIP.v[2]; MY_IP_BYTE4 = destIP.v[3]; myDHCPBindCount--; } } #endif } #if defined(STACK_USE_TCP) else if ( type.IPFrameType == IP_PROT_TCP ) smStack = SM_STACK_TCP; #endif #if defined(STACK_USE_UDP) else if ( type.IPFrameType == IP_PROT_UDP ) smStack = SM_STACK_UDP; #endif else // Unknown/unsupported higher level protocol { lbContinue = FALSE; MACDiscardRx(); //Discard the contents of the current RX buffer smStack = SM_STACK_IDLE; } } else // Improper IP header version or checksum { MACDiscardRx(); //Discard the contents of the current RX buffer smStack = SM_STACK_IDLE; } break; //case SM_STACK_IP: #if defined(STACK_USE_UDP) case SM_STACK_UDP: if ( UDPProcess(&remoteNode, &destIP, dataCount) ) smStack = SM_STACK_IDLE; //lbContinue = FALSE; //Removed in latest Microchip TCP/IP stack break; //case SM_STACK_UDP: #endif #if defined(STACK_USE_TCP) case SM_STACK_TCP: if ( TCPProcess(&remoteNode, &destIP, dataCount) ) //Will return TRUE if TCPProcess finished it's task, else FALSE smStack = SM_STACK_IDLE; //lbContinue = FALSE; //Removed in latest Microchip TCP/IP stack break; //case SM_STACK_TCP: #endif case SM_STACK_ICMP: smStack = SM_STACK_IDLE; #if defined(STACK_USE_ICMP) if ( dataCount <= (MAX_ICMP_DATA_LEN+9) ) { if ( ICMPGet(&type.ICMPCode, data, (BYTE*)&dataCount, &ICMPId, &ICMPSeq) ) { if ( type.ICMPCode == ICMP_ECHO_REQUEST ) { lbContinue = TRUE; smStack = SM_STACK_ICMP_REPLY; } } } #endif MACDiscardRx(); //Discard the contents of the current RX buffer break; //case SM_STACK_ICMP: #if defined(STACK_USE_ICMP) case SM_STACK_ICMP_REPLY: if ( ICMPIsTxReady() ) { ICMPPut(&remoteNode, ICMP_ECHO_REPLY, data, (BYTE)dataCount, ICMPId, ICMPSeq); smStack = SM_STACK_IDLE; } break; //case SM_STACK_ICMP_REPLY: #endif } //switch(smStack) FAST_USER_PROCESS(); } while(lbContinue); #if defined(STACK_USE_TCP) // Perform timed TCP FSM. TCPTick(); #endif //MODIFIED DHCP BEGIN // Removed this //#if defined(STACK_USE_DHCP) /* * DHCP must be called all the time even after IP configuration is * discovered. * DHCP has to account lease expiration time and renew the configuration * time. */ // DHCPTask(); // if(DHCPIsBound()) // stackFlags.bits.bInConfigMode = FALSE; //#endif //debugPutGenRomStr(2, (ROM char*)"MACTask"); //@mxd:2:%s //Perform routine MAC tasks MACTask(); }
void HTTPExecCmd(BYTE** argv, BYTE argc) { BYTE command; BYTE var; #if defined(ENABLE_REMOTE_CONFIG) DWORD_VAL dwVal; BYTE CurrentArg; WORD_VAL TmpWord; #endif /* * Design your pages such that they contain command code * as a one character numerical value. * Being a one character numerical value greatly simplifies * the job. */ command = argv[0][0] - '0'; /* * Find out the cgi file name and interpret parameters * accordingly */ switch(command) { case CGI_CMD_DIGOUT: // ACTION=0 /* * Identify the parameters. * Compare it in upper case format. */ var = argv[1][0] - '0'; switch(var) { case CMD_LED1: // NAME=0 // Toggle LED. LED1_IO ^= 1; break; case CMD_LED2: // NAME=1 // Toggle LED. LED2_IO ^= 1; break; } memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN); break; #if defined(USE_LCD) case CGI_CMD_LCDOUT: // ACTION=1 if(argc > 2u) // Text provided in argv[2] { // Convert %20 to spaces, and other URL transformations UnencodeURL(argv[2]); // Write 32 received characters or less to LCDText if(strlen((char*)argv[2]) < 32u) { memset(LCDText, ' ', 32); strcpy((char*)LCDText, (char*)argv[2]); } else { memcpy(LCDText, (void*)argv[2], 32); } // Write LCDText to the LCD LCDUpdate(); } else // No text provided { LCDErase(); } memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN); break; #endif #if defined(ENABLE_REMOTE_CONFIG) // Possibly useful code for remotely reconfiguring the board through // HTTP case CGI_CMD_RECONFIG: // ACTION=2 // Loop through all variables that we've been given CurrentArg = 1; while(argc > CurrentArg) { // Get the variable identifier (HTML "name"), and // increment to the variable's value TmpWord.v[1] = argv[CurrentArg][0]; TmpWord.v[0] = argv[CurrentArg++][1]; var = hexatob(TmpWord); // Make sure the variable's value exists if(CurrentArg >= argc) break; // Take action with this variable/value switch(var) { case VAR_IP_ADDRESS: case VAR_SUBNET_MASK: case VAR_GATEWAY_ADDRESS: { // Convert the returned value to the 4 octect // binary representation if(!StringToIPAddress(argv[CurrentArg], (IP_ADDR*)&dwVal)) break; // Reconfigure the App to use the new values if(var == VAR_IP_ADDRESS) { // Cause the IP address to be rebroadcast // through Announce.c or the RS232 port since // we now have a new IP address if(dwVal.Val != *(DWORD*)&AppConfig.MyIPAddr) DHCPBindCount++; // Set the new address memcpy((void*)&AppConfig.MyIPAddr, (void*)&dwVal, sizeof(AppConfig.MyIPAddr)); } else if(var == VAR_SUBNET_MASK) memcpy((void*)&AppConfig.MyMask, (void*)&dwVal, sizeof(AppConfig.MyMask)); else if(var == VAR_GATEWAY_ADDRESS) memcpy((void*)&AppConfig.MyGateway, (void*)&dwVal, sizeof(AppConfig.MyGateway)); } break; case VAR_DHCP: if(AppConfig.Flags.bIsDHCPEnabled) { if(!(argv[CurrentArg][0]-'0')) { AppConfig.Flags.bIsDHCPEnabled = FALSE; } } else { if(argv[CurrentArg][0]-'0') { AppConfig.MyIPAddr.Val = 0x00000000ul; AppConfig.Flags.bIsDHCPEnabled = TRUE; AppConfig.Flags.bInConfigMode = TRUE; DHCPReset(); } } break; } // Advance to the next variable (if present) CurrentArg++; } // Save any changes to non-volatile memory SaveAppConfig(); // Return the same CONFIG.CGI file as a result. memcpypgm2ram((void*)argv[0], (ROM void*)CONFIG_UPDATE_PAGE, CONFIG_UPDATE_PAGE_LEN); break; #endif default: memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN); break; } }
/****************************************************************************** * Function: void StackTask(void) * PreCondition: StackInit() is already called. * Input: None * Output: Stack FSM is executed. * Side Effects: None * Note: This FSM checks for new incoming packets, * and routes it to appropriate stack components. * It also performs timed operations. * This function must be called periodically to * ensure timely responses. ******************************************************************************/ void StackTask(void) { static WORD dataCount; IP_ADDR tempLocalIP; BOOL lbContinue; #if defined(STACK_USE_ICMP) static BYTE data[MAX_ICMP_DATA_LEN]; static WORD ICMPId, ICMPSeq; #endif union { BYTE MACFrameType; BYTE IPFrameType; ICMP_CODE ICMPCode; } type; do { lbContinue = FALSE; switch(smStack) { case SM_STACK_IDLE: case SM_STACK_MAC: if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) ) { #if defined(STACK_USE_DHCP) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if ( AppConfig.Flags.bIsDHCPEnabled ) { if ( !MACIsLinked() ) { AppConfig.MyIPAddr.Val = 0x00000000ul; AppConfig.Flags.bInConfigMode = TRUE; DHCPReset(); } } #endif break; } lbContinue = TRUE; if ( type.MACFrameType == MAC_IP ) smStack = SM_STACK_IP; else if ( type.MACFrameType == MAC_ARP ) smStack = SM_STACK_ARP; else MACDiscardRx(); break; case SM_STACK_ARP: if ( ARPProcess() ) smStack = SM_STACK_IDLE; break; case SM_STACK_IP: if ( IPGetHeader(&tempLocalIP,&remoteNode,&type.IPFrameType,&dataCount) ) { lbContinue = TRUE; if ( type.IPFrameType == IP_PROT_ICMP ) { smStack = SM_STACK_ICMP; #if defined(STACK_USE_IP_GLEANING) if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled) { /* * Accoriding to "IP Gleaning" procedure, * when we receive an ICMP packet with a valid * IP address while we are still in configuration * mode, accept that address as ours and conclude * configuration mode. */ if( tempLocalIP.Val != 0xffffffff ) { AppConfig.Flags.bInConfigMode = FALSE; AppConfig.MyIPAddr = tempLocalIP; myDHCPBindCount--; } } #endif } #if defined(STACK_USE_TCP) else if ( type.IPFrameType == IP_PROT_TCP ) smStack = SM_STACK_TCP; #endif #if defined(STACK_USE_UDP) else if ( type.IPFrameType == IP_PROT_UDP ) smStack = SM_STACK_UDP; #endif else // Unknown/unsupported higher level protocol { lbContinue = FALSE; MACDiscardRx(); smStack = SM_STACK_IDLE; } } else // Improper IP header version or checksum { MACDiscardRx(); smStack = SM_STACK_IDLE; } break; #if defined(STACK_USE_UDP) case SM_STACK_UDP: if ( UDPProcess(&remoteNode, &tempLocalIP, dataCount) ) smStack = SM_STACK_IDLE; break; #endif #if defined(STACK_USE_TCP) case SM_STACK_TCP: if ( TCPProcess(&remoteNode, &tempLocalIP, dataCount) ) smStack = SM_STACK_IDLE; break; #endif case SM_STACK_ICMP: smStack = SM_STACK_IDLE; #if defined(STACK_USE_ICMP) if ( dataCount <= (MAX_ICMP_DATA_LEN+8) ) { if ( ICMPGet(&type.ICMPCode,data,(BYTE*)&dataCount,&ICMPId,&ICMPSeq) ) { if ( type.ICMPCode == ICMP_ECHO_REQUEST ) { lbContinue = TRUE; smStack = SM_STACK_ICMP_REPLY; } } } #endif MACDiscardRx(); break; #if defined(STACK_USE_ICMP) case SM_STACK_ICMP_REPLY: if ( ICMPIsTxReady() ) { ICMPPut(&remoteNode,ICMP_ECHO_REPLY,data,(BYTE)dataCount,ICMPId,ICMPSeq); smStack = SM_STACK_IDLE; } break; #endif } } while(lbContinue); #if defined(STACK_USE_TCP) TCPTick(); // Perform timed TCP FSM. #endif #if defined(STACK_USE_DHCP) /* * DHCP must be called all the time even after IP configuration is * discovered. * DHCP has to account lease expiration time and renew the configuration * time. */ DHCPTask(); if(DHCPIsBound()) AppConfig.Flags.bInConfigMode = FALSE; #endif #if defined(STACK_USE_SNTP) SNTPTask(); // Execute SNTP client FSM #endif #if defined(STACK_USE_NBNS) NBNSTask(); // Execute NetBIOS name service task #endif }
/** * This FSM checks for new incoming packets, and routes it to appropriate * stack components. It also performs timed operations. * * This function must be called periodically called * to make sure that timely response. * * @preCondition StackInit() is already called. * * side affect: Stack FSM is executed. */ void StackTask(void) { static NODE_INFO remoteNode; static WORD dataCount; #if defined(STACK_USE_ICMP) static BYTE data[MAX_ICMP_DATA_LEN]; static WORD ICMPId; static WORD ICMPSeq; #endif IP_ADDR destIP; //Is filled with the Destination IP address contained in the IP header union { BYTE MACFrameType; BYTE IPFrameType; ICMP_CODE ICMPCode; } type; BOOL lbContinue; lbContinue = TRUE; while( lbContinue ) { lbContinue = FALSE; switch(smStack) { case SM_STACK_IDLE: case SM_STACK_MAC: //Check if the MAC RX Buffer has any data, and if it does, read the header. //Get the next header from the NIC. The node who sent it's address will be copied to //'remoteNode.MACAddr'. if ( !MACRxbufGetHdr(&remoteNode.MACAddr, &type.MACFrameType) ) { //Header was NOT read if MACRxbufGetHdr returned FALSE #if defined(STACK_USE_DHCP) //If DHCP is enabled AND MAC is not linked yet, set our IP to 0 if (STACK_IS_DHCP_ENABLED) { if ( !MACIsLinked() ) { #if (DEBUG_STACKTSK >= LOG_INFO) debugPutMsg(1); //@mxd:1:DHCP Enabled but MAC not linked yet - set IP to 0.0.0.0 #endif //IP address must be 0.0.0.0 before DHCP has obtained a valid IP address MY_IP_BYTE1 = 0; MY_IP_BYTE2 = 0; MY_IP_BYTE3 = 0; MY_IP_BYTE4 = 0; stackFlags.bits.bInConfigMode = TRUE; DHCPReset(); } } #endif break; } lbContinue = TRUE; if ( type.MACFrameType == MAC_IP ) { smStack = SM_STACK_IP; #if (DEBUG_STACKTSK >= LOG_DEBUG) debugPutMsg(2); //@mxd:2:Reading MAC IP header #endif } else if ( type.MACFrameType == MAC_ARP ) { smStack = SM_STACK_ARP; #if (DEBUG_STACKTSK >= LOG_DEBUG) debugPutMsg(3); //@mxd:3:Reading MAC ARP header #endif } else { MACRxbufDiscard(); #if (DEBUG_STACKTSK >= LOG_WARN) debugPutMsg(4); //@mxd:4:Unknown MAC header read, MAC Frame Type = 0x%x debugPutByteHex(type.MACFrameType); #endif } break; case SM_STACK_ARP: lbContinue = FALSE; if ( ARPProcess() ) smStack = SM_STACK_IDLE; break; case SM_STACK_IP: if ( IPGetHeader(&destIP, /* Get Destination IP Address as received in IP header */ &remoteNode, &type.IPFrameType, &dataCount) ) { lbContinue = TRUE; if ( type.IPFrameType == IP_PROT_ICMP ) { smStack = SM_STACK_ICMP; #if defined(STACK_USE_IP_GLEANING) if ( stackFlags.bits.bInConfigMode ) { /* * Accoriding to "IP Gleaning" procedure, when we receive an ICMP packet * with a valid IP address while we are still in configuration mode, * accept that address as ours and conclude configuration mode. */ if ( destIP.Val != 0xffffffff ) { stackFlags.bits.bInConfigMode = FALSE; MY_IP_BYTE1 = destIP.v[0]; MY_IP_BYTE2 = destIP.v[1]; MY_IP_BYTE3 = destIP.v[2]; MY_IP_BYTE4 = destIP.v[3]; #if defined(STACK_USE_DHCP) /* * If DHCP and IP gleaning is enabled at the * same time, we must ensuer that once we have * IP address through IP gleaning, we abort * any pending DHCP requests and do not renew * any new DHCP configuration. */ DHCPAbort(); #endif } } #endif } #if defined(STACK_USE_TCP) else if ( type.IPFrameType == IP_PROT_TCP ) smStack = SM_STACK_TCP; #endif #if defined(STACK_USE_UDP) else if ( type.IPFrameType == IP_PROT_UDP ) smStack = SM_STACK_UDP; #endif else { lbContinue = FALSE; MACRxbufDiscard(); smStack = SM_STACK_IDLE; } } else { MACRxbufDiscard(); smStack = SM_STACK_IDLE; } break; #if defined(STACK_USE_UDP) case SM_STACK_UDP: //tempLocalIP.v[0] = MY_IP_BYTE1; //tempLocalIP.v[1] = MY_IP_BYTE2; //tempLocalIP.v[2] = MY_IP_BYTE3; //tempLocalIP.v[3] = MY_IP_BYTE4; if ( UDPProcess(&remoteNode, &destIP, dataCount) ) smStack = SM_STACK_IDLE; lbContinue = FALSE; break; #endif #if defined(STACK_USE_TCP) case SM_STACK_TCP: //tempLocalIP.v[0] = MY_IP_BYTE1; //tempLocalIP.v[1] = MY_IP_BYTE2; //tempLocalIP.v[2] = MY_IP_BYTE3; //tempLocalIP.v[3] = MY_IP_BYTE4; //Will return TRUE if TCPProcess finished it's task, else FALSE if ( TCPProcess(&remoteNode, &destIP, dataCount) ) smStack = SM_STACK_IDLE; lbContinue = FALSE; break; #endif case SM_STACK_ICMP: smStack = SM_STACK_IDLE; #if defined(STACK_USE_ICMP) if ( dataCount <= (MAX_ICMP_DATA_LEN+9) ) { if ( ICMPGet(&type.ICMPCode, data, (BYTE*)&dataCount, &ICMPId, &ICMPSeq) ) { if ( type.ICMPCode == ICMP_ECHO_REQUEST ) { lbContinue = TRUE; smStack = SM_STACK_ICMP_REPLY; } else { smStack = SM_STACK_IDLE; } } else { smStack = SM_STACK_IDLE; } } #endif MACRxbufDiscard(); break; #if defined(STACK_USE_ICMP) case SM_STACK_ICMP_REPLY: if ( ICMPIsTxReady() ) { ICMPPut(&remoteNode, ICMP_ECHO_REPLY, data, (BYTE)dataCount, ICMPId, ICMPSeq); smStack = SM_STACK_IDLE; } break; #endif } } #if defined(STACK_USE_TCP) // Perform timed TCP FSM. TCPTick(); #endif #if defined(STACK_USE_DHCP) /* * DHCP must be called all the time even after IP configuration is discovered. * DHCP has to account lease expiration time and renew the configuration time. */ DHCPTask(); if ( DHCPIsBound() ) stackFlags.bits.bInConfigMode = FALSE; #endif //Perform routine MAC tasks MACTask(); }
/********************************************************************* * Function: void DHCPTask(void) * * PreCondition: DHCPInit() is already called AND * IPGetHeader() is called with * IPFrameType == IP_PROT_UDP * * Input: None * * Output: None * * Side Effects: None * * Overview: Fetches pending UDP packet from MAC receive buffer * and dispatches it appropriate UDP socket. * If not UDP socket is matched, UDP packet is * silently discarded. * * Note: Caller must make sure that MAC receive buffer * access pointer is set to begining of UDP packet. * Required steps before calling this function is: * * If ( MACIsRxReady() ) * { * MACGetHeader() * If MACFrameType == IP * IPGetHeader() * if ( IPFrameType == IP_PROT_UDP ) * Call DHCPTask() * ... ********************************************************************/ void DHCPTask(void) { NODE_INFO DHCPServerNode; static TICKTYPE lastTryTick; BYTE DHCPRecvReturnValue; TICKTYPE tickDiff; //static int8 debugLastState; //debugLastState = smDHCPState; switch(smDHCPState) { case SM_DHCP_INIT_FIRST_TIME: tempIPAddress.Val = 0x0; // smDHCPState = SM_DHCP_INIT; // State automatically changes /* No break */ case SM_DHCP_INIT: //debug(debug_putc,"\r\n\r\nDHCP: INIT"); //dsr add 061404 //MY_IP=0; DHCPServerNode.MACAddr.v[0] = 0xff; DHCPServerNode.MACAddr.v[1] = 0xff; DHCPServerNode.MACAddr.v[2] = 0xff; DHCPServerNode.MACAddr.v[3] = 0xff; DHCPServerNode.MACAddr.v[4] = 0xff; DHCPServerNode.MACAddr.v[5] = 0xff; DHCPServerNode.IPAddr.Val = 0xffffffff; DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, &DHCPServerNode, DHCP_SERVER_PORT); lastTryTick = TickGet(); smDHCPState = SM_DHCP_RESET_WAIT; /* No break */ case SM_DHCP_RESET_WAIT: if ( TickGetDiff(TickGet(), lastTryTick) >= (TICKS_PER_SECOND/5) ) //debug(debug_putc,"\r\n\r\nDHCP: RESET_WAIT"); smDHCPState = SM_DHCP_BROADCAST; break; case SM_DHCP_BROADCAST: // 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; // If we have already obtained some IP address, renew it. if(DHCPState.bits.bIsBound) { smDHCPState = SM_DHCP_REQUEST; } else if ( UDPIsPutReady(DHCPSocket) ) { // To minimize code requirement, user must make sure that // above call will be successful by making at least one // UDP socket available. // Usually this will be the case, given that DHCP will be // the first one to use UDP socket. // Also, we will not check for transmitter readiness, // we assume it to be ready. _DHCPSend(DHCP_DISCOVER_MESSAGE); ValidValues.Val = 0x00; lastTryTick = TickGet(); smDHCPState = SM_DHCP_DISCOVER; } break; case SM_DHCP_DISCOVER: if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT ) { //debug(debug_putc,"\r\n\r\nDHCP: DISCOVER TO BROADCAST"); smDHCPState = SM_DHCP_BROADCAST; //return; } if ( UDPIsGetReady(DHCPSocket) ) { if ( _DHCPReceive() == DHCP_OFFER_MESSAGE ) { //debug(debug_putc,"\r\n\r\nDHCP: DISCOVER BACK TO REQUEST"); smDHCPState = SM_DHCP_REQUEST; } else break; } else break; case SM_DHCP_REQUEST: if ( UDPIsPutReady(DHCPSocket) ) { _DHCPSend(DHCP_REQUEST_MESSAGE); lastTryTick = TickGet(); smDHCPState = SM_DHCP_BIND; //debug(debug_putc,"\r\n\r\nDHCP: REQUEST TO BIND"); } break; case SM_DHCP_BIND: if ( UDPIsGetReady(DHCPSocket) ) { DHCPRecvReturnValue = _DHCPReceive(); if ( DHCPRecvReturnValue == DHCP_NAK_MESSAGE ) { // (RSS) NAK recieved. DHCP server didn't like our DHCP Request format DHCPReset(); // Start all over again return; } else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE ) { // Once DCHP is successful, release the UDP socket // This will ensure that UDP layer discards any further DHCP related packets. UDPClose(DHCPSocket); DHCPSocket = INVALID_UDP_SOCKET; lastTryTick = TickGet(); smDHCPState = SM_DHCP_BOUND; if(ValidValues.bits.IPAddress) AppConfig.MyIPAddr = tempIPAddress; if(ValidValues.bits.Mask) AppConfig.MyMask = tempMask; if(ValidValues.bits.Gateway) AppConfig.MyGateway = tempGateway; #if STACK_USE_DNS if(ValidValues.bits.DNS) AppConfig.PrimaryDNSServer = tempDNS; #endif // if(ValidValues.bits.HostName) // memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName)); DHCPState.bits.bIsBound = TRUE; DHCPBindCount++; return; } } else if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT ) smDHCPState = SM_DHCP_BROADCAST; break; case SM_DHCP_BOUND: // Keep track of how long we use this IP configuration. // When lease period expires, renew the configuration. tickDiff = TickGetDiff(TickGet(), lastTryTick); if(tickDiff >= TICKS_PER_SECOND) { do { DHCPLeaseTime.Val--; tickDiff -= TICKS_PER_SECOND; if(DHCPLeaseTime.Val == 0u) smDHCPState = SM_DHCP_INIT; } while(tickDiff >= TICKS_PER_SECOND); lastTryTick = TickGet() - tickDiff; } } /*if (debugLastState != smDHCPState) { debug_dhcp("\r\nDHCP TASK - ", ); DebugDHCPDisplayState(debugLastState); debug_dhcp(" -> "); DebugDHCPDisplayState(smDHCPState); }*/ }
/********************************************************************* * Function: void StackTask(void) * * PreCondition: StackInit() is already called. * * Input: None * * Output: Stack FSM is executed. * * Side Effects: None * * Note: This FSM checks for new incoming packets, * and routes it to appropriate stack components. * It also performs timed operations. * * This function must be called periodically to * ensure timely responses. * ********************************************************************/ void StackTask(void) { WORD dataCount; IP_ADDR tempLocalIP; BYTE cFrameType; BYTE cIPFrameType; #if defined(STACK_USE_DHCP_CLIENT) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if(AppConfig.Flags.bIsDHCPEnabled) { if(!MACIsLinked()) { AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val; AppConfig.MyMask.Val = AppConfig.DefaultMask.Val; DHCPFlags.bits.bDHCPServerDetected = FALSE; AppConfig.Flags.bInConfigMode = TRUE; DHCPReset(); } // DHCP must be called all the time even after IP configuration is // discovered. // DHCP has to account lease expiration time and renew the configuration // time. DHCPTask(); if(DHCPIsBound()) AppConfig.Flags.bInConfigMode = FALSE; } #endif #if defined(STACK_USE_TCP) // Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc) TCPTick(); #endif // Process as many incomming packets as we can while(MACGetHeader(&remoteNode.MACAddr, &cFrameType)) { switch(cFrameType) { case MAC_ARP: ARPProcess(); break; case MAC_IP: if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount)) break; #if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT) if(cIPFrameType == IP_PROT_ICMP) { ICMPProcess(&remoteNode, dataCount); #if defined(STACK_USE_IP_GLEANING) if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled) { // Accoriding to "IP Gleaning" procedure, // when we receive an ICMP packet with a valid // IP address while we are still in configuration // mode, accept that address as ours and conclude // configuration mode. if(tempLocalIP.Val != 0xffffffff) { AppConfig.Flags.bInConfigMode = FALSE; AppConfig.MyIPAddr = tempLocalIP; myDHCPBindCount--; } } #endif break; } #endif #if defined(STACK_USE_TCP) if(cIPFrameType == IP_PROT_TCP) { TCPProcess(&remoteNode, &tempLocalIP, dataCount); break; } #endif #if defined(STACK_USE_UDP) if(cIPFrameType == IP_PROT_UDP) { UDPProcess(&remoteNode, &tempLocalIP, dataCount); break; } #endif break; } } }
/********************************************************************* * Function: void StackTask(void) * * PreCondition: StackInit() is already called. * * Input: None * * Output: Stack FSM is executed. * * Side Effects: None * * Note: This FSM checks for new incoming packets, * and routes it to appropriate stack components. * It also performs timed operations. * * This function must be called periodically to * ensure timely responses. * ********************************************************************/ void StackTask(void) { WORD dataCount; IP_ADDR tempLocalIP; BYTE cFrameType; BYTE cIPFrameType; #if defined(STACK_USE_DHCP_CLIENT) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if(AppConfig.Flags.bIsDHCPEnabled) { if(!MACIsLinked()) { AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val; AppConfig.MyMask.Val = AppConfig.DefaultMask.Val; DHCPFlags.bits.bDHCPServerDetected = FALSE; AppConfig.Flags.bInConfigMode = TRUE; DHCPReset(); } // DHCP must be called all the time even after IP configuration is // discovered. // DHCP has to account lease expiration time and renew the configuration // time. DHCPTask(); if(DHCPIsBound()) AppConfig.Flags.bInConfigMode = FALSE; } #endif #if defined(STACK_USE_TCP) // Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc) TCPTick(); #endif #if defined(STACK_USE_UDP) UDPTask(); #endif // Process as many incomming packets as we can while(1) { //if using the random module, generate entropy #if defined(STACK_USE_RANDOM) RandomAdd(remoteNode.MACAddr.v[5]); #endif // We are about to fetch a new packet, make sure that the // UDP module knows that any old RX data it has laying // around will now be gone. #if defined(STACK_USE_UDP) UDPDiscard(); #endif // Fetch a packet (throws old one away, if not thrown away // yet) if(!MACGetHeader(&remoteNode.MACAddr, &cFrameType)) break; // Dispatch the packet to the appropriate handler switch(cFrameType) { case MAC_ARP: ARPProcess(); break; case MAC_IP: if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount)) break; #if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT) if(cIPFrameType == IP_PROT_ICMP) { #if defined(STACK_USE_IP_GLEANING) if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled) { // Accoriding to "IP Gleaning" procedure, // when we receive an ICMP packet with a valid // IP address while we are still in configuration // mode, accept that address as ours and conclude // configuration mode. if(tempLocalIP.Val != 0xffffffff) { AppConfig.Flags.bInConfigMode = FALSE; AppConfig.MyIPAddr = tempLocalIP; myDHCPBindCount--; } } #endif // Process this ICMP packet if it the destination IP address matches our address or one of the broadcast IP addressees if( (tempLocalIP.Val == AppConfig.MyIPAddr.Val) || (tempLocalIP.Val == 0xFFFFFFFF) || (tempLocalIP.Val == ((AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) | ~AppConfig.MyMask.Val))) { ICMPProcess(&remoteNode, dataCount); } break; } #endif #if defined(STACK_USE_TCP) if(cIPFrameType == IP_PROT_TCP) { TCPProcess(&remoteNode, &tempLocalIP, dataCount); break; } #endif #if defined(STACK_USE_UDP) if(cIPFrameType == IP_PROT_UDP) { // Stop processing packets if we came upon a UDP frame with application data in it if(UDPProcess(&remoteNode, &tempLocalIP, dataCount)) return; } #endif break; } } }
/* * Main entry point. */ void main(void) { static TICK8 t = 0; static TICK8 tmr10ms = 0; //Initialize any application specific hardware. InitializeBoard(); //Initialize all stack related components. Following steps must //be performed for all applications using PICmicro TCP/IP Stack. TickInit(); //Initialize file system. fsysInit(); //Intialize HTTP Execution unit htpexecInit(); //Initialze serial port serInit(); //Initialize Stack and application related NV variables. appcfgInit(); appcfgUSART(); //Configure the USART #ifdef SER_USE_INTERRUPT //Interrupt enabled serial ports have to be enabled serEnable(); #endif appcfgCpuIO(); //Configure the CPU's I/O port pin directions - input or output appcfgCpuIOValues(); //Configure the CPU's I/O port pin default values appcfgADC(); //Configure ADC unit appcfgPWM(); //Configure PWM Channels //Serial configuration menu - display it for configured time and allow user to enter configuration menu scfInit(appcfgGetc(APPCFG_STARTUP_SER_DLY)); //LCD Display Initialize lcdInit(); StackInit(); #if defined(STACK_USE_HTTP_SERVER) HTTPInit(); #endif #if defined(STACK_USE_FTP_SERVER) FTPInit(); #endif //Initializes "UDP Command Port" and "UDP Command Responce Port". cmdUdpInit(); #if defined(STACK_USE_DHCP) || defined(STACK_USE_IP_GLEANING) DHCPReset(); //Initialize DHCP module //If DHCP is NOT enabled if ((appcfgGetc(APPCFG_NETFLAGS) & APPCFG_NETFLAGS_DHCP) == 0) { //Force IP address display update. myDHCPBindCount = 1; #if defined(STACK_USE_DHCP) DHCPDisable(); #endif } #endif #if (DEBUG_MAIN >= LOG_DEBUG) debugPutMsg(1); //@mxd:1:Starting main loop #endif /* * Once all items are initialized, go into infinite loop and let * stack items execute their tasks. * If 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) { //Clear timer 1 every cycle, can be used to measure events. Has a overflow of 65ms. //Get delay in this function with: // TMR1L | (TMR1H<<8) TMR1H = 0; //First write to TMR1H buffer! TMR1L = 0; //This write will also update TMR1H with value written above to buffer //Blink SYSTEM LED every second. if (appcfgGetc(APPCFG_SYSFLAGS) & APPCFG_SYSFLAGS_BLINKB6) { if ( TickGetDiff8bit(t) >= ((TICK8)TICKS_PER_SECOND / (TICK8)2) ) { t = TickGet8bit(); TRISB_RB6 = 0; LATB6 ^= 1; } } //Enter each 10ms if ( TickGetDiff8bit(tmr10ms) >= ((TICK8)TICKS_PER_SECOND / (TICK8)100) ) { tmr10ms = TickGet8bit(); } //This task performs normal stack task including checking for incoming packet, //type of packet and calling appropriate stack entity to process it. StackTask(); //Process "UDP Command Port" and "UDP Command Responce Port" cmdProcess(); #if defined(STACK_USE_HTTP_SERVER) //This is a TCP application. It listens to TCP port 80 //with one or more sockets and responds to remote requests. HTTPServer(); #endif #if defined(STACK_USE_FTP_SERVER) FTPServer(); #endif #if defined(STACK_USE_ANNOUNCE) DiscoveryTask(); #endif #if defined(STACK_USE_NBNS) NBNSTask(); #endif //Add your application speicifc tasks here. ProcessIO(); //For DHCP information, display how many times we have renewed the IP //configuration since last reset. if ( DHCPBindCount != myDHCPBindCount ) { #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg(2); //@mxd:2:DHCP Bind Count = %D debugPutByteHex(DHCPBindCount); #endif //Display new IP address #if (DEBUG_MAIN >= LOG_INFO) debugPutMsg(3); //@mxd:3:DHCP complete, IP = %D.%D.%D.%D debugPutByteHex(AppConfig.MyIPAddr.v[0]); debugPutByteHex(AppConfig.MyIPAddr.v[1]); debugPutByteHex(AppConfig.MyIPAddr.v[2]); debugPutByteHex(AppConfig.MyIPAddr.v[3]); #endif myDHCPBindCount = DHCPBindCount; #if defined(STACK_USE_ANNOUNCE) AnnounceIP(); #endif } } }
/** * Fetches pending UDP packet from MAC receive buffer and dispatches it appropriate UDP socket. * If not UDP socket is matched, UDP packet is silently discarded. * Note: Caller must make sure that MAC receive buffer * access pointer is set to begining of UDP packet. * Required steps before calling this function is: * * If ( MACIsRxReady() ) * { * MACGetHeader() * If MACFrameType == IP * IPGetHeader() * if ( IPFrameType == IP_PROT_UDP ) * Call DHCPTask() * ... * } * * @@preCondition DHCPInit() is already called AND IPGetHeader() is called with * IPFrameType == IP_PROT_UDP */ void DHCPTask(void) { NODE_INFO DHCPServerNode; static TICK16 lastTryTick; BYTE DHCPRecvReturnValue; static BYTE broadcastCount; switch(smDHCPState) { case SM_DHCP_INIT_FIRST_TIME: tempIPAddress.Val = 0x0; // smDHCPState = SM_DHCP_INIT; // State automatically changes /* No break */ case SM_DHCP_INIT: broadcastCount = 3; DHCPServerNode.MACAddr.v[0] = 0xff; DHCPServerNode.MACAddr.v[1] = 0xff; DHCPServerNode.MACAddr.v[2] = 0xff; DHCPServerNode.MACAddr.v[3] = 0xff; DHCPServerNode.MACAddr.v[4] = 0xff; DHCPServerNode.MACAddr.v[5] = 0xff; DHCPServerNode.IPAddr.Val = 0xffffffff; DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, &DHCPServerNode, DHCP_SERVER_PORT); if( DHCPSocket == INVALID_UDP_SOCKET ) { #if (DEBUG_DHCP >= LOG_ERROR) debugPutMsg(7); //@mxd:7:Could not open UDP socket #endif break; } lastTryTick = TickGet16bit(); smDHCPState = SM_DHCP_RESET_WAIT; /* No break */ case SM_DHCP_RESET_WAIT: //More then 200ms has passed if ( TickGetDiff16bit(lastTryTick) >= ((TICK16)TICKS_PER_SECOND / (TICK16)5) ) smDHCPState = SM_DHCP_BROADCAST; break; case SM_DHCP_BROADCAST: // 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; //After a certian number of tries, give up, and assign a static IP address if (broadcastCount-- == 0) { //Once DCHP is successful, release the UDP socket //This will ensure that UDP layer discards any further DHCP related packets. UDPClose(DHCPSocket); DHCPSocket = INVALID_UDP_SOCKET; smDHCPState = SM_DHCP_BOUND; DHCPState.bits.bIsBound = TRUE; DHCPBindCount++; //Disable DHCP. No more attempts will be made to obtain a IP from the DHCP server, except //if the cable is unplugged. DHCPState.bits.bStaticIP = TRUE; MY_IP_BYTE1 = MY_STATIC_IP_BYTE1; MY_IP_BYTE2 = MY_STATIC_IP_BYTE2; MY_IP_BYTE3 = MY_STATIC_IP_BYTE3; MY_IP_BYTE4 = MY_STATIC_IP_BYTE4; #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(10); //@mxd:10:Maxumum Broadcast tries, assigned static IP address #endif return; } // If we have already obtained some IP address, renew it. if(DHCPState.bits.bIsBound) { smDHCPState = SM_DHCP_REQUEST; } else if ( UDPIsPutReady(DHCPSocket) ) { // To minimize code requirement, user must make sure that // above call will be successful by making at least one // UDP socket available. // Usually this will be the case, given that DHCP will be // the first one to use UDP socket. // Also, we will not check for transmitter readiness, // we assume it to be ready. _DHCPSend(DHCP_DISCOVER_MESSAGE); ValidValues.Val = 0x00; // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(1); //@mxd:1:Broadcast #endif lastTryTick = TickGet16bit(); smDHCPState = SM_DHCP_DISCOVER; } else { // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(8); //@mxd:8:Can not Broadcase, UDP Not ready! #endif } break; case SM_DHCP_DISCOVER: if ( TickGetDiff16bit(lastTryTick) >= DHCP_TIMEOUT) //Timeout has expired { smDHCPState = SM_DHCP_BROADCAST; // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(9); //@mxd:9:Discover time out #endif break; } if ( UDPIsGetReady(DHCPSocket) ) { // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(2); //@mxd:2:Discover #endif if ( _DHCPReceive() == DHCP_OFFER_MESSAGE ) { // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(3); //@mxd:3:Offer Message #endif smDHCPState = SM_DHCP_REQUEST; } else break; } else break; case SM_DHCP_REQUEST: if ( UDPIsPutReady(DHCPSocket) ) { _DHCPSend(DHCP_REQUEST_MESSAGE); lastTryTick = TickGet16bit(); smDHCPState = SM_DHCP_BIND; // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(12); //@mxd:12:Sending Request #endif } break; case SM_DHCP_BIND: if ( UDPIsGetReady(DHCPSocket) ) { DHCPRecvReturnValue = _DHCPReceive(); if ( DHCPRecvReturnValue == DHCP_NAK_MESSAGE ) { // (RSS) NAK recieved. DHCP server didn't like our DHCP Request (format wrong/IP address allocated to someone else/outside IP pool) #if (DEBUG_DHCP >= LOG_WARN) debugPutMsg(4); //@mxd:4:NAK recieved (RSS). DHCP server didn't like our DHCP Request format #endif DHCPReset(); // Start all over again return; } else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE ) { // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(5); //@mxd:5:ACK Received #endif // Once DCHP is successful, release the UDP socket // This will ensure that UDP layer discards any further DHCP related packets. UDPClose(DHCPSocket); DHCPSocket = INVALID_UDP_SOCKET; lastTryTick = TickGet16bit(); smDHCPState = SM_DHCP_BOUND; if(ValidValues.bits.IPAddress) { MY_IP_BYTE1 = tempIPAddress.v[0]; MY_IP_BYTE2 = tempIPAddress.v[1]; MY_IP_BYTE3 = tempIPAddress.v[2]; MY_IP_BYTE4 = tempIPAddress.v[3]; } if(ValidValues.bits.Mask) { MY_MASK_BYTE1 = tempMask.v[0]; MY_MASK_BYTE2 = tempMask.v[1]; MY_MASK_BYTE3 = tempMask.v[2]; MY_MASK_BYTE4 = tempMask.v[3]; } if(ValidValues.bits.Gateway) { MY_GATE_BYTE1 = tempGateway.v[0]; MY_GATE_BYTE2 = tempGateway.v[1]; MY_GATE_BYTE3 = tempGateway.v[2]; MY_GATE_BYTE4 = tempGateway.v[3]; } #if defined(STACK_USE_DNS) if(ValidValues.bits.DNS) { MY_DNS_BYTE1_SET(tempDNS.v[0]); MY_DNS_BYTE2_SET(tempDNS.v[1]); MY_DNS_BYTE3_SET(tempDNS.v[2]); MY_DNS_BYTE4_SET(tempDNS.v[3]); } #endif // if(ValidValues.bits.HostName) // memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName)); DHCPState.bits.bIsBound = TRUE; DHCPBindCount++; return; } } else if ( TickGetDiff16bit(lastTryTick) >= DHCP_TIMEOUT ) //Timeout has expired { #if (DEBUG_DHCP >= LOG_WARN) debugPutMsg(6); //@mxd:6:Timeout #endif smDHCPState = SM_DHCP_BROADCAST; } break; case SM_DHCP_BOUND: //If a static IP was assigned, it never times out. Only when the cable is unplugged, will //the DHCP server be reset, and start looking for an IP again. if (DHCPState.bits.bStaticIP) return; // Keep track of how long we use this IP configuration. // When lease period expires, renew the configuration. while ( TickGetDiff16bit(lastTryTick) >= ((TICK16)TICKS_PER_SECOND) ) { DHCPLeaseTime.Val--; //Decrement lease time if ( DHCPLeaseTime.Val == 0 ) { smDHCPState = SM_DHCP_INIT; // DEBUG #if (DEBUG_DHCP >= LOG_INFO) debugPutMsg(11); //@mxd:11:Lease time expired #endif } //Add 1 seconds to lastTryTick - will cause this statement to execute in 1 second again lastTryTick += ((TICK16)TICKS_PER_SECOND); //Add 1 second to lastTryTick } } }