Commit 79494974 authored by 尹佳钦's avatar 尹佳钦
parents 66fdf9b9 d61a4575
......@@ -11,56 +11,15 @@ typedef struct {
void *mutex;
void *hearbeat_thread;
int hearbeat_thread_running;
//struct list_head dev_list;
struct list_head gw_status_list;
} kk_heartbeat_ctx_t;
#if 0
typedef struct {
unsigned int timerstamp;
int isOnline;
time_t starttime;
char deviceCode[DEVICE_CODE_MAXLEN];
struct list_head linked_list;
} kk_dev_heartbeat_node_t;
static int _kk_add_heartbeat_node(const char* deviceCode,unsigned int timestamp)
{
kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
kk_dev_heartbeat_node_t *node = NULL;
node = malloc(sizeof(kk_dev_heartbeat_node_t));
if (node == NULL) {
return MEMORY_NOT_ENOUGH;
}
_kk_heartbeat_lock();
memset(node,0x0,sizeof(kk_dev_heartbeat_node_t));
memcpy(node->deviceCode,deviceCode,strlen(deviceCode));
node->timerstamp = timestamp;
INIT_LIST_HEAD(&node->linked_list);
list_add_tail(&node->linked_list, &ctx->dev_list);
_kk_heartbeat_unlock();
return SUCCESS_RETURN;
}
int kk_heartbeat_update_time(const char deviceCode[DEVICE_CODE_MAXLEN],unsigned int timestamp)
{
kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
kk_dev_heartbeat_node_t *search_node = NULL;
_kk_heartbeat_lock();
list_for_each_entry(search_node, &ctx->dev_list, linked_list, kk_dev_heartbeat_node_t) {
if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
search_node->timerstamp = timestamp;
_kk_heartbeat_unlock();
return SUCCESS_RETURN;
}
}
_kk_add_heartbeat_node(deviceCode,timestamp);
_kk_heartbeat_unlock();
return FAIL_RETURN;
}
#endif
} kk_gw_status_ctx_t;
static kk_heartbeat_ctx_t s_kk_heartbeat_ctx = {0};
static kk_heartbeat_ctx_t *_kk_heartbeat_get_ctx(void)
......@@ -87,14 +46,50 @@ uint64_t s_start_time = 0;
void *kk_heartbeat_yield(void *args)
{
kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
uint64_t current_time = 0;
dm_mgr_dev_node_t *search_node = NULL;
time_t current_time = 0;
int res = 0;
dm_mgr_dev_node_t *node = NULL;
kk_gw_status_ctx_t *gw = NULL;
while (ctx->hearbeat_thread_running) {
current_time = HAL_UptimeMs() - s_start_time;
current_time = HAL_GetTime();
_kk_heartbeat_lock();
dm_mgr_check_heartbeat_timeout(current_time);
if (!list_empty(&ctx->gw_status_list)) {
list_for_each_entry(gw, &ctx->gw_status_list, linked_list, kk_gw_status_ctx_t){
if(gw->isOnline == KK_DEV_ONLINE){
list_del(&gw->linked_list);
//kk_subDev_send_property_get(gw->deviceCode);
free(gw);
}
else{
res = dm_mgr_get_device_by_devicecode(gw->deviceCode,&node);
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
}
if(node->hb_timeout == 0){
node->hb_timeout = DEFAULT_HEARTBEAT_TIMEOUT;
}
/*开机如果一直没有收到网关reply,等待到超时到后发送超时到云端*/
if((current_time - gw->starttime) >= node->hb_timeout){
//printf("&&&&&&&&&&&&&&&&&&&&&&[%s][%d]\n",__FUNCTION__,__LINE__);
INFO_PRINT("GW is off line now!!! deviceCode:%s\n",node->deviceCode);
dm_mgr_set_dev_onoffline(node,KK_DEV_OFFLINE);
list_del(&gw->linked_list);
free(gw);
}
else{
/*先下发网关属性获取,判断网关是否在线*/
kk_msg_execute_property_get(node);
}
}
}
}
_kk_heartbeat_unlock();
sleep(30);
dm_mgr_check_heartbeat_timeout(current_time);
sleep(1);
}
return NULL;
}
......@@ -109,6 +104,7 @@ int kk_heartbeat_init(void)
return FAIL_RETURN;
}
/* Init Device Id*/
INIT_LIST_HEAD(&ctx->gw_status_list);
ctx->hearbeat_thread_running = 1;
s_start_time = HAL_UptimeMs();
......@@ -125,4 +121,48 @@ int kk_heartbeat_init(void)
}
int kk_dm_gw_status_check_push(const char *deviceCode)
{
kk_gw_status_ctx_t *gw = NULL;
kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
if(deviceCode == NULL){
ERROR_PRINT("kk_dm_gw_status_check_push Failed\n");
return INVALID_PARAMETER;
}
gw = malloc(sizeof(kk_gw_status_ctx_t));
if (gw == NULL) {
ERROR_PRINT("kk_dm_gw_status_check_push malloc Failed\n");
return MEMORY_NOT_ENOUGH;
}
memset(gw, 0, sizeof(kk_gw_status_ctx_t));
_kk_heartbeat_lock();
memcpy(gw->deviceCode,deviceCode,strlen(deviceCode));
gw->isOnline = KK_DEV_UNKNOW;
gw->starttime = HAL_GetTime();
INIT_LIST_HEAD(&gw->linked_list);
list_add_tail(&gw->linked_list, &ctx->gw_status_list);
_kk_heartbeat_unlock();
return SUCCESS_RETURN;
}
int kk_dm_gw_status_update_online(const char *deviceCode)
{
kk_gw_status_ctx_t *gw = NULL;
kk_heartbeat_ctx_t *ctx = _kk_heartbeat_get_ctx();
_kk_heartbeat_lock();
list_for_each_entry(gw,&ctx->gw_status_list,linked_list,kk_gw_status_ctx_t){
if(0 == strcmp(gw->deviceCode,deviceCode))
{
INFO_PRINT("kk_dm_gw_status_update_online find!!!\n");
gw->isOnline = KK_DEV_ONLINE;
_kk_heartbeat_unlock();
return SUCCESS_RETURN;
}
}
_kk_heartbeat_unlock();
return FAIL_RETURN;
}
......@@ -250,7 +250,7 @@ int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MA
if (dev_type != KK_DM_DEVICE_CCU && fatherDeviceCode != NULL) {
memcpy(node->fatherDeviceCode, fatherDeviceCode, strlen(fatherDeviceCode));
}
node->timestamp = 0;
node->timestamp = HAL_GetTime();
//node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED;
//if(strcmp(productCode,"1035") == 0){
//tsl_str = kk_load_json("130", dev_type);
......@@ -375,7 +375,7 @@ int dm_mgr_get_device_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _O
}
int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],uint64_t timestamp)
int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],time_t timestamp)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL;
......@@ -394,36 +394,58 @@ int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLE
ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
return FAIL_RETURN;
}
#define TEST_TIMEOUT 600000 // ten minutes
int dm_mgr_check_heartbeat_timeout(uint64_t timestamp)
int dm_mgr_set_dev_onoffline(dm_mgr_dev_node_t *node,int isOffline)
{
if(node == NULL){
return INVALID_PARAMETER;
}
if(isOffline){
INFO_PRINT("---------->dev timeout,send offline\n");
node->isOffline = KK_DEV_OFFLINE;
iotx_dm_dev_offline(node->devid);
kk_subDev_update_offline(node->isOffline,node->deviceCode);
}
else{
INFO_PRINT("---------->dev online,send online\n");
node->isOffline = KK_DEV_ONLINE;
iotx_dm_dev_online(node->devid);
if(node->dev_type == KK_DM_DEVICE_CCU){
/*先上报主机属性*/
dm_msg_ccu_property_post(node);
/*再报对应网关和子设备的属性,主机上线后子设备属性直接从数据库获取并上报*/
kk_subDev_send_property_get_from_db();
}
else{
kk_subDev_update_offline(node->isOffline,node->deviceCode);
/*如果网关在线,下发对应子设备的属性获取*/
if(node->dev_type == KK_DM_DEVICE_GATEWAY){
kk_subDev_send_property_get(node->deviceCode);
}
}
}
return SUCCESS_RETURN;
}
int dm_mgr_check_heartbeat_timeout(time_t timestamp)
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL;
_dm_mgr_mutex_lock();
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if(search_node->dev_type == KK_DM_DEVICE_CCU){
continue;
}
if(search_node->hb_timeout == 0){
search_node->hb_timeout = TEST_TIMEOUT;
search_node->hb_timeout = DEFAULT_HEARTBEAT_TIMEOUT;
}
if((timestamp - search_node->timestamp) >= search_node->hb_timeout/*search_node->hb_timeout*/){
if(search_node->isOffline == 0){
INFO_PRINT("---------->dev timeout,send offline\n");
search_node->isOffline = 1;
iotx_dm_dev_offline(search_node->devid);
kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode);
if(search_node->isOffline != KK_DEV_OFFLINE){
dm_mgr_set_dev_onoffline(search_node,1);
}
}
else{
if(search_node->isOffline == 1 && search_node->timestamp != 0) {//need send online
INFO_PRINT("---------->dev online again,send online\n");
search_node->isOffline = 0;
iotx_dm_dev_online(search_node->devid);
kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode);
if(search_node->isOffline == KK_DEV_OFFLINE){
/*如果是离线状态,上报在线给云端*/
dm_mgr_set_dev_onoffline(search_node,0);
}
}
}
......@@ -490,7 +512,7 @@ int dm_mgr_init(void)
HAL_Get_mac(mac);
res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",0,&devId,&heartbeat);
res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",KK_DEV_UNKNOW,&devId,&heartbeat);
if (res != SUCCESS_RETURN) {
goto ERROR;
}
......
......@@ -29,7 +29,7 @@ typedef struct {
char productType[PRODUCT_TYPE_MAXLEN];
char isOffline;
int hb_timeout; //heartbeat time
uint64_t timestamp;
time_t timestamp;
struct list_head linked_list;
} dm_mgr_dev_node_t;
......
......@@ -883,6 +883,20 @@ int dm_msg_thing_property_post_all(char *deviceCode)
}
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;
}
int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params)
{
......@@ -894,7 +908,7 @@ int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params)
cJSON *propertyItem = NULL;
char tmpValue[20] = {0};
if(params == NULL || deviceCode == NULL){
return FAIL_RETURN;
return INVALID_PARAMETER;
}
res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
......@@ -1060,6 +1074,88 @@ int kk_msg_execute_property_set(const char *productCode,const char *deviceCode,c
}
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;
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;
payload = malloc(payload_len);
if (payload == NULL) {
free(req_info);
return MEMORY_NOT_ENOUGH;
}
memset(payload, 0, payload_len);
snprintf(payload, payload_len, DM_MSG_REQUEST, iotx_report_id(),
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);
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;
......
......@@ -72,6 +72,7 @@ const char DM_MSG_INFO[] DM_READ_ONLY;
#define KK_THING_SERVICE_ADDSCENC "/thing/service/addScene"
#define KK_THING_SERVICE_DELETESCENC "/thing/service/deleteScene"
#define KK_THING_SERVICE_UPDATESCENC "/thing/service/updateScene"
#define KK_THING_SERVICE_PROPERTY_GET_REPLY "/thing/service/property/get_reply"
#define KK_THING_EVENT_MESSAGE "/thing/event/"
#define KK_THING_EVENT_POST "/post"
......
......@@ -773,14 +773,10 @@ static void _iotx_linkkit_event_callback(iotx_dm_event_types_t type, char *data)
}
kk_property_db_update("CCU_66666");
if(s_CloudStatus){
node->isOffline = KK_DEV_ONLINE;
iotx_dm_dev_online(KK_DM_DEVICE_CCU_DEVICEID);//first online,report the online status
usleep(200000);
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;
}
dm_msg_ccu_property_post(node);
}
}else if (strstr(typeJson->valuestring,KK_THING_OTA_DEVICE_UPGRADE)){
INFO_PRINT("ota upgrade... \n");
......@@ -2252,12 +2248,11 @@ int kk_mid_subdev_add(int devType, char productCode[PRODUCT_CODE_MAXLEN], char d
int devid = 0;
int heartbeat = 0;
dm_mgr_dev_node_t *node = NULL;
res = dm_mgr_subdev_create(devType,productCode,deviceCode,mac,fatherDeviceCode,0,&devid,&heartbeat);
res = dm_mgr_subdev_create(devType,productCode,deviceCode,mac,fatherDeviceCode,KK_DEV_ONLINE,&devid,&heartbeat);
if (res != SUCCESS_RETURN && TSL_ALREADY_EXIST != res) {
ERROR_PRINT("subdev create Failed\n");
return FAIL_RETURN;
}
INFO_PRINT("subdev open susseed, devid = %d\n", devid);
if (TSL_ALREADY_EXIST == res){
//todo
......@@ -2293,12 +2288,11 @@ int kk_mid_subdev_batch_add( char productCode[PRODUCT_CODE_MAXLEN], char deviceC
int res = 0;
int devid = 0;
int heartbeat = 0;
res = dm_mgr_subdev_create(KK_DM_DEVICE_SUBDEV,productCode,deviceCode,mac,fatherDeviceCode,0,&devid,&heartbeat);
res = dm_mgr_subdev_create(KK_DM_DEVICE_SUBDEV,productCode,deviceCode,mac,fatherDeviceCode,KK_DEV_ONLINE,&devid,&heartbeat);
if (res != SUCCESS_RETURN && TSL_ALREADY_EXIST != res) {
ERROR_PRINT("subdev create Failed\n");
return FAIL_RETURN;
}
INFO_PRINT("subdev open susseed, devid = %d\n", devid);
if (TSL_ALREADY_EXIST == res){
//todo
......
......@@ -314,13 +314,13 @@ int kk_property_db_update(const char *deviceCode)
kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
}
else if(property->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
sprintf(tmpValue,"%d",property->data_value.value_float);
sprintf(tmpValue,"%f",property->data_value.value_float);
kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
}
else if(property->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
sprintf(tmpValue,"%d",property->data_value.value_double);
sprintf(tmpValue,"%f",property->data_value.value_double);
kk_property_db_update_value(deviceCode,property->identifier,tmpValue);
}
else if(property->data_value.type == KK_TSL_DATA_TYPE_TEXT||
......
......@@ -96,18 +96,20 @@ static int _kk_load_subDevice(void)
{
const char *searchCmd = "select * from SubDeviceInfo;";
sqlite3_stmt *stmt;
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){
res = dm_mgr_subdev_create(sqlite3_column_int(stmt, DB_DEVTYPE),
deviceType = sqlite3_column_int(stmt, DB_DEVTYPE);
res = dm_mgr_subdev_create(deviceType,
sqlite3_column_text(stmt, DB_PRODUCTCODE),
sqlite3_column_text(stmt, DB_DEVICECODE),
sqlite3_column_text(stmt, DB_MAC),
sqlite3_column_text(stmt, DB_FATHERDEVICECODE),
sqlite3_column_int(stmt, DB_ONLINE),&devId,&heartbeat);
KK_DEV_UNKNOW,&devId,&heartbeat);
if(res != SUCCESS_RETURN){
ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__);
......@@ -123,8 +125,11 @@ static int _kk_load_subDevice(void)
kk_property_sync_values(sqlite3_column_text(stmt, DB_DEVICECODE));
usleep(100000);
if(deviceType == KK_DM_DEVICE_GATEWAY){
kk_dm_gw_status_check_push(sqlite3_column_text(stmt, DB_DEVICECODE));
}
//post the property to cloud
dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE));
//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);
}
......@@ -302,8 +307,75 @@ int kk_subDev_update_auth(int isAuth,const char *deviceCode)
return SUCCESS_RETURN;
}
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_DEVTYPE);
if(isOffline == KK_DEV_ONLINE){
res = dm_mgr_get_device_by_devicecode(sqlite3_column_text(stmt, DB_DEVICECODE), &node);
if (res != SUCCESS_RETURN) {
continue;
}
iotx_dm_dev_online(node->devid);
dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE));
}
}
sqlite3_finalize(stmt);
_kk_subDb_unlock();
return SUCCESS_RETURN;
}
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 = sqlite3_column_text(stmt, DB_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(!strcmp(pDeviceCode,"842E14FFFE9A26CA")){
//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;
}
......
......@@ -284,7 +284,6 @@ void gw2mid_cb(void* data, int len, char* chalMark){
}
}
extern uint64_t s_start_time;
void kk_platMsg_handle(void* data, char* chalMark){
char *out;
......@@ -315,20 +314,22 @@ void kk_platMsg_handle(void* data, char* chalMark){
msgType = cJSON_GetObjectItem(info, MSG_TYPE_STR);
info_dcode = cJSON_GetObjectItem(info, MSG_DEVICE_CODE_STR);
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
if (msgType == NULL || info_dcode == NULL || jsonPay == NULL){
if (msgType == NULL || info_dcode == NULL){
ERROR_PRINT("msgType info_dcode or jsonPay params are error\n");
goto error;
}
if (chalMark != NULL){
dm_mgr_update_timestamp_by_devicecode(chalMark,HAL_UptimeMs()-s_start_time);
dm_mgr_update_timestamp_by_devicecode(chalMark,HAL_GetTime());
}
dm_mgr_update_timestamp_by_devicecode(info_dcode->valuestring,HAL_UptimeMs()-s_start_time);
dm_mgr_update_timestamp_by_devicecode(info_dcode->valuestring,HAL_GetTime());
if (strcmp(msgType->valuestring, KK_THING_TOPO_ADD_MSG)==0){
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
proCode = cJSON_GetObjectItem(jsonPay, MSG_PRODUCT_CODE_STR);
devCode = cJSON_GetObjectItem(jsonPay, MSG_DEVICE_CODE_STR);
mac = cJSON_GetObjectItem(jsonPay, "mac");
......@@ -345,10 +346,12 @@ void kk_platMsg_handle(void* data, char* chalMark){
}else{
kk_mid_subdev_add(KK_DM_DEVICE_SUBDEV,proCode->valuestring,devCode->valuestring, mac->valuestring,info_dcode->valuestring);
}
dm_mgr_update_timestamp_by_devicecode(devCode->valuestring,HAL_UptimeMs()-s_start_time);
dm_mgr_update_timestamp_by_devicecode(devCode->valuestring,HAL_GetTime());
}else if (strstr(msgType->valuestring, KK_THING_TOPO_BATCH_ADD_MSG) != NULL){
}
else if (strstr(msgType->valuestring, KK_THING_TOPO_BATCH_ADD_MSG) != NULL){
kk_ipc_send(IPC_MID2APP,data,strlen(data));
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
cJSON *devices = cJSON_GetObjectItem(jsonPay, MSG_TOPO_CHANGE_DEVICES_STR);
cJSON * item = devices->child;
while(item != NULL){
......@@ -362,32 +365,43 @@ void kk_platMsg_handle(void* data, char* chalMark){
}else if (strstr(msgType->valuestring, KK_THING_PROPERTY_POST) != NULL){
INFO_PRINT("save property and send to cloud \n");
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
char* outstr = cJSON_Print(payload);
kk_tsl_t *dev_shadow = NULL;
dm_mgr_get_device_shadow_by_devicecode(info_dcode->valuestring,&dev_shadow);
kk_tsl_property_set_by_shadow(dev_shadow, outstr, strlen(outstr)+1);
dm_mgr_dev_node_t *search_node = NULL;
dm_mgr_get_device_by_devicecode(info_dcode->valuestring,&search_node);
if(search_node->isOffline){
/*如果是离线状态,上报在线给云端*/
dm_mgr_set_dev_onoffline(search_node,0);
}
kk_tsl_property_set_by_shadow(search_node->dev_shadow, outstr, strlen(outstr)+1);
dm_msg_thing_property_post_by_identify(info_dcode->valuestring,jsonPay);
kk_scene_iftt_check(info_dcode->valuestring,jsonPay);
free(outstr);
}else if(strstr(msgType->valuestring, KK_THING_TOPO_DELETE_MSG) != NULL){
INFO_PRINT("kk_platMsg_handle data: handle delete\n");
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
devCode = cJSON_GetObjectItem(jsonPay, MSG_DEVICE_CODE_STR);
kk_ipc_send(IPC_MID2APP,data,strlen(data)+1);
dm_mgr_subdev_delete(devCode->valuestring);
}else if(strstr(msgType->valuestring, KK_THING_EVENT_MESSAGE) != NULL && \
strstr(msgType->valuestring, KK_THING_EVENT_POST) != NULL){
kk_tsl_t *dev_shadow = NULL;
dm_mgr_dev_node_t *node = NULL;
int idx = 0;
kk_tsl_event_t *eventItem =NULL;
char tmpStr[128] = {0};
cJSON * itemStr = NULL;
res = dm_mgr_get_device_shadow_by_devicecode(info_dcode->valuestring,&dev_shadow);
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
res = dm_mgr_get_device_by_devicecode(info_dcode->valuestring,&node);
if (res < SUCCESS_RETURN) {
goto error;
}
for(idx = 0; idx < dev_shadow->event_number; idx++){
eventItem = dev_shadow->events + idx;
if(node->isOffline){
/*如果是离线状态,上报在线给云端*/
dm_mgr_set_dev_onoffline(node,0);
}
for(idx = 0; idx < node->dev_shadow->event_number; idx++){
eventItem = node->dev_shadow->events + idx;
if(eventItem != NULL){
if(strcmp(eventItem->identifier,MSG_PROPERTY_STR) != 0 &&
eventItem->output_data_number > 0){
......@@ -412,10 +426,11 @@ void kk_platMsg_handle(void* data, char* chalMark){
kk_tsl_set_value(kk_tsl_set_event_output_value,dev_shadow,tmpStr,&itemStr->valueint,NULL);
}
#else
kk_tsl_set_value(kk_tsl_set_event_output_value,dev_shadow,tmpStr,&itemStr->valueint,NULL);
kk_tsl_set_value(kk_tsl_set_event_output_value,node->dev_shadow,tmpStr,&itemStr->valueint,NULL);
#endif
INFO_PRINT("kk_platMsg_handle data: event post\n");
dm_msg_thing_event_post(info_dcode->valuestring,eventItem->identifier);
kk_scene_iftt_check(info_dcode->valuestring,jsonPay);
}
}
......@@ -431,8 +446,10 @@ void kk_platMsg_handle(void* data, char* chalMark){
}
}
}
}else if(strstr(msgType->valuestring, KK_THING_TOPO_BATCH_DELETE_MSG) != NULL){
}
else if(strstr(msgType->valuestring, KK_THING_TOPO_BATCH_DELETE_MSG) != NULL){
kk_ipc_send(IPC_MID2APP,data,strlen(data));
jsonPay = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
cJSON *devices = cJSON_GetObjectItem(jsonPay, MSG_TOPO_CHANGE_DEVICES_STR);
cJSON * item = devices->child;
while(item != NULL){
......@@ -441,7 +458,26 @@ void kk_platMsg_handle(void* data, char* chalMark){
item = item->next;
}
}else{
}
else if(strstr(msgType->valuestring, KK_THING_SERVICE_PROPERTY_GET_REPLY) != NULL){
INFO_PRINT("kk_platMsg_handle data: KK_THING_SERVICE_PROPERTY_GET_REPLY\n");
int res = 0;
dm_mgr_dev_node_t *node = NULL;
res = dm_mgr_get_device_by_devicecode(info_dcode->valuestring,&node);
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return;
}
/*开机先获取网关属性,网关返回relay,置网关状态在线*/
if(node->dev_type == KK_DM_DEVICE_GATEWAY){
kk_dm_gw_status_update_online(info_dcode->valuestring);
if(node->isOffline){
/*如果是离线状态,上报在线给云端*/
dm_mgr_set_dev_onoffline(node,0);
}
}
}
else{
INFO_PRINT("kk_platMsg_handle data: don't handle it [%s]\n",data);
}
......@@ -707,7 +743,7 @@ void *ccu_property_monitor(void *args)
int needReport = 0;
int time_second = 60;
dm_mgr_dev_node_t *node = NULL;
dm_mgr_search_dev_by_devid(KK_DM_DEVICE_CCU_DEVICEID,&node);
while (mid_ctx->g_ccuProChg_dispatch_thread_running) {
if(kk_get_cloud_recv_status() == 0){
......@@ -715,7 +751,9 @@ void *ccu_property_monitor(void *args)
sleep(10);
continue;
}
dm_mgr_search_dev_by_devid(KK_DM_DEVICE_CCU_DEVICEID,&node);
//dm_mgr_update_timestamp_by_devicecode(node->deviceCode,HAL_GetTime());
node->timestamp = HAL_GetTime();
HAL_Get_IP(s_IP,NULL);
res = kk_tsl_get_value(kk_tsl_get_property_value,node->dev_shadow,KK_TSL_CCU_WANIP_IDENTIFIER,s_IP_TSL,NULL);
if(res != SUCCESS_RETURN){
......@@ -725,7 +763,7 @@ void *ccu_property_monitor(void *args)
if(strcmp(s_IP,s_IP_TSL)){
kk_tsl_set_value(kk_tsl_set_property_value,node->dev_shadow,KK_TSL_CCU_WANIP_IDENTIFIER,NULL,s_IP);
INFO_PRINT("current ip:%s,before ip:%s\n",s_IP,s_IP_TSL);
kk_property_db_update("CCU_66666");
kk_property_db_update(node->deviceCode);
needReport = 1;
}
}
......@@ -773,9 +811,9 @@ int main(const int argc, const char **argv)
kk_ipc_init(IPC_MID2PLAT, mid2p_cb, NULL, "*");
kk_init_dmproc();
kk_subDb_init();
kk_heartbeat_init();
kk_subDb_init();
kk_area_init();
kk_scene_init();
mid_ctx->g_mid_dispatch_thread_running = 1;
......
......@@ -237,7 +237,7 @@ extern uint64_t s_start_time;
void *kk_scene_yield(void *args)
{
uint64_t current_time = 0;
time_t current_time = 0;
kk_scene_action_delay_t *actionDelayInfo = NULL;
kk_scene_action_delay_t *pTemp = NULL;
kk_scene_timer_list_t *scene_timer_list = NULL;
......@@ -849,6 +849,7 @@ int kk_scene_get_scene_info(const char* sceneId,int *sceneType,int *enable)
static char kk_scene_date_to_week(time_t t)
{
struct tm *p = localtime(&t);
INFO_PRINT("kk_scene_date_to_week t p->tm_wday:%d\n",p->tm_wday);
return ((p->tm_wday == 0)?7 : p->tm_wday);
}
static int kk_scene_update_starttime(kk_scene_timer_list_t *pInfo,int starttime,int current)
......@@ -885,14 +886,23 @@ static int kk_scene_update_starttime(kk_scene_timer_list_t *pInfo,int starttime,
}
static int kk_scene_creat_new_starttime(time_t starttime,time_t current)
static time_t kk_scene_creat_new_starttime(time_t starttime,time_t current)
{
int hour,min,sec;
time_t newTime = 0;
struct tm *s = localtime(&starttime);
hour = s->tm_hour;
min = s->tm_min;
sec = s->tm_sec;
struct tm *c = localtime(&current);
c->tm_hour = s->tm_hour;
c->tm_min = s->tm_min;
c->tm_sec = s->tm_sec;
return mktime(c);
c->tm_hour = hour;
c->tm_min = min;
c->tm_sec = sec;
newTime = mktime(c);
INFO_PRINT("kk_scene_creat_new_starttime:%ld\n",newTime);
return newTime;
}
int kk_scene_check_condition(const char *sceneId)
......@@ -901,12 +911,13 @@ int kk_scene_check_condition(const char *sceneId)
char *sqlCmd = NULL;
char curWeek = 0;
char repeatday = 0;
int startTime = 0,startTime_m = 0;
int endTime = 0,endTime_m = 0;
time_t startTime = 0,startTime_m = 0;
time_t endTime = 0,endTime_m = 0;
int duration = 0;
int crossDay = 0;
sqlite3_stmt *stmt;
kk_scene_ctx_t *ctx = _kk_scene_get_ctx();
uint64_t current = HAL_GetTime();
time_t current = HAL_GetTime();
curWeek = kk_scene_date_to_week(current);
sqlCmd = sqlite3_mprintf("select * from SceneConditionInfo WHERE sceneId = '%s'",sceneId);
......@@ -915,18 +926,46 @@ int kk_scene_check_condition(const char *sceneId)
repeatday = sqlite3_column_int(stmt, DB_SCENECONDITION_REPEATDAY);
startTime = sqlite3_column_int(stmt, DB_SCENECONDITION_STARTTIME);
endTime = sqlite3_column_int(stmt, DB_SCENECONDITION_ENDTIME);
crossDay = sqlite3_column_int(stmt, DB_SCENECONDITION_CROSSDAY);
duration = endTime - startTime;
startTime_m = kk_scene_creat_new_starttime(startTime,current);
INFO_PRINT("current:%ld,startTime_m:%ld,repeatday:%d\n",current,startTime_m,repeatday);
/********check today is one of repeatday**************/
if((repeatday > 0) && (repeatday &(1<<(curWeek-1)))){
if(current >= startTime_m && current <= (startTime_m + duration)){
if(crossDay && current < startTime_m){
/*跨天处理,判断当前时间是否在上一天的结束时间内*/
if(current <= (startTime_m + duration - 86400)){
res = SUCCESS_RETURN;
}
}
else if(current >= startTime_m && current <= (startTime_m + duration)){
res = SUCCESS_RETURN;
}
else{
INFO_PRINT("time not match current:%ld,startTime_m:%ld,repeatday:%d\n",current,startTime_m,repeatday);
}
}
else if((repeatday > 0)&&(!(repeatday &(1<<(curWeek-1))))){
/*跨天处理,获取前一天的星期*/
if(crossDay == 1){
curWeek = (curWeek - 1) == 0? 7:(curWeek - 1);
/*前一天的星期必须要在重复星期内*/
if(repeatday &(1<<(curWeek-1))){
if(current <= (startTime_m + duration - 86400)){
res = SUCCESS_RETURN;
}
}
}
}
else{
if(current >= startTime && current <= (startTime + duration)){
res = SUCCESS_RETURN;
}
else
{
INFO_PRINT("time not match current:%ld,startTime:%ld\n",current,startTime);
}
}
}
sqlite3_finalize(stmt);
......@@ -1166,6 +1205,7 @@ int kk_scene_query_trigger_info(const char *deviceCode,cJSON *param)
sqlCmd = sqlite3_mprintf("select * from SceneTriggerInfo WHERE deviceCode= '%s'",deviceCode);
sqlite3_prepare_v2(ctx->pDb, sqlCmd, strlen(sqlCmd), &stmt, NULL);
while(sqlite3_step(stmt) == SQLITE_ROW){
sceneId = sqlite3_column_text(stmt, DB_SCENETRIGGER_SCENEID);
identifier = sqlite3_column_text(stmt,DB_SCENETRIGGER_PROPERTYNAME);
compareType = sqlite3_column_text(stmt,DB_SCENETRIGGER_COMPARETYPE);
......@@ -1195,6 +1235,7 @@ int kk_scene_query_trigger_info(const char *deviceCode,cJSON *param)
}
int kk_scene_iftt_check(const char*deviceCode,cJSON *param)
{
printf("[%s][%d] deviceCode:%s\n",__FUNCTION__,__LINE__,deviceCode);
return kk_scene_query_trigger_info(deviceCode,param);
}
......
......@@ -14,14 +14,14 @@ typedef struct {
} kk_scene_action_info_t;
typedef struct kk_action_list{
int starttime;
time_t starttime;
kk_scene_action_info_t *action;
struct kk_action_list *next;
} kk_scene_action_delay_t;
typedef struct kk_scene_timer_list{
int starttime;
int endtime;
time_t starttime;
time_t endtime;
char sceneId[32];
int repeatday;
struct kk_scene_timer_list *next;
......
......@@ -81,6 +81,14 @@
#define KK_TSL_GATAWAY_SN_IDENTIFIER "SN"
#define KK_TSL_GATAWAY_WHITELIST_IDENTIFIER "WhiteListState"
#define DEFAULT_HEARTBEAT_TIMEOUT (60*4)// four minutes
typedef enum {
KK_DEV_ONLINE = 0,
KK_DEV_OFFLINE,
KK_DEV_UNKNOW,
} kk_dev_status_e;
typedef enum {
KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA,
KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA
......
......@@ -752,6 +752,57 @@ static int _kk_tsl_service_inputdata_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_da
return SUCCESS_RETURN;
}
static int _kk_tsl_service_parse_get_input_identifier(char *str,int count,kk_tsl_data_t *input_datas)
{
char *pstr = str;
char *start = NULL;
char *end = NULL;
int i = 0;
int len = 0;
char *identifier = NULL;
kk_tsl_data_t *input_data = NULL;
if(input_datas == NULL){
return -1;
}
for(i = 0; i < count; i++){
input_data = input_datas + i;
start = strchr(pstr,'"') ;
end = strchr(start+1,'"');
len = end-start-1;
identifier = malloc(len+1);
if(identifier == NULL)
return -1;
memset(identifier,0x0,len);
strncpy(identifier,start+1,len);
identifier[len] = '\0';
input_data->identifier = identifier;
pstr = end + 1;
}
return 0;
}
static int _kk_tsl_service_inputdatas_get_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *service,
_IN_ lite_cjson_t *root)
{
int res = 0, index = 0;
lite_cjson_t lite_item;
kk_tsl_data_t *input_data = NULL;
printf("input Number: %d\n", service->input_data_number);
if (service->input_data_number == 0) {
return SUCCESS_RETURN;
}
//Allocate Memory For Output Datas
service->input_datas = malloc((service->input_data_number) * (sizeof(kk_tsl_data_t)));
if (service->input_datas == NULL) {
return MEMORY_NOT_ENOUGH;
}
memset(service->input_datas, 0, (service->input_data_number) * (sizeof(kk_tsl_data_t)));
_kk_tsl_service_parse_get_input_identifier( root->value,service->input_data_number,service->input_datas);
return SUCCESS_RETURN;
}
static int _kk_tsl_service_inputdatas_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *service,
_IN_ lite_cjson_t *root)
{
......@@ -759,7 +810,7 @@ static int _kk_tsl_service_inputdatas_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_s
lite_cjson_t lite_item;
kk_tsl_data_t *input_data = NULL;
printf("Number: %d", service->input_data_number);
printf("input Number: %d\n", service->input_data_number);
if (service->input_data_number == 0) {
return SUCCESS_RETURN;
}
......@@ -791,6 +842,7 @@ static int _kk_tsl_service_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *s
{
int res = 0;
lite_cjson_t lite_item;
int isGetService = 0;
//Parse Identifier (Mandatory)
memset(&lite_item, 0, sizeof(lite_cjson_t));
......@@ -806,16 +858,18 @@ static int _kk_tsl_service_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *s
//printf("Identifier: %s", service->identifier);
/* Check If Current Service Id Is Set Or Get */
if (((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) &&
if ((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) &&
(memcmp(service->identifier, KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER,
strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) == 0)) ||
((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) &&
(memcmp(service->identifier, KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER,
strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) == 0))) {
strlen(KK_TSL_SPECIAL_SERVICE_SET_IDENTIFIER)) == 0)) {
/* dm_log_info("TSL Special Service Identifier: %s, Ignore It",service->identifier); */
return SUCCESS_RETURN;
}
if((strlen(service->identifier) == strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) &&
(memcmp(service->identifier, KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER,
strlen(KK_TSL_SPECIAL_SERVICE_GET_IDENTIFIER)) == 0))
{
isGetService = 1;
}
//Parse Output Data (Optional)
memset(&lite_item, 0, sizeof(lite_cjson_t));
res = lite_cjson_object_item(root, KK_TSL_KEY_OUTPUTDATA, strlen(KK_TSL_KEY_OUTPUTDATA), &lite_item);
......@@ -832,13 +886,16 @@ static int _kk_tsl_service_parse(_IN_ kk_tsl_t *shadow, _IN_ kk_tsl_service_t *s
res = lite_cjson_object_item(root, KK_TSL_KEY_INPUTDATA, strlen(KK_TSL_KEY_INPUTDATA), &lite_item);
if (res == SUCCESS_RETURN && lite_cjson_is_array(&lite_item)) {
service->input_data_number = lite_item.size;
if(isGetService && service->input_data_number > 0){
res = _kk_tsl_service_inputdatas_get_parse(shadow, service, &lite_item);
}else
{
res = _kk_tsl_service_inputdatas_parse(shadow, service, &lite_item);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
}
return SUCCESS_RETURN;
return res;
}
static int _kk_tsl_services_parse(_IN_ kk_tsl_t *shadow, _IN_ lite_cjson_t *root)
......@@ -1604,7 +1661,7 @@ static int _kk_tsl_heartbeat_parse(_OU_ int *heartbeat, _IN_ lite_cjson_t *root)
if (res != SUCCESS_RETURN || !lite_cjson_is_string(&lite_item_heartbeat)) {
return JSON_PARSE_FAILED;
}
*heartbeat = atoi(lite_item_heartbeat.value)*1000;
*heartbeat = atoi(lite_item_heartbeat.value);
return SUCCESS_RETURN;
}
int kk_tsl_create(_IN_ const char *tsl, _IN_ int tsl_len, _OU_ kk_tsl_t **shadow,_OU_ int *heartbeat)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment