Пример #1
0
MPFS MPFSOpenROM(ROM BYTE* file) 
{
   BYTE nameRAM[MAX_FILE_NAME_LEN+1];
   
   memcpypgm2ram(nameRAM, (ROM void*)file, strlenpgm((ROM char*)file));
   nameRAM[strlenpgm((ROM char*)file)] = '\0';
   
   return MPFSOpen(nameRAM);
}   
Пример #2
0
/*= CursorLeft ==============================================================
Purpose: Moves the cursor left by one character

Inputs:  none

Returns: none
============================================================================*/
tZGVoidReturn CursorLeft(tZGVoidInput)
{
    /* if cursor is not already at the left-most position */
    if (GET_CURSOR() > strlenpgm( (ROM FAR char *) gCmdLinePrompt))
    {
        SET_CURSOR( GET_CURSOR() - 1);
        ZG_PUTRSUART( (ROM FAR char *) cursorLeftEscapeSequence);
    }
}
Пример #3
0
/*= CursorLeft ==============================================================
Purpose: Moves the cursor left by one character

Inputs:  none

Returns: none
============================================================================*/
void CursorLeft(void)
{
   /* if cursor is not already at the left-most position */
   if (GET_CURSOR() > strlenpgm( (ROM FAR char *) gCmdLinePrompt))
   {
      SET_CURSOR( GET_CURSOR() - 1);
      putrsUART( (ROM FAR char *) cursorLeftEscapeSequence);
   }
}
Пример #4
0
BYTE* HTTPGetROMArg(BYTE *data, ROM BYTE* arg)
{
	// Search through the array while bytes remain
	while(*data != '\0')
	{
		// Look for arg at current position
		if(!memcmppgm2ram(data, (ROM void*)arg, strlenpgm((ROM char*)arg) + 1))
		{// Found it, so skip to next string
			return data + strlenpgm((ROM char*)arg) + 1;
		}
		
		// Skip past two strings (NUL bytes)
		data += strlen((char*)data) + 1;
		data += strlen((char*)data) + 1;
	}
	 	
	// Return NULL if not found
	return NULL;
}
BOOL net_sms_in(char *caller, char *buf)
{
    // The buf contains an SMS command
    // and caller contains the caller telephone number
    char *p;
    int k;

    // Convert SMS command (first word) to upper-case
    for (p=buf; ((*p!=0)&&(*p!=' ')); p++)
        if ((*p > 0x60) && (*p < 0x7b)) *p=*p-0x20;
    if (*p==' ') p++;

    // Command parsing...
    for (k=0; sms_cmdtable[k][0] != 0; k++)
    {
        if (memcmppgm2ram(buf, (char const rom far*)sms_cmdtable[k]+1, strlenpgm((char const rom far*)sms_cmdtable[k])-1) == 0)
        {
            BOOL result = FALSE;
            char *arguments = net_sms_initargs(p);

            if (!net_sms_checkauth(sms_cmdtable[k][0], caller, &arguments))
                return FALSE; // auth error

            if (vehicle_fn_smshandler != NULL)
            {
                if (vehicle_fn_smshandler(TRUE, caller, buf, arguments))
                    return TRUE; // handled
            }

            result = (*sms_hfntable[k])(caller, buf, arguments);
            if (result)
            {
                if (vehicle_fn_smshandler != NULL)
                    vehicle_fn_smshandler(FALSE, caller, buf, arguments);
                net_send_sms_finish();
            }
            return result;
        }
    }

    if (vehicle_fn_smsextensions != NULL)
    {
        // Try passing the command to the vehicle module for handling...
        if (vehicle_fn_smsextensions(caller, buf, p))
            return TRUE; // handled
    }

    // SMS didn't match any command pattern, forward to user via net msg
    net_msg_forward_sms(caller, buf);
    return FALSE; // unknown command
}
Пример #6
0
static void InitAppConfig(void)
{
	AppConfig.Flags.bIsDHCPEnabled = TRUE;
	AppConfig.Flags.bInConfigMode = TRUE;
	memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
//	{
//		_prog_addressT MACAddressAddress;
//		MACAddressAddress.next = 0x157F8;
//		_memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr));
//	}
	AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
	AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
	AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
	AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
	AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
	AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul  | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul  | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
	AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul  | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul  | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;


	// SNMP Community String configuration
	#if defined(STACK_USE_SNMP_SERVER)
	{
		BYTE i;
		static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES;
		static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES;
		ROM char * strCommunity;
		
		for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++)
		{
			// Get a pointer to the next community string
			strCommunity = cReadCommunities[i];
			if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0]))
				strCommunity = "";

			// Ensure we don't buffer overflow.  If your code gets stuck here, 
			// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
			// is either too small or one of your community string lengths 
			// (SNMP_READ_COMMUNITIES) are too large.  Fix either.
			if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0]))
				while(1);
			
			// Copy string into AppConfig
			strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity);

			// Get a pointer to the next community string
			strCommunity = cWriteCommunities[i];
			if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0]))
				strCommunity = "";

			// Ensure we don't buffer overflow.  If your code gets stuck here, 
			// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
			// is either too small or one of your community string lengths 
			// (SNMP_WRITE_COMMUNITIES) are too large.  Fix either.
			if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0]))
				while(1);

			// Copy string into AppConfig
			strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity);
		}
	}
	#endif

	// Load the default NetBIOS Host Name
	memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
	FormatNetBIOSName(AppConfig.NetBIOSName);

}
Пример #7
0
/****************************************************************************
  Function:
    void DDNSTask(void)

  Summary:
    Dynamic DNS client task/state machine.

  Description:
  	This function performs the background tasks of the Dynamic DNS Client.
  	Once the DDNSPointers structure is configured, this task attempt to 
  	update the Dynamic DNS hostname on a periodic schedule.
  	
  	The task first accesses the CheckIP server to determine the device's
  	current external IP address.  If the IP address has changed, it 
  	issues an update command to the dynamic DNS service to propagate the
  	change.  This sequence executes whenever dwUpdateAt elapses, which by
  	default is every 10 minutes, or when an update is forced.
    
  Precondition:
    DDNSInit() has been called.

  Parameters:
	None
	
  Returns:
    None

  Remarks:
	This function acts as a task (similar to one in an RTOS).  It
	performs its task in a co-operative manner, and the main application
	must call this function periodically to ensure that its tasks get 
	executed in a timely fashion.
  ***************************************************************************/
void DDNSTask(void)
{
	BYTE 				i;
	static TICK			Timer;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static char ROM * 	ROMStrPtr;
	static char * 		RAMStrPtr;

	static BYTE vBuffer[16];
	WORD wPos;
	static IP_ADDR ipParsed;
	
	static enum
	{
		SM_IDLE = 0u,
		SM_BEGIN_CHECKIP,				//0x1
		SM_CHECKIP_SKT_OBTAINED,		//0x2
		SM_CHECKIP_FIND_DELIMITER,		//0x3
		SM_CHECKIP_FIND_ADDRESS,		//0x4
		SM_CHECKIP_DISCONNECT,			//0x5
		SM_IP_UPDATE_HOME,				//0x6
		SM_IP_UPDATE_SKT_OBTAINED,		//0x7

		/*  
			HTTP request msg is divided into 6 parts 
			SM_IP_UPDATE_REQ_A,B,C,D,E,F as the tcp ip tx
			buffer is only able to carry 200 bytes at a time.
		*/
		
		SM_IP_UPDATE_REQ_A,				//0x8
		SM_IP_UPDATE_REQ_B,				//0x9
		SM_IP_UPDATE_REQ_C,				//0xa	
		SM_IP_UPDATE_REQ_D,				//0xb
		SM_IP_UPDATE_REQ_E,				//0xc
		SM_IP_UPDATE_REQ_F,				//0xd

		SM_IPUPDATE_FIND_RESPONSE,		//0xe
		SM_IPUPDATE_PARSE_RESPONSE,		//0xf
		SM_IPUDATE_DISCONNECT,			//0x10
		SM_DONE,						// Done, try again in 10 minutes
		SM_SOFT_ERROR,					// Soft error, try again in 30 seconds
		SM_SYSTEM_ERROR 				// System error, try again in 30 minutes
	} smDDNS = SM_IDLE;

	switch(smDDNS)
	{
		case SM_IDLE:

			// Wait for timeout to begin IP check
			if((LONG)(TickGet() - dwUpdateAt) < 0)
				break;
			
			// Otherwise, continue to next state
			smDDNS = SM_BEGIN_CHECKIP;
				
		case SM_BEGIN_CHECKIP:
			
			// If a fatal error has occurred, abort to the SM_DONE state and keep
			// the error message.
			if(lastStatus >= DDNS_STATUS_ABUSE && lastStatus <= DDNS_STATUS_911)
			{
				smDDNS = SM_DONE;
				break;
			}

			// If DDNSClient is not properly configured, abort
			if( 
				// Verify that each pointer is not null, and is not empty
				(DDNSClient.ROMPointers.Host && (!DDNSClient.Host.szROM || *DDNSClient.Host.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Host && (!DDNSClient.Host.szRAM || *DDNSClient.Host.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.Username && (!DDNSClient.Username.szROM || *DDNSClient.Username.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Username && (!DDNSClient.Username.szRAM || *DDNSClient.Username.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.Password && (!DDNSClient.Password.szROM || *DDNSClient.Password.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.Password && (!DDNSClient.Password.szRAM || *DDNSClient.Password.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.CheckIPServer && (!DDNSClient.CheckIPServer.szROM || *DDNSClient.CheckIPServer.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.CheckIPServer && (!DDNSClient.CheckIPServer.szRAM || *DDNSClient.CheckIPServer.szRAM == '\0') ) ||
				(DDNSClient.ROMPointers.UpdateServer && (!DDNSClient.UpdateServer.szROM || *DDNSClient.UpdateServer.szROM == '\0') ) ||
				(!DDNSClient.ROMPointers.UpdateServer && (!DDNSClient.UpdateServer.szRAM || *DDNSClient.UpdateServer.szRAM == '\0') )
			)
			{
				smDDNS = SM_SOFT_ERROR;
				lastStatus = DDNS_STATUS_INVALID;
				break;
			}
			
			// Start with an invalidated IP String
			vBuffer[0] = '\0';
	
			// Connect a socket to the remote server
			if(DDNSClient.ROMPointers.CheckIPServer)
			{	
				MySocket = TCPOpen((DWORD)(ROM_PTR_BASE)DDNSClient.CheckIPServer.szROM, TCP_OPEN_ROM_HOST,
					DDNSClient.CheckIPPort, TCP_PURPOSE_DEFAULT);
			}
			else
			{
				MySocket = TCPOpen((DWORD)(PTR_BASE)DDNSClient.CheckIPServer.szRAM, TCP_OPEN_RAM_HOST,
					DDNSClient.CheckIPPort, TCP_PURPOSE_DEFAULT);						
			}
			
			// If no socket available, try again on next loop
			if(MySocket == INVALID_SOCKET)
				break;

			smDDNS++;
			Timer = TickGet();
			break;

		case SM_CHECKIP_SKT_OBTAINED:

			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet()-Timer > 6*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					// We will retry soon
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					lastStatus = DDNS_STATUS_CHECKIP_ERROR;
					smDDNS = SM_SOFT_ERROR;
				}
				break;
			}

			Timer = TickGet();

			// Make certain the socket can be written to
			if(TCPIsPutReady(MySocket) < 125)//125 = size of TCP Tx buffer
				break;
			
			// Transmit the request to the server
			TCPPutROMString(MySocket, (ROM BYTE*)"GET / HTTP/1.0\r\nHost: ");

			if(DDNSClient.ROMPointers.CheckIPServer)
			{
				TCPPutROMString(MySocket, DDNSClient.CheckIPServer.szROM);
			}
			else
			{
				TCPPutString(MySocket, DDNSClient.CheckIPServer.szRAM);
			}

			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			// Send the packet
			TCPFlush(MySocket);
			smDDNS++;
			break;

		case SM_CHECKIP_FIND_DELIMITER:

			// Check if remote node is still connected.  If not, force to the disconnect state,
			// but don't break because data may still be waiting.
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
				smDDNS = SM_CHECKIP_DISCONNECT;

			// Search out the "Address: " delimiter in the response
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"Address: ", 9, 0, FALSE);
			
			// If not yet found, clear as much as possible and break
			if(wPos == 0xffff)
			{
				wPos = TCPIsGetReady(MySocket);
				if(wPos > 9)
					TCPGetArray(MySocket, NULL, wPos - 9);
				break;
			}
				
			// Clear up to and past that string
			TCPGetArray(MySocket, NULL, wPos + 9);
		
			// Continue on to read the IP
			Timer = TickGet();
			smDDNS++;
		
		case SM_CHECKIP_FIND_ADDRESS:
			
			// Check if remote node is still connected.  If not, force to the disconnect state,
			// but don't break because data may still be waiting.
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
				smDDNS = SM_CHECKIP_DISCONNECT;

			// Search out the "</body>" delimiter in the response
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"</body>", 7, 0, FALSE);
			
			// If not yet found, break
			if(wPos == 0xffff)
				break;
				
			// Read and terminate that string as the IP address (preventing buffer overflows)
			if(wPos > 15)
				wPos = 15;
			TCPGetArray(MySocket, vBuffer, wPos);
			vBuffer[wPos] = '\0';
			
			// Parse the IP address that was read, invalidating on failure
			if(!StringToIPAddress(vBuffer, &ipParsed))
				vBuffer[0] = '\0';

			// Continue on to close the socket			
			
		case SM_CHECKIP_DISCONNECT:

			// Close the socket
			TCPDisconnect(MySocket);
			MySocket = INVALID_SOCKET;

			// Determine if an update is necessary
			if(vBuffer[0] == '\0')
			{// CheckIP Failed
				lastStatus = DDNS_STATUS_CHECKIP_ERROR;
				smDDNS = SM_SOFT_ERROR;
				break;
			}

			if( (ipParsed.Val ==lastKnownIP.Val) && (!bForceUpdate))
			{
				// IP address has not changed and no update is forced
				lastStatus = DDNS_STATUS_UNCHANGED;
				smDDNS = SM_DONE;
				break;
			}
			
			// Need to perform an update
			lastKnownIP = ipParsed;
			bForceUpdate = FALSE;
			smDDNS++;
			break;
			 
		case SM_IP_UPDATE_HOME:

			// Connect a socket to the remote server
			if(DDNSClient.ROMPointers.UpdateServer)
			{
				MySocket = TCPOpen((DWORD)(ROM_PTR_BASE)DDNSClient.UpdateServer.szROM, TCP_OPEN_ROM_HOST, 
					DDNSClient.UpdatePort, TCP_PURPOSE_DEFAULT);
			}
			else
			{
				MySocket = TCPOpen((DWORD)(PTR_BASE)DDNSClient.UpdateServer.szRAM, TCP_OPEN_RAM_HOST,
					DDNSClient.UpdatePort, TCP_PURPOSE_DEFAULT);
			}
	
			// If no socket is available, try again on the next loop
			if(MySocket == INVALID_SOCKET)
				break;
			
			// Move on to the next state
			smDDNS++;
			Timer = TickGet();
			break;

		case SM_IP_UPDATE_SKT_OBTAINED:
		
			// Wait for the remote server to accept our connection request
			if(!TCPIsConnected(MySocket))
			{
				// Time out if too much time is spent in this state
				if(TickGet() - Timer > 6*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					// We will try again immediately
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					lastStatus = DDNS_STATUS_UPDATE_ERROR;
					smDDNS--;
				}
				break;
			}
			
			// Reset timer and begin sending the request
			Timer = TickGet();
			smDDNS++;
			// No break needed...try to send first bit immediately.

		case SM_IP_UPDATE_REQ_A:
	
			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || (TickGet() - Timer > 10*TICK_SECOND))
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break;
			}
			
			if(TCPIsPutReady(MySocket) < 25u)  // 25 =~ 16+9
				break;

			TCPPutROMString(MySocket, (ROM BYTE*)"GET /nic/update?hostname=");
			smDDNS++;
			// No break needed...try to send next bit immediately.
			
		case SM_IP_UPDATE_REQ_B:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || (TickGet() - Timer > 10*TICK_SECOND))
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}

			// Try to write, verifying that space is available first
			if(DDNSClient.ROMPointers.Host)
			{
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)DDNSClient.Host.szROM))
					break;
				TCPPutROMString(MySocket,DDNSClient.Host.szROM);
			}
			else
			{
				if(TCPIsPutReady(MySocket) < strlen((char*)DDNSClient.Host.szRAM))
					break;
				TCPPutString(MySocket,DDNSClient.Host.szRAM);
			}

			smDDNS++;
			// No break needed...try to send next bit immediately.
			
		case SM_IP_UPDATE_REQ_C:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}

			if(TCPIsPutReady(MySocket) < 70u)
				break;
	
			TCPPutROMString(MySocket, (ROM BYTE*)"&myip=");
			TCPPutString(MySocket, vBuffer);
			TCPPutROMString(MySocket, (ROM BYTE*)"&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG HTTP/1.0");	

			TCPFlush(MySocket);
			smDDNS++;
			// No break needed...try to send next bit immediately.

		case SM_IP_UPDATE_REQ_D:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			if(TCPIsPutReady(MySocket) < 131u) // 131 =~ 8+23 + dynamic dns server hostname
				break;

			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nHost: ");//8
			
			if(DDNSClient.ROMPointers.UpdateServer)
				TCPPutROMString(MySocket,DDNSClient.UpdateServer.szROM);
			else
				TCPPutString(MySocket,DDNSClient.UpdateServer.szRAM);
			
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nAuthorization: Basic ");//23

			TCPFlush(MySocket);
			smDDNS++;
			// No break needed...try to send the next bit immediately.

		case SM_IP_UPDATE_REQ_E:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 6*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			// User name and passwords for DynDNS.org can each be up to 24 characters
			// Base64 encoded data is always at least 25% bigger than the original
			if(TCPIsPutReady(MySocket) < 100u)
				break;	

			if(DDNSClient.ROMPointers.Username)
			{
				ROMStrPtr = (ROM char*)DDNSClient.Username.szROM;
				wPos = strlenpgm(ROMStrPtr);
			}
			else
			{
				RAMStrPtr = (char*)DDNSClient.Username.szRAM;
				wPos = strlen((char*)RAMStrPtr);
			}

			i = 0;
			while(wPos)
			{
				while(i < wPos && i < 3u)
				{
					if(DDNSClient.ROMPointers.Username)
						vBuffer[i] = *ROMStrPtr++;
					else
						vBuffer[i] = *RAMStrPtr++;
					i++;
				}
				wPos -= i; 				
										
				if(i == 3u)
				{
					Base64Encode(vBuffer, i, vBuffer, 4);
					TCPPutArray(MySocket, vBuffer, 4);
					i = 0;
				}
			}

			if(DDNSClient.ROMPointers.Password)
			{		
				ROMStrPtr = (ROM char*)DDNSClient.Password.szROM;
				wPos = strlenpgm(ROMStrPtr);
			}
			else
			{
				RAMStrPtr = (char*)DDNSClient.Password.szRAM;
				wPos = strlen((char*)RAMStrPtr);
			}

		  	// Increment for the ':' separator and i for bytes left in username
		  	wPos += i + 1;
			
			vBuffer[i++] = ':';

			while(wPos)
			{
				while(i < wPos && i < 3u)
				{
					if(DDNSClient.ROMPointers.Password)
						vBuffer[i] = *ROMStrPtr++;
					else
						vBuffer[i] = *RAMStrPtr++;
					i++;
				}
				wPos -= i; 				
				Base64Encode(vBuffer, i, vBuffer, 4);
				TCPPutArray(MySocket, vBuffer, 4);
				i = 0;
			}
			
			TCPFlush(MySocket);
			smDDNS++;
			break;

			
		case SM_IP_UPDATE_REQ_F:

			// Check for lost connections or timeouts
			if(!TCPIsConnected(MySocket) || TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break; 
			}
			
			if(TCPIsPutReady(MySocket) < 50)
				break;
			
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nUser-Agent: Microchip - TCPIPSTACK - "VERSION"\r\n\r\n");
			TCPFlush(MySocket);
			smDDNS++;
			
			// Reset the timer to wait for a response
			Timer = TickGet();
			break;
								
		case SM_IPUPDATE_FIND_RESPONSE:
			// Locate the response string

			// Wait up to 10 seconds for a response
			if(TickGet() - Timer > 10*TICK_SECOND)
			{
				lastStatus = DDNS_STATUS_UPDATE_ERROR;
				smDDNS = SM_IPUDATE_DISCONNECT;
				break;
			}
		
			// According to HTTP, the response will start after the two CRLFs
			wPos = TCPFindROMArray(MySocket, (ROM BYTE*)"\r\n\r\n", 4, 0, FALSE);

			// If not yet found, eliminate everything up to
			if(wPos == 0xffff)
			{
				wPos = TCPIsGetReady(MySocket);
				if(wPos > 4)
					TCPGetArray(MySocket, NULL, wPos - 4);
				break;
			}
				
			TCPGetArray(MySocket, NULL, wPos+4);
			smDDNS++;
			// No break...continue to next state immediately
			
		case SM_IPUPDATE_PARSE_RESPONSE:
			// Try to parse the response text
			
			// Wait up to 10 seconds for the remote server to disconnect
			// so we know all data has been received
			if(TCPIsConnected(MySocket) && TickGet() - Timer < 10*TICK_SECOND)
				break;
			
			// Read the response code
		 	wPos = TCPIsGetReady(MySocket);
		 	if(wPos > sizeof(vBuffer) - 1)
		 		wPos = sizeof(vBuffer) - 1;

			wPos = TCPGetArray(MySocket, vBuffer, wPos);
			vBuffer[wPos] = '\0';
			for(i = 0; i < sizeof(vBuffer); i++)
				if(vBuffer[i] == ' ')
					vBuffer[i] = '\0';

			for(lastStatus = 0; lastStatus <= DDNS_STATUS_UPDATE_ERROR; lastStatus++)
				if(!strcmppgm2ram((char*)vBuffer, (ROM char*)_updateIpSrvrResponse[lastStatus]))
					break;
		
			smDDNS++;
			// No break...continue to finalization

		case SM_IPUDATE_DISCONNECT:
			// Close the socket so it can be used by other modules.
			if(MySocket != INVALID_SOCKET)
			{
				TCPDisconnect(MySocket);
				MySocket = INVALID_SOCKET;
			}
			
			// Determine what to do based on status
			if(lastStatus <= DDNS_STATUS_NUMHOST || lastStatus == DDNS_STATUS_UNCHANGED)
				smDDNS = SM_DONE;
			else if(lastStatus == DDNS_STATUS_911 || lastStatus == DDNS_STATUS_DNSERR)
				smDDNS = SM_SYSTEM_ERROR;
			else
				smDDNS = SM_SOFT_ERROR;
			
			smDDNS++;
			break;
			
		case SM_DONE:
			dwUpdateAt = TickGet() + 10*60*TICK_SECOND;	// 10 minutes
			smDDNS = SM_IDLE;
			break;
			
		case SM_SOFT_ERROR:
			dwUpdateAt = TickGet() + 30*TICK_SECOND; 		// 30 seconds
			smDDNS = SM_IDLE;
			break;
					
		case SM_SYSTEM_ERROR:
			dwUpdateAt = TickGet() + 30*60*TICK_SECOND;		// 30 minutes
			smDDNS = SM_IDLE;
			break;
	}
}
Пример #8
0
void TelnetTask(void)
{
	BYTE		vTelnetSession;
	WORD		w, w2;
	TCP_SOCKET	MySocket;
	char outstr[60];


	// Perform one time initialization on power up
	if(!bInitialized)
	{
		for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
		{
			hTelnetSockets[vTelnetSession] = INVALID_SOCKET;
			vTelnetStates[vTelnetSession] = SM_HOME;
		}
		bInitialized = TRUE;
	}

	// Loop through each telnet session and process state changes and TX/RX data
	for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
	{
		// Load up static state information for this session
		MySocket = hTelnetSockets[vTelnetSession];
		TelnetState = vTelnetStates[vTelnetSession];

		// Reset our state if the remote client disconnected from us
		if(MySocket != INVALID_SOCKET)
		{
			if(TCPWasReset(MySocket))
				TelnetState = SM_PRINT_LOGIN;
		}

		// Handle session state
		switch(TelnetState)
		{
			case SM_HOME:
				// Connect a socket to the remote TCP server
				MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
				
				// Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
				// If this ever happens, you need to go add one to TCPIPConfig.h
				if(MySocket == INVALID_SOCKET)
					break;
	
				// Open an SSL listener if SSL server support is enabled
				#if defined(STACK_USE_SSL_SERVER)
					TCPAddSSLListener(MySocket, TELNETS_PORT);
				#endif
	
				TelnetState++;
				break;
	
			case SM_PRINT_LOGIN:
				#if defined(STACK_USE_SSL_SERVER)
					// Reject unsecured connections if TELNET_REJECT_UNSECURED is defined
					#if defined(TELNET_REJECT_UNSECURED)
						if(!TCPIsSSL(MySocket))
						{
							if(TCPIsConnected(MySocket))
							{
								TCPDisconnect(MySocket);
								TCPDisconnect(MySocket);
								break;
							}	
						}
					#endif
						
					// Don't attempt to transmit anything if we are still handshaking.
					if(TCPSSLIsHandshaking(MySocket))
						break;
				#endif

				sprintf(outstr,"%s%d%s",(char *)strTitle,AppConfig.SerialNumber,(char *)strTitle1);
			
				// Make certain the socket can be written to
				if(TCPIsPutReady(MySocket) < strlen(outstr))
					break;
				
				// Place the application protocol data into the transmit buffer.
				TCPPutString(MySocket, (BYTE *)outstr);
	
				// Send the packet
				TCPFlush(MySocket);
				TelnetState++;
	
			case SM_GET_LOGIN:
				// Make sure we can put the password prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
			
				// Search for the username -- case insensitive
				w2 = TCPFindArray(MySocket, TELNET_USERNAME, strlen((char*)TELNET_USERNAME), 0, TRUE);
				if((w2 < 0) || !((w2 == ((w - strlen((char *)TELNET_USERNAME)) - 1)) || (w2 == (w - strlen((char *)TELNET_USERNAME)))))
				{
					// Did not find the username, but let's pretend we did so we don't leak the user name validity
					TelnetState = SM_GET_PASSWORD_BAD_LOGIN;	
				}
				else
				{
					TelnetState = SM_GET_PASSWORD;
				}
	
				// Username verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the password prompt
				TCPPutROMString(MySocket, strPassword);
				TCPFlush(MySocket);
				break;
	
			case SM_GET_PASSWORD:
			case SM_GET_PASSWORD_BAD_LOGIN:
				// Make sure we can put the authenticated prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
	
				// Search for the password -- case sensitive
				w2 = TCPFindArray(MySocket, TELNET_PASSWORD, strlen((char *)TELNET_PASSWORD), 0, FALSE);

				if((w2 != 3u) || !(((strlen((char *)TELNET_PASSWORD) == w-4)) || ((strlen((char *)TELNET_PASSWORD) == w-3)))
					|| (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
				{
					// Did not find the password
					TelnetState = SM_PRINT_LOGIN;	
					TCPPutROMString(MySocket, strAccessDenied);
					TCPDisconnect(MySocket);
					break;
				}
	
				// Password verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the authenticated prompt
				TCPPutROMString(MySocket, strAuthenticated);
				TCPFlush(MySocket);
				TelnetState = SM_AUTHENTICATED;
				// No break
		
			case SM_AUTHENTICATED:
				break;
		}
		// Save session state back into the static array
		hTelnetSockets[vTelnetSession] = MySocket;
		vTelnetStates[vTelnetSession] = TelnetState;
	}
}
Пример #9
0
static void InitAppConfig(void)
{
#if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS)
	unsigned char vNeedToSaveDefaults = 0;
#endif
	
	while(1)
	{
		// Start out zeroing all AppConfig bytes to ensure all fields are 
		// deterministic for checksum generation
		memset((void*)&AppConfig, 0x00, sizeof(AppConfig));
		
		AppConfig.Flags.bIsDHCPEnabled = TRUE;
		AppConfig.Flags.bInConfigMode = TRUE;
		memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
//		{
//			_prog_addressT MACAddressAddress;
//			MACAddressAddress.next = 0x157F8;
//			_memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr));
//		}
		AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
		AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
		AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
		AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
		AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
		AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul  | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul  | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
		AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul  | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul  | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;
	
	
		// SNMP Community String configuration
		#if defined(STACK_USE_SNMP_SERVER)
		{
			BYTE i;
			static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES;
			static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES;
			ROM char * strCommunity;
			
			for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++)
			{
				// Get a pointer to the next community string
				strCommunity = cReadCommunities[i];
				if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0]))
					strCommunity = "";
	
				// Ensure we don't buffer overflow.  If your code gets stuck here, 
				// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
				// is either too small or one of your community string lengths 
				// (SNMP_READ_COMMUNITIES) are too large.  Fix either.
				if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0]))
					while(1);
				
				// Copy string into AppConfig
				strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity);
	
				// Get a pointer to the next community string
				strCommunity = cWriteCommunities[i];
				if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0]))
					strCommunity = "";
	
				// Ensure we don't buffer overflow.  If your code gets stuck here, 
				// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
				// is either too small or one of your community string lengths 
				// (SNMP_WRITE_COMMUNITIES) are too large.  Fix either.
				if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0]))
					while(1);
	
				// Copy string into AppConfig
				strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity);
			}
		}
		#endif
	
		// Load the default NetBIOS Host Name
		memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
		FormatNetBIOSName(AppConfig.NetBIOSName);
	
		#if defined(WF_CS_TRIS)
			// Load the default SSID Name
			WF_ASSERT(sizeof(MY_DEFAULT_SSID_NAME) <= sizeof(AppConfig.MySSID));
			memcpypgm2ram(AppConfig.MySSID, (ROM void*)MY_DEFAULT_SSID_NAME, sizeof(MY_DEFAULT_SSID_NAME));
			AppConfig.SsidLength = sizeof(MY_DEFAULT_SSID_NAME) - 1;
	        #if defined (EZ_CONFIG_STORE)
	        AppConfig.SecurityMode = MY_DEFAULT_WIFI_SECURITY_MODE;
	        AppConfig.networkType = MY_DEFAULT_NETWORK_TYPE;
	        AppConfig.dataValid = 0;
	        #endif // EZ_CONFIG_STORE
		#endif

		// Compute the checksum of the AppConfig defaults as loaded from ROM
		wOriginalAppConfigChecksum = CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig));

		#if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS)
		{
			NVM_VALIDATION_STRUCT NVMValidationStruct;

			// Check to see if we have a flag set indicating that we need to 
			// save the ROM default AppConfig values.
			if(vNeedToSaveDefaults)
				SaveAppConfig(&AppConfig);
		
			// Read the NVMValidation record and AppConfig struct out of EEPROM/Flash
			#if defined(EEPROM_CS_TRIS)
			{
				XEEReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct));
				XEEReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig));
			}
			#elif defined(SPIFLASH_CS_TRIS)
			{
				SPIFlashReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct));
				SPIFlashReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig));
			}
			#endif
	
			// Check EEPROM/Flash validitity.  If it isn't valid, set a flag so 
			// that we will save the ROM default values on the next loop 
			// iteration.
			if((NVMValidationStruct.wConfigurationLength != sizeof(AppConfig)) ||
			   (NVMValidationStruct.wOriginalChecksum != wOriginalAppConfigChecksum) ||
			   (NVMValidationStruct.wCurrentChecksum != CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig))))
			{
				// Check to ensure that the vNeedToSaveDefaults flag is zero, 
				// indicating that this is the first iteration through the do 
				// loop.  If we have already saved the defaults once and the 
				// EEPROM/Flash still doesn't pass the validity check, then it 
				// means we aren't successfully reading or writing to the 
				// EEPROM/Flash.  This means you have a hardware error and/or 
				// SPI configuration error.
				if(vNeedToSaveDefaults)
				{
					while(1);
				}
				
				// Set flag and restart loop to load ROM defaults and save them
				vNeedToSaveDefaults = 1;
				continue;
			}
			
			// If we get down here, it means the EEPROM/Flash has valid contents 
			// and either matches the ROM defaults or previously matched and 
			// was run-time reconfigured by the user.  In this case, we shall 
			// use the contents loaded from EEPROM/Flash.
			break;
		}
		#endif
		break;
	}
	WiFiInfo.CurrentConfigHasChanged = 1;

    #if defined (EZ_CONFIG_STORE)
    // Set configuration for ZG from NVM
    /* Set security type and key if necessary, convert from app storage to ZG driver */

    if (AppConfig.dataValid)
        CFGCXT.isWifiDoneConfigure = 1;

    AppConfig.saveSecurityInfo = FALSE;
    #endif // EZ_CONFIG_STORE
}
Пример #10
0
/*********************************************************************
 * Function:        void TelnetTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void TelnetTask(void)
{
	BYTE 		i;
	BYTE		vTelnetSession;
	WORD		w, w2;
	TCP_SOCKET	MySocket;
	enum
	{
		SM_HOME = 0,
		SM_PRINT_LOGIN,
		SM_GET_LOGIN,
		SM_GET_PASSWORD,
		SM_GET_PASSWORD_BAD_LOGIN,
		SM_AUTHENTICATED,
		SM_REFRESH_VALUES
	} TelnetState;
	static TCP_SOCKET hTelnetSockets[MAX_TELNET_CONNECTIONS];
	static BYTE vTelnetStates[MAX_TELNET_CONNECTIONS];
	static BOOL bInitialized = FALSE;

	// Perform one time initialization on power up
	if(!bInitialized)
	{
		for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
		{
			hTelnetSockets[vTelnetSession] = INVALID_SOCKET;
			vTelnetStates[vTelnetSession] = SM_HOME;
		}
		bInitialized = TRUE;
	}


	// Loop through each telnet session and process state changes and TX/RX data
	for(vTelnetSession = 0; vTelnetSession < MAX_TELNET_CONNECTIONS; vTelnetSession++)
	{
		// Load up static state information for this session
		MySocket = hTelnetSockets[vTelnetSession];
		TelnetState = vTelnetStates[vTelnetSession];

		// Reset our state if the remote client disconnected from us
		if(MySocket != INVALID_SOCKET)
		{
			if(TCPWasReset(MySocket))
				TelnetState = SM_PRINT_LOGIN;
		}
	
		// Handle session state
		switch(TelnetState)
		{
			case SM_HOME:
				// Connect a socket to the remote TCP server
				MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
				
				// Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
				// If this ever happens, you need to go add one to TCPIPConfig.h
				if(MySocket == INVALID_SOCKET)
					break;
	
				TelnetState++;
				break;
	
			case SM_PRINT_LOGIN:
				// Make certain the socket can be written to
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle))
					break;
				
				// Place the application protocol data into the transmit buffer.
				TCPPutROMString(MySocket, strTitle);
	
				// Send the packet
				TCPFlush(MySocket);
				TelnetState++;
	
			case SM_GET_LOGIN:
				// Make sure we can put the password prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
			
				// Search for the username -- case insensitive
				w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_USERNAME, sizeof(TELNET_USERNAME)-1, 0, TRUE);
				if((w2 != 0u) || !((sizeof(TELNET_USERNAME)-1 == w) || (sizeof(TELNET_USERNAME) == w)))
				{
					// Did not find the username, but let's pretend we did so we don't leak the user name validity
					TelnetState = SM_GET_PASSWORD_BAD_LOGIN;	
				}
				else
				{
					TelnetState = SM_GET_PASSWORD;
				}
	
				// Username verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the password prompt
				TCPPutROMString(MySocket, strPassword);
				TCPFlush(MySocket);
				break;
	
			case SM_GET_PASSWORD:
			case SM_GET_PASSWORD_BAD_LOGIN:
				// Make sure we can put the authenticated prompt
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
					break;
	
				// See if the user pressed return
				w = TCPFind(MySocket, '\n', 0, FALSE);
				if(w == 0xFFFFu)
				{
					if(TCPGetRxFIFOFree(MySocket) == 0u)
					{
						TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
						TCPDisconnect(MySocket);
					}
	
					break;
				}
	
				// Search for the password -- case sensitive
				w2 = TCPFindROMArray(MySocket, (ROM BYTE*)TELNET_PASSWORD, sizeof(TELNET_PASSWORD)-1, 0, FALSE);
				if((w2 != 3u) || !((sizeof(TELNET_PASSWORD)-1 == w-3) || (sizeof(TELNET_PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
				{
					// Did not find the password
					TelnetState = SM_PRINT_LOGIN;	
					TCPPutROMString(MySocket, strAccessDenied);
					TCPDisconnect(MySocket);
					break;
				}
	
				// Password verified, throw this line of data away
				TCPGetArray(MySocket, NULL, w + 1);
	
				// Print the authenticated prompt
				TCPPutROMString(MySocket, strAuthenticated);
				TelnetState = SM_AUTHENTICATED;
				// No break
		
			case SM_AUTHENTICATED:
				if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4)
					break;
	
				TCPPutROMString(MySocket, strDisplay);
				TelnetState++;
	
				// All future characters will be bold
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m");
	
			case SM_REFRESH_VALUES:
				if(TCPIsPutReady(MySocket) >= 78u)
				{
					//[10;1]
					//"SNTP Time:    (disabled)\r\n"
					//"Analog:             1023\r\n"
					//"Buttons:         3 2 1 0\r\n"
					//"LEDs:    7 6 5 4 3 2 1 0\r\n"
		
					// Write current UTC seconds from SNTP module, if it is enable 
					// and has changed.  Note that conversion from a DWORD to an 
					// ASCII string can take a lot of CPU power, so we only print 
					// this if the value has changed.
					#if defined(STACK_USE_SNTP_CLIENT)
					{
						static DWORD dwTime;
						BYTE vTime[11];
						
						if(dwTime != SNTPGetUTCSeconds())
						{
							
							// Position cursor at Line 10, Col 15
							TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;15f");
							dwTime = SNTPGetUTCSeconds();
							ultoa(dwTime, vTime);
							TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 10-strlen((char*)vTime));							
							TCPPutString(MySocket, vTime);
						}
					}
					#endif
	
					// Position cursor at Line 11, Col 21
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;21f");
	
					// Put analog value with space padding on right side for 4 characters
					TCPPutROMArray(MySocket, (ROM BYTE*)strSpaces, 4-strlen((char*)AN0String));
					TCPPutString(MySocket, AN0String);
	
					// Put Buttons
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;18f");
					TCPPut(MySocket, BUTTON3_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON2_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON1_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, BUTTON0_IO ? '1':'0');
		
		
					// Put LEDs
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;10f");
					TCPPut(MySocket, LED1_IO ? '1':'0');
					TCPPut(MySocket, ' ');
					TCPPut(MySocket, LED0_IO ? '1':'0');
		
					// Put cursor at beginning of next line
					TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[14;1f");
	
					// Send the data out immediately
					TCPFlush(MySocket);
				}
	
				if(TCPIsGetReady(MySocket))
				{
					TCPGet(MySocket, &i);
					switch(i)
					{
						case '\r':
						case 'q':
						case 'Q':
							if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye))
								TCPPutROMString(MySocket, strGoodBye);
							TCPDisconnect(MySocket);
							TelnetState = SM_PRINT_LOGIN;							
							break;
					}
				}
	
				break;
		}


		// Save session state back into the static array
		hTelnetSockets[vTelnetSession] = MySocket;
		vTelnetStates[vTelnetSession] = TelnetState;
	}
}
Пример #11
0
Файл: HTTP.c Проект: sonite/mGit
/*********************************************************************
 * Serve a single connection
 ********************************************************************/
static void HTTP_Process(BOOL available)
{
    BYTE error;
	const struct HTTP_FileContent rom *content;

retry:
	switch(HTTP.StateMachine)
	{
	// Introduced explicit disconnect state handling in order to properly
	// finish all queries
	case SM_HTTP_IDLE:
		// Connections closed for any reason will automatically end up in
		// the disconnected state, so this is a good place to make sure
		// we don't leak files.
		if(HTTP.file)
		{
			FSfclose(HTTP.file);
			HTTP.file = NULL;
		}

		// Just wait for any connection to be made
		if(!TCPIsConnected(HTTP.socket))
			// Don't break for new connections.  There may be 
 			// an entire request in the buffer already.
			return;
		
		HTTP.StateMachine = SM_HTTP_PARSE_REQUEST;
		
		// Adjust the TCP FIFOs for optimal reception of 
		// the next HTTP request from the browser
		///while(!TCPAdjustFIFOSize(HTTP.socket, 1, 0, TCP_ADJUST_PRESERVE_RX | TCP_ADJUST_GIVE_REST_TO_RX));
		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PARSE_REQUEST:
		// Verify the entire first line is in the FIFO and
		if(!HTTP_SetBuf(-1))
			break;

		// Check that the file system is mounted
		error = HTTP_ERR_NOT_AVAILABLE;

		if(available)
		{
			// Parse the request line
			error = HTTP_ERR_NOT_IMPLEMENTED;
			// Parses the first line for a file name and GET args 
			if(HTTP_Parse())
			{				
				static char read[] = FS_READ;
				
				error = HTTP_ERR_NOT_FOUND;
				// Open the file
				if(HTTP.file = FSfopen(HTTP_ParseName, read), HTTP.file)
					// Success!
					goto retry;
			}
		}

		HTTP.FileType = error;
		HTTP.StateMachine = SM_HTTP_ERROR;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_ERROR:
		if(TCPIsPutReady(HTTP.socket) >= strlenpgm((const char far rom *) HTTP_Errors[HTTP.FileType]))
		{
			TCPPutROMString(HTTP.socket, (ROM BYTE *) HTTP_Errors[HTTP.FileType]);
			TCPFlush(HTTP.socket);
			TCPDisconnect(HTTP.socket);
			HTTP.StateMachine = SM_HTTP_IDLE;
		}
		break;

	// Parse out the POST header lines
	case SM_HTTP_POST_HEADER:
		// Is the next line ready yet?
		while(HTTP_SetBuf(-1))
		{
			char ch;

			// Isolate the field name
			HTTP_Buffer.write = HTTP_Data;

			do
			{
				ch = HTTP_GetBuf();

				// The payload starts after the first empty line
				if(ch == '\0')
				{
					HTTP.StateMachine = SM_HTTP_POST_ARGUMENTS;
					goto retry;
				}

				HTTP_PutBuf(ch);
			}
			while(ch != ' ');

			HTTP_PutBuf('\0');

			// The content length is needed to know the length of the variable block
			if(!Cfg_StringCompare(HTTP_Data, (const char ROM *) HTTP_CONTENT_LENGTH_STRING))
			{
				unsigned int len = 0;

				while(ch = HTTP_GetBuf() - '0', (unsigned char) ch <= 9)
				{
					len *= 10;
					len += ch;
				}

				HTTP.length = len;
			}
		}
		break;

	case SM_HTTP_POST_ARGUMENTS:
		if(!HTTP_SetBuf(HTTP.length))
			break;

		if(HTTP_ParseAttribs())
		{
			Microchip_RefreshSettings();
			Microchip_RestoreSPI();
		};

		HTTP.StateMachine = SM_HTTP_PARSE_HEADERS;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PARSE_HEADERS:
		content = &HTTP_FileContent[HTTP.FileType];
		
		// Write response string
		TCPPutROMString(HTTP.socket, HTTP_OK_STRING);
		TCPPutROMString(HTTP.socket, (ROM BYTE *) content->mime);

		// Generic cache control mechanism
		TCPPutROMString(HTTP.socket, content->cache ? HTTP_NL_DO_CACHE_STRING : HTTP_NL_NO_CACHE_STRING);

		//  Generate the content-length field so that dismount errors can be detected
		HTTP.dynamic = content->dynamic;

		if(!HTTP.dynamic)
		{
			Numeric(Num_Buffer, HTTP.file->size);
			TCPPutROMString(HTTP.socket, HTTP_NL_CONTENT_LENGTH_STRING);
			TCPPutString(HTTP.socket, (BYTE *) Num_Buffer);
		}

		TCPPutROMString(HTTP.socket, HTTP_NL_HEADER_END_STRING);

		HTTP.StateMachine = SM_HTTP_PROCESS_GET;

		// Fallthrough
		// .
		// .
		// .
	case SM_HTTP_PROCESS_GET:
		// Throw away any more data receieved - we aren't going to use it.
		TCPDiscard(HTTP.socket);

		if(HTTP_SendFile())
		{
			TCPFlush(HTTP.socket);
			TCPDisconnect(HTTP.socket);
			HTTP.StateMachine = SM_HTTP_IDLE;
		}
		break;
	}

	// Flush out any remaining line-buffered data
	HTTP_FlushBuf();

	// If, during handling of HTTP socket, it gets disconnected then forget
	// about any previous processing and return to the idle state.
	//
	// Do wait until as much processing as possible has been completed on
	// whatever data remains in the buffers however
	if(!TCPIsConnected(HTTP.socket))
		HTTP.StateMachine = SM_HTTP_IDLE;
}
Пример #12
0
static int process_host_buffer(bd_t handler)
{
	int result = 0;
//    event_t sm_evnt=0;
	bcp_header_t * hdr = (bcp_header_t *) bcp_buffer(handler)->buf;

	switch (TYPE(hdr->hdr_s.type)) {
	case TYPE_NPD1:
		switch (hdr->raw[RAW_QAC]) {
		case QAC_GETVER:
			switch (hdr->hdr_s.packtype_u.npd1.data) {
			case (MYSELF + 1):
				/* readers ver */
				hdr->hdr_s.type = TYPE_NPDL;
				hdr->raw[RAW_DATA] = hdr->hdr_s.packtype_u.npd1.data;
				hdr->hdr_s.packtype_u.npdl.len = strlenpgm(ver) + 3;
				strcpypgm2ram((char *) &hdr->raw[RAW_DATA + 1], ver);
				bcp_send_buffer(handler);
				break;
			default:
				result = -1;
			}
			break;

		default:
			result = -1;
		}
		break;
	case TYPE_NPDL:

	if(hdr->hdr_s.packtype_u.npdl.qac == QAC_AR_REQUEST) {

		BYTE msg_len = hdr->hdr_s.packtype_u.npdl.len - (sizeof(ar_rsp) - MAX_MSG_SIZE) - 2;
		ar_rsp *request = (ar_rsp *) &hdr->raw[RAW_DATA];

		if(state == WAIT_HOST_ANSWER)	// else DropIt() )
			ServiceIt (request->access_code, request->msg,  msg_len);


//		msg_len = (msg_len > 32) ? 32 : msg_len;

//		memset((void *)LCDText, ' ', 32);
//		memcpy((void *)LCDText, (void *)request->msg, msg_len);
//		LCDText[msg_len] = '\0';
//		LCD_decode(LCDText);
//		LCDUpdate();

//        if(request->access_code & ACCESS_INDICATOR)        
//        	event_send(MODULE_SRVMACHINE, EVT_SM_ENABLE_INDICATOR);
//
//		if(!(request->access_code & ACCESS_CONTROL)) {
//			event_send(MODULE_SRVMACHINE, EVT_SM_DISABLE_CONTROL);
//			state = WAIT_UID;
//			readers_reset_state();
//		} else {
//			event_send(MODULE_SRVMACHINE, EVT_SM_ENABLE_CONTROL);
//			state = WAIT_SM;
//		}

	}
		break;

	default:
		result = -1;
	}

	bcp_release_buffer(handler);
	TRACE("\n\rACS: buffer released (rsp sent)");

	return result;
}
Пример #13
0
ROM uint8_t* UDPPutROMString(ROM uint8_t *strData)
{
    return strData + UDPPutROMArray(strData, strlenpgm((ROM char*)strData));
}
Пример #14
0
ROM BYTE* UDPPutROMString(ROM BYTE *strData)
{
	return strData + UDPPutROMArray(strData, strlenpgm((ROM char*)strData));
}
Пример #15
0
/*********************************************************************
 * 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;
    DWORD 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 = 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;
}
Пример #16
0
void MyWIFI_InitAppConfig(void) {

    // Start out zeroing all AppConfig bytes to ensure all fields are
    // deterministic for checksum generation
    memset((void*) &AppConfig, 0x00, sizeof (AppConfig));

    AppConfig.Flags.bIsDHCPEnabled = TRUE;
    AppConfig.Flags.bInConfigMode = TRUE;
    memcpypgm2ram((void*) &AppConfig.MyMACAddr, (ROM void*) SerializedMACAddress, sizeof (AppConfig.MyMACAddr));

    AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2 << 8ul | MY_DEFAULT_IP_ADDR_BYTE3 << 16ul | MY_DEFAULT_IP_ADDR_BYTE4 << 24ul;
    AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
    AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2 << 8ul | MY_DEFAULT_MASK_BYTE3 << 16ul | MY_DEFAULT_MASK_BYTE4 << 24ul;
    AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
    AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2 << 8ul | MY_DEFAULT_GATE_BYTE3 << 16ul | MY_DEFAULT_GATE_BYTE4 << 24ul;
    AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2 << 8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3 << 16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4 << 24ul;
    AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2 << 8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3 << 16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4 << 24ul;


    // SNMP Community String configuration
    #if defined(STACK_USE_SNMP_SERVER)
    {
        BYTE i;
        static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES;
        static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES;
        ROM char * strCommunity;

        for (i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++) {
            // Get a pointer to the next community string
            strCommunity = cReadCommunities[i];
            if (i >= sizeof (cReadCommunities) / sizeof (cReadCommunities[0]))
                strCommunity = "";

            // Ensure we don't buffer overflow.  If your code gets stuck here,
            // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h
            // is either too small or one of your community string lengths
            // (SNMP_READ_COMMUNITIES) are too large.  Fix either.
            if (strlenpgm(strCommunity) >= sizeof (AppConfig.readCommunity[0]))
                while (1);

            // Copy string into AppConfig
            strcpypgm2ram((char*) AppConfig.readCommunity[i], strCommunity);

            // Get a pointer to the next community string
            strCommunity = cWriteCommunities[i];
            if (i >= sizeof (cWriteCommunities) / sizeof (cWriteCommunities[0]))
                strCommunity = "";

            // Ensure we don't buffer overflow.  If your code gets stuck here,
            // it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h
            // is either too small or one of your community string lengths
            // (SNMP_WRITE_COMMUNITIES) are too large.  Fix either.
            if (strlenpgm(strCommunity) >= sizeof (AppConfig.writeCommunity[0]))
                while (1);

            // Copy string into AppConfig
            strcpypgm2ram((char*) AppConfig.writeCommunity[i], strCommunity);
        }
    }
    #endif

    // Load the default NetBIOS Host Name
    memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*) MY_DEFAULT_HOST_NAME, 16);
    FormatNetBIOSName(AppConfig.NetBIOSName);

    // Load the default SSID Name
    WF_ASSERT(sizeof (MY_DEFAULT_SSID_NAME) <= sizeof (AppConfig.MySSID));
    memcpypgm2ram(AppConfig.MySSID, (ROM void*) MY_DEFAULT_SSID_NAME, sizeof (MY_DEFAULT_SSID_NAME));
    AppConfig.SsidLength = sizeof (MY_DEFAULT_SSID_NAME) - 1;

    AppConfig.SecurityMode = MY_DEFAULT_WIFI_SECURITY_MODE;
    AppConfig.WepKeyIndex = MY_DEFAULT_WEP_KEY_INDEX;

    #if (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_OPEN)
        memset(AppConfig.SecurityKey, 0x00, sizeof (AppConfig.SecurityKey));
        AppConfig.SecurityKeyLength = 0;

    #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_40
        memcpypgm2ram(AppConfig.SecurityKey, (ROM void*) MY_DEFAULT_WEP_KEYS_40, sizeof (MY_DEFAULT_WEP_KEYS_40) - 1);
        AppConfig.SecurityKeyLength = sizeof (MY_DEFAULT_WEP_KEYS_40) - 1;

    #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_104
        memcpypgm2ram(AppConfig.SecurityKey, (ROM void*) MY_DEFAULT_WEP_KEYS_104, sizeof (MY_DEFAULT_WEP_KEYS_104) - 1);
        AppConfig.SecurityKeyLength = sizeof (MY_DEFAULT_WEP_KEYS_104) - 1;

    #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_KEY)       || \
          (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_KEY)      || \
	  (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_KEY)
        memcpypgm2ram(AppConfig.SecurityKey, (ROM void*) MY_DEFAULT_PSK, sizeof (MY_DEFAULT_PSK) - 1);
        AppConfig.SecurityKeyLength = sizeof (MY_DEFAULT_PSK) - 1;

    #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_PASS_PHRASE)     || \
	  (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_PASS_PHRASE)    || \
	  (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE)
        memcpypgm2ram(AppConfig.SecurityKey, (ROM void*) MY_DEFAULT_PSK_PHRASE, sizeof (MY_DEFAULT_PSK_PHRASE) - 1);
        AppConfig.SecurityKeyLength = sizeof (MY_DEFAULT_PSK_PHRASE) - 1;

    #else
        #error "No security defined"
    #endif

    // Compute the checksum of the AppConfig defaults as loaded from ROM
    wOriginalAppConfigChecksum = CalcIPChecksum((BYTE*) & AppConfig, sizeof (AppConfig));
}
Пример #17
0
/*********************************************************************
 * Function:        static void HTTPProcess(void)
 *
 * PreCondition:    HTTPInit() called and curHTTP loaded
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:		Serves the current HTTP connection in curHTTP
 *
 * Note:            None
 ********************************************************************/
static void HTTPProcess(void)
{
    WORD lenA, lenB;
	BYTE c, i;
    BOOL isDone;
	BYTE *ext;
	BYTE buffer[HTTP_MAX_HEADER_LEN+1];

    do
    {
        isDone = TRUE;

        // If a socket is disconnected at any time 
        // forget about it and return to idle state.
        if(TCPWasReset(sktHTTP))
        {
            smHTTP = SM_HTTP_IDLE;

			// Make sure any opened files are closed
			if(curHTTP.file != MPFS_INVALID_HANDLE)
			{
				MPFSClose(curHTTP.file);
				curHTTP.file = MPFS_INVALID_HANDLE;
			}
			if(curHTTP.offsets != MPFS_INVALID_HANDLE)
			{
				MPFSClose(curHTTP.offsets);
				curHTTP.offsets = MPFS_INVALID_HANDLE;
			}

			// Adjust the TCP FIFOs for optimal reception of 
			// the next HTTP request from the browser
			TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_GIVE_REST_TO_RX | TCP_ADJUST_PRESERVE_RX);
        }


        switch(smHTTP)
        {

        case SM_HTTP_IDLE:

			// Check how much data is waiting
			lenA = TCPIsGetReady(sktHTTP);

			// If a connection has been made, then process the request
            if(lenA)
            {// Clear out state info and move to next state
				curHTTP.ptrData = curHTTP.data;
				smHTTP = SM_HTTP_PARSE_REQUEST;
				curHTTP.isAuthorized = 0xff;
				curHTTP.hasArgs = FALSE;
				curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
				curHTTP.callbackPos = 0xffffffff;
				curHTTP.byteCount = 0;
			}
			
			// In all cases, we break
			// For new connections, this waits for the buffer to fill
			break;

		case SM_HTTP_PARSE_REQUEST:

			// Verify the entire first line is in the FIFO
			if(TCPFind(sktHTTP, '\n', 0, FALSE) == 0xffff)
			{// First line isn't here yet
				if(TCPGetRxFIFOFree(sktHTTP) == 0)
				{// If the FIFO is full, we overflowed
					curHTTP.httpStatus = HTTP_OVERFLOW;
					smHTTP = SM_HTTP_SERVE_HEADERS;
					isDone = FALSE;
				}
				if(TickGet() > curHTTP.callbackID)
				{// A timeout has occurred
					TCPDisconnect(sktHTTP);
					smHTTP = SM_HTTP_DISCONNECT;
					isDone = FALSE;
				}
				break;
			}

			// Reset the watchdog timer
			curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;

			// Determine the request method
			lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
			if(lenA > 5)
				lenA = 5;
			TCPGetArray(sktHTTP, curHTTP.data, lenA+1);

		    if ( memcmppgm2ram(curHTTP.data, (ROM void*)"GET", 3) == 0)
			    curHTTP.httpStatus = HTTP_GET;
			#if defined(HTTP_USE_POST)
		    else if ( memcmppgm2ram(curHTTP.data, (ROM void*)"POST", 4) == 0)
			    curHTTP.httpStatus = HTTP_POST;
			#endif
		    else
			{// Unrecognized method, so return not implemented
		        curHTTP.httpStatus = HTTP_NOT_IMPLEMENTED;
				smHTTP = SM_HTTP_SERVE_HEADERS;
				isDone = FALSE;
				break;
			}

			// Find end of filename
			lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
			lenB = TCPFindEx(sktHTTP, '?', 0, lenA, FALSE);
			lenA = mMIN(lenA, lenB);
			
			// If the file name is too long, then reject the request
			if(lenA > HTTP_MAX_DATA_LEN - HTTP_DEFAULT_LEN - 1)
			{
				curHTTP.httpStatus = HTTP_OVERFLOW;
				smHTTP = SM_HTTP_SERVE_HEADERS;
				isDone = FALSE;
				break;
			}

			// Read in the filename and decode
			lenB = TCPGetArray(sktHTTP, curHTTP.data, lenA);
			curHTTP.data[lenB] = '\0';
			HTTPURLDecode(curHTTP.data);
			
			// Check if this is an MPFS Upload
			#if defined(HTTP_MPFS_UPLOAD)
			if(memcmppgm2ram(&curHTTP.data[1], HTTP_MPFS_UPLOAD, strlenpgm(HTTP_MPFS_UPLOAD)) == 0)
			{// Read remainder of line, and bypass all file opening, etc.
				#if defined(HTTP_USE_AUTHENTICATION)
				curHTTP.isAuthorized = HTTPAuthenticate(NULL, NULL, &curHTTP.data[1]);
				#endif
				if(curHTTP.httpStatus == HTTP_GET)
					curHTTP.httpStatus = HTTP_MPFS_FORM;
				else
					curHTTP.httpStatus = HTTP_MPFS_UP;

				smHTTP = SM_HTTP_PARSE_HEADERS;
				isDone = FALSE;
				break;
			}
			#endif
			
			// If the last character is a not a directory delimiter, then try to open the file
			// String starts at 2nd character, because the first is always a '/'
			if(curHTTP.data[lenB-1] != '/')
				curHTTP.file = MPFSOpen(&curHTTP.data[1]);
				
			// If the open fails, then add our default name and try again
			if(curHTTP.file == MPFS_INVALID_HANDLE)
			{
				// Add the directory delimiter if needed
				if(curHTTP.data[lenB-1] != '/')
					curHTTP.data[lenB++] = '/';
				
				// Add our default file name			
				// If this is a loopback, then it's an SSL connection
				if(TCPIsLoopback(sktHTTP))
				{
					strcpypgm2ram((void*)&curHTTP.data[lenB], HTTPS_DEFAULT_FILE);
					lenB += strlenpgm(HTTPS_DEFAULT_FILE);
				}
				else
				{
					strcpypgm2ram((void*)&curHTTP.data[lenB], HTTP_DEFAULT_FILE);
					lenB += strlenpgm(HTTP_DEFAULT_FILE);
				}
					
				// Try to open again
				curHTTP.file = MPFSOpen(&curHTTP.data[1]);
			}
			
			// Find the extension in the filename
			for(ext = curHTTP.data + lenB-1; ext != curHTTP.data; ext--)
				if(*ext == '.')
					break;
					
			// Compare to known extensions to determine Content-Type
			ext++;
			for(curHTTP.fileType = HTTP_TXT; curHTTP.fileType < HTTP_UNKNOWN; curHTTP.fileType++)
				if(!stricmppgm2ram(ext, (ROM void*)httpFileExtensions[curHTTP.fileType]))
					break;
			
			// Perform first round authentication (pass file name only)
			#if defined(HTTP_USE_AUTHENTICATION)
			curHTTP.isAuthorized = HTTPAuthenticate(NULL, NULL, &curHTTP.data[1]);
			#endif
			
			// If the file was found, see if it has an index
			if(curHTTP.file != MPFS_INVALID_HANDLE &&
				(MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_HASINDEX) )
			{
				curHTTP.data[lenB-1] = '#';
				curHTTP.offsets = MPFSOpen(&curHTTP.data[1]);
			}

			// Read GET args, up to buffer size - 1
			lenA = TCPFind(sktHTTP, ' ', 0, FALSE);
			if(lenA != 0)
			{
				curHTTP.hasArgs = TRUE;
				
				// Trash the '?'
				TCPGet(sktHTTP, &c);

				// Verify there's enough space
				lenA--;
				if(lenA >= HTTP_MAX_DATA_LEN - 2)
				{
			        curHTTP.httpStatus = HTTP_OVERFLOW;
					smHTTP = SM_HTTP_SERVE_HEADERS;
					isDone = FALSE;
					break;
				}

				// Read in the arguments and '&'-terminate in anticipation of cookies
				curHTTP.ptrData += TCPGetArray(sktHTTP, curHTTP.data, lenA);
				*(curHTTP.ptrData++) = '&';

			}

			// Clear the rest of the line
			lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
			TCPGetArray(sktHTTP, NULL, lenA + 1);

			// Move to parsing the headers
			smHTTP = SM_HTTP_PARSE_HEADERS;
			
			// No break, continue to parsing headers

		case SM_HTTP_PARSE_HEADERS:

			// Loop over all the headers
			while(1)
			{
				// Make sure entire line is in the FIFO
				lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
				if(lenA == 0xffff)
				{// If not, make sure we can receive more data
					if(TCPGetRxFIFOFree(sktHTTP) == 0)
					{// Overflow
						curHTTP.httpStatus = HTTP_OVERFLOW;
						smHTTP = SM_HTTP_SERVE_HEADERS;
						isDone = FALSE;
					}
					if(TickGet() > curHTTP.callbackID)
					{// A timeout has occured
						TCPDisconnect(sktHTTP);
						smHTTP = SM_HTTP_DISCONNECT;
						isDone = FALSE;
					}
					break;
				}
				
				// Reset the watchdog timer
				curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
				
				// If a CRLF is immediate, then headers are done
				if(lenA == 1)
				{// Remove the CRLF and move to next state
					TCPGetArray(sktHTTP, NULL, 2);
					smHTTP = SM_HTTP_AUTHENTICATE;
					isDone = FALSE;
					break;
				}
	
				// Find the header name, and use isDone as a flag to indicate a match
				lenB = TCPFindEx(sktHTTP, ':', 0, lenA, FALSE) + 2;
				isDone = FALSE;
	
				// If name is too long or this line isn't a header, ignore it
				if(lenB > sizeof(buffer))
				{
					TCPGetArray(sktHTTP, NULL, lenA+1);
					continue;
				}
				
				// Read in the header name
				TCPGetArray(sktHTTP, buffer, lenB);
				buffer[lenB-1] = '\0';
				lenA -= lenB;
		
				// Compare header read to ones we're interested in
				for(i = 0; i < HTTP_NUM_HEADERS; i++)
				{
					if(strcmppgm2ram((char*)buffer, (ROM char *)HTTPRequestHeaders[i]) == 0)
					{// Parse the header and stop the loop
						HTTPHeaderParseLookup(i);
						isDone = TRUE;
						break;
					}
				}
				
				// Clear the rest of the line, and call the loop again
				if(isDone)
				{// We already know how much to remove unless a header was found
					lenA = TCPFind(sktHTTP, '\n', 0, FALSE);
				}
				TCPGetArray(sktHTTP, NULL, lenA+1);
			}
			
			break;

		case SM_HTTP_AUTHENTICATE:
		
			#if defined(HTTP_USE_AUTHENTICATION)
			// Check current authorization state
			if(curHTTP.isAuthorized < 0x80)
			{// 401 error
				curHTTP.httpStatus = HTTP_UNAUTHORIZED;
				smHTTP = SM_HTTP_SERVE_HEADERS;
				isDone = FALSE;
				
				#if defined(HTTP_NO_AUTH_WITHOUT_SSL)
				if(!TCPIsLoopback(sktHTTP))
					curHTTP.httpStatus = HTTP_SSL_REQUIRED;
				#endif

				break;
			}
			#endif

			// Parse the args string
			*curHTTP.ptrData = '\0';
			curHTTP.ptrData = HTTPURLDecode(curHTTP.data);

			// If this is an MPFS upload form request, bypass to headers
			#if defined(HTTP_MPFS_UPLOAD)
			if(curHTTP.httpStatus == HTTP_MPFS_FORM)
			{
				smHTTP = SM_HTTP_SERVE_HEADERS;
				isDone = FALSE;
				break;
			}
			#endif
			
			// Move on to GET args, unless there are none
			smHTTP = SM_HTTP_PROCESS_GET;
			if(!curHTTP.hasArgs)
				smHTTP = SM_HTTP_PROCESS_POST;
			isDone = FALSE;
			curHTTP.hasArgs = FALSE;
			break;

		case SM_HTTP_PROCESS_GET:

			// Run the application callback HTTPExecuteGet()
			if(HTTPExecuteGet() == HTTP_IO_WAITING)
			{// If waiting for asynchronous process, return to main app
				break;
			}

			// Move on to POST data
			smHTTP = SM_HTTP_PROCESS_POST;

		case SM_HTTP_PROCESS_POST:

			#if defined(HTTP_USE_POST)
			
			// See if we have any new data
			if(TCPIsGetReady(sktHTTP) == curHTTP.callbackPos)
			{
				if(TickGet() > curHTTP.callbackID)
				{// If a timeout has occured, disconnect
					TCPDisconnect(sktHTTP);
					smHTTP = SM_HTTP_DISCONNECT;
					isDone = FALSE;
					break;
				}
			}
			
			if(curHTTP.httpStatus == HTTP_POST 
				#if defined(HTTP_MPFS_UPLOAD)
				|| (curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR)
				#endif
				 )
			{
				// Run the application callback HTTPExecutePost()
				#if defined(HTTP_MPFS_UPLOAD)
				if(curHTTP.httpStatus >= HTTP_MPFS_UP && curHTTP.httpStatus <= HTTP_MPFS_ERROR)
				{
					c = HTTPMPFSUpload();
					if(c == HTTP_IO_DONE)
					{
						smHTTP = SM_HTTP_SERVE_HEADERS;
						isDone = FALSE;
						break;
					}
				}
				else
				#endif
				c = HTTPExecutePost();
				
				// If waiting for asynchronous process, return to main app
				if(c == HTTP_IO_WAITING)
				{// return to main app and make sure we don't get stuck by the watchdog
					curHTTP.callbackPos = TCPIsGetReady(sktHTTP) - 1;
					break;
				} else if(c == HTTP_IO_NEED_DATA)
				{// If waiting for more data
					curHTTP.callbackPos = TCPIsGetReady(sktHTTP);
					curHTTP.callbackID = TickGet() + HTTP_TIMEOUT*TICK_SECOND;
					// If more is expected and space is available, return to main app
					if(curHTTP.byteCount > 0 && TCPGetRxFIFOFree(sktHTTP) != 0)
						break;
					else
					{// Handle cases where application ran out of data or buffer space
						curHTTP.httpStatus = HTTP_INTERNAL_SERVER_ERROR;
						smHTTP = SM_HTTP_SERVE_HEADERS;
						isDone = FALSE;
						break;
					}	
				}
			}
			#endif

			// We're done with POST
			smHTTP = SM_HTTP_PROCESS_REQUEST;
			// No break, continue to sending request

		case SM_HTTP_PROCESS_REQUEST:

			// Check for 404
            if(curHTTP.file == MPFS_INVALID_HANDLE)
            {
                curHTTP.httpStatus = HTTP_NOT_FOUND;
                smHTTP = SM_HTTP_SERVE_HEADERS;
                isDone = FALSE;
                break;
            }

			// Set up the dynamic substitutions
			curHTTP.byteCount = 0;
			if(curHTTP.offsets == MPFS_INVALID_HANDLE)
            {// If no index file, then set next offset to huge
	            curHTTP.nextCallback = 0xffffffff;
            }
            else
            {// Read in the next callback index
	            MPFSGetLong(curHTTP.offsets, &(curHTTP.nextCallback));
			}
			
			// Move to next state
			smHTTP = SM_HTTP_SERVE_HEADERS;

		case SM_HTTP_SERVE_HEADERS:

			// We're in write mode now:
			// Adjust the TCP FIFOs for optimal transmission of 
			// the HTTP response to the browser
			TCPAdjustFIFOSize(sktHTTP, 1, 0, TCP_ADJUST_GIVE_REST_TO_TX);
				
			// Send headers
			TCPPutROMString(sktHTTP, (ROM BYTE*)HTTPResponseHeaders[curHTTP.httpStatus]);
			
			// If this is a redirect, print the rest of the Location: header			   
			if(curHTTP.httpStatus == HTTP_REDIRECT)
			{
				TCPPutString(sktHTTP, curHTTP.data);
				TCPPutROMString(sktHTTP, (ROM BYTE*)"\r\n\r\n304 Redirect: ");
				TCPPutString(sktHTTP, curHTTP.data);
				TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CRLF);
			}

			// If not GET or POST, we're done
			if(curHTTP.httpStatus != HTTP_GET && curHTTP.httpStatus != HTTP_POST)
			{// Disconnect
				smHTTP = SM_HTTP_DISCONNECT;
				break;
			}

			// Output the content type, if known
			if(curHTTP.fileType != HTTP_UNKNOWN)
			{
				TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Type: ");
				TCPPutROMString(sktHTTP, (ROM BYTE*)httpContentTypes[curHTTP.fileType]);
				TCPPutROMString(sktHTTP, HTTP_CRLF);
			}
			
			// Output the gzip encoding header if needed
			if(MPFSGetFlags(curHTTP.file) & MPFS2_FLAG_ISZIPPED)
			{
				TCPPutROMString(sktHTTP, (ROM BYTE*)"Content-Encoding: gzip\r\n");
			}
						
			// Output the cache-control
			TCPPutROMString(sktHTTP, (ROM BYTE*)"Cache-Control: ");
			if(curHTTP.httpStatus == HTTP_POST || curHTTP.nextCallback != 0xffffffff)
			{// This is a dynamic page or a POST request, so no cache
				TCPPutROMString(sktHTTP, (ROM BYTE*)"no-cache");
			}
			else
			{// This is a static page, so save it for the specified amount of time
				TCPPutROMString(sktHTTP, (ROM BYTE*)"max-age=");
				TCPPutROMString(sktHTTP, (ROM BYTE*)HTTP_CACHE_LEN);
			}
			TCPPutROMString(sktHTTP, HTTP_CRLF);
			
			// Check if we should output cookies
			if(curHTTP.hasArgs)
				smHTTP = SM_HTTP_SERVE_COOKIES;
			else
			{// Terminate the headers
				TCPPutROMString(sktHTTP, HTTP_CRLF);
				smHTTP = SM_HTTP_SERVE_BODY;
			}
	
			// Move to next stage
			isDone = FALSE;
			break;

		case SM_HTTP_SERVE_COOKIES:

			#if defined(HTTP_USE_COOKIES)
			// If the TX FIFO runs out of space, the client will never get CRLFCRLF
			// Avoid writing huge cookies - keep it under a hundred bytes max

			// Write cookies one at a time as space permits
			for(curHTTP.ptrRead = curHTTP.data; curHTTP.hasArgs != 0; curHTTP.hasArgs--)
			{
				// Write the header
				TCPPutROMString(sktHTTP, (ROM BYTE*)"Set-Cookie: ");

				// Write the name, URL encoded, one character at a time
				while((c = *(curHTTP.ptrRead++)))
				{
					if(c == ' ')
						TCPPut(sktHTTP, '+');
					else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z')
					{
						TCPPut(sktHTTP, '%');
						TCPPut(sktHTTP, btohexa_high(c));
						TCPPut(sktHTTP, btohexa_low(c));
					}
					else
						TCPPut(sktHTTP, c);
				}
				
				TCPPut(sktHTTP, '=');
				
				// Write the value, URL encoded, one character at a time
				while((c = *(curHTTP.ptrRead++)))
				{
					if(c == ' ')
						TCPPut(sktHTTP, '+');
					else if(c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || c > 'z')
					{
						TCPPut(sktHTTP, '%');
						TCPPut(sktHTTP, btohexa_high(c));
						TCPPut(sktHTTP, btohexa_low(c));
					}
					else
						TCPPut(sktHTTP, c);
				}
				
				// Finish the line
				TCPPutROMString(sktHTTP, HTTP_CRLF);

			}
			#endif

			// We're done, move to next state
			TCPPutROMString(sktHTTP, HTTP_CRLF);
			smHTTP = SM_HTTP_SERVE_BODY;

		case SM_HTTP_SERVE_BODY:

			isDone = FALSE;

			// Try to send next packet
			if(HTTPSendFile())
			{// If EOF, then we're done so close and disconnect
				MPFSClose(curHTTP.file);
				curHTTP.file = MPFS_INVALID_HANDLE;
				smHTTP = SM_HTTP_DISCONNECT;
				isDone = TRUE;
			}
			
			// If the TX FIFO is full, then return to main app loop
			if(TCPIsPutReady(sktHTTP) == 0)
				isDone = TRUE;
            break;

		case SM_HTTP_SEND_FROM_CALLBACK:

			isDone = TRUE;

			// Check that at least the minimum bytes are free
			if(TCPIsPutReady(sktHTTP) < HTTP_MIN_CALLBACK_FREE)
				break;

			// Fill TX FIFO from callback
			HTTPPrint(curHTTP.callbackID);
			
			if(curHTTP.callbackPos == 0)
			{// Callback finished its output, so move on
				isDone = FALSE;
				smHTTP = SM_HTTP_SERVE_BODY;
			}// Otherwise, callback needs more buffer space, so return and wait
			
			break;

		case SM_HTTP_DISCONNECT:
		
			// Loopbacks have no wait state, so all data must be retrieved first
			if(TCPIsLoopback(sktHTTP) && TCPGetTxFIFOFull(sktHTTP) != 0)
				break;

			// Make sure any opened files are closed
			if(curHTTP.file != MPFS_INVALID_HANDLE)
			{
				MPFSClose(curHTTP.file);
				curHTTP.file = MPFS_INVALID_HANDLE;
			}
			if(curHTTP.offsets != MPFS_INVALID_HANDLE)
			{
				MPFSClose(curHTTP.offsets);
				curHTTP.offsets = MPFS_INVALID_HANDLE;
			}

			TCPDisconnect(sktHTTP);
            smHTTP = SM_HTTP_IDLE;
            break;
		}
	} while(!isDone);

}
Пример #18
0
/*********************************************************************
 * Function:        void TelnetTask(void)
 *
 * PreCondition:    Stack is initialized()
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void TelnetTask(void)
{
	BYTE 				i;
	WORD				w, w2;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	static enum _TelnetState
	{
		SM_HOME = 0,
		SM_PRINT_LOGIN,
		SM_GET_LOGIN,
		SM_GET_PASSWORD,
		SM_GET_PASSWORD_BAD_LOGIN,
		SM_AUTHENTICATED,
		SM_REFRESH_VALUES,
	} 					TelnetState = SM_HOME;

	// Reset our state if the remote client disconnected from us
	if(MySocket != INVALID_SOCKET)
	{
		if(TCPWasReset(MySocket))
			TelnetState = SM_PRINT_LOGIN;
	}


	switch(TelnetState)
	{
		case SM_HOME:
			// Connect a socket to the remote TCP server
			MySocket = TCPOpen(0, TCP_OPEN_SERVER, TELNET_PORT, TCP_PURPOSE_TELNET);
			
			// Abort operation if no TCP socket of type TCP_PURPOSE_TELNET is available
			// If this ever happens, you need to go add one to TCPIPConfig.h
			if(MySocket == INVALID_SOCKET)
				break;

			TelnetState++;
			break;

		case SM_PRINT_LOGIN:
			// Make certain the socket can be written to
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strTitle))
				break;
			
			// Place the application protocol data into the transmit buffer.
			TCPPutROMString(MySocket, strTitle);

			// Send the packet
			TCPFlush(MySocket);
			TelnetState++;

		case SM_GET_LOGIN:
			// Make sure we can put the password prompt
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strPassword))
				break;

			// See if the user pressed return
			w = TCPFind(MySocket, '\n', 0, FALSE);
			if(w == 0xFFFFu)
			{
				if(TCPGetRxFIFOFree(MySocket) == 0u)
				{
					TCPPutROMString(MySocket, (ROM BYTE*)"\r\nToo much data.\r\n");
					TCPDisconnect(MySocket);
				}

				break;
			}
		
			// Search for the username -- case insensitive
			w2 = TCPFindROMArray(MySocket, (ROM BYTE*)USERNAME, sizeof(USERNAME)-1, 0, TRUE);
			if((w2 != 0) || !((sizeof(USERNAME)-1 == w) || (sizeof(USERNAME) == w)))
			{
				// Did not find the username, but let's pretend we did so we don't leak the user name validity
				TelnetState = SM_GET_PASSWORD_BAD_LOGIN;	
			}
			else
			{
				TelnetState = SM_GET_PASSWORD;
			}

			// Username verified, throw this line of data away
			TCPGetArray(MySocket, NULL, w + 1);

			// Print the password prompt
			TCPPutROMString(MySocket, strPassword);
			TCPFlush(MySocket);
			break;

		case SM_GET_PASSWORD:
		case SM_GET_PASSWORD_BAD_LOGIN:
			// Make sure we can put the authenticated prompt
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strAuthenticated))
				break;

			// See if the user pressed return
			w = TCPFind(MySocket, '\n', 0, FALSE);
			if(w == 0xFFFFu)
			{
				if(TCPGetRxFIFOFree(MySocket) == 0u)
				{
					TCPPutROMString(MySocket, (ROM BYTE*)"Too much data.\r\n");
					TCPDisconnect(MySocket);
				}

				break;
			}

			// Search for the password -- case sensitive
			w2 = TCPFindROMArray(MySocket, (ROM BYTE*)PASSWORD, sizeof(PASSWORD)-1, 0, FALSE);
			if((w2 != 3) || !((sizeof(PASSWORD)-1 == w-3) || (sizeof(PASSWORD) == w-3)) || (TelnetState == SM_GET_PASSWORD_BAD_LOGIN))
			{
				// Did not find the password
				TelnetState = SM_PRINT_LOGIN;	
				TCPPutROMString(MySocket, strAccessDenied);
				TCPDisconnect(MySocket);
				break;
			}

			// Password verified, throw this line of data away
			TCPGetArray(MySocket, NULL, w + 1);

			// Print the authenticated prompt
			TCPPutROMString(MySocket, strAuthenticated);
			TelnetState = SM_AUTHENTICATED;
			// No break
	
		case SM_AUTHENTICATED:
			if(TCPIsPutReady(MySocket) < strlenpgm((ROM char*)strDisplay) + 4)
				break;

			TCPPutROMString(MySocket, strDisplay);
			TelnetState++;

			// All future characters will be bold
			TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[1m");

		case SM_REFRESH_VALUES:
			if(TCPIsPutReady(MySocket) >= 60u)
			{
				//[10;1]
				//"Analog:             1023\r\n"
				//"Buttons:         3 2 1 0\r\n"
				//"LEDs:    7 6 5 4 3 2 1 0\r\n"
	
				// Position cursor at Line 10, Col 21
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[10;21f");

				// Put analog value with space padding on right side for 4 characters
				TCPPutROMArray(MySocket, (ROM BYTE*)"    ", 4-strlen((char*)AN0String));
				TCPPutString(MySocket, AN0String);

				// Put Buttons
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[11;18f");
				TCPPut(MySocket, BUTTON3_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON2_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON1_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, BUTTON0_IO ? '1':'0');
	
	
				// Put LEDs
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[12;10f");
				TCPPut(MySocket, LED7_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED6_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED5_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED4_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED3_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED2_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED1_IO ? '1':'0');
				TCPPut(MySocket, ' ');
				TCPPut(MySocket, LED0_IO ? '1':'0');
	
	
				// Put cursor at beginning of next line
				TCPPutROMString(MySocket, (ROM BYTE*)"\x1b[13;1f");

				// Send the data out immediately
				TCPFlush(MySocket);
			}

			if(TCPIsGetReady(MySocket))
			{
				TCPGet(MySocket, &i);
				switch(i)
				{
					case '\r':
					case 'q':
					case 'Q':
						if(TCPIsPutReady(MySocket) >= strlenpgm((ROM char*)strGoodBye))
							TCPPutROMString(MySocket, strGoodBye);
						TCPDisconnect(MySocket);
						TelnetState = SM_PRINT_LOGIN;							
						break;
				}
			}

			break;
	}
}
Пример #19
0
static void InitAppConfig(void)
{
#if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS)
	unsigned char vNeedToSaveDefaults = 0;
#endif
	
	while(1)
	{
		// Start out zeroing all AppConfig bytes to ensure all fields are 
		// deterministic for checksum generation
		memset((void*)&AppConfig, 0x00, sizeof(AppConfig));
		
		AppConfig.Flags.bIsDHCPEnabled = TRUE;
		AppConfig.Flags.bInConfigMode = TRUE;
		memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
//		{
//			_prog_addressT MACAddressAddress;
//			MACAddressAddress.next = 0x157F8;
//			_memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr));
//		}
		AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
		AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
		AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
		AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
		AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
		AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul  | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul  | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
		AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul  | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul  | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;
	
	
		// SNMP Community String configuration
		#if defined(STACK_USE_SNMP_SERVER)
		{
			BYTE i;
			static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES;
			static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES;
			ROM char * strCommunity;
			
			for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++)
			{
				// Get a pointer to the next community string
				strCommunity = cReadCommunities[i];
				if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0]))
					strCommunity = "";
	
				// Ensure we don't buffer overflow.  If your code gets stuck here, 
				// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
				// is either too small or one of your community string lengths 
				// (SNMP_READ_COMMUNITIES) are too large.  Fix either.
				if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0]))
					while(1);
				
				// Copy string into AppConfig
				strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity);
	
				// Get a pointer to the next community string
				strCommunity = cWriteCommunities[i];
				if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0]))
					strCommunity = "";
	
				// Ensure we don't buffer overflow.  If your code gets stuck here, 
				// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
				// is either too small or one of your community string lengths 
				// (SNMP_WRITE_COMMUNITIES) are too large.  Fix either.
				if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0]))
					while(1);
	
				// Copy string into AppConfig
				strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity);
			}
		}
		#endif
	

		// Vending machine specific defaults
		strcpypgm2ram((char*)Products[0].name, (ROM char*)"Cola");
		strcpypgm2ram((char*)Products[1].name, (ROM char*)"Diet Cola");
		strcpypgm2ram((char*)Products[2].name, (ROM char*)"Root Beer");
		strcpypgm2ram((char*)Products[3].name, (ROM char*)"Orange");
		strcpypgm2ram((char*)Products[4].name, (ROM char*)"Lemonade");
		strcpypgm2ram((char*)Products[5].name, (ROM char*)"Iced Tea");
		strcpypgm2ram((char*)Products[6].name, (ROM char*)"Water");
		Products[0].price = 4;
		Products[1].price = 4;
		Products[2].price = 4;
		Products[3].price = 4;
		Products[4].price = 5;
		Products[5].price = 7;
		Products[6].price = 8;
		strcpypgm2ram((char*)machineDesc, (ROM char*)"Building C4 - 2nd Floor NW");
		machineDesc[32] = '\0';
		curItem = 0;
		curCredit = 0;

		// Load the default NetBIOS Host Name
		memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
		FormatNetBIOSName(AppConfig.NetBIOSName);
	
		#if defined(WF_CS_TRIS)
			// Load the default SSID Name
			WF_ASSERT(sizeof(MY_DEFAULT_SSID_NAME) <= sizeof(AppConfig.MySSID));
			memcpypgm2ram(AppConfig.MySSID, (ROM void*)MY_DEFAULT_SSID_NAME, sizeof(MY_DEFAULT_SSID_NAME));
			AppConfig.SsidLength = sizeof(MY_DEFAULT_SSID_NAME) - 1;
	
	        AppConfig.SecurityMode = MY_DEFAULT_WIFI_SECURITY_MODE;
	        AppConfig.WepKeyIndex  = MY_DEFAULT_WEP_KEY_INDEX;
	        
	        #if (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_OPEN)
	            memset(AppConfig.SecurityKey, 0x00, sizeof(AppConfig.SecurityKey));
	            AppConfig.SecurityKeyLength = 0;
	
	        #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_40
	            memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_WEP_KEYS_40, sizeof(MY_DEFAULT_WEP_KEYS_40) - 1);
	            AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_WEP_KEYS_40) - 1;
	
	        #elif MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WEP_104
			    memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_WEP_KEYS_104, sizeof(MY_DEFAULT_WEP_KEYS_104) - 1);
			    AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_WEP_KEYS_104) - 1;
	
	        #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_KEY)       || \
	              (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_KEY)      || \
	              (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_KEY)
			    memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_PSK, sizeof(MY_DEFAULT_PSK) - 1);
			    AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_PSK) - 1;
	
	        #elif (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_WITH_PASS_PHRASE)     || \
	              (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA2_WITH_PASS_PHRASE)    || \
	              (MY_DEFAULT_WIFI_SECURITY_MODE == WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE)
	            memcpypgm2ram(AppConfig.SecurityKey, (ROM void*)MY_DEFAULT_PSK_PHRASE, sizeof(MY_DEFAULT_PSK_PHRASE) - 1);
	            AppConfig.SecurityKeyLength = sizeof(MY_DEFAULT_PSK_PHRASE) - 1;
	
	        #else 
	            #error "No security defined"
	        #endif /* MY_DEFAULT_WIFI_SECURITY_MODE */
	
		#endif

		// Compute the checksum of the AppConfig defaults as loaded from ROM
		wOriginalAppConfigChecksum = CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig));

		#if defined(EEPROM_CS_TRIS) || defined(SPIFLASH_CS_TRIS)
		{
			NVM_VALIDATION_STRUCT NVMValidationStruct;

			// Check to see if we have a flag set indicating that we need to 
			// save the ROM default AppConfig values.
			if(vNeedToSaveDefaults)
				SaveAppConfig(&AppConfig);
		
			// Read the NVMValidation record and AppConfig struct out of EEPROM/Flash
			#if defined(EEPROM_CS_TRIS)
			{
				XEEReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct));
				XEEReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig));
				XEEReadArray(sizeof(NVMValidationStruct) + sizeof(AppConfig), (BYTE*)&Products, sizeof(Products));
				XEEReadArray(sizeof(NVMValidationStruct) + sizeof(AppConfig) + sizeof(Products), (BYTE*)&machineDesc, sizeof(machineDesc));
			}
			#elif defined(SPIFLASH_CS_TRIS)
			{
				SPIFlashReadArray(0x0000, (BYTE*)&NVMValidationStruct, sizeof(NVMValidationStruct));
				SPIFlashReadArray(sizeof(NVMValidationStruct), (BYTE*)&AppConfig, sizeof(AppConfig));
				SPIFlashReadArray(sizeof(NVMValidationStruct) + sizeof(AppConfig), (BYTE*)&Products, sizeof(Products));
				SPIFlashReadArray(sizeof(NVMValidationStruct) + sizeof(AppConfig) + sizeof(Products), (BYTE*)&machineDesc, sizeof(machineDesc));
			}
			#endif
	
			// Check EEPROM/Flash validitity.  If it isn't valid, set a flag so 
			// that we will save the ROM default values on the next loop 
			// iteration.
			if((NVMValidationStruct.wConfigurationLength != sizeof(AppConfig)) ||
			   (NVMValidationStruct.wOriginalChecksum != wOriginalAppConfigChecksum) ||
			   (NVMValidationStruct.wCurrentChecksum != CalcIPChecksum((BYTE*)&AppConfig, sizeof(AppConfig))))
			{
				// Check to ensure that the vNeedToSaveDefaults flag is zero, 
				// indicating that this is the first iteration through the do 
				// loop.  If we have already saved the defaults once and the 
				// EEPROM/Flash still doesn't pass the validity check, then it 
				// means we aren't successfully reading or writing to the 
				// EEPROM/Flash.  This means you have a hardware error and/or 
				// SPI configuration error.
				if(vNeedToSaveDefaults)
				{
					while(1);
				}
				
				// Set flag and restart loop to load ROM defaults and save them
				vNeedToSaveDefaults = 1;
				continue;
			}
			
			// If we get down here, it means the EEPROM/Flash has valid contents 
			// and either matches the ROM defaults or previously matched and 
			// was run-time reconfigured by the user.  In this case, we shall 
			// use the contents loaded from EEPROM/Flash.
			break;
		}
		#endif
		break;
	}
	
	// Update with default stock values on every reboot
	Products[0].stock = 15;
	Products[1].stock = 9;
	Products[2].stock = 22;
	Products[3].stock = 18;
	Products[4].stock = 4;
	Products[5].stock = 29;
	Products[6].stock = 14;
}
Пример #20
0
/*****************************************************************************
  Function:
	void SMTPTask(void)

  Summary:
	Performs any pending SMTP client tasks

  Description:
	This function handles periodic tasks associated with the SMTP client,
	such as processing initial connections and command sequences.

  Precondition:
	None

  Parameters:
	None

  Returns:
	None

  Remarks:
	This function acts as a task (similar to one in an RTOS).  It
	performs its task in a co-operative manner, and the main application
	must call this function repeatedly to ensure that all open or new
	connections are served in a timely fashion.
  ***************************************************************************/
void SMTPTask(void)
{
	BYTE			i;
	WORD			w;
	BYTE			vBase64Buffer[4];
	static DWORD	Timer;
	static BYTE		RXBuffer[4];
	static ROM BYTE *ROMStrPtr, *ROMStrPtr2;
	static BYTE 	*RAMStrPtr;
	static WORD		wAddressLength;

 WORD tmp;

	switch(TransportState)
	{
		case TRANSPORT_HOME:
			// SMTPBeginUsage() is the only function which will kick 
			// the state machine into the next state
			break;

		case TRANSPORT_BEGIN:
			// Wait for the user to program all the pointers and then 
			// call SMTPSendMail()
			if(!SMTPFlags.bits.ReadyToStart)
				break;

			// Obtain ownership of the DNS resolution module
			if(!DNSBeginUsage())
				break;

			// Obtain the IP address associated with the SMTP mail server
			if(SMTPClient.Server.szRAM || SMTPClient.Server.szROM)
			{
				if(SMTPClient.ROMPointers.Server)
					DNSResolveROM(SMTPClient.Server.szROM, DNS_TYPE_A);
				else
					DNSResolve(SMTPClient.Server.szRAM, DNS_TYPE_A);
			}
			else
			{
				// If we don't have a mail server, try to send the mail 
				// directly to the destination SMTP server
				if(SMTPClient.To.szRAM && !SMTPClient.ROMPointers.To)
				{
					SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.To.szRAM, '@');
					SMTPClient.ROMPointers.Server = 0;
				}
				else if(SMTPClient.To.szROM && SMTPClient.ROMPointers.To)
				{
					SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.To.szROM, '@');
					SMTPClient.ROMPointers.Server = 1;
				}

				if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM))
				{
					if(SMTPClient.CC.szRAM && !SMTPClient.ROMPointers.CC)
					{
						SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.CC.szRAM, '@');
						SMTPClient.ROMPointers.Server = 0;
					}
					else if(SMTPClient.CC.szROM && SMTPClient.ROMPointers.CC)
					{
						SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.CC.szROM, '@');
						SMTPClient.ROMPointers.Server = 1;
					}
				}

				if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM))
				{
					if(SMTPClient.BCC.szRAM && !SMTPClient.ROMPointers.BCC)
					{
						SMTPClient.Server.szRAM = (BYTE*)strchr((char*)SMTPClient.BCC.szRAM, '@');
						SMTPClient.ROMPointers.Server = 0;
					}
					else if(SMTPClient.BCC.szROM && SMTPClient.ROMPointers.BCC)
					{
						SMTPClient.Server.szROM = (ROM BYTE*)strchrpgm((ROM char*)SMTPClient.BCC.szROM, '@');
						SMTPClient.ROMPointers.Server = 1;
					}
				}

				// See if we found a hostname anywhere which we could resolve
				if(!(SMTPClient.Server.szRAM || SMTPClient.Server.szROM))
				{
					DNSEndUsage();
					ResponseCode = SMTP_RESOLVE_ERROR;
					TransportState = TRANSPORT_HOME;
					break;
				}

				// Skip over the @ sign and resolve the host name
				if(SMTPClient.ROMPointers.Server)
				{
					SMTPClient.Server.szROM++;
					DNSResolveROM(SMTPClient.Server.szROM, DNS_TYPE_MX);
				}
				else
				{
					SMTPClient.Server.szRAM++;
					DNSResolve(SMTPClient.Server.szRAM, DNS_TYPE_MX);
				}
			}
			
			Timer = TickGet();
			TransportState++;
			break;

		case TRANSPORT_NAME_RESOLVE:
			// Wait for the DNS server to return the requested IP address
			if(!DNSIsResolved(&SMTPServer))
			{
				// Timeout after 6 seconds of unsuccessful DNS resolution
				if(TickGet() - Timer > 6*TICK_SECOND)
				{
					ResponseCode = SMTP_RESOLVE_ERROR;
					TransportState = TRANSPORT_HOME;
					DNSEndUsage();
				}
				break;
			}

			// Release the DNS module, we no longer need it
			if(!DNSEndUsage())
			{
				// An invalid IP address was returned from the DNS 
				// server.  Quit and fail permanantly if host is not valid.
				ResponseCode = SMTP_RESOLVE_ERROR;
				TransportState = TRANSPORT_HOME;
				break;
			}

			TransportState++;
			// No need to break here

		case TRANSPORT_OBTAIN_SOCKET:
			// Connect a TCP socket to the remote SMTP server
			MySocket = TCPOpen(SMTPServer.Val, TCP_OPEN_IP_ADDRESS, SMTPClient.ServerPort, TCP_PURPOSE_DEFAULT);
			
			// Abort operation if no TCP sockets are available
			// If this ever happens, add some more 
			// TCP_PURPOSE_DEFAULT sockets in TCPIPConfig.h
			if(MySocket == INVALID_SOCKET)
				break;

			TransportState++;
			Timer = TickGet();
			// No break; fall into TRANSPORT_SOCKET_OBTAINED
			
		#if defined(STACK_USE_SSL_CLIENT)
		case TRANSPORT_SECURING_SOCKET:		
			if(!TCPIsConnected(MySocket))
			{
				// Don't stick around in the wrong state if the
				// server was connected, but then disconnected us.
				// Also time out if we can't establish the connection 
				// to the SMTP server
				if((LONG)(TickGet()-Timer) > (LONG)(SMTP_SERVER_REPLY_TIMEOUT))
				{
					ResponseCode = SMTP_CONNECT_ERROR;
					TransportState = TRANSPORT_CLOSE;
				}

				break;
			}
			SMTPFlags.bits.ConnectedOnce = TRUE;
			
			// Start SSL if needed for this connection
			if(SMTPClient.UseSSL && !TCPStartSSLClient(MySocket,NULL))
				break;
			
			// Move on to main state
			Timer = TickGet();
			TransportState++;
			break;		
		#endif

		case TRANSPORT_SOCKET_OBTAINED:
			if(!TCPIsConnected(MySocket))
			{
				// Don't stick around in the wrong state if the
				// server was connected, but then disconnected us.
				// Also time out if we can't establish the connection 
				// to the SMTP server
				if(SMTPFlags.bits.ConnectedOnce || ((LONG)(TickGet()-Timer) > (LONG)(SMTP_SERVER_REPLY_TIMEOUT)))
				{
					ResponseCode = SMTP_CONNECT_ERROR;
					TransportState = TRANSPORT_CLOSE;
				}

				break;
			}
			SMTPFlags.bits.ConnectedOnce = TRUE;
			
			#if defined(STACK_USE_SSL_CLIENT)
			// Make sure the SSL handshake has completed
			if(SMTPClient.UseSSL && TCPSSLIsHandshaking(MySocket))
				break;
			#endif

			// See if the server sent us anything
			while(TCPIsGetReady(MySocket))
			{
				TCPGet(MySocket, &i);
				switch(RXParserState)
				{
					case RX_BYTE_0:
					case RX_BYTE_1:
					case RX_BYTE_2:
						RXBuffer[RXParserState] = i;
						RXParserState++;
						break;
	
					case RX_BYTE_3:
						switch(i)
						{
							case ' ':
								SMTPFlags.bits.RXSkipResponse = FALSE;
								RXParserState++;
								break;
							case '-':
								SMTPFlags.bits.RXSkipResponse = TRUE;
								RXParserState++;
								break;
							case '\r':
								RXParserState = RX_SEEK_LF;
								break;
						}
						break;
	
					case RX_SEEK_CR:
						if(i == '\r')
							RXParserState++;
						break;
	
					case RX_SEEK_LF:
						// If we received the whole command
						if(i == '\n')
						{
							RXParserState = RX_BYTE_0;

							if(!SMTPFlags.bits.RXSkipResponse)
							{
								// The server sent us a response code
								// Null terminate the ASCII reponse code so we can convert it to an integer
								RXBuffer[3] = 0;
								ResponseCode = atoi((char*)RXBuffer);

								// Handle the response
								switch(SMTPState)
								{
									case SMTP_HELO_ACK:
										if(ResponseCode >= 200u && ResponseCode <= 299u)
										{
											if(SMTPClient.Username.szRAM || SMTPClient.Username.szROM)
												SMTPState = SMTP_AUTH_LOGIN;
											else
												SMTPState = SMTP_MAILFROM;
										}
										else
											SMTPState = SMTP_QUIT_INIT;
										break;


									case SMTP_AUTH_LOGIN_ACK:
									case SMTP_AUTH_USERNAME_ACK:
										if(ResponseCode == 334u)
											SMTPState++;
										else
											SMTPState = SMTP_QUIT_INIT;
										break;

									case SMTP_AUTH_PASSWORD_ACK:
										if(ResponseCode == 235u)
											SMTPState++;
										else
											SMTPState = SMTP_QUIT_INIT;
										break;

									case SMTP_HOME:
									case SMTP_MAILFROM_ACK:
									case SMTP_RCPTTO_ACK:
									case SMTP_RCPTTOCC_ACK:
									case SMTP_RCPTTOBCC_ACK:
                                                                            tmp = SMTPState;
										if(ResponseCode >= 200u && ResponseCode <= 299u)
											SMTPState++;
										else
											SMTPState = SMTP_QUIT_INIT;
										break;
							
									case SMTP_DATA_ACK:
										if(ResponseCode == 354u)
											SMTPState++;
										else
											SMTPState = SMTP_QUIT_INIT;
										break;
							
									case SMTP_DATA_BODY_ACK:
										if(ResponseCode >= 200u && ResponseCode <= 299u)
											SMTPFlags.bits.SentSuccessfully = TRUE;
							
										SMTPState = SMTP_QUIT_INIT;
										break;

									// Default case needed to supress compiler diagnostics
									default:
										break;
								}
							}
						}
						else if(i != '\r')
							RXParserState--;
	
						break;
				}
			}

			// Generate new data in the TX buffer, as needed, if possible
			if(TCPIsPutReady(MySocket) < 64u)
				break;

			switch(SMTPState)
			{
				case SMTP_HELO:
					if(SMTPClient.Username.szROM == NULL)
						TCPPutROMString(MySocket, (ROM BYTE*)"HELO MCHPBOARD\r\n");
					else
						TCPPutROMString(MySocket, (ROM BYTE*)"EHLO MCHPBOARD\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_AUTH_LOGIN:
					// Note: This state is only entered from SMTP_HELO_ACK if the application 
					// has specified a Username to use (either SMTPClient.Username.szROM or 
					// SMTPClient.Username.szRAM is non-NULL)
					TCPPutROMString(MySocket, (ROM BYTE*)"AUTH LOGIN\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_AUTH_USERNAME:
					// Base 64 encode and transmit the username.
					if(SMTPClient.ROMPointers.Username)
					{
						ROMStrPtr = SMTPClient.Username.szROM;
						w = strlenpgm((ROM char*)ROMStrPtr);
					}
					else
					{
						RAMStrPtr = SMTPClient.Username.szRAM;
						w = strlen((char*)RAMStrPtr);
					}

					while(w)
					{
						i = 0;
						while((i < w) && (i < sizeof(vBase64Buffer)*3/4))
						{
							if(SMTPClient.ROMPointers.Username)
								vBase64Buffer[i] = *ROMStrPtr++;
							else
								vBase64Buffer[i] = *RAMStrPtr++;
							i++;
						}
						w -= i;					
						Base64Encode(vBase64Buffer, i, vBase64Buffer, sizeof(vBase64Buffer));
						TCPPutArray(MySocket, vBase64Buffer, sizeof(vBase64Buffer));
					}
					TCPPutROMString(MySocket, (ROM BYTE*)"\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_AUTH_PASSWORD:
					// Base 64 encode and transmit the password
					if(SMTPClient.ROMPointers.Password)
					{
						ROMStrPtr = SMTPClient.Password.szROM;
						w = strlenpgm((ROM char*)ROMStrPtr);
					}
					else
					{
						RAMStrPtr = SMTPClient.Password.szRAM;
						w = strlen((char*)RAMStrPtr);
					}

					while(w)
					{
						i = 0;
						while((i < w) && (i < sizeof(vBase64Buffer)*3/4))
						{
							if(SMTPClient.ROMPointers.Password)
								vBase64Buffer[i] = *ROMStrPtr++;
							else
								vBase64Buffer[i] = *RAMStrPtr++;
							i++;
						}
						w -= i;					
						Base64Encode(vBase64Buffer, i, vBase64Buffer, sizeof(vBase64Buffer));
						TCPPutArray(MySocket, vBase64Buffer, sizeof(vBase64Buffer));
					}
					TCPPutROMString(MySocket, (ROM BYTE*)"\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_MAILFROM:
					// Send MAIL FROM header.  Note that this is for the SMTP server validation, 
					// not what actually will be displayed in the recipients mail client as a 
					// return address.
					TCPPutROMString(MySocket, (ROM BYTE*)"MAIL FROM:<");
					if(SMTPClient.ROMPointers.From)
					{
						ROMStrPtr = FindROMEmailAddress(SMTPClient.From.szROM, &wAddressLength);
						TCPPutROMArray(MySocket, ROMStrPtr, wAddressLength);
					}
					else
					{
						RAMStrPtr = FindEmailAddress(SMTPClient.From.szRAM, &wAddressLength);
						TCPPutArray(MySocket, RAMStrPtr, wAddressLength);
					}
					TCPPutROMString(MySocket, (ROM BYTE*)">\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_RCPTTO_INIT:
					// See if there are any (To) recipients to process
					if(SMTPClient.To.szRAM && !SMTPClient.ROMPointers.To)
					{
						RAMStrPtr = FindEmailAddress(SMTPClient.To.szRAM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTO;
							break;
						}
					}
					if(SMTPClient.To.szROM && SMTPClient.ROMPointers.To)
					{
						ROMStrPtr = FindROMEmailAddress(SMTPClient.To.szROM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTO;
							break;
						}
					}
					
					SMTPState = SMTP_RCPTTOCC_INIT;
					break;

				case SMTP_RCPTTO:
				case SMTP_RCPTTOCC:
				case SMTP_RCPTTOBCC:
					TCPPutROMString(MySocket, (ROM BYTE*)"RCPT TO:<");
					if(	(SMTPClient.ROMPointers.To  && (SMTPState == SMTP_RCPTTO)) || 
						(SMTPClient.ROMPointers.CC  && (SMTPState == SMTP_RCPTTOCC)) || 
						(SMTPClient.ROMPointers.BCC && (SMTPState == SMTP_RCPTTOBCC)) )
						TCPPutROMArray(MySocket, ROMStrPtr, wAddressLength);
					else
						TCPPutArray(MySocket, RAMStrPtr, wAddressLength);
					TCPPutROMString(MySocket, (ROM BYTE*)">\r\n");
					TCPFlush(MySocket);
					SMTPState++;
					break;

				case SMTP_RCPTTO_ISDONE:
					// See if we have any more (To) recipients to process
					// If we do, we must roll back a couple of states
					if(SMTPClient.ROMPointers.To)
						ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength);
					else
						RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength);
	
					if(wAddressLength)
					{
						SMTPState = SMTP_RCPTTO;
						break;
					}

					// All done with To field
					SMTPState++;
					//No break

				case SMTP_RCPTTOCC_INIT:
					// See if there are any Carbon Copy (CC) recipients to process
					if(SMTPClient.CC.szRAM && !SMTPClient.ROMPointers.CC)
					{
						RAMStrPtr = FindEmailAddress(SMTPClient.CC.szRAM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTOCC;
							break;
						}
					}
					if(SMTPClient.CC.szROM && SMTPClient.ROMPointers.CC)
					{
						ROMStrPtr = FindROMEmailAddress(SMTPClient.CC.szROM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTOCC;
							break;
						}
					}
					
					SMTPState = SMTP_RCPTTOBCC_INIT;
					break;

				case SMTP_RCPTTOCC_ISDONE:
					// See if we have any more Carbon Copy (CC) recipients to process
					// If we do, we must roll back a couple of states
					if(SMTPClient.ROMPointers.CC)
						ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength);
					else
						RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength);

					if(wAddressLength)
					{
						SMTPState = SMTP_RCPTTOCC;
						break;
					}

					// All done with CC field
					SMTPState++;
					//No break

				case SMTP_RCPTTOBCC_INIT:
					// See if there are any Blind Carbon Copy (BCC) recipients to process
					if(SMTPClient.BCC.szRAM && !SMTPClient.ROMPointers.BCC)
					{
						RAMStrPtr = FindEmailAddress(SMTPClient.BCC.szRAM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTOBCC;
							break;
						}
					}
					if(SMTPClient.BCC.szROM && SMTPClient.ROMPointers.BCC)
					{
						ROMStrPtr = FindROMEmailAddress(SMTPClient.BCC.szROM, &wAddressLength);
						if(wAddressLength)
						{
							SMTPState = SMTP_RCPTTOBCC;
							break;
						}
					}

					// All done with BCC field
					SMTPState = SMTP_DATA;
					break;

				case SMTP_RCPTTOBCC_ISDONE:
					// See if we have any more Blind Carbon Copy (CC) recipients to process
					// If we do, we must roll back a couple of states
					if(SMTPClient.ROMPointers.BCC)
						ROMStrPtr = FindROMEmailAddress(ROMStrPtr+wAddressLength, &wAddressLength);
					else
						RAMStrPtr = FindEmailAddress(RAMStrPtr+wAddressLength, &wAddressLength);

					if(wAddressLength)
					{
						SMTPState = SMTP_RCPTTOBCC;
						break;
					}

					// All done with BCC field
					SMTPState++;
					//No break

				case SMTP_DATA:
					TCPPutROMString(MySocket, (ROM BYTE*)"DATA\r\n");
					SMTPState++;
					PutHeadersState = PUTHEADERS_FROM_INIT;
					TCPFlush(MySocket);
					break;

				case SMTP_DATA_HEADER:
					while((PutHeadersState != PUTHEADERS_DONE) && (TCPIsPutReady(MySocket) > 64u))
					{
						switch(PutHeadersState)
						{
							case PUTHEADERS_FROM_INIT:
								if(SMTPClient.From.szRAM || SMTPClient.From.szROM)
								{
									PutHeadersState = PUTHEADERS_FROM;
									TCPPutROMString(MySocket, (ROM BYTE*)"From: ");
								}
								else
								{
									PutHeadersState = PUTHEADERS_TO_INIT;
								}
								break;
								
							case PUTHEADERS_FROM:
								if(SMTPClient.ROMPointers.From)
								{
									SMTPClient.From.szROM = TCPPutROMString(MySocket, SMTPClient.From.szROM);
									if(*SMTPClient.From.szROM == 0u)
										PutHeadersState = PUTHEADERS_TO_INIT;
								}
								else
								{
									SMTPClient.From.szRAM = TCPPutString(MySocket, SMTPClient.From.szRAM);
									if(*SMTPClient.From.szRAM == 0u)
										PutHeadersState = PUTHEADERS_TO_INIT;
								}
								break;

							case PUTHEADERS_TO_INIT:
								if(SMTPClient.To.szRAM || SMTPClient.To.szROM)
								{
									PutHeadersState = PUTHEADERS_TO;
									TCPPutROMString(MySocket, (ROM BYTE*)"\r\nTo: ");
								}
								else
								{
									PutHeadersState = PUTHEADERS_CC_INIT;
								}
								break;
								
							case PUTHEADERS_TO:
								if(SMTPClient.ROMPointers.To)
								{
									SMTPClient.To.szROM = TCPPutROMString(MySocket, SMTPClient.To.szROM);
									if(*SMTPClient.To.szROM == 0u)
										PutHeadersState = PUTHEADERS_CC_INIT;
								}
								else
								{
									SMTPClient.To.szRAM = TCPPutString(MySocket, SMTPClient.To.szRAM);
									if(*SMTPClient.To.szRAM == 0u)
										PutHeadersState = PUTHEADERS_CC_INIT;
								}
								break;

							case PUTHEADERS_CC_INIT:
								if(SMTPClient.CC.szRAM || SMTPClient.CC.szROM)
								{
									PutHeadersState = PUTHEADERS_CC;
									TCPPutROMString(MySocket, (ROM BYTE*)"\r\nCC: ");
								}
								else
								{
									PutHeadersState = PUTHEADERS_SUBJECT_INIT;
								}
								break;
								
							case PUTHEADERS_CC:
								if(SMTPClient.ROMPointers.CC)
								{
									SMTPClient.CC.szROM = TCPPutROMString(MySocket, SMTPClient.CC.szROM);
									if(*SMTPClient.CC.szROM == 0u)
										PutHeadersState = PUTHEADERS_SUBJECT_INIT;
								}
								else
								{
									SMTPClient.CC.szRAM = TCPPutString(MySocket, SMTPClient.CC.szRAM);
									if(*SMTPClient.CC.szRAM == 0u)
										PutHeadersState = PUTHEADERS_SUBJECT_INIT;
								}
								break;

							case PUTHEADERS_SUBJECT_INIT:
								if(SMTPClient.Subject.szRAM || SMTPClient.Subject.szROM)
								{
									PutHeadersState = PUTHEADERS_SUBJECT;
									TCPPutROMString(MySocket, (ROM BYTE*)"\r\nSubject: ");
								}
								else
								{
									PutHeadersState = PUTHEADERS_OTHER_INIT;
								}
								break;
								
							case PUTHEADERS_SUBJECT:
								if(SMTPClient.ROMPointers.Subject)
								{
									SMTPClient.Subject.szROM = TCPPutROMString(MySocket, SMTPClient.Subject.szROM);
									if(*SMTPClient.Subject.szROM == 0u)
										PutHeadersState = PUTHEADERS_OTHER_INIT;
								}
								else
								{
									SMTPClient.Subject.szRAM = TCPPutString(MySocket, SMTPClient.Subject.szRAM);
									if(*SMTPClient.Subject.szRAM == 0u)
										PutHeadersState = PUTHEADERS_OTHER_INIT;
								}
								break;

							case PUTHEADERS_OTHER_INIT:
								TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2);
								if(SMTPClient.OtherHeaders.szRAM || SMTPClient.OtherHeaders.szROM)
								{
									PutHeadersState = PUTHEADERS_OTHER;
								}
								else
								{
									TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2);
									PutHeadersState = PUTHEADERS_DONE;
									SMTPState++;
								}
								break;
								
							case PUTHEADERS_OTHER:
								if(SMTPClient.ROMPointers.OtherHeaders)
								{
									SMTPClient.OtherHeaders.szROM = TCPPutROMString(MySocket, SMTPClient.OtherHeaders.szROM);
									if(*SMTPClient.OtherHeaders.szROM == 0u)
									{
										TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2);
										PutHeadersState = PUTHEADERS_DONE;
										SMTPState++;
									}
								}
								else
								{
									SMTPClient.OtherHeaders.szRAM = TCPPutString(MySocket, SMTPClient.OtherHeaders.szRAM);
									if(*SMTPClient.OtherHeaders.szRAM == 0u)
									{
										TCPPutROMArray(MySocket, (ROM BYTE*)"\r\n", 2);
										PutHeadersState = PUTHEADERS_DONE;
										SMTPState++;
									}
								}
								break;
							
							// Default case needed to supress compiler diagnostics
							default:
								break;
						}
					}
					TCPFlush(MySocket);
					break;
		
				case SMTP_DATA_BODY_INIT:
					SMTPState++;
					RAMStrPtr = SMTPClient.Body.szRAM;
					ROMStrPtr2 = (ROM BYTE*)"\r\n.\r\n";
					CRPeriod.Pos = NULL;
					if(RAMStrPtr)
						CRPeriod.Pos = (BYTE*)strstrrampgm((char*)RAMStrPtr, (ROM char*)"\r\n.");
					// No break here
		
				case SMTP_DATA_BODY:
					if(SMTPClient.Body.szRAM || SMTPClient.Body.szROM)
					{
						if(*ROMStrPtr2)
						{
							// Put the application data, doing the transparancy replacement of "\r\n." with "\r\n.."
							while(CRPeriod.Pos)
							{
								CRPeriod.Pos += 3;
								RAMStrPtr += TCPPutArray(MySocket, RAMStrPtr, CRPeriod.Pos-RAMStrPtr);
								if(RAMStrPtr == CRPeriod.Pos)
								{
									if(!TCPPut(MySocket, '.'))
									{
										CRPeriod.Pos -= 3;
										break;
									}
								}
								else
								{
									CRPeriod.Pos -= 3;
									break;
								}
								CRPeriod.Pos = (BYTE*)strstrrampgm((char*)RAMStrPtr, (ROM char*)"\r\n.");
							}
							
							// If we get down here, either all replacements have been made or there is no remaining space in the TCP output buffer
							RAMStrPtr = TCPPutString(MySocket, RAMStrPtr);
							ROMStrPtr2 = TCPPutROMString(MySocket, ROMStrPtr2);
							TCPFlush(MySocket);
						}
					}
					else
					{
						if(SMTPFlags.bits.ReadyToFinish)
						{
							if(*ROMStrPtr2)
							{
								ROMStrPtr2 = TCPPutROMString(MySocket, ROMStrPtr2);
								TCPFlush(MySocket);
							}
		
						}
					}

					if(*ROMStrPtr2 == 0u)
					{
						SMTPState++;
					}
					break;
		
				case SMTP_QUIT_INIT:
					SMTPState++;
					ROMStrPtr = (ROM BYTE*)"QUIT\r\n";
					// No break here

				case SMTP_QUIT:
					if(*ROMStrPtr)
					{
						ROMStrPtr = TCPPutROMString(MySocket, ROMStrPtr);
						TCPFlush(MySocket);
					}

					if(*ROMStrPtr == 0u)
					{
						TransportState = TRANSPORT_CLOSE;
					}
					break;
				
				// Default case needed to supress compiler diagnostics
				default:
					break;
			}
			break;

		case TRANSPORT_CLOSE:
			// Close the socket so it can be used by other modules
			TCPDisconnect(MySocket);
			MySocket = INVALID_SOCKET;

			// Go back to doing nothing
			TransportState = TRANSPORT_HOME;
			break;
	}
}
Пример #21
0
static void InitAppConfig(void)
{
	AppConfig.Flags.bIsDHCPEnabled = TRUE;
	AppConfig.Flags.bInConfigMode = TRUE;
	memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
//	{
//		_prog_addressT MACAddressAddress;
//		MACAddressAddress.next = 0x157F8;
//		_memcpy_p2d24((char*)&AppConfig.MyMACAddr, MACAddressAddress, sizeof(AppConfig.MyMACAddr));
//	}
	AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
	AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
	AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
	AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
	AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
	AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul  | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul  | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
	AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul  | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul  | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;


	// SNMP Community String configuration
	#if defined(STACK_USE_SNMP_SERVER)
	{
		BYTE i;
		static ROM char * ROM cReadCommunities[] = SNMP_READ_COMMUNITIES;
		static ROM char * ROM cWriteCommunities[] = SNMP_WRITE_COMMUNITIES;
		ROM char * strCommunity;
		
		for(i = 0; i < SNMP_MAX_COMMUNITY_SUPPORT; i++)
		{
			// Get a pointer to the next community string
			strCommunity = cReadCommunities[i];
			if(i >= sizeof(cReadCommunities)/sizeof(cReadCommunities[0]))
				strCommunity = "";

			// Ensure we don't buffer overflow.  If your code gets stuck here, 
			// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
			// is either too small or one of your community string lengths 
			// (SNMP_READ_COMMUNITIES) are too large.  Fix either.
			if(strlenpgm(strCommunity) >= sizeof(AppConfig.readCommunity[0]))
				while(1);
			
			// Copy string into AppConfig
			strcpypgm2ram((char*)AppConfig.readCommunity[i], strCommunity);

			// Get a pointer to the next community string
			strCommunity = cWriteCommunities[i];
			if(i >= sizeof(cWriteCommunities)/sizeof(cWriteCommunities[0]))
				strCommunity = "";

			// Ensure we don't buffer overflow.  If your code gets stuck here, 
			// it means your SNMP_COMMUNITY_MAX_LEN definition in TCPIPConfig.h 
			// is either too small or one of your community string lengths 
			// (SNMP_WRITE_COMMUNITIES) are too large.  Fix either.
			if(strlenpgm(strCommunity) >= sizeof(AppConfig.writeCommunity[0]))
				while(1);

			// Copy string into AppConfig
			strcpypgm2ram((char*)AppConfig.writeCommunity[i], strCommunity);
		}
	}
	#endif

	// Load the default NetBIOS Host Name
	memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
	FormatNetBIOSName(AppConfig.NetBIOSName);

	#if defined(ZG_CS_TRIS)
		// Load the default SSID Name
		if (sizeof(MY_DEFAULT_SSID_NAME) > sizeof(AppConfig.MySSID))
		{
			ZGErrorHandler((ROM char *)"AppConfig.MySSID[] too small");
		}
		memcpypgm2ram(AppConfig.MySSID, (ROM void*)MY_DEFAULT_SSID_NAME, sizeof(MY_DEFAULT_SSID_NAME));
	#endif

	#if defined(EEPROM_CS_TRIS)
	{
		BYTE c;
		
	    // When a record is saved, first byte is written as 0x60 to indicate
	    // that a valid record was saved.  Note that older stack versions
		// used 0x57.  This change has been made to so old EEPROM contents
		// will get overwritten.  The AppConfig() structure has been changed,
		// resulting in parameter misalignment if still using old EEPROM
		// contents.
		
		// TCPIP configuration settings will be moved to start from 0x0050.
		// The first 80 bytes will be used for application settings.
		XEEReadArray(0x0000, &c, 1);
	    if(c == 0x60u)
		     XEEReadArray(0x0001, (BYTE*)&AppConfig, sizeof(AppConfig));
	    else
	        SaveAppConfig();
	}
	#elif defined(SPIFLASH_CS_TRIS)
	{
		BYTE c;
		
		SPIFlashReadArray(0x0000, &c, 1);
		if(c == 0x60u)
			SPIFlashReadArray(0x0001, (BYTE*)&AppConfig, sizeof(AppConfig));
		else
			SaveAppConfig();
	}
	#endif
}