Commit 1ce0a1fb authored by whmaizmy's avatar whmaizmy

【修改内容】增加物模型的数据解析

【提交人】陈伟灿
parent 6eaf29f5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kk_dm_mng.h"
#include "kk_dm_msg.h"
#include "solo_tsl.data"
static dm_mgr_ctx g_dm_mgr = {0};
static dm_mgr_ctx *_dm_mgr_get_ctx(void)
{
return &g_dm_mgr;
}
static void _dm_mgr_mutex_lock(void)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
if (ctx->mutex) {
kk_MutexLock(ctx->mutex);
}
}
static void _dm_mgr_mutex_unlock(void)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
if (ctx->mutex) {
kk_MutexUnLock(ctx->mutex);
}
}
int dm_mgr_search_dev_by_devid(_IN_ int devid, _OU_ dm_mgr_dev_node_t **node)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if (search_node->devid == devid) {
/* dm_log_debug("Device Found, devid: %d", devid); */
if (node) {
*node = search_node;
}
return SUCCESS_RETURN;
}
}
printf("Device Not Found, devid: %d", devid);
return FAIL_RETURN;
}
static int _dm_mgr_search_dev_by_pkdn(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
_IN_ char device_name[DEVICE_NAME_MAXLEN], _OU_ dm_mgr_dev_node_t **node)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if ((strlen(search_node->product_key) == strlen(product_key)) &&
(memcmp(search_node->product_key, product_key, strlen(product_key)) == 0) &&
(strlen(search_node->device_name) == strlen(device_name)) &&
(memcmp(search_node->device_name, device_name, strlen(device_name)) == 0)) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
if (node) {
*node = search_node;
}
return SUCCESS_RETURN;
}
}
printf("Device Not Found, Product Key: %s, Device Name: %s", product_key, device_name);
return FAIL_RETURN;
}
static int _dm_mgr_next_devid(void)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
return ctx->global_devid++;
}
int dm_mgr_device_create(_IN_ int dev_type, _IN_ char product_key[PRODUCT_KEY_MAXLEN],
_IN_ char device_name[DEVICE_NAME_MAXLEN], _IN_ char device_secret[DEVICE_SECRET_MAXLEN], _OU_ int *devid)
{
int res = 0;
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *node = NULL;
if (product_key == NULL || device_name == NULL ||
strlen(product_key) >= PRODUCT_KEY_MAXLEN ||
strlen(device_name) >= DEVICE_NAME_MAXLEN) {
return INVALID_PARAMETER;
}
if (device_secret != NULL && strlen(device_secret) >= DEVICE_SECRET_MAXLEN) {
return INVALID_PARAMETER;
}
res = _dm_mgr_search_dev_by_pkdn(product_key, device_name, &node);
if (res == SUCCESS_RETURN) {
if (devid) {
*devid = node->devid;
}
return FAIL_RETURN;
}
node = malloc(sizeof(dm_mgr_dev_node_t));
if (node == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(node, 0, sizeof(dm_mgr_dev_node_t));
if(dev_type == KK_DM_DEVICE_GATEWAY)
node->devid = 1;
else
node->devid = _dm_mgr_next_devid();
node->dev_type = dev_type;
node->dev_shadow = NULL;
memcpy(node->product_key, product_key, strlen(product_key));
memcpy(node->device_name, device_name, strlen(device_name));
if (device_secret != NULL) {
memcpy(node->device_secret, device_secret, strlen(device_secret));
}
//node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED;
if(dev_type == KK_DM_DEVICE_SUBDEV){
res = kk_tsl_create(TSL_STRING,strlen(TSL_STRING),&node->dev_shadow);
if(res != 0)
{
return FAIL_RETURN;
}
}
INIT_LIST_HEAD(&node->linked_list);
list_add_tail(&node->linked_list, &ctx->dev_list);
if (devid) {
*devid = node->devid;
}
return SUCCESS_RETURN;
}
int dm_mgr_search_device_by_pkdn(_IN_ char product_key[PRODUCT_KEY_MAXLEN], _IN_ char device_name[DEVICE_NAME_MAXLEN],
_OU_ int *devid)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (product_key == NULL || device_name == NULL) {
return INVALID_PARAMETER;
}
res = _dm_mgr_search_dev_by_pkdn(product_key, device_name, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (devid) {
*devid = node->devid;
}
return SUCCESS_RETURN;
}
int dm_mgr_init(void)
{
int res = 0;
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
char product_key[PRODUCT_KEY_MAXLEN] = {0};
char device_name[DEVICE_NAME_MAXLEN] = {0};
char device_secret[DEVICE_SECRET_MAXLEN]= {0};
int devId = 0;
memset(ctx, 0, sizeof(dm_mgr_ctx));
/* Create Mutex */
ctx->mutex = kk_MutexCreate();
if (ctx->mutex == NULL) {
goto ERROR;
}
/* Init Device Id*/
ctx->global_devid = 1;
/* Init Device List */
INIT_LIST_HEAD(&ctx->dev_list);
/*----------to do************************ */
//HAL_GetProductKey(product_key);
//HAL_GetDeviceName(device_name);
//_dm_mgr_legacy_thing_created(IOTX_DM_LOCAL_NODE_DEVID);
res = dm_mgr_device_create(KK_DM_DEVICE_SUBDEV,product_key,product_key,device_secret,&devId);
if (res != SUCCESS_RETURN) {
goto ERROR;
}
return SUCCESS_RETURN;
ERROR:
if (ctx->mutex) {
kk_MutexDestroy(ctx->mutex);
}
memset(ctx, 0, sizeof(dm_mgr_ctx));
return FAIL_RETURN;
}
static int _dm_mgr_upstream_request_assemble(_IN_ int msgid, _IN_ int devid, _IN_ const char *service_prefix,
_IN_ const char *service_name,
_IN_ char *params, _IN_ int params_len, _IN_ char *method, _OU_ dm_msg_request_t *request)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
request->msgid = msgid;
request->devid = devid;
request->service_prefix = service_prefix;
request->service_name = service_name;
memcpy(request->product_key, node->product_key, strlen(node->product_key));
memcpy(request->device_name, node->device_name, strlen(node->device_name));
request->params = params;
request->params_len = params_len;
request->method = method;
return SUCCESS_RETURN;
}
static unsigned int g_report_id = 0;
int iotx_report_id(void)
{
return g_report_id++;
}
int dm_mgr_upstream_thing_property_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len)
{
int res = 0;
dm_msg_request_t request;
if (devid < 0 || payload == NULL || payload_len <= 0) {
return INVALID_PARAMETER;
}
memset(&request, 0, sizeof(dm_msg_request_t));
res = _dm_mgr_upstream_request_assemble(iotx_report_id(), devid, DM_URI_SYS_PREFIX, DM_URI_THING_EVENT_PROPERTY_POST,
payload, payload_len, "thing.event.property.post", &request);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Callback */
//request.callback = dm_client_thing_event_post_reply;
/* Send Message To Cloud */
res = dm_msg_request(&request);
return res;
}
#ifndef __KK_DM_MNG__
#define __KK_DM_MNG__
#include "kk_tsl_common.h"
#include "klist.h"
#define KK_DM_DEVICE_SINGLE (0x01)
#define KK_DM_DEVICE_SUBDEV (0x02)
#define KK_DM_DEVICE_GATEWAY (0x04)
typedef struct {
int devid;
int dev_type;
kk_tsl_t *dev_shadow;
char product_key[PRODUCT_KEY_MAXLEN];
char device_name[DEVICE_NAME_MAXLEN];
char device_secret[DEVICE_SECRET_MAXLEN];
//iotx_dm_dev_avail_t status;
//iotx_dm_dev_status_t dev_status;
struct list_head linked_list;
} dm_mgr_dev_node_t;
typedef struct {
void *mutex;
int global_devid;
struct list_head dev_list;
} dm_mgr_ctx;
typedef struct {
int msgid;
int devid;
const char *service_prefix;
const char *service_name;
char product_key[PRODUCT_KEY_MAXLEN];
char device_name[DEVICE_NAME_MAXLEN];
char *params;
int params_len;
char *method;
//iotx_cm_data_handle_cb callback;
} dm_msg_request_t;
#endif
#include "kk_dm_msg.h"
#include "kk_dm_mng.h"
#include "lite-cjson.h"
const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/";
const char DM_URI_THING_EVENT_PROPERTY_POST[] DM_READ_ONLY = "thing/event/property/post";
const char DM_MSG_REQUEST[] DM_READ_ONLY = "{\"id\":\"%d\",\"version\":\"%s\",\"params\":%.*s,\"method\":\"%s\"}";
int dm_msg_request (_IN_ dm_msg_request_t *request)
{
int res = 0, payload_len = 0;
char *payload = NULL, *uri = NULL;
lite_cjson_t lite;
if (request == NULL || request->params == NULL || request->method == NULL) {
return INVALID_PARAMETER;
}
/* Request URI */
res = kk_utils_service_name(request->service_prefix, request->service_name,
request->product_key, request->device_name, &uri);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + request->params_len + strlen(
request->method) + 1;
payload = malloc(payload_len);
if (payload == NULL) {
free(uri);
return MEMORY_NOT_ENOUGH;
}
memset(payload, 0, payload_len);
snprintf(payload, payload_len, DM_MSG_REQUEST, request->msgid,
DM_MSG_VERSION, request->params_len, request->params, request->method);
memset(&lite, 0, sizeof(lite_cjson_t));
res = lite_cjson_parse(payload, payload_len, &lite);
if (res < SUCCESS_RETURN) {
printf("Wrong JSON Format, URI: %s, Payload: %s", uri, payload);
free(uri);
free(payload);
return FAIL_RETURN;
}
printf("DM Send Message, URI: %s, Payload: %s", uri, payload);
//if (type & DM_MSG_DEST_CLOUD) {
//dm_client_publish(uri, (unsigned char *)payload, strlen(payload), request->callback);
//}
free(uri);
free(payload);
return SUCCESS_RETURN;
}
#ifndef __KK_DM_MSG__
#define __KK_DM_MSG__
#include "kk_tsl_common.h"
typedef enum {
IOTX_DM_EVENT_CLOUD_CONNECTED = 0,
IOTX_DM_EVENT_CLOUD_DISCONNECT,
IOTX_DM_EVENT_CLOUD_RECONNECT,
IOTX_DM_EVENT_LOCAL_CONNECTED,
IOTX_DM_EVENT_LOCAL_DISCONNECT,
IOTX_DM_EVENT_LOCAL_RECONNECT,
IOTX_DM_EVENT_FOUND_DEVICE,
IOTX_DM_EVENT_REMOVE_DEVICE,
IOTX_DM_EVENT_REGISTER_RESULT,
IOTX_DM_EVENT_UNREGISTER_RESULT,
IOTX_DM_EVENT_INITIALIZED,
IOTX_DM_EVENT_SEND_RESULT,
IOTX_DM_EVENT_ADD_SERVICE_RESULT,
IOTX_DM_EVENT_REMOVE_SERVICE_RESULT,
IOTX_DM_EVENT_NEW_DATA_RECEIVED,
IOTX_DM_EVENT_PROPERTY_SET,
IOTX_DM_EVENT_PROPERTY_GET,
IOTX_DM_EVENT_TOPO_ADD_NOTIFY,
IOTX_DM_EVENT_THING_SERVICE_REQUEST,
IOTX_DM_EVENT_THING_DISABLE,
IOTX_DM_EVENT_THING_ENABLE,
IOTX_DM_EVENT_THING_DELETE,
IOTX_DM_EVENT_MODEL_DOWN_RAW,
IOTX_DM_EVENT_GATEWAY_PERMIT,
IOTX_DM_EVENT_SUBDEV_REGISTER_REPLY,
IOTX_DM_EVENT_SUBDEV_UNREGISTER_REPLY,
IOTX_DM_EVENT_TOPO_ADD_REPLY,
IOTX_DM_EVENT_TOPO_DELETE_REPLY,
IOTX_DM_EVENT_TOPO_GET_REPLY,
IOTX_DM_EVENT_TOPO_ADD_NOTIFY_REPLY,
IOTX_DM_EVENT_EVENT_PROPERTY_POST_REPLY,
IOTX_DM_EVENT_EVENT_SPECIFIC_POST_REPLY,
IOTX_DM_EVENT_DEVICEINFO_UPDATE_REPLY,
IOTX_DM_EVENT_DEVICEINFO_DELETE_REPLY,
IOTX_DM_EVENT_DSLTEMPLATE_GET_REPLY,
IOTX_DM_EVENT_COMBINE_LOGIN_REPLY,
IOTX_DM_EVENT_COMBINE_LOGOUT_REPLY,
IOTX_DM_EVENT_MODEL_UP_RAW_REPLY,
IOTX_DM_EVENT_LEGACY_THING_CREATED,
IOTX_DM_EVENT_COTA_NEW_CONFIG,
IOTX_DM_EVENT_FOTA_NEW_FIRMWARE,
IOTX_DM_EVENT_NTP_RESPONSE,
IOTX_DM_EVENT_RRPC_REQUEST,
IOTX_DM_EVENT_MAX
} iotx_dm_event_types_t;
#ifndef DM_READ_ONLY
#define DM_READ_ONLY
#endif
#define DM_MSG_VERSION "1.0"
extern const char DM_URI_SYS_PREFIX[] DM_READ_ONLY;
extern const char DM_URI_THING_EVENT_PROPERTY_POST[] DM_READ_ONLY;
#endif
#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_tsl_load.h"
#include "kk_dm_mng.h"
typedef enum {
KK_MSG_PROPERTY_SET,
KK_MSG_SERVICE_SET
} kk_msg_set_type_t;
typedef int (*dm_get_shadow_data)(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data);
typedef int (*dm_set_shadow_data)(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len);
static int _kk_msg_set_object(kk_msg_set_type_t type, int devid, char *key, lite_cjson_t *root);
int kk_msg_get_property_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_tsl_get_property_data(node->dev_shadow, key, key_len, data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_get_event_output_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_get_event_output_data(node->dev_shadow, key, key_len, data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_set_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0 || value == NULL) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tls_set_event_output_value(node->dev_shadow, key, key_len, value, value_len);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_get_service_input_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_get_service_input_output_data(KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA, node->dev_shadow, key, key_len, data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_get_service_output_data(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_get_service_input_output_data(KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA, node->dev_shadow, key, key_len,
data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_set_service_input_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0 || value == NULL) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_set_service_input_output_value(KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA, node->dev_shadow, key, key_len,
value, value_len);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_set_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0 || value == NULL) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_set_service_input_output_value(KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA, node->dev_shadow, key, key_len,
value, value_len);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_msg_set_property_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (key == NULL || key_len <= 0 || value == NULL) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = dm_tsl_set_property_value(node->dev_shadow, key, key_len, value, value_len);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_msg_set_numberOrStr(kk_msg_set_type_t type, int devid, char *key, lite_cjson_t *root)
{
int res = 0;
void *data = NULL;
kk_tsl_data_type_e data_type;
dm_get_shadow_data get_shadow_data_func = (type == KK_MSG_PROPERTY_SET) ? (kk_msg_get_property_data) :
(kk_msg_get_service_input_data);
dm_set_shadow_data set_shadow_data_func = (type == KK_MSG_PROPERTY_SET) ? (kk_msg_set_property_value) :
(kk_msg_set_service_input_value);
/* dm_log_debug("Current Key: %s", key); */
res = get_shadow_data_func(devid, key, strlen(key), &data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_tsl_get_data_type(data, &data_type);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* dm_log_debug("Current Type: %d", data_type); */
switch (data_type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_BOOL: {
res = set_shadow_data_func(devid, key, strlen(key), &root->value_int, 0);
}
break;
case KK_TSL_DATA_TYPE_FLOAT: {
float value_float = (float)root->value_double;
res = set_shadow_data_func(devid, key, strlen(key), &value_float, 0);
}
break;
case KK_TSL_DATA_TYPE_DOUBLE: {
res = set_shadow_data_func(devid, key, strlen(key), &root->value_double, 0);
}
break;
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_DATE: {
res = set_shadow_data_func(devid, key, strlen(key), root->value, root->value_length);
}
break;
default:
printf("Unkonwn Number Type");
break;
}
return res;
}
static int _kk_msg_set_array(kk_msg_set_type_t type, int devid, char *key, lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item_value;
char *ascii_index = NULL;
char *new_key = NULL;
int new_key_len = 0;
for (index = 0; index < root->size; index++) {
res = lite_cjson_array_item(root, index, &lite_item_value);
if (res != SUCCESS_RETURN) {
continue;
}
/* dm_log_debug("Current Value: %.*s", lite_item_value.value_length, lite_item_value.value); */
res = kk_utils_itoa(index, &ascii_index);
if (res != SUCCESS_RETURN) {
continue;
}
/* Original Key '[' Index ']'*/
new_key_len = ((key == NULL) ? (0) : (strlen(key) + 1)) + 1 + strlen(ascii_index) + 1 + 1;
new_key = malloc(new_key_len);
if (new_key == NULL) {
free(ascii_index);
return MEMORY_NOT_ENOUGH;
}
memset(new_key, 0, new_key_len);
if (key) {
memcpy(new_key, key, strlen(key));
}
new_key[strlen(new_key)] = '[';
memcpy(new_key + strlen(new_key), ascii_index, strlen(ascii_index));
new_key[strlen(new_key)] = ']';
/* dm_log_debug("New Key: %s", new_key); */
free(ascii_index);
if (lite_cjson_is_object(&lite_item_value)) {
res = _kk_msg_set_object(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_array(&lite_item_value)) {
res = _kk_msg_set_array(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_number(&lite_item_value)) {
res = _kk_msg_set_numberOrStr(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_string(&lite_item_value)) {
res = _kk_msg_set_numberOrStr(type, devid, new_key, &lite_item_value);
}
free(new_key);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
return SUCCESS_RETURN;
}
static int _kk_msg_set_object(kk_msg_set_type_t type, int devid, char *key, lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item_key;
lite_cjson_t lite_item_value;
char *new_key = NULL;
int new_key_len = 0;
for (index = 0; index < root->size; index++) {
res = lite_cjson_object_item_by_index(root, index, &lite_item_key, &lite_item_value);
if (res != SUCCESS_RETURN) {
continue;
}
/* dm_log_debug("Current Key: %.*s, Value: %.*s",
lite_item_key.value_length, lite_item_key.value,
lite_item_value.value_length, lite_item_value.value); */
//new_key_len = lite_item_key.value_length + 1;
new_key_len = ((key == NULL) ? (0) : (strlen(key) + 1)) + lite_item_key.value_length + 1;
/* dm_log_debug("new_key_len: %d", new_key_len); */
new_key = malloc(new_key_len);
if (new_key == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(new_key, 0, new_key_len);
if (key) {
memcpy(new_key, key, strlen(key));
new_key[strlen(new_key)] = KK_MSG_KEY_DELIMITER;
}
memcpy(new_key + strlen(new_key), lite_item_key.value, lite_item_key.value_length);
/* dm_log_debug("New Key: %s", new_key); */
if (lite_cjson_is_object(&lite_item_value)) {
res = _kk_msg_set_object(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_array(&lite_item_value)) {
res = _kk_msg_set_array(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_number(&lite_item_value)) {
res = _kk_msg_set_numberOrStr(type, devid, new_key, &lite_item_value);
}
if (lite_cjson_is_string(&lite_item_value)) {
res = _kk_msg_set_numberOrStr(type, devid, new_key, &lite_item_value);
}
free(new_key);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
return SUCCESS_RETURN;
}
int kk_msg_property_set(int devid, kk_msg_request_payload_t *request)
{
int res = 0, message_len = 0;
char *message = NULL;
lite_cjson_t lite;
if (request == NULL) {
return INVALID_PARAMETER;
}
/* Parse Root */
memset(&lite, 0, sizeof(lite_cjson_t));
res = lite_cjson_parse(request->params.value, request->params.value_length, &lite);
if (res != SUCCESS_RETURN || (!lite_cjson_is_object(&lite) && !lite_cjson_is_array(&lite))) {
return JSON_PARSE_FAILED;
}
/* dm_log_info("Property Set, Size: %d", lite.size); */
if (lite_cjson_is_object(&lite)) {
res = _kk_msg_set_object(KK_MSG_PROPERTY_SET, devid, NULL, &lite);
}
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
#if 0
message_len = strlen(DM_MSG_PROPERTY_SET_FMT) + DM_UTILS_UINT32_STRLEN + request->params.value_length + 1;
message = DM_malloc(message_len);
if (message == NULL) {
return DM_MEMORY_NOT_ENOUGH;
}
memset(message, 0, message_len);
HAL_Snprintf(message, message_len, DM_MSG_PROPERTY_SET_FMT, devid, request->params.value_length, request->params.value);
res = _dm_msg_send_to_user(IOTX_DM_EVENT_PROPERTY_SET, message);
if (res != SUCCESS_RETURN) {
DM_free(message);
}
#endif
return SUCCESS_RETURN;
}
static int kk_msg_request_parse(_IN_ char *payload, _IN_ int payload_len, _OU_ kk_msg_request_payload_t *request)
{
lite_cjson_t lite;
if (payload == NULL || payload_len <= 0 || request == NULL) {
return INVALID_PARAMETER;
}
if (lite_cjson_parse(payload, payload_len, &lite) != SUCCESS_RETURN ||
lite_cjson_object_item(&lite, KK_MSG_KEY_ID, strlen(KK_MSG_KEY_ID), &request->id) != SUCCESS_RETURN ||
lite_cjson_object_item(&lite, KK_MSG_KEY_VERSION, strlen(KK_MSG_KEY_VERSION),
&request->version) != SUCCESS_RETURN ||
lite_cjson_object_item(&lite, KK_MSG_KEY_METHOD, strlen(KK_MSG_KEY_METHOD),
&request->method) != SUCCESS_RETURN ||
lite_cjson_object_item(&lite, KK_MSG_KEY_PARAMS, strlen(KK_MSG_KEY_PARAMS),
&request->params) != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Current Request Message ID: %.*s", request->id.value_length, request->id.value);
printf("Current Request Message Version: %.*s", request->version.value_length, request->version.value);
printf("Current Request Message Method: %.*s", request->method.value_length, request->method.value);
printf("Current Request Message Params: %.*s", request->params.value_length, request->params.value);
return SUCCESS_RETURN;
}
int kk_set_event_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ char *value_str)
{
int res = 0;
void *data = NULL;
kk_tsl_data_type_e type;
if (devid < 0 || key == NULL || key_len <= 0 || ((value == NULL) && (value_str == NULL))) {
return INVALID_PARAMETER;
}
res = kk_msg_get_event_output_data(devid, key, key_len, &data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_tsl_get_data_type(data, &type);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
switch (type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_BOOL: {
int value_int = (value == NULL) ? (atoi(value_str)) : (*(int *)value);
res = dm_tls_set_event_output_value(devid, key, key_len, &value_int, sizeof(int));
}
break;
case KK_TSL_DATA_TYPE_FLOAT: {
float value_float = (value == NULL) ? (atof(value_str)) : (*(float *)value);
res = dm_tls_set_event_output_value(devid, key, key_len, &value_float, sizeof(float));
}
break;
case KK_TSL_DATA_TYPE_DOUBLE: {
double value_double = (value == NULL) ? (atof(value_str)) : (*(double *)value);
res = dm_tls_set_event_output_value(devid, key, key_len, &value_double, sizeof(double));
}
break;
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_DATE: {
char *value_string = (value == NULL) ? (value_str) : (value);
res = dm_tls_set_event_output_value(devid, key, key_len, value_string, strlen(value_string));
}
break;
default: {
res = FAIL_RETURN;
}
break;
}
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_set_service_output_value(_IN_ int devid, _IN_ char *key, _IN_ int key_len,
_IN_ void *value,
_IN_ char *value_str)
{
int res = 0;
void *data = NULL;
kk_tsl_data_type_e type;
if (devid < 0 || key == NULL || key_len <= 0 || ((value == NULL) && (value_str == NULL))) {
return INVALID_PARAMETER;
}
res = kk_msg_get_service_output_data(devid, key, key_len, &data);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_tsl_get_data_type(data, &type);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
switch (type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_BOOL: {
int value_int = (value == NULL) ? (atoi(value_str)) : (*(int *)value);
res = kk_msg_set_service_output_value(devid, key, key_len, &value_int, sizeof(int));
}
break;
case KK_TSL_DATA_TYPE_FLOAT: {
float value_float = (value == NULL) ? (atof(value_str)) : (*(float *)value);
res = kk_msg_set_service_output_value(devid, key, key_len, &value_float, sizeof(float));
}
break;
case KK_TSL_DATA_TYPE_DOUBLE: {
double value_double = (value == NULL) ? (atof(value_str)) : (*(double *)value);
res = kk_msg_set_service_output_value(devid, key, key_len, &value_double, sizeof(double));
}
break;
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_DATE: {
char *value_string = (value == NULL) ? (value_str) : (value);
res = kk_msg_set_service_output_value(devid, key, key_len, value_string, strlen(value_string));
}
break;
default: {
res = FAIL_RETURN;
}
break;
}
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
/***********************************************************/
typedef struct {
void *mutex;
} kk_tsl_api_ctx_t;
static kk_tsl_api_ctx_t s_kk_tsl_api_ctx;
static kk_tsl_api_ctx_t *_kk_tsl_api_get_ctx(void)
{
return &s_kk_tsl_api_ctx;
}
static void _kk_tsl_api_lock(void)
{
kk_tsl_api_ctx_t *ctx = _kk_tsl_api_get_ctx();
if (ctx->mutex) {
kk_MutexLock(ctx->mutex);
}
}
static void _kk_tsl_api_unlock(void)
{
kk_tsl_api_ctx_t *ctx = _kk_tsl_api_get_ctx();
if (ctx->mutex) {
kk_MutexUnLock(ctx->mutex);
}
}
int kk_tsl_api_init(void)
{
kk_tsl_api_ctx_t *ctx = _kk_tsl_api_get_ctx();
memset(ctx, 0, sizeof(dm_mgr_ctx));
/* Create Mutex */
ctx->mutex = kk_MutexCreate();
if (ctx->mutex == NULL) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_tsl_set_value(kk_tsl_set_t set, int devId, const char *identifier,
const void *value,
const char *value_str)
{
int res = 0, devid = 0;
kk_tsl_api_ctx_t *kk_tsl_api_ctx = _kk_tsl_api_get_ctx();
if ( identifier == NULL || (value == NULL && value_str == NULL)) {
printf("Invalid Parameter");
return FAIL_RETURN;
}
_kk_tsl_api_lock();
switch (set) {
case kk_tsl_set_property_value: {
res = kk_msg_set_property_value(devid, (char *)identifier, strlen(identifier), (void *)value,
strlen(value));
}
break;
case kk_tsl_set_event_output_value: {
res = kk_set_event_output_value(devid, (char *)identifier, strlen(identifier), (void *)value,
(char *)value_str);
}
break;
case kk_tsl_set_service_output_value: {
res = kk_set_service_output_value(devid, (char *)identifier, strlen(identifier), (void *)value,
(char *)value_str);
}
break;
default: {
printf("Invalid Parameter");
res = FAIL_RETURN;
}
break;
}
if (res < SUCCESS_RETURN) {
_kk_tsl_api_unlock();
return FAIL_RETURN;
}
_kk_tsl_api_unlock();
return SUCCESS_RETURN;
}
int kk_msg_uri_parse_pkdn(_IN_ char *uri, _IN_ int uri_len, _IN_ int start_deli, _IN_ int end_deli,
_OU_ char product_key[PRODUCT_KEY_MAXLEN], _OU_ char device_name[DEVICE_NAME_MAXLEN])
{
int res = 0, start = 0, end = 0, slice = 0;
if (uri == NULL || uri_len <= 0 || product_key == NULL || device_name == NULL ||
(strlen(product_key) >= PRODUCT_KEY_MAXLEN) || (strlen(device_name) >= DEVICE_NAME_MAXLEN)) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(uri, uri_len, KK_URI_SERVICE_DELIMITER, start_deli, &start);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_utils_memtok(uri, uri_len, KK_URI_SERVICE_DELIMITER, start_deli + 1, &slice);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_utils_memtok(uri, uri_len, KK_URI_SERVICE_DELIMITER, end_deli, &end);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* dm_log_debug("URI Product Key: %.*s, Device Name: %.*s", slice - start - 1, uri + start + 1, end - slice - 1,
uri + slice + 1); */
memcpy(product_key, uri + start + 1, slice - start - 1);
memcpy(device_name, uri + slice + 1, end - slice - 1);
return SUCCESS_RETURN;
}
int kk_tsl_service_property_set(_IN_ kk_msg_source_t *source, _IN_ kk_msg_dest_t *dest,
_OU_ kk_msg_request_payload_t *request, _OU_ kk_msg_response_t *response)
{
int res = 0, devid = 0;
char product_key[PRODUCT_KEY_MAXLEN] = {0};
char device_name[DEVICE_NAME_MAXLEN] = {0};
/**************to do*******************/
//dm_log_info(DM_URI_THING_SERVICE_PROPERTY_SET);
/* Request */
res = kk_msg_uri_parse_pkdn((char *)source->uri, strlen(source->uri), 2 + KK_URI_OFFSET, 4 + KK_URI_OFFSET, product_key,
device_name);
if (res < SUCCESS_RETURN) {
return res;
}
res = dm_mgr_search_device_by_pkdn(product_key, device_name, &devid);
if (res < SUCCESS_RETURN) {
return res;
}
res = kk_msg_request_parse((char *)source->payload, source->payload_len, request);
if (res < SUCCESS_RETURN) {
return res ;
}
/* Operation */
res = kk_msg_property_set(devid, request);
/* Response */
//response->service_prefix = DM_URI_SYS_PREFIX;
response->service_name = dest->uri_name;
memcpy(response->product_key, product_key, strlen(product_key));
memcpy(response->device_name, device_name, strlen(device_name));
response->code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
dm_msg_response(&request, &response, "{}", strlen("{}"), NULL);
return SUCCESS_RETURN;
}
static int kk_tsl_post_property_start(_IN_ int devid, _OU_ void **handle)
{
dm_api_property_t *dapi_property = NULL;
if (devid < 0 || handle == NULL || *handle != NULL) {
return INVALID_PARAMETER;
}
dapi_property = malloc(sizeof(dm_api_property_t));
if (dapi_property == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(dapi_property, 0, sizeof(dm_api_property_t));
/* Create Mutex */
dapi_property->mutex = kk_MutexCreate();
if (dapi_property->mutex == NULL) {
free(dapi_property);
return MEMORY_NOT_ENOUGH;
}
/* Set Devid */
dapi_property->devid = devid;
/* Init Json Object */
dapi_property->lite = lite_cjson_create_object();
if (dapi_property->lite == NULL) {
free(dapi_property->mutex);
free(dapi_property);
return FAIL_RETURN;
}
*handle = (void *)dapi_property;
return SUCCESS_RETURN;
}
int kk_tsl_get_property_by_index(_IN_ int devid, _IN_ int index, _OU_ kk_tsl_data_t **property)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (devid < 0 || index < 0) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
*property = (kk_tsl_data_t *)(node->dev_shadow->properties + index);
return SUCCESS_RETURN;
}
int kk_tsl_get_property_number(_IN_ int devid, _OU_ int *number)
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if (devid < 0 || number == NULL) {
return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if(node->dev_shadow == NULL)
{
return FAIL_RETURN;
}
*number = node->dev_shadow->property_number;
return SUCCESS_RETURN;
}
static int _kk_tsl_post_property_add(_IN_ void *handle, _IN_ char *identifier, _IN_ int identifier_len)
{
int res = 0;
dm_api_property_t *dapi_property = NULL;
dm_mgr_dev_node_t *node = NULL;
if (handle == NULL || identifier == NULL || identifier_len <= 0) {
return INVALID_PARAMETER;
}
dapi_property = (dm_api_property_t *)handle;
/* Assemble Property Payload */
res = dm_mgr_search_dev_by_devid(dapi_property->devid, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
res = kk_tsl_assemble_property(dapi_property->devid, identifier, identifier_len, dapi_property->lite);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
int kk_tsl_post_property_add(_IN_ void *handle, _IN_ char *identifier, _IN_ int identifier_len)
{
int ret = SUCCESS_RETURN, res = 0, index = 0, number = 0;
kk_tsl_data_t *property_refer = NULL;
char *identifier_refer = NULL;
dm_api_property_t *dapi_property = NULL;
if (handle == NULL) {
return INVALID_PARAMETER;
}
dapi_property = (dm_api_property_t *)handle;
if (identifier != NULL) {
if (identifier_len <= 0) {
return FAIL_RETURN;
}
ret = _kk_tsl_post_property_add(handle, identifier, identifier_len);
return ret;
}
res = kk_tsl_get_property_number(dapi_property->devid, &number);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
for (index = 0; index < number; index++) {
property_refer = NULL;
identifier_refer = NULL;
res = kk_tsl_get_property_by_index(dapi_property->devid, index, &property_refer);
if (res != SUCCESS_RETURN) {
continue;
}
identifier_refer = property_refer->identifier;
res = _kk_tsl_post_property_add(handle, identifier_refer, strlen(identifier_refer));
if (res != SUCCESS_RETURN) {
ret = FAIL_RETURN;
}
}
return ret;
}
int kk_tsl_post_property_end(_IN_ void **handle)
{
int res = 0;
char *payload = NULL;
dm_api_property_t *dapi_property = NULL;
if (handle == NULL) {
return INVALID_PARAMETER;
}
dapi_property = *((dm_api_property_t **)handle);
payload = lite_cjson_print_unformatted(dapi_property->lite);
if (payload == NULL) {
lite_cjson_delete(dapi_property->lite);
if (dapi_property->mutex) {
HAL_MutexDestroy(dapi_property->mutex);
}
free(dapi_property);
return MEMORY_NOT_ENOUGH;
}
printf("Current Property Post Payload, Length: %d, Payload: %s", strlen(payload), payload);
res = dm_mgr_upstream_thing_property_post(dapi_property->devid, payload, strlen(payload));
free(payload);
lite_cjson_delete(dapi_property->lite);
if (dapi_property->mutex) {
kk_MutexDestroy(dapi_property->mutex);
}
free(dapi_property);
*handle = NULL;
return res;
}
int kk_tsl_post_property(int devId, const char *property_identifier)
{
int res = 0, devid = 0, msgid = 0, property_identifier_len = 0, post_property_reply = 0;
void *property_handle = NULL;
kk_tsl_api_ctx_t *kk_tsl_api_ctx = _kk_tsl_api_get_ctx();
_kk_tsl_api_lock();
res = kk_tsl_post_property_start(devid, &property_handle);
if (res != SUCCESS_RETURN) {
_kk_tsl_api_lock();
return FAIL_RETURN;
}
property_identifier_len = (property_identifier) ? (strlen((char *)property_identifier)) : (0);
res = kk_tsl_post_property_add(property_handle, (char *)property_identifier, property_identifier_len);
if (res != SUCCESS_RETURN) {
kk_tsl_post_property_end(&property_handle);
_kk_tsl_api_lock();
return FAIL_RETURN;
}
res = kk_tsl_post_property_end(&property_handle);
if (res < SUCCESS_RETURN) {
_kk_tsl_api_lock();
return FAIL_RETURN;
}
_kk_tsl_api_lock();
return SUCCESS_RETURN;
}
#ifndef _TSL_API_H__
#define _TSL_API_H__
#include "lite-cjson.h"
#include "kk_tsl_common.h"
#define KK_MSG_KEY_ID "id"
#define KK_MSG_KEY_VERSION "version"
#define KK_MSG_KEY_METHOD "method"
#define KK_MSG_KEY_PARAMS "params"
#define KK_MSG_KEY_CODE "code"
#define KK_MSG_KEY_DATA "data"
#define KK_MSG_KEY_MESSAGE "message"
typedef enum {
IOTX_DM_ERR_CODE_SUCCESS = 200,
IOTX_DM_ERR_CODE_REQUEST_ERROR = 400,
IOTX_DM_ERR_CODE_REQUEST_PARAMS_ERROR = 460,
IOTX_DM_ERR_CODE_REQUEST_TOO_MANY = 429,
IOTX_DM_ERR_CODE_NO_ACTIVE_SESSION = 520,
IOTX_DM_ERR_CODE_TIMEOUT = 100000
} iotx_dm_error_code_t;
typedef struct {
const char *uri;
unsigned char *payload;
unsigned int payload_len;
void *context;
} kk_msg_source_t;
typedef struct {
const char *uri_name;
} kk_msg_dest_t;
typedef struct {
lite_cjson_t id;
lite_cjson_t version;
lite_cjson_t method;
lite_cjson_t params;
} kk_msg_request_payload_t;
typedef struct {
lite_cjson_t id;
lite_cjson_t code;
lite_cjson_t data;
lite_cjson_t message;
} kk_msg_response_payload_t;
typedef struct {
int msgid;
int devid;
const char *service_prefix;
const char *service_name;
char product_key[PRODUCT_KEY_MAXLEN];
char device_name[DEVICE_NAME_MAXLEN];
char *params;
int params_len;
char *method;
//iotx_cm_data_handle_cb callback;
} kk_msg_request_t;
typedef struct {
const char *service_prefix;
const char *service_name;
char product_key[PRODUCT_KEY_MAXLEN];
char device_name[DEVICE_NAME_MAXLEN];
iotx_dm_error_code_t code;
} kk_msg_response_t;
typedef enum {
kk_tsl_set_property_value = 0,
kk_tsl_set_event_output_value,
kk_tsl_set_service_output_value,
kk_tsl_set_number,
} kk_tsl_set_t;
typedef struct {
void *mutex;
int devid;
lite_cjson_item_t *lite;
} dm_api_property_t;
#endif
#ifndef __KK_TSL_COM__
#define __KK_TSL_COM__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _IN_
#define _IN_
#endif
#ifndef _OU_
#define _OU_
#endif
#define PRODUCT_KEY_MAXLEN (20 + 1)
#define DEVICE_NAME_MAXLEN (32 + 1)
#define DEVICE_SECRET_MAXLEN (64 + 1)
#define DM_UTILS_UINT16_STRLEN (5)
#define DM_UTILS_UINT32_STRLEN (10)
#define DM_UTILS_UINT64_STRLEN (20)
#define KK_TSL_KEY_SCHEMA "schema"
#define KK_TSL_KEY_LINK "link"
#define KK_TSL_KEY_PROFILE "profile"
#define KK_TSL_KEY_PROPERTIES "properties"
#define KK_TSL_KEY_EVENTS "events"
#define KK_TSL_KEY_SERVICES "services"
#define KK_TSL_KEY_PROFILE_PK "productKey"
#define KK_TSL_KEY_PROFILE_DN "deviceName"
#define KK_TSL_KEY_IDENTIFIER "identifier"
#define KK_TSL_KEY_NAME "name"
#define KK_TSL_KEY_DESC "desc"
#define KK_TSL_KEY_ACCESS_MODE "accessMode"
#define KK_TSL_KEY_REQUIRED "required"
#define KK_TSL_KEY_METHOD "method"
#define KK_TSL_KEY_CALLTYPE "callType"
#define KK_TSL_KEY_OUTPUTDATA "outputData"
#define KK_TSL_KEY_INPUTDATA "inputData"
#define KK_TSL_KEY_DATATYPE "dataType"
#define KK_TSL_KEY_TYPE "type"
#define KK_TSL_KEY_SPECS "specs"
#define KK_TSL_KEY_UNIT "unit"
#define KK_TSL_KEY_UNITNAME "unitName"
#define KK_TSL_KEY_MIN "min"
#define KK_TSL_KEY_MAX "max"
#define KK_TSL_KEY_LENGTH "length"
#define KK_TSL_KEY_SIZE "size"
#define KK_TSL_KEY_ITEM "item"
#define KK_MSG_KEY_DELIMITER '.'
#define KK_URI_SERVICE_DELIMITER '/'
#define KK_URI_OFFSET 1
//Special Service And Event
#define KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER "set"
#define KK_TSL_SPECIAL_SERVICE_SET_METHOD "thing.service.property.set"
#define KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER "get"
#define KK_TSL_SPECIAL_SERVICE_GET_METHOD "thing.service.property.get"
#define KK_TSL_SPECIAL_EVENT_POST_IDENTIFIER "post"
#define KK_TSL_SPECIAL_EVENT_POST_METHOD "thing.event.property.post"
typedef enum {
KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA,
KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA
} kk_tsl_data_target_e;
typedef enum {
TSL_SERVICE_GET_FAILED = -13,
TSL_SERVICE_SET_FAILED = -12,
TSL_EVENT_GET_FAILED = -11,
TSL_EVENT_SET_FAILED = -10,
TSL_PROPERTY_GET_FAILED = -9,
TSL_PROPERTY_SET_FAILED = -8,
TSL_EVENT_NOT_EXIST = -7,
TSL_PROPERTY_NOT_EXIST = -6,
TSL_SERVICE_NOT_EXIST = -5,
JSON_PARSE_FAILED = -4,
MEMORY_NOT_ENOUGH = -3,
INVALID_PARAMETER = -2,
FAIL_RETURN = -1,
SUCCESS_RETURN = 0,
} kk_tsl_error_code_t;
typedef enum {
KK_TSL_DATA_TYPE_NONE, //none
KK_TSL_DATA_TYPE_INT, //int
KK_TSL_DATA_TYPE_FLOAT, //float
KK_TSL_DATA_TYPE_DOUBLE, //double
KK_TSL_DATA_TYPE_TEXT, //string
KK_TSL_DATA_TYPE_ENUM, //int
KK_TSL_DATA_TYPE_DATE, //string
KK_TSL_DATA_TYPE_BOOL, //bool,0 or 1
KK_TSL_DATA_TYPE_ARRAY, //support int, float, double, text
KK_TSL_DATA_TYPE_STRUCT, //support above 8 data types
} kk_tsl_data_type_e;
typedef struct {
kk_tsl_data_type_e type;
int size;
void *value;
} kk_tsl_data_value_complex_t;
typedef struct {
kk_tsl_data_type_e type;
union {
int value_int;
float value_float;
double value_double;
void *value; //string or complex type accroding to data type
};
} kk_tsl_data_value_t;
typedef struct {
char *identifier;
kk_tsl_data_value_t data_value;
} kk_tsl_data_t;
typedef struct {
char *identifier;
int input_data_number; //input_data Number
kk_tsl_data_t *input_datas; //input_data array, type is dm_shw_data_t
int output_data_number; //ouput_data Number
kk_tsl_data_t *output_datas; //output_data array, type is dm_shw_data_t
} kk_tsl_event_t;
typedef struct {
char *identifier; //synchronized or asynchronized
int input_data_number; //input_data_number
kk_tsl_data_t *input_datas; //input_data array, type is dm_shw_data_t
int output_data_number; //ouput_data Number
kk_tsl_data_t *output_datas; //output_data array, type is dm_shw_data_t
} kk_tsl_service_t;
typedef struct {
int property_number;
kk_tsl_data_t *properties; //property array, type is dm_shw_data_t
int event_number;
kk_tsl_event_t *events; //event array, type is dm_shw_event_t
int service_number;
kk_tsl_service_t *services; //service array, type is dm_shw_service_t
} kk_tsl_t;
#endif
#include "kk_tsl_common.h"
typedef int (*kk_tsl_data_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
typedef int (*kk_tsl_array_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
typedef int (*kk_tsl_data_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
typedef int (*kk_tsl_array_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
typedef void (*kk_tsl_data_free)(_IN_ kk_tsl_data_value_t *data_value);
typedef void (*kk_tsl_array_free)(_IN_ kk_tsl_data_value_t *data_value);
typedef void (*kk_tsl_data_print)(_IN_ kk_tsl_data_value_t *data_value);
typedef struct {
kk_tsl_data_type_e type;
const char *name;
kk_tsl_data_set func_set;
kk_tsl_array_set func_array_set;
kk_tsl_data_get func_get;
kk_tsl_array_get func_array_get;
kk_tsl_data_free func_free;
kk_tsl_array_free func_array_free;
} kk_tsl_data_type_mapping_t;
//Data Set
static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
//Array Data Set
static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index);
//Data Get
static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
//Array Data Get
static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
//Data Free
static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property);
//Array Data Free
static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value);
static kk_tsl_data_type_mapping_t g_iotx_data_type_mapping[] = {
{KK_TSL_DATA_TYPE_NONE, "none", NULL, NULL, NULL, NULL, NULL, NULL },
{KK_TSL_DATA_TYPE_INT, "int", _kk_tsl_int_set, _kk_tsl_array_int_set, _kk_tsl_int_get, _kk_tsl_array_int_get, _kk_tsl_int_free, _kk_tsl_array_int_free },
{KK_TSL_DATA_TYPE_FLOAT, "float", _kk_tsl_float_set, _kk_tsl_array_float_set, _kk_tsl_float_get, _kk_tsl_array_float_get, _kk_tsl_float_free, _kk_tsl_array_float_free, },
{KK_TSL_DATA_TYPE_DOUBLE, "double", _kk_tsl_double_set, _kk_tsl_array_double_set, _kk_tsl_double_get, _kk_tsl_array_double_get, _kk_tsl_double_free, _kk_tsl_array_double_free, },
{KK_TSL_DATA_TYPE_TEXT, "text", _kk_tsl_text_set, _kk_tsl_array_text_set, _kk_tsl_text_get, _kk_tsl_array_text_get, _kk_tsl_text_free, _kk_tsl_array_text_free, },
{KK_TSL_DATA_TYPE_ENUM, "enum", _kk_tsl_enum_set, _kk_tsl_array_enum_set, _kk_tsl_enum_get, _kk_tsl_array_enum_get, _kk_tsl_enum_free, _kk_tsl_array_enum_free, },
{KK_TSL_DATA_TYPE_DATE, "date", _kk_tsl_date_set, _kk_tsl_array_date_set, _kk_tsl_date_get, _kk_tsl_array_date_get, _kk_tsl_date_free, _kk_tsl_array_date_free, },
{KK_TSL_DATA_TYPE_BOOL, "bool", _kk_tsl_bool_set, _kk_tsl_array_bool_set, _kk_tsl_bool_get, _kk_tsl_array_bool_get, _kk_tsl_bool_free, _kk_tsl_array_bool_free, },
{KK_TSL_DATA_TYPE_ARRAY, "array", NULL, NULL, NULL, NULL, _kk_tsl_array_free, _kk_tsl_array_array_free, },
{KK_TSL_DATA_TYPE_STRUCT, "struct", NULL, NULL, NULL, NULL, _kk_tsl_struct_free, _kk_tsl_array_struct_free, }
};
static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
float float_set = (value == NULL) ? (0) : (*(float *)value);
data_value->value_float = float_set;
printf("Current Float Value Be Set(Float): %f", data_value->value_float);
return SUCCESS_RETURN;
}
static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
double double_set = (value == NULL) ? (0) : (*(double *)value);
data_value->value_double = double_set;
printf("Current Double Value Be Set(Double): %f", data_value->value_double);
return SUCCESS_RETURN;
}
static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
int res = 0;
char *value_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (data_value->value) {
free(data_value->value);
data_value->value = NULL;
}
res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1);
if (res != SUCCESS_RETURN) {
return MEMORY_NOT_ENOUGH;
}
printf("Current Text Value Be Set(String): %s", data_value->value);
return SUCCESS_RETURN;
}
static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
int enum_set = (value == NULL) ? (0) : (*(int *)value);
enum_set = (enum_set < 0) ? (0) : (enum_set);
data_value->value_int = enum_set;
printf("Current Enum Value Be Set(Enum): %d", data_value->value_int);
return SUCCESS_RETURN;
}
static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
int res = 0;
char *value_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (data_value->value) {
free(data_value->value);
data_value->value = NULL;
}
res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1);
if (res != SUCCESS_RETURN) {
return MEMORY_NOT_ENOUGH;
}
printf("Current Date Value Be Set(String): %s", data_value->value);
return SUCCESS_RETURN;
}
static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
int int_set = (value == NULL) ? (0) : (*(int *)value);
int_set = (int_set == 0) ? (int_set) : ((int_set == 1) ? (int_set) : (0));
data_value->value_int = int_set;
printf("Current Bool Value Be Set(Bool): %d", data_value->value_int);
return SUCCESS_RETURN;
}
static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
int int_set = (value == NULL) ? (0) : (*(int *)value);
data_value->value_int = int_set;
printf("Current Int Value Be Set(Int): %d", data_value->value_int);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
char *text_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL;
}
res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Current Array Value Be Set(Text String), Index: %d, Value: %s", index,
*((char **)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Enum), Index: %d, Value: %d", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
char *text_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL;
}
res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Current Array Value Be Set(Date String), Index: %d, Value: %s", index,
*((char **)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
*(float *)(value) = data_value->value_float;
return SUCCESS_RETURN;
}
static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
*(double *)(value) = data_value->value_double;
return SUCCESS_RETURN;
}
static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
int res = 0;
if (*(char **)value != NULL || data_value->value == NULL) {
return FAIL_RETURN;
}
res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
*(int *)(value) = data_value->value_int;
return SUCCESS_RETURN;
}
static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
int res = 0;
if (*(char **)value != NULL || data_value->value == NULL) {
return FAIL_RETURN;
}
res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
*(int *)(value) = data_value->value_int;
return SUCCESS_RETURN;
}
static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER;
}
*((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((float *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER;
}
*((float *)value) = *((float *)(complex_array->value) + index);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((double *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER;
}
*((double *)value) = *((double *)(complex_array->value) + index);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) {
return INVALID_PARAMETER;
}
res = kk_utils_copy_direct(*((char **)(complex_array->value) + index),
strlen(*((char **)(complex_array->value) + index)),
(void **)value, strlen(*((char **)(complex_array->value) + index)) + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER;
}
*((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) {
return INVALID_PARAMETER;
}
res = kk_utils_copy_direct(*((char **)(complex_array->value) + index),
strlen(*((char **)(complex_array->value) + index)),
(void **)value, strlen(*((char **)(complex_array->value) + index)) + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER;
}
*((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN;
}
static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
}
static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
}
static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
}
static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
if (data_value->value) {
free(data_value->value);
data_value->value = NULL;
}
}
static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
}
static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
if (data_value->value) {
free(data_value->value);
data_value->value = NULL;
}
}
static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value)
{
//Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
}
static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value)
{
int index = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value
if (complex_array) {
for (index = 0; index < complex_array->size; index++) {
if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL;
}
}
}
}
static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value)
{
int index = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value
if (complex_array) {
for (index = 0; index < complex_array->size; index++) {
if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL;
}
}
}
}
static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value)
{
}
static void _kk_tsl_data_free(kk_tsl_data_value_t *data_value)
{
if (g_iotx_data_type_mapping[data_value->type].func_free == NULL) {
return;
}
g_iotx_data_type_mapping[data_value->type].func_free(data_value);
}
static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property)
{
if (property->identifier) {
free(property->identifier);
}
_kk_tsl_data_free(&property->data_value);
}
static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value)
{
int index = 0;
kk_tsl_data_t *data = NULL;
kk_tsl_data_value_complex_t *complex_struct = (kk_tsl_data_value_complex_t *)data_value->value;
if (complex_struct) {
for (index = 0; index < complex_struct->size; index++) {
data = (kk_tsl_data_t *)complex_struct->value + index;
_kk_tsl_property_free(data);
}
}
}
static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value
if (complex_array) {
/* dm_log_err("complex_array->type: %d",complex_array->type); */
if (g_iotx_data_type_mapping[complex_array->type].func_array_free != NULL) {
g_iotx_data_type_mapping[complex_array->type].func_array_free(data_value);
}
if (complex_array->value) {
free(complex_array->value);
}
free(complex_array);
data_value->value = NULL;
}
}
static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value)
{
int index = 0;
kk_tsl_data_t *property = NULL;
kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value
if (complex_array) {
for (index = 0; index < complex_array->size; index++) {
property = (kk_tsl_data_t *)(complex_array->value) + index;
_kk_tsl_property_free(property);
}
if (complex_array->value) {
free(complex_array->value);
}
free(complex_array);
data_value->value = NULL;
}
}
static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Bool), Index: %d, Value: %d", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Int), Index: %d, Value: %d", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
float float_set = (value == NULL) ? (0) : (*(float *)value);
*((float *)(complex_array->value) + index) = float_set;
printf("Current Array Value Be Set(Float), Index: %d, Value: %f", index,
*((float *)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
double double_set = (value == NULL) ? (0) : (*(double *)value);
*((double *)(complex_array->value) + index) = double_set;
printf("Current Array Value Be Set(Double), Index: %d, Value: %f", index,
*((double *)(complex_array->value) + index));
return SUCCESS_RETURN;
}
static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{
*(int *)(value) = data_value->value_int;
return SUCCESS_RETURN;
}
static int _kk_tsl_data_array_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index)
{
kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array == NULL || index < 0 || index >= complex_array->size) {
return INVALID_PARAMETER;
}
if (g_iotx_data_type_mapping[complex_array->type].func_array_set == NULL) {
return FAIL_RETURN;
}
return g_iotx_data_type_mapping[complex_array->type].func_array_set(data_value, value, value_len, index);
}
static int _kk_tsl_data_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{
if (g_iotx_data_type_mapping[data_value->type].func_set == NULL) {
return FAIL_RETURN;
}
return g_iotx_data_type_mapping[data_value->type].func_set(data_value, value, value_len);
}
int dm_tsl_set_property_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0, array_index = 0;
kk_tsl_data_t *data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return FAIL_RETURN;
}
printf("Key:%d %s", key_len, key);
res = _kk_tsl_property_search(shadow, key, key_len, &data, &array_index);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
if (data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
printf("Current Found Data Index: %d", array_index);
res = _kk_tsl_data_array_set(&data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) {
return TSL_PROPERTY_SET_FAILED;
}
} else {
res = _kk_tsl_data_set(&data->data_value, value, value_len);
if (res != SUCCESS_RETURN) {
return TSL_PROPERTY_SET_FAILED;
}
}
return SUCCESS_RETURN;
}
static int _kk_tsl_event_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_event_t **event)
{
int index = 0;
kk_tsl_event_t *dtsl_event = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
for (index = 0; index < shadow->event_number; index++) {
dtsl_event = shadow->events + index;
if ((strlen(dtsl_event->identifier) == key_len) &&
(memcmp(dtsl_event->identifier, key, key_len) == 0)) {
/* dm_log_debug("TSL Event Found: %s",dtsl_event->identifier); */
if (event) {
*event = dtsl_event;
}
return SUCCESS_RETURN;
}
}
/* dm_log_debug("TSL Event Not Found: %.*s",key_len,key); */
return FAIL_RETURN;
}
static int _kk_tsl_event_output_search(_IN_ kk_tsl_data_t *outputdatas, _IN_ int number, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **event_data, _OU_ int *index)
{
int res = 0, item_index = 0;
kk_tsl_data_t *outputdata = NULL;
if (outputdatas == NULL || number <= 0 || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
for (item_index = 0; item_index < number; item_index++) {
outputdata = outputdatas + item_index;
res = kk_tsl_data_search(outputdata, key, key_len, event_data, index);
if (res == SUCCESS_RETURN) {
return SUCCESS_RETURN;
}
}
return SUCCESS_RETURN;
}
int dm_tsl_get_event_output_data(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
int offset = 0, array_index = 0;
char *pos = NULL;
kk_tsl_event_t *event = NULL;
kk_tsl_data_t *event_data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Key: %.*s", key_len, key);
res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
pos = key + offset + 1;
/* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */
res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
if (data) {
*data = (void *)event_data;
}
return SUCCESS_RETURN;
}
int dm_tls_set_event_output_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len)
{
int res = 0, array_index = 0;
int offset = 0;
char *pos = NULL;
kk_tsl_event_t *event = NULL;
kk_tsl_data_t *event_data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Key: %.*s", key_len, key);
res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
pos = key + offset + 1;
/* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */
res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
if (event_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
res = _kk_tsl_data_array_set(&event_data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_SET_FAILED;
}
} else {
res = _kk_tsl_data_set(&event_data->data_value, value, value_len);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_SET_FAILED;
}
}
return SUCCESS_RETURN;
}
static int _kk_tsl_service_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len,
_OU_ kk_tsl_service_t **service)
{
int index = 0;
kk_tsl_service_t *dtsl_service = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
for (index = 0; index < shadow->service_number; index++) {
dtsl_service = shadow->services + index;
if ((strlen(dtsl_service->identifier) == key_len) &&
(memcmp(dtsl_service->identifier, key, key_len) == 0)) {
/* dm_log_debug("TSL Service Found: %s",dtsl_service->identifier); */
if (service) {
*service = dtsl_service;
}
return SUCCESS_RETURN;
}
}
/* dm_log_debug("TSL Service Not Found: %.*s",key_len,key); */
return FAIL_RETURN;
}
static int _kk_tsl_service_input_output_search(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_service_t *service,
_IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_data_t **service_data, _OU_ int *index)
{
int res = 0, item_index = 0, datas_number = 0;
kk_tsl_data_t *datas = NULL;
kk_tsl_data_t *data = NULL;
if (type == KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA) {
datas = service->input_datas;
datas_number = service->input_data_number;
} else {
datas = service->output_datas;
datas_number = service->output_data_number;
}
for (item_index = 0; item_index < datas_number; item_index++) {
data = datas + item_index;
res = kk_tsl_data_search(data, key, key_len, service_data, index);
if (res == SUCCESS_RETURN) {
return SUCCESS_RETURN;
}
}
return SUCCESS_RETURN;
}
int dm_tsl_get_service_input_output_data(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
_IN_ int key_len, _OU_ void **data)
{
int res = 0;
int offset = 0, array_index = 0;
char *pos = NULL;
kk_tsl_service_t *service = NULL;
kk_tsl_data_t *service_data = NULL;
if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL
|| key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Key: %.*s", key_len, key);
res = _kk_tsl_service_search(shadow, key, offset, &service);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
pos = key + offset + 1;
printf("TSL Service input/output Data Search, Event Data ID: %s", pos);
res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index);
if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST;
}
if (data) {
*data = (void *)service_data;
}
return SUCCESS_RETURN;
}
int dm_tsl_set_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
_IN_ int key_len, _IN_ void *value, _IN_ int value_len)
{
int res = 0, array_index = 0;
int offset = 0;
char *pos = NULL;
kk_tsl_service_t *service = NULL;
kk_tsl_data_t *service_data = NULL;
if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL
|| key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Key: %.*s", key_len, key);
res = _kk_tsl_service_search(shadow, key, offset, &service);
if (res != SUCCESS_RETURN) {
return TSL_SERVICE_NOT_EXIST;
}
pos = key + offset + 1;
printf("TSL Service Input/Output Data Search, Event Data ID: %s", pos);
res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index);
if (res != SUCCESS_RETURN) {
return TSL_SERVICE_NOT_EXIST;
}
if (service_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
res = _kk_tsl_data_array_set(&service_data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) {
return TSL_SERVICE_SET_FAILED;
}
} else {
res = _kk_tsl_data_set(&service_data->data_value, value, value_len);
if (res != SUCCESS_RETURN) {
return TSL_SERVICE_SET_FAILED;
}
}
return SUCCESS_RETURN;
}
int kk_tsl_get_data_type(_IN_ void *data, _OU_ kk_tsl_data_type_e *type)
{
kk_tsl_data_t *data_item = (kk_tsl_data_t *)data;
if (data_item == NULL || type == NULL) {
return INVALID_PARAMETER;
}
if (data_item->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
kk_tsl_data_value_complex_t *complex_value = (kk_tsl_data_value_complex_t *)data_item->data_value.value;
*type = complex_value->type;
} else {
*type = data_item->data_value.type;
}
return SUCCESS_RETURN;
}
#ifndef _DM_SHADOW_H_
#define _DM_SHADOW_H_
#include "kk_tsl_common.h"
int kk_tsl_create(_IN_ const char *tsl, _IN_ int tsl_len, _OU_ kk_tsl_t **shadow);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lite-cjson.h"
#include "kk_tsl_load.h"
typedef int (*kk_tsl_data_parse)(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
typedef int (*kk_tsl_array_parse)(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
typedef struct {
kk_tsl_data_type_e type;
const char *name;
kk_tsl_data_parse func_parse;
kk_tsl_array_parse func_array_parse;
} kk_tsl_mapping_t;
static int _kk_tsl_data_array_search(_IN_ kk_tsl_data_t *input, _IN_ int input_index, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **output, _OU_ int *output_index);
//Data Parse
static int _kk_tsl_int_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_float_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_double_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_text_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_enum_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_date_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_bool_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_struct_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_property_parse(_IN_ kk_tsl_data_t *property, _IN_ lite_cjson_t *root);
//Array Data Parse
static int _kk_tsl_array_int_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_float_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_double_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_text_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_enum_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_date_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_bool_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_array_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static int _kk_tsl_array_struct_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root);
static kk_tsl_mapping_t s_kk_tsl_mapping[] = {
{KK_TSL_DATA_TYPE_NONE, "none", NULL, NULL },
{KK_TSL_DATA_TYPE_INT, "int", _kk_tsl_int_parse, _kk_tsl_array_int_parse },
{KK_TSL_DATA_TYPE_FLOAT, "float", _kk_tsl_float_parse, _kk_tsl_array_float_parse },
{KK_TSL_DATA_TYPE_DOUBLE, "double", _kk_tsl_double_parse, _kk_tsl_array_double_parse },
{KK_TSL_DATA_TYPE_TEXT, "text", _kk_tsl_text_parse, _kk_tsl_array_text_parse },
{KK_TSL_DATA_TYPE_ENUM, "enum", _kk_tsl_enum_parse, _kk_tsl_array_enum_parse },
{KK_TSL_DATA_TYPE_DATE, "date", _kk_tsl_date_parse, _kk_tsl_array_date_parse },
{KK_TSL_DATA_TYPE_BOOL, "bool", _kk_tsl_bool_parse, _kk_tsl_array_bool_parse },
{KK_TSL_DATA_TYPE_ARRAY, "array", _kk_tsl_array_parse, _kk_tsl_array_array_parse },
{KK_TSL_DATA_TYPE_STRUCT, "struct", _kk_tsl_struct_parse, _kk_tsl_array_struct_parse }
};
static int _kk_tsl_get_type(_IN_ const char *name, _IN_ int name_len, _OU_ kk_tsl_data_type_e *type)
{
if (name == NULL || name_len <= 0 || type == NULL) {
return INVALID_PARAMETER;
}
int index = 0;
for (index = 0; index < sizeof(s_kk_tsl_mapping) / sizeof(kk_tsl_mapping_t); index++) {
if (strlen(s_kk_tsl_mapping[index].name) == name_len &&
memcmp(s_kk_tsl_mapping[index].name, name, name_len) == 0) {
*type = s_kk_tsl_mapping[index].type;
return SUCCESS_RETURN;
}
}
return FAIL_RETURN;
}
static int _kk_tsl_int_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_float_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_double_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_text_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_enum_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_date_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_bool_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_array_int_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(int)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(int)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_float_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(float)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(float)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
int res = 0;
char size_str[DM_UTILS_UINT32_STRLEN] = {0};
lite_cjson_t lite_item, lite_type, lite_specs;
kk_tsl_data_value_complex_t *complex_array = NULL;
/* dm_log_debug("DM_SHW_DATA_TYPE_ARRAY"); */
if (root == NULL || !lite_cjson_is_object(root)) {
return INVALID_PARAMETER;
}
//Allocate Memory For Data Type Specs
complex_array = malloc(sizeof(kk_tsl_data_value_complex_t));
if (complex_array == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array, 0, sizeof(kk_tsl_data_value_complex_t));
data_value->value = (void *)complex_array;
//Parse Size (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_SIZE, strlen(KK_TSL_KEY_SIZE), &lite_item);
if (res != SUCCESS_RETURN && !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
if (lite_item.value_length > DM_UTILS_UINT32_STRLEN) {
return FAIL_RETURN;
}
memcpy(size_str, lite_item.value, lite_item.value_length);
complex_array->size = atoi(size_str);
/* dm_log_debug("TSL Property Array Size: %d",complex_array->size); */
//Parse Item And Type (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_ITEM, strlen(KK_TSL_KEY_ITEM), &lite_item);
if (res != SUCCESS_RETURN && !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
memset(&lite_type, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(&lite_item, KK_TSL_KEY_TYPE, strlen(KK_TSL_KEY_TYPE), &lite_type);
if (res != SUCCESS_RETURN && !lite_cjson_is_string(&lite_type)) {
return JSON_PARSE_FAILED;
}
res = _kk_tsl_get_type(lite_type.value, lite_type.value_length, &complex_array->type);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* dm_log_debug("TSL Property Array Type: %d",complex_array->type); */
//Parse Specs (Optional)
memset(&lite_specs, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(&lite_item, KK_TSL_KEY_SPECS, strlen(KK_TSL_KEY_SPECS), &lite_specs);
if ((complex_array->type == KK_TSL_DATA_TYPE_ARRAY || complex_array->type == KK_TSL_DATA_TYPE_STRUCT) &&
(res != SUCCESS_RETURN)) {
return JSON_PARSE_FAILED;
}
if (s_kk_tsl_mapping[complex_array->type].func_array_parse == NULL) {
return FAIL_RETURN;
}
/* dm_log_debug("TSL Property Specs Type: %s",g_dm_tsl_alink_mapping[complex_array->type].name); */
//Parse Array Type
res = s_kk_tsl_mapping[complex_array->type].func_array_parse(data_value, &lite_specs);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_struct_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item;
kk_tsl_data_t *property = NULL;
kk_tsl_data_value_complex_t *complex_struct = NULL;
/* dm_log_debug("DM_SHW_DATA_TYPE_STRUCT"); */
if (root == NULL || !lite_cjson_is_array(root) || root->size == 0) {
return INVALID_PARAMETER;
}
/* dm_log_debug("TSL Property Struct Size: %d",root->size); */
//Allocate Memory For Data Type Specs
complex_struct = malloc(sizeof(kk_tsl_data_value_complex_t));
if (complex_struct == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_struct, 0, sizeof(kk_tsl_data_value_complex_t));
data_value->value = (void *)complex_struct;
complex_struct->size = root->size;
//Allocate Memory For Multi Identifier
complex_struct->value = malloc((complex_struct->size) * (sizeof(kk_tsl_data_t)));
if (complex_struct->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_struct->value, 0, (complex_struct->size) * (sizeof(kk_tsl_data_t)));
for (index = 0; index < complex_struct->size; index++) {
memset(&lite_item, 0, sizeof(lite_cjson_t));
property = (kk_tsl_data_t *)complex_struct->value + index;
/* dm_log_debug("TSL Property Struct Index: %d",index); */
res = lite_cjson_array_item(root, index, &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
/* dm_log_debug("TSL Property Struct Property: %.*s",lite_item.value_length,lite_item.value); */
res = _kk_tsl_property_parse(property, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
return SUCCESS_RETURN;
}
static int _kk_tsl_array_double_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(double)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(double)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_text_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(char *)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(char *)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_enum_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(int)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(int)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_date_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(char *)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(char *)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_bool_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
complex_array->value = malloc((complex_array->size) * (sizeof(int)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(int)));
return SUCCESS_RETURN;
}
static int _kk_tsl_array_array_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
return SUCCESS_RETURN;
}
static int _kk_tsl_array_struct_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
kk_tsl_data_value_complex_t *complex_array = (kk_tsl_data_value_complex_t *)data_value->value;
kk_tsl_data_t *data = NULL;
if (!lite_cjson_is_array(root) || root->size <= 0) {
return INVALID_PARAMETER;
}
printf("Array Struct Size: %d", complex_array->size);
complex_array->value = malloc((complex_array->size) * (sizeof(kk_tsl_data_t)));
if (complex_array->value == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(complex_array->value, 0, (complex_array->size) * (sizeof(kk_tsl_data_t)));
printf("Array Struct Spec Size: %d", root->size);
for (index = 0; index < complex_array->size; index++) {
data = (kk_tsl_data_t *)complex_array->value + index;
data->data_value.type = KK_TSL_DATA_TYPE_STRUCT;
res = _kk_tsl_struct_parse(&data->data_value, root);
if (res != SUCCESS_RETURN) {
continue;
}
}
return SUCCESS_RETURN;
}
static int _kk_tsl_data_parse(_IN_ kk_tsl_data_value_t *data_value, _IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
memset(data_value, 0, sizeof(kk_tsl_data_value_t));
//Parse Type
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_TYPE, strlen(KK_TSL_KEY_TYPE), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
printf("TSL Data Type: %.*s", lite_item.value_length, lite_item.value);
res = _kk_tsl_get_type(lite_item.value, lite_item.value_length, &data_value->type);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
//Parse Specs
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_SPECS, strlen(KK_TSL_KEY_SPECS), &lite_item);
if (res == SUCCESS_RETURN) {
/* dm_log_debug("TSL Data Specs: %.*s",lite_item.value_length,lite_item.value); */
}
//Parse Type And Value
if (s_kk_tsl_mapping[data_value->type].func_parse == NULL) {
return FAIL_RETURN;
}
res = s_kk_tsl_mapping[data_value->type].func_parse(data_value, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_property_parse(_IN_ kk_tsl_data_t *property, _IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
//Parse Identifier (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **)(&property->identifier),
lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s\n", property->identifier);
//Parse DataType
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_DATATYPE, strlen(KK_TSL_KEY_DATATYPE), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
/* dm_log_debug("TSL Property Data Type: %.*s",lite_item.value_length,lite_item.value); */
res = _kk_tsl_data_parse(&property->data_value, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_properties_parse(_IN_ kk_tsl_t *shadow, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_properties, lite_property;
memset(&lite_properties, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_PROPERTIES, strlen(KK_TSL_KEY_PROPERTIES), &lite_properties);
if (res == SUCCESS_RETURN) {
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
if (!lite_cjson_is_array(&lite_properties)) {
return JSON_PARSE_FAILED;
}
} else {
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
return SUCCESS_RETURN;
}
printf("Number: %d", lite_properties.size);
if (lite_properties.size == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For TSL Properties Struct
shadow->property_number = lite_properties.size;
shadow->properties = malloc(sizeof(kk_tsl_data_t) * (lite_properties.size));
if (shadow->properties == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(shadow->properties, 0, sizeof(kk_tsl_data_t) * (lite_properties.size));
for (index = 0; index < lite_properties.size; index++) {
memset(&lite_property, 0, sizeof(lite_cjson_t));
res = lite_cjson_array_item(&lite_properties, index, &lite_property);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_property)) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_kk_tsl_property_parse(shadow->properties + index, &lite_property);
}
return SUCCESS_RETURN;
}
/*********************event parse*********************************/
static int _kk_tsl_event_outputdata_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_data_t *event_data,
_IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
//Parse Identifier (Madantory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **) & (event_data->identifier),
lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s", event_data->identifier);
//Parse DataType
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_DATATYPE, strlen(KK_TSL_KEY_DATATYPE), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
/* dm_log_debug("TSL Output Event Data Type: %.*s",lite_item.value_length,lite_item.value); */
res = _kk_tsl_data_parse(&event_data->data_value, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_event_outputdatas_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_event_t *event, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item;
kk_tsl_data_t *output_data = NULL;
printf("event outputdata Number: %d", event->output_data_number);
if (event->output_data_number == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For Output Datas
event->output_datas = malloc((event->output_data_number) * (sizeof(kk_tsl_data_t)));
if (event->output_datas == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(event->output_datas, 0, (event->output_data_number) * (sizeof(kk_tsl_data_t)));
for (index = 0; index < event->output_data_number; index++) {
memset(&lite_item, 0, sizeof(lite_cjson_t));
output_data = event->output_datas + index;
res = lite_cjson_array_item(root, index, &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_kk_tsl_event_outputdata_parse(shadow, output_data, &lite_item);
}
return SUCCESS_RETURN;
}
static int _dm_shw_event_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_event_t *event, _IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
//Parse Identifier (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **)(&event->identifier), lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s", event->identifier);
/* Check If Current Event Id Is Post */
if (((strlen(event->identifier) == strlen(KK_TSL_SPECIAL_EVENT_POST_IDENTIFIER)) &&
(memcmp(event->identifier, KK_TSL_SPECIAL_EVENT_POST_IDENTIFIER, strlen(KK_TSL_SPECIAL_EVENT_POST_IDENTIFIER)) == 0))) {
/* dm_log_info("TSL Special Event Identifier: %s, Ignore It",event->identifier); */
return SUCCESS_RETURN;
}
//Parse Output Data (Madantory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_OUTPUTDATA, strlen(KK_TSL_KEY_OUTPUTDATA), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_array(&lite_item)) {
return JSON_PARSE_FAILED;
}
event->output_data_number = lite_item.size;
res = _kk_tsl_event_outputdatas_parse(shadow, event, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_events_parse(_IN_ kk_tsl_t *shadow, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_events, lite_event;
memset(&lite_events, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_EVENTS, strlen(KK_TSL_KEY_EVENTS), &lite_events);
if (res == SUCCESS_RETURN) {
if (!lite_cjson_is_array(&lite_events)) {
return JSON_PARSE_FAILED;
}
} else {
return SUCCESS_RETURN;
}
printf("\nevent Number: %d\n", lite_events.size);
if (lite_events.size == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For TSL Events Struct
shadow->event_number = lite_events.size;
shadow->events = malloc(sizeof(kk_tsl_event_t) * (lite_events.size));
if (shadow->events == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(shadow->events, 0, sizeof(kk_tsl_event_t) * (lite_events.size));
for (index = 0; index < lite_events.size; index++) {
memset(&lite_event, 0, sizeof(lite_cjson_t));
res = lite_cjson_array_item(&lite_events, index, &lite_event);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_event)) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_dm_shw_event_parse(shadow, shadow->events + index, &lite_event);
}
return SUCCESS_RETURN;
}
/**********************service parse**********************************/
static int _kk_tsl_service_outputdata_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_data_t *service_data,
_IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
//Parse Identifier (Madantory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **) & (service_data->identifier),
lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s", service_data->identifier);
//Parse DataType
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_DATATYPE, strlen(KK_TSL_KEY_DATATYPE), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
/* dm_log_debug("TSL Output Service Data Type: %.*s",lite_item.value_length,lite_item.value); */
res = _kk_tsl_data_parse(&service_data->data_value, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_service_outputdatas_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *service,
_IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item;
kk_tsl_data_t *output_data = NULL;
printf("Number: %d", service->output_data_number);
if (service->output_data_number == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For Output Datas
service->output_datas = malloc((service->output_data_number) * (sizeof(kk_tsl_data_t)));
if (service->output_datas == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(service->output_datas, 0, (service->output_data_number) * (sizeof(kk_tsl_data_t)));
for (index = 0; index < service->output_data_number; index++) {
memset(&lite_item, 0, sizeof(lite_cjson_t));
output_data = service->output_datas + index;
res = lite_cjson_array_item(root, index, &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_kk_tsl_service_outputdata_parse(shadow, output_data, &lite_item);
}
return SUCCESS_RETURN;
}
static int _kk_tsl_service_inputdata_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_data_t *input_data,
_IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
if (!lite_cjson_is_object(root)) {
return INVALID_PARAMETER;
}
//Parse Identifier (Madantory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **) & (input_data->identifier),
lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s", input_data->identifier);
//Parse DataType
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_DATATYPE, strlen(KK_TSL_KEY_DATATYPE), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_item)) {
return JSON_PARSE_FAILED;
}
/* dm_log_debug("TSL Input Service Data Type: %.*s",lite_item.value_length,lite_item.value); */
res = _kk_tsl_data_parse(&input_data->data_value, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_service_inputdatas_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *service,
_IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item;
kk_tsl_data_t *input_data = NULL;
printf("Number: %d", service->input_data_number);
if (service->input_data_number == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For Output Datas
service->input_datas = malloc((service->input_data_number) * (sizeof(kk_tsl_data_t)));
if (service->input_datas == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(service->input_datas, 0, (service->input_data_number) * (sizeof(kk_tsl_data_t)));
for (index = 0; index < service->input_data_number; index++) {
memset(&lite_item, 0, sizeof(lite_cjson_t));
input_data = service->input_datas + index;
res = lite_cjson_array_item(root, index, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_kk_tsl_service_inputdata_parse(shadow, input_data, &lite_item);
}
return SUCCESS_RETURN;
}
static int _kk_tsl_service_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *service, _IN_ lite_cjson_t *root)
{
int res = 0;
lite_cjson_t lite_item;
//Parse Identifier (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_IDENTIFIER, strlen(KK_TSL_KEY_IDENTIFIER), &lite_item);
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item)) {
return JSON_PARSE_FAILED;
}
res = kk_utils_copy(lite_item.value, lite_item.value_length, (void **)(&service->identifier),
lite_item.value_length + 1);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
printf("Identifier: %s", service->identifier);
/* Check If Current Service Id Is Set Or Get */
if (((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) &&
(memcmp(service->identifier, KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER,
strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) == 0)) ||
((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) &&
(memcmp(service->identifier, KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER,
strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) == 0))) {
/* dm_log_info("TSL Special Service Identifier: %s, Ignore It",service->identifier); */
return SUCCESS_RETURN;
}
//Parse Output Data (Optional)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_OUTPUTDATA, strlen(KK_TSL_KEY_OUTPUTDATA), &lite_item);
if (res == SUCCESS_RETURN && lite_cjson_is_array(&lite_item)) {
service->output_data_number = lite_item.size;
res = _kk_tsl_service_outputdatas_parse(shadow, service, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
//Parse Input Data (Optional)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_INPUTDATA, strlen(KK_TSL_KEY_INPUTDATA), &lite_item);
if (res == SUCCESS_RETURN && lite_cjson_is_array(&lite_item)) {
service->input_data_number = lite_item.size;
res = _kk_tsl_service_inputdatas_parse(shadow, service, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
return SUCCESS_RETURN;
}
static int _kk_tsl_services_parse(_IN_ kk_tsl_t *shadow, _IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_services, lite_service;
kk_tsl_service_t *service = NULL;
memset(&lite_services, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_SERVICES, strlen(KK_TSL_KEY_SERVICES), &lite_services);
if (res == SUCCESS_RETURN) {
if (!lite_cjson_is_array(&lite_services)) {
return JSON_PARSE_FAILED;
}
} else {
return SUCCESS_RETURN;
}
printf("Number: %d", lite_services.size);
if (lite_services.size == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For TSL Services Struct
shadow->service_number = lite_services.size;
shadow->services = malloc(sizeof(kk_tsl_service_t) * (lite_services.size));
if (shadow->services == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(shadow->services, 0, sizeof(kk_tsl_service_t) * (lite_services.size));
for (index = 0; index < lite_services.size; index++) {
memset(&lite_service, 0, sizeof(lite_cjson_t));
service = shadow->services + index;
res = lite_cjson_array_item(&lite_services, index, &lite_service);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_service)) {
return FAIL_RETURN;
}
printf("Index: %d", index);
_kk_tsl_service_parse(shadow, service, &lite_service);
}
return SUCCESS_RETURN;
}
static int _kk_tsl_data_struct_search(_IN_ kk_tsl_data_t *input, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **output, _OU_ int *index)
{
int res = 0, item_index = 0, deli_offset = 0, partial_offset = 0;
int partial_input_len = 0, array_input_len = 0, array_index = 0;
kk_tsl_data_t *data_item = NULL;
/* dm_log_debug("Current Key: %.*s",key_len,key); */
kk_tsl_data_value_complex_t *complex_struct = (kk_tsl_data_value_complex_t *)input->data_value.value;
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &deli_offset);
if (res != SUCCESS_RETURN) {
deli_offset = key_len;
}
partial_offset = deli_offset;
res = kk_utils_strarr_index(key, deli_offset, &partial_input_len, &array_input_len, &array_index);
if (res == SUCCESS_RETURN) {
/* dm_log_debug("Current Index: %d",array_index); */
partial_offset = partial_input_len;
}
for (item_index = 0; item_index < complex_struct->size; item_index++) {
data_item = (kk_tsl_data_t *)complex_struct->value + item_index;
if (strlen(data_item->identifier) != partial_offset ||
memcmp(data_item->identifier, key, partial_offset) != 0) {
continue;
}
switch (data_item->data_value.type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_FLOAT:
case KK_TSL_DATA_TYPE_DOUBLE:
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_DATE:
case KK_TSL_DATA_TYPE_BOOL: {
if (partial_input_len != 0 || deli_offset != key_len) {
return FAIL_RETURN;
}
if (output) {
*output = data_item;
}
return SUCCESS_RETURN;
}
break;
case KK_TSL_DATA_TYPE_ARRAY: {
int key_offset = (deli_offset == key_len) ? (deli_offset - 1) : (deli_offset + 1);
int key_len_offset = (deli_offset == key_len) ? (key_len) : (deli_offset + 1);
if ((partial_input_len == 0) && (deli_offset == key_len)) {
if (output) {
*output = data_item;
}
return SUCCESS_RETURN;
}
if (partial_input_len == 0) {
return FAIL_RETURN;
}
return _kk_tsl_data_array_search(data_item, array_index, key + key_offset, key_len - key_len_offset, output, index);
}
case KK_TSL_DATA_TYPE_STRUCT: {
if (deli_offset == key_len) {
if (output) {
*output = data_item;
}
return SUCCESS_RETURN;
}
if (partial_input_len != 0) {
return FAIL_RETURN;
}
return _kk_tsl_data_struct_search(data_item, key + deli_offset + 1, key_len - deli_offset - 1, output, index);
}
default:
printf("Unknown Data Type");
break;
}
}
return FAIL_RETURN;
}
static int _kk_tsl_data_array_search(_IN_ kk_tsl_data_t *input, _IN_ int input_index, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **output, _OU_ int *output_index)
{
int res = 0, deli_offset = 0;
kk_tsl_data_value_complex_t *complex_struct = (kk_tsl_data_value_complex_t *)input->data_value.value;
/* dm_log_debug("Current Key: %s, Len: %d",key,key_len);
dm_log_debug("Current Item Identifier: %s",input->identifier); */
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &deli_offset);
if (res != SUCCESS_RETURN) {
deli_offset = key_len;
}
switch (complex_struct->type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_FLOAT:
case KK_TSL_DATA_TYPE_DOUBLE:
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_DATE:
case KK_TSL_DATA_TYPE_BOOL: {
if (deli_offset != key_len) {
return FAIL_RETURN;
}
if (output) {
*output = input;
}
if (output_index) {
*output_index = input_index;
}
return SUCCESS_RETURN;
}
break;
case KK_TSL_DATA_TYPE_STRUCT: {
kk_tsl_data_t *search_data = NULL;
if (complex_struct->value == NULL) {
return FAIL_RETURN;
}
search_data = (kk_tsl_data_t *)complex_struct->value + input_index;
return _kk_tsl_data_struct_search(search_data, key, deli_offset, output, output_index);
}
break;
default:
printf("Unknown Data Type: %d", complex_struct->type);
break;
}
return FAIL_RETURN;
}
static int _kk_tsl_property_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len,
_OU_ kk_tsl_data_t **property, _OU_ int *index)
{
int res = 0, item_index = 0;
kk_tsl_data_t *property_item = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
if (shadow->property_number == 0 || shadow->properties == NULL) {
return TSL_PROPERTY_NOT_EXIST;
}
for (item_index = 0; item_index < shadow->property_number; item_index++) {
property_item = shadow->properties + item_index;
res = kk_tsl_data_search(property_item, key, key_len, property, index);
if (res == SUCCESS_RETURN) {
return SUCCESS_RETURN;
}
}
return FAIL_RETURN;
}
int kk_tsl_get_property_data(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{
int res = 0;
if (shadow == NULL || key == NULL || key_len <= 0 || data == NULL || *data != NULL) {
return INVALID_PARAMETER;
}
res = _kk_tsl_property_search(shadow, key, key_len, (kk_tsl_data_t **)data, NULL);
if (res != SUCCESS_RETURN) {
return TSL_PROPERTY_NOT_EXIST;
}
return SUCCESS_RETURN;
}
int kk_tsl_data_search(_IN_ kk_tsl_data_t *input, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **output, _OU_ int *index)
{
int res = 0, deli_offset = 0, partial_offset = 0;
int partial_input_len = 0, array_input_len = 0, array_index = 0;
if (input == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
}
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &deli_offset);
if (res != SUCCESS_RETURN) {
deli_offset = key_len;
}
partial_offset = deli_offset;
res = kk_utils_strarr_index(key, deli_offset, &partial_input_len, &array_input_len, &array_index);
if (res == SUCCESS_RETURN) {
/* dm_log_debug("Current Index: %d",array_index); */
partial_offset = partial_input_len;
}
/* dm_log_debug("Current Input Identifier: %s",input->identifier);
dm_log_debug("Current Compare Key: %.*s",partial_offset,key); */
if (strlen(input->identifier) != partial_offset ||
memcmp(input->identifier, key, partial_offset) != 0) {
return FAIL_RETURN;
}
switch (input->data_value.type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_FLOAT:
case KK_TSL_DATA_TYPE_DOUBLE:
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_ENUM:
case KK_TSL_DATA_TYPE_DATE:
case KK_TSL_DATA_TYPE_BOOL: {
if (output) {
*output = input;
}
return SUCCESS_RETURN;
}
break;
case KK_TSL_DATA_TYPE_ARRAY: {
int key_offset = (deli_offset == key_len) ? (deli_offset - 1) : (deli_offset + 1);
int key_len_offset = (deli_offset == key_len) ? (key_len) : (deli_offset + 1);
if ((partial_input_len == 0) && (deli_offset == key_len)) {
if (output) {
*output = input;
}
return SUCCESS_RETURN;
}
if (partial_input_len == 0) {
return FAIL_RETURN;
}
return _kk_tsl_data_array_search(input, array_index, key + key_offset, key_len - key_len_offset, output, index);
}
break;
case KK_TSL_DATA_TYPE_STRUCT: {
if (deli_offset == key_len) {
if (output) {
*output = input;
}
return SUCCESS_RETURN;
}
if (partial_input_len != 0) {
return FAIL_RETURN;
}
return _kk_tsl_data_struct_search(input, key + deli_offset + 1, key_len - deli_offset - 1, output, index);
}
break;
default:
printf("Unknow Data Type");
break;
}
return FAIL_RETURN;
}
int kk_tsl_create(_IN_ const char *tsl, _IN_ int tsl_len, _OU_ kk_tsl_t **shadow)
{
int res = 0;
lite_cjson_t lite_root;
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
if (shadow == NULL || *shadow != NULL || tsl == NULL || tsl_len <= 0) {
return INVALID_PARAMETER;
}
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
*shadow = malloc(sizeof(kk_tsl_t));
if (*shadow == NULL) {
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
return MEMORY_NOT_ENOUGH;
}
memset(*shadow, 0, sizeof(kk_tsl_t));
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
//Parse Root
memset(&lite_root, 0, sizeof(lite_root));
res = lite_cjson_parse(tsl, tsl_len, &lite_root);
if (res != SUCCESS_RETURN || !lite_cjson_is_object(&lite_root)) {
free(*shadow);
return JSON_PARSE_FAILED;
}
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
//Parse Properties (Mandatory)
res = _kk_tsl_properties_parse(*shadow, &lite_root);
if (res != SUCCESS_RETURN) {
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
//Parse Events (Mandatory)
res = _kk_tsl_events_parse(*shadow, &lite_root);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
//Parse Services (Mandatory)
res = _kk_tsl_services_parse(*shadow, &lite_root);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
static int _kk_tsl_int_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
lite_cjson_add_number_to_object(lite, data->identifier, data->data_value.value_int);
return SUCCESS_RETURN;
}
static int _kk_tsl_float_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
lite_cjson_add_number_to_object(lite, data->identifier, data->data_value.value_float);
return SUCCESS_RETURN;
}
static int _kk_tsl_double_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
lite_cjson_add_number_to_object(lite, data->identifier, data->data_value.value_double);
return SUCCESS_RETURN;
}
static int _kk_tsl_string_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
char *value = (data->data_value.value == NULL) ? ("") : (data->data_value.value);
lite_cjson_add_string_to_object(lite, data->identifier, value);
return SUCCESS_RETURN;
}
static int _kk_tsl_array_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite);
static int _kk_tsl_struct_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite);
static int _kk_tsl_data_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite);
static int _kk_tsl_array_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
int res = SUCCESS_RETURN, index = 0;
lite_cjson_item_t *array = NULL, *array_item = NULL;
kk_tsl_data_value_complex_t *complex_array = NULL;
if (data == NULL || lite == NULL) {
return INVALID_PARAMETER;
}
complex_array = data->data_value.value;
if (lite->type == cJSON_Array) {
array = lite_cjson_create_object();
if (array == NULL) {
return MEMORY_NOT_ENOUGH;
}
}
array_item = lite_cjson_create_array();
if (array_item == NULL) {
if (array) {
lite_cjson_delete(array);
}
return MEMORY_NOT_ENOUGH;
}
switch (complex_array->type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_BOOL:
case KK_TSL_DATA_TYPE_ENUM: {
int value = 0;
for (index = 0; index < complex_array->size; index++) {
value = *((int *)(complex_array->value) + index);
lite_cjson_add_item_to_array(array_item, lite_cjson_create_number((double)value));
}
if (lite->type == cJSON_Array) {
lite_cjson_add_item_to_object(array, data->identifier, array_item);
lite_cjson_add_item_to_array(lite, array);
} else {
lite_cjson_add_item_to_object(lite, data->identifier, array_item);
lite_cjson_delete(array);
}
}
break;
case KK_TSL_DATA_TYPE_FLOAT: {
float value = 0;
for (index = 0; index < complex_array->size; index++) {
value = *((float *)(complex_array->value) + index);
lite_cjson_add_item_to_array(array_item, lite_cjson_create_number((double)value));
}
if (lite->type == cJSON_Array) {
lite_cjson_add_item_to_object(array, data->identifier, array_item);
lite_cjson_add_item_to_array(lite, array);
} else {
lite_cjson_add_item_to_object(lite, data->identifier, array_item);
lite_cjson_delete(array);
}
}
break;
case KK_TSL_DATA_TYPE_DOUBLE: {
double value = 0;
for (index = 0; index < complex_array->size; index++) {
value = *((double *)(complex_array->value) + index);
lite_cjson_add_item_to_array(array_item, lite_cjson_create_number(value));
}
if (lite->type == cJSON_Array) {
lite_cjson_add_item_to_object(array, data->identifier, array_item);
lite_cjson_add_item_to_array(lite, array);
} else {
lite_cjson_add_item_to_object(lite, data->identifier, array_item);
lite_cjson_delete(array);
}
}
break;
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_DATE: {
char *value = NULL;
for (index = 0; index < complex_array->size; index++) {
value = *((char **)(complex_array->value) + index);
value = (value == NULL) ? ("") : (value);
lite_cjson_add_item_to_array(array_item, lite_cjson_create_string((const char *)value));
}
if (lite->type == cJSON_Array) {
lite_cjson_add_item_to_object(array, data->identifier, array_item);
lite_cjson_add_item_to_array(lite, array);
} else {
lite_cjson_add_item_to_object(lite, data->identifier, array_item);
lite_cjson_delete(array);
}
}
break;
case KK_TSL_DATA_TYPE_STRUCT: {
kk_tsl_data_t *array_data = NULL;
for (index = 0; index < complex_array->size; index++) {
array_data = (kk_tsl_data_t *)(complex_array->value) + index;
if (array_data) {
_kk_tsl_struct_insert_json_item(array_data, array_item);
}
}
if (lite->type == cJSON_Array) {
lite_cjson_add_item_to_object(array, data->identifier, array_item);
lite_cjson_add_item_to_array(lite, array);
} else {
lite_cjson_add_item_to_object(lite, data->identifier, array_item);
lite_cjson_delete(array);
}
}
break;
default: {
lite_cjson_delete(array_item);
lite_cjson_delete(array);
}
break;
}
return res;
}
static int _kk_tsl_struct_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
int res = 0, index = 0;
lite_cjson_item_t *lite_object = NULL, *lite_item = NULL;
kk_tsl_data_t *current_data = NULL;
kk_tsl_data_value_complex_t *complex_struct = NULL;
if (data == NULL || lite == NULL) {
return INVALID_PARAMETER;
}
if (lite->type == cJSON_Array) {
lite_object = lite_cjson_create_object();
if (lite_object == NULL) {
return MEMORY_NOT_ENOUGH;
}
}
lite_item = lite_cjson_create_object();
if (lite_item == NULL) {
lite_cjson_delete(lite_object);
return MEMORY_NOT_ENOUGH;
}
complex_struct = data->data_value.value;
for (index = 0; index < complex_struct->size; index++) {
current_data = (kk_tsl_data_t *)complex_struct->value + index;
_kk_tsl_data_insert_json_item(current_data, lite_item);
}
if (lite->type == cJSON_Array) {
if (data->identifier) {
lite_cjson_add_item_to_object(lite_object, data->identifier, lite_item);
lite_cjson_add_item_to_array(lite, lite_object);
} else {
lite_cjson_add_item_to_array(lite, lite_item);
lite_cjson_delete(lite_object);
}
} else {
if (data->identifier) {
lite_cjson_add_item_to_object(lite, data->identifier, lite_item);
lite_cjson_delete(lite_object);
} else {
res = FAIL_RETURN;
lite_cjson_delete(lite_item);
lite_cjson_delete(lite_object);
}
}
return res;
}
static int _kk_tsl_data_insert_json_item(_IN_ kk_tsl_data_t *data, _IN_ lite_cjson_item_t *lite)
{
int res = 0;
lite_cjson_item_t *data_object = NULL;
printf("--------------------------->[%s][%d]data->i:%s\n",__FUNCTION__,__LINE__,data->identifier,data->data_value);
if (data == NULL || lite == NULL) {
return INVALID_PARAMETER;
}
if (lite->type == cJSON_Array) {
data_object = lite_cjson_create_object();
if (data_object == NULL) {
return MEMORY_NOT_ENOUGH;
}
}
printf("--------------------------->[%s][%d]data->type:%d\n",__FUNCTION__,__LINE__,data->data_value.type);
switch (data->data_value.type) {
case KK_TSL_DATA_TYPE_INT:
case KK_TSL_DATA_TYPE_BOOL:
case KK_TSL_DATA_TYPE_ENUM: {
if (lite->type == cJSON_Array) {
res = _kk_tsl_int_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_int_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
case KK_TSL_DATA_TYPE_FLOAT: {
if (lite->type == cJSON_Array) {
res = _kk_tsl_float_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_float_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
case KK_TSL_DATA_TYPE_DOUBLE: {
if (lite->type == cJSON_Array) {
res = _kk_tsl_double_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_double_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
case KK_TSL_DATA_TYPE_TEXT:
case KK_TSL_DATA_TYPE_DATE: {
if (lite->type == cJSON_Array) {
res = _kk_tsl_string_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_string_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
case KK_TSL_DATA_TYPE_ARRAY: {
/* dm_log_debug("DM_SHW_DATA_TYPE_ARRAY"); */
if (lite->type == cJSON_Array) {
res = _kk_tsl_array_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_array_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
case KK_TSL_DATA_TYPE_STRUCT: {
/* dm_log_debug("DM_SHW_DATA_TYPE_STRUCT"); */
if (lite->type == cJSON_Array) {
res = _kk_tsl_struct_insert_json_item(data, data_object);
if (res == SUCCESS_RETURN) {
lite_cjson_add_item_to_array(lite, data_object);
}
} else {
res = _kk_tsl_struct_insert_json_item(data, lite);
lite_cjson_delete(data_object);
}
}
break;
default:
lite_cjson_delete(data_object);
res = FAIL_RETURN;
break;
}
return res;
}
int kk_tsl_assemble_property(_IN_ kk_tsl_t *shadow, _IN_ char *identifier, _IN_ int identifier_len,
_IN_ lite_cjson_item_t *lite)
{
int res = 0, index = 0;
kk_tsl_data_t *property = NULL;
if (shadow == NULL || identifier == NULL || identifier_len <= 0 || lite == NULL || lite->type != cJSON_Object) {
return INVALID_PARAMETER;
}
for (index = 0; index < shadow->property_number; index++) {
property = shadow->properties + index;
if ((strlen(property->identifier) == identifier_len) &&
(memcmp(property->identifier, identifier, identifier_len) == 0)) {
/* dm_log_debug("Property Found: %.*s",identifier_len,identifier); */
break;
}
}
if (index == shadow->property_number) {
printf("Property Not Found: %.*s", identifier_len, identifier);
return FAIL_RETURN;
}
res = _kk_tsl_data_insert_json_item(property, lite);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
return SUCCESS_RETURN;
}
#if 0
int main(int argc, char* argv[])
{
int rc = 0;
int item_index = 0;
int oitem_index = 0;
kk_tsl_t *ktsl = NULL;
kk_tsl_data_t *property_item = NULL;
kk_tsl_event_t *event_item = NULL;
kk_tsl_data_t *output_event_item = NULL;
kk_tsl_data_type_e type;
rc = kk_tsl_create(TSL_STRING,strlen(TSL_STRING),&ktsl);
if(rc == SUCCESS_RETURN)
{
printf("num:%d\n",ktsl->property_number);
for (item_index = 0; item_index < ktsl->property_number; item_index++)
{
property_item = ktsl->properties+ item_index;
printf("identifier:%s\n",property_item->identifier);
printf("type:%d\n",property_item->data_value.type);
}
printf("event num:%d\n",ktsl->event_number);
for (item_index = 0; item_index < ktsl->event_number; item_index++)
{
event_item = ktsl->events+ item_index;
printf("identifier:%s\n",event_item->identifier);
printf("OUTPUT:%d\n",event_item->output_data_number);
for(oitem_index = 0;oitem_index < event_item->output_data_number;oitem_index++)
{
output_event_item = event_item->output_datas + oitem_index;
printf("output identifier:%s\n",output_event_item->identifier);
printf("type:%d\n",output_event_item->data_value.type);
}
}
}
return 0;
}
#endif
#include "kk_utils.h"
int kk_utils_copy(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len)
{
if (input == NULL || output == NULL || *output != NULL) {
return INVALID_PARAMETER;
}
*output = malloc(output_len);
if (*output == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(*output, 0, output_len);
memcpy(*output, input, input_len);
return SUCCESS_RETURN;
}
int kk_utils_memtok(_IN_ char *input, _IN_ int input_len, _IN_ char delimiter, _IN_ int index, _OU_ int *offset)
{
int item_index = 0;
int count = 0;
if (input == NULL || input_len <= 0 || offset == NULL) {
return INVALID_PARAMETER;
}
for (item_index = 0; item_index < input_len; item_index++) {
if (input[item_index] == delimiter && (item_index + 1) < input_len) {
count++;
if (count == index) {
*offset = item_index;
return SUCCESS_RETURN;
}
}
}
return FAIL_RETURN;
}
int kk_utils_strarr_index(_IN_ char *input, _IN_ int input_len,
_OU_ int *partial_input_len, _OU_ int *array_input_len, _OU_ int *array_index)
{
if (input == NULL || input_len <= 1 || array_index == NULL) {
return INVALID_PARAMETER;
}
int index = 0;
int deep = 0;
char *bracket_pre = NULL;
char *bracket_suf = NULL;
char array_index_str[10] = {0};
for (index = 0; index < input_len; index++) {
switch (input[index]) {
case '[': {
if (deep != 0) {
return FAIL_RETURN;
}
deep++;
if (!bracket_pre) {
bracket_pre = (char *)&input[index];
}
}
break;
case ']': {
if (deep != 1) {
return FAIL_RETURN;
}
deep--;
if (input[index - 1] == '[') {
return FAIL_RETURN;
}
if (!bracket_suf) {
bracket_suf = (char *)&input[index];
}
}
break;
default:
break;
}
}
if (bracket_pre && bracket_suf && ((bracket_suf - input + 1) == input_len)) {
if (partial_input_len) {
*partial_input_len = bracket_pre - input;
}
if (array_input_len) {
*array_input_len = bracket_suf - input + 1;
}
//Get Index
memcpy(array_index_str, bracket_pre + 1, bracket_suf - bracket_pre - 1);
*array_index = atoi(array_index_str);
return SUCCESS_RETURN;
}
return FAIL_RETURN;
}
int kk_utils_copy_direct(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len)
{
if (input == NULL || output == NULL || *output != NULL) {
return INVALID_PARAMETER;
}
*output = malloc(output_len);
if (*output == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(*output, 0, output_len);
memcpy(*output, input, input_len);
return SUCCESS_RETURN;
}
int kk_utils_itoa(_IN_ int input, _OU_ char **output)
{
int res = 0;
char temp_output[10 + 1] = {0};
if (output == NULL || *output != NULL) {
return INVALID_PARAMETER;
}
res = snprintf(temp_output, 10, "%d", input);
if (res < 0) {
return FAIL_RETURN;
}
*output = malloc(strlen(temp_output) + 1);
if (*output == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(*output, 0, strlen(temp_output) + 1);
memcpy(*output, temp_output, strlen(temp_output));
return SUCCESS_RETURN;
}
void *kk_MutexCreate(void)
{
int err_num;
pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
if (NULL == mutex)
{
return NULL;
}
if (0 != (err_num = pthread_mutex_init(mutex, NULL)))
{
printf("create mutex failed\n");
free(mutex);
return NULL;
}
return mutex;
}
void kk_MutexLock(void *mutex)
{
int err_num;
if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)mutex)))
{
printf("lock mutex failed: - '%s' (%d)\n", strerror(err_num), err_num);
}
}
void kk_MutexUnLock(void *mutex)
{
int err_num;
if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)mutex)))
{
printf("unlock mutex failed - '%s' (%d)\n", strerror(err_num), err_num);
}
}
void kk_MutexDestroy(void *mutex)
{
int err_num;
if (!mutex)
{
printf("mutex want to destroy is NULL!\n");
return;
}
if (0 != (err_num = pthread_mutex_destroy((pthread_mutex_t *)mutex)))
{
printf("destroy mutex failed\n");
}
free(mutex);
}
int kk_utils_service_name(_IN_ const char *prefix, _IN_ const char *name, _IN_ char product_key[PRODUCT_KEY_MAXLEN],
_IN_ char device_name[DEVICE_NAME_MAXLEN], _OU_ char **service_name)
{
int prefix_len = (prefix == NULL) ? (0) : (strlen(prefix));
int name_len = (name == NULL) ? (0) : (strlen(name));
int service_name_len = 0;
if ((prefix == NULL && name == NULL) || product_key == NULL || device_name == NULL ||
service_name == NULL || *service_name != NULL) {
return INVALID_PARAMETER;
}
service_name_len = prefix_len + name_len + strlen(product_key) + strlen(device_name) + 1;
*service_name = malloc(service_name_len);
if (*service_name == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(*service_name, 0, service_name_len);
if (prefix != NULL) {
snprintf(*service_name, service_name_len, prefix, product_key, device_name);
}
if (name != NULL) {
memcpy(*service_name + strlen(*service_name), name, name_len);
}
return SUCCESS_RETURN;
}
#ifndef __KK_UTILS_H__
#define __KK_UTILS_H__
#include "kk_tsl_common.h"
int kk_utils_copy(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len);
int kk_utils_strarr_index(_IN_ char *input, _IN_ int input_len,_OU_ int *partial_input_len, _OU_ int *array_input_len, _OU_ int *array_index);
int kk_utils_copy_direct(_IN_ void *input, _IN_ int input_len, _OU_ void **output, _IN_ int output_len);
int kk_utils_itoa(_IN_ int input, _OU_ char **output);
int kk_utils_memtok(_IN_ char *input, _IN_ int input_len, _IN_ char delimiter, _IN_ int index, _OU_ int *offset);
void *kk_MutexCreate(void);
void kk_MutexLock(void *mutex);
void kk_MutexUnLock(void *mutex);
void kk_MutexDestroy(void *mutex);
#endif
#ifndef _INFRA_LIST_H_
#define _INFRA_LIST_H_
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) || defined(__GNUC__)) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Get offset of a member variable.
*
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the variable within the struct.
*/
#define aos_offsetof(type, member) ((int)&(((type *)0)->member))
/*
* Get the struct for this entry.
*
* @param[in] ptr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the variable within the struct.
*/
#define aos_container_of(ptr, type, member) \
((type *) ((char *) (ptr) - aos_offsetof(type, member)))
/* for double link list */
typedef struct dlist_s {
struct dlist_s *prev;
struct dlist_s *next;
} dlist_t;
static inline void __dlist_add(dlist_t *node, dlist_t *prev, dlist_t *next)
{
node->next = next;
node->prev = prev;
//printf("[%s][%d]node->name:%d\n",__FUNCTION__,__LINE__);
prev->next = node;
next->prev = node;
}
/*
* Get the struct for this entry.
*
* @param[in] addr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the dlist_t within the struct.
*/
#define dlist_entry(addr, type, member) \
((type *)((long)addr - aos_offsetof(type, member)))
static inline void dlist_add(dlist_t *node, dlist_t *queue)
{
__dlist_add(node, queue, queue->next);
}
static inline void dlist_add_tail(dlist_t *node, dlist_t *queue)
{
__dlist_add(node, queue->prev, queue);
}
static inline void dlist_del(dlist_t *node)
{
dlist_t *prev = node->prev;
dlist_t *next = node->next;
prev->next = next;
next->prev = prev;
}
static inline void dlist_init(dlist_t *node)
{
node->next = node->prev = node;
}
static inline void INIT_AOS_DLIST_HEAD(dlist_t *list)
{
list->next = list;
list->prev = list;
}
static inline int dlist_empty(const dlist_t *head)
{
return head->next == head;
}
/*
* Initialise the list.
*
* @param[in] list the list to be inited.
*/
#define AOS_DLIST_INIT(list) {&(list), &(list)}
/*
* Get the first element from a list
*
* @param[in] ptr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the dlist_t within the struct.
*/
#define dlist_first_entry(ptr, type, member) \
dlist_entry((ptr)->next, type, member)
/*
* Iterate over a list.
*
* @param[in] pos the &struct dlist_t to use as a loop cursor.
* @param[in] head he head for your list.
*/
#define dlist_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/*
* Iterate over a list safe against removal of list entry.
*
* @param[in] pos the &struct dlist_t to use as a loop cursor.
* @param[in] n another &struct dlist_t to use as temporary storage.
* @param[in] head he head for your list.
*/
#define dlist_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/*
* Iterate over list of given type.
*
* @param[in] queue he head for your list.
* @param[in] node the &struct dlist_t to use as a loop cursor.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the dlist_t within the struct.
*/
#define dlist_for_each_entry(queue, node, type, member) \
for (node = aos_container_of((queue)->next, type, member); \
&node->member != (queue); \
node = aos_container_of(node->member.next, type, member))
/*
* Iterate over list of given type safe against removal of list entry.
*
* @param[in] queue the head for your list.
* @param[in] n the type * to use as a temp.
* @param[in] node the type * to use as a loop cursor.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the dlist_t within the struct.
*/
#define dlist_for_each_entry_safe(queue, n, node, type, member) \
for (node = aos_container_of((queue)->next, type, member), \
n = (queue)->next ? (queue)->next->next : NULL; \
&node->member != (queue); \
node = aos_container_of(n, type, member), n = n ? n->next : NULL)
/*
* Get the struct for this entry.
* @param[in] ptr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the variable within the struct.
*/
#define list_entry(ptr, type, member) \
aos_container_of(ptr, type, member)
/*
* Iterate backwards over list of given type.
*
* @param[in] pos the type * to use as a loop cursor.
* @param[in] head he head for your list.
* @param[in] member the name of the dlist_t within the struct.
* @param[in] type the type of the struct this is embedded in.
*/
#define dlist_for_each_entry_reverse(pos, head, member, type) \
for (pos = list_entry((head)->prev, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, type, member))
/*
* Get the list length.
*
* @param[in] queue the head for your list.
*/
static inline int __dlist_entry_number(dlist_t *queue)
{
int num;
dlist_t *cur = queue;
for (num = 0; cur->next != queue; cur = cur->next, num++)
;
return num;
}
/*
* Get the list length.
*
* @param[in] queue the head for your list.
*/
#define dlist_entry_number(head) \
__dlist_entry_number(head)
/*
* Initialise the list.
*
* @param[in] name the list to be initialized.
*/
#define AOS_DLIST_HEAD_INIT(name) { &(name), &(name) }
/*
* Initialise the list.
*
* @param[in] name the list to be initialized.
*/
#define AOS_DLIST_HEAD(name) \
dlist_t name = AOS_DLIST_HEAD_INIT(name)
/* for single link list */
typedef struct slist_s {
struct slist_s *next;
} slist_t;
static inline void slist_add(slist_t *node, slist_t *head)
{
node->next = head->next;
head->next = node;
}
static inline void slist_add_tail(slist_t *node, slist_t *head)
{
while (head->next) {
head = head->next;
}
slist_add(node, head);
}
static inline void slist_del(slist_t *node, slist_t *head)
{
while (head->next) {
if (head->next == node) {
head->next = node->next;
break;
}
head = head->next;
}
}
static inline int slist_empty(const slist_t *head)
{
return !head->next;
}
static inline void slist_init(slist_t *head)
{
head->next = 0;
}
/*
* Iterate over list of given type.
*
* @param[in] queue he head for your list.
* @param[in] node the type * to use as a loop cursor.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the slist_t within the struct.
*/
#define slist_for_each_entry(queue, node, type, member) \
for (node = aos_container_of((queue)->next, type, member); \
&node->member; \
node = aos_container_of(node->member.next, type, member))
/*
* Iterate over list of given type safe against removal of list entry.
*
* @param[in] queue the head for your list.
* @param[in] tmp the type * to use as a temp.
* @param[in] node the type * to use as a loop cursor.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the slist_t within the struct.
*/
#define slist_for_each_entry_safe(queue, tmp, node, type, member) \
for (node = aos_container_of((queue)->next, type, member), \
tmp = (queue)->next ? (queue)->next->next : NULL; \
&node->member; \
node = aos_container_of(tmp, type, member), tmp = tmp ? tmp->next : tmp)
/*
* Initialise the list.
*
* @param[in] name the list to be initialized.
*/
#define AOS_SLIST_HEAD_INIT(name) {0}
/*
* Initialise the list.
*
* @param[in] name the list to be initialized.
*/
#define AOS_SLIST_HEAD(name) \
slist_t name = AOS_SLIST_HEAD_INIT(name)
/*
* Get the struct for this entry.
* @param[in] addr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the slist_t within the struct.
*/
#define slist_entry(addr, type, member) ( \
addr ? (type *)((long)addr - aos_offsetof(type, member)) : (type *)addr \
)
/*
* Get the first element from a list.
*
* @param[in] ptr the list head to take the element from.
* @param[in] type the type of the struct this is embedded in.
* @param[in] member the name of the slist_t within the struct.
*/
#define slist_first_entry(ptr, type, member) \
slist_entry((ptr)->next, type, member)
/*
* Get the list length.
*
* @param[in] queue the head for your list.
*/
static inline int slist_entry_number(slist_t *queue)
{
int num;
slist_t *cur = queue;
for (num = 0; cur->next; cur = cur->next, num++)
;
return num;
}
#ifndef offset_of
#define offset_of aos_offsetof
#endif
#ifndef container_of
#define container_of aos_container_of
#endif
#define LIST_HEAD AOS_DLIST_HEAD
#define LIST_HEAD_INIT AOS_DLIST_INIT
#define INIT_LIST_HEAD INIT_AOS_DLIST_HEAD
#define LIST_INIT AOS_DLIST_INIT
#define list_head dlist_s
#define list_head_t dlist_t
#define list_add dlist_add
#define list_add_tail dlist_add_tail
#define list_del dlist_del
#define list_empty dlist_empty
#define list_entry_number dlist_entry_number
#define list_first_entry dlist_first_entry
#define list_for_each dlist_for_each
#define list_for_each_entry_reverse dlist_for_each_entry_reverse
#define list_for_each_safe dlist_for_each_safe
#define list_init dlist_init
#define list_for_each_entry(pos, head, member, type) \
dlist_for_each_entry(head, pos, type, member)
#define list_for_each_entry_safe(pos, n, head, member, type) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#define list_next_entry(pos, member, type) \
list_entry((pos)->member.next, type, member)
static inline void list_del_init(struct list_head *entry)
{
list_del(entry);
INIT_LIST_HEAD(entry);
}
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{
return list->next == head;
}
typedef struct propertyInfo
{
char name[50];
char identifier[50];
struct list_head list;
}propertyInfo_t;
#ifdef __cplusplus
}
#endif
#endif /* AOS_LIST_H */
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <float.h>
#include <ctype.h>
//#include "iotx_utils.h"
#include "lite-cjson.h"
typedef struct {
const unsigned char *content;
int length;
int offset;
int depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */
} parse_buffer;
/* check if the given size is left to read in a given parse buffer (starting with 1) */
#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length))
/* check if the buffer can be accessed at the given index (starting with 0) */
#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length))
#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index))
/* get a pointer to the buffer at the position */
#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset)
/* Predeclare these prototypes. */
static int parse_value(lite_cjson_t *const item, parse_buffer *const input_buffer);
static int parse_string(lite_cjson_t *const item, parse_buffer *const input_buffer);
static int parse_array(_IN_ lite_cjson_t *const item, _IN_ parse_buffer *const input_buffer);
static int parse_object(lite_cjson_t *const item, parse_buffer *const input_buffer);
/* Utility to jump whitespace and cr/lf */
static parse_buffer *buffer_skip_whitespace(parse_buffer *const buffer)
{
if ((buffer == NULL) || (buffer->content == NULL)) {
return NULL;
}
while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) {
buffer->offset++;
}
if (buffer->offset == buffer->length) {
buffer->offset--;
}
return buffer;
}
/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */
static parse_buffer *skip_utf8_bom(parse_buffer *const buffer)
{
if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) {
return NULL;
}
if (can_access_at_index(buffer, 4) && (strncmp((const char *)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) {
buffer->offset += 3;
}
return buffer;
}
/* Parse the input text to generate a number, and populate the result into item. */
static int parse_number(_IN_ lite_cjson_t *const item, _IN_ parse_buffer *const input_buffer)
{
double number = 0;
unsigned char *after_end = NULL;
unsigned char number_c_string[64];
unsigned char decimal_point = '.';
int i = 0;
if ((input_buffer == NULL) || (input_buffer->content == NULL)) {
return -1;
}
/* copy the number into a temporary buffer and replace '.' with the decimal point
* of the current locale (for strtod)
* This also takes care of '\0' not necessarily being available for marking the end of the input */
for (i = 0; (i < (sizeof(number_c_string) - 1)) && can_access_at_index(input_buffer, i); i++) {
switch (buffer_at_offset(input_buffer)[i]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
case 'e':
case 'E':
number_c_string[i] = buffer_at_offset(input_buffer)[i];
break;
case '.':
number_c_string[i] = decimal_point;
break;
default:
goto loop_end;
}
}
loop_end:
number_c_string[i] = '\0';
number = strtod((const char *)number_c_string, (char **)&after_end);
if (number_c_string == after_end) {
return -1;
}
item->type = cJSON_Number;
item->value = (char *)buffer_at_offset(input_buffer);
item->value_length = (int)(after_end - number_c_string);
item->value_double = number;
/* use saturation in case of overflow */
if (number >= INT_MAX) {
item->value_int = INT_MAX;
} else if (number <= INT_MIN) {
item->value_int = INT_MIN;
} else {
item->value_int = (int)number;
}
input_buffer->offset += (int)(after_end - number_c_string);
return 0;
}
/* Build an array from input text. */
static int parse_array(_IN_ lite_cjson_t *const item, _IN_ parse_buffer *const input_buffer)
{
lite_cjson_t current_item;
int start_pos = input_buffer->offset;
item->size = 0;
if (input_buffer->depth >= LITE_CJSON_NESTING_LIMIT) {
return -1; /* to deeply nested */
}
input_buffer->depth++;
if (buffer_at_offset(input_buffer)[0] != '[') {
/* not an array */
goto fail;
}
input_buffer->offset++;
buffer_skip_whitespace(input_buffer);
if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) {
/* empty array */
goto success;
}
/* check if we skipped to the end of the buffer */
if (cannot_access_at_index(input_buffer, 0)) {
input_buffer->offset--;
goto fail;
}
/* step back to character in front of the first element */
input_buffer->offset--;
/* loop through the comma separated array elements */
do {
memset(&current_item, 0, sizeof(lite_cjson_t));
/* parse next value */
input_buffer->offset++;
buffer_skip_whitespace(input_buffer);
if (parse_value(&current_item, input_buffer) != 0) {
goto fail; /* failed to parse value */
}
buffer_skip_whitespace(input_buffer);
//printf("current item index: %d, type: %d, length: %d, value: %.*s\n",
// item->size+1, current_item.type, current_item.value_length, current_item.value_length, current_item.value);
item->size++;
} while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') {
goto fail; /* expected end of array */
}
success:
input_buffer->depth--;
item->type = cJSON_Array;
item->value = (char *)(input_buffer->content + start_pos);
item->value_length = input_buffer->offset - start_pos + 1;
input_buffer->offset++;
return 0;
fail:
return -1;
}
/* Build an object from the text. */
static int parse_object(_IN_ lite_cjson_t *const item, _IN_ parse_buffer *const input_buffer)
{
lite_cjson_t current_item_key;
lite_cjson_t current_item_value;
int start_pos = input_buffer->offset;
item->size = 0;
if (input_buffer->depth >= LITE_CJSON_NESTING_LIMIT) {
return -1; /* to deeply nested */
}
input_buffer->depth++;
if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) {
goto fail; /* not an object */
}
input_buffer->offset++;
buffer_skip_whitespace(input_buffer);
if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) {
goto success; /* empty object */
}
/* check if we skipped to the end of the buffer */
if (cannot_access_at_index(input_buffer, 0)) {
input_buffer->offset--;
goto fail;
}
/* step back to character in front of the first element */
input_buffer->offset--;
/* loop through the comma separated array elements */
do {
memset(&current_item_key, 0, sizeof(lite_cjson_t));
memset(&current_item_value, 0, sizeof(lite_cjson_t));
/* parse the name of the child */
input_buffer->offset++;
buffer_skip_whitespace(input_buffer);
if (parse_string(&current_item_key, input_buffer) != 0) {
goto fail; /* faile to parse name */
}
buffer_skip_whitespace(input_buffer);
if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) {
goto fail; /* invalid object */
}
/* parse the value */
input_buffer->offset++;
buffer_skip_whitespace(input_buffer);
if (parse_value(&current_item_value, input_buffer) != 0) {
goto fail; /* failed to parse value */
}
buffer_skip_whitespace(input_buffer);
//printf("Current Object [Index: %d], [Key Length: %d, Key Value: %.*s], [Value Length: %d, Value: %.*s]\n",
// item->size+1,current_item_key.value_length,current_item_key.value_length,current_item_key.value,
// current_item_value.value_length,current_item_value.value_length,current_item_value.value);
item->size++;
} while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ','));
if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) {
goto fail; /* expected end of object */
}
success:
input_buffer->depth--;
item->type = cJSON_Object;
item->value = (char *)(input_buffer->content + start_pos);
item->value_length = input_buffer->offset - start_pos + 1;
input_buffer->offset++;
return 0;
fail:
return -1;
}
/* Parse the input text into an unescaped cinput, and populate item. */
static int parse_string(_IN_ lite_cjson_t *const item, _IN_ parse_buffer *const input_buffer)
{
const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1;
const unsigned char *input_end = buffer_at_offset(input_buffer) + 1;
//unsigned char *output_pointer = NULL;
//unsigned char *output = NULL;
/* not a string */
if (buffer_at_offset(input_buffer)[0] != '\"') {
//printf("not a string");
goto fail;
}
{
/* calculate approximate size of the output (overestimate) */
//int allocation_length = 0;
int skipped_bytes = 0;
while (((int)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) {
/* is escape sequence */
if (input_end[0] == '\\') {
if ((int)(input_end + 1 - input_buffer->content) >= input_buffer->length) {
/* prevent buffer overflow when last input character is a backslash */
goto fail;
}
skipped_bytes++;
input_end++;
}
input_end++;
}
if (((int)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) {
//printf("end error\n");
goto fail; /* string ended unexpectedly */
}
#if 0
/* This is at most how much we need for the output */
allocation_length = (int)(input_end - buffer_at_offset(input_buffer)) - skipped_bytes;
output = (unsigned char *)input_buffer->hooks.allocate(allocation_length + sizeof(""));
if (output == NULL) {
goto fail; /* allocation failure */
}
#endif
}
#if 0
output_pointer = output;
/* loop through the string literal */
while (input_pointer < input_end) {
if (*input_pointer != '\\') {
*output_pointer++ = *input_pointer++;
}
/* escape sequence */
else {
unsigned char sequence_length = 2;
if ((input_end - input_pointer) < 1) {
goto fail;
}
switch (input_pointer[1]) {
case 'b':
*output_pointer++ = '\b';
break;
case 'f':
*output_pointer++ = '\f';
break;
case 'n':
*output_pointer++ = '\n';
break;
case 'r':
*output_pointer++ = '\r';
break;
case 't':
*output_pointer++ = '\t';
break;
case '\"':
case '\\':
case '/':
*output_pointer++ = input_pointer[1];
break;
/* UTF-16 literal */
case 'u':
sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer);
if (sequence_length == 0) {
/* failed to convert UTF16-literal to UTF-8 */
goto fail;
}
break;
default:
goto fail;
}
input_pointer += sequence_length;
}
}
/* zero terminate the output */
*output_pointer = '\0';
#endif
item->type = cJSON_String;
item->value = (char *)input_pointer;
item->value_length = input_end - input_pointer;
input_buffer->offset = (int)(input_end - input_buffer->content);
input_buffer->offset++;
return 0;
fail:
#if 0
if (output != NULL) {
input_buffer->hooks.deallocate(output);
}
#endif
if (input_pointer != NULL) {
input_buffer->offset = (int)(input_pointer - input_buffer->content);
}
return -1;
}
/* Parser core - when encountering text, process appropriately. */
static int parse_value(_IN_ lite_cjson_t *const lite, _IN_ parse_buffer *const input_buffer)
{
if ((input_buffer == NULL) || (input_buffer->content == NULL)) {
return -1; /* no input */
}
/* parse the different types of values */
/* null */
if (can_read(input_buffer, 4) && (strncmp((const char *)buffer_at_offset(input_buffer), "null", 4) == 0)) {
lite->type = cJSON_NULL;
lite->value = (char *)buffer_at_offset(input_buffer);
lite->value_length = 4;
input_buffer->offset += 4;
return 0;
}
/* false */
if (can_read(input_buffer, 5) && (strncmp((const char *)buffer_at_offset(input_buffer), "false", 5) == 0)) {
lite->type = cJSON_False;
lite->value = (char *)buffer_at_offset(input_buffer);
lite->value_length = 5;
input_buffer->offset += 5;
return 0;
}
/* true */
if (can_read(input_buffer, 4) && (strncmp((const char *)buffer_at_offset(input_buffer), "true", 4) == 0)) {
lite->type = cJSON_True;
lite->value = (char *)buffer_at_offset(input_buffer);
lite->value_length = 4;
input_buffer->offset += 4;
return 0;
}
/* string */
if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) {
//printf("parse string\n");
return parse_string(lite, input_buffer);
}
/* number */
if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-')
|| ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) {
//printf("parse number\n");
return parse_number(lite, input_buffer);
}
/* array */
if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) {
//printf("parse array\n");
return parse_array(lite, input_buffer);
}
/* object */
if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) {
return parse_object(lite, input_buffer);
}
return -1;
}
int lite_cjson_parse(_IN_ const char *src, _IN_ int src_len, _OU_ lite_cjson_t *lite)
{
if (!lite || !src || !lite || src_len <= 0) {
return -1;
}
parse_buffer buffer;
memset(&buffer, 0, sizeof(parse_buffer));
buffer.content = (const unsigned char *)src;
buffer.length = src_len;
buffer.offset = 0;
if (parse_value(lite, buffer_skip_whitespace(skip_utf8_bom(&buffer))) != 0) {
lite->type = cJSON_Invalid;
lite->value = NULL;
lite->value_length = 0;
return -1;
}
return 0;
}
#if 0
int lite_cjson_is_false(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_False;
}
int lite_cjson_is_true(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_True;
}
int lite_cjson_is_null(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_NULL;
}
#endif
int lite_cjson_is_number(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_Number;
}
int lite_cjson_is_string(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_String;
}
int lite_cjson_is_array(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_Array;
}
int lite_cjson_is_object(_IN_ lite_cjson_t *lite)
{
if (!lite) {
return -1;
}
return (lite->type & 0xFF) == cJSON_Object;
}
int lite_cjson_array_item(_IN_ lite_cjson_t *lite, _IN_ int index, _OU_ lite_cjson_t *lite_item)
{
if (!lite || lite->type != cJSON_Array || !lite->value ||
index < 0 || index >= lite->size || !lite_item) {
return -1;
}
parse_buffer buffer;
parse_buffer *p_buffer = &buffer;
memset(&buffer, 0, sizeof(parse_buffer));
buffer.content = (const unsigned char *)lite->value;
buffer.length = lite->value_length;
buffer.offset = 0;
lite_cjson_t current_item;
//int start_pos = p_buffer->offset;
int iter_index = 0;
if (buffer_at_offset(p_buffer)[0] != '[') {
/* not an array */
return -1;
}
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == ']')) {
/* empty array */
return -1;
}
/* check if we skipped to the end of the buffer */
if (cannot_access_at_index(p_buffer, 0)) {
p_buffer->offset--;
return -1;
}
/* step back to character in front of the first element */
p_buffer->offset--;
/* loop through the comma separated array elements */
do {
memset(&current_item, 0, sizeof(lite_cjson_t));
/* parse next value */
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (parse_value(&current_item, p_buffer) != 0) {
return -1; /* failed to parse value */
}
buffer_skip_whitespace(p_buffer);
//printf("current item index: %d, type: %d, length: %d, value: %.*s\n",
// iter_index+1, current_item.type, current_item.value_length, current_item.value_length, current_item.value);
if (iter_index == index) {
memcpy(lite_item, &current_item, sizeof(lite_cjson_t));
return 0;
}
iter_index++;
} while (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == ','));
return -1;
}
static int _lite_cjson_object_item(_IN_ lite_cjson_t *lite, _IN_ const char *key, _IN_ int key_len,
_OU_ lite_cjson_t *lite_item)
{
if (!lite || lite->type != cJSON_Object || !lite->value || lite->size == 0 || !key || key_len <= 0 || !lite_item) {
return -1;
};
parse_buffer buffer;
parse_buffer *p_buffer = &buffer;
memset(&buffer, 0, sizeof(parse_buffer));
buffer.content = (const unsigned char *)lite->value;
buffer.length = lite->value_length;
buffer.offset = 0;
lite_cjson_t current_item_key;
lite_cjson_t current_item_value;
//int start_pos = p_buffer->offset;
int index = 0;
if (cannot_access_at_index(p_buffer, 0) || (buffer_at_offset(p_buffer)[0] != '{')) {
return -1; /* not an object */
}
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == '}')) {
return -1; /* empty object */
}
/* check if we skipped to the end of the buffer */
if (cannot_access_at_index(p_buffer, 0)) {
p_buffer->offset--;
return -1;
}
/* step back to character in front of the first element */
p_buffer->offset--;
/* loop through the comma separated array elements */
do {
memset(&current_item_key, 0, sizeof(lite_cjson_t));
memset(&current_item_value, 0, sizeof(lite_cjson_t));
/* parse the name of the child */
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (parse_string(&current_item_key, p_buffer) != 0) {
return -1; /* faile to parse name */
}
buffer_skip_whitespace(p_buffer);
if (cannot_access_at_index(p_buffer, 0) || (buffer_at_offset(p_buffer)[0] != ':')) {
return -1; /* invalid object */
}
/* parse the value */
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (parse_value(&current_item_value, p_buffer) != 0) {
return -1; /* failed to parse value */
}
buffer_skip_whitespace(p_buffer);
//printf("Current Object [Index: %d], [Key Length: %d, Key Value: %.*s], [Value Length: %d, Value: %.*s]\n",
// index + 1, current_item_key.value_length,current_item_key.value_length,current_item_key.value,
// current_item_value.value_length,current_item_value.value_length,current_item_value.value);
index++;
//printf("key: %s, ken_len: %d\n",key,key_len);
if ((current_item_key.value_length == key_len) &&
memcmp(current_item_key.value, key, key_len) == 0) {
memcpy(lite_item, &current_item_value, sizeof(lite_cjson_t));
return 0;
}
} while (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == ','));
return -1;
}
static int _lite_cjson_key_array_index(_IN_ const char *key, _IN_ int key_len,
_OU_ int *partial_key_len, _OU_ int *array_key_len, _OU_ int *array_index)
{
if (!key || !partial_key_len || !array_key_len || !array_index) {
return -1;
}
char *bracket_pre = NULL;
char *bracket_suf = NULL;
int index = 0;
int deep = 0;
char array_index_str[10] = {0};
for (index = 0; index < key_len; index++) {
switch (key[index]) {
case '[': {
if (deep != 0) {
return -1;
}
deep++;
if (!bracket_pre) {
bracket_pre = (char *)&key[index];
}
}
break;
case ']': {
if (deep != 1) {
return -1;
}
deep--;
if (key[index - 1] == '[') {
return -1;
}
if (!bracket_suf) {
bracket_suf = (char *)&key[index];
}
}
break;
default:
break;
}
}
if (bracket_pre && bracket_suf && ((bracket_suf - key + 1) == key_len)) {
*partial_key_len = bracket_pre - key;
*array_key_len = bracket_suf - key + 1;
//Get Index
memcpy(array_index_str, bracket_pre + 1, bracket_suf - bracket_pre - 1);
*array_index = atoi(array_index_str);
return 0;
}
return -1;
}
int lite_cjson_object_item(_IN_ lite_cjson_t *lite, _IN_ const char *key, _IN_ int key_len,
_OU_ lite_cjson_t *lite_item)
{
if (!lite || lite->type != cJSON_Object || !lite->value || lite->size == 0 || !key || key_len <= 0 || !lite_item) {
return -1;
};
int res = 0;
char *delim = NULL;
lite_cjson_t lite_prev;
lite_cjson_t lite_next;
lite_cjson_t lite_iter;
char *key_iter = (char *)key;
int key_iter_len = 0;
int partial_key_len = 0;
int array_key_len = 0;
int array_index = 0;
memcpy(&lite_iter, lite, sizeof(lite_cjson_t));
memset(&lite_prev, 0, sizeof(lite_cjson_t));
do {
if ((delim = strchr(key_iter, '.')) != NULL) {
//printf("delim exist,delim : %s\n",delim);
memset(&lite_next, 0, sizeof(lite_cjson_t));
partial_key_len = array_key_len = array_index = 0;
key_iter_len = (int)(delim - key_iter);
} else {
key_iter_len = key_len - (key_iter - key);
//printf("key: %s, last key: %s, key len: %d, last key len: %d\n",key, key_iter, key_len, key_iter_len);
}
if (_lite_cjson_key_array_index(key_iter, key_iter_len,
&partial_key_len, &array_key_len, &array_index) == 0) {
//printf("partial_key_len: %d, array_key_len: %d, array_index: %d\n", partial_key_len, array_key_len, array_index);
res = _lite_cjson_object_item(&lite_iter, key_iter, partial_key_len, &lite_prev);
if (res || lite_prev.type != cJSON_Array) {
return -1;
}
//printf("current array: %.*s\n",lite_prev.value_length,lite_prev.value);
res = lite_cjson_array_item(&lite_prev, array_index, &lite_next);
if (res) {
return -1;
}
//printf("current array item: %.*s\n",lite_next.value_length,lite_next.value);
memcpy(&lite_iter, &lite_next, sizeof(lite_cjson_t));
key_iter += array_key_len + 1;
//printf("key_iter: %s\n",key_iter);
} else {
res = _lite_cjson_object_item(&lite_iter, key_iter, key_iter_len, &lite_prev);
if (res) {
return -1;
}
//printf("current object: %.*s\n",lite_prev.value_length,lite_prev.value);
memcpy(&lite_iter, &lite_prev, sizeof(lite_cjson_t));
key_iter = delim + 1;
}
} while (delim);
//printf("final lite cjson value: %.*s\n",lite_iter.value_length,lite_iter.value);
memcpy(lite_item, &lite_iter, sizeof(lite_cjson_t));
return 0;
}
int lite_cjson_object_item_by_index(_IN_ lite_cjson_t *lite, _IN_ int index, _OU_ lite_cjson_t *lite_item_key,
_OU_ lite_cjson_t *lite_item_value)
{
if (!lite || lite->type != cJSON_Object || !lite->value || lite->size == 0 || index < 0 || index >= lite->size) {
return -1;
};
parse_buffer buffer;
parse_buffer *p_buffer = &buffer;
memset(&buffer, 0, sizeof(parse_buffer));
buffer.content = (const unsigned char *)lite->value;
buffer.length = lite->value_length;
buffer.offset = 0;
lite_cjson_t current_item_key;
lite_cjson_t current_item_value;
//int start_pos = p_buffer->offset;
int item_index = 0;
if (cannot_access_at_index(p_buffer, 0) || (buffer_at_offset(p_buffer)[0] != '{')) {
return -1; /* not an object */
}
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == '}')) {
return -1; /* empty object */
}
/* check if we skipped to the end of the buffer */
if (cannot_access_at_index(p_buffer, 0)) {
p_buffer->offset--;
return -1;
}
/* step back to character in front of the first element */
p_buffer->offset--;
/* loop through the comma separated array elements */
do {
memset(&current_item_key, 0, sizeof(lite_cjson_t));
memset(&current_item_value, 0, sizeof(lite_cjson_t));
/* parse the name of the child */
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (parse_string(&current_item_key, p_buffer) != 0) {
return -1; /* faile to parse name */
}
buffer_skip_whitespace(p_buffer);
if (cannot_access_at_index(p_buffer, 0) || (buffer_at_offset(p_buffer)[0] != ':')) {
return -1; /* invalid object */
}
/* parse the value */
p_buffer->offset++;
buffer_skip_whitespace(p_buffer);
if (parse_value(&current_item_value, p_buffer) != 0) {
return -1; /* failed to parse value */
}
buffer_skip_whitespace(p_buffer);
//printf("Current Object [Index: %d], [Key Length: %d, Key Value: %.*s], [Value Length: %d, Value: %.*s]\n",
// index + 1, current_item_key.value_length,current_item_key.value_length,current_item_key.value,
// current_item_value.value_length,current_item_value.value_length,current_item_value.value);
//printf("index:%d, key: %.*s, value: %.*s\n",index,
// current_item_key.value_length,current_item_key.value,
// current_item_value.value_length,current_item_value.value);
if (item_index == index) {
if (lite_item_key) {
memcpy(lite_item_key, &current_item_key, sizeof(lite_cjson_t));
}
if (lite_item_value) {
memcpy(lite_item_value, &current_item_value, sizeof(lite_cjson_t));
}
return 0;
}
item_index++;
} while (can_access_at_index(p_buffer, 0) && (buffer_at_offset(p_buffer)[0] == ','));
return -1;
}
#define true ((cJSON_bool)1)
#define false ((cJSON_bool)0)
#define cjson_min(a, b) ((a < b) ? a : b)
typedef struct internal_hooks {
void *(*allocate)(uint32_t size);
void (*deallocate)(void *pointer);
void *(*reallocate)(void *pointer, size_t size);
} internal_hooks;
typedef struct {
unsigned char *buffer;
size_t length;
size_t offset;
size_t depth; /* current nesting depth (for formatted printing) */
cJSON_bool noalloc;
cJSON_bool format; /* is this print a formatted print */
internal_hooks hooks;
} printbuffer;
static void *internal_malloc(uint32_t size)
{
return malloc(size);
}
static void internal_free(void *ptr)
{
free(ptr);
}
static internal_hooks global_hooks = { internal_malloc, internal_free, NULL };
static cJSON_bool print_value(const lite_cjson_item_t *const item, printbuffer *const output_buffer);
void lite_cjson_init_hooks(lite_cjson_hooks *hooks)
{
if (hooks == NULL || hooks->malloc_fn == NULL || hooks->free_fn == NULL) {
return;
}
global_hooks.allocate = hooks->malloc_fn;
global_hooks.deallocate = hooks->free_fn;
}
static unsigned char *ensure(printbuffer *const p, size_t needed)
{
unsigned char *newbuffer = NULL;
size_t newsize = 0;
if ((p == NULL) || (p->buffer == NULL)) {
return NULL;
}
if ((p->length > 0) && (p->offset >= p->length)) {
/* make sure that offset is valid */
return NULL;
}
if (needed > INT_MAX) {
/* sizes bigger than INT_MAX are currently not supported */
return NULL;
}
needed += p->offset + 1;
if (needed <= p->length) {
return p->buffer + p->offset;
}
if (p->noalloc) {
return NULL;
}
/* calculate new buffer size */
if (needed > (INT_MAX / 2)) {
/* overflow of int, use INT_MAX if possible */
if (needed <= INT_MAX) {
newsize = INT_MAX;
} else {
return NULL;
}
} else {
newsize = needed * 2;
}
if (p->hooks.reallocate != NULL) {
/* reallocate with realloc if available */
newbuffer = (unsigned char *)p->hooks.reallocate(p->buffer, newsize);
if (newbuffer == NULL) {
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
} else {
/* otherwise reallocate manually */
newbuffer = (unsigned char *)p->hooks.allocate(newsize);
if (!newbuffer) {
p->hooks.deallocate(p->buffer);
p->length = 0;
p->buffer = NULL;
return NULL;
}
if (newbuffer) {
memcpy(newbuffer, p->buffer, p->offset + 1);
}
p->hooks.deallocate(p->buffer);
}
p->length = newsize;
p->buffer = newbuffer;
return newbuffer + p->offset;
}
/* get the decimal point character of the current locale */
static unsigned char get_decimal_point(void)
{
#ifdef ENABLE_LOCALES
struct lconv *lconv = localeconv();
return (unsigned char) lconv->decimal_point[0];
#else
return '.';
#endif
}
static int remove_zero(unsigned char buffer[26], int length)
{
int idx = 0, found = 0;
for (idx = 0;idx < 26;idx++) {
if (buffer[idx] == '.') {
found = 1;
continue;
}
if (buffer[idx] == '\0') {
break;
}
}
if (found == 0) {
return length;
}
for (;idx > 0;idx--) {
if (buffer[idx-1] == '0') {
buffer[idx-1] = '\0';
length--;
}else{
if (buffer[idx-1] == '.') {
buffer[idx-1] = '\0';
length--;
}
break;
}
}
return length;
}
/* Render the number nicely from the given item into a string. */
static cJSON_bool print_number(const lite_cjson_item_t *const item, printbuffer *const output_buffer)
{
unsigned char *output_pointer = NULL;
double d = item->valuedouble;
int length = 0;
size_t i = 0;
unsigned char number_buffer[26]; /* temporary buffer to print the number into */
unsigned char decimal_point = get_decimal_point();
float test_float;
double test;
if (output_buffer == NULL) {
return false;
}
/* This checks for NaN and Infinity */
if ((d * 0) != 0) {
length = sprintf((char *)number_buffer, "null");
} else {
/* Try float data type */
length = sprintf((char *)number_buffer, "%f", d);
if ((sscanf((char *)number_buffer, "%f", &test_float) != 1) || ((double)test_float != d)) {
/* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
length = sprintf((char *)number_buffer, "%1.15g", d);
/* Check whether the original double can be recovered */
if ((sscanf((char *)number_buffer, "%lg", &test) != 1) || ((double)test != d)) {
/* If not, print with 17 decimal places of precision */
length = sprintf((char *)number_buffer, "%1.17g", d);
}
}else{
length = remove_zero(number_buffer,length);
}
}
/* sprintf failed or buffer overrun occured */
if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) {
return false;
}
/* reserve appropriate space in the output */
output_pointer = ensure(output_buffer, (size_t)length + sizeof(""));
if (output_pointer == NULL) {
return false;
}
/* copy the printed number to the output and replace locale
* dependent decimal point with '.' */
for (i = 0; i < ((size_t)length); i++) {
if (number_buffer[i] == decimal_point) {
output_pointer[i] = '.';
continue;
}
output_pointer[i] = number_buffer[i];
}
output_pointer[i] = '\0';
output_buffer->offset += (size_t)length;
return true;
}
/* Render the cstring provided to an escaped version that can be printed. */
static cJSON_bool print_string_ptr(const unsigned char *const input, printbuffer *const output_buffer)
{
const unsigned char *input_pointer = NULL;
unsigned char *output = NULL;
unsigned char *output_pointer = NULL;
size_t output_length = 0;
/* numbers of additional characters needed for escaping */
size_t escape_characters = 0;
if (output_buffer == NULL) {
return false;
}
/* empty string */
if (input == NULL) {
output = ensure(output_buffer, sizeof("\"\""));
if (output == NULL) {
return false;
}
strcpy((char *)output, "\"\"");
return true;
}
/* set "flag" to 1 if something needs to be escaped */
for (input_pointer = input; *input_pointer; input_pointer++) {
switch (*input_pointer) {
case '\"':
case '\\':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
/* one character escape sequence */
escape_characters++;
break;
default:
if (*input_pointer < 32) {
/* UTF-16 escape sequence uXXXX */
escape_characters += 5;
}
break;
}
}
output_length = (size_t)(input_pointer - input) + escape_characters;
output = ensure(output_buffer, output_length + sizeof("\"\""));
if (output == NULL) {
return false;
}
/* no characters have to be escaped */
if (escape_characters == 0) {
output[0] = '\"';
memcpy(output + 1, input, output_length);
output[output_length + 1] = '\"';
output[output_length + 2] = '\0';
return true;
}
output[0] = '\"';
output_pointer = output + 1;
/* copy the string */
for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) {
if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) {
/* normal character, copy */
*output_pointer = *input_pointer;
} else {
/* character needs to be escaped */
*output_pointer++ = '\\';
switch (*input_pointer) {
case '\\':
*output_pointer = '\\';
break;
case '\"':
*output_pointer = '\"';
break;
case '\b':
*output_pointer = 'b';
break;
case '\f':
*output_pointer = 'f';
break;
case '\n':
*output_pointer = 'n';
break;
case '\r':
*output_pointer = 'r';
break;
case '\t':
*output_pointer = 't';
break;
default:
/* escape and print as unicode codepoint */
sprintf((char *)output_pointer, "u%04x", *input_pointer);
output_pointer += 4;
break;
}
}
}
output[output_length + 1] = '\"';
output[output_length + 2] = '\0';
return true;
}
/* Invoke print_string_ptr (which is useful) on an item. */
static cJSON_bool print_string(const lite_cjson_item_t *const item, printbuffer *const p)
{
return print_string_ptr((unsigned char *)item->valuestring, p);
}
/* calculate the new length of the string in a printbuffer and update the offset */
static void update_offset(printbuffer *const buffer)
{
const unsigned char *buffer_pointer = NULL;
if ((buffer == NULL) || (buffer->buffer == NULL)) {
return;
}
buffer_pointer = buffer->buffer + buffer->offset;
buffer->offset += strlen((const char *)buffer_pointer);
}
/* Render an array to text */
static cJSON_bool print_array(const lite_cjson_item_t *const item, printbuffer *const output_buffer)
{
unsigned char *output_pointer = NULL;
size_t length = 0;
lite_cjson_item_t *current_element = item->child;
if (output_buffer == NULL) {
return false;
}
/* Compose the output array. */
/* opening square bracket */
output_pointer = ensure(output_buffer, 1);
if (output_pointer == NULL) {
return false;
}
*output_pointer = '[';
output_buffer->offset++;
output_buffer->depth++;
while (current_element != NULL) {
if (!print_value(current_element, output_buffer)) {
return false;
}
update_offset(output_buffer);
if (current_element->next) {
length = (size_t)(output_buffer->format ? 2 : 1);
output_pointer = ensure(output_buffer, length + 1);
if (output_pointer == NULL) {
return false;
}
*output_pointer++ = ',';
if (output_buffer->format) {
*output_pointer++ = ' ';
}
*output_pointer = '\0';
output_buffer->offset += length;
}
current_element = current_element->next;
}
output_pointer = ensure(output_buffer, 2);
if (output_pointer == NULL) {
return false;
}
*output_pointer++ = ']';
*output_pointer = '\0';
output_buffer->depth--;
return true;
}
/* Render an object to text. */
static cJSON_bool print_object(const lite_cjson_item_t *const item, printbuffer *const output_buffer)
{
unsigned char *output_pointer = NULL;
size_t length = 0;
lite_cjson_item_t *current_item = item->child;
if (output_buffer == NULL) {
return false;
}
/* Compose the output: */
length = (size_t)(output_buffer->format ? 2 : 1); /* fmt: {\n */
output_pointer = ensure(output_buffer, length + 1);
if (output_pointer == NULL) {
return false;
}
*output_pointer++ = '{';
output_buffer->depth++;
if (output_buffer->format) {
*output_pointer++ = '\n';
}
output_buffer->offset += length;
while (current_item) {
if (output_buffer->format) {
size_t i;
output_pointer = ensure(output_buffer, output_buffer->depth);
if (output_pointer == NULL) {
return false;
}
for (i = 0; i < output_buffer->depth; i++) {
*output_pointer++ = '\t';
}
output_buffer->offset += output_buffer->depth;
}
/* print key */
if (!print_string_ptr((unsigned char *)current_item->string, output_buffer)) {
return false;
}
update_offset(output_buffer);
length = (size_t)(output_buffer->format ? 2 : 1);
output_pointer = ensure(output_buffer, length);
if (output_pointer == NULL) {
return false;
}
*output_pointer++ = ':';
if (output_buffer->format) {
*output_pointer++ = '\t';
}
output_buffer->offset += length;
/* print value */
if (!print_value(current_item, output_buffer)) {
return false;
}
update_offset(output_buffer);
/* print comma if not last */
length = (size_t)((output_buffer->format ? 1 : 0) + (current_item->next ? 1 : 0));
output_pointer = ensure(output_buffer, length + 1);
if (output_pointer == NULL) {
return false;
}
if (current_item->next) {
*output_pointer++ = ',';
}
if (output_buffer->format) {
*output_pointer++ = '\n';
}
*output_pointer = '\0';
output_buffer->offset += length;
current_item = current_item->next;
}
output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2);
if (output_pointer == NULL) {
return false;
}
if (output_buffer->format) {
size_t i;
for (i = 0; i < (output_buffer->depth - 1); i++) {
*output_pointer++ = '\t';
}
}
*output_pointer++ = '}';
*output_pointer = '\0';
output_buffer->depth--;
return true;
}
/* Render a value to text. */
static cJSON_bool print_value(const lite_cjson_item_t *const item, printbuffer *const output_buffer)
{
unsigned char *output = NULL;
if ((item == NULL) || (output_buffer == NULL)) {
return false;
}
switch ((item->type) & 0xFF) {
case cJSON_NULL:
output = ensure(output_buffer, 5);
if (output == NULL) {
return false;
}
strcpy((char *)output, "null");
return true;
case cJSON_False:
output = ensure(output_buffer, 6);
if (output == NULL) {
return false;
}
strcpy((char *)output, "false");
return true;
case cJSON_True:
output = ensure(output_buffer, 5);
if (output == NULL) {
return false;
}
strcpy((char *)output, "true");
return true;
case cJSON_Number:
return print_number(item, output_buffer);
case cJSON_Raw: {
size_t raw_length = 0;
if (item->valuestring == NULL) {
return false;
}
raw_length = strlen(item->valuestring) + sizeof("");
output = ensure(output_buffer, raw_length);
if (output == NULL) {
return false;
}
memcpy(output, item->valuestring, raw_length);
return true;
}
case cJSON_String:
return print_string(item, output_buffer);
case cJSON_Array:
return print_array(item, output_buffer);
case cJSON_Object:
return print_object(item, output_buffer);
default:
return false;
}
}
static unsigned char *print(const lite_cjson_item_t *const item, cJSON_bool format, const internal_hooks *const hooks)
{
static const size_t default_buffer_size = 256;
printbuffer buffer[1];
unsigned char *printed = NULL;
memset(buffer, 0, sizeof(buffer));
/* create buffer */
buffer->buffer = (unsigned char *) hooks->allocate(default_buffer_size);
buffer->length = default_buffer_size;
buffer->format = format;
buffer->hooks = *hooks;
if (buffer->buffer == NULL) {
goto fail;
}
/* print the value */
if (!print_value(item, buffer)) {
goto fail;
}
update_offset(buffer);
/* check if reallocate is available */
if (hooks->reallocate != NULL) {
printed = (unsigned char *) hooks->reallocate(buffer->buffer, buffer->offset + 1);
if (printed == NULL) {
goto fail;
}
buffer->buffer = NULL;
} else { /* otherwise copy the JSON over to a new buffer */
printed = (unsigned char *) hooks->allocate(buffer->offset + 1);
if (printed == NULL) {
goto fail;
}
memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
printed[buffer->offset] = '\0'; /* just to be sure */
/* free the buffer */
hooks->deallocate(buffer->buffer);
}
return printed;
fail:
if (buffer->buffer != NULL) {
hooks->deallocate(buffer->buffer);
}
return NULL;
}
char *lite_cjson_print(lite_cjson_item_t *item)
{
return (char *)print(item, true, &global_hooks);
}
char *lite_cjson_print_unformatted(lite_cjson_item_t *item)
{
return (char *)print(item, false, &global_hooks);
}
/* Delete a cJSON structure. */
void lite_cjson_delete(lite_cjson_item_t *item)
{
lite_cjson_item_t *next = NULL;
while (item != NULL) {
next = item->next;
if (!(item->type & cJSON_IsReference) && (item->child != NULL)) {
lite_cjson_delete(item->child);
}
if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) {
global_hooks.deallocate(item->valuestring);
}
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) {
global_hooks.deallocate(item->string);
}
global_hooks.deallocate(item);
item = next;
}
}
static void suffix_object(lite_cjson_item_t *prev, lite_cjson_item_t *item)
{
prev->next = item;
item->prev = prev;
}
static cJSON_bool add_item_to_array(lite_cjson_item_t *array, lite_cjson_item_t *item)
{
lite_cjson_item_t *child = NULL;
if ((item == NULL) || (array == NULL)) {
return false;
}
child = array->child;
if (child == NULL) {
/* list is empty, start new one */
array->child = item;
} else {
/* append to the end */
while (child->next) {
child = child->next;
}
suffix_object(child, item);
}
return true;
}
void lite_cjson_add_item_to_array(lite_cjson_item_t *array, lite_cjson_item_t *item)
{
add_item_to_array(array, item);
}
static void *cast_away_const(const void *string)
{
return (void *)string;
}
static unsigned char *cJSON_strdup(const unsigned char *string, const internal_hooks *const hooks)
{
size_t length = 0;
unsigned char *copy = NULL;
if (string == NULL) {
return NULL;
}
length = strlen((const char *)string) + sizeof("");
copy = (unsigned char *)hooks->allocate(length);
if (copy == NULL) {
return NULL;
}
memcpy(copy, string, length);
return copy;
}
static cJSON_bool add_item_to_object(lite_cjson_item_t *const object, const char *const string,
lite_cjson_item_t *const item, const internal_hooks *const hooks, const cJSON_bool constant_key)
{
char *new_key = NULL;
int new_type = cJSON_Invalid;
if ((object == NULL) || (string == NULL) || (item == NULL)) {
return false;
}
if (constant_key) {
new_key = (char *)cast_away_const(string);
new_type = item->type | cJSON_StringIsConst;
} else {
new_key = (char *)cJSON_strdup((const unsigned char *)string, hooks);
if (new_key == NULL) {
return false;
}
new_type = item->type & ~cJSON_StringIsConst;
}
if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) {
hooks->deallocate(item->string);
}
item->string = new_key;
item->type = new_type;
return add_item_to_array(object, item);
}
void lite_cjson_add_item_to_object(lite_cjson_item_t *object, const char *string, lite_cjson_item_t *item)
{
add_item_to_object(object, string, item, &global_hooks, false);
}
static lite_cjson_item_t *cJSON_New_Item(const internal_hooks *const hooks)
{
lite_cjson_item_t *node = (lite_cjson_item_t *)hooks->allocate(sizeof(lite_cjson_item_t));
if (node) {
memset(node, '\0', sizeof(lite_cjson_item_t));
}
return node;
}
lite_cjson_item_t *lite_cjson_create_null(void)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_NULL;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_true(void)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_True;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_false(void)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_False;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_bool(cJSON_bool b)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = b ? cJSON_True : cJSON_False;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_number(double num)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_Number;
item->valuedouble = num;
/* use saturation in case of overflow */
if (num >= INT_MAX) {
item->valueint = INT_MAX;
} else if (num <= INT_MIN) {
item->valueint = INT_MIN;
} else {
item->valueint = (int)num;
}
}
return item;
}
lite_cjson_item_t *lite_cjson_create_string(const char *string)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_String;
item->valuestring = (char *)cJSON_strdup((const unsigned char *)string, &global_hooks);
if (!item->valuestring) {
lite_cjson_delete(item);
return NULL;
}
}
return item;
}
lite_cjson_item_t *lite_cjson_create_array(void)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_Array;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_object(void)
{
lite_cjson_item_t *item = cJSON_New_Item(&global_hooks);
if (item) {
item->type = cJSON_Object;
}
return item;
}
lite_cjson_item_t *lite_cjson_create_intArray(const int *numbers, int count)
{
size_t i = 0;
lite_cjson_item_t *n = NULL;
lite_cjson_item_t *p = NULL;
lite_cjson_item_t *a = NULL;
if ((count < 0) || (numbers == NULL)) {
return NULL;
}
a = lite_cjson_create_array();
for (i = 0; a && (i < (size_t)count); i++) {
n = lite_cjson_create_number(numbers[i]);
if (!n) {
lite_cjson_delete(a);
return NULL;
}
if (!i) {
a->child = n;
} else {
suffix_object(p, n);
}
p = n;
}
return a;
}
lite_cjson_item_t *lite_cjson_create_floatArray(const float *numbers, int count)
{
size_t i = 0;
lite_cjson_item_t *n = NULL;
lite_cjson_item_t *p = NULL;
lite_cjson_item_t *a = NULL;
if ((count < 0) || (numbers == NULL)) {
return NULL;
}
a = lite_cjson_create_array();
for (i = 0; a && (i < (size_t)count); i++) {
n = lite_cjson_create_number((double)numbers[i]);
if (!n) {
lite_cjson_delete(a);
return NULL;
}
if (!i) {
a->child = n;
} else {
suffix_object(p, n);
}
p = n;
}
return a;
}
lite_cjson_item_t *lite_cjson_create_doubleArray(const double *numbers, int count)
{
size_t i = 0;
lite_cjson_item_t *n = NULL;
lite_cjson_item_t *p = NULL;
lite_cjson_item_t *a = NULL;
if ((count < 0) || (numbers == NULL)) {
return NULL;
}
a = lite_cjson_create_array();
for (i = 0; a && (i < (size_t)count); i++) {
n = lite_cjson_create_number(numbers[i]);
if (!n) {
lite_cjson_delete(a);
return NULL;
}
if (!i) {
a->child = n;
} else {
suffix_object(p, n);
}
p = n;
}
return a;
}
lite_cjson_item_t *lite_cjson_create_stringArray(const char **strings, int count)
{
size_t i = 0;
lite_cjson_item_t *n = NULL;
lite_cjson_item_t *p = NULL;
lite_cjson_item_t *a = NULL;
if ((count < 0) || (strings == NULL)) {
return NULL;
}
a = lite_cjson_create_array();
for (i = 0; a && (i < (size_t)count); i++) {
n = lite_cjson_create_string(strings[i]);
if (!n) {
lite_cjson_delete(a);
return NULL;
}
if (!i) {
a->child = n;
} else {
suffix_object(p, n);
}
p = n;
}
return a;
}
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
#ifndef __LITE_CJSON_H__
#define __LITE_CJSON_H__
#ifndef _IN_
#define _IN_
#endif
#ifndef _OU_
#define _OU_
#endif
typedef unsigned int uint32_t;
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#ifndef LITE_CJSON_NESTING_LIMIT
#define LITE_CJSON_NESTING_LIMIT 1000
#endif
/* The cJSON structure: */
typedef struct lite_cjson_st {
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *value;
int value_length;
/* The item's size, if type == cJSON_Array and type == cJSON_Object */
int size;
double value_double;
int value_int;
} lite_cjson_t;
int lite_cjson_parse(_IN_ const char *src, _IN_ int src_len, _OU_ lite_cjson_t *lite);
int lite_cjson_is_false(_IN_ lite_cjson_t *lite);
int lite_cjson_is_true(_IN_ lite_cjson_t *lite);
int lite_cjson_is_null(_IN_ lite_cjson_t *lite);
int lite_cjson_is_number(_IN_ lite_cjson_t *lite);
int lite_cjson_is_string(_IN_ lite_cjson_t *lite);
int lite_cjson_is_array(_IN_ lite_cjson_t *lite);
int lite_cjson_is_object(_IN_ lite_cjson_t *lite);
int lite_cjson_array_item(_IN_ lite_cjson_t *lite, _IN_ int index, _OU_ lite_cjson_t *lite_item);
int lite_cjson_object_item(
_IN_ lite_cjson_t *lite,
_IN_ const char *key,
_IN_ int key_len,
_OU_ lite_cjson_t *lite_item);
int lite_cjson_object_item_by_index(
_IN_ lite_cjson_t *lite,
_IN_ int index,
_OU_ lite_cjson_t *lite_item_key,
_OU_ lite_cjson_t *lite_item_value);
/*** lite_cjson create, add and print ***/
typedef int cJSON_bool;
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct lite_cjson_item_t {
struct lite_cjson_item_t *next,
*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct lite_cjson_item_t
*child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} lite_cjson_item_t;
typedef struct {
void *(*malloc_fn)(unsigned int sz);
void(*free_fn)(void *ptr);
} lite_cjson_hooks;
void lite_cjson_init_hooks(lite_cjson_hooks *hooks);
/* Render a lite_cjson_item_t entity to text for transfer/storage. Free the char* when finished. */
char *lite_cjson_print(lite_cjson_item_t *item);
char *lite_cjson_print_unformatted(lite_cjson_item_t *item);
/* Delete a lite_cjson_item_t entity and all subentities. */
void lite_cjson_delete(lite_cjson_item_t *item);
/* Append item to specific object */
void lite_cjson_add_item_to_array(lite_cjson_item_t *array, lite_cjson_item_t *item);
void lite_cjson_add_item_to_object(lite_cjson_item_t *object, const char *string, lite_cjson_item_t *item);
/* These calls create a lite_cjson_item_t item of the appropriate type. */
lite_cjson_item_t *lite_cjson_create_null(void);
lite_cjson_item_t *lite_cjson_create_true(void);
lite_cjson_item_t *lite_cjson_create_false(void);
lite_cjson_item_t *lite_cjson_create_bool(int b);
lite_cjson_item_t *lite_cjson_create_number(double num);
lite_cjson_item_t *lite_cjson_create_string(const char *string);
lite_cjson_item_t *lite_cjson_create_array(void);
lite_cjson_item_t *lite_cjson_create_object(void);
/* These utilities create an Array of count items. */
lite_cjson_item_t *lite_cjson_create_intArray(const int *numbers, int count);
lite_cjson_item_t *lite_cjson_create_floatArray(const float *numbers, int count);
lite_cjson_item_t *lite_cjson_create_doubleArray(const double *numbers, int count);
lite_cjson_item_t *lite_cjson_create_stringArray(const char **strings, int count);
/* Macros for creating things quickly. */
#define lite_cjson_add_null_to_object(object,name) lite_cjson_add_item_to_object(object, name, lite_cjson_create_null())
#define lite_cjson_add_true_to_object(object,name) lite_cjson_add_item_to_object(object, name, lite_cjson_create_true())
#define lite_cjson_add_false_to_object(object,name) lite_cjson_add_item_to_object(object, name, lite_cjson_create_false())
#define lite_cjson_add_bool_to_object(object,name,b) lite_cjson_add_item_to_object(object, name, lite_cjson_create_bool(b))
#define lite_cjson_add_number_to_object(object,name,n) lite_cjson_add_item_to_object(object, name, lite_cjson_create_number(n))
#define lite_cjson_add_string_to_object(object,name,s) lite_cjson_add_item_to_object(object, name, lite_cjson_create_string(s))
#endif
/*
* please modify this string follow as product's TSL.
*/
static const char TSL_STRING[] =
"{\"schema\":\"https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/"
"schema.json\",\"profile\":{\"productKey\":\"a1X2bEnP82z\"},\"services\":[{"
"\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":"
"true,\"callType\":\"async\",\"desc\":\"属性设置\"},{\"outputData\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":"
"\"WIFI_Band\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{"
"\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_"
"BSSID\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},"
"\"name\":\"热点BSSID\"},{\"identifier\":\"WIFI_Channel\",\"dataType\":{"
"\"specs\":{\"min\":\"1\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":"
"\"127\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信噪比\"},{"
"\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_"
"Name\"},{\"identifier\":\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Rx_Rate_Name\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":"
"\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"红色\"},"
"{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":\"RGB调色\"},{"
"\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":"
"\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":"
"\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":"
"\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0."
"01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"明度\"}],\"type\":\"struct\"},\"name\":\"HSV调色\"},{\"identifier\":"
"\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Lightness\",\"dataType\":"
"{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"亮度\"}],"
"\"type\":\"struct\"},\"name\":\"HSL调色\"},{\"identifier\":\"WorkMode\","
"\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":"
"\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},\"name\":"
"\"工作模式\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{"
"\"0\":\"关闭\",\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\"},{"
"\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"明暗度\"},{\"identifier\":\"ColorTemperature\","
"\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2000\",\"unitName\":"
"\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"冷暖色温\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":"
"{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\"}"
",{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-"
"100\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"Propertypoint_Name\"}],\"identifier\":\"get\",\"inputData\":["
"\"LightSwitch\",\"WIFI_Band\",\"WiFI_RSSI\",\"WIFI_AP_BSSID\",\"WIFI_"
"Channel\",\"WiFI_SNR\",\"WIFI_Tx_Rate\",\"WIFI_Rx_Rate\",\"RGBColor\","
"\"HSVColor\",\"HSLColor\",\"WorkMode\",\"NightLightSwitch\",\"Brightness\","
"\"ColorTemperature\",\"PropertyCharacter\",\"Propertypoint\"],\"method\":"
"\"thing.service.property.get\",\"name\":\"get\",\"required\":true,"
"\"callType\":\"async\",\"desc\":\"属性获取\"}],\"properties\":[{"
"\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"主灯开关\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_Band\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"频段\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WiFI_RSSI\","
"\"dataType\":{\"specs\":{\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"-"
"1\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信号强度\",\"accessMode\":"
"\"rw\",\"required\":true},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\","
"\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"WIFI_Channel\","
"\"dataType\":{\"specs\":{\"min\":\"1\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"信道\",\"accessMode\":\"rw\","
"\"required\":true},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\",\"accessMode\":\"rw\",\"required\":"
"true},{\"identifier\":\"WIFI_Tx_Rate\",\"dataType\":{\"specs\":{\"min\":"
"\"0\",\"max\":\"99999\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_"
"Tx_Rate_Name\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WIFI_Rx_Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"RGBColor\","
"\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{"
"\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":\"Blue\",\"dataType\":"
"{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":\"struct\"},\"name\":"
"\"RGB调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{"
"\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":"
"\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\","
"\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"明度\"}],"
"\"type\":\"struct\"},\"name\":\"HSV调色\",\"accessMode\":\"rw\","
"\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"手动\",\"1\":\"阅读\",\"2\":"
"\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":\"柔和\"},\"type\":\"enum\"},"
"\"name\":\"工作模式\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\","
"\"1\":\"开启\"},\"type\":\"bool\"},\"name\":\"夜灯开关\",\"accessMode\":"
"\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"明暗度\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":"
"\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":"
"\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\",\"step\":\"1\"},\"type\":"
"\"int\"},\"name\":\"冷暖色温\",\"accessMode\":\"rw\",\"required\":false},{"
"\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":"
"\"255\"},\"type\":\"text\"},\"name\":\"PropertyCharacter_Name\","
"\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\","
"\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\",\"step\":\"0.01\"}"
",\"type\":\"double\"},\"name\":\"Propertypoint_Name\",\"accessMode\":\"rw\","
"\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":"
"\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"},"
"\"type\":\"bool\"},\"name\":\"主灯开关\"},{\"identifier\":\"WIFI_Band\","
"\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":"
"\"频段\"},{\"identifier\":\"WiFI_RSSI\",\"dataType\":{\"specs\":{\"min\":\"-"
"127\",\"unitName\":\"无\",\"max\":\"-1\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信号强度\"},{\"identifier\":\"WIFI_AP_BSSID\",\"dataType\":{"
"\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"热点BSSID\"},{"
"\"identifier\":\"WIFI_Channel\",\"dataType\":{\"specs\":{\"min\":\"1\","
"\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"},\"type\":\"int\"},"
"\"name\":\"信道\"},{\"identifier\":\"WiFI_SNR\",\"dataType\":{\"specs\":{"
"\"min\":\"-127\",\"unitName\":\"无\",\"max\":\"127\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"信噪比\"},{\"identifier\":\"WIFI_Tx_Rate\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":\"1\"},"
"\"type\":\"int\"},\"name\":\"WIFI_Tx_Rate_Name\"},{\"identifier\":\"WIFI_Rx_"
"Rate\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"99999\",\"step\":"
"\"1\"},\"type\":\"int\"},\"name\":\"WIFI_Rx_Rate_Name\"},{\"identifier\":"
"\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{"
"\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\",\"step\":\"1\"}"
",\"type\":\"int\"},\"name\":\"红色\"},{\"identifier\":\"Green\","
"\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":\"255\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"绿色\"},{\"identifier\":"
"\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"无\",\"max\":"
"\"255\",\"step\":\"1\"},\"type\":\"int\"},\"name\":\"蓝色\"}],\"type\":"
"\"struct\"},\"name\":\"RGB调色\"},{\"identifier\":\"HSVColor\",\"dataType\":"
"{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\","
"\"min\":\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":"
"\"饱和度\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%"
"\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"明度\"}],\"type\":\"struct\"},\"name\":"
"\"HSV调色\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{"
"\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":"
"\"0\",\"unitName\":\"度\",\"max\":\"360\",\"step\":\"0.01\"},\"type\":"
"\"double\"},\"name\":\"色调\"},{\"identifier\":\"Saturation\",\"dataType\":{"
"\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"百分比\",\"max\":"
"\"100\",\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"饱和度\"},{"
"\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\","
"\"min\":\"0\",\"unitName\":\"百分比\",\"max\":\"100\",\"step\":\"0.01\"},"
"\"type\":\"double\"},\"name\":\"亮度\"}],\"type\":\"struct\"},\"name\":"
"\"HSL调色\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":"
"\"手动\",\"1\":\"阅读\",\"2\":\"影院\",\"3\":\"夜灯\",\"4\":\"生活\",\"5\":"
"\"柔和\"},\"type\":\"enum\"},\"name\":\"工作模式\"},{\"identifier\":"
"\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"关闭\",\"1\":\"开启\"}"
",\"type\":\"bool\"},\"name\":\"夜灯开关\"},{\"identifier\":\"Brightness\","
"\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":"
"\"百分比\",\"max\":\"100\",\"step\":\"1\"},\"type\":\"int\"},\"name\":"
"\"明暗度\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{"
"\"unit\":\"K\",\"min\":\"2000\",\"unitName\":\"开尔文\",\"max\":\"7000\","
"\"step\":\"1\"},\"type\":\"int\"},\"name\":\"冷暖色温\"},{\"identifier\":"
"\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":"
"\"text\"},\"name\":\"PropertyCharacter_Name\"},{\"identifier\":"
"\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\","
"\"step\":\"0.01\"},\"type\":\"double\"},\"name\":\"Propertypoint_Name\"}],"
"\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":"
"\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"属性上报\"},{"
"\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{"
"\"0\":\"恢复正常\"},\"type\":\"enum\"},\"name\":\"故障代码\"}],"
"\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":"
"\"故障上报\",\"type\":\"error\",\"required\":true}]}";
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment