static void USARTPutString(BYTE *s) { BYTE c; while( (c = *s++) ) USARTPut(c); }
void USARTPutROMString(ROM char* str) { BYTE v; while( v = *str++ ) USARTPut(v); }
/********************************************************************* * Function: void SMTPSend(void) * * PreCondition: SMTP module is already initialized. * * Input: None * * Output: None * * Side Effects: None * * Overview: Triggers sending of mail * This function must be called when the application * Wants to send a mail. * Note: ********************************************************************/ void SMTPSend() { if (smSMTP == SM_SMTP_STDBY) { // check if standby (do not overtrigger) lastActivity = TickGet(); // init delay before sending cptretry = NRETRY ; // retry count fsend_mail = TRUE ; // flag for State machine ! USARTPut(0xAA) ; } }
static void ProcessIO(void) { char i; char temp_buff[10]; int read_temp; float real_temp,temp_count; //Get raw data from DS1820 convert(temp_buff); //Convert raw data to degree C in accorance with datasheet read_temp=((temp_buff[1]<<8) | temp_buff[0]) >> 1; temp_count=(float)(temp_buff[7] - temp_buff[6])/(float)temp_buff[7]; real_temp = ((float)read_temp-0.25)+temp_count; sprintf(AN1String,"%2.2f",real_temp); USARTPutString((BYTE*)AN1String); USARTPut(0x0D); USARTPut(0x0a); }
static void DisplayIPValue(IP_ADDR *IPVal, BOOL bToLCD) { char IPDigit[8]; #if defined(APP_USE_LCD) if ( bToLCD ) { /* * Erase second line. */ XLCDGoto(1, 0); XLCDPutROMString(blankLCDLine); } #endif /* * Rewrite the second line. */ #if defined(APP_USE_LCD) XLCDGoto(1, 0); #endif itoa(IPVal->v[0], IPDigit); #if defined(APP_USE_LCD) if ( bToLCD ) { XLCDPutString(IPDigit); XLCDPut('.'); } else #endif { USARTPutString((BYTE*)IPDigit); USARTPut('.'); } itoa(IPVal->v[1], IPDigit); #if defined(APP_USE_LCD) if ( bToLCD ) { XLCDPutString(IPDigit); XLCDPut('.'); } else #endif { USARTPutString((BYTE*)IPDigit); USARTPut('.'); } itoa(IPVal->v[2], IPDigit); #if defined(APP_USE_LCD) if ( bToLCD ) { XLCDPutString(IPDigit); XLCDPut('.'); } else #endif { USARTPutString((BYTE*)IPDigit); USARTPut('.'); } itoa(IPVal->v[3], IPDigit); #if defined(APP_USE_LCD) if ( bToLCD ) XLCDPutString(IPDigit); else #endif { USARTPutString((BYTE*)IPDigit); } }
/* * Main entry point. */ void main(void) { static TICK t = 0; BYTE c, i; /* * 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(); /* * Following steps must be performed for all applications using * PICmicro TCP/IP Stack. */ MPFSInit(); /* * Initialize Stack and application related NV variables. */ InitAppConfig(); /* * Depending on whether internal program memor is used or external * EEPROM is used, keep/remove these block. */ /* * Wait a couple of seconds for user input. * - If something is detected, start config. * - If nothing detected, start main program. */ USARTPutROMString(PressKeyForConfig); for (i = 60; i > 0; --i) //Delay for 50mS x 60 = 3 sec { if ((i % 8) == 0) USARTPut('.'); if (USARTIsGetReady()) { #if defined(APP_USE_LCD) XLCDGoto(1, 0); XLCDPutROMString(SetupMsg); #endif SetConfig(); break; } DelayMs(50); } USARTPut('\r'); USARTPut('\n'); StackInit(); #if defined(STACK_USE_HTTP_SERVER) HTTPInit(); #endif #if defined(STACK_USE_FTP_SERVER) && defined(MPFS_USE_EEPROM) FTPInit(); #endif #if defined(STACK_USE_DHCP) || defined(STACK_USE_IP_GLEANING) if ( AppConfig.Flags.bIsDHCPEnabled ) { #if defined(APP_USE_LCD) XLCDGoto(1, 0); XLCDPutROMString(DHCPMsg); #endif } else { /* * Force IP address display update. */ myDHCPBindCount = 1; #if defined(STACK_USE_DHCP) DHCPDisable(); #endif } #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) { //Turn off the heater after about 1min to prevent over heating if(heater_started ==1) { if ( TickGetDiff(TickGet(), t) >= 9000 ) { LATB4 = 0; heater_started = 0; } }else { t = TickGet(); } /* * This task performs normal stack task including checking * for incoming packet, type of packet and calling * appropriate stack entity to process it. */ StackTask(); #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) && defined(MPFS_USE_EEPROM) FTPServer(); #endif /* * In future, as new TCP/IP applications are written, it * will be added here as new tasks. */ /* * 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 ) { DisplayIPValue(&AppConfig.MyIPAddr, TRUE); myDHCPBindCount = DHCPBindCount; #if defined(APP_USE_LCD) if ( AppConfig.Flags.bIsDHCPEnabled ) { XLCDGoto(1, 14); if ( myDHCPBindCount < 0x0a ) XLCDPut(myDHCPBindCount + '0'); else XLCDPut(myDHCPBindCount + 'A'); } #endif } } }
static BOOL DownloadMPFS(void) { enum SM_MPFS { SM_MPFS_SOH, SM_MPFS_BLOCK, SM_MPFS_BLOCK_CMP, SM_MPFS_DATA, } state; BYTE c; MPFS handle; BOOL lbDone; BYTE blockLen; BYTE lResult; BYTE tempData[XMODEM_BLOCK_LEN]; TICK lastTick; TICK currentTick; state = SM_MPFS_SOH; lbDone = FALSE; handle = MPFSFormat(); /* * Notify the host that we are ready to receive... */ lastTick = TickGet(); do { /* * Update tick here too - just in case interrupt is not used. */ TickUpdate(); currentTick = TickGet(); if ( TickGetDiff(currentTick, lastTick) >= (TICK_SECOND/2) ) { lastTick = TickGet(); USARTPut(XMODEM_NAK); /* * Blink LED to indicate that we are waiting for * host to send the file. */ //LATA2 ^= 1; } } while( !USARTIsGetReady() ); while(!lbDone) { /* * Update tick here too - just in case interrupt is not used. */ TickUpdate(); if ( USARTIsGetReady() ) { /* * Toggle LED as we receive the data from host. */ //LATA2 ^= 1; c = USARTGet(); } else { /* * Real application should put some timeout to make sure * that we do not wait forever. */ continue; } switch(state) { default: if ( c == XMODEM_SOH ) { state = SM_MPFS_BLOCK; } else if ( c == XMODEM_EOT ) { /* * Turn off LED when we are done. */ //LATA2 = 1; MPFSClose(); USARTPut(XMODEM_ACK); lbDone = TRUE; } else USARTPut(XMODEM_NAK); break; case SM_MPFS_BLOCK: /* * We do not use block information. */ lResult = XMODEM_ACK; blockLen = 0; state = SM_MPFS_BLOCK_CMP; break; case SM_MPFS_BLOCK_CMP: /* * We do not use 1's comp. block value. */ state = SM_MPFS_DATA; break; case SM_MPFS_DATA: /* * Buffer block data until it is over. */ tempData[blockLen++] = c; if ( blockLen > XMODEM_BLOCK_LEN ) { /* * We have one block data. * Write it to EEPROM. */ MPFSPutBegin(handle); lResult = XMODEM_ACK; for ( c = 0; c < XMODEM_BLOCK_LEN; c++ ) MPFSPut(tempData[c]); handle = MPFSPutEnd(); USARTPut(lResult); state = SM_MPFS_SOH; } break; } } /* * This small wait is required if SLIP is in use. * If this is not used, PC might misinterpret SLIP * module communication and never close file transfer * dialog box. */ #if defined(STACK_USE_SLIP) { BYTE i; i = 255; while( i-- ); } #endif return TRUE; }
void ExecuteMenuChoice(MENU_CMD choice) { char response[MAX_USER_RESPONSE_LEN]; IP_ADDR tempIPValue; IP_ADDR *destIPValue; USARTPut('\r'); USARTPut('\n'); USARTPutROMString(menuCommandPrompt[choice-'0'-1]); switch(choice) { case MENU_CMD_SERIAL_NUMBER: itoa(AppConfig.SerialNumber.Val, response); USARTPutString((BYTE*)response); USARTPut(')'); USARTPut(':'); USARTPut(' '); if ( USARTGetString(response, sizeof(response)) ) { AppConfig.SerialNumber.Val = atoi(response); AppConfig.MyMACAddr.v[4] = AppConfig.SerialNumber.v[1]; AppConfig.MyMACAddr.v[5] = AppConfig.SerialNumber.v[0]; } else goto HandleInvalidInput; break; case MENU_CMD_IP_ADDRESS: destIPValue = &AppConfig.MyIPAddr; goto ReadIPConfig; case MENU_CMD_GATEWAY_ADDRESS: destIPValue = &AppConfig.MyGateway; goto ReadIPConfig; case MENU_CMD_SUBNET_MASK: destIPValue = &AppConfig.MyMask; ReadIPConfig: DisplayIPValue(destIPValue, FALSE); USARTPut(')'); USARTPut(':'); USARTPut(' '); USARTGetString(response, sizeof(response)); if ( !StringToIPAddress(response, &tempIPValue) ) { HandleInvalidInput: USARTPutROMString(InvalidInputMsg); while( !USARTIsGetReady() ); USARTGet(); } else { destIPValue->Val = tempIPValue.Val; } break; case MENU_CMD_ENABLE_AUTO_CONFIG: AppConfig.Flags.bIsDHCPEnabled = TRUE; break; case MENU_CMD_DISABLE_AUTO_CONFIG: AppConfig.Flags.bIsDHCPEnabled = FALSE; break; case MENU_CMD_DOWNLOAD_MPFS: #if defined(MPFS_USE_EEPROM) DownloadMPFS(); #endif break; case MENU_CMD_QUIT: #if defined(MPFS_USE_EEPROM) SaveAppConfig(); #endif break; } }
static BOOL PutFile(void) { BYTE v; switch(smFTPCommand) { case SM_FTP_CMD_IDLE: if ( !FTPFlags.Bits.bLoggedIn ) { FTPResponse = FTP_RESP_LOGIN; return TRUE; } else { FTPResponse = FTP_RESP_DATA_OPEN; FTPDataSocket = TCPConnect(&REMOTE_HOST(FTPSocket), FTPDataPort.Val); // Make sure that a valid socket was available and returned // If not, return with an error if(FTPDataSocket != INVALID_SOCKET) { smFTPCommand = SM_FTP_CMD_WAIT; } else { FTPResponse = FTP_RESP_DATA_NO_SOCKET; return TRUE; } } break; case SM_FTP_CMD_WAIT: if ( TCPIsConnected(FTPDataSocket) ) { #if defined(FTP_PUT_ENABLED) if ( !MPFSIsInUse() ) #endif { #if defined(FTP_PUT_ENABLED) FTPFileHandle = MPFSFormat(); #endif smFTPCommand = SM_FTP_CMD_RECEIVE; } } break; case SM_FTP_CMD_RECEIVE: if ( TCPIsGetReady(FTPDataSocket) ) { // Reload timeout timer. lastActivity = TickGet(); MPFSPutBegin(FTPFileHandle); while( TCPGet(FTPDataSocket, &v) ) { USARTPut(v); #if defined(FTP_PUT_ENABLED) MPFSPut(v); #endif } FTPFileHandle = MPFSPutEnd(); TCPDiscard(FTPDataSocket); // Print hash characters on FTP client display if(TCPIsPutReady(FTPSocket)) { TCPPut(FTPSocket, '#'); TCPFlush(FTPSocket); } } else if ( !TCPIsConnected(FTPDataSocket) ) { #if defined(FTP_PUT_ENABLED) MPFSPutEnd(); MPFSClose(); #endif TCPDisconnect(FTPDataSocket); FTPDataSocket = INVALID_SOCKET; FTPResponse = FTP_RESP_DATA_CLOSE; return TRUE; } } return FALSE; }
/********************************************************************* * Function: void FTPServer(void) * * PreCondition: FTPInit() must already be called. * * Input: None * * Output: Opened FTP connections are served. * * Side Effects: None * * Overview: * * Note: This function acts as a task (similar to one in * RTOS). This function performs its task in * co-operative manner. Main application must call * this function repeatdly to ensure all open * or new connections are served on time. ********************************************************************/ BOOL FTPServer(void) { BYTE v; TICK currentTick; if ( !TCPIsConnected(FTPSocket) ) { FTPStringLen = 0; FTPCommand = FTP_CMD_NONE; smFTP = SM_FTP_NOT_CONNECTED; FTPFlags.Val = 0; smFTPCommand = SM_FTP_CMD_IDLE; return TRUE; } if ( TCPIsGetReady(FTPSocket) ) { lastActivity = TickGet(); while( TCPGet(FTPSocket, &v ) ) { USARTPut(v); FTPString[FTPStringLen++] = v; if ( FTPStringLen == MAX_FTP_CMD_STRING_LEN ) FTPStringLen = 0; } TCPDiscard(FTPSocket); if ( v == '\n' ) { FTPString[FTPStringLen] = '\0'; FTPStringLen = 0; ParseFTPString(); FTPCommand = ParseFTPCommand(FTP_argv[0]); } } else if ( smFTP != SM_FTP_NOT_CONNECTED ) { currentTick = TickGet(); currentTick = TickGetDiff(currentTick, lastActivity); if ( currentTick >= FTP_TIMEOUT ) { lastActivity = TickGet(); FTPCommand = FTP_CMD_QUIT; smFTP = SM_FTP_CONNECTED; } } switch(smFTP) { case SM_FTP_NOT_CONNECTED: FTPResponse = FTP_RESP_BANNER; lastActivity = TickGet(); /* No break - Continue... */ case SM_FTP_RESPOND: SM_FTP_RESPOND_Label: if(!TCPIsPutReady(FTPSocket)) { return TRUE; } else { ROM char* pMsg; pMsg = FTPResponseString[FTPResponse]; while( (v = *pMsg++) ) { USARTPut(v); TCPPut(FTPSocket, v); } TCPFlush(FTPSocket); FTPResponse = FTP_RESP_NONE; smFTP = SM_FTP_CONNECTED; } // No break - this will speed up little bit case SM_FTP_CONNECTED: if ( FTPCommand != FTP_CMD_NONE ) { if ( ExecuteFTPCommand(FTPCommand) ) { if ( FTPResponse != FTP_RESP_NONE ) smFTP = SM_FTP_RESPOND; else if ( FTPCommand == FTP_CMD_QUIT ) smFTP = SM_FTP_NOT_CONNECTED; FTPCommand = FTP_CMD_NONE; smFTPCommand = SM_FTP_CMD_IDLE; } else if ( FTPResponse != FTP_RESP_NONE ) { smFTP = SM_FTP_RESPOND; goto SM_FTP_RESPOND_Label; } } break; } return TRUE; }
/********************************************************************* * Function: void SMTP Client State machine(void) * * PreCondition: FTPInit() must already be called. * * Input: None * * Output: Ready to send mail. * * Side Effects: None * * Overview: * * Note: This function acts as a task (similar to one in * RTOS). This function performs its task in * co-operative manner. Main application must call * this function repeatedly to ensure it can send * mails when requested. (include in the main loop) ********************************************************************/ void SMTPClient(void) { BYTE v; // TICK currentTick; // check if state machine is stuck somewhere and reset the SM after a while if needed : if ((smSMTP != SM_SMTP_STDBY) && (TickGetDiff(TickGet(), lastActivity) > (15 * TICK_SECOND))) { if (TCPIsConnected(SMTPSocket)) TCPDisconnect(SMTPSocket) ; if(cptretry--) { // if not all retries done... lastActivity = TickGet(); // re-init delay smSMTP = SM_SMTP_STDBY ; // force standby state } else { fsend_mail = FALSE ; // give up ! smSMTP = SM_SMTP_STDBY ; // -> standby } } // work each state : switch(smSMTP) { case SM_SMTP_STDBY: // standby: idle, waiting for connection request if (fsend_mail) { if (TickGetDiff(TickGet(), lastActivity) > (10 * TICK_SECOND)) { USARTPut(0xBB) ; lastActivity = TickGet(); ARPResolve(&nodedist.IPAddr) ; // resolve IP adress smSMTP = SM_SMTP_ARP ; // -> wait ARP answer } } break ; case SM_SMTP_ARP: // wait ARP to be resolved if ( ARPIsResolved(&nodedist.IPAddr, &nodedist.MACAddr)) { SMTPSocket = TCPConnect(&nodedist, SMTP_PORT) ; if (SMTPSocket == INVALID_SOCKET) { fsend_mail = FALSE ; // avorte } else { smSMTP = SM_SMTP_CONNECT ; // -> attente ACK } } break ; case SM_SMTP_CONNECT: // standby: attente ack connexion if (TCPIsConnected(SMTPSocket)) { smSMTP = SM_SMTP_WELCOME ; // -> attente WELCOME } break ; case SM_SMTP_WELCOME: // attente welcome du serveur if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket, &v)) { if (v == '2') { // commence par un 2 ? (220..) TCPDiscard(SMTPSocket) ; ExecuteSMTPCommand(SMTP_CMD_HELO) ; smSMTP = SM_SMTP_HELO ; // -> attente reponse au HELO }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_HELO: // attente HELO du serveur if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket,&v)) { if (v == '2') { // commence par un 2 ? (220..) TCPDiscard(SMTPSocket) ; ExecuteSMTPCommand(SMTP_CMD_FROM) ; smSMTP = SM_SMTP_FROM ; // -> attente reponse au FROM }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_FROM: // attente HELO du serveur if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket,&v)) { if (v == '2') { // commence par un 2 ? (220..) TCPDiscard(SMTPSocket) ; ExecuteSMTPCommand(SMTP_CMD_TO) ; smSMTP = SM_SMTP_TO ; // -> attente reponse au TO }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_TO: // attente HELO du serveur if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket,&v)) { if (v == '2') { // commence par un 2 ? (220..) TCPDiscard(SMTPSocket) ; ExecuteSMTPCommand(SMTP_CMD_DATA) ; smSMTP = SM_SMTP_DATA1 ; // -> attente reponse au DATA }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_DATA1: // when OK send message headers if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket,&v)) { if (v == '3') { // commence par un 3 ? (220..) TCPDiscard(SMTPSocket) ; ExecuteSMTPCommand(SMTP_CMD_DATA_HEADERS) ; // send headers // ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ; // message // ExecuteSMTPCommand(SMTP_CMD_DATA_END) ; // termine smSMTP = SM_SMTP_DATA2; // -> send body }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_DATA2: // wait to send message body if (TCPIsPutReady(SMTPSocket)) { // wait for TX buffer free ExecuteSMTPCommand(SMTP_CMD_DATA_MESSAGE) ; // message smSMTP = SM_SMTP_DATA3 ; // -> attente reponse au TO } else { // USARTPut(0xCC) ; vérifié qu'il y avait bien besoin d'une attente ici } break ; case SM_SMTP_DATA3: // wait to send the final "." if (TCPIsPutReady(SMTPSocket)) { // wait for TX buffer free ExecuteSMTPCommand(SMTP_CMD_DATA_END) ; // termine smSMTP = SM_SMTP_QUIT ; // -> end } else { // USARTPut(0xDD) ; vérifié qu'il y avait bien besoin d'une attente ici } break ; case SM_SMTP_QUIT: // wait last message before leaving... if (TCPIsGetReady(SMTPSocket)) { if (TCPGet(SMTPSocket,&v)) { if (v == '2') { // commence par un 2 ? (220..) TCPDiscard(SMTPSocket) ; smSMTP = SM_SMTP_DONE ; // -> deconnecte }else { smSMTP = SM_SMTP_DONE ; // -> disconnect } } } break ; case SM_SMTP_DONE: // disconnect Socket : if (TCPIsConnected(SMTPSocket) && (TCPIsPutReady(SMTPSocket))) { // wait for TX buff free TCPDisconnect(SMTPSocket) ; } fsend_mail = FALSE ; // done ! smSMTP = SM_SMTP_STDBY ; // -> standby break ; } }
/********************************************************************* * 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 TICK lastTryTick; BYTE DHCPRecvReturnValue; switch(smDHCPState) { case SM_DHCP_INIT: 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; tempIPAddress.Val = 0x0; 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) >= (TICK_SECOND/(TICK)5) ) smDHCPState = SM_DHCP_BROADCAST; break; case SM_DHCP_BROADCAST: /* * If we have already obtained some IP address, renew it. */ if ( tempIPAddress.Val != 0x00000 ) { 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); // DEBUG USARTPut('\n'); USARTPut('\r'); USARTPut('D'); lastTryTick = TickGet(); smDHCPState = SM_DHCP_DISCOVER; } break; case SM_DHCP_DISCOVER: if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT ) { smDHCPState = SM_DHCP_BROADCAST; //return; } if ( UDPIsGetReady(DHCPSocket) ) { // DEBUG USARTPut('R'); if ( _DHCPReceive() == DHCP_OFFER_MESSAGE ) { // DEBUG USARTPut('O'); 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; } 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 USARTPut('n'); smDHCPState = SM_DHCP_REQUEST; // Request again } else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE ) { // DEBUG USARTPut('B'); /* * 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; MY_IP_BYTE1 = tempIPAddress.v[0]; MY_IP_BYTE2 = tempIPAddress.v[1]; MY_IP_BYTE3 = tempIPAddress.v[2]; MY_IP_BYTE4 = tempIPAddress.v[3]; MY_MASK_BYTE1 = tempMask.v[0]; MY_MASK_BYTE2 = tempMask.v[1]; MY_MASK_BYTE3 = tempMask.v[2]; MY_MASK_BYTE4 = tempMask.v[3]; MY_GATE_BYTE1 = tempGateway.v[0]; MY_GATE_BYTE2 = tempGateway.v[1]; MY_GATE_BYTE3 = tempGateway.v[2]; MY_GATE_BYTE4 = tempGateway.v[3]; DHCPState.bits.bIsBound = TRUE; DHCPBindCount++; return; } } else if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT ) { USARTPut('t'); 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. */ if ( TickGetDiff(TickGet(), lastTryTick) >= TICK_SECOND ) { DHCPLeaseTime.Val -= 1; if ( DHCPLeaseTime.Val == 0 ) smDHCPState = SM_DHCP_INIT; lastTryTick = TickGet(); } } }