Example #1
0
// Find a variable by name.
//
AP_Param *
AP_Param::find(const char *name, enum ap_var_type *ptype)
{
    for (uint8_t i=0; i<_num_vars; i++) {
        uint8_t type = PGM_UINT8(&_var_info[i].type);
        if (type == AP_PARAM_GROUP) {
            uint8_t len = strnlen_P(_var_info[i].name, AP_MAX_NAME_SIZE);
            if (strncmp_P(name, _var_info[i].name, len) != 0) {
                continue;
            }
            const struct GroupInfo *group_info = (const struct GroupInfo *)PGM_POINTER(&_var_info[i].group_info);
            AP_Param *ap = find_group(name + len, i, group_info, ptype);
            if (ap != NULL) {
                return ap;
            }
            // we continue looking as we want to allow top level
            // parameter to have the same prefix name as group
            // parameters, for example CAM_P_G
        } else if (strcasecmp_P(name, _var_info[i].name) == 0) {
            *ptype = (enum ap_var_type)type;
            return (AP_Param *)PGM_POINTER(&_var_info[i].ptr);
        }
    }
    return NULL;
}
Example #2
0
// Find a variable by name in a group
AP_Param *
AP_Param::find_group(const char *name, uint8_t vindex, const struct GroupInfo *group_info, enum ap_var_type *ptype)
{
    uint8_t type;
    for (uint8_t i=0;
         (type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
         i++) {
#ifdef AP_NESTED_GROUPS_ENABLED
        if (type == AP_PARAM_GROUP) {
            const struct GroupInfo *ginfo = (const struct GroupInfo *)PGM_POINTER(&group_info[i].group_info);
            AP_Param *ap = find_group(name, vindex, ginfo, ptype);
            if (ap != NULL) {
                return ap;
            }
        } else
#endif // AP_NESTED_GROUPS_ENABLED
        if (strcasecmp_P(name, group_info[i].name) == 0) {
            uintptr_t p = PGM_POINTER(&_var_info[vindex].ptr);
            *ptype = (enum ap_var_type)type;
            return (AP_Param *)(p + PGM_POINTER(&group_info[i].offset));
        } else if (type == AP_PARAM_VECTOR3F) {
            // special case for finding Vector3f elements
            uint8_t suffix_len = strnlen_P(group_info[i].name, AP_MAX_NAME_SIZE);
            if (strncmp_P(name, group_info[i].name, suffix_len) == 0 &&
                name[suffix_len] == '_' &&
                (name[suffix_len+1] == 'X' ||
                 name[suffix_len+1] == 'Y' ||
                 name[suffix_len+1] == 'Z')) {
                uintptr_t p = PGM_POINTER(&_var_info[vindex].ptr);
                AP_Float *v = (AP_Float *)(p + PGM_POINTER(&group_info[i].offset));
                *ptype = AP_PARAM_FLOAT;
                switch (name[suffix_len+1]) {
                case 'X':
                    return (AP_Float *)&v[0];
                case 'Y':
                    return (AP_Float *)&v[1];
                case 'Z':
                    return (AP_Float *)&v[2];
                }
            }
        }
    }
    return NULL;
}
Example #3
0
void
BetterStream::_vprintf (unsigned char in_progmem, const char *fmt, va_list ap)
{
        unsigned char c;        /* holds a char from the format string */
        unsigned char flags;
        unsigned char width;
        unsigned char prec;
        unsigned char buf[11];  /* size for -1 in octal, without '\0'   */

        for (;;) {

                /*
                 * Process non-format characters
                 */
                for (;;) {
                        c = GETBYTE (in_progmem, 1, fmt);
                        if (!c) return;
                        if (c == '%') {
                                c = GETBYTE (in_progmem, 1, fmt);
                                if (c != '%') break;
                        }
                        /* emit cr before lf to make most terminals happy */
                        if (c == '\n')
                                write('\r');
                        write(c);
                }

                flags = 0;
                width = 0;
                prec = 0;
                
                /*
                 * Process format adjustment characters, precision, width.
                 */
                do {
                        if (flags < FL_WIDTH) {
                                switch (c) {
                                case '0':
                                        flags |= FL_ZFILL;
                                        continue;
                                case '+':
                                        flags |= FL_PLUS;
                                        /* FALLTHROUGH */
                                case ' ':
                                        flags |= FL_SPACE;
                                        continue;
                                case '-':
                                        flags |= FL_LPAD;
                                        continue;
                                case '#':
                                        flags |= FL_ALT;
                                        continue;
                                }
                        }

                        if (flags < FL_LONG) {
                                if (c >= '0' && c <= '9') {
                                        c -= '0';
                                        if (flags & FL_PREC) {
                                                prec = 10*prec + c;
                                                continue;
                                        }
                                        width = 10*width + c;
                                        flags |= FL_WIDTH;
                                        continue;
                                }
                                if (c == '.') {
                                        if (flags & FL_PREC)
                                                return;
                                        flags |= FL_PREC;
                                        continue;
                                }
                                if (c == 'l') {
                                        flags |= FL_LONG;
                                        continue;
                                }
                                if (c == 'h')
                                        continue;
                        }
            
                        break;
                } while ( (c = GETBYTE (in_progmem, 1, fmt)) != 0);

                /*
                 * Handle floating-point formats E, F, G, e, f, g.
                 */
                if (c >= 'E' && c <= 'G') {
                        flags |= FL_FLTUPP;
                        c += 'e' - 'E';
                        goto flt_oper;

                } else if (c >= 'e' && c <= 'g') {

                        int exp;                /* exponent of master decimal digit     */
                        int n;
                        unsigned char vtype;    /* result of float value parse  */
                        unsigned char sign;     /* sign character (or 0)        */
                        unsigned char ndigs;

                        flags &= ~FL_FLTUPP;

                flt_oper:
                        if (!(flags & FL_PREC))
                                prec = 6;
                        flags &= ~(FL_FLTEXP | FL_FLTFIX);
                        if (c == 'e')
                                flags |= FL_FLTEXP;
                        else if (c == 'f')
                                flags |= FL_FLTFIX;
                        else if (prec > 0)
                                prec -= 1;

                        if (flags & FL_FLTFIX) {
                                vtype = 7;              /* 'prec' arg for 'ftoa_engine' */
                                ndigs = prec < 60 ? prec + 1 : 60;
                        } else {
                                if (prec > 7) prec = 7;
                                vtype = prec;
                                ndigs = 0;
                        }
                        exp = __ftoa_engine (va_arg(ap,double), (char *)buf, vtype, ndigs);
                        vtype = buf[0];
    
                        sign = 0;
                        if ((vtype & FTOA_MINUS) && !(vtype & FTOA_NAN))
                                sign = '-';
                        else if (flags & FL_PLUS)
                                sign = '+';
                        else if (flags & FL_SPACE)
                                sign = ' ';

                        if (vtype & (FTOA_NAN | FTOA_INF)) {
                                const char *p;
                                ndigs = sign ? 4 : 3;
                                if (width > ndigs) {
                                        width -= ndigs;
                                        if (!(flags & FL_LPAD)) {
                                                do {
                                                        write(' ');
                                                } while (--width);
                                        }
                                } else {
                                        width = 0;
                                }
                                if (sign)
                                        write(sign);
                                p = PSTR("inf");
                                if (vtype & FTOA_NAN)
                                        p = PSTR("nan");
                                while ( (ndigs = pgm_read_byte((const prog_char *)p)) != 0) {
                                        if (flags & FL_FLTUPP)
                                                ndigs += 'I' - 'i';
                                        write(ndigs);
                                        p++;
                                }
                                goto tail;
                        }

                        /* Output format adjustment, number of decimal digits in buf[] */
                        if (flags & FL_FLTFIX) {
                                ndigs += exp;
                                if ((vtype & FTOA_CARRY) && buf[1] == '1')
                                        ndigs -= 1;
                                if ((signed char)ndigs < 1)
                                        ndigs = 1;
                                else if (ndigs > 8)
                                        ndigs = 8;
                        } else if (!(flags & FL_FLTEXP)) {              /* 'g(G)' format */
                                if (exp <= prec && exp >= -4)
                                        flags |= FL_FLTFIX;
                                while (prec && buf[1+prec] == '0')
                                        prec--;
                                if (flags & FL_FLTFIX) {
                                        ndigs = prec + 1;               /* number of digits in buf */
                                        prec = prec > exp
                                                ? prec - exp : 0;       /* fractional part length  */
                                }
                        }
    
                        /* Conversion result length, width := free space length */
                        if (flags & FL_FLTFIX)
                                n = (exp>0 ? exp+1 : 1);
                        else
                                n = 5;          /* 1e+00 */
                        if (sign) n += 1;
                        if (prec) n += prec + 1;
                        width = width > n ? width - n : 0;
    
                        /* Output before first digit    */
                        if (!(flags & (FL_LPAD | FL_ZFILL))) {
                                while (width) {
                                        write(' ');
                                        width--;
                                }
                        }
                        if (sign) write(sign);
                        if (!(flags & FL_LPAD)) {
                                while (width) {
                                        write('0');
                                        width--;
                                }
                        }
    
                        if (flags & FL_FLTFIX) {                /* 'f' format           */

                                n = exp > 0 ? exp : 0;          /* exponent of left digit */
                                do {
                                        if (n == -1)
                                                write('.');
                                        flags = (n <= exp && n > exp - ndigs)
                                                ? buf[exp - n + 1] : '0';
                                        if (--n < -prec)
                                                break;
                                        write(flags);
                                } while (1);
                                if (n == exp
                                    && (buf[1] > '5'
                                        || (buf[1] == '5' && !(vtype & FTOA_CARRY))) )
                                        {
                                                flags = '1';
                                        }
                                write(flags);
        
                        } else {                                /* 'e(E)' format        */

                                /* mantissa     */
                                if (buf[1] != '1')
                                        vtype &= ~FTOA_CARRY;
                                write(buf[1]);
                                if (prec) {
                                        write('.');
                                        sign = 2;
                                        do {
                                                write(buf[sign++]);
                                        } while (--prec);
                                }

                                /* exponent     */
                                write(flags & FL_FLTUPP ? 'E' : 'e');
                                ndigs = '+';
                                if (exp < 0 || (exp == 0 && (vtype & FTOA_CARRY) != 0)) {
                                        exp = -exp;
                                        ndigs = '-';
                                }
                                write(ndigs);
                                for (ndigs = '0'; exp >= 10; exp -= 10)
                                        ndigs += 1;
                                write(ndigs);
                                write('0' + exp);
                        }

                        goto tail;
                }

                /*
                 * Handle string formats c, s, S.
                 */
                {
                        const char * pnt;
                        size_t size;

                        switch (c) {

                        case 'c':
                                buf[0] = va_arg (ap, int);
                                pnt = (char *)buf;
                                size = 1;
                                goto no_pgmstring;

                        case 's':
                                pnt = va_arg (ap, char *);
                                size = strnlen (pnt, (flags & FL_PREC) ? prec : ~0);
                        no_pgmstring:
                                flags &= ~FL_PGMSTRING;
                                goto str_lpad;

                        case 'S':
                        // pgmstring: // not yet used
                                pnt = va_arg (ap, char *);
                                size = strnlen_P (pnt, (flags & FL_PREC) ? prec : ~0);
                                flags |= FL_PGMSTRING;

                        str_lpad:
                                if (!(flags & FL_LPAD)) {
                                        while (size < width) {
                                                write(' ');
                                                width--;
                                        }
                                }
                                while (size) {
                                        write(GETBYTE (flags, FL_PGMSTRING, pnt));
                                        if (width) width -= 1;
                                        size -= 1;
                                }
                                goto tail;
                        }
                }

                /*
                 * Handle integer formats variations for d/i, u, o, p, x, X.
                 */
                if (c == 'd' || c == 'i') {
                        long x = (flags & FL_LONG) ? va_arg(ap,long) : va_arg(ap,int);
                        flags &= ~(FL_NEGATIVE | FL_ALT);
                        if (x < 0) {
                                x = -x;
                                flags |= FL_NEGATIVE;
                        }
                        c = __ultoa_invert (x, (char *)buf, 10) - (char *)buf;

                } else {
/**
 @brief	Analyse HTTP request and then services WEB.
*/
void process_HTTP(
	SOCKET s, 			/**< http server socket */
	uint8_t * buffer, 	/**< buffer pointer included http request */
	uint16_t length		/**< length of http request */
	)
{
	uint8_t * name;
	uint16_t bytes_read;
	TickType_t wait_send;
	FIL source_file;	/* File object for the source file */

	parse_HTTP_request(pHTTPRequest, buffer);			// After analysing request, convert into pHTTPRequest

	/* method Analyse */
	switch (pHTTPRequest->METHOD)
	{
		case METHOD_HEAD:
		case METHOD_GET :
		case METHOD_POST :

			name = get_HTTP_URI_name(pHTTPRequest->URI);

			if (!strcmp((const char *)name, "/")) strcpy((char *)name,"index.htm");	// If URI is "/", respond by index.htm

#ifdef WEB_DEBUG
			if(strlen( (const char *)name) < MAX_INT_STR ) xSerialPrintf_P(PSTR("\r\nPAGE : %s "), name);
			else xSerialPrint_P(PSTR("\r\nFILENAME TOO LONG"));
#endif

			find_HTTP_URI_type(&pHTTPRequest->TYPE, name);	//Check file type (HTML, TEXT, ICO, GIF, JPEG, ZIP are included)

			// OK now we start to respond to the info we've decoded.

			/* Open the specified file stored in the SD card FAT32 */
			if (f_open(&source_file, (const TCHAR *)name, FA_OPEN_EXISTING | FA_READ))
			{	// if file open failure

				memcpy_P( (char *)pHTTPResponse, ERROR_HTML_PAGE, strnlen_P(ERROR_HTML_PAGE, FILE_BUFFER_SIZE) );

#ifdef WEB_DEBUG
				xSerialPrint_P(PSTR("HTTP Unknown file or page.\r\n"));
				xSerialPrintf_P(PSTR("HTTP Response...\r\n%s\r\nResponse Size: %u \r\n"), pHTTPResponse, strlen_P(ERROR_HTML_PAGE));
#endif

				send( s, (const uint8_t*)pHTTPResponse, strlen_P(ERROR_HTML_PAGE));

			}
			else
			{	// if file open success

				make_HTTP_response_header( pHTTPResponse, pHTTPRequest->TYPE, source_file.fsize);

#ifdef WEB_DEBUG
				xSerialPrintf_P(PSTR("HTTP Opened file: %s  Source Size: %u \r\n"), name, source_file.fsize);
				xSerialPrintf_P(PSTR("HTTP Response Header...\r\n%s\r\nResponse Header Size: %u \r\n"), pHTTPResponse, strlen((char*)pHTTPResponse ));
#endif

				send(s, (const uint8_t*)pHTTPResponse, strlen((char*)pHTTPResponse ));

				wait_send = xTaskGetTickCount();

				while(getSn_TX_FSR(s)!= WIZCHIP_getTxMAX(s))

				{
					if( (xTaskGetTickCount() - wait_send) > (WEBSERVER_SOCKET_TIMEOUT / portTICK_PERIOD_MS) ) // wait up to 1.5 Sec
					{
#ifdef WEB_DEBUG
						xSerialPrint_P(PSTR("HTTP Response head send fail\r\n"));
#endif
						break;
					}
					vTaskDelay( 0 ); // yield until next tick.
				}

				for (;;)
				{
					if ( f_read(&source_file, pHTTPResponse, (sizeof(uint8_t)*(FILE_BUFFER_SIZE) ), &bytes_read) || bytes_read == 0 )
						break;   // read error or reached end of file

					if(pHTTPRequest->TYPE == PTYPE_HTML) // if we've got a html document, there might be some system variables to set
					{
						*(pHTTPResponse + bytes_read + 1) = 0; // make the buffer a string, null terminated
						bytes_read = replace_sys_env_value(pHTTPResponse, bytes_read); // Replace html system environment value to real value
					}

					if (send(s, (const uint8_t*)pHTTPResponse, bytes_read) != bytes_read)
						break;  // TCP/IP send error

					wait_send = xTaskGetTickCount();

					while(getSn_TX_FSR(s)!= WIZCHIP_getTxMAX(s))

					{
						if( (xTaskGetTickCount() - wait_send) > (WEBSERVER_SOCKET_TIMEOUT / portTICK_PERIOD_MS) ) // wait up to 1.5 Sec
						{
#ifdef WEB_DEBUG
							xSerialPrint_P(PSTR("HTTP Response body send fail\r\n"));
#endif
							break;
						}
						vTaskDelay( 0 ); // yield until next tick.
					}
				}
				f_close(&source_file);

				eeprom_busy_wait();
				eeprom_update_dword( &pagesServed, eeprom_read_dword(&pagesServed) +1 );
			}
			break;

		case METHOD_ERR :

			memcpy_P( (char *)pHTTPResponse, ERROR_REQUEST_PAGE, strnlen_P(ERROR_REQUEST_PAGE, FILE_BUFFER_SIZE) );

#ifdef WEB_DEBUG
			xSerialPrint_P(PSTR("HTTP Method Error.\r\n"));
			xSerialPrintf_P(PSTR("HTTP Response...\r\n%s\r\nResponse Size: %u \r\n"), pHTTPResponse, strlen_P(ERROR_REQUEST_PAGE));
#endif

			send( s, (const uint8_t*)pHTTPResponse, strlen_P(ERROR_REQUEST_PAGE));

			break;

		default :
			break;
	}
}