#include <stdio.h>
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "kk_voice_panel_cfg.h"
#include "kk_ccu_msg.h"
#include "kk_lan_node_db.h"
#include "kk_voice_panel_handle.h"
#ifdef VOICE_SUPPORT
static _OUT int node_id_check(_IN cJSON *zbDevsAry,_IN const char *id);



_OUT cJSON *scenes_ary_build(_IN int num,_IN VP_SCENE_ITEM list[]);
_OUT cJSON *rooms_ary_build(_IN int num,_IN VP_ROOM_ITEM list[]);
_OUT cJSON *ac_indoors_ary_build(_IN int num,_IN VP_AC_INDOOR_ITEM list[]);
_OUT cJSON *gws_ary_build(_IN int num,_IN VP_GW_ITEM list[]);


static pthread_mutex_t *mutex;

void kk_vp_ac_mutex_init(void)
{
	mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
	if (0 != pthread_mutex_init(mutex, NULL)) {
		free(mutex);
	}
}

static _OUT cJSON *zigbee_devices_item_build(_IN VP_ZB_DEV_ITEM *item);



static _OUT int kk_vp_get_room_id_by_scene_id(_IN cJSON *data,_IN const char *scene_id,_IN int size,_OUT char *buf)
{
	cJSON *roomsAry = NULL;
	cJSON *roomObj = NULL;
	cJSON *roomId = NULL,*scenes = NULL;
	cJSON *sceneItem = NULL,*sceneId = NULL;
			
	int i,j;
	int roomNum = 0;
	int sceneNum = 0;


			

	if(scene_id==NULL ){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return 0;
	}

	if((roomsAry = cJSON_GetObjectItem(data,ROOMS_STR))==NULL||
		roomsAry->type!=cJSON_Array){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return 0;
	}
	
	
	roomNum = cJSON_GetArraySize(roomsAry);
	//printf("[%s][%d]roomNum=%d,scene_id=%s\n",__FUNCTION__,__LINE__,roomNum,scene_id);
	for(i=0;i<roomNum;i++){
		roomObj = cJSON_GetArrayItem(roomsAry,i);
		if(roomObj->type!=cJSON_Object){
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			continue ;
		}
		roomId = cJSON_GetObjectItem(roomObj,ROOMS_ID_STR);
		scenes= cJSON_GetObjectItem(roomObj,SCENES_STR);
		
		if(roomId==NULL||roomId->type!=cJSON_String||
			scenes==NULL||scenes->type!=cJSON_Array){
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			continue ;
		}
		
		sceneNum = cJSON_GetArraySize(scenes);
		//printf("[%s][%d]sceneNum=%d\n",__FUNCTION__,__LINE__,sceneNum);
		for(j=0;j<sceneNum;j++){
			sceneItem = cJSON_GetArrayItem(scenes,j);
			if((sceneId = cJSON_GetObjectItem(sceneItem,"sceneId"))==NULL ||
				sceneId->type!=cJSON_String){
				//printf("[%s][%d]sceneId->type=%d\n",__FUNCTION__,__LINE__,sceneId->type);
				continue ;
			}
			//printf("[%s][%d]%d,%d,%s,%s\n",__FUNCTION__,__LINE__,strlen(sceneId->valuestring),strlen(scene_id),
			//	scene_id,sceneId->valuestring);

			if(strlen(sceneId->valuestring)==strlen(scene_id) &&
				!strcmp(sceneId->valuestring,scene_id)) {
				memset(buf,0,size);
				snprintf(buf,size,"%s",roomId->valuestring);
				//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
				return 1;
			}
		}
	}
	//printf("[%s][%d]\n",__FUNCTION__,__LINE__);

	return 0;
}



static _OUT cJSON *kk_vp_sync_rooms(_IN cJSON *data)
{
	cJSON *roomsAry = NULL;
	cJSON *roomObj = NULL;
	cJSON *roomId = NULL,*name = NULL;

	VP_ROOM_ITEM *roomsItems = NULL;
	VP_ROOM_ITEM* pRoomItem = NULL;
	int i,roomNum = 0;

	if((roomsAry = cJSON_GetObjectItem(data,ROOMS_STR))==NULL||
		roomsAry->type!=cJSON_Array){
		return rooms_ary_build(0,NULL);
	}

	if((roomNum = cJSON_GetArraySize(roomsAry))==0){
		return rooms_ary_build(0,NULL);
	}

	roomsItems = (VP_ROOM_ITEM*)malloc(sizeof(VP_ROOM_ITEM)*roomNum);
	memset(roomsItems,0,(sizeof(VP_ROOM_ITEM)*roomNum));
	pRoomItem = roomsItems;

	for(i=0;i<roomNum;i++,pRoomItem++){
		if((roomObj = cJSON_GetArrayItem(roomsAry,i))==NULL||
			roomObj->type!=cJSON_Object){
			continue ;
		}
		
		roomId = cJSON_GetObjectItem(roomObj,ROOMS_ID_STR);
		name = cJSON_GetObjectItem(roomObj,NAME_STR);

		if(roomId==NULL||roomId->type!=cJSON_String||
			name==NULL||name->type!=cJSON_String){
			continue ;
		}
		
		snprintf(pRoomItem->id,sizeof(pRoomItem->id)-1,"%s",roomId->valuestring);
		snprintf(pRoomItem->name,sizeof(pRoomItem->name)-1,"%s",name->valuestring);
	}

	roomsAry = rooms_ary_build(roomNum,roomsItems);
	free(roomsItems);
	
	return roomsAry;
}

static _OUT cJSON *kk_vp_sync_scences(_IN cJSON *data)
{
	int i,sceneNum = 0;

	cJSON *scenesAry = NULL;

	cJSON *scenes = NULL;
	cJSON *sceneName = NULL,*sceneId = NULL,*sceneType = NULL;
	cJSON *item = NULL;
	char roomId[32] = {0};

	VP_SCENE_ITEM *pSceneList = NULL;
	VP_SCENE_ITEM *pScene = NULL;
	//
	if((scenes = cJSON_GetObjectItem(data,SCENES_STR))==NULL||
		scenes->type!=cJSON_Array){
		////printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return scenes_ary_build(0,NULL);
	}

	if((sceneNum = cJSON_GetArraySize(scenes))==0){
		////printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return scenes_ary_build(0,NULL);
	}

	pSceneList = (VP_SCENE_ITEM *)malloc(sizeof(VP_SCENE_ITEM)*sceneNum);
	memset(pSceneList,0,sizeof(VP_SCENE_ITEM)*sceneNum);
	pScene = pSceneList;


	vp_scene_id_map_deinit();
	for(i=0;i<sceneNum;i++,pScene++){
		item = cJSON_GetArrayItem(scenes,i);

		sceneId= cJSON_GetObjectItem(item,SCENE_ID_STR);
		sceneType= cJSON_GetObjectItem(item,SCENE_TYPE_STR);
		sceneName = cJSON_GetObjectItem(item,NAME_STR);

		if(sceneId==NULL||sceneId->type!=cJSON_String||
			sceneType==NULL||sceneType->type!=cJSON_Number||
			sceneName==NULL||sceneName->type!=cJSON_String){
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			continue ;
		}
			
		
		if(kk_vp_get_room_id_by_scene_id(data,sceneId->valuestring,sizeof(roomId),roomId)!=0){

			int map_id = vp_scene_id_item_add(atoi(sceneId->valuestring));
			
			snprintf(pScene->room,sizeof(pScene->room)-1,"%s",roomId);
			snprintf(pScene->id,sizeof(pScene->id)-1,"%d",map_id);
			snprintf(pScene->type,sizeof(pScene->type)-1,"%d",sceneType->valueint);
			snprintf(pScene->name,sizeof(pScene->name)-1,"%s",sceneName->valuestring);
			debug_log(LOG_NOTICE_LEVEL,"[%d]map_id=%d.\n",i,map_id);
		}
	}
	vp_scene_id_map_save();

	scenesAry = scenes_ary_build(sceneNum,pSceneList);

	free(pSceneList);
	return scenesAry;
}




static int kk_vp_get_device_name(_IN cJSON *devices,_IN const char*epNum,_IN const char*deviceCode,_IN int multi,_IN int size,_OUT char *buf)
{
	int i = 0,devNum = 0;
	cJSON *name = NULL;
	cJSON *epNumObj = NULL;
	cJSON *deviceItem = NULL,*devCodeObj = NULL;

	devNum = cJSON_GetArraySize(devices);
	printf("[%s][%d]devNum=%d\n",__FUNCTION__,__LINE__,devNum);
	for(i=0;i<devNum;i++){
		deviceItem = cJSON_GetArrayItem(devices,i);
		if(deviceItem->type!=cJSON_Object){
			printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			continue ;
		}

		
		devCodeObj = cJSON_GetObjectItem(deviceItem,"deviceCode");

		if(devCodeObj==NULL||devCodeObj->type!=cJSON_String){
			continue ;
		}
		//printf("[%s][%d]%d,%d,%s,%s\n",__FUNCTION__,__LINE__,strlen(devCodeObj->valuestring),strlen(deviceCode),devCodeObj->valuestring,deviceCode);
		if((strlen(devCodeObj->valuestring)==strlen(deviceCode)) &&
			!strcmp(devCodeObj->valuestring,deviceCode)){

			if((name = cJSON_GetObjectItem(deviceItem,"name"))!=NULL &&
				name->type==cJSON_String){
				printf("[%s][%d]name=%s\n",__FUNCTION__,__LINE__,name->valuestring);

				if((epNumObj = cJSON_GetObjectItem(deviceItem,"epNum"))!=NULL){
					if(multi!=0){
						if(epNumObj->type==cJSON_String &&
							!strcmp(epNumObj->valuestring,epNum)){
							snprintf(buf,size,"%s",name->valuestring);
							return 1;
						}
					}else{
						if(epNumObj->type==cJSON_String &&
							!strcmp(epNumObj->valuestring,"1")){
							snprintf(buf,size,"%s",name->valuestring);
							return 1;
						}
						return 1;
					}
				}else{
					snprintf(buf,size,"%s",name->valuestring);
					return 1;
				}
			}
		}
	}
	return 0;
}


static int kk_vp_get_device_info(_IN cJSON *rooms,_IN VP_ZB_DEV_ITEM *pDevs,_IN int multi)
{
	cJSON *roomItem = NULL;
	cJSON *roomId = NULL,*devices = NULL;

	int i = 0,roomNum = 0,isFind = 0;



	roomNum = cJSON_GetArraySize(rooms);
	//printf("[%s][%d]roomNum=%d\n",__FUNCTION__,__LINE__,roomNum);
	for(i=0;i<roomNum;i++){
		roomItem = cJSON_GetArrayItem(rooms,i);

		if((roomId = cJSON_GetObjectItem(roomItem,ROOMS_ID_STR))==NULL||
			roomId->type!=cJSON_String){
			//printf("[prase fail]roomId...\n");
			continue ;
		}

		if((devices= cJSON_GetObjectItem(roomItem,DEVICES_STR))==NULL ||
			devices->type!=cJSON_Array){
			//printf("[prase fail]devices...\n");
			continue ;
		}
			
		isFind = kk_vp_get_device_name(devices,pDevs->ch,pDevs->mac,multi,sizeof(pDevs->name),pDevs->name);

		if(!strcmp(pDevs->name,"")){
			if(is_ac_gw_pid(atoi(pDevs->pid))!=0){
				snprintf(pDevs->name,sizeof(pDevs->name),"%s","空调网关");
			}
		}
		
		if(isFind!=0){
			snprintf(pDevs->room,sizeof(pDevs->room),"%s",roomId->valuestring);
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			return isFind;
		}
		
	}
	//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	return 0;
}


static int kk_vp_sync_device_multi_eps(_IN cJSON *zbDevsAry,_IN cJSON *dev,_IN cJSON *rooms,_IN cJSON *eps)
{
	int nodeId;
	kk_map_dev_node_t *node = NULL;

	VP_ZB_DEV_ITEM *pDevs = NULL;
	cJSON *zbDevObj = NULL;
	cJSON *mac = NULL,*onlineStatus = NULL,*productCode = NULL;
	cJSON *epItem = NULL,*epNum = NULL;
	int i = 0,num = 0,isFind = 0;
	
		
	pDevs = (VP_ZB_DEV_ITEM *)malloc(sizeof(VP_ZB_DEV_ITEM));
	memset(pDevs,0,sizeof(VP_ZB_DEV_ITEM));
	
	mac = cJSON_GetObjectItem(dev,"mac");
	onlineStatus = cJSON_GetObjectItem(dev,"onlineStatus");
	productCode = cJSON_GetObjectItem(dev,"productCode");




	if(mac==NULL||mac->type!=cJSON_String){
		snprintf(pDevs->mac,sizeof(pDevs->mac)-1,"%s","0000000000000000");
	}else{
		snprintf(pDevs->mac,sizeof(pDevs->mac)-1,"%s",mac->valuestring);
	}

	if(onlineStatus==NULL||onlineStatus->type!=cJSON_Number){
		snprintf(pDevs->online,sizeof(pDevs->online)-1,"%d",0);
	}else{
		snprintf(pDevs->online,sizeof(pDevs->online)-1,"%d",onlineStatus->valueint);
	}
	
	if(productCode==NULL||productCode->type!=cJSON_String){
		snprintf(pDevs->pid,sizeof(pDevs->pid)-1,"%d",-1);
	}else{
		snprintf(pDevs->pid,sizeof(pDevs->pid)-1,"%s",productCode->valuestring);
	}

	num = cJSON_GetArraySize(eps);
	printf("[%s][%d]num=%d\n",__FUNCTION__,__LINE__,num);
	for(i=0;i<num;i++){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);

		memset(pDevs->ch,0,sizeof(pDevs->ch));
		memset(pDevs->name,0,sizeof(pDevs->name));
		memset(pDevs->room,0,sizeof(pDevs->room));
		
		epItem = cJSON_GetArrayItem(eps,i);

		if((epNum = cJSON_GetObjectItem(epItem,"epNum"))==NULL ||
			epNum->type!=cJSON_String){
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			continue ;
		}
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		snprintf(pDevs->ch,sizeof(pDevs->ch)-1,"%s",epNum->valuestring);


		nodeId = kk_lan_db_node_get(pDevs->mac,atoi(pDevs->ch));

		snprintf(pDevs->nodeId,sizeof(pDevs->nodeId)-1,"%d",nodeId);


		if(kk_map_dev_search_by_deviceCode(pDevs->mac,&node) == 0){
			/*if(strcmp(pDevs->online,"1")==0){
				node->online_status = 1;
			}else{
				node->online_status = 0;
			}*/
			snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s",node->opearteType);
		}else{

			if(is_ac_gw_pid(atoi(pDevs->pid))!=0){
				snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s","12008");
			}else{

				snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s","1");
			}
		}

		printf("pDevs->mac=%s,pDevs->ch=%s,pDevs->nodeId=%s\n",pDevs->mac,pDevs->ch,pDevs->nodeId);
		if(kk_vp_get_device_info(rooms,pDevs,1)!=0){
			
			if(node_id_check(zbDevsAry,pDevs->nodeId)==0){
				if((zbDevObj = zigbee_devices_item_build(pDevs))!=NULL){
					cJSON_AddItemToArray(zbDevsAry,zbDevObj);
	
					isFind = 1;
				}
			}
		}
	}
	
	free(pDevs);
	//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	return isFind;
}



static int kk_vp_sync_device_single_ep(_IN cJSON *zbDevsAry,_IN cJSON *dev,_IN cJSON *rooms)
{
	int nodeId;
	kk_map_dev_node_t *node = NULL;

	VP_ZB_DEV_ITEM *pDevs = NULL;
	cJSON *zbDevObj = NULL;
	cJSON *mac = NULL,*onlineStatus = NULL,*productCode = NULL;

	pDevs = (VP_ZB_DEV_ITEM *)malloc(sizeof(VP_ZB_DEV_ITEM));
	memset(pDevs,0,sizeof(VP_ZB_DEV_ITEM));
	
	mac = cJSON_GetObjectItem(dev,"mac");
	onlineStatus = cJSON_GetObjectItem(dev,"onlineStatus");
	productCode = cJSON_GetObjectItem(dev,"productCode");


	snprintf(pDevs->ch,sizeof(pDevs->ch)-1,"%d",1);

	if(mac==NULL||mac->type!=cJSON_String){
		snprintf(pDevs->mac,sizeof(pDevs->mac)-1,"%s","0000000000000000");
	}else{
		snprintf(pDevs->mac,sizeof(pDevs->mac)-1,"%s",mac->valuestring);
	}

	if(onlineStatus==NULL||onlineStatus->type!=cJSON_Number){
		snprintf(pDevs->online,sizeof(pDevs->online)-1,"%d",0);
	}else{
		snprintf(pDevs->online,sizeof(pDevs->online)-1,"%d",onlineStatus->valueint);
	}
	
	if(productCode==NULL||productCode->type!=cJSON_String){
		snprintf(pDevs->pid,sizeof(pDevs->pid)-1,"%d",-1);
	}else{
		snprintf(pDevs->pid,sizeof(pDevs->pid)-1,"%s",productCode->valuestring);
	}


	nodeId = kk_lan_db_node_get(pDevs->mac,atoi(pDevs->ch));
	
	snprintf(pDevs->nodeId,sizeof(pDevs->nodeId)-1,"%d",nodeId);


	if(kk_map_dev_search_by_deviceCode(pDevs->mac,&node) == 0){
		snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s",node->opearteType);

		/*if(strcmp(pDevs->online,"1")==0){
			node->online_status = 1;
		}else{
			node->online_status = 0;
		}*/
	}else{
		if(is_ac_gw_pid(atoi(pDevs->pid))!=0){

			snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s","12008");
		}else{
			snprintf(pDevs->operateType,sizeof(pDevs->operateType)-1,"%s","1");
		}
	}
	

	if(kk_vp_get_device_info(rooms,pDevs,0)!=0){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		if((zbDevObj = zigbee_devices_item_build(pDevs))!=NULL){
			cJSON_AddItemToArray(zbDevsAry,zbDevObj);
			free(pDevs);
			//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			return 1;
		}
	}
	
	free(pDevs);
	//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	return 0;
}


#define VP_AC_GW_MAX_DEVICE_NUMBER						5
#define VP_AC_GW_INDOOR_MAX_DEVICE_NUMBER				16

static const int ac_gw_pid[]={3062};

typedef struct{
	int insert;
	char mac[17];
}AC_GW_TABLE_S;
static AC_GW_TABLE_S ac_gw_mac[VP_AC_GW_MAX_DEVICE_NUMBER];


static void ac_gw_table_init(void)
{
	memset(ac_gw_mac,0,sizeof(ac_gw_mac));
}

static int ac_gw_table_insert(const char* mac)
{
	int i;
	for(i=0;i<VP_AC_GW_MAX_DEVICE_NUMBER;i++){
		if(ac_gw_mac[i].insert==0){
			snprintf(ac_gw_mac[i].mac,17,"%s",mac);
			ac_gw_mac[i].insert = 1;

			debug_log(LOG_DEBUG_LEVEL,"[insert suc] index=%d,mac=%s\n",i,ac_gw_mac[i].mac);
			return 0;
		}
	}
	debug_log(LOG_DEBUG_LEVEL,"[insert fail] no space!mac=%s\n",ac_gw_mac[i].mac);
	return -1;
}

static int ac_gw_table_find(const char* mac)
{
	int i;
	if(mac==NULL){
		return 0;
	}
	for(i=0;i<VP_AC_GW_MAX_DEVICE_NUMBER;i++){
		if(ac_gw_mac[i].insert!=0){
			if(!strcmp(mac,ac_gw_mac[i].mac)){
				return 1;
			}
		}
	}
	
	return 0;
}

static int ac_gw_table_handle(cJSON *productCode,cJSON *mac)
{
	int i;
	int pid = 0;
	
	if(productCode==NULL||mac==NULL||
		productCode->type!=cJSON_String||mac->type!=cJSON_String){
		return 0;
	}

	pid = atoi(productCode->valuestring);
	for(i=0;i<sizeof(ac_gw_pid)/sizeof(int);i++){
		if(pid==ac_gw_pid[i]){
			ac_gw_table_insert(mac->valuestring);
			return 1;
		}
	}
	return 0;
}

int is_ac_gw_pid(int pid)
{
	int i;

	for(i=0;i<sizeof(ac_gw_pid)/sizeof(int);i++){
		if(pid==ac_gw_pid[i]){
			return 1;
		}
	}
	return 0;
}

static _OUT cJSON *kk_vp_sync_device(_IN cJSON *data)
{
	int i,j;
	int isAcGw = 0;

	cJSON *zbDevsAry = NULL;

	int devicesAryNum = 0;
	int subDevAryNum = 0;
	cJSON *devicesAry = NULL;
	cJSON *devicesAryItem = NULL;
	cJSON *subDevAry = NULL;

	cJSON *roomsAry = NULL;
	
	cJSON *dev = NULL;
	cJSON *properties = NULL;
	cJSON *eps = NULL;

	cJSON *productCode = NULL;
	cJSON *mac = NULL;


	if((zbDevsAry  = cJSON_CreateArray())==NULL){
		printf("[cJSON_CreateArray err]zbDevsAry...\n");
		return NULL;
	}
	
	devicesAry = cJSON_GetObjectItem(data,DEVICES_STR);

	if(devicesAry==NULL ||
		devicesAry->type!=cJSON_Array){
		return zbDevsAry;
	}

	devicesAryNum = cJSON_GetArraySize(devicesAry);
		

	for(i=0;i<devicesAryNum;i++){
		devicesAryItem = cJSON_GetArrayItem(devicesAry,i);

		if(devicesAryItem==NULL||devicesAryItem->type!=cJSON_Object){
			printf("[prase fail]devicesAryItem...\n");
			continue;
		}
	
		subDevAry = cJSON_GetObjectItem(devicesAryItem,DEVICES_STR);
		if(subDevAry==NULL||subDevAry->type!=cJSON_Array){
			printf("[prase fail]subDevAry...\n");
			continue;
		}
		subDevAryNum = cJSON_GetArraySize(subDevAry);


		
		for(j=0;j<subDevAryNum;j++){
		
			if((dev = cJSON_GetArrayItem(subDevAry,j))==NULL||
				dev->type!=cJSON_Object){
				printf("[prase fail]dev...\n");
				continue ;
			}

			productCode= cJSON_GetObjectItem(dev,"productCode");
			mac= cJSON_GetObjectItem(dev,"mac");


			pthread_mutex_lock(mutex);
			isAcGw = ac_gw_table_handle(productCode,mac);
			pthread_mutex_unlock(mutex);


			if(isAcGw!=0){
				roomsAry = cJSON_GetObjectItem(data,ROOMS_STR);
				if(roomsAry==NULL||roomsAry->type!=cJSON_Array){
					printf("[prase fail]roomsAry...\n");
					continue ;
				}
				kk_vp_sync_device_single_ep(zbDevsAry,dev,roomsAry);
			}else{
				if((properties = cJSON_GetObjectItem(dev,"properties"))==NULL||
						properties->type!=cJSON_Object){
					printf("[prase fail]properties...\n");
					continue ;
				}
	
				eps = cJSON_GetObjectItem(properties,"eps");
	
			
	
				roomsAry = cJSON_GetObjectItem(data,ROOMS_STR);
				if(roomsAry==NULL||roomsAry->type!=cJSON_Array){
					printf("[prase fail]roomsAry...\n");
					continue ;
				}
	
				if(eps==NULL){
					printf("[%s][%d]---------------->\n",__FUNCTION__,__LINE__);
					kk_vp_sync_device_single_ep(zbDevsAry,dev,roomsAry);
				}else if(eps->type==cJSON_Array){
					printf("[%s][%d]---------------->\n",__FUNCTION__,__LINE__);
					kk_vp_sync_device_multi_eps(zbDevsAry,dev,roomsAry,eps);
				}

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

	return zbDevsAry;
}


static _OUT cJSON *kk_vp_sync_gws(_IN cJSON *data)
{
	int i,gw_num = 0;

	cJSON *gwAry = NULL;

	cJSON *devicesAry = NULL;
	cJSON *item = NULL,*gw_mac = NULL,*gw_name = NULL;
	VP_GW_ITEM *gws = NULL;

	if((devicesAry = cJSON_GetObjectItem(data,DEVICES_STR)) == NULL
		||devicesAry->type!=cJSON_Array){
		return gws_ary_build(0,NULL);
	}

	if((gw_num = cJSON_GetArraySize(devicesAry))==0){
		return gws_ary_build(0,NULL);
	}

	gws = (VP_GW_ITEM *)malloc(sizeof(VP_GW_ITEM)*gw_num);
	memset(gws,0,sizeof(VP_GW_ITEM)*gw_num);
		
	for(i=0;i<gw_num;i++){
		if((item = cJSON_GetArrayItem(devicesAry,i))==NULL||
			item->type!=cJSON_Object){
			continue ;
		}
		gw_mac = cJSON_GetObjectItem(item,"mac");
		gw_name = cJSON_GetObjectItem(item,"name");

		if(gw_mac==NULL||gw_mac->type!=cJSON_String){
			snprintf(gws->mac,sizeof(gws->mac)-1,"%016d",i);
		}else {
			snprintf(gws->mac,sizeof(gws->mac)-1,"%s",gw_mac->valuestring);
		}

		if(gw_name==NULL||gw_name->type!=cJSON_String){
			snprintf(gws->name,sizeof(gws->name)-1,"gw%d",i);
		}else {
			snprintf(gws->name,sizeof(gws->name)-1,"%s",gw_name->valuestring);
		}
		
		snprintf(gws->nodeId,sizeof(gws->nodeId)-1,"%d",0);
	}

	gwAry = gws_ary_build(gw_num,gws);
	free(gws);
	return gwAry;
}

static _OUT cJSON *kk_vp_sync_ac_indoors(_IN cJSON *data)
{
	cJSON *roomsAry = NULL;
	
	cJSON *roomObj = NULL;
	cJSON *roomId = NULL,*room_name = NULL;
	cJSON *devsAry = NULL,*devObj = NULL;
	cJSON *dev_name = NULL,*epNum = NULL,*deviceCode = NULL;


	
	
	VP_AC_INDOOR_ITEM *indoorList = NULL;
	VP_AC_INDOOR_ITEM* pIndoorItem = NULL;
	int i,j,roomNum = 0,devNum = 0;
	int node;

	int max_indoor_size = VP_AC_GW_MAX_DEVICE_NUMBER*VP_AC_GW_INDOOR_MAX_DEVICE_NUMBER;
	int indoor_num = 0;

	if((roomsAry = cJSON_GetObjectItem(data,ROOMS_STR))==NULL||
		roomsAry->type!=cJSON_Array){
		return ac_indoors_ary_build(0,NULL);
	}

	if((roomNum = cJSON_GetArraySize(roomsAry))==0){
		return ac_indoors_ary_build(0,NULL);
	}

	indoorList = (VP_AC_INDOOR_ITEM*)malloc(sizeof(VP_AC_INDOOR_ITEM)*VP_AC_GW_MAX_DEVICE_NUMBER*VP_AC_GW_INDOOR_MAX_DEVICE_NUMBER);
	memset(indoorList,0,sizeof(VP_AC_INDOOR_ITEM)*VP_AC_GW_MAX_DEVICE_NUMBER*VP_AC_GW_INDOOR_MAX_DEVICE_NUMBER);
	pIndoorItem = indoorList;

	for(i=0;i<roomNum;i++){
		if((roomObj = cJSON_GetArrayItem(roomsAry,i))==NULL||
			roomObj->type!=cJSON_Object){
			continue ;
		}
		
		roomId = cJSON_GetObjectItem(roomObj,ROOMS_ID_STR);
		room_name = cJSON_GetObjectItem(roomObj,NAME_STR);
		
		if(roomId==NULL||roomId->type!=cJSON_String||
			room_name==NULL||room_name->type!=cJSON_String){
			continue ;
		}

		if((devsAry = cJSON_GetObjectItem(roomObj,DEVICES_STR))==NULL&&
			devsAry->type!=cJSON_Array){
			continue ;
		}

		if((devNum = cJSON_GetArraySize(devsAry))==0){
			continue ;
		}
		
		for(j=0;j<devNum;j++){
			devObj = cJSON_GetArrayItem(devsAry,j);
			
			
			if((deviceCode = cJSON_GetObjectItem(devObj,"deviceCode"))==NULL||
				deviceCode->type!=cJSON_String){
				continue;
			}

			pthread_mutex_lock(mutex);
			if(ac_gw_table_find(deviceCode->valuestring)!=0){
				pthread_mutex_unlock(mutex);
				dev_name = cJSON_GetObjectItem(devObj,NAME_STR);
				epNum = cJSON_GetObjectItem(devObj,"epNum");
				if(dev_name->type!=cJSON_String ||
					epNum->type!=cJSON_String||
					!strcmp(epNum->valuestring,"1")){
					continue ;
				}
				debug_log(LOG_DEBUG_LEVEL,"deviceCode=%s,epNum=%s,dev_name=%s",deviceCode->valuestring,epNum->valuestring,dev_name->valuestring);

				pIndoorItem->online = 1;

				node = kk_lan_db_node_get(deviceCode->valuestring,1);
				snprintf(pIndoorItem->ac_gw_nodeId,sizeof(pIndoorItem->ac_gw_nodeId),"%d",node);
				node = kk_lan_db_node_get(deviceCode->valuestring,atoi(epNum->valuestring));
				snprintf(pIndoorItem->nodeId,sizeof(pIndoorItem->nodeId),"%d",node);
				
				snprintf(pIndoorItem->addr,sizeof(pIndoorItem->addr),"%s",epNum->valuestring);
				snprintf(pIndoorItem->operateType,sizeof(pIndoorItem->operateType),"%s","-5");
				snprintf(pIndoorItem->name,sizeof(pIndoorItem->name),"%s",dev_name->valuestring);
				snprintf(pIndoorItem->room,sizeof(pIndoorItem->room),"%s",roomId->valuestring);

				indoor_num+=1;
				++pIndoorItem;
			}
			pthread_mutex_unlock(mutex);
		}

	}


	roomsAry = ac_indoors_ary_build(indoor_num,indoorList);
	free(indoorList);
	
	return roomsAry;


}

//保留
static _OUT cJSON *infrared_codelib_info_ary_build(_IN cJSON *data)
{
	cJSON *resAry = cJSON_CreateArray();
	return resAry;
}

//保留
static _OUT cJSON *controller_buttons_config_build(_IN cJSON *data)
{
	return cJSON_CreateNull();
}




_OUT cJSON * kk_voice_panel_cfg_build(_IN VP_CFG_JSON *arg,int ver)
{
	cJSON *root = NULL;
	cJSON *params = NULL;

	if(arg == NULL || arg->controller_buttons_config == NULL ||
		arg->gws == NULL ||arg->infrared_codelib_info == NULL ||
		arg->other_devices == NULL ||arg->rooms == NULL ||
		arg->scenes == NULL ||arg->zigbee_devices == NULL){
		return root;
	}
		
	if((root = cJSON_CreateObject())!=NULL){
		if((params = cJSON_CreateObject())!=NULL) {
	
			cJSON_AddItemToObject(params,"controller_buttons_config",arg->controller_buttons_config);

			cJSON_AddItemToObject(params,"gws",arg->gws);
	
			cJSON_AddItemToObject(params,"infrared_codelib_info",arg->infrared_codelib_info);
		
			cJSON_AddItemToObject(params,"other_devices",arg->other_devices);
		
			cJSON_AddItemToObject(params,"rooms",arg->rooms);
		
			cJSON_AddItemToObject(params,"scenes",arg->scenes);
	
			cJSON_AddItemToObject(params,"zigbee_devices",arg->zigbee_devices);

			cJSON_AddItemToObject(root, "params",params);

		}
		
		cJSON_AddNumberToObject(root, "version",ver);
	}

	

	return root;
}




static _OUT int node_id_check(_IN cJSON *zbDevsAry,_IN const char *id)
{
	int itemNum;
	int chansItemNum;
	int i,j;
	cJSON *itemObj = NULL;
	cJSON *chans = NULL;
	cJSON *chansItem = NULL;
	cJSON *idObj = NULL;

	if(zbDevsAry==NULL||zbDevsAry->type!=cJSON_Array){
		return 0;
	}
	
	itemNum = cJSON_GetArraySize(zbDevsAry);
	for(i=0;i<itemNum;i++){
		if((itemObj = cJSON_GetArrayItem(zbDevsAry, i))==NULL||
			itemObj->type!=cJSON_Object){
			continue;
		}

		if((chans = cJSON_GetObjectItem(itemObj,"chans"))==NULL||
			chans->type!=cJSON_Array){
			continue;
		}

		chansItemNum = cJSON_GetArraySize(chans);
		for(j=0;j<chansItemNum;j++){
			if((chansItem = cJSON_GetArrayItem(chans, j))==NULL||
				chansItem->type!=cJSON_Object){
				continue;
			}
				
			if((idObj = cJSON_GetObjectItem(chansItem,"id"))==NULL||
				idObj->type!=cJSON_String){
				continue;
			}

			if(!strcmp(id,idObj->valuestring)){
				return 1;
			}

		}

	}
	
	return 0;
}



static _OUT cJSON *zigbee_devices_item_build(_IN VP_ZB_DEV_ITEM *item)
{
	cJSON *devItemObj = NULL;
	cJSON *chansAry = NULL;

	if(item == NULL ||item->operateType==NULL||item->nodeId==NULL||
		item->name==NULL||item->room == NULL||item->mac == NULL||
		item->online == NULL||item->pid == NULL){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return NULL;
	}

	if((devItemObj = cJSON_CreateObject())!=NULL) {
		if((chansAry = cJSON_CreateArray())!=NULL){
			cJSON *chansItem = cJSON_CreateObject();
			cJSON_AddStringToObject(chansItem, "oid",item->operateType);
			cJSON_AddStringToObject(chansItem, "id",item->nodeId);
			cJSON_AddStringToObject(chansItem, "name",item->name);
			cJSON_AddStringToObject(chansItem, "room",item->room);
			cJSON_AddStringToObject(chansItem, "chan",item->ch);
			
			cJSON_AddItemToArray(chansAry,chansItem);
			cJSON_AddItemToObject(devItemObj, "chans", chansAry);
		}
		
		cJSON_AddStringToObject(devItemObj, "mac",item->mac);
	
		cJSON_AddStringToObject(devItemObj, "online",item->online);
		cJSON_AddStringToObject(devItemObj, "pid",item->pid);
		cJSON_AddStringToObject(devItemObj, "gw","1");
		cJSON_AddStringToObject(devItemObj, "zaddr","0000");
		cJSON_AddStringToObject(devItemObj, "mid","00000000");
	}
	return devItemObj;
}


_OUT cJSON *zigbee_devices_ary_build(_IN int num,_IN VP_ZB_DEV_ITEM list[])
{
	int i = 0;
	cJSON *zbDevsAry = NULL;
	cJSON *zbDevObj = NULL;
	VP_ZB_DEV_ITEM *pItem = NULL;
	zbDevsAry = cJSON_CreateArray();
	
	if(list==NULL || num==0){
		return zbDevsAry;
	}
	
	pItem = (VP_ZB_DEV_ITEM *)list;

	for(i=0;i<num;i++,pItem++){
		if((zbDevObj = zigbee_devices_item_build(pItem))!=NULL){
			cJSON_AddItemToArray(zbDevsAry,zbDevObj);
		}
	}

	return zbDevsAry;
}



static _OUT cJSON *scenes_item_build(_IN VP_SCENE_ITEM *item)
{
	cJSON *sceItemObj = NULL;

	if(item == NULL ||item->id==NULL||item->name==NULL ||
		item->room==NULL||item->type==NULL){
		return NULL;
	}

	if((sceItemObj = cJSON_CreateObject())!=NULL) {
		cJSON_AddStringToObject(sceItemObj, "id",item->id);
		cJSON_AddStringToObject(sceItemObj, "name",item->name);
		cJSON_AddStringToObject(sceItemObj, "room",item->room);
		cJSON_AddStringToObject(sceItemObj, "type",item->type);
	}

	return sceItemObj;
}


_OUT cJSON *scenes_ary_build(_IN int num,_IN VP_SCENE_ITEM list[])
{
	int i = 0;
	cJSON *scenesAry = NULL;
	cJSON *sceneObj = NULL;
	VP_SCENE_ITEM *pItem = NULL;
	scenesAry = cJSON_CreateArray();
	
	if(list==NULL || num==0){
		return scenesAry;
	}
	
	pItem = (VP_SCENE_ITEM *)list;

	for(i=0;i<num;i++,pItem++){
		if((sceneObj = scenes_item_build(pItem))!=NULL){
			cJSON_AddItemToArray(scenesAry,sceneObj);
		}
	}

	return scenesAry;
}

static _OUT cJSON *room_item_build(_IN VP_ROOM_ITEM *item)
{
	cJSON *roomObj = NULL;

	if(item == NULL ||item->id==NULL||item->name==NULL){
		return NULL;
	}

	if((roomObj = cJSON_CreateObject())!=NULL) {
		cJSON_AddStringToObject(roomObj, "id",item->id);
		cJSON_AddStringToObject(roomObj, "name",item->name);

	}

	return roomObj;
}

_OUT cJSON *rooms_ary_build(_IN int num,_IN VP_ROOM_ITEM list[])
{
	int i = 0;
	cJSON *roomsAry = NULL;
	cJSON *roomObj = NULL;
	VP_ROOM_ITEM *pItem = NULL;
	roomsAry = cJSON_CreateArray();
	
	if(list==NULL || num==0){
		return roomsAry;
	}
	
	pItem = (VP_ROOM_ITEM *)list;

	for(i=0;i<num;i++,pItem++){
		if((roomObj = room_item_build(pItem))!=NULL){
			cJSON_AddItemToArray(roomsAry,roomObj);
		}
	}

	return roomsAry;
}

static _OUT cJSON *ac_indoor_item_build(_IN VP_AC_INDOOR_ITEM *item)
{
	cJSON *indoorObj = NULL;

	if(item == NULL ||item->ac_gw_nodeId==NULL||item->addr==NULL ||
		item->nodeId==NULL ||item->name==NULL||item->operateType==NULL||item->room==NULL){
		return NULL;
	}

	if((indoorObj = cJSON_CreateObject())!=NULL) {
		cJSON_AddStringToObject(indoorObj, "ac_gw_id",item->ac_gw_nodeId);
		cJSON_AddStringToObject(indoorObj, "addr",item->addr);
		cJSON_AddStringToObject(indoorObj, "id",item->nodeId);
		cJSON_AddStringToObject(indoorObj, "name",item->name);
		cJSON_AddStringToObject(indoorObj, "oid",item->operateType);
		cJSON_AddStringToObject(indoorObj, "room",item->room);
		cJSON_AddNumberToObject(indoorObj, "online",item->online);
	}

	return indoorObj;
}



_OUT cJSON *ac_indoors_ary_build(_IN int num,_IN VP_AC_INDOOR_ITEM list[])
{
	int i = 0;
	cJSON *acIndoorsAry = NULL;
	cJSON *acIndoorObj = NULL;
	VP_AC_INDOOR_ITEM *pItem = NULL;
	acIndoorsAry = cJSON_CreateArray();
	
	if(list==NULL || num==0){
		return acIndoorsAry;
	}
	
	pItem = (VP_AC_INDOOR_ITEM *)list;

	for(i=0;i<num;i++,pItem++){
		if((acIndoorObj = ac_indoor_item_build(pItem))!=NULL){
			cJSON_AddItemToArray(acIndoorsAry,acIndoorObj);
		}
	}

	return acIndoorsAry;
}






static _OUT cJSON *gw_item_build(_IN VP_GW_ITEM *item)
{
	cJSON *gwObj = NULL;

	if(item == NULL || item->nodeId==NULL||
		item->mac==NULL || item->name==NULL ){
		return NULL;
	}

	if((gwObj = cJSON_CreateObject())!=NULL) {
		cJSON_AddStringToObject(gwObj, "id",item->nodeId);
		cJSON_AddStringToObject(gwObj, "mac",item->mac);
		cJSON_AddStringToObject(gwObj, "name",item->name);
	}

	return gwObj;
}


_OUT cJSON *gws_ary_build(_IN int num,_IN VP_GW_ITEM list[])
{
	int i = 0;
	cJSON *gwsAry = NULL;
	cJSON *gwObj = NULL;
	VP_GW_ITEM *pItem = NULL;
	gwsAry = cJSON_CreateArray();
	
	if(list==NULL || num==0){
		return gwsAry;
	}
	
	pItem = (VP_GW_ITEM *)list;

	for(i=0;i<num;i++,pItem++){
		if((gwObj = gw_item_build(pItem))!=NULL){
			cJSON_AddItemToArray(gwsAry,gwObj);
		}
	}

	return gwsAry;
}







_OUT int kk_vp_syncinfo(_IN cJSON *payload,_IN int ver,_OUT cJSON **root)
{
	VP_CFG_JSON json = {0};

	cJSON *data = NULL;

	if(payload==NULL ||payload->type!=cJSON_Object){
		return -2;
	}

	if((data = cJSON_GetObjectItem(payload,DATA_STR))==NULL ||
		data->type!=cJSON_Object){
		return -1;
	}

	pthread_mutex_lock(mutex);
	ac_gw_table_init();
	pthread_mutex_unlock(mutex);

	

	json.controller_buttons_config = infrared_codelib_info_ary_build(data);
	json.infrared_codelib_info = infrared_codelib_info_ary_build(data);

	json.rooms = kk_vp_sync_rooms(data);
	json.scenes =  kk_vp_sync_scences(data);
	json.gws = kk_vp_sync_gws(data);
	json.zigbee_devices = kk_vp_sync_device(data);
	json.other_devices = kk_vp_sync_ac_indoors(data);

	if((*root = kk_voice_panel_cfg_build(&json,ver))!=NULL){
		//printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		return 0;
	}
	
	//printf("[%s][%d]\n",__FUNCTION__,__LINE__);

	return -1;
}
#endif


















