Ejemplo n.º 1
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_string                                                *
 *                                                                            *
 * Purpose: Parses JSON string value or object name                           *
 *                                                                            *
 * Parameters: start - [IN] the JSON data without leading whitespace          *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
static int	json_parse_string(const char *start, char **error)
{
	const char	*ptr = start;

	/* skip starting '"' */
	ptr++;

	while ('"' != *ptr)
	{
		/* unexpected end of string data, failing */
		if ('\0' == *ptr)
			return json_error("unexpected end of string data", NULL, error);

		if ('\\' == *ptr)
		{
			const char	*escape_start = ptr;
			int		i;

			/* unexpected end of string data, failing */
			if ('\0' == *(++ptr))
				return json_error("invalid escape sequence in string", escape_start, error);

			switch (*ptr)
			{
				case '"':
				case '\\':
				case '/':
				case 'b':
				case 'f':
				case 'n':
				case 'r':
				case 't':
					break;
				case 'u':
					/* check if the \u is followed with 4 hex digits */
					for (i = 0; i < 4; i++)
					{
						if (0 == isxdigit((unsigned char)*(++ptr)))
						{
							return json_error("invalid escape sequence in string",
									escape_start, error);
						}
					}

					break;
				default:
					return json_error("invalid escape sequence in string data",
							escape_start, error);
			}
		}

		/* found control character in string, failing */
		if (0 != iscntrl((unsigned char)*ptr))
			return json_error("invalid control character in string data", ptr, error);

		ptr++;
	}

	return ptr - start + 1;
}
Ejemplo n.º 2
0
static JSON *json_parse_array(struct lexer *lx) {
	
	JSON *v = malloc(sizeof *v);
	v->type = j_array;
	v->value = NULL;
	v->next = NULL;
	
	JSON *tail = NULL;
	
	if(!lx_expect(lx, '[')) {
		json_error("line %d: %s", lx_lineno(lx), lx_text(lx));
		return NULL;
	}
	if(lx_sym(lx) != ']') {
		do {		
			JSON *value = json_parse_value(lx);
			if(!value) 
				return NULL;
			if(v->value) {
				assert(tail);
				tail->next = value;			
			} else {
				v->value = value;
			}	
			tail = value;
			
		} while(lx_accept(lx, ','));
	}
	if(!lx_expect(lx, ']')) {
		json_error("line %d: %s", lx_lineno(lx), lx_text(lx));
		return NULL;
	}
	
	return v;
}
Ejemplo n.º 3
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_number                                                *
 *                                                                            *
 * Purpose: Parses JSON number value                                          *
 *                                                                            *
 * Parameters: start - [IN] the JSON data without leading whitespace          *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
static int	json_parse_number(const char *start, char **error)
{
	const char	*ptr = start;
	char		first_digit;
	int		point = 0, digit = 0;

	if ('-' == *ptr)
		ptr++;

	first_digit = *ptr;

	while ('\0' != *ptr)
	{
		if ('.' == *ptr)
		{
			if (0 != point)
				break;
			point = 1;
		}
		else if (0 == isdigit((unsigned char)*ptr))
			break;

		ptr++;
		if (0 == point)
			digit++;
	}

	/* number does not contain any digits, failing */
	if (0 == digit)
		return json_error("invalid numeric value format", start, error);

	/* number has zero leading digit following by other digits, failing */
	if ('0' == first_digit && 1 < digit)
		return json_error("invalid numeric value format", start, error);

	if ('e' == *ptr || 'E' == *ptr)
	{
		if ('\0' == *(++ptr))
			return json_error("unexpected end of numeric value", NULL, error);

		if ('+' == *ptr || '-' == *ptr)
		{
			if ('\0' == *(++ptr))
				return json_error("unexpected end of numeric value", NULL, error);
		}

		if (0 == isdigit((unsigned char)*ptr))
			return json_error("invalid power value of number in E notation", ptr, error);

		while ('\0' != *(++ptr))
		{
			if (0 == isdigit((unsigned char)*ptr))
				break;
		}
	}

	return ptr - start;
}
Ejemplo n.º 4
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_object                                                *
 *                                                                            *
 * Purpose: Parses JSON object                                                *
 *                                                                            *
 * Parameters: start - [IN] the JSON data                                     *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
static int	json_parse_object(const char *start, char **error)
{
	const char	*ptr = start;
	int		len;

	/* parse object name */
	SKIP_WHITESPACE(ptr);

	/* not an object, failing */
	if ('{' != *ptr)
		return json_error("invalid object format, expected opening character '{'", ptr, error);

	ptr++;
	SKIP_WHITESPACE(ptr);

	if ('}' != *ptr)
	{
		while (1)
		{
			if ('"' != *ptr)
				return json_error("invalid object name", ptr, error);

			/* cannot parse object name, failing */
			if (0 == (len = json_parse_string(ptr, error)))
				return 0;

			ptr += len;

			/* parse name:value separator */
			SKIP_WHITESPACE(ptr);

			if (':' != *ptr)
				return json_error("invalid object name/value separator", ptr, error);
			ptr++;

			if (0 == (len = json_parse_value(ptr, error)))
				return 0;

			ptr += len;

			SKIP_WHITESPACE(ptr);

			if (',' != *ptr)
				break;

			ptr++;
			SKIP_WHITESPACE(ptr);
		}

		/* object is not properly closed, failing */
		if ('}' != *ptr)
			return json_error("invalid object format, expected closing character '}'", ptr, error);
	}

	return ptr - start + 1;
}
Ejemplo n.º 5
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_value                                                 *
 *                                                                            *
 * Purpose: Parses JSON object value                                          *
 *                                                                            *
 * Parameters: start - [IN] the JSON data                                     *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
int	json_parse_value(const char *start, char **error)
{
	const char	*ptr = start;
	int		len;

	SKIP_WHITESPACE(ptr);

	switch (*ptr)
	{
		case '\0':
			return json_error("unexpected end of object value", NULL, error);
		case '"':
			if (0 == (len = json_parse_string(ptr, error)))
				return 0;
			break;
		case '{':
			if (0 == (len = json_parse_object(ptr, error)))
				return 0;
			break;
		case '[':
			if (0 == (len = json_parse_array(ptr, error)))
				return 0;
			break;
		case 't':
			if (0 == (len = json_parse_literal(ptr, "true", error)))
				return 0;
			break;
		case 'f':
			if (0 == (len = json_parse_literal(ptr, "false", error)))
				return 0;
			break;
		case 'n':
			if (0 == (len = json_parse_literal(ptr, "null", error)))
				return 0;
			break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case '-':
			if (0 == (len = json_parse_number(ptr, error)))
				return 0;
			break;
		default:
			return json_error("invalid JSON object value starting character", ptr, error);
	}

	return ptr - start + len;
}
Ejemplo n.º 6
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_array                                                 *
 *                                                                            *
 * Purpose: Parses JSON array value                                           *
 *                                                                            *
 * Parameters: start - [IN] the JSON data without leading whitespace          *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
static int	json_parse_array(const char *start, char **error)
{
	const char	*ptr = start;
	int		len;

	ptr++;
	SKIP_WHITESPACE(ptr);

	if (']' != *ptr)
	{
		while (1)
		{
			/* json_parse_value strips leading whitespace, so we don't have to do it here */
			if (0 == (len = json_parse_value(ptr, error)))
				return 0;

			ptr += len;
			SKIP_WHITESPACE(ptr);

			if (',' != *ptr)
				break;

			ptr++;
		}

		/* no closing ], failing */
		if (']' != *ptr)
			return json_error("invalid array format, expected closing character ']'", ptr, error);
	}

	return ptr - start + 1;
}
Ejemplo n.º 7
0
LOCAL void ICACHE_FLASH_ATTR finger_default(finger_packet *packet) {
	if (packet->pid == FINGER_ACK && packet->data[0] != FINGER_OK) {
		char response[WEBSERVER_MAX_VALUE];
		json_error(response, MOD_FINGER, finger_error_str(packet->data[0]), NULL);
		user_event_raise(FINGER_URL, response);
	}
}
Ejemplo n.º 8
0
LOCAL void ICACHE_FLASH_ATTR finger_timeout(finger_packet *packet) {
	char response[WEBSERVER_MAX_VALUE];
	finger_clear_timeout(packet);
	json_error(response, MOD_FINGER, TIMEOUT, NULL);
	user_event_raise(FINGER_URL, response);
	finger_start_read();
}
Ejemplo n.º 9
0
void PredicateChecker::pop_path()
{
    if(m_path_sizes.empty())
    {
        return;
    }

    size_t count = m_path_sizes.top();
    m_path_sizes.pop();

    if(m_path.size() < count || m_path.size() != m_mode.size())
    {
        throw json_error("invalid state");
    }

    for(size_t i = 0; i < count; ++i)
    {
        if(m_mode.back() != predicate_mode::NORMAL)
        {
            if(!m_pred_matches)
            {
                m_matched = false;
            }
        }

        m_path.pop_back();
        m_mode.pop_back();
    }
}
Ejemplo n.º 10
0
static void 
validate_keyword(char* expected_key, struct json_string_ex_s* key, char *json, struct json_error_info err_info){
    if (strcmp(expected_key, (char*) key->string.string) != 0){
        json_set_error_info(&err_info, INVALID_KEYWORD, key->line_no, key->row_no, (char*) key->string.string);
        json_error(json, err_info);
    }
}
Ejemplo n.º 11
0
LOCAL void ICACHE_FLASH_ATTR mod_tc_mk2_read(i2c_config *config, char *response, bool poll) {
	poll = true;
	
	tc_config_data *config_data = (tc_config_data *)config->data;
	
	char address_str[MAX_I2C_ADDRESS];
	json_i2c_address(address_str, config->address);
	
	i2c_status status = tc_read(config);
	if (status == I2C_OK) {
		char poll_str[WEBSERVER_MAX_VALUE];
		if (poll) {
			json_poll_str(poll_str, tc_refresh / 1000, tc_each, tc_threshold);
		} else {
			poll_str[0] = '\0';
		}
		
		char data_str[WEBSERVER_MAX_VALUE];
		json_data(
			response, MOD_TC_MK2, OK_STR,
			json_sprintf(
				data_str,
				"\"Temperature\" : %s %s",
				config_data->temperature_str,
				poll_str
			),
			address_str
		);
	} else {
		json_error(response, MOD_TC_MK2, i2c_status_str(status), address_str);
	}
}
Ejemplo n.º 12
0
/**
 * \brief Recognizes a named token.
 *
 * \param reader The reader.
 * \param token The token code that we expect to recognize.
 * \param name The name of the token.  The first character is assumed
 * to have already been recognized.
 */
static void json_named_token
    (JSONReader *reader, JSONToken token, const char *name)
{
    const char *n = name + 1;
    int ch;
    for (;;) {
        ch = getc(reader->stream);
        if (*n == '\0') {
            if (ch == ',' || ch == ' ' || ch == '\t' ||
                    ch == '\r' || ch == '\n') {
                ungetc(ch, reader->stream);
                reader->token = token;
                return;
            } else if (ch == EOF) {
                reader->token = token;
                reader->saw_eof = 1;
                return;
            } else {
                break;
            }
        }
        if (ch == EOF || ch != *n)
            break;
        ++n;
    }
    json_error(reader, "Could not recognize '%s' token", name);
    reader->token = JSON_TOKEN_END;
}
Ejemplo n.º 13
0
LOCAL void ICACHE_FLASH_ATTR emtr_timeout() {
	char response[WEBSERVER_MAX_VALUE];
	json_error(response, MOD_EMTR, TIMEOUT, NULL);
	user_event_raise(EMTR_URL, response);
	
	emtr_clear_timeout();
	emtr_start_read();
}
Ejemplo n.º 14
0
static JSON *json_parse_object(struct lexer *lx) {
	
	Hash_Tbl *h = ht_create (16);
	JSON *v = malloc(sizeof *v);
	v->type = j_object;
	v->value = h;
	v->next = NULL;
	
	if(!lx_expect(lx, '{')) {
		json_error("line %d: %s", lx_lineno(lx), lx_text(lx));
		free(v);
		return NULL;
	}
	if(lx_sym(lx) != '}') {
		do {
			char *key;
			JSON *value;
			lx_accept(lx, LX_STRING);
			key = strdup(lx_text(lx));
			lx_accept(lx, ':');		
			value = json_parse_value(lx);
			if(!value) {
				free(key);
				free(v);
				return NULL;
			}
			
			ht_put (h, key, value);
			
			free(key);	
			
		} while(lx_accept(lx, ','));
	}
	if(!lx_expect(lx, '}')) {
		json_error("line %d: %s", lx_lineno(lx), lx_text(lx));
		free(v);
		return NULL;
	}
		
	return v;
}
Ejemplo n.º 15
0
static JSON *json_parse_value(struct lexer *lx) {
	if(lx_sym(lx) == '{')
		return json_parse_object(lx);	
	else if(lx_sym(lx) == '[')
		return json_parse_array(lx);
	else {
		JSON *v = malloc(sizeof *v);
		v->type = j_null;
		v->value = NULL;
		v->next = NULL;
		if(lx_sym(lx) == LX_NUMBER || lx_sym(lx) == '-') {
			v->type = j_number;
			if(lx_sym(lx) == '-') {
				lx_getsym(lx);
				char *val = malloc(strlen(lx_text(lx)) + 2);
				sprintf(val, "-%s", lx_text(lx));
				v->value = val;
			} else
				v->value = strdup(lx_text(lx));
		} else if(lx_sym(lx) == LX_STRING) {
			v->type = j_string;
			v->value = strdup(lx_text(lx));
		} else if(lx_sym(lx) == J_TRUE) {
			v->type = j_true;
		} else if(lx_sym(lx) == J_FALSE) {
			v->type = j_false;
		}else if(lx_sym(lx) == J_NULL) {
			v->type = j_null;
		} else {
			if(isprint(lx_sym(lx))) {
				json_error("line %d: Unexpected operator: %c", lx_lineno(lx), lx_sym(lx));
			} else {
				json_error("line %d: Unexpected symbol type %d", lx_lineno(lx), lx_sym(lx));
			}
			return NULL;
		}
		lx_getsym(lx);	
		
		return v;
	}
}
Ejemplo n.º 16
0
/******************************************************************************
 *                                                                            *
 * Function: json_parse_literal                                               *
 *                                                                            *
 * Purpose: Parses the specified literal value                                *
 *                                                                            *
 * Parameters: start - [IN] the JSON data without leading whitespace          *
 *             text  - [IN] the literal value to parse                        *
 *             error - [OUT] the parsing error message (can be NULL)          *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 * Comments: This function is used to parse JSON literal values null, true    *
 *           false.                                                           *
 *                                                                            *
 ******************************************************************************/
static int	json_parse_literal(const char *start, const char *text, char **error)
{
	const char	*ptr = start;

	while ('\0' != *text)
	{
		if (*ptr != *text)
			return json_error("invalid literal value", start, error);
		ptr++;
		text++;
	}

	return ptr - start;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[]) {
	JSON *j;
	if(argc < 2) 
		return EXIT_FAILURE;
	j = json_read(argv[1]);
	if(!j) {
		json_error("Unable to parse %s", argv[1]);
		return EXIT_FAILURE;
	} else {
		json_dump(j);
		json_free(j);
		return EXIT_SUCCESS;
	}
}
Ejemplo n.º 18
0
static unsigned int
digit2int(lua_State *L, const unsigned char digit)
{
	unsigned int val;

	if (digit >= '0' && digit <= '9')
		val = digit - '0';
	else if (digit >= 'a' || digit <= 'f')
		val = digit - 'a' + 10;
	else if (digit >= 'A' || digit <= 'F')
		val = digit - 'A' + 10;
	else
		json_error(L, "Invalid hex digit");
	return val;
}
Ejemplo n.º 19
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_json_validate                                                *
 *                                                                            *
 * Purpose: Validates JSON object                                             *
 *                                                                            *
 * Parameters: start - [IN]  the string to validate                           *
 *             error - [OUT] the parse error message. If the error value is   *
 *                           set it must be freed by caller after it has      *
 *                           been used (can be NULL).                         *
 *                                                                            *
 * Return value: The number of characters parsed. On error 0 is returned and  *
 *               error parameter (if not NULL) contains allocated error       *
 *               message.                                                     *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
int	zbx_json_validate(const char *start, char **error)
{
	int	len;

	if (0 == (len = json_parse_object(start, error)))
		return 0;

	start += len;
	SKIP_WHITESPACE(start);

	if ('\0' != *start)
		return json_error("invalid character following JSON object", start, error);

	return len;
}
Ejemplo n.º 20
0
void ICACHE_FLASH_ATTR wifi_scan_get_result(char *response) {
	if (wifi_scan_in_progress) {
		webserver_set_status(0);
		return;
	}
	
	if (wifi_scan_ap_count == 0 || wifi_scan_result == NULL) {
		if (wifi_scan_start()) {
			webserver_set_status(0);
			return;
		}
		
		webserver_set_status(200);
		json_error(response, ESP8266, "Can not start scan", NULL);
		return;
	}
	
	webserver_set_status(200);
	
	char result[WEBSERVER_MAX_VALUE*wifi_scan_ap_count];
	os_memset(result, '\0', sizeof(result));
	
	uint8 i=0;
	for (i=0; i<wifi_scan_ap_count; i++) {
		os_sprintf(
			result + os_strlen(result), 
			"%s{\"SSID\" : \"%s\", \"Strength\" : %d, \"Mode\" : \"%s\"}", 
			i > 0 ? ", " : "",
			wifi_scan_result[i]->ssid, 
			wifi_scan_result[i]->rssi, 
			wifi_auth_mode_str(wifi_scan_result[i]->authmode)
		);
	}
	
	char data_str[WEBSERVER_MAX_VALUE*wifi_scan_ap_count];
	json_data(
		response, ESP8266, OK_STR,
		json_sprintf(
			data_str,
			"\"WiFi\" : [%s]",
			result
		),
		NULL
	);
}
/* Make response */
LOCAL void ICACHE_FLASH_ATTR mb_pcd8544_set_response(char *response, bool is_fault, uint8 req_type) {
	char data_str[WEBSERVER_MAX_RESPONSE_LEN];
	char full_device_name[USER_CONFIG_USER_SIZE];
	
	mb_make_full_device_name(full_device_name, MB_PCD8544_DEVICE, USER_CONFIG_USER_SIZE);
	
	MB_PCD8544_DEBUG("PCD8544:Resp.prep:%d;isFault:%d:\n", req_type, is_fault)
	
	// Sensor fault
	if (is_fault) {
		json_error(response, full_device_name, DEVICE_STATUS_FAULT, NULL);
	}
	// POST request - status & config only
	else if (req_type == MB_REQTYPE_POST) {
		json_status(response, full_device_name, DEVICE_STATUS_OK, 
			json_sprintf(
				data_str, 
				"\"Config\" : {"
					"\"Reset_pin\": %d,"
					"\"Sce_pin\":%d,"
					"\"Dc_pin\": %d,"
					"\"Sdin_pin\": %d,"
					"\"Sclk_pin\": %d"
				"}",
				mb_p_pcd8544_config->resetPin,
				mb_p_pcd8544_config->scePin,
				mb_p_pcd8544_config->dcPin,
				mb_p_pcd8544_config->sdinPin,
				mb_p_pcd8544_config->sclkPin
			)
		);

	// normal event measurement
	} else {
		json_data(
			response, full_device_name, DEVICE_STATUS_OK, 
				json_sprintf(data_str,
					"\"pcd8544\": {"
					"}"
				),
				NULL
		);
	}
}
Ejemplo n.º 22
0
void PredicateChecker::push_key(const std::string &key)
{
    if(key.empty())
    {
        throw json_error("cannot push empty key");
    }

    if(key == keyword(IN))
    {
        m_mode.push_back(predicate_mode::IN);

        m_pred_matches = false;
        m_pred_values.clear();

        for(auto &path: path_strings(m_path, m_document))
        {
            json::Document view(m_document, path, false);

            pred_value val;
            val.type = view.get_type();

            switch(val.type)
            {
            case ObjectType::Integer:
                val.integer = view.as_integer();
                break;
            case ObjectType::String:
                val.str = view.as_string();
                break;
            case ObjectType::Float:
                val.floating = view.as_float();
                break;
            default:
                val.type = ObjectType::Null;
                break;
            }

            m_pred_values.push_back(val);
        }
    }
    else if(key == keyword(LESS_THAN) || key == keyword(LESS_THAN_EQUAL)
            || key == keyword(GREATER_THAN) || key == keyword(GREATER_THAN_EQUAL)
            || key == keyword(EQUAL) || key == keyword(NOT_EQUAL))
    {
        if(key == keyword(LESS_THAN))
        {
            m_mode.push_back(predicate_mode::LESS_THAN);
        }
        else if(key == keyword(LESS_THAN_EQUAL))
        {
            m_mode.push_back(predicate_mode::LESS_THAN_EQUAL);
        }
        else if(key == keyword(GREATER_THAN))
        {
            m_mode.push_back(predicate_mode::GREATER_THAN);
        }
        else if(key == keyword(GREATER_THAN_EQUAL))
        {
            m_mode.push_back(predicate_mode::GREATER_THAN_EQUAL);
        }
        else if(key == keyword(EQUAL))
        {
            m_mode.push_back(predicate_mode::EQUAL);
        }
        else if(key == keyword(NOT_EQUAL))
        {
            m_mode.push_back(predicate_mode::NOT_EQUAL);
        }
        else
        {
            throw json_error("invalid state");
        }

        m_pred_values.clear();
        m_pred_matches = false;

        for(auto &path: path_strings(m_path, m_document))
        {
            json::Document view(m_document, path, false);

            pred_value val;
            val.type = view.get_type();

            switch(val.type)
            {
            case ObjectType::Integer:
                val.integer = view.as_integer();
                break;
            case ObjectType::Float:
                val.floating = view.as_float();
                break;
            case ObjectType::String:
                val.str = view.as_string();
                break;
            default:
                val.type = ObjectType::Null;
                break;
            }

            m_pred_values.push_back(val);
        }
    }
    else
    {
        m_mode.push_back(predicate_mode::NORMAL);
    }

    m_path.push_back(key);
}
Ejemplo n.º 23
0
void 
parse_topology(char *json, size_t s, struct parsed_topology *ptopo){
    struct json_parse_result_s result;
    struct json_value_s* root = json_parse_ex(json, s, json_parse_flags_allow_location_information, NULL, NULL, &result);
    struct json_object_s* obj;
    struct json_object_element_s* elements;
    struct json_string_ex_s* key;
    struct json_array_s* array;
    struct json_array_element_s* arr_elem;
    struct json_error_info err_info;
    size_t i;
    if (root == NULL) {
        json_set_error_info(&err_info, INVALID_JSON, result.error_line_no, result.error_row_no, NO_KEY);
        json_error(json, err_info);
    }
    // Parse datapaths
    obj = (struct json_object_s*)root->payload;
    elements = obj->start;
    // Validate dps key
    key = (struct json_string_ex_s*) elements->name;
    validate_keyword(DPS_KEY, key, json, err_info);
    // Get Values 
    array = (struct json_array_s*) elements->value->payload;
    arr_elem = array->start;
    // store dpids in array
    for(i = 0; i < array->length; ++i){
        struct json_number_s* dpid = arr_elem->value->payload;
        sscanf((char*) dpid->number, "%"PRIx64"", &ptopo->dps[i]);
        arr_elem = arr_elem->next; 
    }
    // Sorts the array so we can use bsearch
    qsort (ptopo->dps, array->length, sizeof(uint64_t), cmpfunc);
    ptopo->ndps = i;
    // Parse links
    elements = elements->next;
    if (elements != NULL){
        // Validate links key
        key = (struct json_string_ex_s*) elements->name;
        validate_keyword(LINKS_KEY, key, json, err_info);
        array = (struct json_array_s*) elements->value->payload;
        arr_elem = array->start;
        for(i = 0; i < array->length; ++i){
            struct json_number_s* value;
            struct json_object_s* links = (struct json_object_s*) arr_elem->value->payload;
            struct json_object_element_s* link_elem = links->start;
            // Validate SwitchX
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(SWITCHX, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx64"", &ptopo->links[i].switchX);
            if (validate_link_dp(ptopo->links[i].switchX, *ptopo) < 0) {
                struct json_value_ex_s *v = (struct json_value_ex_s *) link_elem->value;
                json_set_error_info(&err_info, INVALID_LINK_DP, v->line_no, v->row_no, (char*) value->number);
                json_error(json, err_info);
            }
            // Validate SwitchY
            link_elem = link_elem->next; 
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(SWITCHY, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx64"", &ptopo->links[i].switchY);
            if (validate_link_dp(ptopo->links[i].switchY, *ptopo) < 0) {
                struct json_value_ex_s *v = (struct json_value_ex_s *) link_elem->value;
                json_set_error_info(&err_info, INVALID_LINK_DP, v->line_no, v->row_no, (char*) value->number);
                json_error(json, err_info);
            }
            // Validate portX
            link_elem = link_elem->next;
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(PORTX, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx32"", &ptopo->links[i].portX);
            // Validate portY
            link_elem = link_elem->next;
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(PORTY, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx32"", &ptopo->links[i].portY);
            // Validate delay
            link_elem = link_elem->next;
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(DELAY, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx32"", &ptopo->links[i].delay);
            // Validate bw
            link_elem = link_elem->next;
            key = (struct json_string_ex_s*) link_elem->name;
            validate_keyword(BW, key, json, err_info);
            value = link_elem->value->payload;
            sscanf((char*) value->number, "%"PRIx32"", &ptopo->links[i].bw);
            arr_elem = arr_elem->next;
        }
        ptopo->nlinks = i;
    }
    free(root);
    free(json); 
}
Ejemplo n.º 24
0
void ICACHE_FLASH_ATTR emtr_handler(
	struct espconn *pConnection, 
	request_method method, 
	char *url, 
	char *data, 
	uint16 data_len, 
	uint32 content_len, 
	char *response,
	uint16 response_len
) {
	if (device_get_uart() != UART_EMTR) {
		json_error(response, MOD_EMTR, DEVICE_NOT_FOUND, NULL);
		return;
	}
	
	if (emtr_registers.calibration == NULL) {
		emtr_registers.calibration = (emtr_calibration_registers *)os_zalloc(sizeof(emtr_calibration_registers));
	}
	
	if (emtr_registers.event == NULL) {
		emtr_registers.event = (emtr_event_registers *)os_zalloc(sizeof(emtr_event_registers));
	}
		
	struct jsonparse_state parser;
	int type;
	bool set_counter = false;
	emtr_mode mode = emtr_current_mode;
	_uint64_ counter_active = emtr_counter_active();
	_uint64_ counter_apparent = emtr_counter_apparent();
	
	if (method == POST && data != NULL && data_len != 0) {
		jsonparse_setup(&parser, data, data_len);
		
		while ((type = jsonparse_next(&parser)) != 0) {
			if (type == JSON_TYPE_PAIR_NAME) {
				if (jsonparse_strcmp_value(&parser, "Mode") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					if (jsonparse_strcmp_value(&parser, "Log") == 0) {
						emtr_current_mode = EMTR_LOG;
					} else if (jsonparse_strcmp_value(&parser, "Configure") == 0) {
						emtr_current_mode = EMTR_CONFIGURE;
					} else if (jsonparse_strcmp_value(&parser, "Calibration") == 0) {
						emtr_current_mode = EMTR_CALIBRATION;
					}
				} else if (jsonparse_strcmp_value(&parser, "ReadInterval") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					emtr_read_interval = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "CounterActive") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					counter_active = jsonparse_get_value_as_int(&parser);
					set_counter = true;
				} else if (jsonparse_strcmp_value(&parser, "CounterApparent") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					counter_apparent = jsonparse_get_value_as_int(&parser);
					set_counter = true;
				}
				
				if (mode == EMTR_CONFIGURE) {
					if (jsonparse_strcmp_value(&parser, "OverCurrentLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_current_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverPowerLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_power_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverFrequencyLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_frequency_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "UnderFrequencyLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->under_frequency_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverTemperatureLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_temperature_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "UnderTemperatureLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->under_temperature_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "VoltageSagLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->voltage_sag_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "VoltageSurgeLimit") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->voltage_surge_limit = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverCurrentHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_current_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverPowerHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_power_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverFrequencyHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_frequency_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "UnderFrequencyHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->under_frequency_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "OverTemperatureHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->over_temperature_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "UnderTemperatureHold") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->under_temperature_hold = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "EventEnable") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->event_enable = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "EventMaskCritical") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->event_mask_critical = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "EventMaskStandard") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->event_mask_standard = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "EventTest") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->event_test = jsonparse_get_value_as_int(&parser);
					} else if (jsonparse_strcmp_value(&parser, "EventClear") == 0) {
						jsonparse_next(&parser);
						jsonparse_next(&parser);
						emtr_registers.event->event_clear = jsonparse_get_value_as_int(&parser);
					}
				}
			}
		}
		
		if (mode == EMTR_CONFIGURE) {
			emtr_set_event(emtr_registers.event, NULL);
		}
		
		if (set_counter) {
			emtr_set_counter(counter_active, counter_apparent, NULL);
		}
	}
	
	char data_str[WEBSERVER_MAX_RESPONSE_LEN];
	if (emtr_current_mode == EMTR_CALIBRATION) {
		json_data(
			response, MOD_EMTR, OK_STR,
			json_sprintf(
				data_str,
				"\"Address\" : \"0x%04X\", "
				"\"Mode\" : \"%s\", "
				"\"CounterActive\" : %d, "
				"\"CounterApparent\" : %d, "
				"\"ReadInterval\" : %d, "
				
				"\"GainCurrentRMS\" : %d, "
				"\"GainVoltageRMS\" : %d, "
				"\"GainActivePower\" : %d, "
				"\"GainReactivePower\" : %d, "
				"\"OffsetCurrentRMS\" : %d, "
				"\"OffsetActivePower\" : %d, "
				"\"OffsetReactivePower\" : %d, "
				"\"DCOffsetCurrent\" : %d, "
				"\"PhaseCompensation\" : %d, "
				"\"ApparentPowerDivisor\" : %d, "
				"\"SystemConfiguration\" : \"0x%08X\", "
				"\"DIOConfiguration\" : \"0x%04X\", "
				"\"Range\" : \"0x%08X\", "
				
				"\"CalibrationCurrent\" : %d, "
				"\"CalibrationVoltage\" : %d, "
				"\"CalibrationActivePower\" : %d, "
				"\"CalibrationReactivePower\" : %d, "
				"\"AccumulationInterval\" : %d",
				emtr_address(),
				emtr_mode_str(emtr_current_mode),
				emtr_counter_active(),
				emtr_counter_apparent(),
				emtr_read_interval,
				
				emtr_registers.calibration->gain_current_rms,
				emtr_registers.calibration->gain_voltage_rms,
				emtr_registers.calibration->gain_active_power,
				emtr_registers.calibration->gain_reactive_power,
				emtr_registers.calibration->offset_current_rms,
				emtr_registers.calibration->offset_active_power,
				emtr_registers.calibration->offset_reactive_power,
				emtr_registers.calibration->dc_offset_current,
				emtr_registers.calibration->phase_compensation,
				emtr_registers.calibration->apparent_power_divisor,
				emtr_registers.calibration->system_configuration,
				emtr_registers.calibration->dio_configuration,
				emtr_registers.calibration->range,
				
				emtr_registers.calibration->calibration_current,
				emtr_registers.calibration->calibration_voltage,
				emtr_registers.calibration->calibration_active_power,
				emtr_registers.calibration->calibration_reactive_power,
				emtr_registers.calibration->accumulation_interval
			),
			NULL
		);
		setTimeout(emtr_calibration_read, NULL, 1500);
	} else if (emtr_current_mode == EMTR_CONFIGURE) {
		json_data(
			response, MOD_EMTR, OK_STR,
			json_sprintf(
				data_str,
				"\"Address\" : \"0x%04X\", "
				"\"Mode\" : \"%s\", "
				"\"CounterActive\" : %d, "
				"\"CounterApparent\" : %d, "
				"\"ReadInterval\" : %d, "
				
				"\"OverCurrentLimit\" : %d, "
				"\"OverPowerLimit\" : %d, "
				"\"OverFrequencyLimit\" : %d, "
				"\"UnderFrequencyLimit\" : %d, "
				"\"OverTemperatureLimit\" : %d, "
				"\"UnderTemperatureLimit\" : %d, "
				"\"VoltageSagLimit\" : %d, "
				"\"VoltageSurgeLimit\" : %d, "
				"\"OverCurrentHold\" : %d, "
				"\"OverPowerHold\" : %d, "
				"\"OverFrequencyHold\" : %d, "
				"\"UnderFrequencyHold\" : %d, "
				"\"OverTemperatureHold\" : %d, "
				"\"UnderTemperatureHold\" : %d, "
				"\"EventEnable\" : %d, "
				"\"EventMaskCritical\" : %d, "
				"\"EventMaskStandard\" : %d, "
				"\"EventTest\" : %d, "
				"\"EventClear\" : %d",
				emtr_address(),
				emtr_mode_str(emtr_current_mode),
				emtr_counter_active(),
				emtr_counter_apparent(),
				emtr_read_interval,
				
				emtr_registers.event->over_current_limit,
				emtr_registers.event->over_power_limit,
				emtr_registers.event->over_frequency_limit,
				emtr_registers.event->under_frequency_limit,
				emtr_registers.event->over_temperature_limit,
				emtr_registers.event->under_temperature_limit,
				emtr_registers.event->voltage_sag_limit,
				emtr_registers.event->voltage_surge_limit,
				emtr_registers.event->over_current_hold,
				emtr_registers.event->over_power_hold,
				emtr_registers.event->over_frequency_hold,
				emtr_registers.event->under_frequency_hold,
				emtr_registers.event->over_temperature_hold,
				emtr_registers.event->under_temperature_hold,
				emtr_registers.event->event_enable,
				emtr_registers.event->event_mask_critical,
				emtr_registers.event->event_mask_standard,
				emtr_registers.event->event_test,
				emtr_registers.event->event_clear
			),
			NULL
		);
		setTimeout(emtr_events_read, NULL, 1500);
	} else {
		json_data(
			response, MOD_EMTR, OK_STR,
			json_sprintf(
				data_str,
				"\"Address\" : \"0x%04X\", "
				"\"Mode\" : \"%s\", "
				"\"CounterActive\" : %d, "
				"\"CounterApparent\" : %d, "
				"\"ReadInterval\" : %d",
				emtr_address(),
				emtr_mode_str(emtr_current_mode),
				emtr_counter_active(),
				emtr_counter_apparent(),
				emtr_read_interval
			),
			NULL
		);
	}
	
	emtr_start_read();
}
Ejemplo n.º 25
0
void ICACHE_FLASH_ATTR dimmer_handler(
	struct espconn *pConnection, 
	request_method method, 
	char *url, 
	char *data, 
	uint16 data_len, 
	uint32 content_len, 
	char *response,
	uint16 response_len
) {
	i2c_status status = I2C_OK;
	i2c_config *config = i2c_init_handler(DIMMER_STR, DIMMER_URL, dimmer_init, url, response);
	if (config == NULL) {
		return;
	}
	
	dimmer_config_data *config_data = (dimmer_config_data *)config->data;
	
	struct jsonparse_state parser;
	int type;

	if (method == POST && data != NULL && data_len != 0) {
		jsonparse_setup(&parser, data, data_len);

		while ((type = jsonparse_next(&parser)) != 0) {
			if (type == JSON_TYPE_PAIR_NAME) {
				if (jsonparse_strcmp_value(&parser, "Relay") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->relay = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "Brightness") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->brightness = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "Refresh") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					dimmer_refresh = jsonparse_get_value_as_int(&parser) * 1000;
				} else if (jsonparse_strcmp_value(&parser, "Each") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					dimmer_each = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "Threshold") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					dimmer_threshold = jsonparse_get_value_as_int(&parser);
				}
			}
		}
		
		dimmer_timer_init();
		status = dimmer_set(config);
	}
	
	char address_str[MAX_I2C_ADDRESS];
	json_i2c_address(address_str, config->address);
	
	if (status == I2C_OK) {
		dimmer_response(config, response, true);
	} else {
		json_error(response, DIMMER_STR, i2c_status_str(status), address_str);
	}
}
Ejemplo n.º 26
0
void ICACHE_FLASH_ATTR finger_handler(
	struct espconn *pConnection, 
	request_method method, 
	char *url, 
	char *data, 
	uint16 data_len, 
	uint32 content_len, 
	char *response,
	uint16 response_len
) {
	if (device_get_uart() != UART_FINGER) {
		json_error(response, MOD_FINGER, DEVICE_NOT_FOUND, NULL);
		return;
	}
	
	struct jsonparse_state parser;
	int type, delete_len;
	uint16 delete_id;
	
	if (method == POST && data != NULL && data_len != 0) {
		jsonparse_setup(&parser, data, data_len);
		
		while ((type = jsonparse_next(&parser)) != 0) {
			if (type == JSON_TYPE_PAIR_NAME) {
				if (jsonparse_strcmp_value(&parser, "Address") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					
					char *convert_err = NULL;
					char address_str[20];
					jsonparse_copy_value(&parser, address_str, 20);
					uint32 address = strtoul(address_str, &convert_err, 16);
					
					if (*convert_err == '\0' && address != finger_address()) {
						finger_set_address(address, finger_default);
					}
				} else if (jsonparse_strcmp_value(&parser, "SecurityLevel") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					uint8 security_level = jsonparse_get_value_as_int(&parser);
					
					if (security_level != finger_security_level()) {
						finger_set_security_lefel(security_level, finger_default);
					}
				} else if (jsonparse_strcmp_value(&parser, "Mode") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					if (jsonparse_strcmp_value(&parser, "Read") == 0) {
						finger_current_mode = FINGER_READ;
					} else if (jsonparse_strcmp_value(&parser, "New") == 0) {
						finger_current_mode = FINGER_NEW;
					} else if (jsonparse_strcmp_value(&parser, "Delete") == 0) {
						finger_current_mode = FINGER_DELETE;
					} else if (jsonparse_strcmp_value(&parser, "Empty DB") == 0) {
						finger_current_mode = FINGER_EMPTY_DB;
					}
				} else if (jsonparse_strcmp_value(&parser, "DeleteID") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					delete_id = jsonparse_get_value_as_int(&parser);
					delete_len = jsonparse_get_len(&parser);
				}
			}
		}
		
		if (finger_current_mode == FINGER_DELETE && delete_len > 0) {
			finger_current_mode = FINGER_READ;
			finger_remove(delete_id, NULL);
#if FINGER_DEBUG
			debug("FINGER: Delete ID: %d\n", delete_id);
#endif
		}
		
		if (finger_current_mode == FINGER_EMPTY_DB) {
			finger_current_mode = FINGER_READ;
			finger_empty_db(NULL);
#if FINGER_DEBUG
			debug("FINGER: Empty DB\n");
#endif
		}
	}
	
	webserver_set_status(0);
	finger_frech_params();
	finger_start_read();
}
Ejemplo n.º 27
0
        bool to_json(SEXP sexp, js::value& result) {
            int type = TYPEOF(sexp);

            switch (type) {
            case NILSXP:
                result = js::value();
                return true;

            case VECSXP: {
                SEXP names = Rf_getAttrib(sexp, R_NamesSymbol);
                if (Rf_isNull(names)) {
                    result = js::value(js::array());
                    list_to_array(sexp, result.get<js::array>());
                } else {
                    result = js::value(js::object());
                    list_to_object(sexp, names, result.get<js::object>());
                }
                return true;
            }

            case ENVSXP:
                result = js::value(js::object());
                env_to_object(sexp, result.get<js::object>());
                return true;
            }

            if (Rf_length(sexp) == 0) {
                result = js::value();
                return true;
            }

            switch (type) {
            case LGLSXP: {
                at_most_one(sexp);
                int x = *LOGICAL(sexp);
                result = x == R_NaInt ? js::value() : js::value(x != 0);
                break;
            }

            case INTSXP: {
                at_most_one(sexp);
                int x = *INTEGER(sexp);
                result = x == R_NaInt ? js::value() : js::value(static_cast<double>(x));
                break;
            }

            case REALSXP: {
                at_most_one(sexp);
                double x = *REAL(sexp);
                if (R_IsNA(x)) {
                    result = js::value();
                } else {
                    if (isinf(x) || isnan(x)) {
                        json_error(sexp, "+Inf, -Inf and NaN cannot be serialized.");
                    }
                    result = js::value(x);
                }
                break;
            }

            case STRSXP: {
                at_most_one(sexp);
                SEXP x = STRING_ELT(sexp, 0);
                if (x == R_NaString) {
                    result = js::value();
                } else {
                    std::string s;
                    result = strsxp_to_utf8(x, s) ? js::value(s) : js::value();
                }
                break;
            }

            default:
                json_error(sexp, "Unsupported type - must be one of: NULL; logical, integer, real, character vector; list; environment.");
            }

            return result != js::value();
        }
Ejemplo n.º 28
0
void ICACHE_FLASH_ATTR mod_rgb_handler(
	struct espconn *pConnection, 
	request_method method, 
	char *url, 
	char *data, 
	uint16 data_len, 
	uint32 content_len, 
	char *response,
	uint16 response_len
) {
	i2c_status status;
	i2c_config *config = i2c_init_handler(MOD_RGB, MOD_RGB_URL, rgb_init, url, response);
	if (config == NULL) {
		return;
	}
	
	rgb_config_data *config_data = (rgb_config_data *)config->data;
	
	struct jsonparse_state parser;
	int type;
	
	if (method == POST && data != NULL && data_len != 0) {
		jsonparse_setup(&parser, data, data_len);

		while ((type = jsonparse_next(&parser)) != 0) {
			if (type == JSON_TYPE_PAIR_NAME) {
				if (jsonparse_strcmp_value(&parser, "R") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->red = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "G") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->green = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "B") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->blue = jsonparse_get_value_as_int(&parser);
				}
			}
		}
	}
	
	char address_str[MAX_I2C_ADDRESS];
	json_i2c_address(address_str, config->address);
	
	status = rgb_set(config);
	if (status == I2C_OK) {
		char data_str[WEBSERVER_MAX_VALUE];
		json_data(
			response, MOD_RGB, OK_STR,
			json_sprintf(
				data_str,
				"\"R\" : %d, \"G\" : %d, \"B\" : %d",
				config_data->red, 
				config_data->green, 
				config_data->blue
			),
			address_str
		);
	} else {
		json_error(response, MOD_RGB, i2c_status_str(status), address_str);
	}
}
Ejemplo n.º 29
0
void ICACHE_FLASH_ATTR mod_irda_handler(
	struct espconn *pConnection, 
	request_method method, 
	char *url, 
	char *data, 
	uint16 data_len, 
	uint32 content_len, 
	char *response,
	uint16 response_len
) {
	i2c_status status = I2C_OK;
	i2c_config *config = i2c_init_handler(MOD_IRDA, MOD_IRDA_URL, irda_init, url, response);
	if (config == NULL) {
		return;
	}
	
	irda_config_data *config_data = (irda_config_data *)config->data;
	
	struct jsonparse_state parser;
	int type;
	
	if (method == POST && data != NULL && data_len != 0) {
		jsonparse_setup(&parser, data, data_len);

		while ((type = jsonparse_next(&parser)) != 0) {
			if (type == JSON_TYPE_PAIR_NAME) {
				if (jsonparse_strcmp_value(&parser, "Mode") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					if (jsonparse_strcmp_value(&parser, "SIRC") == 0) {
						config_data->mode = 1;
					} else {
						config_data->mode = 0;
					}
				} else if (jsonparse_strcmp_value(&parser, "Device") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->device = jsonparse_get_value_as_int(&parser);
				} else if (jsonparse_strcmp_value(&parser, "Command") == 0) {
					jsonparse_next(&parser);
					jsonparse_next(&parser);
					config_data->command = jsonparse_get_value_as_int(&parser);
				}
			}
		}
		
		status = irda_set(config);
	}
	
	char address_str[MAX_I2C_ADDRESS];
	json_i2c_address(address_str, config->address);
	
	if (status == I2C_OK) {
		char data_str[WEBSERVER_MAX_VALUE];
		json_data(
			response, MOD_IRDA, OK_STR,
			json_sprintf(
				data_str,
				"\"Mode\" : \"%s\", "
				"\"Device\" : %d, "
				"\"Command\" : %d ",
				irda_mode_str(config_data->mode), 
				config_data->device,
				config_data->command
			),
			address_str
		);
	} else {
		json_error(response, MOD_IRDA, i2c_status_str(status), address_str);
	}
}
Ejemplo n.º 30
0
/**
 * \brief Reads the next token from the input stream.
 *
 * \param reader The reader.
 *
 * \return The token code.
 */
JSONToken json_next_token(JSONReader *reader)
{
    int ch;

    /* Bail out if we already reached the end of the stream */
    if (reader->token == JSON_TOKEN_END)
        return JSON_TOKEN_END;
    if (reader->saw_eof) {
        reader->token = JSON_TOKEN_END;
        return JSON_TOKEN_END;
    }

    /* Free the previous token's string value */
    if (reader->str_value) {
        free(reader->str_value);
        reader->str_value = 0;
    }

    /* Skip whitespace */
    for (;;) {
        ch = getc(reader->stream);
        if (ch == EOF) {
            reader->token = JSON_TOKEN_END;
            reader->saw_eof = 1;
            return reader->token;
        } else if (ch == '\n') {
            ++(reader->line_number);
        } else if (ch != ' ' && ch != '\t' && ch != '\r') {
            break;
        }
    }

    /* Parse the next token */
    if (ch == '{') {
        reader->token = JSON_TOKEN_LBRACE;
    } else if (ch == '}') {
        reader->token = JSON_TOKEN_RBRACE;
    } else if (ch == '[') {
        reader->token = JSON_TOKEN_LSQUARE;
    } else if (ch == ']') {
        reader->token = JSON_TOKEN_RSQUARE;
    } else if (ch == ',') {
        reader->token = JSON_TOKEN_COMMA;
    } else if (ch == ':') {
        reader->token = JSON_TOKEN_COLON;
    } else if (ch == 't') {
        json_named_token(reader, JSON_TOKEN_TRUE, "true");
    } else if (ch == 'f') {
        json_named_token(reader, JSON_TOKEN_FALSE, "false");
    } else if (ch == 'n') {
        json_named_token(reader, JSON_TOKEN_FALSE, "null");
    } else if (ch == '"') {
        /* Recognize very simple strings with no escaping */
        char buffer[JSON_STR_MAX];
        size_t posn = 0;
        for (;;) {
            ch = getc(reader->stream);
            if (ch == '"') {
                break;
            } else if (ch == '\r' || ch == '\n' || ch == EOF) {
                json_error(reader, "Unterminated string");
                reader->token = JSON_TOKEN_END;
                return reader->token;
            } else if (ch == '\\') {
                json_error(reader, "String escapes are not supported");
                reader->token = JSON_TOKEN_END;
                return reader->token;
            } else {
                if (posn >= (sizeof(buffer) - 1)) {
                    json_error(reader, "String is too long");
                    reader->token = JSON_TOKEN_END;
                    return reader->token;
                }
                buffer[posn++] = (char)ch;
            }
        }
        buffer[posn] = '\0';
        reader->str_value = (char *)malloc(posn + 1);
        if (!(reader->str_value)) {
            json_error(reader, "Out of memory");
            reader->token = JSON_TOKEN_END;
            return reader->token;
        }
        strcpy(reader->str_value, buffer);
        reader->token = JSON_TOKEN_STRING;
    } else {
        /* Unknown character.  Note: numbers are not yet supported. */
        json_error(reader, "Unknown character 0x%02x", ch);
        reader->token = JSON_TOKEN_END;
    }

    return reader->token;
}