/****************************************************************************** * * * 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; }
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; }
/****************************************************************************** * * * 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; }
/****************************************************************************** * * * 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; }
/****************************************************************************** * * * 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; }
/****************************************************************************** * * * 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; }
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); } }
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(); }
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(); } }
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); } }
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); } }
/** * \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; }
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(); }
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; }
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; } }
/****************************************************************************** * * * 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; }
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; } }
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; }
/****************************************************************************** * * * 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; }
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 ); } }
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); }
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); }
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(); }
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); } }
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(); }
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(); }
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); } }
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); } }
/** * \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; }