#include "kk_dm_msg.h"
#include "kk_dm_mng.h"
#include "kk_tsl_api.h"

#include "lite-cjson.h"
#include "cJSON.h"
#include "com_api.h"


const char DM_MSG_REQUEST[] DM_READ_ONLY = "{\"msgId\":\"%d\",\"version\":\"%s\",\"params\":%.*s,\"method\":\"%s\"}";
const char DM_MSG_INFO[] DM_READ_ONLY = "{\"msgtype\":\"%d\",\"product_type\":\"%s\",\"device_name\":\"%s\",\"identifier\":\"%s\"}";

void kk_sendData2app(void *info, void *payload){
    cJSON *root=cJSON_CreateObject();
    cJSON_AddStringToObject(root, "info", info);
    cJSON_AddStringToObject(root, "payload", payload);
    void *buf = cJSON_Print(root);
    kk_ipc_send(IPC_MID2APP, buf, strlen(buf) + 1);
    free(buf);
    cJSON_Delete(root);
    
}

const char DM_MSG_THING_SUB_REGISTER_METHOD[] = "thing.sub.register";
const char DM_MSG_THING_SUB_REGISTER_PARAMS[] = "[{\"productKey\":\"%s\",\"deviceName\":\"%s\"}]";

int dm_msg_thing_sub_register(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                              _IN_ char device_name[DEVICE_NAME_MAXLEN],
                              _OU_ dm_msg_request_t *request)
{
    int params_len = 0;
    char *params = NULL;

    if (request == NULL || product_key == NULL || device_name == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        (strlen(request->product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(request->device_name) >= DEVICE_NAME_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    params_len = strlen(DM_MSG_THING_SUB_REGISTER_PARAMS) + strlen(product_key) + strlen(device_name) + 1;
    params = malloc(params_len);
    if (params == NULL) {
        return MEMORY_NOT_ENOUGH;
    }

    memset(params, 0, params_len);
    snprintf(params, params_len, DM_MSG_THING_SUB_REGISTER_PARAMS, product_key, device_name);

    /* Get Params */
    request->params = params;
    request->params_len = strlen(request->params);

    /* Get Method */
    request->method = (char *)DM_MSG_THING_SUB_REGISTER_METHOD;

    return SUCCESS_RETURN;
}

const char DM_MSG_THING_SUB_UNREGISTER_METHOD[] DM_READ_ONLY = "thing.sub.unregister";
const char DM_MSG_THING_SUB_UNREGISTER_PARAMS[] DM_READ_ONLY = "[{\"productKey\":\"%s\",\"deviceName\":\"%s\"}]";
int dm_msg_thing_sub_unregister(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                                  _IN_ char device_name[DEVICE_NAME_MAXLEN],
                                  _OU_ dm_msg_request_t *request)
{
    int params_len = 0;
    char *params = NULL;

    if (request == NULL || product_key == NULL || device_name == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        (strlen(request->product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(request->device_name) >= DEVICE_NAME_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    params_len = strlen(DM_MSG_THING_SUB_UNREGISTER_PARAMS) + strlen(product_key) + strlen(device_name) + 1;
    params = malloc(params_len);
    if (params == NULL) {
    return MEMORY_NOT_ENOUGH;
    }
    memset(params, 0, params_len);
    snprintf(params, params_len, DM_MSG_THING_SUB_UNREGISTER_PARAMS, product_key, device_name);

    /* Get Params */
    request->params = params;
    request->params_len = strlen(request->params);

    /* Get Method */
    request->method = (char *)DM_MSG_THING_SUB_UNREGISTER_METHOD;

    return SUCCESS_RETURN;
}

const char DM_MSG_THING_TOPO_ADD_SIGN_SOURCE[] DM_READ_ONLY = "clientId%sdeviceName%sproductKey%stimestamp%s";
const char DM_MSG_THING_TOPO_ADD_METHOD[] DM_READ_ONLY = "thing.topo.add";
const char DM_MSG_THING_TOPO_ADD_PARAMS[] DM_READ_ONLY =
          "[{\"productKey\":\"%s\",\"deviceName\":\"%s\",\"signmethod\":\"%s\",\"sign\":\"%s\",\"timestamp\":\"%s\",\"clientId\":\"%s\"}]";
int dm_msg_thing_topo_add(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                        _IN_ char device_name[DEVICE_NAME_MAXLEN],
                        _IN_ char device_secret[DEVICE_SECRET_MAXLEN], _OU_ dm_msg_request_t *request)
{
    char *params = NULL;
    int params_len = 0;
    char timestamp[DM_UTILS_UINT64_STRLEN] = {0};
    char client_id[PRODUCT_KEY_MAXLEN + DEVICE_NAME_MAXLEN + 1] = {0};
    char *sign_source = NULL;
    int sign_source_len = 0;
    char *sign_method = DM_MSG_SIGN_METHOD_HMACSHA1;
    char sign[65] = {0};


    if (request == NULL || product_key == NULL ||
        device_name == NULL || device_secret == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        (strlen(device_secret) >= DEVICE_SECRET_MAXLEN) ||
        (strlen(request->product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(request->device_name) >= DEVICE_NAME_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    /* TimeStamp */
    HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%llu", (unsigned long long)HAL_UptimeMs());
    /* dm_log_debug("Time Stamp: %s", timestamp); */

    /* Client ID */
    HAL_Snprintf(client_id, PRODUCT_KEY_MAXLEN + DEVICE_NAME_MAXLEN + 1, "%s.%s", product_key, device_name);

    /* Sign */
    sign_source_len = strlen(DM_MSG_THING_TOPO_ADD_SIGN_SOURCE) + strlen(client_id) +
                    strlen(device_name) + strlen(product_key) + strlen(timestamp) + 1;
    sign_source = malloc(sign_source_len);
    if (sign_source == NULL) {
      return MEMORY_NOT_ENOUGH;
    }
    memset(sign_source, 0, sign_source_len);
    HAL_Snprintf(sign_source, sign_source_len, DM_MSG_THING_TOPO_ADD_SIGN_SOURCE, client_id,
               device_name, product_key, timestamp);

    /* dm_log_debug("Sign Srouce: %s", sign_source); */
#if 0
  if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACMD5) == 0) {
      utils_hmac_md5(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
  } else if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACSHA1) == 0) {
      utils_hmac_sha1(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
  } else if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACSHA256) == 0) {
      utils_hmac_sha256(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
  } else {
      DM_free(sign_source);
      return FAIL_RETURN;
  }
#else
  //utils_hmac_sha1(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
#endif
  free(sign_source);
  /* dm_log_debug("Sign : %s", sign); */

  /* Params */
  request->method = (char *)DM_MSG_THING_TOPO_ADD_METHOD;
  params_len = strlen(DM_MSG_THING_TOPO_ADD_PARAMS) + strlen(product_key) + strlen(device_name) +
               strlen(sign_method) + strlen(sign) + strlen(timestamp) + strlen(client_id) + 1;
  params = malloc(params_len);

  if (params == NULL) {
      return MEMORY_NOT_ENOUGH;
  }
  memset(params, 0, params_len);
  HAL_Snprintf(params, params_len, DM_MSG_THING_TOPO_ADD_PARAMS, product_key, device_name,
               sign_method, sign, timestamp, client_id);

  request->params = params;
  request->params_len = strlen(request->params);

  return SUCCESS_RETURN;
}

const char DM_MSG_THING_TOPO_DELETE_METHOD[] DM_READ_ONLY = "thing.topo.delete";
const char DM_MSG_THING_TOPO_DELETE_PARAMS[] DM_READ_ONLY = "[{\"productKey\":\"%s\",\"deviceName\":\"%s\"}]";
int dm_msg_thing_topo_delete(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                             _IN_ char device_name[DEVICE_NAME_MAXLEN],
                             _OU_ dm_msg_request_t *request)
{
    char *params = NULL;
    int params_len = 0;

    if (request == NULL || product_key == NULL ||
        device_name == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        (strlen(request->product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(request->device_name) >= DEVICE_NAME_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    /* Params */
    request->method = (char *)DM_MSG_THING_TOPO_DELETE_METHOD;
    params_len = strlen(DM_MSG_THING_TOPO_DELETE_PARAMS) + strlen(product_key) + strlen(device_name) + 1;
    params = malloc(params_len);
    if (params == NULL) {
        return MEMORY_NOT_ENOUGH;
    }
    memset(params, 0, params_len);
    HAL_Snprintf(params, params_len, DM_MSG_THING_TOPO_DELETE_PARAMS, product_key, device_name);

    request->params = params;
    request->params_len = strlen(request->params);

    return SUCCESS_RETURN;
}

 const char DM_MSG_THING_TOPO_GET_METHOD[] DM_READ_ONLY = "thing.topo.get";
 const char DM_MSG_THING_TOPO_GET_PARAMS[] DM_READ_ONLY = "{}";
 int dm_msg_thing_topo_get(_OU_ dm_msg_request_t *request)
 {
     char *params = NULL;
     int params_len = 0;
 
     /* Params */
     request->method = (char *)DM_MSG_THING_TOPO_GET_METHOD;
     params_len = strlen(DM_MSG_THING_TOPO_GET_PARAMS) + 1;
     params = malloc(params_len);
     if (params == NULL) {
         return MEMORY_NOT_ENOUGH;
     }
     memset(params, 0, params_len);
     memcpy(params, DM_MSG_THING_TOPO_GET_PARAMS, strlen(DM_MSG_THING_TOPO_GET_PARAMS));
 
     request->params = params;
     request->params_len = strlen(request->params);
 
     return SUCCESS_RETURN;
 }

 const char DM_MSG_THING_LIST_FOUND_METHOD[] DM_READ_ONLY = "thing.list.found";
 const char DM_MSG_THING_LIST_FOUND_PARAMS[] DM_READ_ONLY = "[{\"productKey\":\"%s\",\"deviceName\":\"%s\"}]";
 int dm_msg_thing_list_found(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                             _IN_ char device_name[DEVICE_NAME_MAXLEN],
                             _OU_ dm_msg_request_t *request)
 {
     char *params = NULL;
     int params_len = 0;
 
     if (product_key == NULL || device_name == NULL ||
         (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
         (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
         request == NULL) {
         return INVALID_PARAMETER;
     }
 
     /* Params */
     request->method = (char *)DM_MSG_THING_LIST_FOUND_METHOD;
     params_len = strlen(DM_MSG_THING_LIST_FOUND_PARAMS) + strlen(product_key) + strlen(device_name) + 1;
     params = malloc(params_len);
     if (params == NULL) {
         return MEMORY_NOT_ENOUGH;
     }
     memset(params, 0, params_len);
     HAL_Snprintf(params, params_len, DM_MSG_THING_LIST_FOUND_PARAMS, product_key, device_name);
 
     request->params = params;
     request->params_len = strlen(request->params);
 
     return SUCCESS_RETURN;
 }


const char DM_MSG_COMBINE_LOGIN_SIGN_SOURCE[] DM_READ_ONLY = "clientId%sdeviceName%sproductKey%stimestamp%s";
const char DM_MSG_COMBINE_LOGIN_METHOD[] DM_READ_ONLY = "combine.login";
const char DM_MSG_COMBINE_LOGIN_PARAMS[] DM_READ_ONLY =
            "{\"productKey\":\"%s\",\"deviceName\":\"%s\",\"clientId\":\"%s\",\"timestamp\":\"%s\",\"signMethod\":\"%s\",\"sign\":\"%s\",\"cleanSession\":\"%s\"}";
int dm_msg_combine_login(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                         _IN_ char device_name[DEVICE_NAME_MAXLEN],
                         _IN_ char device_secret[DEVICE_SECRET_MAXLEN], _OU_ dm_msg_request_t *request)
{
    char *params = NULL;
    int params_len = 0;
    char timestamp[DM_UTILS_UINT64_STRLEN] = {0};
    char client_id[PRODUCT_KEY_MAXLEN + DEVICE_NAME_MAXLEN + 20] = {0};
    char *sign_source = NULL;
    int sign_source_len = 0;
    char *sign_method = DM_MSG_SIGN_METHOD_HMACSHA1;
    char sign[64] = {0};


    if (request == NULL || product_key == NULL ||
        device_name == NULL || device_secret == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        (strlen(device_secret) >= DEVICE_SECRET_MAXLEN) ||
        (strlen(request->product_key) >= PRODUCT_KEY_MAXLEN) ||
        (strlen(request->device_name) >= DEVICE_NAME_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    /* TimeStamp */
    HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%llu", (unsigned long long)HAL_UptimeMs());
    /* dm_log_debug("Time Stamp: %s", timestamp); */

    /* Client ID */
    HAL_Snprintf(client_id, PRODUCT_KEY_MAXLEN + DEVICE_NAME_MAXLEN + 20, "%s.%s|_v=sdk-c-3.0.1|", product_key, device_name);

    /* Sign */
    sign_source_len = strlen(DM_MSG_COMBINE_LOGIN_SIGN_SOURCE) + strlen(client_id) +
                      strlen(device_name) + strlen(product_key) + strlen(timestamp) + 1;
    sign_source = malloc(sign_source_len);
    if (sign_source == NULL) {
        return DM_MEMORY_NOT_ENOUGH;
    }
    memset(sign_source, 0, sign_source_len);
    HAL_Snprintf(sign_source, sign_source_len, DM_MSG_COMBINE_LOGIN_SIGN_SOURCE, client_id,
                 device_name, product_key, timestamp);

    /* dm_log_debug("Sign Srouce: %s", sign_source); */
#if 0
    if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACMD5) == 0) {
        utils_hmac_md5(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
    } else if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACSHA1) == 0) {
        utils_hmac_sha1(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
    } else if (strcmp(sign_method, DM_MSG_SIGN_METHOD_HMACSHA256) == 0) {
        utils_hmac_sha256(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
    } else {
        DM_free(sign_source);
        return FAIL_RETURN;
    }
#else
    //utils_hmac_sha1(sign_source, strlen(sign_source), sign, device_secret, strlen(device_secret));
#endif
    free(sign_source);
    /* dm_log_debug("Sign : %s", sign); */

    /* Params */
    request->method = (char *)DM_MSG_COMBINE_LOGIN_METHOD;
    params_len = strlen(DM_MSG_COMBINE_LOGIN_PARAMS) + strlen(product_key) + strlen(device_name) +
                 strlen(sign_method) + strlen(sign) + strlen(timestamp) + strlen(client_id) + 1;
    params = malloc(params_len);

    if (params == NULL) {
        return DM_MEMORY_NOT_ENOUGH;
    }
    memset(params, 0, params_len);
    HAL_Snprintf(params, params_len, DM_MSG_COMBINE_LOGIN_PARAMS, product_key, device_name,
                 client_id, timestamp, sign_method, sign, "true");

    request->params = params;
    request->params_len = strlen(request->params);

    return SUCCESS_RETURN;
}


const char DM_MSG_COMBINE_LOGOUT_METHOD[] DM_READ_ONLY = "combine.logout";
const char DM_MSG_COMBINE_LOGOUT_PARAMS[] DM_READ_ONLY = "{\"productKey\":\"%s\",\"deviceName\":\"%s\"}";
int dm_msg_combine_logout(_IN_ char product_key[PRODUCT_KEY_MAXLEN],
                                    _IN_ char device_name[DEVICE_NAME_MAXLEN],
                                     _OU_ dm_msg_request_t *request)
{

    char *params = NULL;
    int params_len = 0;

    if (product_key == NULL || device_name == NULL ||
        (strlen(product_key) >= PRODUCT_KEY_MAXLEN ||
        (strlen(device_name) >= DEVICE_NAME_MAXLEN) ||
        request == NULL) ){
        return INVALID_PARAMETER;
    }

    /* Params */
    request->method = (char *)DM_MSG_COMBINE_LOGOUT_METHOD;
    params_len = strlen(DM_MSG_COMBINE_LOGOUT_PARAMS) + strlen(product_key) + strlen(device_name) + 1;
    params = malloc(params_len);

    if (params == NULL) {
        return MEMORY_NOT_ENOUGH;
    }
    memset(params, 0, params_len);
    HAL_Snprintf(params, params_len, DM_MSG_COMBINE_LOGOUT_PARAMS, product_key, device_name);

    request->params = params;
    request->params_len = strlen(request->params);

    return SUCCESS_RETURN;
 
}

 
int dm_msg_request (_IN_ dm_msg_request_t *request)
{
    int res = 0, payload_len = 0,req_info_len = 0;
    char *payload = NULL;
    lite_cjson_t lite;
	char *req_info = NULL;
    if (request == NULL || request->params == NULL || request->method == NULL) {
        return INVALID_PARAMETER;
    }

    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) {
        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);

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(request->product_key)+strlen(request->device_name)+strlen(request->identity)+1;
    req_info = malloc(req_info_len);
    if (req_info == NULL) {
		free(payload);
        return MEMORY_NOT_ENOUGH;
    }
    memset(req_info, 0, req_info_len);
    snprintf(req_info, req_info_len, DM_MSG_INFO, request->msgtype,
            		 			 request->product_key, request->device_name,request->identity);

    memset(&lite, 0, sizeof(lite_cjson_t));
    res = lite_cjson_parse(payload, payload_len, &lite);
    if (res < SUCCESS_RETURN) {
        printf("Wrong JSON Format, Payload: %s", payload);
        free(req_info);
        free(payload);
        return FAIL_RETURN;
    }
    memset(&lite, 0, sizeof(lite_cjson_t));
    res = lite_cjson_parse(req_info, req_info_len, &lite);
    if (res < SUCCESS_RETURN) {
        printf("Wrong JSON Format, Payload: %s", req_info_len);
        free(req_info);
        free(payload);
        return FAIL_RETURN;
    }

    //if (type & DM_MSG_DEST_CLOUD) {
    // dm_client_publish(uri, (unsigned char *)payload, strlen(payload), request->callback);
     kk_sendData2app(req_info, payload);
    //}
    free(req_info);
    free(payload);
    return SUCCESS_RETURN;
}


const char DM_MSG_RESPONSE_WITH_DATA[] DM_READ_ONLY = "{\"msgId\":\"%.*s\",\"code\":%d,\"data\":%.*s}";
int dm_msg_response(_IN_ kk_msg_request_payload_t *request, _IN_ kk_msg_response_t *response,
                    _IN_ char *data, _IN_ int data_len, _IN_ void *user_data)
{
    int res = 0, payload_len = 0,res_info_len = 0;
    char *uri = NULL, *payload = NULL;
    lite_cjson_t lite;
	char *res_info = NULL;
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
    if (request == NULL || response == NULL || data == NULL || data_len <= 0) {
        return INVALID_PARAMETER;
    }
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);

    /* Response Payload */
    payload_len = strlen(DM_MSG_RESPONSE_WITH_DATA) + request->id.value_length + DM_UTILS_UINT32_STRLEN + data_len + 1;
    payload = malloc(payload_len);
    if (payload == NULL) {
        free(uri);
        return MEMORY_NOT_ENOUGH;
    }
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
    memset(payload, 0, payload_len);
    snprintf(payload, payload_len, DM_MSG_RESPONSE_WITH_DATA,
                 request->id.value_length, request->id.value, response->code, data_len, data);

	 res_info_len = strlen(DM_MSG_INFO)+10+strlen(response->product_key)+strlen(response->device_name)+strlen(response->identity)+1;
	 res_info = malloc(res_info_len);
	 if (res_info == NULL) {
		 free(payload);
		 return MEMORY_NOT_ENOUGH;
	 }
	 	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	 memset(res_info, 0, res_info_len);
	 snprintf(res_info, res_info_len, DM_MSG_INFO, response->msgtype,
								  response->product_key, response->device_name,response->identity);


    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("[%s][%d]\n",__FUNCTION__,__LINE__);

    memset(&lite, 0, sizeof(lite_cjson_t));
    res = lite_cjson_parse(res_info, res_info_len, &lite);
    if (res < SUCCESS_RETURN) {
        printf("Wrong JSON Format, Payload: %s", res_info_len);
        free(res_info);
        free(payload);
        return FAIL_RETURN;
    }
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);

    //dm_client_publish(uri, (unsigned char *)payload, strlen(payload), NULL);
    kk_sendData2app(res_info, payload);

    free(res_info);
    free(payload);

    return SUCCESS_RETURN;
}

int dm_msg_response_parse(_IN_ char *payload, _IN_ int payload_len, _OU_ dm_msg_response_payload_t *response)
{
    lite_cjson_t lite, lite_message;

    if (payload == NULL || payload_len <= 0 || response == NULL) {
        return INVALID_PARAMETER;
    }

    if (kk_utils_json_parse(payload, payload_len, cJSON_Invalid, &lite) != SUCCESS_RETURN ||
        kk_utils_json_object_item(&lite, DM_MSG_KEY_ID, strlen(DM_MSG_KEY_ID), cJSON_Invalid, &response->id) != SUCCESS_RETURN ||
        kk_utils_json_object_item(&lite, DM_MSG_KEY_CODE, strlen(DM_MSG_KEY_CODE), cJSON_Invalid,
                                  &response->code) != SUCCESS_RETURN ||
        kk_utils_json_object_item(&lite, DM_MSG_KEY_DATA, strlen(DM_MSG_KEY_DATA), cJSON_Invalid,
                                  &response->data) != SUCCESS_RETURN) {
         printf("Current Request parse faild \n");                          
        return FAIL_RETURN;
    }

    printf("Current Request Message ID: %.*s", response->id.value_length, response->id.value);
    printf("Current Request Message Code: %d", response->code.value_int);
    printf("Current Request Message Data: %.*s", response->data.value_length, response->data.value);

    memset(&lite_message, 0, sizeof(lite_cjson_t));
    if (kk_utils_json_object_item(&lite, DM_MSG_KEY_MESSAGE, strlen(DM_MSG_KEY_MESSAGE), cJSON_Invalid,
                                  &response->message) == SUCCESS_RETURN) {
        printf("Current Request Message Desc: %.*s", response->message.value_length, response->message.value);
    }

    return SUCCESS_RETURN;
}

static int dm_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 dm_msg_thing_property_set_reply(char product_type[PRODUCT_KEY_MAXLEN], char device_name[DEVICE_NAME_MAXLEN],char *payload, unsigned int payload_len,
        void *context){
        
    kk_msg_request_payload_t request;
    kk_msg_response_t response;

    int res = 0, devid = 0;

    memset(&request, 0, sizeof(kk_msg_request_payload_t));
    memset(&response, 0, sizeof(kk_msg_response_t));

	printf("[%s][%d]\n",__FUNCTION__,__LINE__);

    res = dm_mgr_search_device_by_pkdn(product_type, device_name, &devid);
    if (res < SUCCESS_RETURN) {
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
        return res;
    }
    res = dm_msg_request_parse((char *)payload, payload_len, &request);
    if (res < SUCCESS_RETURN) {
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
        return res ;
    }
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);

    /* Response */
    response.msgtype = MSG_SETREPLY;
	memset(response.identity,"",strlen(""));
    memcpy(response.product_key, product_type, strlen(product_type));
    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);
}


