/**************************************************************************** * apps/examples/wgetjson/wgetjson_main.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "netutils/netlib.h" #include "netutils/webclient.h" #include "netutils/cJSON.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #ifndef CONFIG_EXAMPLES_WGETJSON_MAXSIZE # define CONFIG_EXAMPLES_WGETJSON_MAXSIZE 1024 #endif #ifndef CONFIG_EXAMPLES_WGETJSON_URL # define CONFIG_EXAMPLES_WGETJSON_URL "http://10.0.0.1/wgetjson/json_cmd.php" #endif #ifndef CONFIG_EXAMPLES_WGETPOST_URL # define CONFIG_EXAMPLES_WGETPOST_URL "http://10.0.0.1/wgetjson/post_cmd.php" #endif #define MULTI_POST_NDATA 3 /**************************************************************************** * Private Types ****************************************************************************/ /**************************************************************************** * Private Function Prototypes ****************************************************************************/ /**************************************************************************** * Private Data ****************************************************************************/ static FAR char *g_json_buff = NULL; static int g_json_bufflen = 0; static bool g_has_json = false; /**************************************************************************** * Private Functions ****************************************************************************/ static int wgetjson_postdebug_callback(FAR char **buffer, int offset, int datend, FAR int *buflen, FAR void *arg) { int len = datend - offset; if (len <= 0) { printf("Callback No Data!\n"); return 0; } ((*buffer)[datend]) = '\0'; printf("Callback Data(Length:%d):\n%s\n", len, &((*buffer)[offset])); return 0; } /**************************************************************************** * Name: wgetjson_callback ****************************************************************************/ static int wgetjson_callback(FAR char **buffer, int offset, int datend, FAR int *buflen, FAR void *arg) { FAR char *new_json_buff; int len = datend - offset; int org = len; if (len <= 0) { return 0; } if (!g_json_buff) { g_json_buff = malloc(len + 1); memcpy(g_json_buff, &((*buffer)[offset]), len); g_json_buff[len] = 0; g_json_bufflen = len; } else { if (g_json_bufflen >= CONFIG_EXAMPLES_WGETJSON_MAXSIZE) { g_json_bufflen += org; return 0; } if (g_json_bufflen + len > CONFIG_EXAMPLES_WGETJSON_MAXSIZE) { len = CONFIG_EXAMPLES_WGETJSON_MAXSIZE - g_json_bufflen; } new_json_buff = (FAR char *)realloc(g_json_buff, g_json_bufflen + len + 1); if (new_json_buff) { g_json_buff = new_json_buff; memcpy(&g_json_buff[g_json_bufflen], &((*buffer)[offset]), len); g_json_buff[g_json_bufflen + len] = 0; g_json_bufflen += org; } } return 0; } /**************************************************************************** * Name: wgetjson_json_release ****************************************************************************/ static void wgetjson_json_release(void) { if (g_json_buff) { free(g_json_buff); g_json_buff = NULL; } g_json_bufflen = 0; } /**************************************************************************** * Name: wgetjson_doit ****************************************************************************/ #if 0 /* Not used */ static void wgetjson_doit(char *text) { char *out; cJSON *json; json = cJSON_Parse(text); if (!json) { printf("Error before: [%s]\n", cJSON_GetErrorPtr()); } else { out = cJSON_Print(json); cJSON_Delete(json); printf("%s\n", out); free(out); } } #endif /**************************************************************************** * Name: wgetjson_json_item_callback ****************************************************************************/ static int wgetjson_json_item_callback(const char *name, int type, cJSON *item) { if (strlen(name) > 8 && !memcmp(name, "/(null)", 7)) { name += 8; g_has_json = true; } if (!strcmp(name, "name")) { printf("name:\t\t\t%s\n", item->valuestring); /* todo something.... */ } else if (strcmp(name, "format/type") == 0) { printf("format/type:\t\t%s\n", item->valuestring); /* todo something.... */ } else if (!strcmp(name, "format/width")) { printf("format/width:\t\t%d\n", item->valueint); /* todo something.... */ } else if (!strcmp(name, "format/height")) { printf("format/height:\t\t%d\n", item->valueint); /* todo something.... */ } else if (!strcmp(name, "format/interlace")) { printf("format/interlace:\t%s\n", (item->valueint) ? "true" : "false"); /* todo something.... */ } else if (!strcmp(name, "format/frame rate")) { printf("format/frame rate:\t%d\n", item->valueint); /* todo something.... */ } return 1; } /**************************************************************************** * Name: wgetjson_json_item_scan ****************************************************************************/ static void wgetjson_json_item_scan(cJSON *item, const char *prefix) { char *newprefix; int dorecurse; while (item) { const char *string = item->string ? item->string : "(null)"; size_t len = strlen(prefix) + strlen(string) + 2; newprefix = malloc(len); snprintf(newprefix, len, "%s/%s", prefix, string); dorecurse = wgetjson_json_item_callback(newprefix, item->type, item); if (item->child && dorecurse) { wgetjson_json_item_scan(item->child, newprefix); } item = item->next; free(newprefix); } } /**************************************************************************** * Name: wgetjson_json_parse ****************************************************************************/ static int wgetjson_json_parse(char *text) { cJSON *json; char *path = ""; json = cJSON_Parse(text); if (!json) { printf("Error before: [%s]\n", cJSON_GetErrorPtr()); return ERROR; } else { wgetjson_json_item_scan(json, path); cJSON_Delete(json); return OK; } } /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: wgetjson_main ****************************************************************************/ int main(int argc, FAR char *argv[]) { char *buffer = NULL; int buffer_len = 512; char *url = CONFIG_EXAMPLES_WGETJSON_URL; int ret = -1; int option; bool is_post = false; bool is_post_multi = false; bool badarg = false; bool is_debug = false; char *post_buff = NULL; int post_buff_len = 0; char *post_single_name = "type"; char *post_single_value = "string"; char *post_multi_names[MULTI_POST_NDATA] = { "name", "gender", "country" }; char *post_multi_values[MULTI_POST_NDATA] = { "darcy", "man", "china" }; webclient_sink_callback_t wget_cb = wgetjson_callback; while ((option = getopt(argc, argv, ":pPD")) != ERROR) { switch (option) { case 'p': is_post = true; break; case 'P': is_post = true; is_post_multi = true; break; case 'D': is_debug = true; break; case ':': badarg = true; break; case '?': default: badarg = true; break; } } if (badarg) { printf("usage: wgetjson -p(single post) -P(multi post) " "-D(debug wget callback)\n"); return -1; } if (is_debug) { wget_cb = wgetjson_postdebug_callback; } if (is_post) { buffer_len = 512 * 2; } buffer = malloc(buffer_len); wgetjson_json_release(); struct webclient_context ctx; webclient_set_defaults(&ctx); ctx.buffer = buffer; ctx.buflen = buffer_len; ctx.sink_callback = wget_cb; ctx.sink_callback_arg = NULL; if (is_post) { url = CONFIG_EXAMPLES_WGETPOST_URL; printf("URL: %s\n", url); if (is_post_multi) { post_buff_len = web_posts_strlen(post_multi_names, post_multi_values, MULTI_POST_NDATA); post_buff = malloc(post_buff_len); web_posts_str(post_buff, &post_buff_len, post_multi_names, post_multi_values, MULTI_POST_NDATA); } else { post_buff_len = web_post_strlen(post_single_name, post_single_value); post_buff = malloc(post_buff_len); web_post_str(post_buff, &post_buff_len, post_single_name, post_single_value); } if (post_buff) { const char *header = "Content-Type: " "application/x-www-form-urlencoded"; ctx.method = "POST"; ctx.url = url; ctx.headers = &header; ctx.nheaders = 1; webclient_set_static_body(&ctx, post_buff, strlen(post_buff)); ret = webclient_perform(&ctx); } } else { printf("URL: %s\n", url); ctx.method = "GET"; ctx.url = url; ret = webclient_perform(&ctx); } if (ret < 0) { printf("get json size: %d\n", g_json_bufflen); } else if (!is_debug) { g_has_json = false; if (wgetjson_json_parse(g_json_buff) == OK && g_has_json) { printf("Parse OK\n"); } else { printf("Parse error\n"); } g_has_json = false; } wgetjson_json_release(); free(buffer); if (post_buff) { free(post_buff); } return 0; }