OCT 1. 支持协议请求JSON字段规范格式检查

This commit is contained in:
huangxin 2023-02-27 14:10:36 +08:00
parent e423c252e4
commit 68fb784531
13 changed files with 115 additions and 176 deletions

View File

@ -1,7 +1,14 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
INCLUDE(CMakeDependentOption)
OPTION(VCPE_AGENT "Enable vCPE agent test application" OFF)
OPTION(USED_LWIP "PPPoE of LWIP support for vCPE" OFF)
OPTION(USED_OPENDHCPD "DHCP server for vCPE" OFF)
OPTION(USED_OPENDHCPDDNS "DHCP And DNS server for vCPE" OFF)
OPTION(USED_USER_VNI "Support pass user vni id from console command line" OFF)
OPTION(USED_JSON_VALIDATE "Support json protocol field validate" OFF)
OPTION(BUILD_TESTING "Enable tests" OFF)
LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/depend)
IF (BUILD_TESTING)
INCLUDE(doctest_framework)
@ -11,12 +18,7 @@ INCLUDE(system_libs)
SET(VCPE_VERSION "1.0.1")
PROJECT(vCPE VERSION "${VCPE_VERSION}")
OPTION(VCPE_AGENT "Enable vCPE agent test application" OFF)
OPTION(USED_LWIP "PPPoE of LWIP support for vCPE" OFF)
OPTION(USED_OPENDHCPD "DHCP server for vCPE" OFF)
OPTION(USED_OPENDHCPDDNS "DHCP And DNS server for vCPE" OFF)
OPTION(USED_USER_VNI "Support pass user vni id from console command line" OFF)
OPTION(BUILD_TESTING "Enable tests" OFF)
CMAKE_DEPENDENT_OPTION(USED_HTTP_SVR "Build-in http(s) server support" ON "USED_OPENDHCPD OR USED_OPENDHCPDDNS" OFF)
#
@ -82,6 +84,10 @@ SET(COMMON_LIBS "")
INCLUDE(./depend/third_libs.cmake)
IF (USED_JSON_VALIDATE)
LIST(APPEND COMMON_DEFINE "-DJSON_SCHEMA_ON")
ENDIF()
IF (USED_USER_VNI)
LIST(APPEND COMMON_DEFINE "-DUSERVNI_ON")
MESSAGE("Select Option USED_USER_VNI")

View File

@ -4,6 +4,7 @@ INCLUDE(FetchContent)
PKG_SEARCH_MODULE(LIBUV QUIET libuv)
PKG_SEARCH_MODULE(LIBCONFIG QUIET libconfig)
FIND_LIBRARY(LIBZLOG zlog PATHS "/usr/local/lib")
IF (USED_JSON_VALIDATE)
PKG_CHECK_MODULES(LIBJSON-C QUIET json-c>=0.13)
IF (NOT LIBJSON-C_FOUND)
@ -12,7 +13,7 @@ IF (NOT LIBJSON-C_FOUND)
URL_MD5 a549a833f886d427148fb5710c3e613e
)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
FETCHCONTENT_DECLARE(libuv
URL file://${CMAKE_SOURCE_DIR}/depend/libuv-v1.44.2.tar.gz
@ -43,10 +44,11 @@ IF (LIBZLOG STREQUAL "LIBZLOG-NOTFOUND")
FETCHCONTENT_MAKEAVAILABLE(zlog)
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
FETCHCONTENT_MAKEAVAILABLE(libjson-c)
ENDIF ()
ENDIF ()
IF (NOT LIBUV_FOUND)
MESSAGE(STATUS "libuv not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libuv)
@ -89,6 +91,7 @@ ELSE ()
LIST(APPEND COMMON_LIBS "${LIBZLOG}")
ENDIF ()
IF (USED_JSON_VALIDATE)
IF (NOT LIBJSON-C_FOUND)
MESSAGE(STATUS "json-c not found, will be used source code to build it ...")
FETCHCONTENT_GETPROPERTIES(libjson-c)
@ -106,3 +109,4 @@ ELSE ()
MESSAGE(STATUS "json-c found ${LIBJSON-C_VERSION} at ${LIBJSON-C_LIBRARY_DIRS}")
LIST(APPEND COMMON_LIBS "${LIBJSON-C_LDFLAGS}")
ENDIF ()
ENDIF ()

View File

@ -2,8 +2,6 @@ SET(LIB_PROJECT_TARGET common)
PROJECT(${LIB_PROJECT_TARGET} VERSION 1.1.0)
ADD_SUBDIRECTORY(./json/json_schema)
STRING(REPLACE ";" ", " BUILD_CONFIG_INFO "${COMMON_DEFINE}")
CONFIGURE_FILE(lib_config.h.in lib_config.h)
@ -26,6 +24,11 @@ AUX_SOURCE_DIRECTORY(hardware C_SRC)
AUX_SOURCE_DIRECTORY(protocol C_SRC)
AUX_SOURCE_DIRECTORY(fs_watch C_SRC)
AUX_SOURCE_DIRECTORY(zlog_module C_SRC)
IF (USED_JSON_VALIDATE)
ADD_SUBDIRECTORY(./json/json_schema)
ENDIF ()
IF (USED_HTTP_SVR)
AUX_SOURCE_DIRECTORY(mongoose C_SRC)
ENDIF ()
@ -64,7 +67,9 @@ ADD_LIBRARY(${LIB_PROJECT_TARGET} ${C_SRC} ${C_HEADS})
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} ${COMMON_LIBS})
IF (USED_JSON_VALIDATE)
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} jsoncdac)
ENDIF ()
IF (USED_OPENDHCPD)
TARGET_LINK_LIBRARIES(${LIB_PROJECT_TARGET} opendhcpd)

View File

@ -10,8 +10,6 @@ extern "C" {
#endif
#include <s2j/cJSON.h>
#define JSON_SCHEMA_ON (1)
typedef enum {
CRYPTO_NONE = 0,
CRYPTO_BASE64 = 1,

View File

@ -35,6 +35,7 @@ typedef enum {
ZLOG_MOD(ZLOG_MOD_MQ, ZLOG_LEVEL_DEBUG, "MQ") \
ZLOG_MOD(ZLOG_MOD_PROTO, ZLOG_LEVEL_DEBUG, "PROTO") \
ZLOG_MOD(ZLOG_MOD_HTTPD, ZLOG_LEVEL_INFO, "HTTPD") \
ZLOG_MOD(ZLOG_MOD_JSCHEM, ZLOG_LEVEL_INFO, "JSCHEM") \
ZLOG_MOD(ZLOG_MOD_USER, ZLOG_LEVEL_DEBUG, "USER") \
ZLOG_MOD(ZLOG_MOD_PPPOE, ZLOG_LEVEL_DEBUG, "PPPOE") \
ZLOG_MOD(ZLOG_MOD_VXLAN, ZLOG_LEVEL_DEBUG, "VXLAN") \

View File

@ -1,103 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include "../include/jsoncdaccord.h"
#include "version_config.h"
char *json_file=NULL, *schema_file=NULL;
void usage()
{
printf("\nUsage:\n");
printf(" jdac-cli -j jsonfile -s schemafile [options]\n\n");
printf(" options:\n");
#ifdef JDAC_REF
printf(" --loadlocal, -l referenced schemas at local filelocationl\n");
#endif
printf(" --version, -v Show version and supported JSON Schema keywords\n");
printf(" --help, -h Show this\n\n");
}
void freeall()
{
if (json_file) free(json_file);
if (schema_file) free(schema_file);
}
int main(int argc, char *argv[])
{
int c;
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"json", required_argument, 0, 'j'},
{"schema", required_argument, 0, 's'},
#ifdef JDAC_REF
{"loadlocal", required_argument, 0, 'l'},
#endif
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "j:s:l:v",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'j':
json_file = strdup(optarg);
break;
case 's':
schema_file = strdup(optarg);
break;
#ifdef JDAC_REF
case 'l':
jdac_ref_set_localpath(optarg);
break;
#endif
case 'v':
printf("jdac-cli (%s version %s)\n", PROJECT_NAME, PROJECT_VER);
printf("supported keywords:\n");
printf(" - base: %s\n", SUPPORTED_KEYWORDS_BASE);
printf(" - selected: %s\n\n", SUPPORTED_KEYWORDS_OPTIONAL);
freeall();
return 0;
break;
case 'h':
usage();
freeall();
return JDAC_ERR_VALID;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (!json_file) {
printf("No json file given\n");
}
if (!schema_file) {
printf("No schema file given");
}
if (!json_file || !schema_file) {
usage();
freeall();
return JDAC_ERR_WRONG_ARGS;
}
printf("validating %s with %s\n", json_file, schema_file);
int err = jdac_validate_file(json_file, schema_file);
if (err==JDAC_ERR_VALID) {
printf("validation ok\n");
} else {
printf("validate failed. err %d: %s\n", err, jdac_errorstr(err));
}
freeall();
return err;
}

View File

@ -3,7 +3,7 @@
#include "optional.h"
int _jdac_check_patternproperties(json_object *jobj, json_object *jschema) {
//printf("%s\n", __func__);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
// check jobj non object is already checked
json_object *jpatprops = json_object_object_get(jschema, "patternProperties");

View File

@ -3,6 +3,7 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
#include "../../include/zlog_module.h"
char localpath[256] = {0};
@ -33,7 +34,7 @@ int _jdac_check_ref(json_object *jobj, json_object *jschema, storage_node *stora
json_object *jref = json_object_object_get(jschema, "$ref");
if (jref) {
const char *refstr = json_object_get_string(jref);
printf("ref is %s\n", refstr);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "ref is %s\n", refstr);
storage_node *rootnode = _jdac_store_get_root_node(storage_list);
// if there is a rootnode id, compare it to the ref
if (rootnode) {
@ -47,7 +48,7 @@ int _jdac_check_ref(json_object *jobj, json_object *jschema, storage_node *stora
if (!path_id) {
char filepath[512];
snprintf(filepath, sizeof(filepath) - 1, "%s.%s", localpath, path_ref);
printf("filepath is %s\n", filepath);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "filepath is %s\n", filepath);
json_object *jschemafromfile = json_object_from_file(filepath);
if (!jschemafromfile) {
return JDAC_ERR_JSON_NOT_FOUND;
@ -58,10 +59,10 @@ int _jdac_check_ref(json_object *jobj, json_object *jschema, storage_node *stora
}
if (strcmp(path_ref, path_id) != 0 && strlen(localpath) > 0) {
printf("yep\n");
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "yep\n");
char filepath[512];
snprintf(filepath, sizeof(filepath) - 1, "%s.%s", localpath, path_ref);
printf("filepath is %s\n", filepath);
LOG_MOD(trace, ZLOG_MOD_JSCHEM, "filepath is %s\n", filepath);
json_object *jschemafromfile = json_object_from_file(filepath);
if (!jschemafromfile) {
return JDAC_ERR_JSON_NOT_FOUND;

View File

@ -2,12 +2,13 @@
#include <stdio.h>
#include <string.h>
#include "jsoncdaccord.h"
#include "../../include/zlog_module.h"
int _jdac_match_string_with_regex(const char *regex_pattern, const char *value) {
regex_t regex;
int reti = regcomp(&regex, regex_pattern, REG_EXTENDED);
if (reti) {
fprintf(stderr, "Could not compile regex\n");
LOG_MOD(error, ZLOG_MOD_JSCHEM, "Could not compile regex\n");
return JDAC_REGEX_COMPILE_FAILED;
}
reti = regexec(&regex, value, 0, NULL, 0);

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include "jsoncdaccord.h"
#include "optional.h"
#include "../../include/zlog_module.h"
void _jdac_store_append(storage_node **head, storage_node *ref) {
storage_node *new_node = malloc(sizeof(storage_node));
@ -69,7 +70,7 @@ int _jdac_store_traverse_json(storage_node **head, json_object *jschema, char *p
} else {
sprintf(pathbuf, "%s/%s", pathbuffer, jkey);
}
//printf("%s\n", pathbuf);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", pathbuf);
_jdac_store_traverse_json(head, jval, pathbuf);
}
}
@ -78,9 +79,29 @@ int _jdac_store_traverse_json(storage_node **head, json_object *jschema, char *p
void _jdac_store_print(storage_node *head) {
storage_node *list = head;
printf("%-*s %-*s %-*s %-*s\n", 32, "JSONPtr", 16, "anchor", 16, "dynamicAnchor", 32, "id");
LOG_MOD(trace,
ZLOG_MOD_JSCHEM,
"%-*s %-*s %-*s %-*s\n",
32,
"JSONPtr",
16,
"anchor",
16,
"dynamicAnchor",
32,
"id");
while (list) {
printf("%-*s %-*s %-*s %-*s\n", 32, list->JSONPtrURI, 16, list->anchor, 16, list->dynamicAnchor, 32, list->id);
LOG_MOD(trace,
ZLOG_MOD_JSCHEM,
"%-*s %-*s %-*s %-*s\n",
32,
list->JSONPtrURI,
16,
list->anchor,
16,
list->dynamicAnchor,
32,
list->id);
list = list->next;
}
}
@ -88,9 +109,9 @@ void _jdac_store_print(storage_node *head) {
storage_node *_jdac_store_get_root_node(storage_node *head) {
// spool to start of list
storage_node *list = head;
//printf("%-*s %-*s %-*s %-*s\n", 32, "JSONPtr", 16, "anchor", 16, "dynamicAnchor", 32, "id");
//LOG_MOD(trace, ZLOG_MOD_JSCHEM, "%-*s %-*s %-*s %-*s\n", 32, "JSONPtr", 16, "anchor", 16, "dynamicAnchor", 32, "id");
while (list) {
//printf("%-*s %-*s %-*s %-*s\n", 32, list->JSONPtrURI, 16, list->anchor, 16, list->dynamicAnchor, 32, list->id);
//LOG_MOD(trace, ZLOG_MOD_JSCHEM, "%-*s %-*s %-*s %-*s\n", 32, list->JSONPtrURI, 16, list->anchor, 16, list->dynamicAnchor, 32, list->id);
if (list->next == NULL) {
return list;
}

View File

@ -6,6 +6,7 @@
#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
#include "../../include/zlog_module.h"
json_object *json = NULL;
json_object *schema = NULL;
@ -102,7 +103,7 @@ int __jdac_inspect_type(json_object *jobj, const char *type) {
return JDAC_ERR_VALID;
}
} else {
printf("WARN unknown type in check type %s\n", type);
LOG_MOD(warn, ZLOG_MOD_JSCHEM, "WARN unknown type in check type %s\n", type);
return JDAC_ERR_SCHEMA_ERROR;
}
return JDAC_ERR_INVALID_TYPE;
@ -136,7 +137,7 @@ int _jdac_check_type(json_object *jobj, json_object *jschema) {
}
int _jdac_check_required(json_object *jobj, json_object *jschema) {
//printf("%s\n%s\n", __func__, json_object_to_json_string(jobj));
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n%s\n", __func__, json_object_to_json_string(jobj));
json_object *jarray = json_object_object_get(jschema, "required");
int missing_required_key = 0;
if (jarray) {
@ -145,12 +146,12 @@ int _jdac_check_required(json_object *jobj, json_object *jschema) {
json_object *iobj = json_object_array_get_idx(jarray, i);
const char *key = json_object_get_string(iobj);
if (key) {
//printf("%s\n", key);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", key);
// use json_object_object_get_ex becuase of json_type_null types
json_object *required_object = NULL;
int err = json_object_object_get_ex(jobj, key, &required_object);
if (err == 0) {
printf("required key missing: %s\n", key);
LOG_MOD(debug, ZLOG_MOD_JSCHEM, "required key missing: %s\n", key);
missing_required_key = 1;
}
}
@ -164,14 +165,14 @@ int _jdac_check_required(json_object *jobj, json_object *jschema) {
}
int _jdac_check_properties(json_object *jobj, json_object *jschema) {
// printf("%s\n", __func__);
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
json_object *jprops = json_object_object_get(jschema, "properties");
if (jprops) {
json_object_object_foreach(jprops, jprop_key, jprop_val) {
// printf("key of prop is %s\n", jprop_key);
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "key of prop is %s\n", jprop_key);
json_object *iobj = json_object_object_get(jobj, jprop_key);
//printf("iobj %s type %d\nkey %s\nval %s\n", json_object_get_string(iobj), json_object_get_type(iobj), jprop_key, json_object_get_string(jprop_val));
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "iobj %s type %d\nkey %s\nval %s\n", json_object_get_string(iobj), json_object_get_type(iobj), jprop_key, json_object_get_string(jprop_val));
if (iobj) {
int err = _jdac_validate_instance(iobj, jprop_val);
if (err) {
@ -199,7 +200,7 @@ int _jdac_check_prefixItems_and_items(json_object *jobj, json_object *jschema) {
prefixitems_arraylen = json_object_array_length(jprefixitems);
for (int i = 0; i < jobj_arraylen && i < prefixitems_arraylen; i++) {
//printf("i=%d prefixitems\n", i);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "i=%d prefixitems\n", i);
json_object *iobj = json_object_array_get_idx(jobj, i);
json_object *ischema = json_object_array_get_idx(jprefixitems, i);
int err = _jdac_validate_instance(iobj, ischema);
@ -215,7 +216,7 @@ int _jdac_check_prefixItems_and_items(json_object *jobj, json_object *jschema) {
}
for (int i = prefixitems_arraylen; i < jobj_arraylen; i++) {
//printf("i=%d items\n", i);
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "i=%d items\n", i);
json_object *iobj = json_object_array_get_idx(jobj, i);
int err = _jdac_validate_instance(iobj, jitems);
if (err) {
@ -298,7 +299,7 @@ int _jdac_check_enums(json_object *jobj, json_object *jschema) {
return JDAC_ERR_VALID;
}
}
printf("ERROR: enum check failed (%s not in enum)\n", json_object_to_json_string(jobj));
LOG_MOD(error, ZLOG_MOD_JSCHEM, "ERROR: enum check failed (%s not in enum)\n", json_object_to_json_string(jobj));
return JDAC_ERR_INVALID_ENUMS;
}
@ -353,7 +354,7 @@ int _jdac_check_maxmin_items(json_object *jobj, json_object *jschema) {
}
if (err) {
printf("ERROR: failed at maxItems or minItems check\n");
LOG_MOD(error, ZLOG_MOD_JSCHEM, "ERROR: failed at maxItems or minItems check\n");
}
return err;
}
@ -440,7 +441,7 @@ int utf8_length(const char *str) {
int _jdac_validate_string(json_object *jobj, json_object *jschema) {
const char *str = json_object_get_string(jobj);
//printf("strlen of %s %ld %d %d\n", str, strlen(str), json_object_get_string_len(jobj), utf8_length(str));
//LOG_MOD(debug, ZLOG_MOD_JSCHEM, "strlen of %s %ld %d %d\n", str, strlen(str), json_object_get_string_len(jobj), utf8_length(str));
json_object *jminlen = json_object_object_get(jschema, "minLength");
if (jminlen) {
int minlen = json_object_get_int64(jminlen);
@ -536,15 +537,15 @@ int _jdac_validate_number(json_object *jobj, json_object *jschema, double value)
}
int _jdac_validate_boolean(json_object *jobj, json_object *jschema) {
// printf("%s\n", __func__);
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", __func__);
return JDAC_ERR_VALID;
}
int _jdac_validate_instance(json_object *jobj, json_object *jschema) {
int err;
// printf("--validate instance--\n");
// printf("%s\n", json_object_get_string(jobj));
// printf("%s\n", json_object_get_string(jschema));
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "--validate instance--\n");
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jobj));
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jschema));
#ifdef JDAC_REF
err = _jdac_check_ref(jobj, jschema, storagelist_head);
@ -580,13 +581,13 @@ int _jdac_validate_instance(json_object *jobj, json_object *jschema) {
}
// if (!json_object_is_type(jobj, json_type_null))
// printf("%s\n", json_object_get_string(jobj));
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jobj));
// else
// printf("jobj was null\n");
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "jobj was null\n");
// if (!json_object_is_type(jschema, json_type_null))
// printf("%s\n", json_object_get_string(jschema));
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "%s\n", json_object_get_string(jschema));
// else
// printf("jschema was null\n");
// LOG_MOD(debug, ZLOG_MOD_JSCHEM, "jschema was null\n");
#ifdef JDAC_SUBSCHEMALOGIC
err = _jdac_check_subschemalogic(jobj, jschema);
@ -612,7 +613,7 @@ int _jdac_validate_instance(json_object *jobj, json_object *jschema) {
} else if (type == json_type_null) {
return JDAC_ERR_VALID;
} else {
printf("WARN: type %d not handled\n", type);
LOG_MOD(warn, ZLOG_MOD_JSCHEM, "WARN: type %d not handled\n", type);
}
return JDAC_ERR_VALID;

View File

@ -10,8 +10,9 @@
#include "crypto.h"
#include "user_errno.h"
#include "zlog_module.h"
#ifdef JSON_SCHEMA_ON
#include "json_schema/jsoncdaccord.h"
#endif
#define CURRENT_PROTOCOL_VERSION (1)
typedef struct {
@ -61,6 +62,7 @@ const char *proto_schema_validation(const char *pJsonStr) {
cJSON_AddStringToObject(pRspRoot, "message", getErrorEnumDesc(ERR_JSON_VALID_SCH));
cJSON_AddStringToObject(pRspRoot, "details", g_json_sch[i].pErrMsg);
json_object_put(pSc);
json_object_put(pJs);
return proto_create_new(pRspRoot, 200);
}
@ -92,6 +94,8 @@ const char *proto_decode_context(const char *pString, unsigned int *pVer, unsign
return NULL;
}
LOG_MOD(debug, ZLOG_MOD_PROTO, "Request: %s\n", pString);
#ifdef JSON_SCHEMA_ON
pSchJson = proto_schema_validation(pString);
if (pSchJson != NULL && strlen(pSchJson) > 0) {
@ -273,7 +277,7 @@ const char *proto_create_new(cJSON *pMsgCtx, int httpCode) {
}
pStrProto = cJSON_PrintUnformatted(pRoot);
LOG_MOD(trace, ZLOG_MOD_PROTO, "Create: \n%s\n", pStrProto);
LOG_MOD(debug, ZLOG_MOD_PROTO, "Create: %s\n", pStrProto);
cJSON_Delete(pRoot);