/************************************************************
*版权所有 （C）2020，公司（或个人）名称
*
*文件名称： kk_sub_db.c
*内容摘要： 网关设备和子设备设备表处理模块
*其他说明： 
*当前版本：  
*************************************************************/

#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_sub_db.h"
#include "kk_property_db.h"
#include "kk_dm_mng.h"
#include "kk_dm_msg.h"
#include "kk_scene_handle.h"
#include "kk_dm_heartbeat.h"
#include "kk_dm_api.h"
#include "sqlite3.h"
#include "kk_log.h"
#include "kk_hal.h"
#include "kk_area_handle.h"
extern sqlite3 *g_kk_pDb;

typedef struct {
	void *mutex;
	int  subDevNum;
	sqlite3 *pDb;	
} kk_subDb_ctx_t;


static kk_subDb_ctx_t s_kk_subDb_ctx = {NULL,0,NULL};
static kk_subDb_ctx_t *_kk_subDb_get_ctx(void)
{
	return &s_kk_subDb_ctx;
}
static void _kk_subDb_lock(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	if (ctx->mutex) {
		HAL_MutexLock(ctx->mutex);
	}
}

static void _kk_subDb_unlock(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	if (ctx->mutex) {
		HAL_MutexUnlock(ctx->mutex);
	}
}

/************************************************************
*功能描述：设备表的初始化
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

static int kk_subDev_db_Init(void)
{
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//eUtils_LockLock(&sLock);
	_kk_subDb_lock();
	
	ctx->pDb = g_kk_pDb;


	const char *pSubDevTable = "CREATE TABLE IF NOT EXISTS SubDeviceInfo( \
		idx INTEGER, \
		isOffline INTEGER, \
		productCode varchar(33), \
		deviceCode varchar(33) UNIQUE, \
		mac varchar(17), \
		fatherDeviceCode varchar(33), \
		version varchar(33), \
		isAuth INTEGER, \
		devType INTEGER, \
		heartbeat INTEGER,\
		productType varchar(33),\
		sceneSupport INTEGER)";

	char *pcErr;

//     DBG_vPrintf(DBG_SQL, "Execute SQL: '%s'\n", pConditionTableDef);

	if (sqlite3_exec(ctx->pDb, pSubDevTable, NULL, NULL, &pcErr) != SQLITE_OK)
	{
		ERROR_PRINT("Error creating table (%s)\n", pcErr);
		sqlite3_free(pcErr);
		//eUtils_LockUnlock(&sLock);
		_kk_subDb_unlock();
		return FAIL_RETURN;
	}
	
	const char *pScreenDevTable = "CREATE TABLE IF NOT EXISTS ScreenDeviceInfo( \
		idx INTEGER PRIMARY KEY , \
		isOffline INTEGER, \
		type INTEGER, \
		serialId varchar(128), \
		deviceIp varchar(32), \
		deviceName varchar(128), \
		mac varchar(33), \
		version varchar(33), \
		roomId varchar(33), \
		roomName varchar(128), \
		expand varchar(256))";

	if (sqlite3_exec(ctx->pDb, pScreenDevTable, NULL, NULL, &pcErr) != SQLITE_OK)
	{
		ERROR_PRINT("Error creating table (%s)\n", pcErr);
		sqlite3_free(pcErr);
		return FAIL_RETURN;
	}
	//eUtils_LockUnlock(&sLock);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：开机从设备数据库导出数据到内存
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
static int _kk_load_subDevice(void)
{
	const char *searchCmd = "select * from SubDeviceInfo;";	
	sqlite3_stmt *stmt;	
	char *version;
	int deviceType = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	int devId = 0,heartbeat = 0;
	int res = 0;
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		deviceType = sqlite3_column_int(stmt, DB_SUB_DEVTYPE);
		version = (char*)sqlite3_column_text(stmt, DB_SUB_VERSION),
		res = dm_mgr_subdev_create(deviceType,
	   					(char*)sqlite3_column_text(stmt, DB_SUB_PRODUCTCODE),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_MAC),
	   					(char*)sqlite3_column_text(stmt, DB_SUB_FATHERDEVICECODE),
	   					KK_DEV_UNKNOW,&devId,&heartbeat,version);
	
		if(res != SUCCESS_RETURN){
			ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__);
		}
		else{
			ctx->subDevNum++;
		}
		usleep(100000);
		// send the topo info
		//iotx_dm_subscribe(devId);

	   //sync the data from property db
	   kk_property_sync_values((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   usleep(100000);

	   if(deviceType == KK_DM_DEVICE_GATEWAY){
			kk_dm_gw_status_check_push((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   }
	   //post the property to cloud
	   //dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE));
	    //kk_dm_ota_report_version(devId,sqlite3_column_text(stmt, DB_VERSION));//post version
	   //usleep(100000);
    }	
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;

}
/************************************************************
*功能描述：设备数据模块初始化
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDb_init(void)
{
	int res = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	
	/* Create Mutex */
	ctx->mutex = HAL_MutexCreate();
	if (ctx->mutex == NULL) {
		return FAIL_RETURN;
	}

	res = kk_subDev_db_Init();
	if(res != SUCCESS_RETURN){
		ERROR_PRINT("[%s][%d]kk_wlist_db_Init FAIL!!!\n",__FUNCTION__,__LINE__);

	}
	_kk_load_subDevice();
	//kk_load_subDevice();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：检查设备是否有重复
*输入参数：deviceCode：设备deviceCode
*输出参数：无
*返 回 值：1:存在；0：不存在
*其他说明：
*************************************************************/

static int _kk_check_subDev_exist(const char* deviceCode)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *pmac = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo;";	
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   pmac = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
	   if(!strcmp(deviceCode,pmac))
	   
{
		 isExist = 1;
		 break;
	   }
    }
    INFO_PRINT("\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return isExist;

}

/************************************************************
*功能描述：保存设备信息到数据库
*输入参数：devType：设备类型
          productCode：产品Id
          deviceCode:设备deviceCode
          fatherDeviceCode:上一级网关的deviceCode
          mac: mac地址
          version：版本号
          heartbeat：心跳时间

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_insert_db(int devType,char productCode[PRODUCT_CODE_MAXLEN], \
										char deviceCode[DEVICE_CODE_MAXLEN],char fatherDeviceCode[DEVICE_CODE_MAXLEN],char mac[DEVICE_MAC_MAXLEN],char version[DEVICE_VERSION_MAXLEN],int heartbeat)
{
	const char *insertCmd = "insert into SubDeviceInfo (idx,isOffline,productCode,deviceCode,mac,fatherDeviceCode,version,isAuth,devType,heartbeat,sceneSupport) \
								values ('%d','%d', '%s','%s','%s','%s','%s','%d','%d','%d','%d');";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();


	if(_kk_check_subDev_exist((const char*)deviceCode) == 1)
	{
		WARNING_PRINT("[%s][%d] DATA ALREADY EXIST!!!\n",__FUNCTION__,__LINE__);
		return SUCCESS_RETURN;
	}
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(insertCmd,ctx->subDevNum,0,productCode,deviceCode,mac,fatherDeviceCode,version,0,devType,heartbeat,0);	

	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	ctx->subDevNum++;
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
								
/************************************************************
*功能描述：删除设备信息
*输入参数：deviceCode:设备deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN])
{
	const char *deleteCmd = "delete from SubDeviceInfo where deviceCode = '%s';";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(deleteCmd,deviceCode);	

	INFO_PRINT("Table delete data sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("Table delete data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新是否在线信息
*输入参数：deviceCode:设备deviceCode
          isOffline：1，离线；0，在线
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_update_offline(int isOffline,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isOffline=%d  WHERE deviceCode= '%s'",isOffline,deviceCode);	
	INFO_PRINT("kk_subDev_update_offline sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	//_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新设备类型
*输入参数：deviceCode:设备deviceCode
          productType：设备类型
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_update_productType(char *productType,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	//_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET productType='%s'  WHERE deviceCode= '%s'",productType,deviceCode);	
	INFO_PRINT("kk_subDev_update_productType sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   //INFO_PRINT("Table updata data successfully\n");
	}
    sqlite3_free(sqlCmd);
	//_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：更新设备注册标记
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_update_auth(int isAuth,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isAuth=%d  WHERE deviceCode= '%s'",isAuth,deviceCode);	
	INFO_PRINT("kk_subDev_update_auth sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
	   ERROR_PRINT("SQL error: %s\n", zErrMsg);
	   sqlite3_free(zErrMsg);
	}else{
	   INFO_PRINT("Table updata data successfully\n");
	}
    sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：更新设备注册标记
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_check_auth(int devType)
{
	char *sqlCmd = NULL;
	sqlite3_stmt *stmt;	
	int rc = 0;
	char *zErrMsg = 0;
	const char *searchCmd = "select * from SubDeviceInfo WHERE devType = '%d';";	
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	sqlCmd = sqlite3_mprintf(searchCmd,devType);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);		
	while(sqlite3_step(stmt) == SQLITE_ROW){
	    char *pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
	   	char *pProductCode = (char*)sqlite3_column_text(stmt, DB_SUB_PRODUCTCODE);
		kk_msg_cloud_status_notify(pDeviceCode,pProductCode);
		//kk_subDev_update_auth(1,pDeviceCode);
    }
	sqlite3_finalize(stmt);
    sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：更新内场景支持，此接口只针对网关设备有效
*输入参数：deviceCode:设备deviceCode
          sceneSupport：1，支持内场景；0，不支持
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_update_sceneSupport(int sceneSupport,const char *deviceCode)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET sceneSupport=%d  WHERE deviceCode= '%s'",sceneSupport,deviceCode);	
	INFO_PRINT("kk_subDev_update_sceneSupport sqlCmd:%s\n",sqlCmd);
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}


/************************************************************
*功能描述：主机重新上线后向云端上报属性
*输入参数：无
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_send_property_get_from_db(void)
{
	const char *searchCmd = "select * from SubDeviceInfo;";	
	sqlite3_stmt *stmt;	
	int isOffline = 0;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	int res = 0;
	dm_mgr_dev_node_t *node = NULL;	
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
	   isOffline = sqlite3_column_int(stmt, DB_SUB_DEVTYPE);
	   if(isOffline == KK_DEV_ONLINE){
		   res = dm_mgr_get_device_by_devicecode((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE), &node);
		   if (res != SUCCESS_RETURN) {
		       continue;
		   }
		   iotx_dm_dev_online(node->devid);

		   dm_msg_thing_property_post_all((char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE));
	   }
    }	
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;


}
/************************************************************
*功能描述：主机断电重启后向网关获取所有子设备属性
*输入参数：fatherDeviceCode：网关deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_send_property_get(const char *fatherDeviceCode)
{
	int res = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;		
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE fatherDeviceCode = '%s'";	

	if(fatherDeviceCode == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}
	sqlCmd = sqlite3_mprintf(searchCmd,fatherDeviceCode);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		res = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		if (res != SUCCESS_RETURN) {
			ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
			continue;
		}
		/*休眠设备，不需要下发获取属性*/
		if(node->dormancyDev){
			continue;
		}
		/*发送之前先置为KK_DEV_UNKNOW*/
		node->isOffline = KK_DEV_UNKNOW;
		kk_msg_execute_property_get(node);
		usleep(100000);
	}

	sqlite3_finalize(stmt);
	sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;


}

/************************************************************
*功能描述：检查网关是否支持内场景
*输入参数：deviceCode：网关deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/

int kk_subDev_check_scene_support(const char *deviceCode)
{
	int res = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE devType= '%d' and sceneSupport = '%d'";	

	if(deviceCode == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}

	sqlCmd = sqlite3_mprintf(searchCmd,KK_DM_DEVICE_GATEWAY,1);	
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		if (!strcmp(deviceCode,pDeviceCode)) {
			res = 1;
		}
	}
	sqlite3_finalize(stmt);
	sqlite3_free(sqlCmd);
	return res;
}

/************************************************************
*功能描述：向所有同类设备执行动作，场景设置中用到
*输入参数：productType：设备类型
          sceneId：场景Id
          propertyName:属性名
          propertyValue：属性值
          type：执行类型
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
typedef struct{
	char *type;
	char *maptype;
}productype_map_s;
static productype_map_s producTypeMap[] = {
	{"CURTAIN","curtain"},
	{"WINDOW","actuator"},	
	{"LIGHT","switch"},		
	{"LIGHT_STRIP","colorDimmableLight"},	
	{"LIGHT_DIMMER","lightPanel"},		
	{"SOCKET","outlet"},	
	{"AC_IndoorUnit","air conditioning gateway"},	
	{"FLOOR_HEATING","floorHeating"},	
	{"FRESH_AIR","freshAir"},	
	{"AIR_SWITCH","airswitch gateway"},	
};
int kk_get_product_type_table_size(void)
{
	return sizeof(producTypeMap)/sizeof(productype_map_s);
}
static int _kk_indoor_air_info_handle(char* deviceCode,char* propertyName,char* propertyValue,int ep,int delay,char* gwDeviceCode,char*sceneId,char* type)
{
	int res = 0;
	kk_scene_action_detail_t info = {0};
	memcpy(info.deviceCode,deviceCode,strlen(deviceCode));
	memcpy(info.propertyName,propertyName,strlen(propertyName));
	memcpy(info.propertyValue,propertyValue,strlen(propertyValue));		
	info.epNum = ep;
	info.delay = delay;
	kk_scene_action_add(gwDeviceCode,sceneId,info);
	res = kk_scene_insert_scene_action(type,deviceCode,info.epNum,
			propertyName,propertyValue,info.delay,sceneId,gwDeviceCode);
	if(res != SUCCESS_RETURN){
		INFO_PRINT("kk_subDev_set_action_by_productType fail!!!\n");
	}
	return res;
}
static int _kk_indoor_air_handle(char* deviceCode, char *sceneId, char *propertyName, char *propertyValue, char *type,int delay, char*gwDeviceCode)
{
	int eplist[64] = {0};
	char data[32] = {0};
	int res = 0;
	int i = 0;
	int count = kk_indoorAir_query_epnums(deviceCode,eplist);
	for(i = 0; i < count; i++){
		
		if(strcmp(propertyName,"CustomAction") == 0){
			cJSON* json = cJSON_Parse(propertyValue);
			if (json == NULL) {
				return -1;
			}
			cJSON*  Temperature = cJSON_GetObjectItem(json, "Temperature");
			if(Temperature == NULL) { cJSON_Delete(json);return -1;}
			memset(data,0x0,sizeof(data));
			sprintf(data,"%f",Temperature->valuedouble);
			_kk_indoor_air_info_handle(deviceCode,"Temperature",data,eplist[i],delay,gwDeviceCode,sceneId,type);
			cJSON*  WindSpeed = cJSON_GetObjectItem(json, "WindSpeed");
			if(WindSpeed == NULL) { cJSON_Delete(json);return -1;}
			memset(data,0x0,sizeof(data));
			sprintf(data,"%d",WindSpeed->valueint);
			_kk_indoor_air_info_handle(deviceCode,"WindSpeed",data,eplist[i],delay,gwDeviceCode,sceneId,type);			
			cJSON*  WorkMode = cJSON_GetObjectItem(json, "WorkMode");
			if(WorkMode == NULL){ cJSON_Delete(json);return -1;}		
			memset(data,0x0,sizeof(data));
			sprintf(data,"%d",WorkMode->valueint);
			_kk_indoor_air_info_handle(deviceCode,"WorkMode",data,eplist[i],delay,gwDeviceCode,sceneId,type);
			cJSON_Delete(json);												
		}else{
			_kk_indoor_air_info_handle(deviceCode,propertyName,propertyValue,eplist[i],delay,gwDeviceCode,sceneId,type);
		}
	}
	return 0;
}

static int _kk_air_switch_handle(char* deviceCode, char *sceneId, char *propertyName, char *propertyValue, char *type,int delay, char*gwDeviceCode)
{
	int eplist[64] = {0};
	char data[32] = {0};
	int res = 0;
	int i = 0;
	int count = kk_subAirSwitch_query_epnums(deviceCode,eplist);
	for(i = 0; i < count; i++){
		
		if(strcmp(propertyName,"CustomAction") == 0){
			#if 0
			cJSON* json = cJSON_Parse(propertyValue);
			if (json == NULL) {
				return -1;
			}
			cJSON*  Temperature = cJSON_GetObjectItem(json, "Temperature");
			if(Temperature == NULL) { cJSON_Delete(json);return -1;}
			memset(data,0x0,sizeof(data));
			sprintf(data,"%f",Temperature->valuedouble);
			_kk_indoor_air_info_handle(deviceCode,"Temperature",data,eplist[i],delay,gwDeviceCode,sceneId,type);
			cJSON*  WindSpeed = cJSON_GetObjectItem(json, "WindSpeed");
			if(WindSpeed == NULL) { cJSON_Delete(json);return -1;}
			memset(data,0x0,sizeof(data));
			sprintf(data,"%d",WindSpeed->valueint);
			_kk_indoor_air_info_handle(deviceCode,"WindSpeed",data,eplist[i],delay,gwDeviceCode,sceneId,type);			
			cJSON*  WorkMode = cJSON_GetObjectItem(json, "WorkMode");
			if(WorkMode == NULL){ cJSON_Delete(json);return -1;}		
			memset(data,0x0,sizeof(data));
			sprintf(data,"%d",WorkMode->valueint);
			_kk_indoor_air_info_handle(deviceCode,"WorkMode",data,eplist[i],delay,gwDeviceCode,sceneId,type);
			cJSON_Delete(json);	
			#endif											
		}else{
			_kk_indoor_air_info_handle(deviceCode,propertyName,propertyValue,eplist[i],delay,gwDeviceCode,sceneId,type);
		}
	}
	return 0;
}
int kk_subDev_set_action_by_productType(const char *productType,const char *roomId,const char *sceneId,const char *propertyName,const char *propertyValue,const char *type,int delay)
{
	int res = 0;
	int devIsExsit = 0;
	sqlite3_stmt *stmt;
	char *sqlCmd = NULL;
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from SubDeviceInfo WHERE productType= '%s'";	
	int idx = 0;
	kk_tsl_data_t *property = NULL;
	int k = 0,count  = 0;
	char typeArray[10][32] = {0};
	int size = 0;
	char *pStart = NULL;
	int allRoom = (strcmp(roomId,"-1")==0)?1:0;
	if(productType == NULL){
		ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
		return INVALID_PARAMETER;
	}
	INFO_PRINT("kk_subDev_set_action_by_productType called!!!\n");
	size = kk_get_product_type_table_size();
	//printf("---------------------------->size:%d\n",size);
	for(k = 0; k < size; k++){
		//printf("---------------------------->producTypeMap[k].type:%s\n",producTypeMap[k].type);
		if(!strcmp(productType,producTypeMap[k].type)){
			memcpy(typeArray[count],producTypeMap[k].maptype,strlen(producTypeMap[k].maptype));
			//printf("---------------------------->producTypeMap[k].maptype:%s\n",producTypeMap[k].maptype);
			count++;
			if(count >= 10){
				break;
			}
		}
	}
	for(k = 0; k < count; k++){
		INFO_PRINT("typeArray[k]:%s\n",typeArray[k]);
		sqlCmd = sqlite3_mprintf(searchCmd,typeArray[k]);	//curtain type
		sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
		devIsExsit = 0;
		//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
		while(sqlite3_step(stmt) == SQLITE_ROW){
		   
		   pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		   res = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		   if (res != SUCCESS_RETURN) {
			   continue;
		   }
		    if(strcmp(typeArray[k],KK_DM_AIR_GATEWAY_TYPE) == 0){
			    _kk_indoor_air_handle(pDeviceCode,(char*)sceneId,(char*)propertyName,(char*)propertyValue,(char*)type,delay,node->fatherDeviceCode);
			    continue;
		    }else if(strcmp(typeArray[k],KK_DM_AIR_SWITCH_GATEWAY_TYPE) == 0){
			    _kk_air_switch_handle(pDeviceCode,(char*)sceneId,(char*)propertyName,(char*)propertyValue,(char*)type,delay,node->fatherDeviceCode);
			    continue;
			}
			for(idx = 0; idx < node->dev_shadow->property_number; idx++){
				property = (kk_tsl_data_t *)(node->dev_shadow->properties + idx);
				if(property == NULL){
					continue;
				}
				char *ptr = strstr(property->identifier,propertyName);
				if(ptr != NULL && (ptr-property->identifier==0) ){
					kk_scene_action_detail_t info = {0};
					memcpy(info.deviceCode,node->deviceCode,strlen(node->deviceCode));
					memcpy(info.propertyName,property->identifier,strlen(property->identifier));
					memcpy(info.propertyValue,propertyValue,strlen(propertyValue));
					//printf("------------------->property->identifier:%s\n",property->identifier);
					pStart = strstr(property->identifier,"_");
					if(pStart != NULL){
						//printf("------------------->num:%s\n",pStart+1);
						info.epNum = atoi(pStart+1);
					}else{
						info.epNum = 1;
					}	
					if(allRoom==0){
						char roomName[256] = {0};
						char roomIdStr[16] = {0};
						if(kk_get_device_roomInfo(pDeviceCode,info.epNum,roomName,roomIdStr)==0){
							continue;
						}
						if(strcmp(roomIdStr,roomId)!=0){
							continue;
						}
					}

					if(strcmp(node->productCode,"3098") == 0 && info.epNum != 1){ //风机盘管多合一只处理第一路
						continue;	
					}
					else if(strcmp(node->productCode,"3097") == 0 && info.epNum != 2){//地暖多合一只处理第二路
						continue;
					}	
					else if(strcmp(node->productCode,"3099") == 0 && info.epNum != 3){//新风多合一只处理第三路
						continue;
					}				
					else if(strcmp(node->productCode,"3095") == 0 && info.epNum != 1){//线控器多合一只处理第一路
						continue;
					}						
					info.delay = delay;
					devIsExsit = 1;
					kk_scene_action_add(node->fatherDeviceCode,sceneId,info);
					res = kk_scene_insert_scene_action(type,node->deviceCode,info.epNum,
							property->identifier,propertyValue,info.delay,sceneId,node->fatherDeviceCode);
					if(res != SUCCESS_RETURN){
						INFO_PRINT("kk_subDev_set_action_by_productType fail!!!\n");
						//return res;
						continue;
					}						
				}
			}		   
	    }
		if(devIsExsit == 0){//设置场景,但是又没有对应的设备需要插入一条无效action用于记录propertyName，同步需要
			res = kk_scene_insert_scene_action(type,"",1,
					propertyName,propertyValue,delay,sceneId,"");
			if(res != SUCCESS_RETURN){
				INFO_PRINT("kk_subDev_set_action_by_productType fail!!!\n");
				//return res;
				continue;
			}			
		}
		sqlite3_finalize(stmt);
		sqlite3_free(sqlCmd);		
	}
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：获取传感器类设备
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_getSensors_reply(SensorType_t*list)
{
	char *sqlCmd = NULL;
	int rc = 0;
	const char *searchCmd = "select * from SubDeviceInfo WHERE productType= '%s'";
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;	
	int currentValue = 0;
	int count = 0;
	//printf("kk_subDev_getSensors_reply----------------------start\n");
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,"sensor");
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		//printf("kk_subDev_getSensors_reply----------------------num\n");
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		rc = dm_mgr_get_device_by_devicecode(pDeviceCode,&node);
		if (rc != SUCCESS_RETURN) {
			ERROR_PRINT("ERROR res:%d\n",rc);
			continue;
		}
		//printf("pDeviceCode:%s\n",pDeviceCode);
		kk_property_db_get_value(pDeviceCode,"SensorType",&currentValue);
		//printf("currentValue:%d\n",currentValue);
		memcpy(list[count].deviceCode,pDeviceCode,strlen(pDeviceCode));
		list[count].SensorType = currentValue;
		count++;
	}
	//printf("kk_subDev_getSensors_reply----------------------end\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	sqlite3_free(sqlCmd);
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：通过deviceType获取设备
*输入参数：deviceCode:设备deviceCode
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_subDev_getDeviceCodes_byProductType(DeviceCode_t *list,char *type)
{
	char *sqlCmd = NULL;
	const char *searchCmd = "select * from SubDeviceInfo WHERE productType= '%s'";
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	char *pDeviceCode = NULL;
	dm_mgr_dev_node_t *node = NULL;	
	int currentValue = 0;
	int count = 0;
	//printf("kk_subDev_getSensors_reply----------------------start\n");
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,type);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		//printf("kk_subDev_getSensors_reply----------------------num\n");
		pDeviceCode = (char*)sqlite3_column_text(stmt, DB_SUB_DEVICECODE);
		memcpy(list[count].deviceCode,pDeviceCode,strlen(pDeviceCode));
		count++;
	}
	//printf("kk_subDev_getSensors_reply----------------------end\n");
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	sqlite3_free(sqlCmd);
	return count;
}

/************************************************************
*功能描述：检查屏类设备是否有重复
*输入参数：deviceCode：设备deviceCode
*输出参数：无
*返 回 值：1:存在；0：不存在
*其他说明：
*************************************************************/

static int _kk_check_screenDev_exist(const char* sId)
{
	int isExist = 0;
	sqlite3_stmt *stmt;
	char *serialId = NULL;
    kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	const char *searchCmd = "select * from ScreenDeviceInfo;";	
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	//INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
	while(sqlite3_step(stmt) == SQLITE_ROW){
		serialId = (char*)sqlite3_column_text(stmt, DB_SCREEN_SERIALID);
		if(!strcmp(sId,serialId))
		{
			isExist = 1;
			break;
		}
    }
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return isExist;

}
/************************************************************
*功能描述：更新设备信息到数据库
*输入参数：devType：设备类型
          serialId：产品Id
          ip:设备ip
          mac: mac地址
          version：版本号
          expand：预留

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/	
int kk_screenDev_update(int devType,char *serialId, \
										char *ip,char *mac,char *version)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE ScreenDeviceInfo SET deviceIp= '%s',mac ='%s',version = '%s' WHERE serialId= '%s'",ip,mac,version,serialId);	
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：保存设备信息到数据库
*输入参数：devType：设备类型
          serialId：产品Id
          ip:设备ip
          mac: mac地址
          version：版本号
          expand：预留

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_screenDev_insert_db(int devType,char *serialId, \
										char *ip,char *mac,char *version,char *expand)
{
	const char *insertCmd = "insert into ScreenDeviceInfo (isOffline,type,serialId,deviceIp,deviceName,mac,version,roomId,roomName,expand) \
								values ('%d','%d','%s','%s','%s','%s','%s','%s','%s','%s');";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();


	if(_kk_check_screenDev_exist((const char*)serialId) == 1)
	{
		kk_screenDev_update(devType,serialId,ip,mac,version);
		return SUCCESS_RETURN;
	}
	_kk_subDb_lock();
	#ifdef CONFIG_A133_PLATFORM	
	sqlCmd = sqlite3_mprintf(insertCmd,1,devType,serialId,ip,"MOOR4S",mac,version,"","",expand);
	#else
	sqlCmd = sqlite3_mprintf(insertCmd,1,devType,serialId,ip,"MOOR4C",mac,version,"","",expand);
	#endif

	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("sub device insert data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}	
/************************************************************
*功能描述：更新设备信息到数据库
*输入参数：devType：设备类型
          serialId：产品Id
          ip:设备ip
          mac: mac地址
          version：版本号
          expand：预留

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/	
void str_trans(char c[]) {
    int i;
 
    for(i=0;c[i];i++)
        if(c[i]>='A'&&c[i]<='Z')
            c[i]=(c[i]-'A')+'a';
        /*以下注释内容为小写转大写，如不需要可删除*/
        /*else if(c[i]<='z' && c[i]>='a')
            c[i]=(c[i]-'a')+'A';*/
}
int kk_screenDev_update_room(char *mac,char *roomid,char *roomname,char* name)
{
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	str_trans(mac);
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf("UPDATE ScreenDeviceInfo SET roomId= '%s',roomName ='%s',deviceName = '%s' WHERE mac= '%s'",roomid,roomname,name,mac);	
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		INFO_PRINT("Table updata data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}
/************************************************************
*功能描述：删除设备信息到数据库
*输入参数：devType：设备类型
          serialId：产品Id
          ip:设备ip
          mac: mac地址
          version：版本号
          expand：预留

*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_screenDev_delete_by_serialId(char *serialId)
{
	const char *deleteCmd = "delete from ScreenDeviceInfo where serialId = '%s';";
	char *sqlCmd = NULL;
	int rc = 0;
	char *zErrMsg = 0;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();

	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(deleteCmd,serialId);	
	rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
	if( rc != SQLITE_OK ){
		ERROR_PRINT("SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}else{
		//INFO_PRINT("Table delete data successfully\n");
	}
	sqlite3_free(sqlCmd);
	_kk_subDb_unlock();
	return SUCCESS_RETURN;
}

/************************************************************
*功能描述：获取屏类列表
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_get_screenDev_list(ScreenDevInfo_t*list)
{
	const char *searchCmd = "select * from ScreenDeviceInfo";
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	char *pSerialId = NULL;
	char *pIp = NULL;
	char *pDevName = NULL;
	char *pMac = NULL;
	char *pRoomId = NULL;	
	char *pVer = NULL;	
	int type = 0;
	int count = 0;
	_kk_subDb_lock();
	sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pSerialId = (char*)sqlite3_column_text(stmt, DB_SCREEN_SERIALID);
		pIp = (char*)sqlite3_column_text(stmt, DB_SCREEN_IP);
		pDevName = (char*)sqlite3_column_text(stmt, DB_SCREEN_NAME);
		pRoomId = (char*)sqlite3_column_text(stmt, DB_SCREEN_ROOMID);		
		pMac = (char*)sqlite3_column_text(stmt, DB_SCREEN_MAC);	
		pVer = (char*)sqlite3_column_text(stmt, DB_SCREEN_VERSION);			
		type = sqlite3_column_int(stmt, DB_SCREEN_TYPE);
		//printf("currentValue:%d\n",currentValue);
		memcpy(list[count].serialId,pSerialId,strlen(pSerialId));
		memcpy(list[count].ip,pIp,strlen(pIp));	
		memcpy(list[count].mac,pMac,strlen(pMac));
		memcpy(list[count].name,pDevName,strlen(pDevName));	
		memcpy(list[count].roomid,pRoomId,strlen(pRoomId));	
		memcpy(list[count].version,pVer,strlen(pVer));						
		list[count].type = type;
		count++;
	}
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	return count;
}
/************************************************************
*功能描述：获取屏类信息
*输入参数：deviceCode:设备deviceCode
          isAuth：1，已注册；0，未注册
*输出参数：无
*返 回 值：0:成功；其他：失败
*其他说明：
*************************************************************/
int kk_get_screenDev_info(ScreenDevInfo_t *devInfo,char*serialId)
{
	const char *searchCmd = "select * from ScreenDeviceInfo where serialId = '%s';";
	char *zErrMsg = 0;
	sqlite3_stmt *stmt;
	kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
	char *pSerialId = NULL;
	char *pIp = NULL;
	char *pDevName = NULL;
	char *pMac = NULL;
	char *pRoomId = NULL;	
	char *pVer = NULL;	
	int type = 0;
	char *sqlCmd = NULL;
	if(devInfo == NULL || serialId == NULL){
		return -1;
	}
	_kk_subDb_lock();
	sqlCmd = sqlite3_mprintf(searchCmd,serialId);
	sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
	while(sqlite3_step(stmt) == SQLITE_ROW){
		pSerialId = (char*)sqlite3_column_text(stmt, DB_SCREEN_SERIALID);
		pIp = (char*)sqlite3_column_text(stmt, DB_SCREEN_IP);
		pDevName = (char*)sqlite3_column_text(stmt, DB_SCREEN_NAME);
		pRoomId = (char*)sqlite3_column_text(stmt, DB_SCREEN_ROOMID);		
		pMac = (char*)sqlite3_column_text(stmt, DB_SCREEN_MAC);	
		pVer = (char*)sqlite3_column_text(stmt, DB_SCREEN_VERSION);			
		type = sqlite3_column_int(stmt, DB_SCREEN_TYPE);
		//printf("currentValue:%d\n",currentValue);
		memcpy(devInfo->serialId,pSerialId,strlen(pSerialId));
		memcpy(devInfo->ip,pIp,strlen(pIp));	
		memcpy(devInfo->mac,pMac,strlen(pMac));
		memcpy(devInfo->name,pDevName,strlen(pDevName));	
		memcpy(devInfo->roomid,pRoomId,strlen(pRoomId));	
		memcpy(devInfo->version,pVer,strlen(pVer));	
		devInfo->type = type;
		break;					
	}
	sqlite3_finalize(stmt);
	_kk_subDb_unlock();
	sqlite3_free(sqlCmd);
	return 0;
}