/* This function is similar to the 'tcpip_thread' function defined in the tcpip.c module */ void lwip_process_timers (void) { unsigned int CurrentTickCnt; #if LWIP_TCP static unsigned int lwip_tcp_timer = 0; #endif #if LWIP_ARP static unsigned int lwip_arp_timer = 0; #endif CurrentTickCnt = TickGet (); #if LWIP_DHCP static unsigned int lwip_DHCP_fine_timer = 0; static unsigned int lwip_DHCP_coarce_timer = 0; #endif #if LWIP_AUTOIP static unsigned int lwip_autoip_timer = 0; #endif #if LWIP_ARP /* Process the ARP timer */ if(TickGetDiff (CurrentTickCnt, lwip_arp_timer) >= TICKS_IN_MS(ARP_TMR_INTERVAL)) { lwip_arp_timer = CurrentTickCnt; etharp_tmr(); } #endif #if LWIP_TCP /* Process the TCP timer */ if (TickGetDiff (CurrentTickCnt, lwip_tcp_timer) >= TICKS_IN_MS(TCP_TMR_INTERVAL)) { lwip_tcp_timer = CurrentTickCnt; /* Increment fast (incremented every 250ms) and slow (incremented every 500ms) tcp timers */ tcp_tmr (); } #endif #if LWIP_DHCP /* Process the DHCP Coarce timer */ if (TickGetDiff (CurrentTickCnt, lwip_DHCP_coarce_timer) >= TICKS_IN_MS(DHCP_COARSE_TIMER_MSECS)) { lwip_DHCP_coarce_timer = CurrentTickCnt; dhcp_coarse_tmr (); } /* Process the DHCP Fine timer */ if (TickGetDiff (CurrentTickCnt, lwip_DHCP_fine_timer) >= TICKS_IN_MS(DHCP_FINE_TIMER_MSECS)) { lwip_DHCP_fine_timer = CurrentTickCnt; dhcp_fine_tmr (); } #endif #if LWIP_AUTOIP /* Process the DHCP Fine timer */ if (TickGetDiff (CurrentTickCnt, lwip_autoip_timer) >= TICKS_IN_MS(AUTOIP_TMR_INTERVAL)) { lwip_autoip_timer = CurrentTickCnt; autoip_tmr (); } #endif }
/********************************************************************* * Function: void MRF24J40Wake(void) * * PreCondition: BoardInit (or other initialzation code is required) * * Input: None * * Output: None * * Side Effects: the ZigBee stack is initialized * * Overview: This function initializes the ZigBee stack and is required * before stack operations can continue ********************************************************************/ void MRF24J40Wake(void) { BYTE results; TICK failureTimer; TICK currentDifference; //;wake up the device PHY_WAKE = 1; failureTimer = TickGet(); while(1) { currentDifference = TickGet(); currentDifference.Val = TickGetDiff(currentDifference,failureTimer); if(currentDifference.Val > 6250) { break; } results = PHYGetShortRAMAddr(ISRSTS); if((results & 0x40)) { break; } } while(1) { currentDifference = TickGet(); currentDifference.Val = TickGetDiff(currentDifference, failureTimer); if( currentDifference.Val > 6250 ) { break; } results = PHYGetLongRAMAddr(RFSTATE); if( (results & 0xE0) == 0xA0 ) { break; } } /* Keep track of radio status - now awake */ #if defined(I_AM_RFD) ZigBeeStatus.flags.bits.bRadioIsSleeping = 0; #endif }
void TimeOutTime(void) { TICK currentTime; currentTime = TickGet(); if( ( TickGetDiff( currentTime, TimeOutStartTime ) ) > (ONE_SECOND) *2) { ScanResponceReceived = 1; TimeOutStartTime = TickGet(); } }
/********************************************************************* * 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; }
/********************************************************************* * Function: void MRF24J40Wake(void) * * PreCondition: BoardInit (or other initialzation code is required) * * Input: None * * Output: None * * Side Effects: the ZigBee stack is initialized * * Overview: This function initializes the ZigBee stack and is required * before stack operations can continue ********************************************************************/ void MRF24J40Wake(void) { BYTE results; TICK failureTimer; TICK currentDifference; //;wake up the device PHY_WAKE = 1; failureTimer = TickGet(); //these commands in the following of this function are added by lab411 @dat_a3cbq91 // Initialisation, only one time needed PHY_WAKE_TRIS = 0; //Set PHY_Wake to 0 that we can pull it high to activat MRF24J40 PHY_WAKE = 0; //1. Set Short Reg 0x22 to be 0x80 (TXBCNINTL) PHYSetShortRAMAddr(TXBCNINTL,0x80); //2. Set Short Reg 0x0D to be 0x60 (RXFLUSH) PHYSetShortRAMAddr(RXFLUSH,0x60); //3. Set Short Reg 0x35 to be 0x80 (SLPACK) PHYSetShortRAMAddr(SLPACK,0x80); while(1) { currentDifference = TickGet(); currentDifference.Val = TickGetDiff(currentDifference, failureTimer); if( currentDifference.Val > FIVE_MILI_SECOND ) { break; } } // Re-enable PA/LNA module PHYSetShortRAMAddr(WRITE_GPIODIR, 0x00); PHYSetLongRAMAddr(TESTMODE, 0x0F); /* Keep track of radio status - now awake */ #if defined(I_AM_RFD) ZigBeeStatus.flags.bits.bRadioIsSleeping = 0; #endif }
/********************************************************************* * Function: TFTP_RESULT TFTPIsPutReady(void) * * PreCondition: TFTPOpenFile() is called with TFTP_FILE_MODE_WRITE * and TFTPIsFileOpened() returned with TRUE. * * Input: None * * Output: TFTP_OK if it is okay to write more data byte. * * TFTP_TIMEOUT if timeout occurred waiting for * ack from server * * TFTP_RETRY if all server did not send ack * on time and application needs to resend * last block. * * TFTP_ERROR if remote server returned ERROR. * Actual error code may be read by calling * TFTPGetError() * * TFTP_NOT_READY if still waiting... * * Side Effects: None * * Overview: Waits for ack from server. If ack does not * arrive within specified timeout, it it instructs * application to retry last block by returning * TFTP_RETRY. * * If all attempts are exhausted, it returns with * TFTP_TIMEOUT. * * Note: None ********************************************************************/ TFTP_RESULT TFTPIsPutReady(void) { WORD_VAL opCode; WORD_VAL blockNumber; BOOL bTimeOut; // Check to see if timeout has occurred. bTimeOut = FALSE; if ( TickGetDiff(TickGet(), _tftpStartTick) >= TFTP_GET_TIMEOUT_VAL ) { bTimeOut = TRUE; _tftpStartTick = TickGet(); } switch(_tftpState) { case SM_TFTP_WAIT_FOR_ACK: // When timeout occurs in this state, application must retry. if ( bTimeOut ) { if ( _tftpRetries++ > (TFTP_MAX_RETRIES-1) ) { DEBUG(printf("TFTPIsPutReady(): Timeout.\n")); // Forget about all previous attempts. _tftpRetries = 1; return TFTP_TIMEOUT; } else { DEBUG(printf("TFTPIsPutReady(): Retry.\n")); return TFTP_RETRY; } } // Must wait for ACK from server before we transmit next block. if ( !UDPIsGetReady(_tftpSocket) ) break; // Get opCode. UDPGet(&opCode.byte.MSB); UDPGet(&opCode.byte.LSB); // Get block number. UDPGet(&blockNumber.byte.MSB); UDPGet(&blockNumber.byte.LSB); // Discard everything else. UDPDiscard(); // This must be ACK or else there is a problem. if ( opCode.Val == TFTP_OPCODE_ACK ) { // Also the block number must match with what we are expecting. if ( MutExVar.group2._tftpBlockNumber.Val == blockNumber.Val ) { // Mark that block we sent previously has been ack'ed. _tftpFlags.bits.bIsAcked = TRUE; // Since we have ack, forget about previous retry count. _tftpRetries = 1; // If this file is being closed, this must be last ack. // Declare it as closed. if ( _tftpFlags.bits.bIsClosing ) { _tftpFlags.bits.bIsClosed = TRUE; return TFTP_OK; } // Or else, wait for put to become ready so that caller // can transfer more data blocks. _tftpState = SM_TFTP_WAIT; } else { DEBUG(printf("TFTPIsPutReady(): "\ "Unexpected block %d received - droping it...\n", \ blockNumber.Val)); return TFTP_NOT_READY; } } else if ( opCode.Val == TFTP_OPCODE_ERROR ) { // For error opCode, remember error code so that application // can read it later. _tftpError = blockNumber.Val; // Declare error. return TFTP_ERROR; } else break; case SM_TFTP_WAIT: // Wait for UDP is to be ready to transmit. if ( UDPIsPutReady(_tftpSocket) ) { // Put next block of data. MutExVar.group2._tftpBlockNumber.Val++; UDPPut(0); UDPPut(TFTP_OPCODE_DATA); UDPPut(MutExVar.group2._tftpBlockNumber.byte.MSB); UDPPut(MutExVar.group2._tftpBlockNumber.byte.LSB); // Remember that this block is not yet flushed. _tftpFlags.bits.bIsFlushed = FALSE; // Remember that this block is not acknowledged. _tftpFlags.bits.bIsAcked = FALSE; // Now, TFTP module is ready to put more data. _tftpState = SM_TFTP_READY; return TFTP_OK; } break; case SM_TFTP_READY: // TFTP module is said to be ready only when underlying UDP // is ready to transmit. if ( UDPIsPutReady(_tftpSocket) ) return TFTP_OK; } return TFTP_NOT_READY; }
/********************************************************************* * Function: TFTP_RESULT TFTPIsGetReady(void) * * PreCondition: TFTPOpenFile() is called with TFTP_FILE_MODE_READ * and TFTPIsFileOpened() returned with TRUE. * * Input: None * * Output: TFTP_OK if it there is more data byte available * to read * * TFTP_TIMEOUT if timeout occurred waiting for * new data. * * TFTP_END_OF_FILE if end of file has reached. * * TFTP_ERROR if remote server returned ERROR. * Actual error code may be read by calling * TFTPGetError() * * TFTP_NOT_READY if still waiting for new data. * * Side Effects: None * * Overview: Waits for data block. If data block does not * arrive within specified timeout, it automatically * sends out ack for previous block to remind * server to send next data block. * If all attempts are exhausted, it returns with * TFTP_TIMEOUT. * * Note: By default, this funciton uses "octet" or binary * mode of file transfer. ********************************************************************/ TFTP_RESULT TFTPIsGetReady(void) { WORD_VAL opCode; WORD_VAL blockNumber; BOOL bTimeOut; // Check to see if timeout has occurred. bTimeOut = FALSE; if ( TickGetDiff(TickGet(), _tftpStartTick) >= TFTP_GET_TIMEOUT_VAL ) { bTimeOut = TRUE; _tftpStartTick = TickGet(); } switch(_tftpState) { case SM_TFTP_WAIT_FOR_DATA: // If timeout occurs in this state, it may be because, we have not // even received very first data block or some in between block. if ( bTimeOut == TRUE ) { bTimeOut = FALSE; if ( _tftpRetries++ > (TFTP_MAX_RETRIES-1) ) { DEBUG(printf("TFTPIsGetReady(): Timeout.\n")); // Forget about all previous attempts. _tftpRetries = 1; return TFTP_TIMEOUT; } // If we have not even received first block, ask application // retry. if ( MutExVar.group2._tftpBlockNumber.Val == 1 ) { DEBUG(printf("TFTPIsGetReady(): TFTPOpen Retry.\n")); return TFTP_RETRY; } else { DEBUG(printf("TFTPIsGetReady(): ACK Retry #%d...,\n", _tftpRetries)); // Block number was already incremented in last ACK attempt, // so decrement it. MutExVar.group2._tftpBlockNumber.Val--; // Do it. _tftpState = SM_TFTP_SEND_ACK; break; } } // For Read operation, server will respond with data block. if ( !UDPIsGetReady(_tftpSocket) ) break; // Get opCode UDPGet(&opCode.byte.MSB); UDPGet(&opCode.byte.LSB); // Get block number. UDPGet(&blockNumber.byte.MSB); UDPGet(&blockNumber.byte.LSB); // In order to read file, this must be data with block number of 0. if ( opCode.Val == TFTP_OPCODE_DATA ) { // Make sure that this is not a duplicate block. if ( MutExVar.group2._tftpBlockNumber.Val == blockNumber.Val ) { // Mark that we have not acked this block. _tftpFlags.bits.bIsAcked = FALSE; // Since we have a packet, forget about previous retry count. _tftpRetries = 1; _tftpState = SM_TFTP_READY; return TFTP_OK; } // If received block has already been received, simply ack it // so that Server can "get over" it and send next block. else if ( MutExVar.group2._tftpBlockNumber.Val > blockNumber.Val ) { DEBUG(printf("TFTPIsGetReady(): "\ "Duplicate block %d received - droping it...\n", \ blockNumber.Val)); MutExVar.group2._tftpDuplicateBlock.Val = blockNumber.Val; _tftpState = SM_TFTP_DUPLICATE_ACK; } #if defined(TFTP_DEBUG) else { DEBUG(printf("TFTPIsGetReady(): "\ "Unexpected block %d received - droping it...\n", \ blockNumber.Val)); } #endif } // Discard all unexpected and error blocks. UDPDiscard(); // If this was an error, remember error code for later delivery. if ( opCode.Val == TFTP_OPCODE_ERROR ) { _tftpError = blockNumber.Val; return TFTP_ERROR; } break; case SM_TFTP_DUPLICATE_ACK: if ( UDPIsPutReady(_tftpSocket) ) { _TFTPSendAck(MutExVar.group2._tftpDuplicateBlock); _tftpState = SM_TFTP_WAIT_FOR_DATA; } break; case SM_TFTP_READY: if ( UDPIsGetReady(_tftpSocket) ) { _tftpStartTick = TickGet(); return TFTP_OK; } // End of file is reached when data block is less than 512 bytes long. // To reduce code, only MSB compared against 0x02 (of 0x200 = 512) to // determine if block is less than 512 bytes long or not. else if ( MutExVar.group2._tftpBlockLength.Val == 0 || MutExVar.group2._tftpBlockLength.byte.MSB < TFTP_BLOCK_SIZE_MSB ) _tftpState = SM_TFTP_SEND_LAST_ACK; else break; case SM_TFTP_SEND_LAST_ACK: case SM_TFTP_SEND_ACK: if ( UDPIsPutReady(_tftpSocket) ) { _TFTPSendAck(MutExVar.group2._tftpBlockNumber); // This is the next block we are expecting. MutExVar.group2._tftpBlockNumber.Val++; // Remember that we have already acked current block. _tftpFlags.bits.bIsAcked = TRUE; if ( _tftpState == SM_TFTP_SEND_LAST_ACK ) return TFTP_END_OF_FILE; _tftpState = SM_TFTP_WAIT_FOR_DATA; } break; } return TFTP_NOT_READY; }
/********************************************************************* * Function: void IPProcess() * * PreCondition: None * Input: None * Output: None * Side Effects: None * Overview: Go thru pending ARP Fifo, * Transmit packets with ARP resolved. * Discard packet if timeout on Arp reply * Note: ********************************************************************/ void IPProcess(void) { NET_PKT* sbfr; BYTE* pDestMAC; IP_HEADER* IPH; TICK diffTicks; NET_PKT* tempPtr = NULL; static BYTE brdcstMACadr[ETH_ADRLEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; //iterate thru the packets that are waiting for ARP reply while( Que_GetHead( &PendingARPQue, &sbfr ) ) { DWORD dest_addr; sbfr->PktFlags &= ~ARP_QUE_MASK; if( tempPtr == sbfr ) //we have checked all { sbfr->PktFlags |= ARP_QUE_MASK; Que_AddTail( &PendingARPQue, sbfr ); break; } if( tempPtr == NULL ) tempPtr = sbfr; IPH = (IP_HEADER*)sbfr->pNetworkLayer; dest_addr = _arrayToDword(IPH->DestAddr); pDestMAC = QueryHostRoute( dest_addr ); if( pDestMAC ) { SetEtherTxDestMAC( sbfr, pDestMAC ); MACTransmit( sbfr ); } else if (dest_addr == 0xffffffff) { SetEtherTxDestMAC( sbfr, brdcstMACadr); MACTransmit( sbfr ); } else { //if not timed out, add this packet back to the arp wait queue. diffTicks = TickGetDiff(SystemTickGet(), sbfr->ARPTickStart); // If timeout has not occured, do not do anything. if ( diffTicks <= ARP_TIMEOUT_TICKS ) { sbfr->PktFlags |= ARP_QUE_MASK; Que_AddTail( &PendingARPQue, sbfr ); continue; } else { if( sbfr->PktFlags&PKT_TX_AUTO_DEALLOC ) DeAllocateBuffer( sbfr ); } } } }
/* * 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 } } }
/********************************************************************* * 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(); } } }
/* * Main entry point. */ void main(void) { static TICK t = 0; BYTE c, i; WORD w; BYTE buf[10]; /* * 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 MPFS file system. */ MPFSInit(); //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 pins appcfgADC(); // Configure ADC unit appcfgPWM(); // Configure PWM unit //Clear Screen serPutRomString(AnsiEscClearScreen); /* * Wait a couple of seconds for user input. * - If something is detected, start config. * - If nothing detected, start main program. */ serPutRomString(PressKeyForConfig); for (i = 60; i > 0; --i) //Delay for 50mS x 60 = 3 sec { if ((i % 8) == 0) serPutByte('.'); if (serIsGetReady()) { SetConfig(); break; } DelayMs(50); } serPutByte('\r'); serPutByte('\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 ) { /* * Force IP address display update. */ myDHCPBindCount = 1; #if defined(STACK_USE_DHCP) DHCPDisable(); #endif } #endif #if defined( STACK_USE_VSCP ) vscp2_udpinit(); // init VSCP subsystem #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 ) { /* * Blink SYSTEM LED every second. */ if ( TickGetDiff( TickGet(), t ) >= TICK_SECOND/2 ) { t = TickGet(); LATB6 ^= 1; } //Perform routine tasks MACTask(); /* * 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(); /* XEEBeginRead( EEPROM_CONTROL, 0x0530 ); while ( 1 ) { c = XEERead(); c = 1; } //c = XEERead(); XEEEndRead(); */ #if defined( STACK_USE_VSCP ) vscp2_Task(); #endif /* * 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; } } }
/********************************************************************* * 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 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); }*/ }
int main () { unsigned char zigbee_mode = 0; HardwareInit(); ConsoleInit(); InitSymbolTimer(); uart_init(); initMSDCLTimers(); IFS1bits.U2RXIF = 0; ConsolePutROMString( (ROM char *)"\r\nW to exit"); SendModuleStartData(); while( StartNetworkFlag == FALSE ) { HanddleUART2(); if(IFS1bits.U2RXIF) { zigbee_mode = U2RXREG; if(zigbee_mode == 'W') break; } } StartNetworkFlag = FALSE; zigbee_mode = 0; ConsolePutROMString( (ROM char *)"\r\n*********************************" ); ConsolePutROMString( (ROM char *)"\r\nMicrochip SE Profile 1.0.version.0.5.3" ); ConsolePutROMString( (ROM char *)"\r\n*********************************" ); ConsolePutROMString( (ROM char *)"\r\nE:Comission device as ESP\r\n" ); ConsolePutROMString( (ROM char *)"\r\nM:Comission device as MTR\r\n" ); { TICK startTime = TickGet(); do { IFS1bits.U2RXIF = 0; do { if( TickGetDiff(TickGet(),startTime) > (2 * ONE_SECOND)) { break; } } while( !IFS1bits.U2RXIF ); if( TickGetDiff(TickGet(),startTime) > (2 * ONE_SECOND)) { break; } zigbee_mode = U2RXREG; ConsolePut(zigbee_mode); }while( (zigbee_mode != 'M') && (zigbee_mode != 'm') && (zigbee_mode != 'E') && (zigbee_mode != 'e') ); NVMRead ( (BYTE*)&MSDCL_Commission, MSDCL_Commission_Locations, sizeof(MSDCL_Commission)); if( ( MSDCL_Commission.ValidCleanStartUp != MSDCL_COMMISSION_DATA_VALID ) && (MSDCL_Commission.ValidCleanStartUp != MSDCL_DEFAULT_MTR) && (MSDCL_Commission.ValidCleanStartUp != MSDCL_DEFAULT_ESP) && (zigbee_mode != 'E') && (zigbee_mode != 'e') ) { zigbee_mode = 'M'; } if( ((zigbee_mode == 'M') || (zigbee_mode == 'm') || (MSDCL_Commission.ValidCleanStartUp == MSDCL_DEFAULT_MTR)) && (zigbee_mode != 'E') && (zigbee_mode != 'e') ) { NowIam = 0; NowIam = A_ROUTER | A_FFD; // These variables are exported in Zigbee.def I_AM_TRUST_CENTER = 0; //Trust center enabled Enabled USE_COMMON_TC_LINK_KEY = 1; MAX_ENERGY_THRESHOLD = 112; DEFAULT_STARTUP_CONTROL = DEFAULT_STARTUP_CONTROL_MTR; MSDCL_Commission.StartupStatus = STARTUP_CONTROL_JOIN_NEW_NETWORK; ALLOWED_CHANNELS = ALLOWED_CHANNELS_PRE_CONFIG; if(MSDCL_Commission.ValidCleanStartUp != MSDCL_DEFAULT_MTR) { MSDCL_Commission.ValidCleanStartUp = MSDCL_DEFAULT_MTR; NVMWrite( MSDCL_Commission_Locations, (BYTE*)&MSDCL_Commission, sizeof(MSDCL_Commission) ); } } else if( (zigbee_mode == 'E') || (zigbee_mode == 'e') || (MSDCL_Commission.ValidCleanStartUp == MSDCL_DEFAULT_ESP) ) { NowIam = 0; NowIam = A_CORDINATOR | A_FFD; // These variables are exported in Zigbee.def I_AM_TRUST_CENTER = 1; //Trust center enabled Enabled USE_COMMON_TC_LINK_KEY = 1; MAX_ENERGY_THRESHOLD = 241; DEFAULT_STARTUP_CONTROL = DEFAULT_STARTUP_CONTROL_ESP; MSDCL_Commission.StartupStatus = STARTUP_CONTROL_FORM_NEW_NETWORK; ALLOWED_CHANNELS = ALLOWED_CHANNELS_PRE_CONFIG; if(MSDCL_Commission.ValidCleanStartUp != MSDCL_DEFAULT_ESP) { MSDCL_Commission.ValidCleanStartUp = MSDCL_DEFAULT_ESP; NVMWrite( MSDCL_Commission_Locations, (BYTE*)&MSDCL_Commission, sizeof(MSDCL_Commission) ); } } if((MSDCL_Commission.ValidCleanStartUp == MSDCL_COMMISSION_DATA_VALID) ) { switch( MSDCL_Commission.StartupStatus ) { case STARTUP_CONTROL_FORM_NEW_NETWORK: ConsolePutROMString( (ROM char *)"\r\nStarting as ESP\r\n" ); NowIam = 0; NowIam = A_CORDINATOR | A_FFD; // These variables are exported in Zigbee.def I_AM_TRUST_CENTER = 1; //Trust center enabled Enabled USE_COMMON_TC_LINK_KEY = 1; MAX_ENERGY_THRESHOLD = 241; ALLOWED_CHANNELS = MSDCL_Commission.ChannelMask.Val ; DEFAULT_STARTUP_CONTROL = DEFAULT_STARTUP_CONTROL_ESP; break; case STARTUP_CONTROL_PART_OF_NETWORK_NO_EXPLICIT_ACTION: case STARTUP_CONTROL_JOIN_NEW_NETWORK: case STARTUP_CONTROL_START_FROM_SCRATCH_AS_ROUTER: default: ConsolePutROMString( (ROM char *)"\r\nStarting as MTR\r\n" ); NowIam = 0; NowIam = A_ROUTER | A_FFD; // These variables are exported in Zigbee.def I_AM_TRUST_CENTER = 1; //Trust center enabled Enabled USE_COMMON_TC_LINK_KEY = 0; MAX_ENERGY_THRESHOLD = 112; ALLOWED_CHANNELS = MSDCL_Commission.ChannelMask.Val ; DEFAULT_STARTUP_CONTROL = DEFAULT_STARTUP_CONTROL_MTR; break; } } } // if (NOW_I_AM_A_CORDINATOR()) // USE_COMMON_TC_LINK_KEY = 1; // else // USE_COMMON_TC_LINK_KEY = 0; if(NOW_I_AM_A_ROUTER()) I_AM_TRUST_CENTER = 0; if(NOW_I_AM_A_ROUTER()) appNextSeqNum_PTR = &appNextSeqNum_MTR; else if (NOW_I_AM_A_CORDINATOR()) appNextSeqNum_PTR = &appNextSeqNum_ESP; if(NOW_I_AM_A_ROUTER()) App_AttributeStorageTable = App_AttributeStorageTable_MTR; else if (NOW_I_AM_A_CORDINATOR()) App_AttributeStorageTable = App_AttributeStorageTable_ESP; if(NOW_I_AM_A_ROUTER()) Config_Node_Descriptor.NodeLogicalType = 0x01; else if (NOW_I_AM_A_CORDINATOR()) Config_Node_Descriptor.NodeLogicalType = 0x00; if( NOW_I_AM_A_ROUTER() ) pAppListOfDeviceServerInfo[0] = &Meter_DeviceServerinfo; else if( NOW_I_AM_A_CORDINATOR() ) pAppListOfDeviceServerInfo[0] = &ESP_DeviceServerinfo; if( NOW_I_AM_A_ROUTER() ) pAppListOfDeviceClientInfo[0] = &Meter_DeviceClientinfo; else if( NOW_I_AM_A_CORDINATOR() ) pAppListOfDeviceClientInfo[0] = &ESP_DeviceClientinfo; if( NOW_I_AM_A_ROUTER() ) Config_Simple_Descriptors = Config_Simple_Descriptors_MTR; else if( NOW_I_AM_A_CORDINATOR() ) Config_Simple_Descriptors = Config_Simple_Descriptors_ESP; if( MSDCL_Commission.ValidCleanStartUp == MSDCL_COMMISSION_DATA_VALID) { if( ChannelsToBeScanned.Val == 0 ) { ChannelsToBeScanned.Val = MSDCL_Commission.ChannelMask.Val & 0x03FFF800UL; } } else { if( ChannelsToBeScanned.Val == 0 ) { ChannelsToBeScanned.Val = ALLOWED_CHANNELS_PRE_CONFIG & 0x03FFF800UL; } } { unsigned long channelMaskToScan = 0x00000800UL; if( ( ChannelsToBeScanned.Val & 0x03FFF800UL ) == 0 ) { ChannelsToBeScanned.Val = ALLOWED_CHANNELS_PRE_CONFIG & 0x03FFF800UL; } ChannelsToBeScanned.Val &= 0x03FFF800UL; while( !(ChannelsToBeScanned.Val & channelMaskToScan) ) { channelMaskToScan <<= 1; } ALLOWED_CHANNELS = channelMaskToScan; ChannelsToBeScanned.Val &= channelMaskToScan ^ 0xFFFFFFFFUL; //ALLOWED_CHANNELS = 0x3FFFC00UL; } //ALLOWED_CHANNELS = 0b000000000111111111101111100000000000; ALLOWED_CHANNELS = 0b0000000000010000000000000000000000; while(1) { if (NOW_I_AM_A_CORDINATOR()) main_ESP(); else { main_MTR(); } } }
/********************************************************************* * 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 ; } }
void lftp_task( void ) { WORD ttt; BYTE c; BOOL bPreLine; BOOL bPostLine; // Nothing to do if we don't have a link if ( !MACIsLinked() ) return; // check if state machine is stuck somewhere and reset the it after a while if needed : if ( ( ftp_state != LFTP_STATE_NONE ) && ( TickGetDiff( TickGet(), lastActivity) > ( LFTP_TIMEOUT * TICK_SECOND ) ) ) { // Close ftp client socker if open //if ( TCPIsConnected( ftpsocket ) ) { writeRomString2Socket( quit ); TCPDisconnect( ftpsocket ); ftpsocket = UNKNOWN_SOCKET; //} // Close data socket if open TCPDisconnect( datasocket ); datasocket = UNKNOWN_SOCKET; // Check if we should try again or if its time // to pack it in cntBeforeFail++; if ( cntBeforeFail > LFTP_MAX_RETRIES ) { cntBeforeFail = 0; ftp_state = LFTP_STATE_NONE; // Give up... bftpLoadWork = FALSE; // Work is done - failed } ftp_state = LFTP_STATE_NONE; } switch( ftp_state ) { // ** // Start to work if its time to do so case LFTP_STATE_NONE: // Check timer and see if we should fetch // data from the server. lastActivity = TickGet(); if ( bftpLoadWork ) { ftp_state = LFTP_STATE_ARP; // Must get MAC address for server cntBeforeFail = 0; // Init. failure counter DBG_OUT('A'); } break; //** // Resolve the MAC address of the ftp server case LFTP_STATE_ARP: ftp_nodeinfo.IPAddr.v[ 0 ] = LFTP_SERVER_IP_v0; ftp_nodeinfo.IPAddr.v[ 1 ] = LFTP_SERVER_IP_v1; ftp_nodeinfo.IPAddr.v[ 2 ] = LFTP_SERVER_IP_v2; ftp_nodeinfo.IPAddr.v[ 3 ] = LFTP_SERVER_IP_v3; if ( ARPIsTxReady() ) { DBG_OUT('B'); ARPResolve( &ftp_nodeinfo.IPAddr ); // resolve IP adress ftp_state = LFTP_STATE_ARP_RESOLVE; lastActivity = TickGet(); } break; // ** // Check if the ftp MAC address is resolved case LFTP_STATE_ARP_RESOLVE: if ( ARPIsResolved( &ftp_nodeinfo.IPAddr, &ftp_nodeinfo.MACAddr ) ) { DBG_OUT('D'); ftp_state = LFTP_STATE_CONNECT; lastActivity = TickGet(); } break; // ** // Connect to ftp server case LFTP_STATE_CONNECT: // Try to connect ftpsocket = TCPConnect( &ftp_nodeinfo, LFTP_PORT ); if ( INVALID_SOCKET != ftpsocket ) { DBG_OUT('E'); ftp_state = LFTP_STATE_CONNECT_WAIT; lastActivity = TickGet(); } break; // ** // Waiting for ftp connection case LFTP_STATE_CONNECT_WAIT: if ( TCPIsConnected( ftpsocket ) ) { DBG_OUT('F'); ftp_state = LFTP_STATE_USER; lastActivity = TickGet(); } break; // Here we wait for server connection and send // USER command if OK case LFTP_STATE_USER: // Fetch data if we are connected if ( TCPIsGetReady( ftpsocket ) ) { // get first digit while( TCPGet( ftpsocket, &c ) ) { if ( isdigit( c ) ) break; } // If connected with positive response "2xx - xxxxxxxx..." // we send username. If not we just timeout if ( '2' == c ) { DBG_OUT('G'); writeRomString2Socket( user ); ftp_state = LFTP_STATE_PASS; lastActivity = TickGet(); } TCPDiscard( ftpsocket ); } break; // ** // Here we wait for response from USER command // and send PASS command if OK case LFTP_STATE_PASS: // Fetch data if we are connected if ( TCPIsGetReady( ftpsocket ) ) { DBG_OUT('$'); // get first digit while( TCPGet( ftpsocket, &c ) ) { DBG_OUT(c); if ( isdigit( c ) ) break; } // If connected with positive response "3xx - xxxxxxxx..." // we send username. If not we just timeout if ( ('3' == c ) || ('2' == c ) ) { DBG_OUT('H'); writeRomString2Socket( pass ); ftp_state = LFTP_STATE_PASV; lastActivity = TickGet(); } TCPDiscard( ftpsocket ); } break; // ** // Here we wait for response of PASS command // and send PASV command if positive and also // creates the data socket case LFTP_STATE_PASV: // Fetch data if we are connected if ( TCPIsGetReady( ftpsocket ) ) { DBG_OUT('!'); // get first digit while( TCPGet( ftpsocket, &c ) ) { DBG_OUT(c); if ( isdigit( c ) ) break; } // If connected with positive response "2xx - xxxxxxxx..." // we send username. If not we just timeout if ( '2' == c ) { DBG_OUT('I'); writeRomString2Socket( pasv ); ftp_state = LFTP_STATE_RETR; lastActivity = TickGet(); } TCPDiscard( ftpsocket ); } break; // ** // Here we wait for the result of PASV command // and parse its data // if OK we send RETR and go on to the next state case LFTP_STATE_RETR: // Fetch data if we are connected if ( TCPIsGetReady( ftpsocket ) ) { TCPGet( ftpsocket, &c ); if ( '2' == c ) { DBG_OUT('J'); // Get pasv parameters getPasvParams(); // retrive file writeRomString2Socket( retr ); ttt = portdata; while ( ttt ) { DBG_OUT('0' + (ttt % 10) ); ttt = ttt / 10; } ftp_state = LFTP_STATE_DATA_CONNECT; } TCPDiscard( ftpsocket ); } break; // ** // Connect to the data socket case LFTP_STATE_DATA_CONNECT: // Try to connect datasocket = TCPConnect( &ftp_nodeinfo, portdata ); if ( INVALID_SOCKET != datasocket ) { DBG_OUT('K'); ftp_state = LFTP_STATE_WAIT_DATA_CONNECT; lastActivity = TickGet(); } break; // ** // Wait for the data connection to establish case LFTP_STATE_WAIT_DATA_CONNECT: if ( TCPIsConnected( datasocket ) ) { DBG_OUT('L'); //writeRomString2Socket( lftpDataSocket, crlf ); ftp_state = LFTP_STATE_FETCH_DATA; lastActivity = TickGet(); } // Check for reply on ftp socket FIX!!!! if ( TCPIsGetReady( ftpsocket ) ) { DBG_OUT('?'); while( TCPGet( ftpsocket, &c ) ) { DBG_OUT( c ); } TCPDiscard( ftpsocket ); } break; // ** // Fetch the data and send it out on the // serial i/f case LFTP_STATE_FETCH_DATA: // Fetch data if we are connected if ( TCPIsGetReady( datasocket ) ) { DBG_OUT('M'); // Framework start serPutByte( 0x00 ); serPutByte( 0xff ); serPutByte( 0xff ); serPutByte( 0x01 ); serPutByte( 0x01 ); serPutByte( 0x01 ); bPreLine = FALSE; bPostLine = FALSE; // get data while( TCPGet( datasocket, &c ) ) { if ( 0x0d == c ) { // We skip CR } else if ( 0x0a == c ) { // Send end line stuff serPutByte( 0xff ); bPreLine = FALSE; bPostLine = TRUE; } else { bPostLine = FALSE; // no end line codes sent if ( !bPreLine ) { // Send preline stuff bPreLine = TRUE; serPutByte( 0x01 ); serPutByte( 0x03 ); serPutByte( 0xef ); serPutByte( 0xb0 ); } serPutByte( c ); } } // If we end with a row without LF we must send // Line end stuff if ( !bPostLine ) { serPutByte( 0xff ); } // Framework end serPutByte( 0xff ); serPutByte( 0x00 ); ftp_state = LFTP_STATE_END; TCPDiscard( datasocket ); } // Check for data on ftp socket if ( TCPIsGetReady( ftpsocket ) ) { while( TCPGet( ftpsocket, &c ) ) { DBG_OUT( c ); } TCPDiscard( ftpsocket ); } break; // ** // We are done for this time case LFTP_STATE_END: DBG_OUT('*'); TCPDisconnect( ftpsocket ); TCPDisconnect( datasocket ); bftpLoadWork = FALSE; // Work is done ftp_state = LFTP_STATE_NONE; break; } }
void HanddleUART2(void) { unsigned char c; int Tp; TICK MeterConcurrentTime; MeterConcurrentTime = TickGet(); if( ( TickGetDiff( MeterConcurrentTime, TotalMeterGetConnceted1 ) ) > TIMETOCHECKNWKTABLE) { CompareNWKTable(); TotalMeterGetConnceted1 = TickGet(); } if(MyCommandFlag.ACK != ACK_PENDING) { if(MyCommandFlag.DataSent == TRUE) { if(MyCommandFlag.ACK == ACK_NOTRECEIVED) { //xprintf("ACK not Received :(\n\r"); MyAskForDeviceAddress(FALSE,PrvSendIeeeAddr); } else if(MyCommandFlag.ACK == ACK_RECEIVED) { //xprintf("ACK Received :)\n\r"); } else { xprintf("This staage I am not Expected\n\t"); } MyCommandFlag.DataSent = FALSE; } else { ACKTimeOut = TickGet(); } } else { TICK currentTime; currentTime = TickGet(); if( ( TickGetDiff( currentTime, ACKTimeOut ) ) > (ONE_SECOND) *5) { MyCommandFlag.ACK = ACK_NOTRECEIVED; ACKTimeOut = TickGet(); } } if(uart_kbhit() != 0) { c = uart_get(); //x2putc(c); Uart2Buffer[NumberofReceived] = c; if(Uart2Buffer[0] == 0x2B || Uart2Buffer[0] == 0x1B) { NumberofReceived++; } else { NumberofReceived = 0; } if(NumberofReceived >=2 && numberofdatareceived == 0) { HowManyData = c; numberofdatareceived = 1; } if(HowManyData !=0 && NumberofReceived == HowManyData+1) { //xprintf("\n\r Data Received \n\r"); //for(Tp=0;Tp<=HowManyData;Tp++) // xprintf("\n\r Data is: %d\n\r",Uart2Buffer[Tp]); //xprintf("\n\r How many data = %d",HowManyData); Uart2Datalen = HowManyData; NumberofReceived = 0; numberofdatareceived = 0; HowManyData = 0; while(uart_kbhit() != 0) c = uart_get(); CheckDataAndSend(); } } }
/* * Main entry point. */ void main(void) { static TICK tickHeartBeat = 0xffffffff; static BYTE testLED; testLED = 1; // Destination address - Always MAC broadcast address broadcastTargetMACAddr.v[ 0 ] = 0xff; broadcastTargetMACAddr.v[ 1 ] = 0xff; broadcastTargetMACAddr.v[ 2 ] = 0xff; broadcastTargetMACAddr.v[ 3 ] = 0xff; broadcastTargetMACAddr.v[ 4 ] = 0xff; broadcastTargetMACAddr.v[ 5 ] = 0xff; //Set SWDTEN bit, this will enable the watch dog timer WDTCON_SWDTEN = 1; aliveCntrMain = 0xff; //Disable alive counter during initialization. Setting to 0xff disables it. //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 serial ports early, because they could be required for debugging if (appcfgGetc(APPCFG_USART1_CFG & APPCFG_USART_ENABLE)) { appcfgUSART(); //Configure the USART1 } #if defined(BRD_SBC65EC) if (appcfgGetc(APPCFG_USART2_CFG & APPCFG_USART_ENABLE)) { appcfgUSART2(); //Configure the USART2 } #endif //After initializing all modules that use interrupts, enable global interrupts INTCON_GIEH = 1; INTCON_GIEL = 1; //Initialize Stack and application related NV variables. appcfgInit(); //First call appcfgCpuIOValues() and then only appcfgCpuIO()!!! This ensures the value are set, before enabling ports. appcfgCpuIOValues(); //Configure the CPU's I/O port pin default values appcfgCpuIO(); //Configure the CPU's I/O port pin directions - input or output appcfgADC(); //Configure ADC unit appcfgPWM(); //Configure PWM Channels MACInit(); #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 ) { //aliveCntrMain = 38; //Reset if not services in 52.42ms x 38 = 2 seconds aliveCntrMain = 0xff; CLRWDT(); // Check for event if ( vscp_getRawPacket() ) { feedVSCP(); } // Send heartbeat every 30 seconds if ( TickGetDiff( tickHeartBeat ) >= ( TICKS_PER_SECOND * 30 ) ) { //vscpevent.head = VSCP_PRIORITY_NORMAL; //vscpevent.vscp_class = VSCP_CLASS2_LEVEL1_INFORMATION; //vscpevent.vscp_type = VSCP_TYPE_INFORMATION_NODE_HEARTBEAT; //vscpevent.sizeData = 3; //vscpevent.data[ 0 ] = 0; //vscpevent.data[ 1 ] = 0; // Zone //vscpevent.data[ 2 ] = 0; // subzone //vscp_sendRawPacket( &vscpevent ); //SendTestVSCPPacket(); tickHeartBeat = TickGet(); /* //If B6 is configured as input, change to output if (appcfgGetc(APPCFG_TRISB) & 0x40) { appcfgPutc(APPCFG_TRISB, appcfgGetc(APPCFG_TRISB) & 0b10111111); } TRISB_RB6 = 0; LATB6 ^= 1; //Toggle //Toggle IOR5E LED, if IOR5E is present if (appcfgGetc(APPCFG_XBRD_TYPE) == XBRD_TYPE_IOR5E) { ior5eLatchData.bits.ledPWR ^= 1; // Toggle } */ } // Do MAC work StackTask(); //MACTask();; //I2C Task i2cTask(); //Add your application specific tasks here. ProcessIO(); // Do VSCP periodic tasks periodicVSCPWork(); } }
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 { currentTick = TickGet(); if ( TickGetDiff(currentTick, lastTick) >= (TICK_SECOND/2) ) { lastTick = TickGet(); serPutByte(XMODEM_NAK); /* * Blink LED to indicate that we are waiting for * host to send the file. */ //LATA2 ^= 1; } } while( !serIsGetReady() ); while(!lbDone) { if ( serIsGetReady() ) { /* * Toggle LED as we receive the data from host. */ //LATA2 ^= 1; c = serGetByte(); } 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(); serPutByte(XMODEM_ACK); lbDone = TRUE; } else serPutByte(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(); serPutByte(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; }
/********************************************************************* * 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; if(FTPDataSocket != INVALID_SOCKET) { TCPDisconnect(FTPDataSocket); FTPDataSocket = INVALID_SOCKET; } return TRUE; } if ( TCPIsGetReady(FTPSocket) ) { lastActivity = TickGet(); while( TCPGet(FTPSocket, &v ) ) { FTPString[FTPStringLen++] = v; if ( FTPStringLen == MAX_FTP_CMD_STRING_LEN ) FTPStringLen = 0; } 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: // Make sure there is enough TCP TX FIFO space to put our response if(TCPIsPutReady(FTPSocket) < strlenpgm(FTPResponseString[FTPResponse])) return TRUE; TCPPutROMString(FTPSocket, (ROM BYTE*)FTPResponseString[FTPResponse]); 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; }