#include "kk_dm_msg.h"

#include "kk_dm_queue.h"
#include "lite-cjson.h"
#include "kk_hal.h"
#include "com_api.h"
#include "kk_log.h"
#include "kk_utils.h"
#include "kk_sync_data.h"

const char DM_MSG_REQUEST[] DM_READ_ONLY = "{\"msgId\":\"%s\",\"version\":\"%s\",\"params\":%s,\"time\":\"%lu\",\"method\":\"%s\"}";
const char DM_MSG_INFO[] DM_READ_ONLY = "{\"msgtype\":\"%s\",\"productCode\":\"%s\",\"deviceCode\":\"%s\"}";

void kk_sendData2app(void *info, void *payload,int isAsync){
	void *buf = NULL;
	cJSON *root=cJSON_CreateObject();
	cJSON* infoObj = cJSON_Parse(info);
	cJSON* payloadObj = cJSON_Parse(payload);
	cJSON_AddItemToObject(root, "info", infoObj);
	cJSON_AddItemToObject(root, "payload",payloadObj);	
	buf = cJSON_Print(root);
	if(isAsync){
		dm_queue_msg_insert4(buf);
		
	}else{
		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[] = "[{\"productCode\":\"%s\",\"deviceCode\":\"%s\"}]";

int dm_msg_thing_sub_register(_IN_ char productCode[DEVICE_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN],
		_OU_ dm_msg_request_t *request)
{
	int params_len = 0;
	char *params = NULL;

	if (request == NULL || deviceCode == NULL ||
		(strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
		(strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
		return INVALID_PARAMETER;
	}

	params_len = strlen(DM_MSG_THING_SUB_REGISTER_PARAMS) +strlen(productCode) + strlen(deviceCode) + 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,productCode, deviceCode);

	/* 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 = "[{\"deviceCode\":\"%s\"}]";
int dm_msg_thing_sub_unregister(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ dm_msg_request_t *request)
{
	int params_len = 0;
	char *params = NULL;

	if (request == NULL || deviceCode == NULL ||
		(strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
		(strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
		return INVALID_PARAMETER;
	}

	params_len = strlen(DM_MSG_THING_SUB_UNREGISTER_PARAMS) + strlen(deviceCode) + 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, deviceCode);

	/* 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%sdeviceCode%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\"}]";
          "{\"productCode\":\"%s\",\"deviceCode\":\"%s\",\"mac\":\"%s\"}";
          
int dm_msg_thing_topo_add(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
                        _IN_ char deviceCode[DEVICE_CODE_MAXLEN], _IN_ char mac[DEVICE_MAC_MAXLEN],
                        _OU_ dm_msg_request_t *request)
{
    char *params = NULL;
    int params_len = 0;
    char client_id[PRODUCT_TYPE_MAXLEN + DEVICE_CODE_MAXLEN + 1] = {0};

    if (request == NULL ||
         deviceCode == NULL ||
        (strlen(productCode) >= PRODUCT_CODE_MAXLEN) ||
        (strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
        (strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
        return INVALID_PARAMETER;
    }

#if 0
    /* 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, DEVICE_CODE_MAXLEN + 1, "%s", deviceCode);

    /* Sign */
    sign_source_len = strlen(DM_MSG_THING_TOPO_ADD_SIGN_SOURCE) + strlen(client_id) +
                    strlen(deviceCode) + 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,
               deviceCode, 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); */
#endif

  /* Params */
  request->method = (char *)DM_MSG_THING_TOPO_ADD_METHOD;
  //params_len = strlen(DM_MSG_THING_TOPO_ADD_PARAMS) + strlen(deviceCode) +
  //             strlen(sign_method) + strlen(sign) + strlen(timestamp) + strlen(client_id) + 1;
  params_len = strlen(DM_MSG_THING_TOPO_ADD_PARAMS) + strlen(deviceCode) +
               strlen(productCode) + strlen(mac) + 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, productType, deviceCode,
  //             sign_method, sign, timestamp, client_id);
  HAL_Snprintf(params, params_len, DM_MSG_THING_TOPO_ADD_PARAMS, productCode, deviceCode,mac);

  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 = "[{\"deviceCode\":\"%s\"}]";
int dm_msg_thing_topo_delete(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ dm_msg_request_t *request)
{
    char *params = NULL;
    int params_len = 0;

    if (request == NULL ||
        deviceCode == NULL ||
        (strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
        (strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    /* Params */
    request->method = (char *)DM_MSG_THING_TOPO_DELETE_METHOD;
    params_len = strlen(DM_MSG_THING_TOPO_DELETE_PARAMS) + strlen(deviceCode) + 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, deviceCode);

    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 = "[{\"deviceCode\":\"%s\"}]";
 int dm_msg_thing_list_found(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],
                             _OU_ dm_msg_request_t *request)
 {
     char *params = NULL;
     int params_len = 0;
 
     if ( deviceCode == NULL ||
         (strlen(deviceCode) >= DEVICE_CODE_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(deviceCode) + 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, deviceCode);
 
     request->params = params;
     request->params_len = strlen(request->params);
 
     return SUCCESS_RETURN;
 }

const char DM_MSG_STATUS_CLOUD_METHOD[] DM_READ_ONLY = "thing.ccu.cloudstate";							 
const char DM_MSG_STATUS_CLOUD[] DM_READ_ONLY =
            "{\"deviceCode\":\"%s\"}";							 
int dm_msg_status_cloud(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
						  _IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_msg_request_t *request)
{
	char *params = NULL;
	int params_len = 0;

	if (request == NULL || 
		deviceCode == NULL || productCode == NULL ||
		(strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
		(strlen(productCode) >= PRODUCT_CODE_MAXLEN) ||
		(strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
		return INVALID_PARAMETER;
	}

	/* Params */
	request->method = (char *)DM_MSG_STATUS_CLOUD_METHOD;
	params_len = strlen(DM_MSG_STATUS_CLOUD) + strlen(deviceCode)  + 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_STATUS_CLOUD,deviceCode);

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

	return SUCCESS_RETURN;
}
const char DM_MSG_COMBINE_STATUS_ONLINE_METHOD[] DM_READ_ONLY = "thing.status.online";							 
const char DM_MSG_COMBINE_STATUS_ONLINE[] DM_READ_ONLY =
            "{\"deviceCode\":\"%s\",\"ccuCode\":\"%s\"}";							 
int dm_msg_status_online(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
						  _IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_msg_request_t *request)
{
	char *params = NULL;
	int params_len = 0;
	char timestamp[DM_UTILS_UINT64_STRLEN] = {0};
	char ccuid[32] = {0};

	if (request == NULL || 
		deviceCode == NULL || productCode == NULL ||
		(strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
		(strlen(productCode) >= PRODUCT_CODE_MAXLEN) ||
		(strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
		return INVALID_PARAMETER;
	}

	/* TimeStamp */
	HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
	/* dm_log_debug("Time Stamp: %s", timestamp); */

	HAL_Get_ccuid(ccuid);
	/* Params */
	request->method = (char *)DM_MSG_COMBINE_STATUS_ONLINE_METHOD;
	params_len = strlen(DM_MSG_COMBINE_STATUS_ONLINE) + strlen(deviceCode)+strlen(ccuid)  + 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_STATUS_ONLINE,deviceCode,ccuid);

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

	return SUCCESS_RETURN;
}

const char DM_MSG_COMBINE_STATUS_OFFLINE_METHOD[] DM_READ_ONLY = "thing.status.offline";						   
const char DM_MSG_COMBINE_STATUS_OFFLINE[] DM_READ_ONLY =
		  "{\"deviceCode\":\"%s\",\"ccuCode\":\"%s\"}";						   
int dm_msg_status_offline(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
						_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_msg_request_t *request)
{
	char *params = NULL;
	int params_len = 0;
	char timestamp[DM_UTILS_UINT64_STRLEN] = {0};
	char ccuid[32] = {0};

	if (request == NULL || 
		deviceCode == NULL || productCode == NULL ||
		(strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
		(strlen(productCode) >= PRODUCT_CODE_MAXLEN) ||
		(strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
		return INVALID_PARAMETER;
	}

	/* TimeStamp */
	HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
	/* dm_log_debug("Time Stamp: %s", timestamp); */

	HAL_Get_ccuid(ccuid);
	/* Params */
	request->method = (char *)DM_MSG_COMBINE_STATUS_OFFLINE_METHOD;
	params_len = strlen(DM_MSG_COMBINE_STATUS_OFFLINE) + strlen(deviceCode)+ strlen(ccuid)  + 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_STATUS_OFFLINE,deviceCode,ccuid);

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

	return SUCCESS_RETURN;
}

const char DM_MSG_COMBINE_LOGIN_SIGN_SOURCE[] DM_READ_ONLY = "clientId%sdeviceCode%stimestamp%s";
const char DM_MSG_COMBINE_LOGIN_METHOD[] DM_READ_ONLY = "combine.login";
const char DM_MSG_COMBINE_LOGIN_PARAMS[] DM_READ_ONLY =
            "{\"deviceCode\":\"%s\",\"clientId\":\"%s\",\"timestamp\":\"%s\",\"signMethod\":\"%s\",\"sign\":\"%s\",\"cleanSession\":\"%s\"}";
int dm_msg_combine_login(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
                         _IN_ char deviceCode[DEVICE_CODE_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_TYPE_MAXLEN + DEVICE_CODE_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 ||
        deviceCode == NULL || productCode == NULL ||
        (strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
        (strlen(productCode) >= PRODUCT_CODE_MAXLEN) ||
        (strlen(request->deviceCode) >= DEVICE_CODE_MAXLEN)) {
        return INVALID_PARAMETER;
    }

    /* TimeStamp */
    HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
    /* dm_log_debug("Time Stamp: %s", timestamp); */

    /* Client ID */
    HAL_Snprintf(client_id, PRODUCT_TYPE_MAXLEN + DEVICE_CODE_MAXLEN + 20, "%s|_v=sdk-c-3.0.1|", deviceCode);

    /* Sign */
    sign_source_len = strlen(DM_MSG_COMBINE_LOGIN_SIGN_SOURCE) + strlen(client_id) +
                      strlen(deviceCode) + 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,
                 deviceCode, 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(deviceCode) +
                 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, deviceCode,
                 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 = "{\"deviceCode\":\"%s\"}";
int dm_msg_combine_logout(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ dm_msg_request_t *request)
{

    char *params = NULL;
    int params_len = 0;

    if ( deviceCode == NULL ||
        (strlen(deviceCode) >= DEVICE_CODE_MAXLEN) ||
        request == NULL){
        return INVALID_PARAMETER;
    }

    /* Params */
    request->method = (char *)DM_MSG_COMBINE_LOGOUT_METHOD;
    params_len = strlen(DM_MSG_COMBINE_LOGOUT_PARAMS) + strlen(deviceCode) + 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, deviceCode);

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

    return SUCCESS_RETURN;
 
}


 const char DM_MSG_OTA_VERSION_PARAMS[] DM_READ_ONLY = "{\"version\":\"%s\"}";
 int dm_msg_ota_report_version(_IN_ char *version,
                                      _OU_ dm_msg_request_t *request)
 {
 
     char *params = NULL;
     int params_len = 0;
 
     if (NULL == version ){
         return INVALID_PARAMETER;
     }
 
     /* Params */
     request->method = (char *)"";
     params_len = strlen(DM_MSG_OTA_VERSION_PARAMS) + strlen(version) + 1;
     params = malloc(params_len);
 
     if (params == NULL) {
         return MEMORY_NOT_ENOUGH;
     }
     memset(params, 0, params_len);
     HAL_Snprintf(params, params_len, DM_MSG_OTA_VERSION_PARAMS, version);
 
     request->params = params;
     request->params_len = strlen(request->params);
 
     return SUCCESS_RETURN;
  
 }

 
int dm_msg_request (_IN_ dm_msg_request_t *request,_IN_ int isAsync)
{
	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 + 20 + strlen(request->msgid);
	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,HAL_GetTime(), request->method);

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(request->productCode)+strlen(request->deviceCode)+strlen(request->msgTypeStr)+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->msgTypeStr, request->productCode, request->deviceCode);

	memset(&lite, 0, sizeof(lite_cjson_t));
	res = lite_cjson_parse(payload, payload_len, &lite);
	if (res < SUCCESS_RETURN) {
		ERROR_PRINT("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) {
		ERROR_PRINT("Wrong JSON Format, Payload: %d", 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,isAsync);

	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;

	if (request == NULL || response == NULL || data == NULL || data_len <= 0) {
		return INVALID_PARAMETER;
	}

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

	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->productCode)+strlen(response->deviceCode)+strlen(response->msgTypeStr)+1;
	res_info = malloc(res_info_len);
	if (res_info == NULL) {
		free(payload);
		return MEMORY_NOT_ENOUGH;
	}

	memset(res_info, 0, res_info_len);
	snprintf(res_info, res_info_len, DM_MSG_INFO, response->msgTypeStr,response->productCode, response->deviceCode);


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

	memset(&lite, 0, sizeof(lite_cjson_t));
	res = lite_cjson_parse(res_info, res_info_len, &lite);
	if (res < SUCCESS_RETURN) {
		ERROR_PRINT("Wrong JSON Format, Payload: %d", res_info_len);
		free(res_info);
		free(payload);
		return FAIL_RETURN;
	}

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

	free(res_info);
	free(payload);

	return SUCCESS_RETURN;
}

const char DM_MSG_SYNC_RESPONSE_WITH_DATA[]= "{\"msgId\":\"%.*s\",\"code\":%d,\"params\":%.*s}";
int dm_msg_sync_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;

	if (request == NULL || response == NULL || data == NULL || data_len <= 0) {
		return INVALID_PARAMETER;
	}

	/* Response Payload */
	payload_len = strlen(DM_MSG_SYNC_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;
	}

	memset(payload, 0, payload_len);
	snprintf(payload, payload_len, DM_MSG_SYNC_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->productCode)+strlen(response->deviceCode)+strlen(response->msgTypeStr)+1;
	res_info = malloc(res_info_len);
	if (res_info == NULL) {
		free(payload);
		return MEMORY_NOT_ENOUGH;
	}

	memset(res_info, 0, res_info_len);
	snprintf(res_info, res_info_len, DM_MSG_INFO, response->msgTypeStr,response->productCode, response->deviceCode);


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

	memset(&lite, 0, sizeof(lite_cjson_t));
	res = lite_cjson_parse(res_info, res_info_len, &lite);
	if (res < SUCCESS_RETURN) {
		ERROR_PRINT("Wrong JSON Format, Payload: %d", res_info_len);
		free(res_info);
		free(payload);
		return FAIL_RETURN;
	}

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

	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) {
		ERROR_PRINT("Current Request parse faild \n");                          
		return FAIL_RETURN;
	}

	INFO_PRINT("Current Request Message ID: %.*s", response->id.value_length, response->id.value);
	INFO_PRINT("Current Request Message Code: %d", response->code.value_int);
	INFO_PRINT("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) {
		INFO_PRINT("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;
	}

	INFO_PRINT("Current Request Message ID: %.*s", request->id.value_length, request->id.value);
	INFO_PRINT("Current Request Message Version: %.*s", request->version.value_length, request->version.value);
	INFO_PRINT("Current Request Message Method: %.*s", request->method.value_length, request->method.value);
	INFO_PRINT("Current Request Message Params: %.*s", request->params.value_length, request->params.value);

	return SUCCESS_RETURN;
}

int dm_msg_thing_syncinfo_reply(void){

	kk_msg_request_payload_t request;
	kk_msg_response_t response;
	dm_mgr_dev_node_t *node = NULL;
	char *info = NULL;
	int res = 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_dev_by_devid(KK_DM_DEVICE_CCU_DEVICEID, &node);
	if (res != SUCCESS_RETURN) {
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return FAIL_RETURN;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	//res = dm_msg_request_parse((char *)payload, payload_len, &request);
	//if (res < SUCCESS_RETURN) {
		//ERROR_PRINT("dm_msg_request_parse failed");
		//return res ;
	//}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	response.msgTypeStr = KK_THING_SERVICE_SYNCINFO_REPLY;
	memcpy(response.productCode, node->productCode, strlen( node->productCode));
	memcpy(response.deviceCode, node->deviceCode, strlen(node->deviceCode));
	response.code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	info = kk_sync_get_info();
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	dm_msg_response(&request, &response, info, strlen(info), NULL);
	free(info);
	return SUCCESS_RETURN;
}

int dm_msg_thing_syncdeviceinfo_reply(cJSON *msgId){

	kk_msg_request_payload_t request;
	kk_msg_response_t response;
	dm_mgr_dev_node_t *node = NULL;
	char *info = NULL;
	int res = 0;

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

	if(msgId!=NULL && msgId->type==cJSON_String){
		request.id.value_length = strlen(msgId->valuestring);
		request.id.value = msgId->valuestring;
	}
	
	
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	res = dm_mgr_search_dev_by_devid(KK_DM_DEVICE_CCU_DEVICEID, &node);
	if (res != SUCCESS_RETURN) {
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return FAIL_RETURN;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	//res = dm_msg_request_parse((char *)payload, payload_len, &request);
	//if (res < SUCCESS_RETURN) {
		//ERROR_PRINT("dm_msg_request_parse failed");
		//return res ;
	//}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	response.msgTypeStr = KK_THING_SERVICE_SYNCDEVICEINFO_REPLY;
	memcpy(response.productCode, node->productCode, strlen( node->productCode));
	memcpy(response.deviceCode, node->deviceCode, strlen(node->deviceCode));
	response.code = (res == SUCCESS_RETURN) ? (IOTX_DM_ERR_CODE_SUCCESS) : (IOTX_DM_ERR_CODE_REQUEST_ERROR);
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	info = kk_sync_get_info();
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	dm_msg_sync_response(&request, &response, info, strlen(info), NULL);
	free(info);
	return SUCCESS_RETURN;
}


const char DM_URI_THING_SERVICE_PROPERTY_SET_REPLY[] = "/thing/service/property/set_reply";

int dm_msg_thing_property_set_reply(char deviceCode[DEVICE_CODE_MAXLEN],char *payload, unsigned int payload_len,
	void *context){

	kk_msg_request_payload_t request;
	kk_msg_response_t response;
	dm_mgr_dev_node_t *node = NULL;

	int res = 0;

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

	res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
	if (res < SUCCESS_RETURN) {
		ERROR_PRINT("dm_mgr_search_device_by_pkdn failed");
		return res;
	}
	res = dm_msg_request_parse((char *)payload, payload_len, &request);
	if (res < SUCCESS_RETURN) {
		ERROR_PRINT("dm_msg_request_parse failed");
		return res ;
	}

	response.msgTypeStr = (char*)DM_URI_THING_SERVICE_PROPERTY_SET_REPLY;
	memcpy(response.productCode, node->productCode, strlen( node->productCode));	
	memcpy(response.deviceCode, node->deviceCode, strlen(node->deviceCode));
	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;
}
int dm_msg_thing_event_post(const char *deviceCode, const char *identifier,const char *msgId)
{
	int res = 0;
	char *payload = NULL;
	dm_mgr_dev_node_t *node = NULL; 
	void *event = NULL;
	char *method = NULL;
	INFO_PRINT("dm_msg_thing_event_post enter\n");

	if(deviceCode == NULL){
		ERROR_PRINT("dm_msg_thing_event_post failed\n");
		return FAIL_RETURN;
	}
	
	res = dm_mgr_get_device_by_devicecode((char*)deviceCode, &node);
	if (res != SUCCESS_RETURN) {
		ERROR_PRINT("dm_msg_thing_event_post failed\n");
		return FAIL_RETURN;
	}
	payload = kk_tsl_get_post_event_str(node->dev_shadow,(char*)identifier,strlen(identifier));
	if(payload != NULL){
	    res = kk_tsl_get_event_by_identifier(node->dev_shadow, identifier, &event);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			ERROR_PRINT("dm_msg_thing_event_post failed\n");
			return FAIL_RETURN;

	    }	
	    res = kk_tsl_get_event_method(event, &method);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			ERROR_PRINT("dm_msg_thing_event_post failed\n");
			return FAIL_RETURN;
	    }		
		if(msgId != NULL){
	    	dm_mgr_upstream_thing_event_post_ex(node->devid, (char*)identifier, strlen(identifier), method, payload, strlen(payload),msgId);	
		}else
		{
	    	dm_mgr_upstream_thing_event_post(node->devid, identifier, strlen(identifier), method, payload, strlen(payload));	
		}
		free(method);
		method = NULL;
		free(payload);
		payload = NULL;
	}
	return SUCCESS_RETURN;
}
int dm_msg_scene_event_post(const char *identifier,kk_tsl_t *dev_shadow,const char *msgId)
{
	int res = 0; 
	char *payload = NULL;
	void *event = NULL;
	char *method = NULL;
	
	payload = kk_tsl_get_post_event_str(dev_shadow,identifier,strlen(identifier));
	if(payload != NULL){
	    res = kk_tsl_get_event_by_identifier(dev_shadow, identifier, &event);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			return FAIL_RETURN;

	    }	
	    res = kk_tsl_get_event_method(event, &method);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			return FAIL_RETURN;
	    }		
	    dm_mgr_upstream_thing_event_post_ex(KK_DM_DEVICE_CCU_DEVICEID, identifier, strlen(identifier), method, payload, strlen(payload),msgId);		
		free(method);
		method = NULL;
		free(payload);
		payload = NULL;
	}
	return SUCCESS_RETURN;
}

int dm_msg_thing_service_post(const char *deviceCode, const char *identifier)
{
	int res = 0;
	char *payload = NULL;
	dm_mgr_dev_node_t *node = NULL; 
	char *method = NULL;
    void *service = NULL;

	if(deviceCode == NULL){
		return FAIL_RETURN;
	}
	
	res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
	if (res != SUCCESS_RETURN) {
		return FAIL_RETURN;
	}
	payload = kk_tsl_get_post_service_str(node->dev_shadow,identifier);
	if(payload != NULL){	
	    res = kk_tsl_get_service_by_identifier(node->dev_shadow, identifier, &service);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			return FAIL_RETURN;

	    }			
		res = kk_tsl_get_service_method(service,&method);
	    if (res != SUCCESS_RETURN) {
	        free(payload);
			return FAIL_RETURN;
	    }		
	    dm_mgr_upstream_thing_service_post(node->devid, identifier, strlen(identifier),method, payload, strlen(payload));
		free(method);
		method = NULL;
		free(payload);
		payload = NULL;

	}
	return SUCCESS_RETURN;
}


int dm_msg_thing_property_post_all(char *deviceCode)
{
	int res = 0;
	char *payload = NULL;
	dm_mgr_dev_node_t *node = NULL; 

	if(deviceCode == NULL){
		return FAIL_RETURN;
	}
	
	res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
	if (res != SUCCESS_RETURN) {
		return FAIL_RETURN;
	}
	payload = kk_tsl_get_post_property_str(node->dev_shadow,NULL);//here need async post
	if(payload != NULL){
		dm_mgr_upstream_thing_property_post(node->devid, payload, strlen(payload),1);
		free(payload);
		payload = NULL;
	}
	return SUCCESS_RETURN;
}
int dm_msg_ccu_property_post(dm_mgr_dev_node_t *node)
{
	if(node == NULL){
		return INVALID_PARAMETER;
	}
	char *payload_property = kk_tsl_get_post_property_str(node->dev_shadow,NULL);
	if(payload_property != NULL){
		dm_mgr_upstream_thing_property_post(node->devid, payload_property, strlen(payload_property),0);
		free(payload_property);
		payload_property = NULL;
	}
	return SUCCESS_RETURN;
}
static void kk_split(char *src,const char *separator,char **dest,int *num) {
    char *pNext;
    int count = 0;
    if (src == NULL || strlen(src) == 0)
        return;
    if (separator == NULL || strlen(separator) == 0)
         return;    
    pNext = strtok(src,separator);
    while(pNext != NULL) {
        *dest++ = pNext;
        ++count;
        pNext = strtok(NULL,separator);  
    }  
    *num = count;
 } 


int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params)
{
	int res = 0;
	int nums = 0;
	int idx = 0; 
	int i = 0;
	dm_mgr_dev_node_t *node = NULL; 
	kk_tsl_data_t *property = NULL;
	cJSON *propertyItem = NULL;
	char tmpValue[20] = {0};	
	kk_dm_property_e_t propertyInfoBuf[DEVICE_PROPERTY_NUM_MAX];
	char propertiesTmp[DEVICE_PROPERTY_NAME_MAX] = {0};
	char pFinal[DEVICE_PROPERTY_NAME_MAX] = {0};
	int num = 0;
	int countPro = 0;	
	int epNumInt = 1;
	int maxEpNum = 1;
	if(params == NULL || deviceCode == NULL){
		return INVALID_PARAMETER;
	}
	
	res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
	if (res != SUCCESS_RETURN) {
		return FAIL_RETURN;
	}
	//printf("dm_msg_thing_property_post_by_identify:%s\n",params->valuestring);
	memset(propertyInfoBuf,0x0,sizeof(kk_dm_property_e_t)*16);
	nums = node->dev_shadow->property_number;
	for(idx = 0; idx < nums; idx++){
		property = (kk_tsl_data_t *)(node->dev_shadow->properties + idx);
		if(property == NULL){
			continue;
		}
		memset(propertiesTmp,0x0,sizeof(propertiesTmp));
		memset(pFinal,0x0,sizeof(pFinal));
		memcpy(propertiesTmp,property->identifier,strlen(property->identifier));
		//printf("---------------------------------->propertiesTmp:%s\n",propertiesTmp);
		if(strstr(propertiesTmp,"_") != NULL){
			char *propertiesbuf[DEVICE_PROPERTY_NAME_MAX] = {0};
			kk_split(propertiesTmp,"_",propertiesbuf,&num);
			
			if(num == 2){
				epNumInt = atoi(propertiesbuf[1]);
			}	
			if(epNumInt < 1 || epNumInt >= 16){
				epNumInt = 1;
			}
			memcpy(pFinal,propertiesbuf[0],strlen(propertiesbuf[0]));
			//printf("---------------------------------------->pFinal:%s,num:%d\n",pFinal,epNumInt);
		}else{
			//printf("---------------------------------->property->identifier:%s\n",property->identifier);
			memcpy(pFinal,property->identifier,strlen(property->identifier));
			//memset(propertiesbuf[0],0x0,sizeof(propertiesbuf[0]));
			//memcpy(propertiesbuf[0],property->identifier,strlen(property->identifier));
			//printf("propertiesbuf[0]:%s,num:%d\n",propertiesbuf[0],num);
			//epNumInt = 1;
		}
		propertyItem = cJSON_GetObjectItem(params, property->identifier);
		if(propertyItem != NULL){
			
			/*update the db data */
			if(property->data_value.type == KK_TSL_DATA_TYPE_INT ||
				property->data_value.type == KK_TSL_DATA_TYPE_ENUM||
				property->data_value.type == KK_TSL_DATA_TYPE_BOOL){
				sprintf(tmpValue,"%d",property->data_value.value_int);
				kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
				propertyInfoBuf[epNumInt-1].num++;
				countPro = propertyInfoBuf[epNumInt-1].num;
				propertyInfoBuf[epNumInt-1].info[countPro-1].type = property->data_value.type;
				memset(propertyInfoBuf[epNumInt-1].info[countPro-1].property,0x0,sizeof(propertyInfoBuf[epNumInt-1].info[countPro-1].property));
				memcpy(propertyInfoBuf[epNumInt-1].info[countPro-1].property,pFinal,strlen(pFinal));
				propertyInfoBuf[epNumInt-1].info[countPro-1].value = property->data_value.value_int;
			}
			else if(property->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
				sprintf(tmpValue,"%f",property->data_value.value_float);
				kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
				propertyInfoBuf[epNumInt-1].num++;
				countPro = propertyInfoBuf[epNumInt-1].num;
				propertyInfoBuf[epNumInt-1].info[countPro-1].type = property->data_value.type;
				memset(propertyInfoBuf[epNumInt-1].info[countPro-1].property,0x0,sizeof(propertyInfoBuf[epNumInt-1].info[countPro-1].property));
				memcpy(propertyInfoBuf[epNumInt-1].info[countPro-1].property,pFinal,strlen(pFinal));
				propertyInfoBuf[epNumInt-1].info[countPro-1].value = property->data_value.value_float;				
			}
			else if(property->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
				sprintf(tmpValue,"%f",property->data_value.value_double);
				kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
				propertyInfoBuf[epNumInt-1].num++;
				countPro = propertyInfoBuf[epNumInt-1].num;
				propertyInfoBuf[epNumInt-1].info[countPro-1].type = property->data_value.type;
				memset(propertyInfoBuf[epNumInt-1].info[countPro-1].property,0x0,sizeof(propertyInfoBuf[epNumInt-1].info[countPro-1].property));
				memcpy(propertyInfoBuf[epNumInt-1].info[countPro-1].property,pFinal,strlen(pFinal));
				propertyInfoBuf[epNumInt-1].info[countPro-1].value = property->data_value.value_double;				
			}	
			else if(property->data_value.type == KK_TSL_DATA_TYPE_TEXT||
				property->data_value.type == KK_TSL_DATA_TYPE_DATE){
				kk_property_db_update_value(deviceCode,property->identifier,property->data_value.value);
				propertyInfoBuf[epNumInt-1].num++;
				countPro = propertyInfoBuf[epNumInt-1].num;
				propertyInfoBuf[epNumInt-1].info[countPro-1].type = property->data_value.type;
				memset(propertyInfoBuf[epNumInt-1].info[countPro-1].property,0x0,sizeof(propertyInfoBuf[epNumInt-1].info[countPro-1].property));
				memcpy(propertyInfoBuf[epNumInt-1].info[countPro-1].property,pFinal,strlen(pFinal));
				propertyInfoBuf[epNumInt-1].info[countPro-1].valueStr = property->data_value.value;
				
			}
			else if(property->data_value.type == KK_TSL_DATA_TYPE_STRUCT){
				kk_tsl_data_value_complex_t *complex_struct = NULL;
				int index = 0;	
				kk_tsl_data_t *current_data = NULL;
				cJSON *propertyItem_1 = NULL;
				char tmp_identifiers[256] = {0};
				complex_struct = property->data_value.value;
				for (index = 0; index < complex_struct->size; index++) {
					current_data = (kk_tsl_data_t *)complex_struct->value + index;
					propertyItem_1 = cJSON_GetObjectItem(propertyItem, current_data->identifier);
					if(propertyItem_1 != NULL){
						memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
						sprintf(tmp_identifiers,"%s.%s",property->identifier,current_data->identifier);
						if(current_data->data_value.type == KK_TSL_DATA_TYPE_INT ||
							current_data->data_value.type == KK_TSL_DATA_TYPE_ENUM||
							current_data->data_value.type == KK_TSL_DATA_TYPE_BOOL){
							sprintf(tmpValue,"%d",current_data->data_value.value_int);
							kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
						}
						else if(current_data->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
							sprintf(tmpValue,"%f",current_data->data_value.value_float);
							kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
						}
						else if(current_data->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
							sprintf(tmpValue,"%u",current_data->data_value.value_double);
							kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
						}	
						else if(current_data->data_value.type == KK_TSL_DATA_TYPE_TEXT||
							current_data->data_value.type == KK_TSL_DATA_TYPE_DATE){
							kk_property_db_update_value(deviceCode,tmp_identifiers,current_data->data_value.value);
						}	
						#if 0
						else if(current_data->data_value.type == KK_TSL_DATA_TYPE_STRUCT){
							kk_tsl_data_value_complex_t *complex_struct_1 = NULL;
							complex_struct_1 = current_data->data_value.value;
							int index1 = 0;
							kk_tsl_data_t *current_data_1 = NULL;
							cJSON *propertyItem_2 = NULL;
							for(index1 = 0; index1 < complex_struct_1->size; index1++){
								current_data_1 = (kk_tsl_data_t *)complex_struct_1->value + index1;
								propertyItem_2 = cJSON_GetObjectItem(propertyItem_1, current_data_1->identifier);
								if(propertyItem_2 != NULL){
									memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
									sprintf(tmp_identifiers,"%s.%s.%s",property->identifier,current_data->identifier,current_data_1->identifier);
									if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_INT ||
										current_data_1->data_value.type == KK_TSL_DATA_TYPE_ENUM||
										current_data_1->data_value.type == KK_TSL_DATA_TYPE_BOOL){
										sprintf(tmpValue,"%d",current_data_1->data_value.value_int);
										kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
									}
									else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
										sprintf(tmpValue,"%f",current_data_1->data_value.value_float);
										kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
									}
									else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
										sprintf(tmpValue,"%u",current_data_1->data_value.value_double);
										kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
									}	
									else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_TEXT||
										current_data_1->data_value.type == KK_TSL_DATA_TYPE_DATE){
										kk_property_db_update_value(deviceCode,tmp_identifiers,current_data_1->data_value.value);
									}
									else{
										ERROR_PRINT("Unsupport Type ~~\n");
									}

								}

							}
						}
						#endif
						else{
							ERROR_PRINT("Unsupport  Type\n");
						}

					}
				}				
			}
			else{
				ERROR_PRINT("Unkonwn Number Type");
			}		
			//cJSON_DeleteItemFromObject(params,property->identifier);
		}
	}
	int epIdx[4] = {0};
	for(idx = 0; idx < epNumInt; idx++){
		countPro = propertyInfoBuf[idx].num; 
		memset(epIdx,0x0,sizeof(epIdx));
		sprintf(epIdx,"%d",idx+1);
		cJSON *	rootData=cJSON_CreateObject();
		cJSON_AddStringToObject(rootData,"epNum", epIdx);
		for(i = 0; i < countPro; i++){
			int vtype = propertyInfoBuf[idx].info[i].type;
			if(vtype == KK_TSL_DATA_TYPE_INT || vtype ==  KK_TSL_DATA_TYPE_ENUM \
				||vtype ==  KK_TSL_DATA_TYPE_BOOL || vtype ==  KK_TSL_DATA_TYPE_FLOAT \
				||vtype ==  KK_TSL_DATA_TYPE_DOUBLE)
			{
				cJSON_AddNumberToObject(rootData,propertyInfoBuf[idx].info[i].property, propertyInfoBuf[idx].info[i].value);
			}else if(vtype == KK_TSL_DATA_TYPE_TEXT || vtype == KK_TSL_DATA_TYPE_DATE){
				cJSON_AddStringToObject(rootData,propertyInfoBuf[idx].info[i].property, propertyInfoBuf[idx].info[i].valueStr);
			}
		}
		char* outstr = cJSON_Print(rootData);
		dm_mgr_upstream_thing_property_post(node->devid,outstr,strlen(outstr),0);
		free(outstr);
		cJSON_Delete(rootData);
	}

	return SUCCESS_RETURN;

}

int kk_msg_execute_property_set(const char *productCode,const char *deviceCode,const char* params,const char *fatherDeviceCode)
{
	char *method = "thing.service.property.set";
	char *req_info = NULL,*payload = NULL;
	int req_info_len = 0,payload_len = 0;
	char msgId[MSG_MAX_LEN] = {0};

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(productCode)+strlen(productCode)+strlen(KK_THING_SERVICE_PROPERTY_SET)+1;
	req_info = malloc(req_info_len);
	if (req_info == NULL) {
		return MEMORY_NOT_ENOUGH;
	}
	memset(req_info, 0, req_info_len);
	snprintf(req_info, req_info_len, DM_MSG_INFO, KK_THING_SERVICE_PROPERTY_SET,productCode, deviceCode);

	payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + strlen(params) + strlen(
					method) + 1 + 20 + sizeof(msgId);
	payload = malloc(payload_len);
	if (payload == NULL) {
		free(req_info);
		return MEMORY_NOT_ENOUGH;
	}
	memset(payload, 0, payload_len);
	iotx_report_id(msgId);
	//sprintf(msgId,"%d",iotx_report_id());
	snprintf(payload, payload_len, DM_MSG_REQUEST, msgId,
			DM_MSG_VERSION, params,HAL_GetTime(), method);

	cJSON *root=cJSON_CreateObject();
	cJSON* infoObj = cJSON_Parse(req_info);
	cJSON* payloadObj = cJSON_Parse(payload);
	cJSON_AddItemToObject(root, "info", infoObj);
	cJSON_AddItemToObject(root, "payload",payloadObj);
	void *buf = cJSON_Print(root);
	kk_sendData2gw(buf, strlen(buf), fatherDeviceCode);
	free(buf);
	free(req_info);
	free(payload);
	cJSON_Delete(root);
	return SUCCESS_RETURN;
}


int kk_msg_execute_property_get(dm_mgr_dev_node_t *node)
{
	char *method = "thing.service.property.get";
	char *req_info = NULL,*payload = NULL;
	int req_info_len = 0,payload_len = 0;
	int res = 0;
	int needFree = 0;
	int i = 0,j = 0,serviceNum = 0;
	char *paramS = NULL;
	char msgId[MSG_MAX_LEN] = {0};

	if(node == NULL){
		return INVALID_PARAMETER;
	}
	req_info_len = strlen(DM_MSG_INFO)+10+strlen(node->productCode)+strlen(node->productCode)+strlen(KK_THING_SERVICE_PROPERTY_SET)+1;
	req_info = malloc(req_info_len);
	if (req_info == NULL) {
		return MEMORY_NOT_ENOUGH;
	}
	memset(req_info, 0, req_info_len);
	snprintf(req_info, req_info_len, DM_MSG_INFO, KK_THING_SERVICE_PROPERTY_GET,node->productCode, node->deviceCode);

	cJSON *rootParam = cJSON_CreateObject();
	cJSON *array = cJSON_CreateArray();

	serviceNum = node->dev_shadow->service_number;
	for(i = 0; i < serviceNum; i++){
		kk_tsl_service_t *item = node->dev_shadow->services + i;
		if(!strcmp(item->identifier,"get")){
			int inputNum = item->input_data_number;
			if(inputNum == 0){
				paramS = "{}";
			}else{
				for(j = 0; j < inputNum; j++){
					kk_tsl_data_t *inputItem = item->input_datas + j;
					cJSON_AddItemToArray(array,cJSON_CreateString(inputItem->identifier));
				}
				cJSON_AddItemToObject(rootParam, KK_TSL_KEY_IDENTIFIER, array);
				paramS = cJSON_Print(rootParam);
				needFree = 1;
			}
			break;
		}
	}

	payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + strlen(paramS) + strlen(
					method) + 1 + 20+sizeof(msgId);
	payload = malloc(payload_len);
	if (payload == NULL) {
		free(req_info);
		return MEMORY_NOT_ENOUGH;
	}
	memset(payload, 0, payload_len);
	iotx_report_id(msgId);
	//sprintf(msgId,"%d",iotx_report_id());
	snprintf(payload, payload_len, DM_MSG_REQUEST, msgId,
			DM_MSG_VERSION, paramS,HAL_GetTime(), method);
	cJSON *root=cJSON_CreateObject();
	cJSON* infoObj = cJSON_Parse(req_info);
	cJSON* payloadObj = cJSON_Parse(payload);
	cJSON_AddItemToObject(root, "info", infoObj);
	cJSON_AddItemToObject(root, "payload",payloadObj);
	void *buf = cJSON_Print(root);
	if(node->dev_type == KK_DM_DEVICE_GATEWAY)
		kk_sendData2gw(buf, strlen(buf), node->deviceCode);
	else
		kk_sendData2gw(buf, strlen(buf), node->fatherDeviceCode);

	if(needFree){
		free(paramS);
	}	
	free(buf);
	free(req_info);
	free(payload);

	cJSON_Delete(root);
	cJSON_Delete(rootParam);
	return SUCCESS_RETURN;

}


int kk_msg_parse_productType(char *str,char *productType)
{
	cJSON *item = NULL;
	cJSON *json=cJSON_Parse(str);
	if(json == NULL){
		return FAIL_RETURN;
	}
	item = cJSON_GetObjectItem(json, KK_TSL_KEY_PRODUCTTYPE);
	if(item != NULL&&strlen(item->valuestring) < PRODUCT_TYPE_MAXLEN){
		memcpy(productType,item->valuestring,strlen(item->valuestring));
	}
	cJSON_Delete(json);
	return SUCCESS_RETURN;
	
}

int kk_msg_execute_scene_set(const char* params,const char *fatherDeviceCode,int isUpdate)
{
	int res = 0;
	char *method = KK_THING_METHOD_ADDSCENC;
	char *msgType = KK_THING_SERVICE_ADDSCENC;	
	char *req_info = NULL,*payload = NULL;
	int req_info_len = 0,payload_len = 0;
	dm_mgr_dev_node_t *node = NULL;
	char msgId[MSG_MAX_LEN] = {0};
	
	if(isUpdate){
		method = KK_THING_METHOD_UPDATESCENC;
		msgType = KK_THING_SERVICE_UPDATESCENC;
	}
	res = dm_mgr_get_device_by_devicecode(fatherDeviceCode,&node);
	if (res != SUCCESS_RETURN) {
		ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
		return FAIL_RETURN;
	}

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(node->productCode)+strlen(fatherDeviceCode)+strlen(msgType)+1;
	req_info = malloc(req_info_len);
	if (req_info == NULL) {
		return MEMORY_NOT_ENOUGH;
	}
	memset(req_info, 0, req_info_len);
	snprintf(req_info, req_info_len, DM_MSG_INFO, msgType,node->productCode, fatherDeviceCode);

	payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + strlen(params) + strlen(
					method) + 1 + 20 + sizeof(msgId);
	payload = malloc(payload_len);
	if (payload == NULL) {
		free(req_info);
		return MEMORY_NOT_ENOUGH;
	}
	memset(payload, 0, payload_len);
	iotx_report_id(msgId);
	//sprintf(msgId,"%d",iotx_report_id());
	snprintf(payload, payload_len, DM_MSG_REQUEST, msgId,
				DM_MSG_VERSION, params,HAL_GetTime(), method);

	cJSON *root=cJSON_CreateObject();
	cJSON* infoObj = cJSON_Parse(req_info);
	cJSON* payloadObj = cJSON_Parse(payload);
	cJSON_AddItemToObject(root, "info", infoObj);
	cJSON_AddItemToObject(root, "payload",payloadObj);
	void *buf = cJSON_Print(root);
	kk_sendData2gw(buf, strlen(buf), fatherDeviceCode);
	free(buf);
	free(req_info);
	free(payload);
	cJSON_Delete(root);
	return SUCCESS_RETURN;

}

int kk_msg_execute_scene_action(const char* params,const char *fatherDeviceCode)
{
	int res = 0;
	char *method = KK_THING_METHOD_EXECUTESCENE;
	char *req_info = NULL,*payload = NULL;
	int req_info_len = 0,payload_len = 0;
	char msgId[MSG_MAX_LEN] = {0};

	dm_mgr_dev_node_t *node = NULL;
	res = dm_mgr_get_device_by_devicecode(fatherDeviceCode,&node);
	if (res != SUCCESS_RETURN) {
		ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
		return FAIL_RETURN;
	}

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(node->productCode)+strlen(fatherDeviceCode)+strlen(KK_THING_SERVICE_EXECUTESCENE)+1;
	req_info = malloc(req_info_len);
	if (req_info == NULL) {
		return MEMORY_NOT_ENOUGH;
	}
	memset(req_info, 0, req_info_len);
	snprintf(req_info, req_info_len, DM_MSG_INFO, KK_THING_SERVICE_EXECUTESCENE,node->productCode, fatherDeviceCode);

	payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + strlen(params) + strlen(
					method) + 1 + 20 + sizeof(msgId);
	payload = malloc(payload_len);
	if (payload == NULL) {
		free(req_info);
		return MEMORY_NOT_ENOUGH;
	}
	memset(payload, 0, payload_len);
	iotx_report_id(msgId);
	//sprintf(msgId,"%d",iotx_report_id());
	snprintf(payload, payload_len, DM_MSG_REQUEST, msgId,
			DM_MSG_VERSION, params,HAL_GetTime(), method);

	cJSON *root=cJSON_CreateObject();
	cJSON* infoObj = cJSON_Parse(req_info);
	cJSON* payloadObj = cJSON_Parse(payload);
	cJSON_AddItemToObject(root, "info", infoObj);
	cJSON_AddItemToObject(root, "payload",payloadObj);
	void *buf = cJSON_Print(root);
	kk_sendData2gw(buf, strlen(buf), fatherDeviceCode);
	free(buf);
	free(req_info);
	free(payload);
	cJSON_Delete(root);
	return SUCCESS_RETURN;
}

int kk_msg_execute_scene_delete(const char* params,const char *fatherDeviceCode)
{
	int res = 0;
	char *method = KK_THING_METHOD_DELETESCENC;
	char *req_info = NULL,*payload = NULL;
	int req_info_len = 0,payload_len = 0;
	char msgId[MSG_MAX_LEN] = {0};

    dm_mgr_dev_node_t *node = NULL;
	res = dm_mgr_get_device_by_devicecode(fatherDeviceCode,&node);
    if (res != SUCCESS_RETURN) {
		ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
        return FAIL_RETURN;
    }

	req_info_len = strlen(DM_MSG_INFO)+10+strlen(node->productCode)+strlen(fatherDeviceCode)+strlen(KK_THING_SERVICE_DELETESCENC)+1;
    req_info = malloc(req_info_len);
    if (req_info == NULL) {
        return MEMORY_NOT_ENOUGH;
    }
    memset(req_info, 0, req_info_len);
    snprintf(req_info, req_info_len, DM_MSG_INFO, KK_THING_SERVICE_DELETESCENC,node->productCode, fatherDeviceCode);

    payload_len = strlen(DM_MSG_REQUEST) + 10 + strlen(DM_MSG_VERSION) + strlen(params) + strlen(
                              method) + 1 + 20 + sizeof(msgId);
    payload = malloc(payload_len);
    if (payload == NULL) {
		free(req_info);
        return MEMORY_NOT_ENOUGH;
    }
    memset(payload, 0, payload_len);
	iotx_report_id(msgId);
	//sprintf(msgId,"%d",iotx_report_id());
	//sprintf(msgId,"%d",iotx_report_id());
    snprintf(payload, payload_len, DM_MSG_REQUEST, msgId,
                 DM_MSG_VERSION, params,HAL_GetTime(), method);

    cJSON *root=cJSON_CreateObject();
    cJSON* infoObj = cJSON_Parse(req_info);
    cJSON* payloadObj = cJSON_Parse(payload);
    cJSON_AddItemToObject(root, "info", infoObj);
    cJSON_AddItemToObject(root, "payload",payloadObj);
	void *buf = cJSON_Print(root);
	printf("----------------->buf:%s\n",buf);
	kk_sendData2gw(buf, strlen(buf), fatherDeviceCode);
	free(buf);
	free(req_info);
	free(payload);
	cJSON_Delete(root);
	return SUCCESS_RETURN;

}

