Ejemplo n.º 1
0
// ===================================
// = Sends the old WLAN setting type =
// ===================================
void HTTPPrint_prevWLAN(void)
{
    if (CFGCXT.prevWLAN == WF_INFRASTRUCTURE)
        TCPPutROMString(sktHTTP, (ROM BYTE*)"Infrastructure (BSS)");
    else
        TCPPutROMString(sktHTTP, (ROM BYTE*)"AdHoc (IBSS)");
}
Ejemplo n.º 2
0
// ===========================================
// = Sends the new/current WLAN setting type =
// ===========================================
void HTTPPrint_wlan(void)
{
    if(CPElements.networkType == WF_ADHOC)
        TCPPutROMString(sktHTTP, (ROM BYTE*)"AdHoc  (IBSS)");
    else
        TCPPutROMString(sktHTTP, (ROM BYTE*)"Infrastructure (BSS)");
}
Ejemplo n.º 3
0
static void exoit(TCP_SOCKET sock) {
	BYTE bafs[12];
	TCPPutROMString(sock,resNDD);
	uitoa(strlen(httpData),bafs);
	TCPPutString(sock,bafs);
	TCPPutROMString(sock,resNDC);
	TCPFlush(sock); TCPDisconnect(sock);

}
Ejemplo n.º 4
0
void PrintButtonState(ButtonState buttonState)
{
	switch (buttonState)
	{
		case BUTTON_ON:
			TCPPutROMString(sktHTTP, ON_STR);
			break;
		case BUTTON_OFF:
			TCPPutROMString(sktHTTP, OFF_STR);
			break;
	}
}
Ejemplo n.º 5
0
// ==============================================
// = Provides the XML list of WiFi Scan Results =
// ==============================================
void HTTPPrint_aplist(void)
{
    int x;
    BYTE security;
    BYTE secString[4];
    BYTE bssTypeString[4];
    BYTE strVal;
    BYTE strString[4];

    for(x=0; x < SCANCXT.numScanResults; x++)
    {
        WFRetrieveScanResult(x, &bssDesc);

        TCPPutROMString(sktHTTP, (ROM BYTE*)"<bss>\n");
        TCPPutROMString(sktHTTP, (ROM BYTE*)"<name>");
        TCPPutString(sktHTTP, bssDesc.ssid);
        TCPPutROMString(sktHTTP, (ROM BYTE*)"</name>\n");
        TCPPutROMString(sktHTTP, (ROM BYTE*)"<privacy>");
        security = (bssDesc.apConfig & 0xd0) >> 4;
        uitoa(security, secString);
        TCPPutString(sktHTTP, secString);
        TCPPutROMString(sktHTTP, (ROM BYTE*)"</privacy>\n");
        TCPPutROMString(sktHTTP, (ROM BYTE*)"<wlan>");
        uitoa(bssDesc.bssType, bssTypeString);
        TCPPutString(sktHTTP, bssTypeString);
        TCPPutROMString(sktHTTP, (ROM BYTE*)"</wlan>\n");
        TCPPutROMString(sktHTTP, (ROM BYTE*)"<strength>");
        if (bssDesc.rssi < 121)
        {
            strVal = 1;
        }
        else if (bssDesc.rssi < 141)
        {
            strVal = 2;
        }
        else if (bssDesc.rssi < 161)
        {
            strVal = 3;
        }
        else
        {
            strVal = 4;
        }

        uitoa(strVal, strString);
        TCPPutString(sktHTTP, strString);
        TCPPutROMString(sktHTTP, (ROM BYTE*)"</strength>\n");
        TCPPutROMString(sktHTTP, (ROM BYTE*)"</bss>\n");
    }
}
Ejemplo n.º 6
0
/*
void PrintChannelJson(int channelNo, Channel *channel) {
	TCPPutROMString(sktHTTP, "\"Channel\":{\"Number\":");
	PrintInt(channelNo);
	TCPPutROMString(sktHTTP, ",\"Type\":\"");
	PrintChannelType(channel->channelType);
	TCPPutROMString(sktHTTP, ",\"LastCommand\":\"");
	TCPPutString(sktHTTP, (BYTE *)&(channel->lastCommandName));
	TCPPutROMString(sktHTTP, ",\"LastCommandStatus\":\"");
	PrintLastCommandStatus(channel->lastCommandStatus);
	TCPPutROMString(sktHTTP, ",\"ChannelPower\":\"");
	PrintLong(channel->channelPower);
	TCPPutROMString(sktHTTP, ",\"TimeOn\":\"");
	PrintLong(channel->timeOn);
	TCPPutROMString(sktHTTP, ",");
	
	PrintTypeSpecJson(channel);

	TCPPutROMString(sktHTTP, "}");
}

void PrintTypeSpecJson(Channel *channel) {
	switch (channel->channelType) {
		case BLINDS:
			PrintBlindsJson(&channel->channelStatus.blinds);
			break;
		case ONOFF_W_KEY:
		case ONOFF_W_BUTTON:
			PrintOnOffWithButtonJson(&channel->channelStatus.onOff);
			break;

		default:
			break;
	}
}

void PrintOnOffWithButtonJson(OnOffChannel *onOffChannel) {
	TCPPutROMString(sktHTTP, "\"OnOff\":{\"PinDefinitions\":\"");
	PrintOnOffPinDefinitions(onOffChannel);
	TCPPutROMString(sktHTTP, ",\"State\":\"");
	PrintBlindsState(onOffChannel->channelStatus.state);
	TCPPutROMString(sktHTTP, "\",");
	
	PrintButtonJson("Button", &onOffChannel->channelStatus.buttonStatus);
}

void PrintOnOffPinDefinitions(OnOffChannel *onOffChannel) {
	TCPPutROMString(sktHTTP, "{");
	PrintInt(onOffChannel->channelPins.pinButton);
	TCPPutROMString(sktHTTP, ",");
	PrintInt(onOffChannel->channelPins.pinCommand);
	TCPPutROMString(sktHTTP, "}");
}

void PrintBlindsJson(BlindsChannel *blindsChannel) {
	TCPPutROMString(sktHTTP, "\"Blinds\":{\"PinDefinitions\":\"");
	//Pin defs
	TCPPutROMString(sktHTTP, "\",\"CalibrationStatus\":\"");
	//Cal status
	TCPPutROMString(sktHTTP, "\",\"CurrentPosition\":");
	//Current Position
	TCPPutROMString(sktHTTP, ",\"TargetPosition\":");
	//Target Position
	TCPPutROMString(sktHTTP, ",\"CalibratingPosition\":");
	//Calibrating Position
	TCPPutROMString(sktHTTP, ",\"CommandUpGraceTimer\":");
	//CommandUpGraceTimer
	TCPPutROMString(sktHTTP, ",\"CommandDownGraceTimer\":");
	//CommandDownGraceTimer
	TCPPutROMString(sktHTTP, ",\"State\":\"");
	PrintBlindsState(blindsChannel->channelStatus.state);
	TCPPutROMString(sktHTTP, "\",");
	
	PrintButtonJson("ButtonUp", &blindsChannel->channelStatus.buttonUpStatus);

	TCPPutROMString(sktHTTP, ",");

	PrintButtonJson("ButtonDown", &blindsChannel->channelStatus.buttonDownStatus);
}

void PrintBlindsPinDefinitions(BlindsChannel *blindsChannel) {
	TCPPutROMString(sktHTTP, "{");
	PrintInt(blindsChannel->channelPins.pinButtonUp);
	TCPPutROMString(sktHTTP, ",");
	PrintInt(blindsChannel->channelPins.pinButtonDown);
	TCPPutROMString(sktHTTP, ",");
	PrintInt(blindsChannel->channelPins.pinCommandUp);
	TCPPutROMString(sktHTTP, ",");
	PrintInt(blindsChannel->channelPins.pinCommandDown);
	TCPPutROMString(sktHTTP, "}");
}

void PrintButtonJson(char *name, ButtonStatus *buttonStatus) {
	TCPPutROMString(sktHTTP, "\"");
	TCPPutROMString(sktHTTP, (BYTE *)name);
	TCPPutROMString(sktHTTP, "\":{\"State\":\"");
	
	PrintButtonState(buttonStatus->state);

	TCPPutROMString(sktHTTP, "\",\"DurationOn\":");
	PrintLong(buttonStatus->durationOn);
	
	TCPPutROMString(sktHTTP, ",\"ItemUpdateHost\":\"");
	TCPPutString(sktHTTP, (BYTE *)buttonStatus->itemUpdateHost);

	TCPPutROMString(sktHTTP, "\",\"ItemUpdatePort\":\"");
	TCPPutString(sktHTTP, (BYTE *)buttonStatus->itemUpdatePort);

	TCPPutROMString(sktHTTP, "\",\"ItemUpdateUrl\":\"");
	TCPPutString(sktHTTP, (BYTE *)buttonStatus->itemUpdateUrl);

	TCPPutROMString(sktHTTP, "\",\"ItemUpdateMethod\":\"");
	TCPPutString(sktHTTP, (BYTE *)buttonStatus->itemUpdateMethod);
	
	TCPPutROMString(sktHTTP, "\"}");
}
*/
void PrintBlindsState(BlindsState blindsState)
{
		switch (blindsState)
		{
			case UP:
				TCPPutROMString(sktHTTP, UP_STR);
				break;
			case DOWN:
				TCPPutROMString(sktHTTP, DOWN_STR);
				break;
			case MOVE:
				TCPPutROMString(sktHTTP, MOVE_STR);
				break;
			case FIX_POS_UP:
				TCPPutROMString(sktHTTP, FIX_UP_STR);
				break;
			case FIX_POS_DOWN:
				TCPPutROMString(sktHTTP, FIX_DOWN_STR);
				break;
			case ZERO_CAL:
			case MOVE_ZERO_CAL:
				TCPPutROMString(sktHTTP, ZERO_CAL_STR);
				break;
			case MAX_CAL:
			case MOVE_MAX_CAL:
				TCPPutROMString(sktHTTP, MAX_CAL_STR);
				break;
			case STOPPED:
				TCPPutROMString(sktHTTP, STOPPED_STR);
				break;
		}	
}
Ejemplo n.º 7
0
void HTTPPrint_onOffCommand(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_COMMAND);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_PULSE);
	if (channelNo)
	{
		if (channels[channelNo - 1].channelType == ONOFF_COMMAND || channels[channelNo - 1].channelType == ONOFF_PULSE)
		{
			PrintInt(channels[channelNo -1].channelStatus.onOffCommand.pinCommand);
		}
		else
		{
			PrintInt(channels[channelNo -1].channelStatus.onOff.channelPins.pinCommand);
		}
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 8
0
void PrintChannelType(ChannelType channelType)
{
	switch (channelType)
	{
		case BLINDS:
			TCPPutROMString(sktHTTP, "BLINDS");
			break;
		case ONOFF_W_KEY:
			TCPPutROMString(sktHTTP, "ONOFF WITH KEY");
			break;
		case ONOFF_W_BUTTON:
			TCPPutROMString(sktHTTP, "ONOFF WITH BUTTON");
			break;
		case ONOFF_BUTTON:
			TCPPutROMString(sktHTTP, "ONOFF BUTTON");
			break;
		case ONOFF_COMMAND:
			TCPPutROMString(sktHTTP, "ONOFF BUTTON");
			break;
		case ONOFF_PULSE:
			TCPPutROMString(sktHTTP, "ONOFF PULSE");
			break;
		default:
			TCPPutROMString(sktHTTP, NOT_DEF_STR);
			break;
	}		
}
Ejemplo n.º 9
0
/* status file functions - return text for status file values */
void HTTPPrint_channeltype(WORD channelNo)
{
	if (channelNo >= 1 && channelNo <= NUM_OF_CHANNELS)
	{
		PrintChannelType(channels[channelNo - 1].channelType);
	}
	else
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
}
Ejemplo n.º 10
0
void HTTPPrint_channelNo(void)
{
	BYTE *ptr;
	ptr = HTTPGetROMArg(curHTTP.data, (ROM BYTE *)"channelNo");		

	if (ptr)
		TCPPutString(sktHTTP, ptr);
	else
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
}
Ejemplo n.º 11
0
void HTTPPrint_blindsPartOpenCalState(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		switch (channels[channelNo - 1].channelStatus.blinds.calibrationStatus.partOpenStatus)
		{
			case NONCALIBRATED:
				TCPPutROMString(sktHTTP, NONCALIBRATED_STR);
				break;
			case CALIBRATED:
				TCPPutROMString(sktHTTP, CALIBRATED_STR);
				break;
		}	
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 12
0
void HTTPPrint_blindsDownBtnState(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		PrintButtonState(channels[channelNo - 1].channelStatus.blinds.channelStatus.buttonDownStatus.state);
	}	
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 13
0
void HTTPPrint_blindsCmdDown(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		PrintInt(channels[channelNo - 1].channelStatus.blinds.channelPins.pinCommandDown);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 14
0
void HTTPPrint_blindsDownBtnItemUpdateUrl(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		TCPPutString(sktHTTP, (BYTE *)channels[channelNo - 1].channelStatus.blinds.channelStatus.buttonDownStatus.buttonSettings.itemUpdateUrl);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 15
0
void HTTPPrint_blindsUpBtnDur(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		PrintLong(channels[channelNo - 1].channelStatus.blinds.channelStatus.buttonUpStatus.durationOn);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 16
0
void HTTPPrint_blindsPartOpenPos(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		PrintLong(channels[channelNo - 1].channelStatus.blinds.calibrationStatus.partOpenPosition);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 17
0
void HTTPPrint_blindsCurPos100th(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		PrintLong(channels[channelNo - 1].channelStatus.blinds.channelStatus.currentPosition);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 18
0
void PrintLastCommandStatus(CommandStatus commandStatus)
{
	switch (commandStatus)
	{
		case OK:
			TCPPutROMString(sktHTTP, OK_STR);
			break;
		case ARG_ERR:
			TCPPutROMString(sktHTTP, ARG_VAL_ERR_STR);
			break;
		case CMD_ERR:
			TCPPutROMString(sktHTTP, UNK_CMD_ERR_STR);
			break;
		case CH_TYPE_ERR:
			TCPPutROMString(sktHTTP, CH_TYPE_ERR_STR);
			break;
		case NDEF:
			TCPPutROMString(sktHTTP, NOT_DEF_STR);
			break;
	}
}
Ejemplo n.º 19
0
void HTTPPrint_blindsCurPos(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(BLINDS);
	if (channelNo)
	{
		/* calculate the current position in percent */
		PrintLong(GetCurrentPositionInPercent(channelNo));
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 20
0
void HTTPPrint_onOffCurValue(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (channelNo)
	{
		PrintLong(channels[channelNo -1].channelStatus.onOff.channelStatus.currentValue);
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 21
0
void HTTPPrint_onOffState(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_COMMAND);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_PULSE);
	if (channelNo)
	{
		int state;
		if (channels[channelNo - 1].channelType == ONOFF_COMMAND || channels[channelNo - 1].channelType == ONOFF_PULSE)
		{
			state = channels[channelNo - 1].channelStatus.onOffCommand.onOffState;
		}
		else
		{
			state = channels[channelNo - 1].channelStatus.onOff.channelStatus.state;
		}
		
		switch (state)
		{
			case ONOFF_ON:
				TCPPutROMString(sktHTTP, ON_STR);
				break;
			case ONOFF_OFF:
				TCPPutROMString(sktHTTP, OFF_STR);
				break;
		}	
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 22
0
void HTTPPrint_btn(WORD num)
{
    // Determine which button
    switch(num)
    {
        case 0:
            num = SW0_IO;
            break;
        default:
            num = 0;
    }

    // Print the output
    TCPPutROMString(sktHTTP, (num?HTML_UP_ARROW:HTML_DOWN_ARROW));
    return;
}
Ejemplo n.º 23
0
void HTTPPrint_onOffBtnItemUpdateUrl(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_BUTTON);
	if (channelNo)
	{
		if (channels[channelNo - 1].channelType == ONOFF_BUTTON)
		{
			TCPPutString(sktHTTP, (BYTE *)channels[channelNo - 1].channelStatus.onOffButton.buttonStatus.buttonSettings.itemUpdateUrl);
		}
		else
		{
			TCPPutString(sktHTTP, (BYTE *)channels[channelNo - 1].channelStatus.onOff.channelStatus.buttonStatus.buttonSettings.itemUpdateUrl);
		}
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 24
0
void HTTPPrint_onOffButton(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_BUTTON);
	if (channelNo)
	{
		if (channels[channelNo - 1].channelType == ONOFF_BUTTON)
		{
			PrintInt(channels[channelNo -1].channelStatus.onOffButton.pinButton);
		}
		else
		{
			PrintInt(channels[channelNo -1].channelStatus.onOff.channelPins.pinButton);
		}
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
Ejemplo n.º 25
0
void HTTPPrint_onOffBtnDur(void)
{
	int channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_KEY);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_W_BUTTON);
	if (!channelNo)
		channelNo = GetChannelNumberWithChannelTypeCheck(ONOFF_BUTTON);
	if (channelNo)
	{
		if (channels[channelNo - 1].channelType == ONOFF_BUTTON)
		{
			PrintLong(channels[channelNo - 1].channelStatus.onOffButton.buttonStatus.durationOn);
		}
		else
		{
			PrintLong(channels[channelNo - 1].channelStatus.onOff.channelStatus.buttonStatus.durationOn);
		}
	}
	else
	{
		TCPPutROMString(sktHTTP, NOT_DEF_STR);
	}
}
void twatchTasks(void){ //this state machine services the #twatch

   static enum _twitterTCPstate{
		TWITTER_INIT=0,
		HOLD_COLOR,
		TWITTER_IDLE,
		TWITTER_SEARCH_TCP_START,
		TWITTER_SEARCH_TCP_SOCKET_OBTAINED,
		TWITTER_SEARCH_TCP_PROCESS_RESPONSE,
		TWITTER_SEARCH_TCP_DISCONNECT,
	} twitterTCPstate = TWITTER_INIT; //massive twitter parsing state machine

   static enum _HTTPstatus{
		UNKNOWN=0,
		OK,
		ERROR,
	} HTTPstatus = UNKNOWN; //get and track HTTP status and handle errors
	static unsigned char HTTPheaderBuf[20]; //used to store HTTP headers 
	static unsigned char HTTPheaderBufCnt; //pointer

	static BYTE HTTPretry=0, gotID=0;//extra static vars for twitter parser

	unsigned char tcpReadBytes, cnt;
	unsigned int	tcpTotalBytes; //for TCPsocket length, can be >256
	#define TCPBUF_LENGTH 50 //best size
	unsigned char	tcpBuf[TCPBUF_LENGTH];
	static DWORD		Timer;
	static TCP_SOCKET	TCPSocket = INVALID_SOCKET;

	static struct _timekeeper{
		DWORD	ticks;
		unsigned char minutes;
		unsigned char seconds;
		unsigned char runsec; //running seconds counter
	} time;

	//a minutes counter for determining when to refresh the search results
	if(TickGet() - time.ticks >= TICK_SECOND){
		time.ticks = TickGet();
		time.seconds++;
		time.runsec++;
		if(time.seconds>59){
			time.seconds=0;
			time.minutes++;
			if(time.minutes>59){
				time.minutes=0;
			}
		}
	}

	switch(twitterTCPstate){

		case TWITTER_INIT: //setup JSON parser structs on first run
			searchParser.searchTag=textTag;//tag to search for
			searchParser.searchTagLength=(sizeof(textTag)-1);//length of search tag
			searchParser.valueBuffer=tweetBuf; //assign buffer to this struct
			searchParser.valueBufferLength=TWEETCHARS;//buffer length
			searchParser.valueEndChar='"'; //text tag, value ends with "

			nameParser.searchTag=nameTag;//tag to name for
			nameParser.searchTagLength=(sizeof(nameTag)-1);//length of name tag
			nameParser.valueBuffer=nameBuf; //assign buffer to this struct
			nameParser.valueBufferLength=NAMECHARS;//buffer length
			nameParser.valueEndChar='"'; //text tag, value ends with "

			max_idParser.searchTag=max_idTag;//tag to search for
			max_idParser.searchTagLength=(sizeof(max_idTag)-1);//length of search tag
			max_idParser.valueBuffer=lastidTempBuf; //assign buffer to this struct
			max_idParser.valueBufferLength=MAX_IDCHARS;//buffer length
			max_idParser.valueEndChar=','; //text tag, value ends with "
			max_idParser.valueBuffer[20]='\0'; //ensure 0 termination

			//zero the last ID before first call
			lastidBuf[0]='\0';
			lastidBuf[1]='\0';

			//reset printer
			UARTTX(0x1b);
			UARTTX('@');
			//Control parameter command
			UARTTX(0x1b);
			UARTTX(0x37);
			UARTTX(0x07);//max printing dots
			UARTTX(0xFF);//heating time
			UARTTX(0x05);	//heating interval
			twitterTCPstate=TWITTER_SEARCH_TCP_START; //start TCP data grabber next cycle

			break;
		case HOLD_COLOR:
			if(time.runsec<HOLD_SECONDS){
				break;
			}		
			twitterTCPstate=TWITTER_IDLE;	
		case TWITTER_IDLE:	//if this variable set, then start the refresh process		
			//have we played all the buffered text
			if(T.cnt>0 && UART_EMPTY()){//step through text when idle
				
				if(T.t[T.read]==0xFF){//0xFF, end of tweet. reset line counter
					T.lncnt=0;
				}else{
					UARTTX(T.t[T.read]);
					T.lncnt++;

					//send a LF at the end of each X characters
					if(T.lncnt==PRINTER_WIDTH){
						UARTTX(0x0a);
						T.lncnt=0;
						
						twitterTCPstate=HOLD_COLOR;//next time hold solid color
					}
				}

				T.read++;
				//is this the final text?
				T.cnt--;
				if(T.cnt==0){//done with text
					time.runsec=0;//clear running counter for pause
					#ifndef DEBUG
						UARTTX(0x0a);
						UARTTX(0x0a);
						twitterTCPstate=HOLD_COLOR;//next time hold solid color
					#endif
				}

			}else if(time.seconds>=REFRESH_INTERVAL){ //if it has been at least X minutes, get tweet search results
				time.seconds=0;
				HTTPretry=0; //reset the number of retries	
				twitterTCPstate=TWITTER_SEARCH_TCP_START; //start TCP data grabber next cycle
			}			
			break;
		case TWITTER_SEARCH_TCP_START: //begins search for tweets 
			//setup the search parser struct
			resetJSONparser(&nameParser);
			resetJSONparser(&searchParser);
			resetJSONparser(&max_idParser);
			gotID=0; //reset the ID finder
			T.cnt=0; //reset the tweet letter counter	
			T.read=0; //reset the read pointer	
			HTTPstatus = UNKNOWN; //clear the HTTP status checker
			HTTPheaderBufCnt=0;
					
			//connect to twitter
			TCPSocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

			if(TCPSocket == INVALID_SOCKET) break; //abort on error

			twitterTCPstate=TWITTER_SEARCH_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWITTER_SEARCH_TCP_SOCKET_OBTAINED:
			//wait for server, with timeout
			if(!TCPIsConnected(TCPSocket)){
				if(TickGet()-Timer > 5*TICK_SECOND){
					TCPDisconnect(TCPSocket);
					TCPSocket = INVALID_SOCKET;
					twitterTCPstate--;
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(TCPSocket) < 125u) break; //socket ready for writes?
			
			TCPPutROMString(TCPSocket, (ROM BYTE*)"GET "); //setup the HTTP GET request 
			TCPPutROMString(TCPSocket, SearchURL);	//JSON search datafeed URL

			//add the last ID to the JSON search URL. (usually requires urlencoding, but we have numbers only)
			//#ifdef 0
			if(lastidBuf[0]!='\0'){ //don't put 0 length IDs into TCP, kills socket
				TCPPutString(TCPSocket, lastidBuf); //put the string in the TCP buffer
			}
			//#endif

			//form the rest of the HTTP request
			TCPPutROMString(TCPSocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(TCPSocket, ServerName);
			TCPPutROMString(TCPSocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(TCPSocket); //send the HTTP request to the Twitter server

			twitterTCPstate=TWITTER_SEARCH_TCP_PROCESS_RESPONSE;
			break;

		case TWITTER_SEARCH_TCP_PROCESS_RESPONSE:
			if(!TCPIsConnected(TCPSocket)) twitterTCPstate = TWITTER_SEARCH_TCP_DISCONNECT; //check for connection // Do not break;  We might still have data in the TCP RX FIFO waiting for us

			tcpTotalBytes = TCPIsGetReady(TCPSocket);	//how many bytes waiting?
			tcpReadBytes = TCPBUF_LENGTH;

			while(tcpTotalBytes){ //process server reply
				if(tcpTotalBytes < tcpReadBytes){
					tcpReadBytes = tcpTotalBytes;
				}
				tcpTotalBytes -= TCPGetArray(TCPSocket, tcpBuf, tcpReadBytes);

				for(cnt=0;cnt<tcpReadBytes;cnt++){
					UART2TX(tcpBuf[cnt]);
					//---------------//
					switch(HTTPstatus){
						case UNKNOWN: //check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=tcpBuf[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(tcpBuf[cnt]==0x0d){//current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling....
									if( ((HTTPheaderBufCnt+2) < 20) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;
									}else{
										HTTPstatus=ERROR;
									}
								}
							}
							break;
						case OK:
							if(tagSearch(tcpBuf[cnt], &nameParser)){//process the tweet for color data
								processname(nameParser.valueBufferCounter);
							}
							if(tagSearch(tcpBuf[cnt], &searchParser)){//process the tweet for color data
								processtweet(searchParser.valueBufferCounter);
							}
							if(gotID==0){//get only the first (highest) tweet ID to append to the URL next time
								if(tagSearch(tcpBuf[cnt], &max_idParser)){
									addValueByte('\0', &max_idParser);
									for(gotID=0; gotID<21; gotID++){
										lastidBuf[gotID]=lastidTempBuf[gotID];//only overwrite if comlete
									}
									gotID=1;
								}
							}
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twitterTCPstate == TWITTER_SEARCH_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWITTER_SEARCH_TCP_DISCONNECT:
			TCPDisconnect(TCPSocket); //close the socket
			TCPSocket = INVALID_SOCKET;

			//did not get valid HTML, retry, got no tags, retry once if no tags
			if(HTTPstatus!=OK ){
				HTTPretry++;
				if(HTTPretry>(HTTP_MAX_RETRY-1)){//retry, then wait till next time...
					twitterTCPstate = TWITTER_IDLE;
					time.seconds=0;
					break;
				}
				twitterTCPstate = TWITTER_SEARCH_TCP_START;
				break;
			}
			HTTPretry=0; //success, clear number or retries

			twitterTCPstate = TWITTER_IDLE;
			break;

	}//switch
	
Ejemplo n.º 27
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;
	}
}
void twatchTasks(char frameAdvance){ //this state machine services the #twatch

   static enum _twatchState
	{
		TWATCH_INIT=0,
		TWATCH_IDLE,
		TWATCH_TRENDS_TCP_START,
		TWATCH_TRENDS_TCP_SOCKET_OBTAINED,
		TWATCH_TRENDS_TCP_PROCESS_RESPONSE,
		TWATCH_TRENDS_TCP_DISCONNECT,
		TWATCH_SEARCH_TCP_START,
		TWATCH_SEARCH_TCP_SOCKET_OBTAINED,
		TWATCH_SEARCH_TCP_PROCESS_RESPONSE,
		TWATCH_SEARCH_TCP_DISCONNECT,
	} twatchState = TWATCH_INIT; //massive twitter parsing state machine

   static enum _HTTPstatus
	{
		UNKNOWN=0,
		OK,
		ERROR,
	} HTTPstatus = UNKNOWN; //get and track HTTP status and handle errors
	static unsigned char HTTPheaderBuf[20]; //used to store HTTP headers 
	static unsigned char HTTPheaderBufCnt; //pointer

	static BYTE refreshFeeds=0, HTTPretry=0, URLencode[]="%20";//extra static vars for twitter parser

	BYTE 				i,k;
	WORD				w;
	BYTE				vBuffer[51];
	BYTE				cnt;
	static TICK			Timer;
	static TCP_SOCKET	MySocket = INVALID_SOCKET;
	
	if(frameAdvance==1) refreshFeeds++; //counts the minutes

	switch(twatchState)
	{
		case TWATCH_INIT:
			trendParser.success=0; //clear these flag on first run
			searchParser.success=0;//display IP address and info until valid connection
			twatchState=TWATCH_TRENDS_TCP_START; //start TCP data grabber next cycle
			break;
		case TWATCH_IDLE:	//if this variable set, then start the refresh process		
			if(refreshFeeds>TWATCH_REFRESH_INTERVAL){ //if it has been at least 5 minutes, get new trends and tweet search results
				refreshFeeds=0;
				HTTPretry=0; //reset the number of retries
				twatchState=TWATCH_TRENDS_TCP_START; //start TCP data grabber next cycle
			}
			break;
		case TWATCH_TRENDS_TCP_START:
			//connect to twitter server
			MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);
			
			if(MySocket == INVALID_SOCKET) break; //abort if error, try again next time
			
			trendParser.updatingData=1; //updating data flag (probably not used anywhere)
			displayMode=UPDATE; //next LCD refresh will draw the update screen and then idle
			twatchState=TWATCH_TRENDS_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWATCH_TRENDS_TCP_SOCKET_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 > 5*TICK_SECOND)
				{
					// Close the socket so it can be used by other modules
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					twatchState--;
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(MySocket) < 125u) break; //if socket error, break and wait
	
			//form our trending topics JSON datafeed request
			TCPPutROMString(MySocket, (ROM BYTE*)"GET ");
			TCPPutROMString(MySocket, TrendURL); //use the trend URL
			TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(MySocket, ServerName);
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(MySocket); //send HTTP request to Twitter
			
			//setup/clear the parser struct
			trendParser.bufWritePointer=0;
			trendParser.foundTag=0;
			trendParser.tagCharMatchCnt=0;
			trendParser.tagTotalCnt=0;
			trendParser.bufWritePointer=0;
			searchParser.bufWritePointer=0;//reset the tweet buffer write pointer
			searchParser.term=0; //reset the number of terns in the tweet search parser structure
			for(i=0; i<MAX_TREND_TERMS; i++) searchParser.bufValueEndPosition[i]=0;//reset all buffer positions to 0
			HTTPstatus = UNKNOWN; //reset the http status checker
			HTTPheaderBufCnt=0; //status checker buffer counter

			twatchState=TWATCH_TRENDS_TCP_PROCESS_RESPONSE; //next time process any incoming data
			break;

		case TWATCH_TRENDS_TCP_PROCESS_RESPONSE:

			if(!TCPIsConnected(MySocket)) twatchState = TWATCH_TRENDS_TCP_DISCONNECT; //check if we're still connected // Do not break;  We might still have data in the TCP RX FIFO waiting for us
	
			w = TCPIsGetReady(MySocket);//how many bytes waiting?	
	
			//process the server reply
			i = sizeof(vBuffer)-1;
			vBuffer[i] = '\0';
			while(w){
				if(w < i){
					i = w;
					vBuffer[i] = '\0';
				}
				w -= TCPGetArray(MySocket, vBuffer, i);

				for(cnt=0;cnt<i;cnt++){
					//---------------//
					switch(HTTPstatus){ //check the first few bytes for HTTP/1.1 200 OK
						case UNKNOWN: //cache until a line break, then check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=vBuffer[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(vBuffer[cnt]==0x0d){//if current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling.... check for overrun
									if( (HTTPheaderBufCnt <=17 ) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;//200 OK
									}else{
										HTTPstatus=ERROR; //other status, error
									}
								}
							}
							break;
						case OK: //HTTP is OK, process the byte
							procTrend(vBuffer[cnt]); //json parsing state maching
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twatchState == TWATCH_TRENDS_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWATCH_TRENDS_TCP_DISCONNECT:
			TCPDisconnect(MySocket); //close the socket
			MySocket = INVALID_SOCKET;
	
			//did not get valid HTML, retry, got no tags, retry
			if(HTTPstatus!=OK || trendParser.tagTotalCnt==0 ){
				HTTPretry++;
				if(HTTPretry>HTTP_MAX_RETRY){//retry 3 times, then wait a minute....
					twatchState = TWATCH_IDLE;
					LCD_CursorPosition(21); //display waiting error
					LCD_WriteString("*Error, waiting 5min");
					break;
				}
				LCD_CursorPosition(21); //display retry error
				LCD_WriteString("*Error, reconnecting");
				twatchState = TWATCH_TRENDS_TCP_START;
				break;
			}
			HTTPretry=0;
		
			addToTrendBuffer(' ');//add trailing space
			
			trendParser.updatingData=0; //data update complete, clear update flag
			if(trendParser.success==0){ //if this is the first time throuigh, set the success flag
				trendParser.success=1; //set success flag, used to identify the very first successful xfer and clear IP address screen
				LCD_refresh(); //clear IP, show update screen
			}
			displayMode=NEWSCROLL;//start scrolling the terms, tweets will show when available in the parser struct
			twatchState = TWATCH_SEARCH_TCP_START; //will start searching on each term next time. searchParser.term set to 0 above...
			break;

		case TWATCH_SEARCH_TCP_START: //begins searching for recent tweets for each trending term
			
			//don't continue if there's no more term, an error, or overrun
			if(searchParser.term>=trendParser.tagTotalCnt || searchParser.term>=MAX_TREND_TERMS ){//don't continue if there's no more terms left to search
				twatchState = TWATCH_IDLE; //go back to idle
				break;
			}
			
			//skip if 0 length term
			if(trendParser.bufValueStartPosition[searchParser.term]==trendParser.bufValueEndPosition[searchParser.term]) {
				searchParser.term++; //increment to next trend term
				twatchState = TWATCH_SEARCH_TCP_START; //try again with the next trend term
				break;
			}
		
			//connect to twitter
			MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

			if(MySocket == INVALID_SOCKET) break; //abort on error

			twatchState=TWATCH_SEARCH_TCP_SOCKET_OBTAINED;
			Timer = TickGet();
			break;

		case TWATCH_SEARCH_TCP_SOCKET_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 > 5*TICK_SECOND){
					// Close the socket so it can be used by other modules
					TCPDisconnect(MySocket);
					MySocket = INVALID_SOCKET;
					twatchState--;
					//searchParser.term++; //increment to next trend term, don't get stuck in loop
										//should add retries
				}
				break;
			}

			Timer = TickGet();

			if(TCPIsPutReady(MySocket) < 125u) break; //socket ready for writes?

			
			TCPPutROMString(MySocket, (ROM BYTE*)"GET "); //setup the HTTP GET request 
			TCPPutROMString(MySocket, SearchURL);	//JSON search datafeed URL
			#ifndef JSON_DEBUG
			//add the search term to the JSON search URL. Requires urlencoding
			i=trendParser.bufValueStartPosition[searchParser.term]; //get the starting position of the term in the trend term buffer
			k=trendParser.bufValueEndPosition[searchParser.term]-1; //end position is one less because of auto increment
			//add each character of the trend term to the search URL
			while((i<k) && i<TREND_PARSER_BUFFER ){ //append each byte to the URL until the end position
				//URLencode anything not a-zA-Z0-9 -_.!~*'()
				if(URLencodeChar(trendParser.buf[i], &URLencode[0])==0){
					TCPPut(MySocket, trendParser.buf[i]); //no URLencode required;
				}else{
					TCPPutString(MySocket, URLencode); //use the URLencoded character now in URLencode array
				}
				i++;
			}
			#endif
			//form the rest of the HTTP request
			TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
			TCPPutString(MySocket, ServerName);
			TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

			TCPFlush(MySocket); //send the HTTP request to the Twitter server

			//setup the search parser struct
			searchParser.foundTag=0;
			searchParser.tagCharMatchCnt=0;
			searchParser.tagTotalCnt=0;
			searchParser.escape=0;
			HTTPstatus = UNKNOWN; //clear the HTTP status checker
			HTTPheaderBufCnt=0;

			addToSearchBuffer(0xff); //add beginning block to the text

			twatchState=TWATCH_SEARCH_TCP_PROCESS_RESPONSE;
			break;

		case TWATCH_SEARCH_TCP_PROCESS_RESPONSE:
			if(!TCPIsConnected(MySocket)) twatchState = TWATCH_SEARCH_TCP_DISCONNECT; //check for connection // Do not break;  We might still have data in the TCP RX FIFO waiting for us
	
			w = TCPIsGetReady(MySocket);	//how many bytes waiting?
	
			i = sizeof(vBuffer)-1;
			vBuffer[i] = '\0'; //add trailing 0 to array.

			while(w){ //process server reply
				if(w < i){
					i = w;
					vBuffer[i] = '\0';
				}
				w -= TCPGetArray(MySocket, vBuffer, i);

				for(cnt=0;cnt<i;cnt++){
					//---------------//
					switch(HTTPstatus){
						case UNKNOWN: //check header for response code before extracting tags
							HTTPheaderBuf[HTTPheaderBufCnt]=vBuffer[cnt];//add to the headerbuf array
							if(HTTPheaderBufCnt<19) HTTPheaderBufCnt++; //if it won't overrun the array, increment the counter
						
							if(vBuffer[cnt]==0x0d){//current character is a line break, examine the header for the response code
								//is it HTTP?
								if(HTTPheaderBuf[0]=='H' &&	HTTPheaderBuf[1]=='T' && 
								HTTPheaderBuf[2]=='T' && HTTPheaderBuf[3]=='P' ){						
									//loop past /1.x and space
									HTTPheaderBufCnt=4;
									while(HTTPheaderBuf[HTTPheaderBufCnt]!=' '){
										HTTPheaderBufCnt++;
										if(HTTPheaderBufCnt>19) break; //buffer overrun
									}
									HTTPheaderBufCnt++;
									//is it 200? (should be a ASCII->int loop that gets the actual value for error handling....
									if( ((HTTPheaderBufCnt+2) < 20) && HTTPheaderBuf[HTTPheaderBufCnt]=='2' &&	HTTPheaderBuf[HTTPheaderBufCnt+1]=='0' && 
										HTTPheaderBuf[HTTPheaderBufCnt+2]=='0'){
										HTTPstatus=OK;
									}else{
										HTTPstatus=ERROR;
									}
								}
							}
							break;
						case OK:
							procSearch(vBuffer[cnt]);
							break;
						case ERROR://do nothing because we need to clear the buffer
							break;
					}
					//------------------//
				}//for loop
				
				if(twatchState == TWATCH_SEARCH_TCP_PROCESS_RESPONSE) break;
			}//while
	
			break;
	
		case TWATCH_SEARCH_TCP_DISCONNECT:
			TCPDisconnect(MySocket); //close the socket
			MySocket = INVALID_SOCKET;

			//did not get valid HTML, retry, got no tags, retry once if no tags
			if(HTTPstatus!=OK ){
				HTTPretry++;
				if(HTTPretry>HTTP_MAX_RETRY){//retry, then wait till next time...
					twatchState = TWATCH_IDLE;
					break;
				}
				twatchState = TWATCH_SEARCH_TCP_START;
				break;
			}
			HTTPretry=0; //success, clear number or retries

			//repeat for each trend term
			searchParser.success=1;
			searchParser.term++;
			twatchState = TWATCH_SEARCH_TCP_START;
			break;

	}//switch
	
}//function
Ejemplo n.º 29
0
/*****************************************************************************
  Function:
	void GenericTCPClient(void)

  Summary:
	Implements a simple HTTP client (over TCP).

  Description:
	This function implements a simple HTTP client, which operates over TCP.
	The function is called periodically by the stack, and waits for BUTTON1
	to be pressed.  When the button is pressed, the application opens a TCP
	connection to an Internet search engine, performs a search for the word
	"Microchip" on "microchip.com", and prints the resulting HTML page to
	the UART.

	This example can be used as a model for many TCP and HTTP client
	applications.

  Precondition:
	TCP is initialized.

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
void GenericTCPClient(void)
{
    BYTE 				i;
    WORD				w;
    BYTE				vBuffer[9];
    static DWORD		Timer;
    static TCP_SOCKET	MySocket = INVALID_SOCKET;
    static enum _GenericTCPExampleState
    {
        SM_HOME = 0,
        SM_SOCKET_OBTAINED,
        SM_PROCESS_RESPONSE,
        SM_DISCONNECT,
        SM_DONE
    } GenericTCPExampleState = SM_DONE;

    switch(GenericTCPExampleState)
    {
    case SM_HOME:
        // Connect a socket to the remote TCP server
        MySocket = TCPOpen((DWORD)&ServerName[0], TCP_OPEN_RAM_HOST, ServerPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

        // Abort operation if no TCP socket of type TCP_PURPOSE_GENERIC_TCP_CLIENT is available
        // If this ever happens, you need to go add one to TCPIPConfig.h
        if(MySocket == INVALID_SOCKET)
            break;

#if defined(STACK_USE_UART)
        putrsUART((ROM char*)"\r\n\r\nConnecting using Microchip TCP API...\r\n");
#endif

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

    case SM_SOCKET_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 > 5*TICK_SECOND)
            {
                // Close the socket so it can be used by other modules
                TCPDisconnect(MySocket);
                MySocket = INVALID_SOCKET;
                GenericTCPExampleState--;
            }
            break;
        }

        Timer = TickGet();

        // Make certain the socket can be written to
        if(TCPIsPutReady(MySocket) < 125u)
            break;

        // Place the application protocol data into the transmit buffer.  For this example, we are connected to an HTTP server, so we'll send an HTTP GET request.
        TCPPutROMString(MySocket, (ROM BYTE*)"GET ");
        TCPPutROMString(MySocket, RemoteURL);
        TCPPutROMString(MySocket, (ROM BYTE*)" HTTP/1.0\r\nHost: ");
        TCPPutString(MySocket, ServerName);
        TCPPutROMString(MySocket, (ROM BYTE*)"\r\nConnection: close\r\n\r\n");

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

    case SM_PROCESS_RESPONSE:
        // Check to see if the remote node has disconnected from us or sent us any application data
        // If application data is available, write it to the UART
        if(!TCPIsConnected(MySocket))
        {
            GenericTCPExampleState = SM_DISCONNECT;
            // Do not break;  We might still have data in the TCP RX FIFO waiting for us
        }

        // Get count of RX bytes waiting
        w = TCPIsGetReady(MySocket);

        // Obtian and print the server reply
        i = sizeof(vBuffer)-1;
        vBuffer[i] = '\0';
        while(w)
        {
            if(w < i)
            {
                i = w;
                vBuffer[i] = '\0';
            }
            w -= TCPGetArray(MySocket, vBuffer, i);
#if defined(STACK_USE_UART)
            putsUART((char*)vBuffer);
#endif

            // putsUART is a blocking call which will slow down the rest of the stack
            // if we shovel the whole TCP RX FIFO into the serial port all at once.
            // Therefore, let's break out after only one chunk most of the time.  The
            // only exception is when the remote node disconncets from us and we need to
            // use up all the data before changing states.
            if(GenericTCPExampleState == SM_PROCESS_RESPONSE)
                break;
        }

        break;

    case SM_DISCONNECT:
        // Close the socket so it can be used by other modules
        // For this application, we wish to stay connected, but this state will still get entered if the remote server decides to disconnect
        TCPDisconnect(MySocket);
        MySocket = INVALID_SOCKET;
        GenericTCPExampleState = SM_DONE;
        break;

    case SM_DONE:
        // Do nothing unless the user pushes BUTTON1 and wants to restart the whole connection/download process
        if(BUTTON1_IO == 0u)
            GenericTCPExampleState = SM_HOME;
        break;
    }
}
Ejemplo n.º 30
0
void TCPTXPerformanceTask(void)
{
	static TCP_SOCKET MySocket = INVALID_SOCKET;
	static DWORD dwTimeStart;
	static DWORD dwBytesSent;
	static DWORD_VAL dwVLine;
	BYTE vBuffer[10];
	static BYTE vBytesPerSecond[12];
	WORD w;
	DWORD dw;
	QWORD qw;
	
	// Start the TCP server, listening on PERFORMANCE_PORT
	if(MySocket == INVALID_SOCKET)
	{
		MySocket = TCPOpen(0, TCP_OPEN_SERVER, TX_PERFORMANCE_PORT, TCP_PURPOSE_TCP_PERFORMANCE_TX);
	
		// Abort operation if no TCP socket of type TCP_PURPOSE_TCP_PERFORMANCE_TEST is available
		// If this ever happens, you need to go add one to TCPIPConfig.h
		if(MySocket == INVALID_SOCKET)
			return;
		
		dwVLine.Val = 0;
		dwTimeStart = TickGet();
		vBytesPerSecond[0] = 0;	// Initialize empty string right now
		dwBytesSent = 0;
	}
	
	// See how many bytes we can write to the TX FIFO
	// If we can't fit a single line of data in, then 
	// lets just wait for now.
	w = TCPIsPutReady(MySocket);
	if(w < 12+27+5+32u)
		return;

	vBuffer[0] = '0';
	vBuffer[1] = 'x';

	// Transmit as much data as the TX FIFO will allow
	while(w >= 12+27+5+32u)
	{
		// Convert line counter to ASCII hex string
		vBuffer[2] = btohexa_high(dwVLine.v[3]);
		vBuffer[3] = btohexa_low(dwVLine.v[3]);
		vBuffer[4] = btohexa_high(dwVLine.v[2]);
		vBuffer[5] = btohexa_low(dwVLine.v[2]);
		vBuffer[6] = btohexa_high(dwVLine.v[1]);
		vBuffer[7] = btohexa_low(dwVLine.v[1]);
		vBuffer[8] = btohexa_high(dwVLine.v[0]);
		vBuffer[9] = btohexa_low(dwVLine.v[0]);

		dwVLine.Val++;
	
		// Place all data in the TCP TX FIFO
		TCPPutArray(MySocket, vBuffer, sizeof(vBuffer));

		dw = TickGet() - dwTimeStart;

		// Calculate exact bytes/second, less truncation
		if((dwVLine.v[0] & 0x3F) == 0x00)
		{
			qw = (QWORD)dwBytesSent * (TICK_SECOND/100);
			qw /= dw;
			ultoa((DWORD)qw, vBytesPerSecond);
		}
		TCPPutROMString(MySocket, (ROM BYTE*)": We are currently achieving ");
		TCPPutROMArray(MySocket, (ROM BYTE*)"       ", 5-strlen((char*)vBytesPerSecond));
		TCPPutString(MySocket, vBytesPerSecond);
		TCPPutROMString(MySocket, (ROM BYTE*)"00 bytes/second TX throughput.\r\n");

		if(dw > TICK_SECOND)
		{
			dwBytesSent >>= 1;
			dwTimeStart += dw>>1;
		}
		
		w -= 12+27+5+32;
		dwBytesSent += 12+27+5+32;
	}