示例#1
0
int32_t getLength(void){
	uint32_t len=0;
	char lenstr[21];
	char *len2;
	for(;;){
		memset(lenstr, 0, 21);
		cli_getsn_cecho(lenstr, 20);
		len2 = strstrip(lenstr);
		if(!strncasecmp_P(len2, PSTR("LEN"), 3)){
			while(*len2 && *len2!='=')
				len2++;
			if(*len2=='='){
				do{
					len2++;
				}while(*len2 && !isdigit((uint8_t)*len2));
				len = my_strtoul(len2);
				//len=(uint32_t)strtoul(len2, NULL, 10);
				return len;
			}
		} else {
			if(!strncasecmp_P(len2, PSTR("EXIT"), 4)){
				return -1;
			}
		}
	}
	return -1;
}
示例#2
0
uint16_t checkHeader(Client &client, uint16_t *contentLength) {
    char buf[70];
    uint8_t p = 0;
    int c = 0;
    bool done = false;  // when we read the blank line or error
    uint16_t ret = 401;  // not found

    if (contentLength) *contentLength = 0;

    //Serial.print("__bss_end 0x");Serial.println(__bss_end,HEX);
    if (client == NULL) {
        Serial.println("Client NULL!!");
        return ret;
    }
    // read until \r\n\r\n then check header values
    while (!done) {
        // read a single line up to a newline \n
        p = cRead(&client, buf, sizeof(buf), '\n');
        // Serial.print("read "); Serial.println(p);
        // process the data in the line
        if (p && buf[p-1] == '\n')  {  // did we succeed in reading a line?
            buf[p] = 0;  // end the string
            //Serial.println(buf);
            ++c;
            if (c >= 20) {
                client.flush();
                return 402;
            }
            //Serial.print("read line of length "); Serial.print(p); Serial.println(": ");
            //Serial.println(buf);
            char *h;
            if ((h = strstr(buf, "HTTP")) != NULL) {
                char *q = strchr(h, ' ') ;
                if (q != NULL) {
                    ret = atoi(q+1);
                    //Serial.print("status "); Serial.println(buf);
                    if (ret != 200) {
                        client.flush();
                        return ret;
                    }
                }
            } else if (contentLength != NULL && !strncasecmp_P(buf, PSTR("Content-Length:"), 15)) {
                char *q = strchr(buf, ' ') ;
                if (q != NULL) {
                    *contentLength = atoi(q+1);
                }
            } else if (p == 2) {  // blank line, done with header
                done = true;
            }
        } else {
            Serial.println("failed");
            // somthing went wrong, didn't read a full line
            ret = 403;  // indicate we're not successful
            client.flush();
            done = true;
        }
    }
    //Serial.print("status "); Serial.println(ret);
    return ret;
}
示例#3
0
文件: util.c 项目: LegionII/ati2.3a5
/*!
 * \brief Find a descriptor for a piece of text.
 *
 * A LookUp Table (LUT) is searched for matching text.
 * The row in which the match was found is returned.
 * If no match was found, the descriptor of the last entry
 * is returned. As a result, the table should always contain
 * at least one entry. And that last one should be the
 * default/empty or error value, depending on your needs.
 *
 * \note    The compare used is not case sensitive.
 * \note    If byLen is 0, only the first part of pcText
 *          needs to match.
 *          E.g. "foo" in the LUT will match "foo",
 *          E.g. "foo" in the LUT will match "foobar"
 *          By passing the length of pcText (not including the
 *          \0 character), will force an exact match.
 *          E.g. "foo" in the LUT will match "foo",
 *          E.g. "foo" in the LUT will not match "foobar",
 *
 * \param   tLookupTable [in] The lookup table.
 * \param   pcText [in] The text to find the value for
 *          this does not need to be 0 terminated.
 * \param   byLen [in] See notes above.
 *
 * \return  The descriptor of the row that matched.
 *          Or the descriptor of the last row if no match.
 */
void *LutSearch(CONST tLut tLookupTable[],
                CONST char *pcText,
                unsigned char byLen)
{
    unsigned char byRow = 0;

    for (byRow = 0; byRow < (unsigned char)(-1); byRow++)
    {
        unsigned char byTagLen = 0;

        if (tLookupTable[byRow].pszTag == NULL)
        {
            break;
        }

        byTagLen = strlen_P(tLookupTable[byRow].pszTag);

        if ((byLen != 0) && (byTagLen != byLen))
        {
            continue;   /* not the same size; keep looking */
        }

        /* case-insensitive compare */
        if (strncasecmp_P(pcText, tLookupTable[byRow].pszTag, byTagLen) == 0)
        {
            break;
        }
    }

#ifdef UTIL_DEBUG
    LogMsg_P(LOG_DEBUG, PSTR("Match %d"), byRow);
#endif /* #ifdef UTIL_DEBUG */

    return (tLookupTable[byRow].pDesc);
}
示例#4
0
static int search_cvars(const char *var_name) {
	int idx=0;
	// Variablenname in Tabelle suchen
#if USE_PROGMEM
	while((int *)pgm_read_word(&cvars[idx].pvar) != NULL &&
	      strncasecmp_P(var_name, cvars[idx].var_name, MAX_NAME_LEN)) {
    	idx++;
    }
#else
	while(cvars[idx].pvar != NULL &&
	      strncasecmp(cvars[idx].var_name, var_name, MAX_NAME_LEN)) {
    	idx++;
    }
#endif
    // keinen Tabelleneintrag gefunden!
#if USE_PROGMEM
    if ((int *)pgm_read_word(&cvars[idx].pvar) == NULL) {
#else
    if (cvars[idx].pvar == NULL) {
#endif
    	tokenizer_error_print(current_linenum, UNKNOWN_CVAR_NAME);
		ubasic_break();
    }
	return idx;
}

void vpoke_statement(void) {
	int idx=0;
#if USE_PROGMEM
	int *var_temp;
#endif

	accept(TOKENIZER_VPOKE);
    accept(TOKENIZER_LEFTPAREN);
	// Variablenname ermitteln
	if(tokenizer_token() == TOKENIZER_STRING) {
		tokenizer_next();
	}
	idx=search_cvars(tokenizer_last_string_ptr());
	accept(TOKENIZER_RIGHTPAREN);
	accept(TOKENIZER_EQ);
#if USE_PROGMEM
	var_temp=(int *)pgm_read_word(&cvars[idx].pvar);
	*var_temp=expr();
#else
	*cvars[idx].pvar = expr();
#endif
	//tokenizer_next();
}
示例#5
0
Adafruit_MQTT_Subscribe *Adafruit_MQTT::readSubscription(int16_t timeout) {
  uint8_t i, topiclen, datalen;

  // Check if data is available to read.
  uint16_t len = readPacket(buffer, MAXBUFFERSIZE, timeout, true); // return one full packet
  if (!len)
    return NULL;  // No data available, just quit.
  DEBUG_PRINTBUFFER(buffer, len);

  // Parse out length of packet.
  topiclen = buffer[3];
  DEBUG_PRINT(F("Looking for subscription len ")); DEBUG_PRINTLN(topiclen);

  // Find subscription associated with this packet.
  for (i=0; i<MAXSUBSCRIPTIONS; i++) {
    if (subscriptions[i]) {
      // Skip this subscription if its name length isn't the same as the
      // received topic name.
      if (strlen_P(subscriptions[i]->topic) != topiclen)
        continue;
      // Stop if the subscription topic matches the received topic. Be careful
      // to make comparison case insensitive.
      if (strncasecmp_P((char*)buffer+4, subscriptions[i]->topic, topiclen) == 0) {
        DEBUG_PRINT(F("Found sub #")); DEBUG_PRINTLN(i);
        break;
      }
    }
  }
  if (i==MAXSUBSCRIPTIONS) return NULL; // matching sub not found ???

  // zero out the old data
  memset(subscriptions[i]->lastread, 0, SUBSCRIPTIONDATALEN);

  datalen = len - topiclen - 4;
  if (datalen > SUBSCRIPTIONDATALEN) {
    datalen = SUBSCRIPTIONDATALEN-1; // cut it off
  }
  // extract out just the data, into the subscription object itself
  memcpy(subscriptions[i]->lastread, buffer+4+topiclen, datalen);
  subscriptions[i]->datalen = datalen;
  DEBUG_PRINT(F("Data len: ")); DEBUG_PRINTLN(datalen);
  DEBUG_PRINT(F("Data: ")); DEBUG_PRINTLN((char *)subscriptions[i]->lastread);

  // return the valid matching subscription
  return subscriptions[i];
}
示例#6
0
文件: rfBeeSerial.c 项目: bpg/RFBee
int processSerialCmd(uint8_t size) {
	int result = MODIFIED;

	uint8_t configItem;   // the ID used in the EEPROM
	uint8_t paramDigits;  // how many digits for the parameter
	uint8_t maxValue;     // maximum value of the parameter
	AT_Command_Function_t function; // the function which does the real work on change

	// read the AT
	if (strncasecmp("AT", (char *) serialData, 2) != 0) {
		return ERR;
	}

	// read the command
	for (int i = 0; i <= sizeof(atCommands) / sizeof(AT_Command_t); i++) {
		// do we have a known command
		if (strncasecmp_P((char *) serialData + 2,
				(PGM_P) pgm_read_word(&(atCommands[i].name)), 2) == 0) {
			// get the data from PROGMEM
			configItem = pgm_read_byte(&(atCommands[i].configItem));
			paramDigits = pgm_read_byte(&(atCommands[i].paramDigits));
			maxValue = pgm_read_byte(&(atCommands[i].maxValue));
			function =
					(AT_Command_Function_t) pgm_read_word(&(atCommands[i].function));

			if (paramDigits > 0) {
				result = modifyConfig(configItem, paramDigits, maxValue);
			}

			if (result == MODIFIED) {
				result = OK;  // config only commands always return OK
				if (function) {
					result = function();    // call the command function
				}
			}

			return (result); // return the result of the execution of the function linked to the command
		}
	}

	return ERR;
}
示例#7
0
文件: httpd.c 项目: AnDann/ethersex
static void
httpd_handle_input(void)
{
  char *ptr = (char *) uip_appdata;

#ifdef HTTPD_AUTH_SUPPORT
  char *start_ptr;
  if (STATE->header_reparse)
  {
    printf("reparse next part of the header\n");
    goto start_auth;
  }
#endif /* HTTPD_AUTH_SUPPORT */

  if (uip_len < 10)
  {
    printf("httpd: received request to short (%d bytes).\n", uip_len);
    STATE->handler = httpd_handle_400;
    return;
  }

#ifdef HTTPD_SOAP_SUPPORT
  if (strncasecmp_P(uip_appdata, PSTR("POST /soap"), 10) == 0)
  {
    soap_initialize_context(&STATE->u.soap);
    STATE->handler = httpd_handle_soap;
    return;
  }
#endif /* HTTPD_SOAP_SUPPORT */

  if (strncasecmp_P(uip_appdata, PSTR("GET /"), 5))
  {
    printf("httpd: received request is not GET.\n");
    STATE->handler = httpd_handle_400;
    return;
  }

  char *filename = (char *)uip_appdata + 5;     /* beyond slash */
  ptr = strchr(filename, ' ');

  if (ptr == NULL)
  {
    printf("httpd: space after filename not found.\n");
    STATE->handler = httpd_handle_400;
    return;
  }

  *ptr = 0;                     /* Terminate filename. */

  /*
   * Successfully parsed the GET request,
   * possibly check authentication.
   */


#ifdef HTTPD_AUTH_SUPPORT
  ptr++;                        /* Increment pointer to the end of
                                 * the GET */
start_auth:
  start_ptr = ptr;
  ptr = strstr_P(ptr, PSTR("Authorization: "));

  if (ptr == NULL)
  {
    if (strstr_P(start_ptr, PSTR("\r\n\r\n")))
    {
      printf("Authorization-header not found.\n");
      printf("%s\n", start_ptr);
      goto auth_failed;
    }
    else
    {
      ptr = start_ptr;
      /* Skip all Lines before the last one */
      while (1)
      {
        ptr = strstr_P(start_ptr, PSTR("\r\n"));
        if (ptr)
          start_ptr = ptr + 2;
        else
          break;
      }
      if (!strncmp(start_ptr, PSTR("Authorization: "), strlen(start_ptr)))
      {
        printf("Authorization header is split over two packages, damn");
        printf("%s\n", start_ptr);
        goto auth_failed;
      }
      else
      {
        STATE->header_reparse = 1;
        goto after_auth;
      }
    }
  }
  ptr += 15;                    /* Skip `Authorization: ' header. */

  if (strncmp_P(ptr, PSTR("Basic "), 6))
  {
    printf("auth: method is not basic.\n");
    goto auth_failed;
  }
  ptr += 6;                     /* Skip `Basic ' string. */

  char *nl = strchr(ptr, '\n');
  if (nl == NULL)
  {
    printf("auth: newline not found.\n");
    goto auth_failed;
  }

  *nl = 0;                      /* Zero-terminate BASE64-string. */

  base64_str_decode(ptr);
  printf("auth: decoded auth string: '%s'.\n", ptr);

  char *password;

  if ((password = strchr(ptr, ':')) == NULL)
  {
    printf("auth: didn't find colon!\n");
  auth_failed:
    httpd_cleanup();
    STATE->handler = httpd_handle_401;
    STATE->header_reparse = 0;
    return;
  }
  *password = 0;
  password++;

  /* Do the PAM authentification */
  pam_auth(ptr, password, &STATE->auth_state);

  if (STATE->header_reparse)
  {
    STATE->header_reparse = 0;
    return;                     /* We musn't open the file once again */
  }

after_auth:
  /* Dummy statement, to keep GCC happy, if HTTP_SD_DIR_SUPPORT is enabled
   * and thus the uint8_t definition the next statement in code. */
  (void) 0;

#endif /* HTTPD_AUTH_SUPPORT */

  /*
   * Authentication is okay, now fulfill request for file
   * refered to in filename.
   */
#ifndef HTTP_SD_DIR_SUPPORT
  if (*filename == 0)           /* No filename, override -> index */
    strcpy_P(filename, PSTR(HTTPD_INDEX));
#endif


#ifdef HTTP_FAVICON_SUPPORT
  if (strcmp_P(filename, PSTR("favicon.ico")) == 0)
    strcpy_P(filename, PSTR("If.ico"));
#endif



#ifdef ECMD_PARSER_SUPPORT
  uint8_t offset = strlen_P(PSTR(ECMD_INDEX "?"));
  if (strncmp_P(filename, PSTR(ECMD_INDEX "?"), offset) == 0)
  {
    httpd_handle_ecmd_setup(filename + offset);
    return;
  }
#endif /* ECMD_PARSER_SUPPORT */

#ifdef VFS_SUPPORT
  /* Keep content-type identifing char. */
  /* filename instead starts after last directory slash. */
  char *slash = strrchr(filename, '/');
  if (slash != NULL)
  {
    STATE->u.vfs.content_type = *(char *) (slash + 1);
  }
  else
  {
    STATE->u.vfs.content_type = *filename;
  }

  STATE->u.vfs.fd = vfs_open(filename);
  if (STATE->u.vfs.fd)
  {
    STATE->handler = httpd_handle_vfs;
    return;
  }

  /* Now try appending the index.html document name */
  ptr = filename + strlen(filename);
#ifdef HTTP_SD_DIR_SUPPORT
  uint8_t lastchar = ptr[-1];
#endif
  if (ptr[-1] != '/')
    *(ptr++) = '/';

  strcpy_P(ptr, PSTR(HTTPD_INDEX));
  STATE->u.vfs.fd = vfs_open(filename);
  if (STATE->u.vfs.fd)
  {
    STATE->handler = httpd_handle_vfs;
    return;
  }

  if (ptr == filename)          /* Make sure not to strip initial slash. */
    ptr[0] = 0;
  else
    ptr[-1] = 0;                /* Strip index filename again,
                                 * including the last slash. */
#endif /* VFS_SUPPORT */

#ifdef HTTP_SD_DIR_SUPPORT
  if ((STATE->u.dir.handle = vfs_sd_chdir(filename - 1)))
  {
    strncpy(STATE->u.dir.dirname, filename - 1, SD_DIR_MAX_DIRNAME_LEN);
    STATE->u.dir.dirname[SD_DIR_MAX_DIRNAME_LEN - 1] = 0;
    if (lastchar != '/')
    {
      STATE->handler = httpd_handle_sd_dir_redirect;
      fat_close_dir(STATE->u.dir.handle);
    }
    else
      STATE->handler = httpd_handle_sd_dir;
    return;
  }
#endif /* HTTP_SD_DIR_SUPPORT */

  /* Fallback, send 404. */
  STATE->handler = httpd_handle_404;
}
示例#8
0
/**
 *	\ingroup allgfunktionen
 *	Zeile nach Parameter durchsuchen und ersetzen
 *
 *	Mögliche Variable haben ein Prozentzeichen (\%) vorangestellt und sind:
 *	\li \b DATE	Tagesdatum
 *	\li \b USDATE	Tagesdatum im Internet kompatiblen Format
 *	\li	\b WDAY	Wochentag, abgekürzt auf 3 Buchstaben
 *	\li \b TIME	aktuelle Zeit
 *	\li \b VA\@nn	analoger Wert nn
 *	\li \b OW\@nn	nn = 00 bis MAXSENSORS-1 gibt 1-Wire Temperaturwerte in 1/10 °C aus
 *	\li \b OW\@mm	mm = 20 bis MAXSENSORS-1+20 gibt 1-Wire Temperaturwerte in °C mit einer Nachkommastelle aus<br>
 *	d.h. OW\@nn für Balkenbreite verwenden und OW\@mm für Celsius-Anzeige
 *	\li \b PORTnm	Status des Ausgangs Pin m (0, 1, ...) an Port n (A, B, C, ...)
 *	\li \b PINnm	Status des Eingangs Pin m (0, 1, ...) an Port n (A, B, C, ...)<br>
 *		 dargestellt durch eine jpg-Datei ledon.jpg / ledoff.jpg
 *
 *	\param[in] buffer String mit eingebetteten Parametern
 *	\param[in,out] ptr Speicherplatz des konvertierten Strings
 *	\param[out] nbytes Anzahl verarbeiteter Bytes
 *	\returns Anzahl der Bytes im konvertierten String
*/
uint16_t translate(char *buffer, char **ptr, uint16_t *nbytes )
{
	uint16_t len = 0;
	char *src = buffer;
	char *dest = *ptr;

	while (*src) {
		
		if (*src != '%') {
			*dest++ = *src++;
			++len;
		}
		else {
			++src;

			if (strncasecmp_P(src,PSTR("TIME"),4)==0) {
				uint16_t year;
				uint8_t month, day, hour, min, sec;
				FUNCS_DEBUG(" - Zeit");
				get_datetime(&year, &month, &day, &hour, &min, &sec);
				sprintf_P(dest,PSTR("%2.2d:%2.2d:%2.2d"),hour,min,sec);
				src += 4;
			}

			else if (strncasecmp_P(src,PSTR("DATE"),4)==0) {
				uint16_t year;
				uint8_t month, day, hour, min, sec;
				FUNCS_DEBUG(" - Datum");
				get_datetime(&year, &month, &day, &hour, &min, &sec);
				sprintf_P(dest,PSTR("%2.2d.%2.2d.%4d"),day,month,year);
				src += 4;
			}

			else if (strncasecmp_P(src,PSTR("USDATE"),6)==0) {
				FUNCS_DEBUG(" - USDatum");
				GetUSdate(dest);
				src += 6;
			}

			else if (strncasecmp_P(src,PSTR("WDAY"),4)==0) {
				FUNCS_DEBUG(" - Wochentag");
				memcpy_P(dest,&Tagesnamen[TM_DOW*3],3);
				dest += 3;
				*dest = '\0';
				src += 4;
			}

			#if USE_ADC
			else if (strncasecmp_P(src,PSTR("VA@"),3)==0) {	
				FUNCS_DEBUG(" - Analogwert");
				uint8_t i = (*(src+3)-48)*10 + (*(src+4)-48);
				itoa (var_array[i],dest,10);
				src += 5;
			}
			#endif

			#if 0
			//
			// KTY0D gibt Differenzmessung in dezimalen Grad aus
			// KTY0x gibt Wert in 1/10 Grad aus
			// entsprechend KTY1D/KTY1x für 2. Differenzmessung
			//
			else if (strncasecmp_P(src,PSTR("KTY"),3)==0) {	
				FUNCS_DEBUG(" - KTY-Wert");
				b = (*(src+3)=='0')? KTY_SENS1 : KTY_SENS2;	// Speicherplätze der Differenzmessungen

				int16_t T = (int16_t) (var_array[b] * -0.62 + 224.3);

				if (*(src+4)=='D') {
					int8_t j = (int8_t)(T / 10);
					itoa (j,dest,10);

					while (*dest++)			// neues Ende finden
						++len;
					--dest;

					*dest++ = ',';
					++len;

					j = T % 10;				// Nachkommastelle
					itoa (j,dest,10);
				} else if (T < 0) {
					T = -T;					// Vorzeichen abschneiden
					itoa (T,dest,10);

					while (*dest++)			// neues Ende finden
						++len;
					--dest;

					// "style rechtsbündig" anhängen
					strcpy_P(dest,PSTR("\" style=\"float: right"));
				}
				else {
					itoa (T,dest,10);
				}
				src += 5;
			}
			#endif
			
#if USE_OW
			/*
			*	1-Wire Temperatursensoren
			*	-------------------------
			*	OW@nn	nn = 00 bis MAXSENSORS-1 gibt Werte in 1/10 °C aus
			*	OW@mm	mm = 20 bis MAXSENSORS-1+20 gibt Werte in °C mit einer Nachkommastelle aus
			*	d.h. OW@nn für Balkenbreite verwenden und OW@mm für Celsius-Anzeige
			*/
			else if (strncasecmp_P(src,PSTR("OW@"),3)==0) {	
				FUNCS_DEBUG(" - 1-wire");
				uint8_t i = (*(src+3)-48)*10 + (*(src+4)-48);
				if (i >= 20) {	// Offset bei Sensor# abziehen und Wert als Dezimalzahl ausgeben
					i -= 20;
					dtostrf(ow_array[i] / 10.0,3,1,dest);
				} else {
					itoa (ow_array[i],dest,10);
				}
				src += 5;
			}
#endif

			//Einsetzen des Port Status %PORTxy durch "checked" wenn Portx.Piny = 1
			//x: A..G  y: 0..7 
			else if (strncasecmp_P(src,PSTR("PORT"),4)==0) {
				FUNCS_DEBUG(" - Portstatus");
				uint8_t pin  = (*(src+5)-48);	
				uint8_t b = 0;
				switch(*(src+4)) {
					case 'A':
						b = (PORTA & (1<<pin));
						break;
					case 'B':
						b = (PORTB & (1<<pin));
						break;
					case 'C':
						b = (PORTC & (1<<pin));
						break;
					case 'D':
						b = (PORTD & (1<<pin));
						break; 
				}
				
				if(b) {
					//strcpy_P(dest, PSTR("checked"));
					strcpy_P(dest, PSTR("ledon.gif"));
				}
				else {
					//strcpy_P(dest, PSTR("unchecked"));
					strcpy_P(dest, PSTR("ledoff.gif"));
				}

				src += 6;
			}
			
			//Einsetzen des Pin Status %PI@xy bis %PI@xy durch "ledon" oder "ledoff"
			//x = 0 : PINA / x = 1 : PINB / x = 2 : PINC / x = 3 : PIND
			else if (strncasecmp_P(src,PSTR("PIN"),3)==0) {
				FUNCS_DEBUG(" - Eingangswert");
				uint8_t pin  = (*(src+4)-48);	
				uint8_t b = 0;
				switch(*(src+3)) {
					case 'A':
						b = (PINA & (1<<pin));
						break;
					case 'B':
						b = (PINB & (1<<pin));
						break;
					case 'C':
						b = (PINC & (1<<pin));
						break;
					case 'D':
						b = (PIND & (1<<pin));
						break;    
				}
				
				if(b) {	// gesetztes bit bedeutet: nix dran, da Pullup Widerstand
					strcpy_P(dest, PSTR("ledoff.gif"));
				} else {
					strcpy_P(dest, PSTR("ledon.gif"));	// Schalter auf Masse geschlossen
				}

				src += 5;
			}
			else {	// nix gefunden -> '%' speichern
				*dest++ = '%';
				*dest = 0;
				++len;
			}

			while (*dest++)	// neues Ende finden
				++len;
			--dest;
		}

	}
	*ptr = dest;
	*nbytes = (uint16_t)(src - buffer);
	return len;
}
示例#9
0
enum PubNub_BH PubNub::_request_bh(PubNub_BASE_CLIENT &client, unsigned long t_start, int timeout)
{
	/* Finish the first line of the request. */
	client.print(" HTTP/1.1\r\n");
	/* Finish HTTP request. */
	client.print("Host: ");
	client.print(origin);
	client.print("\r\nUser-Agent: PubNub-Arduino/1.0\r\nConnection: close\r\n\r\n");

#define WAIT() do { \
	while (!client.available()) { \
		/* wait, just check for timeout */ \
		if (millis() - t_start > (unsigned long) timeout * 1000) { \
			DBGprintln("Timeout in bottom half"); \
			return PubNub_BH_TIMEOUT; \
		} \
		if (!client.connected()) { \
			/* Oops, connection interrupted. */ \
			DBGprintln("Connection reset in bottom half"); \
			return PubNub_BH_ERROR; \
		} \
	} \
} while (0)

	/* Read first line with HTTP code. */
	/* "HTTP/1.x " */
	do {
		WAIT();
	} while (client.read() != ' ');
	/* Now, first digit of HTTP code. */
	WAIT();
	char c = client.read();
	if (c != '2') {
		/* HTTP code that is NOT 2xx means trouble.
		 * kthxbai */
		DBGprint("Wrong HTTP status first digit ");
		DBGprint((int) c, DEC);
		DBGprintln(" in bottom half");
		return PubNub_BH_ERROR;
	}

	/* Now, we enter in a state machine that shall guide us through
	 * the remaining headers to the beginning of the body. */
	enum {
		RS_SKIPLINE, /* Skip the rest of this line. */
		RS_LOADLINE, /* Try loading the line in a buffer. */
	} request_state = RS_SKIPLINE; /* Skip the rest of status line first. */
	bool chunked = false;

	while (client.connected() || client.available()) {
		/* Let's hope there is no stray LF without CR. */
		if (request_state == RS_SKIPLINE) {
			do {
				WAIT();
			} while (client.read() != '\n');
			request_state = RS_LOADLINE;

		} else { /* request_state == RS_LOADLINE */
			/* line[] must be enough to hold
			 * Transfer-Encoding: chunked (or \r\n) */
			const static char PROGMEM chunked_str[] = "Transfer-Encoding: chunked\r\n";
			char line[sizeof(chunked_str)]; /* Not NUL-terminated! */
			int linelen = 0;
			char ch = 0;
			do {
				WAIT();
				ch = client.read();
				line[linelen++] = ch;
				if (linelen == strlen_P(chunked_str)
				    && !strncasecmp_P(line, chunked_str, linelen)) {
					/* Chunked encoding header. */
					chunked = true;
					break;
				}
			} while (ch != '\n' && linelen < sizeof(line));
			if (ch != '\n') {
				/* We are not at the end of the line yet.
				 * Skip the rest of the line. */
				request_state = RS_SKIPLINE;
			} else if (linelen == 2 && line[0] == '\r') {
				/* Empty line. This means headers end. */
				break;
			}
		}
	}

	if (chunked) {
		/* There is one extra line due to Transfer-encoding: chunked.
		 * Our minimalistic support means that we hope for just
		 * a single chunk, just skip the first line after header. */
		do {
			WAIT();
		} while (client.read() != '\n');
	}

	/* Body begins now. */
	return PubNub_BH_OK;
}
示例#10
0
文件: strtod.c 项目: 33d/gbsim-win
/**  The strtod() function converts the initial portion of the string pointed
     to by \a nptr to double representation.

     The expected form of the string is an optional plus ( \c '+' ) or minus
     sign ( \c '-' ) followed by a sequence of digits optionally containing
     a decimal-point character, optionally followed by an exponent.  An
     exponent consists of an \c 'E' or \c 'e', followed by an optional plus
     or minus sign, followed by a sequence of digits.

     Leading white-space characters in the string are skipped.

     The strtod() function returns the converted value, if any.

     If \a endptr is not \c NULL, a pointer to the character after the last
     character used in the conversion is stored in the location referenced by
     \a endptr.

     If no conversion is performed, zero is returned and the value of
     \a nptr is stored in the location referenced by \a endptr.

     If the correct value would cause overflow, plus or minus \c INFINITY is
     returned (according to the sign of the value), and \c ERANGE is stored
     in \c errno.  If the correct value would cause underflow, zero is
     returned and \c ERANGE is stored in \c errno.
 */
ATTRIBUTE_CLIB_SECTION
double
strtod (const char * nptr, char ** endptr)
{
    union {
	unsigned long u32;
	float flt;
    } x;
    unsigned char c;
    int exp;

    unsigned char flag;
#define FL_MINUS    0x01	/* number is negative	*/
#define FL_ANY	    0x02	/* any digit was readed	*/
#define FL_OVFL	    0x04	/* overflow was		*/
#define FL_DOT	    0x08	/* decimal '.' was	*/
#define FL_MEXP	    0x10	/* exponent 'e' is neg.	*/

    if (endptr)
	*endptr = (char *)nptr;

    do {
	c = *nptr++;
    } while (isspace (c));

    flag = 0;
    if (c == '-') {
	flag = FL_MINUS;
	c = *nptr++;
    } else if (c == '+') {
	c = *nptr++;
    }
    
    if (!strncasecmp_P (nptr - 1, pstr_inf, 3)) {
	nptr += 2;
	if (!strncasecmp_P (nptr, pstr_inity, 5))
	    nptr += 5;
	if (endptr)
	    *endptr = (char *)nptr;
	return flag & FL_MINUS ? -INFINITY : +INFINITY;
    }
    
    /* NAN() construction is not realised.
       Length would be 3 characters only.	*/
    if (!strncasecmp_P (nptr - 1, pstr_nan, 3)) {
	if (endptr)
	    *endptr = (char *)nptr + 2;
	return NAN;
    }

    x.u32 = 0;
    exp = 0;
    while (1) {
    
	c -= '0';
    
	if (c <= 9) {
	    flag |= FL_ANY;
	    if (flag & FL_OVFL) {
		if (!(flag & FL_DOT))
		    exp += 1;
	    } else {
		if (flag & FL_DOT)
		    exp -= 1;
		/* x.u32 = x.u32 * 10 + c	*/
		x.u32 = (((x.u32 << 2) + x.u32) << 1) + c;
		if (x.u32 >= (ULONG_MAX - 9) / 10)
		    flag |= FL_OVFL;
	    }

	} else if (c == (('.'-'0') & 0xff)  &&  !(flag & FL_DOT)) {
	    flag |= FL_DOT;
	} else {
	    break;
	}
	c = *nptr++;
    }
    
    if (c == (('e'-'0') & 0xff) || c == (('E'-'0') & 0xff))
    {
	int i;
	c = *nptr++;
	i = 2;
	if (c == '-') {
	    flag |= FL_MEXP;
	    c = *nptr++;
	} else if (c == '+') {
	    c = *nptr++;
	} else {
	    i = 1;
	}
	c -= '0';
	if (c > 9) {
	    nptr -= i;
	} else {
	    i = 0;
	    do {
		if (i < 3200)
		    i = (((i << 2) + i) << 1) + c;	/* i = 10*i + c	*/
		c = *nptr++ - '0';
	    } while (c <= 9);
	    if (flag & FL_MEXP)
		i = -i;
	    exp += i;
	}
    }
    
    if ((flag & FL_ANY) && endptr)
	*endptr = (char *)nptr - 1;
    
    x.flt = __floatunsisf (x.u32);		/* manually	*/
    if ((flag & FL_MINUS) && (flag & FL_ANY))
	x.flt = -x.flt;
	
    if (x.flt != 0) {
	int pwr;
	if (exp < 0) {
	    nptr = (void *)(pwr_m10 + 5);
	    exp = -exp;
	} else {
	    nptr = (void *)(pwr_p10 + 5);
	}
	for (pwr = 32; pwr; pwr >>= 1) {
	    for (; exp >= pwr; exp -= pwr) {
		union {
		    unsigned long u32;
		    float flt;
		} y;
		y.u32 = pgm_read_dword ((float *)nptr);
		x.flt *= y.flt;
	    }
	    nptr -= sizeof(float);
	}
	if (!isfinite(x.flt) || x.flt == 0)
	    errno = ERANGE;
    }
示例#11
0
uint8_t sim900_GPRS_init( const char * const service_APN, const uint8_t isSZPGM )
{

	const char * szRet = NULL;
	char szBuf[32];
	uint8_t len = 32;
	uint8_t i;

	DEBUG_PRINT_FUNCTION_NAME(VERBOSE,"SIM900_GPRS_INIT");


	//CHECK THE STATUS OF THE BEARER
	LITTLE_DELAY;
	if(0!=sim900_cmd_with_read_string(PSTR("AT+SAPBR=2,1\r\n"),true,szBuf,&len))
	{
		debug_string(NORMAL,PSTR("(sim900_gprs_init) the SAPBR #1 query went wrong for some reason, procedure aborted\r\n"),true);
		return 1;
	}
	
	szRet = sim900_wait_retstring();


	debug_string(VERBOSE,PSTR("(sim900_gprs_init) bearer is : "),true);
	debug_string(VERBOSE,szBuf,false);
	debug_string(VERBOSE,szCRLF,true);

	
	//check if the OK was at the end of the answer and
	//the status of the bearer
	
	if(sz_OK!=szRet) { //Something went wrong with the sapbr query, we exit from the init function
		debug_string(NORMAL,PSTR("(sim900_gprs_init) the SAPBR #2 query went wrong for some reason, procedure aborted\r\n"),true);
		return 1;
	}
	

	//check if the bearer is not closed 
	if (strncasecmp_P(szBuf,PSTR("+SAPBR: 1,3,\"0.0.0.0\""),11)!=0)
	{
		//The bearer is not closed maybe we can accept it
		//and try to use it anyway

		const char r = szBuf[10];
		if(r=='2') { //this bearer is closing
			debug_string(NORMAL,PSTR("(sim900_gprs_init) the requested bearer is in closing status (WARNING)\r\n"),true);
			return 2;
		} else {
			debug_string(NORMAL,PSTR("(sim900_gprs_init) the requested bearer is already open(WARNING)\r\n"),true);
			return 0;
		}
	}


	//configure the bearer to be used
	LITTLE_DELAY;
	if(NULL==sim900_cmd_with_retstring(PSTR("AT+SAPBR=3,1,\"Contype\",\"GPRS\"\r\n"),true))
	{
		//Something went wrong with the sapbr query, we exit from the init function
		debug_string(NORMAL,PSTR("(sim900_gprs_init) the SAPBR=3,1,\"Contype\",\"GPRS\""  \
								" query went wrong for some reason, procedure aborted\r\n"),true);
		return 1;
		
	}
	

	//Set the APN
	//We don't use the facility function because of the buffer handling
	LITTLE_DELAY;
	for (i=0;i<2;i++)
	{
		sim900_put_string(PSTR("AT+SAPBR=3,1,\"APN\",\""),PGM_STRING);
		sim900_put_string(service_APN,isSZPGM);
		sim900_put_string(PSTR("\"\r\n"),PGM_STRING);
		szRet=sim900_wait_retstring();

		if (sz_OK==szRet)
		{
			break;
		}
		else if(NULL==szRet)
		{
			continue;
		}

		//Something went wrong with the sapbr query, we exit from the init function
		debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the SAPBR=3,1,\"APN\""  \
								" query went wrong for some reason, procedure aborted\r\n"));
		return 1;
	}


	//Finally open the bearer
	LITTLE_DELAY;
	szRet = sim900_cmd_with_retstring(PSTR("AT+SAPBR=1,1\r\n"),true);
	if(sz_OK!=szRet)
	{
		//Something went wrong with the sapbr query, we exit from the init function
		debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the SAPBR=1,1"  \
					" query went wrong for some reason, procedure aborted\r\n"));
		return 1;
	}



	//Check if the bearer is correctly open
	for(i=0;i<10;++i) {

		len = 32;		
		LITTLE_DELAY;
		if(0!=sim900_cmd_with_read_string(PSTR("AT+SAPBR=2,1\r\n"),true,szBuf,&len))
		{
			debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the SAPBR query went wrong for some reason, procedure aborted\r\n"));
			return 1;
		}

		
		szRet = sim900_wait_retstring();

		debug_string_P(VERBOSE,PSTR("(sim900_gprs_init) bearer is : "));
		debug_string(VERBOSE,szBuf,RAM_STRING);
		debug_string_P(VERBOSE,szCRLF);

	
		//check if the OK was at the end of the answer and
		//the status of the bearer
	
		if(sz_OK!=szRet) { //Something went wrong with the sapbr query, we exit from the init function
			debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the SAPBR query went wrong, procedure aborted\r\n"));
			return 1;
		}

		const char r = szBuf[10];
			
		//check bearer status 0=connecting 1=connected 2=closing 3=closed
		if (r=='0')
		{
			debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the requested bearer is in 'connecting' status. Check again in 2 seconds\r\n"));
			delay_s(2);
			continue;
		} else if (r=='1')
		{
			debug_string_P(VERBOSE,PSTR("(sim900_gprs_init) the requested bearer is open\r\n"));
			break;
		} 
		else if((r=='2') || (r=='3'))
		{
			debug_string_P(NORMAL,PSTR("(sim900_gprs_init) the requested bearer is closed or in closing status (ERROR)\r\n"));
			return 1;
		}
	}

	return 0;
}
示例#12
0
uint8_t sim900_init()
{
	DEBUG_PRINT_FUNCTION_NAME(VERBOSE,"SIM900_INIT");

	
#ifdef SIM900_USART_POLLED
	
	debug_string_P(NORMAL,PSTR("(sim900_init) code compiled with polled usart\r\n"));
#else
	usart_interruptdriver_initialize(&sim900_usart_data,USART_GPRS,USART_INT_LVL_LO);
	usart_set_rx_interrupt_level(USART_GPRS,USART_INT_LVL_LO);
	usart_set_tx_interrupt_level(USART_GPRS,USART_INT_LVL_OFF);

	debug_string_P(NORMAL,PSTR("(sim900_init) code compiled with interrupt usart\r\n"));

#endif

init_sim:

	usart_rx_enable(USART_GPRS);

	sim900_power_off();
	
	const char * szRET = NULL;
	int t=2;
	while(t--) {
		sim900_power_toggle();
		uint8_t i=3;
		while(i--) {
			statusled_blink(1);
			sim900_put_string(sz_AT,PGM_STRING);
			szRET = sim900_wait_retstring();
			if(szRET!=sz_OK) {
				debug_string_P(NORMAL,PSTR("(SIM900_init) trying to set a serial line speed\r\n"));
			} else break;
		}
		if(szRET==sz_OK) break;
		debug_string_P(NORMAL,PSTR("(SIM900_init) Not being able to connect to SIM900. Try to power it on again\r\n"));
	}

	if (szRET!=sz_OK)
	{
		debug_string_P(NORMAL,PSTR("(SIM900_init) failed to synchronize with GPRS UART. The process will end here\r\n"));
		return -1;
	}


	//disabling echo back from the modem
	LITTLE_DELAY;
	szRET = sim900_cmd_with_retstring(PSTR("ATE0\r\n"),PGM_STRING);
	//sim900_wait_retstring();
	
	if(szRET!=sz_OK) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) this sim900 doesn't support ATE0\r\n"));
	} else {
		debug_string_P(VERBOSE,PSTR("(SIM900_init) correctly issued ATE0\r\n"));
	}
	

	LITTLE_DELAY;
	szRET = sim900_cmd_with_retstring(PSTR("AT+CREG=0\r\n"),PGM_STRING);

	if(szRET!=sz_OK) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) this sim900 doesn't support AT+CREG\r\n"));
		} else {
		debug_string_P(VERBOSE,PSTR("(SIM900_init) correctly issued AT+CREG=0\r\n"));
	}

	
	//get the IMEI code
	LITTLE_DELAY;
	szRET = sim900_cmd_with_retstring(PSTR("AT+GSN=?\r\n"),true);
	
	if(szRET!=sz_OK) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) this sim900 doesn't support AT+GSN\r\n"));
	}

	

	uint8_t i=IMEI_CODE_LEN;
	LITTLE_DELAY;
	sim900_cmd_with_read_string(PSTR("AT+GSN\r\n"),PGM_STRING,g_szIMEI,&i);
	sim900_wait_retstring();

	debug_string_P(NORMAL,PSTR("IMEI code is : "));
	debug_string(NORMAL,g_szIMEI,RAM_STRING);
	debug_string_P(NORMAL,szCRLF);

	if(szRET!=sz_OK) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) AT+GSN messed up\r\n"));
	} else {
		debug_string_P(NORMAL,PSTR("(SIM900_init) AT+GSN GOT OK\r\n"));
	}


	LITTLE_DELAY;
	sim900_put_string(PSTR("AT+CPIN=?\r\n"),PGM_STRING);
	szRET = sim900_wait_retstring();
	
	if(szRET!=sz_OK) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) SIM is not present\r\n"));
		return 1;
	}
	

	LITTLE_DELAY;
	sim900_put_string(PSTR("AT+CPIN?\r\n"),PGM_STRING);
	szRET = sim900_wait4dictionary(tbl_CPIN_rets,NUM_OF_CPIN_RETURNS);

	char szBuf[16];

	
	if(szRET==szCPIN_SIM_PIN) {
		debug_string_P(NORMAL,PSTR("(SIM900_init) SIM present and is PIN locked\r\n"));

		cfg_get_sim_pin(szBuf,8);
		if((szBuf[0]==0xFF) || (szBuf[0]==0x00)) {		
			debug_string_P(NORMAL,PSTR("(SIM900_init) PIN code is not present in memory SIM will remain locked\r\n"));
			return 3;
		} else {
			debug_string_P(NORMAL,PSTR("(SIM900_init) PIN code is present in memory trying to unlock\r\nPIN: "));
			debug_string(NORMAL,szBuf,RAM_STRING);
			debug_string_P(NORMAL,szCRLF);
			LITTLE_DELAY;
			sim900_put_string(PSTR("AT+CPIN="),PGM_STRING);
			sim900_put_string(szBuf,RAM_STRING);
			sim900_put_string(szCRLF,PGM_STRING);
			const char * ret = sim900_wait_retstring();
			if(ret!=sz_OK) {
				debug_string_P(NORMAL,PSTR("(sim900_init) WARNING PIN is WRONG\r\n"));
				return 3;
			}
		}
	} else if (szRET==szCPIN_SIM_PUK)
	{
		debug_string_P(NORMAL,PSTR("(SIM900_init) SIM present and is PUK locked\r\n"));
		debug_string_P(NORMAL,PSTR("(SIM900_init) no PUK code, SIM init will fail here\r\n"));
		return 4;
	}
	

	for(i=0;i<18;++i) {
		statusled_blink(1);
		
		LITTLE_DELAY;
		sim900_put_string(PSTR("AT+CREG?\r\n"),PGM_STRING);

		uint8_t l = 16;
		memset(szBuf,0,16);
		sim900_read_string(szBuf,&l);
		if(strncasecmp_P(szBuf,PSTR("+CREG: 1,1"),5)!=0) {
			debug_string_P(NORMAL,PSTR("(SIM900_init) device is not answering as it should restarting it\r\n"));
			goto init_sim;
		}
		if(szBuf[9]=='1') {
			debug_string_P(NORMAL,PSTR("(SIM900_init) device correctly registered in the network\r\n"));
			break;
		}
		debug_string_P(NORMAL,PSTR("(SIM900_init) device answered "));
		debug_string(NORMAL,szBuf,RAM_STRING);
		debug_string_P(NORMAL,PSTR(" seems not registered in the network\r\n"));
		debug_string_P(NORMAL,PSTR("(SIM900_init) will check again in 5 second\r\n"));
		delay_ms(5000);
	}


	return 0;
}
示例#13
0
unsigned char rules_create_httpd_data(unsigned char** new_page_pointer, char *var_conversion_buffer,unsigned char *eth_buffer,unsigned int *pos){

	unsigned int a=*pos;
	unsigned char str_len;

//	eth_buffer[TCP_DATA_START + a++] = 'n';

			if (strncasecmp_P("RULES",*new_page_pointer,5)==0)
			{

				int count=get_rule_count();

				if(rule == 0){
					//Rule Count
					strcpy_P(var_conversion_buffer, PSTR("Rule Count:"));
					str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);


					itoa(count,var_conversion_buffer,10);
					str_len = strnlen(var_conversion_buffer,10);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);


					strcpy_P(var_conversion_buffer, PSTR("<br>"));
					str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);

					eth_buffer[TCP_DATA_START + a++] = '\r';
					eth_buffer[TCP_DATA_START + a++] = '\n';
				}


				RULES_STRUCTUR cur_rul;

				while( (rule<count) && (a<(MTU_SIZE-(TCP_DATA_START)-10)) ){

					//Rule
					itoa(rule,var_conversion_buffer,10);
					str_len = strnlen(var_conversion_buffer,10);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);

					eth_buffer[TCP_DATA_START + a++] = '[';

					itoa(RULES_EEPROM_STORE+1+(rule*sizeof(RULES_STRUCTUR)),var_conversion_buffer,10);
					str_len = strnlen(var_conversion_buffer,10);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);

					eth_buffer[TCP_DATA_START + a++] = ']';

					eth_buffer[TCP_DATA_START + a++] = ':';
					eth_buffer[TCP_DATA_START + a++] = ' ';

					if(eeprom_get_rule(rule,&cur_rul)){


						strcpy_P(var_conversion_buffer, PSTR("if("));
						str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
						memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
						a = a + (str_len);


						eth_buffer[TCP_DATA_START + a++] = cur_rul.elem_A;

						itoa(cur_rul.elem_A_ID,var_conversion_buffer,10);
						str_len = strnlen(var_conversion_buffer,10);
						memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
						a = a + (str_len);

						eth_buffer[TCP_DATA_START + a++] = cur_rul.actor;

						eth_buffer[TCP_DATA_START + a++] = cur_rul.elem_B;



						itoa(cur_rul.elem_B_ID,var_conversion_buffer,10);
						str_len = strnlen(var_conversion_buffer,10);
						memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
						a = a + (str_len);

						strcpy_P(var_conversion_buffer, PSTR(") then"));
						str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
						memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
						a = a + (str_len);

					}
					rule++;

					strcpy_P(var_conversion_buffer, PSTR("<br>"));
					str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
					memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
					a = a + (str_len);

					eth_buffer[TCP_DATA_START + a++] = '\r';
					eth_buffer[TCP_DATA_START + a++] = '\n';

					*new_page_pointer = *new_page_pointer-1;
					a--;
					*pos = a;
					return 1;


				}

				if(rule>count || count == 0)
				{
					//end of operation
					*new_page_pointer = *new_page_pointer + 5;
					a--;
					*pos = a;
					rule=0;
					return 1;

				}
			}
return 0;
}
示例#14
0
void
httpd_handle_solometer (void)
{
  static int8_t i = 0;
  static uint8_t cont_send = 0, parsing = 0;
  uint16_t mss,page_size;
  static uip_ipaddr_t hostaddr, dnsserver;
  //char *buf;
  static uint16_t ppos;
  uint16_t lpos,wslen;
  uint8_t p_par,pct,send_packet,buf[64];

  uip_gethostaddr(&hostaddr);
#ifdef DNS_SUPPORT
  eeprom_restore(dns_server, &dnsserver, IPADDR_LEN);
#endif

  #define NUM_PAR 16
  PARAM p[NUM_PAR] = {
	      {PR_U8,"%u",(uint8_t *)&hostaddr},
	      {PR_U8,"%u",((uint8_t *)&hostaddr)+1},
	      {PR_U8,"%u",((uint8_t *)&hostaddr)+2},
	      {PR_U8,"%u",((uint8_t *)&hostaddr)+3},
	      {PR_U8,"%u",&WRID[0]},
	      {PR_STRING,"%s",post_cookie},
	      {PR_STRING,"%s",post_hostname},
	      {PR_U8,"%u",(uint8_t *)&post_hostip},
	      {PR_U8,"%u",((uint8_t *)&post_hostip)+1},
	      {PR_U8,"%u",((uint8_t *)&post_hostip)+2},
	      {PR_U8,"%u",((uint8_t *)&post_hostip)+3},
	      {PR_STRING,"%s",post_scriptname},
	      {PR_U8,"%u",(uint8_t *)&dnsserver},
	      {PR_U8,"%u",((uint8_t *)&dnsserver)+1},
	      {PR_U8,"%u",((uint8_t *)&dnsserver)+2},
	      {PR_U8,"%u",((uint8_t *)&dnsserver)+3}
  };

  //debug_printf("Handle_solometer called.\n");
  mss = uip_mss();
  if(mss > 400)
    mss = 400;
  wslen = strlen_P(website);
  
  if (uip_newdata()) {
    /* We've received new data (maybe even the first time).  We'll
      receive something like this:
      GET /solometer[?...]
    */
    /* Make sure it's zero-terminated, so we can safely use strstr */
    char *ptr = (char *)uip_appdata;
    ptr[uip_len] = 0;

    //debug_printf("Newdata: ---------\n%s\n-----------\n",ptr);

    if(strncasecmp_P (uip_appdata, PSTR ("GET /solometer"),14) == 0) {
      //debug_printf("This is the GET request header...\n");
      ptr = strstr_P (uip_appdata, PSTR("?")) + 1;
      if(!ptr || *ptr == 0) {
	//debug_printf("This is a request only. Send page.\n");
	i = 0;
      } else {
	//debug_printf("This is a set operation. Parsing...\n");
	i = solometer_parse(ptr);
      }
      //debug_printf("Setze Parsing auf 1.\n");
      parsing = 1;
    }
    
    if (parsing == 1) {
      // Do not start answering until all packets have arrived
      //debug_printf("Parsing = 1\n");
      ptr = strstr_P (uip_appdata, PSTR("\r\n\r\n"));
      if (ptr) {
	//debug_printf("Setze Parsing auf 2.\n");
	parsing = 2;
      } else {
	//debug_printf("Double NL not found. Waiting...\n");
	return;
      }
    }
    
    if (parsing == 2) {
      //debug_printf("Parsing = 2. Sende Antwort.\n");
      PASTE_RESET ();
      if(i || mss < 200) {
	PASTE_P (httpd_header_500_smt);
	cont_send = 0;
      } else {
	page_size = wslen);
	for(i=0;i<NUM_PAR;i++)
	  if(p[i].typ == PR_STRING)
	    page_size += sprintf(buf,p[i].s2,p[i].s3);
	  else
	    page_size += sprintf(buf,p[i].s2,*(uint8_t *)p[i].s3);
	PASTE_P (p1);
	sprintf(uip_appdata+uip_len,"%u\n",page_size);
	PASTE_P (p2);
	cont_send = 1;
	ppos = 0;
      }
      //debug_printf("%d: %s\n",cont_send,uip_appdata);
      PASTE_SEND ();
      parsing = 0;
      return;
    }
  }