Commit a743a1d1 authored by 尹佳钦's avatar 尹佳钦

111

parents 2d71ac7f e6ffee28
LIBA_TARGET := libiot_kcloud.a LIBA_TARGET := libiot_kcloud.a
$(call Append_Conditional, LIB_SRCS_EXCLUDE, kcloud_main.c) $(call Append_Conditional, LIB_SRCS_EXCLUDE, kcloud_main.c)
$(call Append_Conditional, SRCS_kcloud, kcloud_main.c) $(call Append_Conditional, SRCS_kcloud, kcloud_main.c)
$(call Append_Conditional, TARGET, kcloud) $(call Append_Conditional, TARGET, kcloud)
CFLAGS += -I$(TOP_DIR)/common/api CFLAGS += -I$(TOP_DIR)/common/api
CFLAGS += -I$(TOP_DIR)/common/json CFLAGS += -I$(TOP_DIR)/common/json
CFLAGS += -I$(TOP_DIR)/common/nanomsg/include CFLAGS += -I$(TOP_DIR)/common/nanomsg/include
CFLAGS += -I$(TOP_DIR)/common/ev/include CFLAGS += -I$(TOP_DIR)/common/ev/include
LDFLAGS += -lkk_tsl LDFLAGS += -lkk_tsl
LDFLAGS += -lapi_com LDFLAGS += -lapi_com
ifeq ($(CONFIG_VENDOR),ubuntu) ifeq ($(CONFIG_VENDOR),ubuntu)
LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg_ubuntu LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg_ubuntu
LDFLAGS += -L$(TOP_DIR)/common/ev -lev_ubuntu LDFLAGS += -L$(TOP_DIR)/common/ev -lev_ubuntu
else else
LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg
LDFLAGS += -L$(TOP_DIR)/common/ev -lev LDFLAGS += -L$(TOP_DIR)/common/ev -lev
endif endif
LDFLAGS += -liot_cjson -liot_mqtt -ldl -lm -lanl -lkk_hal -lzlog LDFLAGS += -liot_cjson -liot_mqtt -ldl -lm -lanl -lkk_hal
#ifndef MQTT_CONF_H_ #ifndef MQTT_CONF_H_
#define MQTT_CONF_H_ #define MQTT_CONF_H_
#define ADDRESS "tcp://172.25.240.31:1983" #define ADDRESS "tcp://172.25.240.31:1983"
#define CLIENTID "kk_%s" #define CLIENTID "kk_%s"
#define TOPIC "/sys/a1OYuSBt23u/aIqEbWno8yDdsjCX15iq/thing/service/property/set" #define TOPIC "/sys/a1OYuSBt23u/aIqEbWno8yDdsjCX15iq/thing/service/property/set"
#define PAYLOAD "Hello cwc World!" #define PAYLOAD "Hello cwc World!"
#define QOS 2 #define QOS 0
#define TIMEOUT 10000L #define TIMEOUT 10000L
#define USRNAME "hangzhou_gateway " #define USRNAME "hangzhou_gateway "
#define PASSWORD "2ca1442865ff4cb99870f60f2c646190" #define PASSWORD "2ca1442865ff4cb99870f60f2c646190"
#define AUTO_CONN 1 #define AUTO_CONN 1
#define CONNECT_TIMEOUT 3 #define CONNECT_TIMEOUT 3
typedef enum {
RETURN_FAIL = -1,
#endif RETURN_SUCCESS = 0,
} kk_kcloud_error_code_t;
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "mqtt_api.h" #include "mqtt_api.h"
#include "com_api.h" #include "com_api.h"
#include "cJSON.h" #include "cJSON.h"
#include "kk_product.h" #include "kk_product.h"
//#include "kcloud_log.h"
#define KK_FILTER_ADD_TOPIC "/thing/topo/add"
#define KK_FILTER_ADD_TOPIC_REPLY "/thing/topo/add_reply" #define KK_FILTER_ADD_TOPIC "/thing/topo/add"
#define KK_FILTER_DELETE_TOPIC "/thing/topo/delete" #define KK_FILTER_ADD_TOPIC_REPLY "/thing/topo/add_reply"
#define KK_FILTER_DELETE_TOPIC_REPLY "/thing/topo/delete_reply" #define KK_FILTER_DELETE_TOPIC "/thing/topo/delete"
#define KK_FILTER_REGISTER_TOPIC "/thing/sub/register" #define KK_FILTER_DELETE_TOPIC_REPLY "/thing/topo/delete_reply"
#define KK_FILTER_REGISTER_TOPIC_REPLY "/thing/sub/register_reply" #define KK_FILTER_REGISTER_TOPIC "/thing/sub/register"
#define KK_FILTER_LOGIN_TOPIC "/thing/combine/login" #define KK_FILTER_REGISTER_TOPIC_REPLY "/thing/sub/register_reply"
#define KK_FILTER_LOGIN_TOPIC_REPLY "/thing/combine/login_reply" #define KK_FILTER_LOGIN_TOPIC "/thing/combine/login"
#define KK_FILTER_SET_TOPIC "/thing/service/property/set" #define KK_FILTER_LOGIN_TOPIC_REPLY "/thing/combine/login_reply"
#define KK_FILTER_SET_TOPIC_REPLY "/thing/service/property/set_reply" #define KK_FILTER_SET_TOPIC "/thing/service/property/set"
#define KK_FILTER_EVENT_POST_TOPIC "/thing/event/property/post" #define KK_FILTER_SET_TOPIC_REPLY "/thing/service/property/set_reply"
#define KK_FILTER_EVENT_POST_REPLY "/thing/event/property/post_reply" #define KK_FILTER_EVENT_POST_TOPIC "/thing/event/property/post"
#define KK_FILTER_STATUS_ONLINE "/thing/status/online" #define KK_FILTER_EVENT_POST_REPLY "/thing/event/property/post_reply"
#define KK_FILTER_STATUS_ONLINE_REPLY "/thing/status/online_reply" #define KK_FILTER_STATUS_ONLINE "/thing/status/online"
#define KK_FILTER_STATUS_OFFLINE "/thing/status/offline" #define KK_FILTER_STATUS_ONLINE_REPLY "/thing/status/online_reply"
#define KK_FILTER_STATUS_OFFLINE_REPLY "/thing/status/offline_reply" #define KK_FILTER_STATUS_OFFLINE "/thing/status/offline"
#define KK_FILTER_STATUS_OFFLINE_REPLY "/thing/status/offline_reply"
#define KK_CLOUDSTATE_MSG "/thing/ccu/cloudstate" #define KK_FILTER_TOPO_CHANEG_REPLY "/thing/topo/change_reply"
#define KK_CLOUDSTATE_MSG_REPLY "/thing/ccu/cloudstate_reply"
#define KK_CLOUDSTATE_MSG "/thing/ccu/cloudstate"
const char DM_MSG_TO_MIDDWARE[] = "{\"msgtype\":\"%s\",\"productCode\":\"%s\",\"deviceCode\":\"%s\"}"; #define KK_CLOUDSTATE_MSG_REPLY "/thing/ccu/cloudstate_reply"
#define KK_TOPIC_SERVICE_DELIMITER '/' #define KK_TOPO_CHANGE_MSG_STR "/thing/topo/change"
int _kk_sendto_cloud(cJSON *root) const char DM_MSG_TO_MIDDWARE[] = "{\"msgtype\":\"%s\",\"productCode\":\"%s\",\"deviceCode\":\"%s\"}";
{ #define KK_TOPIC_SERVICE_DELIMITER '/'
cJSON *info,*pData; #define KK_POWER_SWITCH_1 "PowerSwitch_1"
char *topic = NULL; #define KK_POWER_SWITCH_2 "PowerSwitch_2"
char *payload = NULL; #define KK_POWER_SWITCH_3 "PowerSwitch_3"
cJSON *msgTypeStr = NULL;
info = cJSON_GetObjectItem(root, MSG_INFO_STR);
if(info == NULL){
return -1; static char *s_split_product[] = {
} "85", //三路面板
msgTypeStr = cJSON_GetObjectItem(info, MSG_TYPE_STR); "3002", //双路面板
if(msgTypeStr == NULL){ "3003" //三路面板
return -1;
} };
topic = KK_Make_Topic(info); static int kk_check_need_split(cJSON * info)
if(topic == NULL){ {
return -1; return 0;//暂时不用拆分处理
} #if 0
pData = cJSON_GetObjectItem(root, MSG_PAYLOAD_STR); cJSON *productCode = NULL;
if(pData == NULL){ int i = 0;
free(topic); int num = sizeof(s_split_product)/sizeof(char*);
return -1;
}
//If topo delete,need UnSubscribe the topic if(info == NULL){
if(strstr(msgTypeStr->valuestring,KK_FILTER_DELETE_TOPIC) != NULL){ return 0;
KK_Subdev_UnSubscribe(pData); }
free(topic); productCode = cJSON_GetObjectItem(info, MSG_PRODUCT_CODE_STR);
return 0; if(productCode == NULL){
return 0;
} }
else if(strstr(msgTypeStr->valuestring,KK_CLOUDSTATE_MSG) != NULL){ for(i = 0; i < num; i++){
KK_Send_CloudState(kk_get_cloud_status()); if(strncmp(s_split_product[i],productCode->valuestring,strlen(productCode->valuestring)) == 0){
free(topic); return 1;
return 0; }
}
} return 0;
char* out=cJSON_Print(pData); #endif
INFO_PRINT("[%s][%d] payload:%s\n",__FUNCTION__,__LINE__,out); }
KK_MQTT_SendMsg(topic,(const char*)out); static int kk_split_send_data(cJSON *pData,const char* topic)
free(topic); {
free(out); cJSON *pParam = NULL;
return 0; cJSON *pParam_new = NULL;
} cJSON *powerswitch1 = NULL;
cJSON *powerswitch2 = NULL;
cJSON *powerswitch3 = NULL;
void KK_Data_FromDev(void* str,int len) if(pData == NULL){
{ return RETURN_FAIL;
cJSON *root,*cmd; }
if(str == NULL){ pParam = cJSON_GetObjectItem(pData, MSG_PARAMS_STR);
return; if(pParam == NULL){
} return RETURN_FAIL;
root=cJSON_Parse((char*)str); }
if(root == NULL){ char* param_tmp = cJSON_Print(pParam);
ERROR_PRINT("[%s][%d] root is null \n",__FUNCTION__,__LINE__); powerswitch1 = cJSON_GetObjectItem(pParam, KK_POWER_SWITCH_1);
return; if(powerswitch1 != NULL){
} cJSON_DeleteItemFromObject(pData,MSG_PARAMS_STR);
cmd = cJSON_GetObjectItem(root, "cmd"); cJSON *pParam_new = cJSON_CreateObject();
if(cmd == NULL){ cJSON_AddNumberToObject(pParam_new, KK_POWER_SWITCH_1, powerswitch1->valueint);
_kk_sendto_cloud(root); cJSON_AddItemToObject(pData,MSG_PARAMS_STR,pParam_new);
} char* out=cJSON_Print(pData);
else{ KK_MQTT_SendMsg(topic,(const char*)out);
KK_Subdev_Subscribe(root); free(out);
}
cJSON_Delete(root); }
pParam = cJSON_Parse(param_tmp);
} powerswitch2 = cJSON_GetObjectItem(pParam, KK_POWER_SWITCH_2);
static int _check_invalid_topic(const char* topic) if(powerswitch2 != NULL){
{ cJSON_DeleteItemFromObject(pData,MSG_PARAMS_STR);
if(strstr(topic, KK_FILTER_ADD_TOPIC) != NULL && \ pParam_new = cJSON_CreateObject();
strstr(topic,KK_FILTER_ADD_TOPIC_REPLY) == NULL){ cJSON_AddNumberToObject(pParam_new, KK_POWER_SWITCH_2, powerswitch2->valueint);
return 1; cJSON_AddItemToObject(pData,MSG_PARAMS_STR,pParam_new);
} char* out=cJSON_Print(pData);
else if(strstr(topic, KK_FILTER_DELETE_TOPIC) != NULL && \ KK_MQTT_SendMsg(topic,(const char*)out);
strstr(topic,KK_FILTER_DELETE_TOPIC_REPLY) == NULL){ free(out);
return 1; }
} powerswitch3 = cJSON_GetObjectItem(pParam, KK_POWER_SWITCH_3);
else if(strstr(topic, KK_FILTER_REGISTER_TOPIC) != NULL && \ if(powerswitch3 != NULL){
strstr(topic,KK_FILTER_REGISTER_TOPIC_REPLY) == NULL){ cJSON_DeleteItemFromObject(pData,MSG_PARAMS_STR);
return 1; pParam_new = cJSON_CreateObject();
} cJSON_AddNumberToObject(pParam_new, KK_POWER_SWITCH_3, powerswitch3->valueint);
else if(strstr(topic, KK_FILTER_LOGIN_TOPIC) != NULL && \ cJSON_AddItemToObject(pData,MSG_PARAMS_STR,pParam_new);
strstr(topic,KK_FILTER_LOGIN_TOPIC_REPLY) == NULL){ char* out=cJSON_Print(pData);
return 1; KK_MQTT_SendMsg(topic,(const char*)out);
} free(out);
else if(strstr(topic, KK_FILTER_SET_TOPIC_REPLY) != NULL){ }
return 1; free(param_tmp);
} return RETURN_SUCCESS;
else if(strstr(topic, KK_FILTER_EVENT_POST_TOPIC) != NULL && \
strstr(topic,KK_FILTER_LOGIN_TOPIC_REPLY) == NULL){ }
return 1; int _kk_sendto_cloud(cJSON *root)
} {
else if(strstr(topic, KK_FILTER_STATUS_ONLINE) != NULL && \ cJSON *info,*pData;
strstr(topic,KK_FILTER_STATUS_ONLINE_REPLY) == NULL){ char *topic = NULL;
return 1; char *payload = NULL;
} cJSON *msgTypeStr = NULL;
else if(strstr(topic, KK_FILTER_STATUS_OFFLINE) != NULL && \ info = cJSON_GetObjectItem(root, MSG_INFO_STR);
strstr(topic,KK_FILTER_STATUS_OFFLINE_REPLY) == NULL){ if(info == NULL){
return 1; return RETURN_FAIL;
} }
return 0; msgTypeStr = cJSON_GetObjectItem(info, MSG_TYPE_STR);
} if(msgTypeStr == NULL){
return RETURN_FAIL;
static int _kk_topic_parse_msgType(_IN_ char *topic, _IN_ int start_deli,_OU_ char **msgTypeStr) }
{ topic = KK_Make_Topic(info);
int res = 0, start = 0, len = 0, slice = 0; if(topic == NULL){
char *msgTypeStr_tmp = NULL; return RETURN_FAIL;
}
if (topic == NULL) { pData = cJSON_GetObjectItem(root, MSG_PAYLOAD_STR);
return -1; if(pData == NULL){
} free(topic);
res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli, &start); return RETURN_FAIL;
if (res != 0) { }
return -1; //If topo delete,need UnSubscribe the topic
} if(strstr(msgTypeStr->valuestring,KK_FILTER_DELETE_TOPIC) != NULL){
len = strlen(topic) - start + 1; KK_Subdev_UnSubscribe(pData);
msgTypeStr_tmp = (char*)malloc(len+1); free(topic);
if(msgTypeStr_tmp == NULL){ return RETURN_SUCCESS;
ERROR_PRINT("[%s][%d]malloc fail!!!\n",__FUNCTION__,__LINE__);
return -1; }
} else if(strstr(msgTypeStr->valuestring,KK_CLOUDSTATE_MSG) != NULL){
memcpy(msgTypeStr_tmp, topic + start, len); KK_Send_CloudState(kk_get_cloud_status());
*msgTypeStr = msgTypeStr_tmp; free(topic);
INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,*msgTypeStr); return RETURN_SUCCESS;
}
/* dm_log_debug("URI Product Key: %.*s, Device Name: %.*s", slice - start - 1, uri + start + 1, end - slice - 1, if(kk_check_need_split(info)){
uri + slice + 1); */ kk_split_send_data(pData,topic);
}
return 0; else{
} char* out=cJSON_Print(pData);
KK_MQTT_SendMsg(topic,(const char*)out);
static int _kk_topic_parse_pkdn(_IN_ char *topic, _IN_ int start_deli, free(out);
_OU_ char productCode[PRODUCT_CODE_LEN],_OU_ char deviceCode[DEVICE_CODE_LEN]) }
{ free(topic);
int res = 0, start = 0, end = 0, slice = 0; return RETURN_SUCCESS;
}
if (topic == NULL || deviceCode == NULL) {
return -1;
} void KK_Data_FromDev(void* str,int len)
res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli, &start); {
if (res != 0) { cJSON *root,*cmd;
return -1; if(str == NULL){
} return;
res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli + 1, &slice); }
if (res != 0) { root=cJSON_Parse((char*)str);
return -1; if(root == NULL){
} ERROR_PRINT("[%s][%d] root is null \n",__FUNCTION__,__LINE__);
return;
res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli + 2, &end); }
if (res != 0) { cmd = cJSON_GetObjectItem(root, "cmd");
return -1; if(cmd == NULL){
} _kk_sendto_cloud(root);
}
memcpy(productCode, topic + start + 1, slice - start - 1); else{
memcpy(deviceCode, topic + slice + 1, end - slice - 1); KK_Subdev_Subscribe(root);
}
return 0; cJSON_Delete(root);
}
}
static char * _kk_data_create(const char *topic,const char *data) static int _check_invalid_topic(const char* topic)
{ {
cJSON *root; if(strstr(topic, KK_FILTER_ADD_TOPIC) != NULL && \
char *out; strstr(topic,KK_FILTER_ADD_TOPIC_REPLY) == NULL){
char *infoStr = NULL; return 1;
int infoStr_len = 0; }
int res = 0; else if(strstr(topic, KK_FILTER_DELETE_TOPIC) != NULL && \
char productCode[PRODUCT_CODE_LEN] = {0}; strstr(topic,KK_FILTER_DELETE_TOPIC_REPLY) == NULL){
char deviceCode[DEVICE_CODE_LEN] = {0}; return 1;
char * msgStr = NULL; }
else if(strstr(topic, KK_FILTER_REGISTER_TOPIC) != NULL && \
res =_kk_topic_parse_pkdn((char *)topic,3,productCode,deviceCode); strstr(topic,KK_FILTER_REGISTER_TOPIC_REPLY) == NULL){
res|=_kk_topic_parse_msgType((char *)topic,5,&msgStr); return 1;
infoStr_len = strlen(DM_MSG_TO_MIDDWARE)+strlen(productCode)+strlen(deviceCode)+strlen(msgStr)+10; }
infoStr = malloc(infoStr_len); else if(strstr(topic, KK_FILTER_LOGIN_TOPIC) != NULL && \
if(infoStr == NULL){ strstr(topic,KK_FILTER_LOGIN_TOPIC_REPLY) == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__); return 1;
free(msgStr); }
return NULL; else if(strstr(topic, KK_FILTER_SET_TOPIC_REPLY) != NULL){
} return 1;
memset(infoStr,0x0,infoStr_len); }
snprintf(infoStr,infoStr_len,DM_MSG_TO_MIDDWARE,msgStr,productCode,deviceCode); else if(strstr(topic,KK_FILTER_TOPO_CHANEG_REPLY) != NULL){
return 1;
root=cJSON_CreateObject(); }
cJSON* infoObj = cJSON_Parse(infoStr); else if(strstr(topic, KK_FILTER_EVENT_POST_TOPIC) != NULL && \
cJSON* payloadObj = cJSON_Parse(data); strstr(topic,KK_FILTER_LOGIN_TOPIC_REPLY) == NULL){
cJSON_AddItemToObject(root, MSG_INFO_STR, infoObj); return 1;
cJSON_AddItemToObject(root, MSG_PAYLOAD_STR,payloadObj); }
out=cJSON_Print(root); else if(strstr(topic, KK_FILTER_STATUS_ONLINE) != NULL && \
cJSON_Delete(root); strstr(topic,KK_FILTER_STATUS_ONLINE_REPLY) == NULL){
free(msgStr); return 1;
free(infoStr); }
INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,out); else if(strstr(topic, KK_FILTER_STATUS_OFFLINE) != NULL && \
return out; strstr(topic,KK_FILTER_STATUS_OFFLINE_REPLY) == NULL){
//free(out); /* Print to text, Delete the cJSON, print it, release the string. */ return 1;
} }
const char DM_MSG_CLOUDSTATE[] = "{\"msgId\":\"1\",\"version\":\"1.0\",\"params\":{\"IOTCloudState\":\"%d\"},\"method\":\"thing.ccu.cloudstate_reply\"}"; return 0;
}
int KK_Send_CloudState(int state)
{ static int _kk_topic_parse_msgType(_IN_ char *topic, _IN_ int start_deli,_OU_ char **msgTypeStr)
char *infoStr = NULL; {
char *payloadStr = NULL; int res = 0, start = 0, len = 0, slice = 0;
int infoStr_len = 0; char *msgTypeStr_tmp = NULL;
int payloadStr_len = 0;
cJSON *root; if (topic == NULL) {
char *out; return RETURN_FAIL;
}
infoStr_len = strlen(DM_MSG_TO_MIDDWARE)+strlen(KK_CLOUDSTATE_MSG_REPLY)+10; res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli, &start);
infoStr = malloc(infoStr_len); if (res != 0) {
if(infoStr == NULL){ return RETURN_FAIL;
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__); }
return -1; len = strlen(topic) - start + 1;
} msgTypeStr_tmp = (char*)malloc(len+1);
memset(infoStr,0x0,infoStr_len); if(msgTypeStr_tmp == NULL){
snprintf(infoStr,infoStr_len,DM_MSG_TO_MIDDWARE,KK_CLOUDSTATE_MSG_REPLY,"",""); ERROR_PRINT("[%s][%d]malloc fail!!!\n",__FUNCTION__,__LINE__);
return RETURN_FAIL;
payloadStr_len = strlen(DM_MSG_CLOUDSTATE) + 10; }
payloadStr = malloc(payloadStr_len); memcpy(msgTypeStr_tmp, topic + start, len);
if(payloadStr == NULL){ *msgTypeStr = msgTypeStr_tmp;
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__); INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,*msgTypeStr);
return -1;
}
memset(payloadStr,0x0,payloadStr_len); /* dm_log_debug("URI Product Key: %.*s, Device Name: %.*s", slice - start - 1, uri + start + 1, end - slice - 1,
snprintf(payloadStr,payloadStr_len,DM_MSG_CLOUDSTATE,state); uri + slice + 1); */
root=cJSON_CreateObject(); return RETURN_SUCCESS;
cJSON* infoObj = cJSON_Parse(infoStr); }
cJSON* payloadObj = cJSON_Parse(payloadStr);
cJSON_AddItemToObject(root, MSG_INFO_STR, infoObj); static int _kk_topic_parse_pkdn(_IN_ char *topic, _IN_ int start_deli,
cJSON_AddItemToObject(root, MSG_PAYLOAD_STR,payloadObj); _OU_ char productCode[PRODUCT_CODE_LEN],_OU_ char deviceCode[DEVICE_CODE_LEN])
out=cJSON_Print(root); {
kk_ipc_send(IPC_APP2MID, out, strlen(out)+1); int res = 0, start = 0, end = 0, slice = 0;
cJSON_Delete(root);
free(payloadStr); if (topic == NULL || deviceCode == NULL) {
free(infoStr); return RETURN_FAIL;
INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,out); }
free(out); res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli, &start);
return 0; if (res != 0) {
} return RETURN_FAIL;
void KK_Sendto_DevData(const char *topic,const char *data) }
{ res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli + 1, &slice);
if(_check_invalid_topic(topic)) if (res != 0) {
{ return RETURN_FAIL;
return;//ingore the message }
}
INFO_PRINT("[%s][%d]receive from cloud,topic:%s\n",__FUNCTION__,__LINE__,topic); res = kk_utils_memtok(topic, strlen(topic), KK_TOPIC_SERVICE_DELIMITER, start_deli + 2, &end);
char *send_data = _kk_data_create(topic,data); if (res != 0) {
if(send_data == NULL){ return RETURN_FAIL;
return; }
}
kk_ipc_send(IPC_APP2MID, send_data, strlen(send_data)+1); memcpy(productCode, topic + start + 1, slice - start - 1);
free(send_data); memcpy(deviceCode, topic + slice + 1, end - slice - 1);
}
return RETURN_SUCCESS;
}
static int _kk_topo_change_handle(cJSON *payload)
{
cJSON *paramStr = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
if(paramStr == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__);
return RETURN_FAIL;
}
cJSON *state = cJSON_GetObjectItem(paramStr, MSG_TOPO_CHANGE_TYPE_STR);
if(state != NULL && state->valueint == 1){
cJSON *deviceArray = cJSON_GetObjectItem(paramStr, MSG_TOPO_CHANGE_DEVICES_STR);
if(deviceArray == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__);
return RETURN_FAIL;
}
cJSON * item = deviceArray->child;
while(item != NULL){
char *deviceCode = cJSON_GetObjectItem(item,MSG_DEVICE_CODE_STR)->valuestring;
char *productCode = cJSON_GetObjectItem(item,MSG_PRODUCT_CODE_STR)->valuestring;
KK_Subdev_UnSubscribe_By_DeviceCode(deviceCode,productCode);
item = item->next;
}
}
return RETURN_SUCCESS;
}
static char * _kk_data_create(const char *topic,const char *data)
{
cJSON *root;
char *out;
char *infoStr = NULL;
int infoStr_len = 0;
int res = 0;
char productCode[PRODUCT_CODE_LEN] = {0};
char deviceCode[DEVICE_CODE_LEN] = {0};
char * msgStr = NULL;
res =_kk_topic_parse_pkdn((char *)topic,3,productCode,deviceCode);
res|=_kk_topic_parse_msgType((char *)topic,5,&msgStr);
infoStr_len = strlen(DM_MSG_TO_MIDDWARE)+strlen(productCode)+strlen(deviceCode)+strlen(msgStr)+10;
infoStr = malloc(infoStr_len);
if(infoStr == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__);
free(msgStr);
return NULL;
}
memset(infoStr,0x0,infoStr_len);
snprintf(infoStr,infoStr_len,DM_MSG_TO_MIDDWARE,msgStr,productCode,deviceCode);
root=cJSON_CreateObject();
cJSON* infoObj = cJSON_Parse(infoStr);
cJSON* payloadObj = cJSON_Parse(data);
cJSON_AddItemToObject(root, MSG_INFO_STR, infoObj);
cJSON_AddItemToObject(root, MSG_PAYLOAD_STR,payloadObj);
if(strstr(topic,KK_TOPO_CHANGE_MSG_STR)){
_kk_topo_change_handle(payloadObj);
}
out=cJSON_Print(root);
cJSON_Delete(root);
free(msgStr);
free(infoStr);
INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,out);
return out;
//free(out); /* Print to text, Delete the cJSON, print it, release the string. */
}
const char DM_MSG_CLOUDSTATE[] = "{\"msgId\":\"1\",\"version\":\"1.0\",\"params\":{\"IOTCloudState\":\"%d\"},\"method\":\"thing.ccu.cloudstate_reply\"}";
int KK_Send_CloudState(int state)
{
char *infoStr = NULL;
char *payloadStr = NULL;
int infoStr_len = 0;
int payloadStr_len = 0;
cJSON *root;
char *out;
infoStr_len = strlen(DM_MSG_TO_MIDDWARE)+strlen(KK_CLOUDSTATE_MSG_REPLY)+10;
infoStr = malloc(infoStr_len);
if(infoStr == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__);
return RETURN_FAIL;
}
memset(infoStr,0x0,infoStr_len);
snprintf(infoStr,infoStr_len,DM_MSG_TO_MIDDWARE,KK_CLOUDSTATE_MSG_REPLY,"","");
payloadStr_len = strlen(DM_MSG_CLOUDSTATE) + 10;
payloadStr = malloc(payloadStr_len);
if(payloadStr == NULL){
ERROR_PRINT("[%s][%d]\n",__FUNCTION__,__LINE__);
return RETURN_FAIL;
}
memset(payloadStr,0x0,payloadStr_len);
snprintf(payloadStr,payloadStr_len,DM_MSG_CLOUDSTATE,state);
root=cJSON_CreateObject();
cJSON* infoObj = cJSON_Parse(infoStr);
cJSON* payloadObj = cJSON_Parse(payloadStr);
cJSON_AddItemToObject(root, MSG_INFO_STR, infoObj);
cJSON_AddItemToObject(root, MSG_PAYLOAD_STR,payloadObj);
out=cJSON_Print(root);
kk_ipc_send(IPC_APP2MID, out, strlen(out)+1);
cJSON_Delete(root);
free(payloadStr);
free(infoStr);
INFO_PRINT("[%s][%d]%s\n",__FUNCTION__,__LINE__,out);
free(out);
return RETURN_SUCCESS;
}
void KK_Sendto_DevData(const char *topic,const char *data)
{
if(_check_invalid_topic(topic))
{
return;//ingore the message
}
INFO_PRINT("[%s][%d]receive from cloud,topic:%s\n",__FUNCTION__,__LINE__,topic);
char *send_data = _kk_data_create(topic,data);
if(send_data == NULL){
return;
}
kk_ipc_send(IPC_APP2MID, send_data, strlen(send_data)+1);
free(send_data);
}
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012, 2020 IBM Corp. * Copyright (c) 2012, 2020 IBM Corp.
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0 * are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution. * and Eclipse Distribution License v1.0 which accompany this distribution.
* *
* The Eclipse Public License is available at * The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/ * https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at * and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * Contributors:
* Ian Craggs - initial contribution * Ian Craggs - initial contribution
*******************************************************************************/ *******************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "MQTTAsync.h" #include "MQTTAsync.h"
#include "mqtt_api.h" #include "mqtt_api.h"
#include "com_api.h" #include "com_api.h"
#include "kk_product.h" #include "kk_product.h"
//#include "kcloud_log.h"
static int mqtt_start(void) static int mqtt_start(void)
{ {
int count = 0; int count = 0;
MQTTAsync mqttClient; MQTTAsync mqttClient;
int rc = 0; int rc = 0;
mqttClient = KK_MQTT_Connect(); mqttClient = KK_MQTT_Connect();
if(mqttClient == NULL) if(mqttClient == NULL)
{ {
WARNING_PRINT("KK_MQTT_Connect FAIL!!!\n"); WARNING_PRINT("KK_MQTT_Connect FAIL!!!\n");
} }
else else
{ {
INFO_PRINT("Waiting for publication of %s\n" INFO_PRINT("Waiting for publication of %s\n"
"on topic %s for client with ClientID: %s\n", "on topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID); PAYLOAD, TOPIC, CLIENTID);
} }
while(1) while(1)
{ {
usleep(100000L); usleep(100000L);
count++; count++;
if(count>50) if(count>50)
{ {
count = 0; count = 0;
//INFO_PRINT("i am send now\n"); //INFO_PRINT("i am send now\n");
//KK_MQTT_SendMsg(TOPIC,"hello my world",2); //KK_MQTT_SendMsg(TOPIC,"hello my world",2);
} }
} }
INFO_PRINT("MQTTAsync_destroy\n"); INFO_PRINT("MQTTAsync_destroy\n");
MQTTAsync_destroy(&mqttClient); MQTTAsync_destroy(&mqttClient);
return rc; return rc;
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int rc = 0; int rc = 0;
//KK_Data_Hdl_Init(); open("kcloud",LOG_PID,LOG_USER);
kk_zlog_init("kcloud"); /*set the callback to get the device date to cloud*/
kk_ipc_init(IPC_APP2MID,KK_Data_FromDev,NULL,NULL);
/*set the callback to get the device date to cloud*/ rc = mqtt_start();
HAL_SetProduct_Type(PRODUCT_TPYE);
HAL_SetProduct_Code(PRODUCT_CODE); return rc;
kk_ipc_init(IPC_APP2MID,KK_Data_FromDev,NULL,NULL); }
rc = mqtt_start();
return rc;
}
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "kk_product.h" #include "kk_product.h"
#include "cJSON.h" #include "cJSON.h"
#include "com_api.h" #include "com_api.h"
#include "kk_log.h" #include "kk_log.h"
const char KK_URI_SYS_PREFIX[] = "/sys/kk/%s/%s/#"; const char KK_URI_SYS_PREFIX[] = "/sys/kk/%s/%s/#";
const char KK_URI_SYS_PREFIX_EX[] = "/sys/kk/%s/%s"; const char KK_URI_SYS_PREFIX_EX[] = "/sys/kk/%s/%s";
const char KK_URI_OTA_PREFIX[] = "/ota/device/upgrade/kk/%s/%s/#"; const char KK_URI_OTA_PREFIX[] = "/ota/device/upgrade/kk/%s/%s/#";
const char KK_URI_OTA_PROCESS[] = "/ota/device/progress/%s/%s"; const char KK_URI_OTA_PROCESS[] = "/ota/device/progress/%s/%s";
const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s"; const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s";
int KK_Subdev_Subscribe(const cJSON *root) int KK_Subdev_Subscribe(const cJSON *root)
{ {
int res = 0; int res = 0;
cJSON *deviceCode = NULL; cJSON *deviceCode = NULL;
cJSON *productCode = NULL; cJSON *productCode = NULL;
cJSON *data = NULL; cJSON *data = NULL;
cJSON *cmd = NULL; cJSON *cmd = NULL;
int url_len = 0; int url_len = 0;
data = cJSON_GetObjectItem(root, "data"); data = cJSON_GetObjectItem(root, "data");
if(data == NULL){ if(data == NULL){
return -1; return -1;
} }
deviceCode = cJSON_GetObjectItem(data,MSG_DEVICE_CODE_STR); deviceCode = cJSON_GetObjectItem(data,MSG_DEVICE_CODE_STR);
if(deviceCode == NULL){ if(deviceCode == NULL){
return -1; return -1;
} }
productCode = cJSON_GetObjectItem(data,MSG_PRODUCT_CODE_STR); productCode = cJSON_GetObjectItem(data,MSG_PRODUCT_CODE_STR);
if(productCode == NULL){ if(productCode == NULL){
return -1; return -1;
} }
url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productCode->valuestring) + strlen(deviceCode->valuestring) + 1; url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productCode->valuestring) + strlen(deviceCode->valuestring) + 1;
char *url = malloc(url_len); char *url = malloc(url_len);
if (url == NULL) { if (url == NULL) {
return -1; return -1;
} }
memset(url, 0, url_len); memset(url, 0, url_len);
snprintf(url, url_len, KK_URI_OTA_PREFIX, productCode->valuestring, deviceCode->valuestring); snprintf(url, url_len, KK_URI_OTA_PREFIX, productCode->valuestring, deviceCode->valuestring);
INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url); INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
res = KK_MQTT_SubTopic(url); res = KK_MQTT_SubTopic(url);
memset(url, 0, url_len); memset(url, 0, url_len);
snprintf(url, url_len, KK_URI_SYS_PREFIX, productCode->valuestring, deviceCode->valuestring); snprintf(url, url_len, KK_URI_SYS_PREFIX, productCode->valuestring, deviceCode->valuestring);
INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url); INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
res = KK_MQTT_SubTopic(url); res = KK_MQTT_SubTopic(url);
free(url); free(url);
return res; return res;
} }
static int _kk_client_subscribe(char productCode[PRODUCT_CODE_LEN],char deviceCode[DEVICE_CODE_LEN]) static int _kk_client_subscribe(char productCode[PRODUCT_CODE_LEN],char deviceCode[DEVICE_CODE_LEN])
{ {
int res = 0, index = 0, fail_count = 0; int res = 0, index = 0, fail_count = 0;
int url_len = 0; int url_len = 0;
url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productCode)+strlen(deviceCode) + 1; url_len = strlen(KK_URI_OTA_PREFIX) + strlen(productCode)+strlen(deviceCode) + 1;
char *url = malloc(url_len); char *url = malloc(url_len);
if (url == NULL) { if (url == NULL) {
return -1; return -1;
} }
memset(url, 0, url_len); memset(url, 0, url_len);
snprintf(url, url_len, KK_URI_OTA_PREFIX, productCode,deviceCode); snprintf(url, url_len, KK_URI_OTA_PREFIX, productCode,deviceCode);
INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url); INFO_PRINT("ota [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
res = KK_MQTT_SubTopic(url); res = KK_MQTT_SubTopic(url);
memset(url, 0, url_len); memset(url, 0, url_len);
snprintf(url, url_len, KK_URI_SYS_PREFIX, productCode,deviceCode); snprintf(url, url_len, KK_URI_SYS_PREFIX, productCode,deviceCode);
INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url); INFO_PRINT("sys [%s][%d] URL:%s\n",__FUNCTION__,__LINE__,url);
res = KK_MQTT_SubTopic(url); res = KK_MQTT_SubTopic(url);
free(url); free(url);
return res; return res;
} }
int KK_Client_Gateway_Subscribe(void) int KK_Client_Gateway_Subscribe(void)
{ {
char productCode[PRODUCT_CODE_LEN] = {0}; char productCode[PRODUCT_CODE_LEN] = {0};
char deviceCode[MAC_ADDR_LEN] = {0}; char deviceCode[MAC_ADDR_LEN] = {0};
HAL_GetProduct_Code(productCode); HAL_GetProduct_Code(productCode);
HAL_Get_mac(deviceCode); HAL_Get_mac(deviceCode);
return _kk_client_subscribe(productCode,"CCU_66666"); return _kk_client_subscribe(productCode,"CCU_66666");
} }
static int _kk_utils_topic(_IN_ const char *name, _IN_ char *product_code, static int _kk_utils_topic(_IN_ const char *name, _IN_ char *product_code,
_IN_ char *device_code, _OU_ char **topic) _IN_ char *device_code, _OU_ char **topic)
{ {
int service_name_len = 0; int service_name_len = 0;
if (name == NULL|| product_code == NULL || device_code == NULL || if (name == NULL|| product_code == NULL || device_code == NULL ||
topic == NULL || *topic != NULL) { topic == NULL || *topic != NULL) {
return -1; return -1;
} }
service_name_len = strlen(KK_URI_SYS_PREFIX_EX) + strlen(product_code) + strlen(device_code) service_name_len = strlen(KK_URI_SYS_PREFIX_EX) + strlen(product_code) + strlen(device_code)
+ strlen(name)+1; + strlen(name)+1;
*topic = malloc(service_name_len); *topic = malloc(service_name_len);
if (*topic == NULL) { if (*topic == NULL) {
return -1; return -1;
} }
memset(*topic, 0, service_name_len); memset(*topic, 0, service_name_len);
snprintf(*topic, service_name_len, KK_URI_SYS_PREFIX_EX, product_code, device_code); snprintf(*topic, service_name_len, KK_URI_SYS_PREFIX_EX, product_code, device_code);
if (name != NULL) { if (name != NULL) {
memcpy(*topic + strlen(*topic), name, strlen(name)); memcpy(*topic + strlen(*topic), name, strlen(name));
} }
return 0; return 0;
} }
static int _kk_utils_topic_ota(_IN_ char* str, _OU_ char **topic) static int _kk_utils_topic_ota(_IN_ char* str, _OU_ char **topic)
{ {
int service_name_len = 0; int service_name_len = 0;
if (str == NULL ||topic == NULL || *topic != NULL) { if (str == NULL ||topic == NULL || *topic != NULL) {
return -1; return -1;
} }
service_name_len = strlen(str)+1; service_name_len = strlen(str)+1;
*topic = malloc(service_name_len); *topic = malloc(service_name_len);
if (*topic == NULL) { if (*topic == NULL) {
return -1; return -1;
} }
memset(*topic, 0, service_name_len); memset(*topic, 0, service_name_len);
memcpy(*topic,str,service_name_len); memcpy(*topic,str,service_name_len);
return 0; return 0;
} }
int KK_Subdev_UnSubscribe(cJSON *payload)
{ int KK_Subdev_UnSubscribe_By_DeviceCode(const char *deviceCode,const char *productCode )
cJSON *params,*productCode,*deviceCode; {
char *topic = NULL; char *topic = NULL;
int topic_len = 0; int topic_len = 0;
if(payload == NULL){ topic_len = strlen(KK_URI_SYS_PREFIX) + strlen(productCode)+strlen(deviceCode) + 1;
goto errorreturn; topic = malloc(topic_len);
} if (topic == NULL) {
params = cJSON_GetObjectItem(payload, MSG_PARAMS_STR); return -1;
if(params == NULL){ }
goto errorreturn; memset(topic,0,topic_len);
} snprintf(topic, topic_len, KK_URI_SYS_PREFIX, productCode,deviceCode);
productCode = cJSON_GetObjectItem(params, MSG_PRODUCT_CODE_STR); INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
if(productCode == NULL){ KK_MQTT_UnsubTopic(topic);
goto errorreturn; free(topic);
} return 0;
deviceCode = cJSON_GetObjectItem(params, MSG_DEVICE_CODE_STR);
if(deviceCode == NULL){ }
goto errorreturn; int KK_Subdev_UnSubscribe(cJSON *payload)
} {
cJSON *params,*productCode,*deviceCode;
topic_len = strlen(KK_URI_SYS_PREFIX) + strlen(productCode->valuestring)+strlen(deviceCode->valuestring) + 1;
topic = malloc(topic_len); if(payload == NULL){
if (topic == NULL) { goto errorreturn;
goto errorreturn; }
} params = cJSON_GetObjectItem(payload, MSG_PARAMS_STR);
memset(topic,0,topic_len); if(params == NULL){
snprintf(topic, topic_len, KK_URI_SYS_PREFIX, productCode->valuestring,deviceCode->valuestring); goto errorreturn;
INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic); }
KK_MQTT_UnsubTopic(topic); productCode = cJSON_GetObjectItem(params, MSG_PRODUCT_CODE_STR);
free(topic); if(productCode == NULL){
return 0; goto errorreturn;
errorreturn: }
return -1; deviceCode = cJSON_GetObjectItem(params, MSG_DEVICE_CODE_STR);
if(deviceCode == NULL){
} goto errorreturn;
char* KK_Make_Topic(cJSON *info) }
{ KK_Subdev_UnSubscribe_By_DeviceCode(deviceCode->valuestring,productCode->valuestring);
cJSON *type,*product_code,*device_code;
char *topic = NULL; return 0;
//root=cJSON_Parse((char*)info->valuestring); errorreturn:
return -1;
type = cJSON_GetObjectItem(info, MSG_TYPE_STR);
if(type == NULL){ }
goto errorreturn; char* KK_Make_Topic(cJSON *info)
} {
cJSON *type,*product_code,*device_code;
product_code = cJSON_GetObjectItem(info, MSG_PRODUCT_CODE_STR); char *topic = NULL;
if(product_code == NULL){ //root=cJSON_Parse((char*)info->valuestring);
goto errorreturn;
} type = cJSON_GetObjectItem(info, MSG_TYPE_STR);
device_code = cJSON_GetObjectItem(info, MSG_DEVICE_CODE_STR); if(type == NULL){
if(device_code == NULL){ goto errorreturn;
goto errorreturn; }
}
if(strstr(type->valuestring,"/ota/device/inform") ||strstr(type->valuestring,"/ota/device/progress")){ product_code = cJSON_GetObjectItem(info, MSG_PRODUCT_CODE_STR);
_kk_utils_topic_ota(type->valuestring,&topic); if(product_code == NULL){
} goto errorreturn;
else{ }
_kk_utils_topic(type->valuestring,product_code->valuestring,device_code->valuestring,&topic); device_code = cJSON_GetObjectItem(info, MSG_DEVICE_CODE_STR);
} if(device_code == NULL){
goto errorreturn;
INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic); }
return topic; if(strstr(type->valuestring,"/ota/device/inform") ||strstr(type->valuestring,"/ota/device/progress")){
errorreturn: _kk_utils_topic_ota(type->valuestring,&topic);
return NULL; }
else{
} _kk_utils_topic(type->valuestring,product_code->valuestring,device_code->valuestring,&topic);
}
INFO_PRINT("[%s][%d] TOPIC:%s\n",__FUNCTION__,__LINE__,topic);
return topic;
errorreturn:
return NULL;
}
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "mqtt_api.h" #include "mqtt_api.h"
static const char* OPT_SEND = "MQTTAsync_sendMessage"; static const char* OPT_SEND = "MQTTAsync_sendMessage";
static const char* OPT_SUB = "MQTTAsync_subscribe"; static const char* OPT_SUB = "MQTTAsync_subscribe";
static const char* OPT_UNSUB = "MQTTAsync_unsubscribe"; static const char* OPT_UNSUB = "MQTTAsync_unsubscribe";
static MQTTAsync s_Client; static MQTTAsync s_Client;
static int s_mqttStop = 0; static int s_mqttStop = 0;
static int s_cloudStatus = 0; static int s_cloudStatus = 0;
int kk_get_cloud_status(void){ int kk_get_cloud_status(void){
return s_cloudStatus; return s_cloudStatus;
} }
/*Connect lost callback*/ /*Connect lost callback*/
static void connlost(void *context, char *cause) static void connlost(void *context, char *cause)
{ {
if(context == NULL || cause == NULL) if(context == NULL || cause == NULL)
{ {
ERROR_PRINT("PARAM ERROR\n"); ERROR_PRINT("PARAM ERROR\n");
s_mqttStop = 1; s_mqttStop = 1;
return; return;
} }
MQTTAsync client = (MQTTAsync)context; MQTTAsync client = (MQTTAsync)context;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc; int rc;
INFO_PRINT("\nConnection lost\n"); INFO_PRINT("\nConnection lost\n");
INFO_PRINT("cause: %s\n", cause); INFO_PRINT("cause: %s\n", cause);
s_cloudStatus = 0; s_cloudStatus = 0;
KK_Send_CloudState(s_cloudStatus); KK_Send_CloudState(s_cloudStatus);
conn_opts.keepAliveInterval = 20; conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1; conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start connect, return code %d\n", rc); ERROR_PRINT("Failed to start connect, return code %d\n", rc);
s_mqttStop = 1; s_mqttStop = 1;
} }
} }
void onDisconnectFailure(void* context, MQTTAsync_failureData* response) void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
{ {
WARNING_PRINT("Disconnect failed\n"); WARNING_PRINT("Disconnect failed\n");
s_mqttStop = 1; s_mqttStop = 1;
} }
void onDisconnect(void* context, MQTTAsync_successData* response) void onDisconnect(void* context, MQTTAsync_successData* response)
{ {
WARNING_PRINT("Successful disconnection\n"); WARNING_PRINT("Successful disconnection\n");
s_mqttStop = 1; s_mqttStop = 1;
} }
void onSendFailure(void* context, MQTTAsync_failureData* response) void onSendFailure(void* context, MQTTAsync_failureData* response)
{ {
if(context == NULL || response == NULL) if(context == NULL || response == NULL)
{ {
ERROR_PRINT("PARAM ERROR\n"); ERROR_PRINT("PARAM ERROR\n");
return; return;
} }
MQTTAsync client = (MQTTAsync)context; MQTTAsync client = (MQTTAsync)context;
MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
int rc; int rc;
WARNING_PRINT("Message send failed token %d error code %d\n", response->token, response->code); WARNING_PRINT("Message send failed token %d error code %d\n", response->token, response->code);
opts.onSuccess = onDisconnect; opts.onSuccess = onDisconnect;
opts.onFailure = onDisconnectFailure; opts.onFailure = onDisconnectFailure;
opts.context = client; opts.context = client;
if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start disconnect, return code %d\n", rc); ERROR_PRINT("Failed to start disconnect, return code %d\n", rc);
} }
} }
void onSend(void* context, MQTTAsync_successData* response) void onSend(void* context, MQTTAsync_successData* response)
{ {
if(response == NULL) if(response == NULL)
{ {
ERROR_PRINT("PARAM ERROR\n"); ERROR_PRINT("PARAM ERROR\n");
return; return;
} }
INFO_PRINT("Message with token value %d delivery confirmed\n", response->token); INFO_PRINT("Message with token value %d delivery confirmed\n", response->token);
} }
void onConnectFailure(void* context, MQTTAsync_failureData* response) void onConnectFailure(void* context, MQTTAsync_failureData* response)
{ {
s_mqttStop = 1; s_mqttStop = 1;
if(response == NULL) if(response == NULL)
{ {
ERROR_PRINT("PARAM ERROR\n"); ERROR_PRINT("PARAM ERROR\n");
return; return;
} }
WARNING_PRINT("Connect failed, rc %d\n", response ? response->code : 0); WARNING_PRINT("Connect failed, rc %d\n", response ? response->code : 0);
} }
void onConnect(void* context, MQTTAsync_successData* response) void onConnect(void* context, MQTTAsync_successData* response)
{ {
INFO_PRINT("Successful connection\n"); INFO_PRINT("Successful connection\n");
s_cloudStatus = 1; s_cloudStatus = 1;
KK_Send_CloudState(s_cloudStatus); KK_Send_CloudState(s_cloudStatus);
} }
int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message) int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
{ {
/* not expecting any messages */ /* not expecting any messages */
//INFO_PRINT("onMessageArrived topic:%s,message length:%d.\n",topicName,message->payloadlen); //INFO_PRINT("onMessageArrived topic:%s,message length:%d.\n",topicName,message->payloadlen);
//INFO_PRINT("payload:%s,\n",message->payload); //INFO_PRINT("payload:%s,\n",message->payload);
KK_MQTT_RecvMsg(topicName,message->payload); KK_MQTT_RecvMsg(topicName,message->payload);
MQTTAsync_freeMessage(&message); MQTTAsync_freeMessage(&message);
MQTTAsync_free(topicName); MQTTAsync_free(topicName);
return 1; return 1;
} }
static void mqttTraceCallback(enum MQTTASYNC_TRACE_LEVELS level, char *message) static void mqttTraceCallback(enum MQTTASYNC_TRACE_LEVELS level, char *message)
{ {
//printf("mqttTraceCallback level:%d,msg:%s.\n",level,message); //printf("mqttTraceCallback level:%d,msg:%s.\n",level,message);
} }
static void onDeliveryComplete(void* context, MQTTAsync_token token) static void onDeliveryComplete(void* context, MQTTAsync_token token)
{ {
//INFO_PRINT("onDeliveryComplete,token:%d \n",token); //INFO_PRINT("onDeliveryComplete,token:%d \n",token);
} }
static void onConnectBuild(void *context, char *cause) static void onConnectBuild(void *context, char *cause)
{ {
int rc = 0; int rc = 0;
INFO_PRINT("onConnectBuild:%s \n",cause); INFO_PRINT("onConnectBuild:%s \n",cause);
rc = KK_Client_Gateway_Subscribe(); rc = KK_Client_Gateway_Subscribe();
if(rc != 0) if(rc != 0)
{ {
ERROR_PRINT("KK_MQTT_SubTopic ERROR rc = %d\n",rc); ERROR_PRINT("KK_MQTT_SubTopic ERROR rc = %d\n",rc);
} }
} }
static void onDisConnected(void *context, MQTTProperties* properties,enum MQTTReasonCodes reasonCode) static void onDisConnected(void *context, MQTTProperties* properties,enum MQTTReasonCodes reasonCode)
{ {
INFO_PRINT("onDisConnected,maybe kicked by broker.\n"); INFO_PRINT("onDisConnected,maybe kicked by broker.\n");
} }
static void onOptSuccess(void* context, MQTTAsync_successData* response) static void onOptSuccess(void* context, MQTTAsync_successData* response)
{ {
if(strcmp((char *)context,OPT_SEND)==0) if(strcmp((char *)context,OPT_SEND)==0)
{ {
INFO_PRINT("MQTTAsync_sendMessage success,return token:%d,msg length:%d \n", INFO_PRINT("MQTTAsync_sendMessage success,return token:%d,msg length:%d \n",
response->token,response->alt.pub.message.payloadlen); response->token,response->alt.pub.message.payloadlen);
} }
else if(strcmp((char *)context,OPT_SUB)==0) else if(strcmp((char *)context,OPT_SUB)==0)
{ {
INFO_PRINT("MQTTAsync_subscribe success,return token:%d \n",response->token); INFO_PRINT("MQTTAsync_subscribe success,return token:%d \n",response->token);
} }
else if(strcmp((char *)context,OPT_UNSUB)==0) else if(strcmp((char *)context,OPT_UNSUB)==0)
{ {
INFO_PRINT("MQTTAsync_unsubscribe success,return token:%d \n",response->token); INFO_PRINT("MQTTAsync_unsubscribe success,return token:%d \n",response->token);
} }
} }
static void onOptFail(void* context, MQTTAsync_failureData* response) static void onOptFail(void* context, MQTTAsync_failureData* response)
{ {
if(strcmp((char *)context,OPT_SEND)==0) if(strcmp((char *)context,OPT_SEND)==0)
{ {
WARNING_PRINT("MQTTAsync_sendMessage fail,token:%d,code:%d,msg:%s \n", WARNING_PRINT("MQTTAsync_sendMessage fail,token:%d,code:%d,msg:%s \n",
response->token,response->code,response->message); response->token,response->code,response->message);
} }
else if(strcmp((char *)context,OPT_SUB)==0) else if(strcmp((char *)context,OPT_SUB)==0)
{ {
WARNING_PRINT("MQTTAsync_subscribe fail,return token:%d \n",response->token); WARNING_PRINT("MQTTAsync_subscribe fail,return token:%d \n",response->token);
} }
else if(strcmp((char *)context,OPT_UNSUB)==0) else if(strcmp((char *)context,OPT_UNSUB)==0)
{ {
WARNING_PRINT("MQTTAsync_unsubscribe fail,return token:%d \n",response->token); WARNING_PRINT("MQTTAsync_unsubscribe fail,return token:%d \n",response->token);
} }
} }
static void mqtt_set_callbacks(void) static void mqtt_set_callbacks(void)
{ {
MQTTAsync_setConnectionLostCallback(s_Client,NULL,connlost); MQTTAsync_setConnectionLostCallback(s_Client,NULL,connlost);
MQTTAsync_setMessageArrivedCallback(s_Client,NULL,messageArrived); MQTTAsync_setMessageArrivedCallback(s_Client,NULL,messageArrived);
MQTTAsync_setDeliveryCompleteCallback(s_Client,NULL,onDeliveryComplete); MQTTAsync_setDeliveryCompleteCallback(s_Client,NULL,onDeliveryComplete);
MQTTAsync_setConnected(s_Client,NULL,onConnectBuild); MQTTAsync_setConnected(s_Client,NULL,onConnectBuild);
MQTTAsync_setDisconnected(s_Client,NULL,onDisConnected); MQTTAsync_setDisconnected(s_Client,NULL,onDisConnected);
} }
void KK_Get_MqttClient(MQTTAsync *pClient) void KK_Get_MqttClient(MQTTAsync *pClient)
{ {
if(pClient != NULL) if(pClient != NULL)
{ {
*pClient = s_Client; *pClient = s_Client;
} }
} }
MQTTAsync KK_MQTT_Connect(void) MQTTAsync KK_MQTT_Connect(void)
{ {
int rc = 0; int rc = 0;
MQTTAsync_createOptions opts = MQTTAsync_createOptions_initializer; MQTTAsync_createOptions opts = MQTTAsync_createOptions_initializer;
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer; MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
MQTTAsync_setTraceCallback(mqttTraceCallback); MQTTAsync_setTraceCallback(mqttTraceCallback);
opts.MQTTVersion = MQTTVERSION_3_1_1; opts.MQTTVersion = MQTTVERSION_3_1_1;
char mac[16]={0}; char mac[16]={0};
char clientBuf[20] = {0}; char clientBuf[20] = {0};
HAL_Get_mac(mac); HAL_Get_mac(mac);
sprintf(clientBuf, CLIENTID, mac); sprintf(clientBuf, CLIENTID, mac);
if ((rc = MQTTAsync_createWithOptions(&s_Client, ADDRESS, clientBuf, MQTTCLIENT_PERSISTENCE_NONE, NULL,&opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_createWithOptions(&s_Client, ADDRESS, clientBuf, MQTTCLIENT_PERSISTENCE_NONE, NULL,&opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to create client object, return code %d\n", rc); ERROR_PRINT("Failed to create client object, return code %d\n", rc);
return NULL; return NULL;
} }
/*Set the mqtt callback*/ /*Set the mqtt callback*/
mqtt_set_callbacks(); mqtt_set_callbacks();
conn_opts.keepAliveInterval = 60; conn_opts.keepAliveInterval = 60;
conn_opts.connectTimeout = CONNECT_TIMEOUT; conn_opts.connectTimeout = CONNECT_TIMEOUT;
conn_opts.automaticReconnect = AUTO_CONN; conn_opts.automaticReconnect = AUTO_CONN;
conn_opts.minRetryInterval = 1; conn_opts.minRetryInterval = 1;
conn_opts.maxRetryInterval = 32; conn_opts.maxRetryInterval = 32;
conn_opts.username = USRNAME; conn_opts.username = USRNAME;
conn_opts.password = PASSWORD; conn_opts.password = PASSWORD;
conn_opts.cleansession = 1; conn_opts.cleansession = 1;
conn_opts.onSuccess = onConnect; conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure; conn_opts.onFailure = onConnectFailure;
conn_opts.context = s_Client; conn_opts.context = s_Client;
if ((rc = MQTTAsync_connect(s_Client, &conn_opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_connect(s_Client, &conn_opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start connect, return code %d\n", rc); ERROR_PRINT("Failed to start connect, return code %d\n", rc);
return NULL; return NULL;
} }
return s_Client; return s_Client;
} }
int KK_MQTT_SubTopic(char *topicName) int KK_MQTT_SubTopic(char *topicName)
{ {
INFO_PRINT("to subtopic:%s \n",topicName); INFO_PRINT("to subtopic:%s \n",topicName);
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
int rc; int rc;
opts.onSuccess = onOptSuccess; opts.onSuccess = onOptSuccess;
opts.onFailure = onOptFail; opts.onFailure = onOptFail;
opts.context = (void*)OPT_SUB; opts.context = (void*)OPT_SUB;
if ((rc = MQTTAsync_subscribe(s_Client,topicName, QOS, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_subscribe(s_Client,topicName, QOS, &opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start subscribe, return code:%d.\n", rc); ERROR_PRINT("Failed to start subscribe, return code:%d.\n", rc);
return -1; return -1;
} }
return 0; return 0;
} }
int KK_MQTT_SendMsg(char *topicName,const char *payload) int KK_MQTT_SendMsg(char *topicName,const char *payload)
{ {
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer; MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
int rc; int rc;
opts.onSuccess = onOptSuccess; opts.onSuccess = onOptSuccess;
opts.onFailure = onOptFail; opts.onFailure = onOptFail;
opts.context = (void*)OPT_SEND; opts.context = (void*)OPT_SEND;
pubmsg.payload = (void*)payload; pubmsg.payload = (void*)payload;
pubmsg.payloadlen = strlen(payload); pubmsg.payloadlen = strlen(payload);
pubmsg.qos = QOS; pubmsg.qos = QOS;
pubmsg.retained = 0; pubmsg.retained = 0;
INFO_PRINT("mqtt send payload len:%d.\n",pubmsg.payloadlen); INFO_PRINT("mqtt send payload :%s.\n",payload);
if ((rc = MQTTAsync_sendMessage(s_Client, topicName, &pubmsg, &opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_sendMessage(s_Client, topicName, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start sendMessage, return code:%d.\n", rc); ERROR_PRINT("Failed to start sendMessage, return code:%d.\n", rc);
return -1; return -1;
} }
return rc; return rc;
} }
int KK_MQTT_RecvMsg(const char *topicName,const char *payload) int KK_MQTT_RecvMsg(const char *topicName,const char *payload)
{ {
if(topicName == NULL || payload ==NULL) if(topicName == NULL || payload ==NULL)
{ {
ERROR_PRINT("PARAM ERROR\n"); ERROR_PRINT("PARAM ERROR\n");
return -1; return -1;
} }
KK_Sendto_DevData(topicName,payload); KK_Sendto_DevData(topicName,payload);
return 0; return 0;
} }
int KK_MQTT_UnsubTopic(const char *topicName) int KK_MQTT_UnsubTopic(const char *topicName)
{ {
INFO_PRINT("to unsubtopic:%s \n",topicName); INFO_PRINT("to unsubtopic:%s \n",topicName);
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
int rc; int rc;
opts.onSuccess = onOptSuccess; opts.onSuccess = onOptSuccess;
opts.onFailure = onOptFail; opts.onFailure = onOptFail;
opts.context = (void*)OPT_UNSUB; opts.context = (void*)OPT_UNSUB;
if ((rc = MQTTAsync_unsubscribe(s_Client,topicName,&opts)) != MQTTASYNC_SUCCESS) if ((rc = MQTTAsync_unsubscribe(s_Client,topicName,&opts)) != MQTTASYNC_SUCCESS)
{ {
ERROR_PRINT("Failed to start unubscribe, return code:%d.\n", rc); ERROR_PRINT("Failed to start unubscribe, return code:%d.\n", rc);
return -1; return -1;
} }
return rc; return rc;
} }
//=========kk============= //=========kk=============
#include "com_api.h" #include "com_api.h"
#include "kk_log.h"
#define APP2MID "ipc:///tmp/app2mid.ipc" #define APP2MID "ipc:///tmp/app2mid.ipc"
#define PLAT2MID "ipc:///tmp/plat2mid.ipc" #define PLAT2MID "ipc:///tmp/plat2mid.ipc"
...@@ -10,21 +11,6 @@ ...@@ -10,21 +11,6 @@
#define FILTERSTR "|" #define FILTERSTR "|"
#ifndef _ZLOG_
#undef INFO_PRINT
#undef WARNING_PRINT
#undef ERROR_PRINT
#define INFO_PRINT printf
#define WARNING_PRINT printf
#define ERROR_PRINT printf
#else
#include "kk_log.h"
#endif
typedef struct { typedef struct {
int n;//nanomsg socket int n;//nanomsg socket
int s;//nanomsg recieve fd int s;//nanomsg recieve fd
......
/* /*
* Copyright (C) 2020-2020 ikonke * Copyright (C) 2020-2020 ikonke
*/ */
#ifndef _KK_COM_API_H_ #ifndef _KK_COM_API_H_
#define _KK_COM_API_H_ #define _KK_COM_API_H_
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "ev.h" #include "ev.h"
#include "nn.h" #include "nn.h"
#include "pair.h" #include "pair.h"
#include "pubsub.h" #include "pubsub.h"
#include "pipeline.h" #include "pipeline.h"
//=====kk====================== //=====kk======================
typedef enum { typedef enum {
IPC_APP2MID = 0, IPC_APP2MID = 0,
IPC_MID2APP, IPC_MID2APP,
IPC_MID2PLAT, IPC_MID2PLAT,
IPC_PLAT2MID, IPC_PLAT2MID,
IPC_UNDEF IPC_UNDEF
} ipc_type; } ipc_type;
#define MSG_TYPE_STR "msgtype" #define MSG_TYPE_STR "msgtype"
#define MSG_PRODUCT_TYPE_STR "productType" #define MSG_PRODUCT_TYPE_STR "productType"
#define MSG_PRODUCT_CODE_STR "productCode" #define MSG_PRODUCT_CODE_STR "productCode"
#define MSG_DEVICE_CODE_STR "deviceCode" #define MSG_DEVICE_CODE_STR "deviceCode"
#define MSG_PAYLOAD_STR "payload" #define MSG_PAYLOAD_STR "payload"
#define MSG_INFO_STR "info" #define MSG_INFO_STR "info"
#define MSG_INDENTIFIER_STR "identifier" #define MSG_INDENTIFIER_STR "identifier"
#define MSG_PARAMS_STR "params" #define MSG_PARAMS_STR "params"
#define MSG_IOTClOUDSTATE_STR "IOTCloudState" #define MSG_IOTClOUDSTATE_STR "IOTCloudState"
#define MSG_TOPO_CHANGE_TYPE_STR "changeType"
typedef void ipc_cb(void* data, int len, char* chalMark); #define MSG_TOPO_CHANGE_DEVICES_STR "devices"
int kk_ipc_init(ipc_type type, ipc_cb cb, char* chalMark, char* ip);
int kk_ipc_deinit(); typedef void ipc_cb(void* data, int len, char* chalMark);
int kk_ipc_send(ipc_type type, void* data, int len); int kk_ipc_init(ipc_type type, ipc_cb cb, char* chalMark, char* ip);
int kk_ipc_send_ex(ipc_type type, void* data, int len, char* chalMark); int kk_ipc_deinit(ipc_type type);
int kk_ipc_send(ipc_type type, void* data, int len);
#if defined(__cplusplus) int kk_ipc_send_ex(ipc_type type, void* data, int len, char* chalMark);
}
#endif #if defined(__cplusplus)
#endif }
#endif
#endif
...@@ -320,7 +320,7 @@ static void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) ...@@ -320,7 +320,7 @@ static void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
} }
int res = 0; int res = 0;
kk_tcp_ctrl_t* tcp_ctrl = (kk_tcp_ctrl_t*)watcher->data; kk_tcp_ctrl_t* tcp_ctrl = (kk_tcp_ctrl_t*)watcher->data;
int32_t bytes = read(watcher->fd, buffer, sizeof(buffer)); int32_t bytes = recv(watcher->fd, buffer, sizeof(buffer),0);
if (-1 == bytes) { if (-1 == bytes) {
//tcp Error //tcp Error
if (EINTR != errno && EAGAIN != errno) { if (EINTR != errno && EAGAIN != errno) {
...@@ -338,7 +338,7 @@ static void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) ...@@ -338,7 +338,7 @@ static void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
free(watcher); free(watcher);
} else { } else {
//intf("READ:\r\n %s\r\n", buffer); //intf("READ:\r\n %s\r\n", buffer);
printf("read_cb deviceCode ip sock [%s][%s][%d]",tcp_ctrl->deviceCode,tcp_ctrl->ip, tcp_ctrl->sock); //printf("read_cb deviceCode ip sock [%s][%s][%d] \n",tcp_ctrl->deviceCode,tcp_ctrl->ip, tcp_ctrl->sock);
if (g_cb != NULL){ if (g_cb != NULL){
g_cb(buffer,bytes,tcp_ctrl->deviceCode); g_cb(buffer,bytes,tcp_ctrl->deviceCode);
} }
...@@ -659,6 +659,7 @@ static void loop_tcp_client_thread(void *arg){ ...@@ -659,6 +659,7 @@ static void loop_tcp_client_thread(void *arg){
{ {
//接受网络数据 //接受网络数据
_MutexLock(g_client_ctrl.mutex); _MutexLock(g_client_ctrl.mutex);
memset(buf,0x0,sizeof(buf));
ret = read(g_client_ctrl.sd, buf, sizeof(buf)); ret = read(g_client_ctrl.sd, buf, sizeof(buf));
_MutexUnlock(g_client_ctrl.mutex); _MutexUnlock(g_client_ctrl.mutex);
...@@ -670,7 +671,7 @@ static void loop_tcp_client_thread(void *arg){ ...@@ -670,7 +671,7 @@ static void loop_tcp_client_thread(void *arg){
break; break;
} }
}else if(ret > 0){ }else if(ret > 0){
printf("buf = %s\n",buf); //printf("11buf = %s\n",buf);
if (g_client_ctrl.cb != NULL){ if (g_client_ctrl.cb != NULL){
g_client_ctrl.cb(buf,ret,""); g_client_ctrl.cb(buf,ret,"");
} }
...@@ -701,6 +702,7 @@ int kk_reset_retry_num(){ ...@@ -701,6 +702,7 @@ int kk_reset_retry_num(){
int kk_tcp_client_send(char* data, int len){ int kk_tcp_client_send(char* data, int len){
int ret = 0; int ret = 0;
int cnt = 0; int cnt = 0;
if ( data != NULL){ if ( data != NULL){
while(g_client_ctrl.sd == -1 && cnt < 5){ while(g_client_ctrl.sd == -1 && cnt < 5){
printf("[%s] tcp don't connect, sleep 1s !!!! \n",__FUNCTION__); printf("[%s] tcp don't connect, sleep 1s !!!! \n",__FUNCTION__);
......
...@@ -115,6 +115,14 @@ uint64_t HAL_UptimeMs(void) ...@@ -115,6 +115,14 @@ uint64_t HAL_UptimeMs(void)
return time_ms; return time_ms;
} }
uint64_t HAL_GetTime(void)
{
time_t t;
t = time(NULL);
return t;
}
uint64_t HAL_GetTimeMs(void) uint64_t HAL_GetTimeMs(void)
{ {
uint64_t time_ms; uint64_t time_ms;
......
#ifndef __KK_PRODUCT_H__ #ifndef __KK_PRODUCT_H__
#define __KK_PRODUCT_H__ #define __KK_PRODUCT_H__
#include <stdio.h> #include <stdio.h>
#ifndef _IN_ #ifndef _IN_
#define _IN_ #define _IN_
#endif #endif
#ifndef _OU_ #ifndef _OU_
#define _OU_ #define _OU_
#endif #endif
#define PRODUCT_TYPE_LEN (32+1) #define PRODUCT_TYPE_LEN (32+1)
#define PRODUCT_CODE_LEN (32+1) #define PRODUCT_CODE_LEN (32+1)
#define DEVICE_CODE_LEN (32+1) #define DEVICE_CODE_LEN (32+1)
#define MAC_ADDR_LEN_MAX (10) #define MAC_ADDR_LEN_MAX (10)
#define PID_STRLEN_MAX (64) #define PID_STRLEN_MAX (64)
#define MID_STRLEN_MAX (64) #define MID_STRLEN_MAX (64)
#define IOTX_URI_MAX_LEN (135) /* IoTx CoAP/HTTP uri & MQTT topic maximal length */ #define IOTX_URI_MAX_LEN (135) /* IoTx CoAP/HTTP uri & MQTT topic maximal length */
#define PID_STR_MAXLEN (64) #define PID_STR_MAXLEN (64)
#define MID_STR_MAXLEN (64) #define MID_STR_MAXLEN (64)
#define PRODUCT_SECRET_MAXLEN (64 + 1) #define PRODUCT_SECRET_MAXLEN (64 + 1)
#define FIRMWARE_VERSION_MAXLEN (32 + 1) #define FIRMWARE_VERSION_MAXLEN (32 + 1)
#define VERSION_MAXLEN (32 + 1) #define VERSION_MAXLEN (32 + 1)
#define HAL_CID_LEN (64 + 1) #define HAL_CID_LEN (64 + 1)
#define NETWORK_ADDR_LEN (16) /* IPÍøÂçµØÖ·µÄ³¤¶È */ #define NETWORK_ADDR_LEN (16+1) /* IPÍøÂçµØÖ·µÄ³¤¶È */
#define MAC_ADDR_LEN (17+1) #define MAC_ADDR_LEN (17+1)
#define SN_ADDR_LEN (32+1) #define SN_ADDR_LEN (32+1)
#define PRODUCT_TPYE "kk" #define PRODUCT_TPYE "kk"
#define PRODUCT_CODE "15" #define PRODUCT_CODE "15"
int HAL_SetProduct_Type(_IN_ char *product_type); int HAL_SetProduct_Type(_IN_ char *product_type);
int HAL_SetProduct_Code(_IN_ char *product_code); int HAL_SetProduct_Code(_IN_ char *product_code);
int HAL_SetDevice_Code(_IN_ char *device_code); int HAL_SetDevice_Code(_IN_ char *device_code);
int HAL_GetProduct_Type(_OU_ char *product_type); int HAL_GetProduct_Type(_OU_ char *product_type);
int HAL_GetProduct_Code(_OU_ char *product_code); int HAL_GetProduct_Code(_OU_ char *product_code);
int HAL_GetDevice_Code(_OU_ char *device_code); int HAL_GetDevice_Code(_OU_ char *device_code);
#endif #endif
...@@ -2885,7 +2885,7 @@ static int MQTTAsync_cleanSession(Clients* client) ...@@ -2885,7 +2885,7 @@ static int MQTTAsync_cleanSession(Clients* client)
static int MQTTAsync_deliverMessage(MQTTAsyncs* m, char* topicName, size_t topicLen, MQTTAsync_message* mm) static int MQTTAsync_deliverMessage(MQTTAsyncs* m, char* topicName, size_t topicLen, MQTTAsync_message* mm)
{ {
int rc; int rc;
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d", Log(TRACE_MIN, -1, "Calling messageArrived for client %s, queue depth %d",
m->c->clientID, m->c->messageQueue->count); m->c->clientID, m->c->messageQueue->count);
rc = (*(m->ma))(m->maContext, topicName, (int)topicLen, mm); rc = (*(m->ma))(m->maContext, topicName, (int)topicLen, mm);
...@@ -2902,7 +2902,6 @@ void Protocol_processPublication(Publish* publish, Clients* client, int allocate ...@@ -2902,7 +2902,6 @@ void Protocol_processPublication(Publish* publish, Clients* client, int allocate
MQTTAsync_message* mm = NULL; MQTTAsync_message* mm = NULL;
MQTTAsync_message initialized = MQTTAsync_message_initializer; MQTTAsync_message initialized = MQTTAsync_message_initializer;
int rc = 0; int rc = 0;
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
FUNC_ENTRY; FUNC_ENTRY;
if ((mm = malloc(sizeof(MQTTAsync_message))) == NULL) if ((mm = malloc(sizeof(MQTTAsync_message))) == NULL)
......
...@@ -304,7 +304,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock) ...@@ -304,7 +304,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock)
Clients* client = NULL; Clients* client = NULL;
char* clientid = NULL; char* clientid = NULL;
int rc = TCPSOCKET_COMPLETE; int rc = TCPSOCKET_COMPLETE;
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
FUNC_ENTRY; FUNC_ENTRY;
client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
...@@ -313,7 +312,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock) ...@@ -313,7 +312,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock)
publish->header.bits.retain, publish->payloadlen, min(20, publish->payloadlen), publish->payload); publish->header.bits.retain, publish->payloadlen, min(20, publish->payloadlen), publish->payload);
if (publish->header.bits.qos == 0){ if (publish->header.bits.qos == 0){
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
Protocol_processPublication(publish, client, 1); Protocol_processPublication(publish, client, 1);
} }
else if (!Socket_noPendingWrites(sock)) else if (!Socket_noPendingWrites(sock))
...@@ -324,7 +322,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock) ...@@ -324,7 +322,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock)
rc = MQTTPacket_send_puback(publish->MQTTVersion, publish->msgId, &client->net, client->clientID); rc = MQTTPacket_send_puback(publish->MQTTVersion, publish->msgId, &client->net, client->clientID);
/* if we get a socket error from sending the puback, should we ignore the publication? */ /* if we get a socket error from sending the puback, should we ignore the publication? */
Protocol_processPublication(publish, client, 1); Protocol_processPublication(publish, client, 1);
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
} }
else if (publish->header.bits.qos == 2) else if (publish->header.bits.qos == 2)
{ {
...@@ -374,7 +371,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock) ...@@ -374,7 +371,6 @@ int MQTTProtocol_handlePublishes(void* pack, int sock)
publish1.payloadlen = m->publish->payloadlen; publish1.payloadlen = m->publish->payloadlen;
publish1.MQTTVersion = m->MQTTVersion; publish1.MQTTVersion = m->MQTTVersion;
publish1.properties = m->properties; publish1.properties = m->properties;
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
Protocol_processPublication(&publish1, client, 1); Protocol_processPublication(&publish1, client, 1);
ListRemove(&(state.publications), m->publish); ListRemove(&(state.publications), m->publish);
......
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdint.h>
#include "zc_defs.h"
#include "buf.h"
/*******************************************************************************/
/* Author's Note
* This buf.c is base on C99, that is, if buffer size is not enough,
* the return value of vsnprintf(3) is a number tell how many character should
* be output. vsnprintf in glibc 2.1 conforms to C99 , but glibc 2.0 doesn't.
* see manpage of vsnprintf(3) on you platform for more detail.
* So, what should you do if you want to using zlog on the platform that doesn't
* conform C99? My Answer is, crack zlog with a portable C99-vsnprintf, like this
* http://sourceforge.net/projects/ctrio/
* http://www.jhweiss.de/software/snprintf.html
* If you can see this note, you can fix it yourself? Aren't you? ^_^
* Oh, I put the snprintf in C99 standard here,
* vsnprintf is the same on return value.
7.19.6.5 The snprintf function
Synopsis
[#1]
#include <stdio.h>
int snprintf(char * restrict s, size_t n,
const char * restrict format, ...);
Description
[#2] The snprintf function is equivalent to fprintf, except
that the output is written into an array (specified by
argument s) rather than to a stream. If n is zero, nothing
is written, and s may be a null pointer. Otherwise, output
characters beyond the n-1st are discarded rather than being
written to the array, and a null character is written at the
end of the characters actually written into the array. If
copying takes place between objects that overlap, the
behavior is undefined.
Returns
[#3] The snprintf function returns the number of characters
that would have been written had n been sufficiently large,
not counting the terminating null character, or a negative
value if an encoding error occurred. Thus, the null-
terminated output has been completely written if and only if
the returned value is nonnegative and less than n.
*/
/*******************************************************************************/
void zlog_buf_profile(zlog_buf_t * a_buf, int flag)
{
//zc_assert(a_buf,);
zc_profile(flag, "---buf[%p][%ld-%ld][%ld][%s][%p:%ld]---",
a_buf,
a_buf->size_min, a_buf->size_max,
a_buf->size_real,
a_buf->truncate_str,
a_buf->start, a_buf->tail - a_buf->start);
return;
}
/*******************************************************************************/
void zlog_buf_del(zlog_buf_t * a_buf)
{
//zc_assert(a_buf,);
if (a_buf->start) free(a_buf->start);
zc_debug("zlog_buf_del[%p]", a_buf);
free(a_buf);
return;
}
zlog_buf_t *zlog_buf_new(size_t buf_size_min, size_t buf_size_max, const char *truncate_str)
{
zlog_buf_t *a_buf;
if (buf_size_min == 0) {
zc_error("buf_size_min == 0, not allowed");
return NULL;
}
if (buf_size_max != 0 && buf_size_max < buf_size_min) {
zc_error("buf_size_max[%lu] < buf_size_min[%lu] && buf_size_max != 0",
(unsigned long)buf_size_max, (unsigned long)buf_size_min);
return NULL;
}
a_buf = calloc(1, sizeof(*a_buf));
if (!a_buf) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
if (truncate_str) {
if (strlen(truncate_str) > sizeof(a_buf->truncate_str) - 1) {
zc_error("truncate_str[%s] overflow", truncate_str);
goto err;
} else {
strcpy(a_buf->truncate_str, truncate_str);
}
a_buf->truncate_str_len = strlen(truncate_str);
}
a_buf->size_min = buf_size_min;
a_buf->size_max = buf_size_max;
a_buf->size_real = a_buf->size_min;
a_buf->start = calloc(1, a_buf->size_real);
if (!a_buf->start) {
zc_error("calloc fail, errno[%d]", errno);
goto err;
}
a_buf->tail = a_buf->start;
a_buf->end_plus_1 = a_buf->start + a_buf->size_real;
a_buf->end = a_buf->end_plus_1 - 1;
//zlog_buf_profile(a_buf, ZC_DEBUG);
return a_buf;
err:
zlog_buf_del(a_buf);
return NULL;
}
/*******************************************************************************/
static void zlog_buf_truncate(zlog_buf_t * a_buf)
{
char *p;
size_t len;
if ((a_buf->truncate_str)[0] == '\0') return;
p = (a_buf->tail - a_buf->truncate_str_len);
if (p < a_buf->start) p = a_buf->start;
len = a_buf->tail - p;
memcpy(p, a_buf->truncate_str, len);
return;
}
/*******************************************************************************/
/* return 0: success
* return <0: fail, set size_real to -1;
* return >0: by conf limit, can't extend size
* increment must > 0
*/
static int zlog_buf_resize(zlog_buf_t * a_buf, size_t increment)
{
int rc = 0;
size_t new_size = 0;
size_t len = 0;
char *p = NULL;
if (a_buf->size_max != 0 && a_buf->size_real >= a_buf->size_max) {
zc_error("a_buf->size_real[%ld] >= a_buf->size_max[%ld]",
a_buf->size_real, a_buf->size_max);
return 1;
}
if (a_buf->size_max == 0) {
/* unlimit */
new_size = a_buf->size_real + 1.5 * increment;
} else {
/* limited */
if (a_buf->size_real + increment <= a_buf->size_max) {
new_size = a_buf->size_real + increment;
} else {
new_size = a_buf->size_max;
rc = 1;
}
}
len = a_buf->tail - a_buf->start;
p = realloc(a_buf->start, new_size);
if (!p) {
zc_error("realloc fail, errno[%d]", errno);
free(a_buf->start);
a_buf->start = NULL;
a_buf->tail = NULL;
a_buf->end = NULL;
a_buf->end_plus_1 = NULL;
return -1;
} else {
a_buf->start = p;
a_buf->tail = p + len;
a_buf->size_real = new_size;
a_buf->end_plus_1 = a_buf->start + new_size;
a_buf->end = a_buf->end_plus_1 - 1;
}
return rc;
}
int zlog_buf_vprintf(zlog_buf_t * a_buf, const char *format, va_list args)
{
va_list ap;
size_t size_left;
int nwrite;
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
va_copy(ap, args);
size_left = a_buf->end_plus_1 - a_buf->tail;
nwrite = vsnprintf(a_buf->tail, size_left, format, ap);
if (nwrite >= 0 && nwrite < size_left) {
a_buf->tail += nwrite;
//*(a_buf->tail) = '\0';
return 0;
} else if (nwrite < 0) {
zc_error("vsnprintf fail, errno[%d]", errno);
zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format);
return -1;
} else if (nwrite >= size_left) {
int rc;
//zc_debug("nwrite[%d]>=size_left[%ld],format[%s],resize", nwrite, size_left, format);
rc = zlog_buf_resize(a_buf, nwrite - size_left + 1);
if (rc > 0) {
zc_error("conf limit to %ld, can't extend, so truncate", a_buf->size_max);
va_copy(ap, args);
size_left = a_buf->end_plus_1 - a_buf->tail;
vsnprintf(a_buf->tail, size_left, format, ap);
a_buf->tail += size_left - 1;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
va_copy(ap, args);
size_left = a_buf->end_plus_1 - a_buf->tail;
nwrite = vsnprintf(a_buf->tail, size_left, format, ap);
if (nwrite < 0) {
zc_error("vsnprintf fail, errno[%d]", errno);
zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format);
return -1;
} else {
a_buf->tail += nwrite;
//*(a_buf->tail) = '\0';
return 0;
}
}
}
return 0;
}
/*******************************************************************************/
/* if width > num_len, 0 padding, else output num */
int zlog_buf_printf_dec32(zlog_buf_t * a_buf, uint32_t ui32, int width)
{
unsigned char *p;
char *q;
unsigned char tmp[ZLOG_INT32_LEN + 1];
size_t num_len, zero_len, out_len;
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
p = tmp + ZLOG_INT32_LEN;
do {
*--p = (unsigned char) (ui32 % 10 + '0');
} while (ui32 /= 10);
/* zero or space padding */
num_len = (tmp + ZLOG_INT32_LEN) - p;
if (width > num_len) {
zero_len = width - num_len;
out_len = width;
} else {
zero_len = 0;
out_len = num_len;
}
if ((q = a_buf->tail + out_len) > a_buf->end) {
int rc;
//zc_debug("size_left not enough, resize");
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
if (rc > 0) {
size_t len_left;
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
len_left = a_buf->end - a_buf->tail;
if (len_left <= zero_len) {
zero_len = len_left;
num_len = 0;
} else if (len_left > zero_len) {
/* zero_len not changed */
num_len = len_left - zero_len;
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail += len_left;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
q = a_buf->tail + out_len; /* re-calculate p*/
}
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail = q;
//*(a_buf->tail) = '\0';
return 0;
}
/*******************************************************************************/
int zlog_buf_printf_dec64(zlog_buf_t * a_buf, uint64_t ui64, int width)
{
unsigned char *p;
char *q;
unsigned char tmp[ZLOG_INT64_LEN + 1];
size_t num_len, zero_len, out_len;
uint32_t ui32;
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
p = tmp + ZLOG_INT64_LEN;
if (ui64 <= ZLOG_MAX_UINT32_VALUE) {
/*
* To divide 64-bit numbers and to find remainders
* on the x86 platform gcc and icc call the libc functions
* [u]divdi3() and [u]moddi3(), they call another function
* in its turn. On FreeBSD it is the qdivrem() function,
* its source code is about 170 lines of the code.
* The glibc counterpart is about 150 lines of the code.
*
* For 32-bit numbers and some divisors gcc and icc use
* a inlined multiplication and shifts. For example,
* unsigned "i32 / 10" is compiled to
*
* (i32 * 0xCCCCCCCD) >> 35
*/
ui32 = (uint32_t) ui64;
do {
*--p = (unsigned char) (ui32 % 10 + '0');
} while (ui32 /= 10);
} else {
do {
*--p = (unsigned char) (ui64 % 10 + '0');
} while (ui64 /= 10);
}
/* zero or space padding */
num_len = (tmp + ZLOG_INT64_LEN) - p;
if (width > num_len) {
zero_len = width - num_len;
out_len = width;
} else {
zero_len = 0;
out_len = num_len;
}
if ((q = a_buf->tail + out_len) > a_buf->end) {
int rc;
//zc_debug("size_left not enough, resize");
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
if (rc > 0) {
size_t len_left;
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
len_left = a_buf->end - a_buf->tail;
if (len_left <= zero_len) {
zero_len = len_left;
num_len = 0;
} else if (len_left > zero_len) {
/* zero_len not changed */
num_len = len_left - zero_len;
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail += len_left;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
q = a_buf->tail + out_len; /* re-calculate p*/
}
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail = q;
//*(a_buf->tail) = '\0';
return 0;
}
/*******************************************************************************/
int zlog_buf_printf_hex(zlog_buf_t * a_buf, uint32_t ui32, int width)
{
unsigned char *p;
char *q;
unsigned char tmp[ZLOG_INT32_LEN + 1];
size_t num_len, zero_len, out_len;
static unsigned char hex[] = "0123456789abcdef";
//static unsigned char HEX[] = "0123456789ABCDEF";
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
p = tmp + ZLOG_INT32_LEN;
do {
/* the "(uint32_t)" cast disables the BCC's warning */
*--p = hex[(uint32_t) (ui32 & 0xf)];
} while (ui32 >>= 4);
#if 0
} else { /* is_hex == 2 */
do {
/* the "(uint32_t)" cast disables the BCC's warning */
*--p = HEX[(uint32_t) (ui64 & 0xf)];
} while (ui64 >>= 4);
}
#endif
/* zero or space padding */
num_len = (tmp + ZLOG_INT32_LEN) - p;
if (width > num_len) {
zero_len = width - num_len;
out_len = width;
} else {
zero_len = 0;
out_len = num_len;
}
if ((q = a_buf->tail + out_len) > a_buf->end) {
int rc;
//zc_debug("size_left not enough, resize");
rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail));
if (rc > 0) {
size_t len_left;
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
len_left = a_buf->end - a_buf->tail;
if (len_left <= zero_len) {
zero_len = len_left;
num_len = 0;
} else if (len_left > zero_len) {
/* zero_len not changed */
num_len = len_left - zero_len;
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail += len_left;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
q = a_buf->tail + out_len; /* re-calculate p*/
}
}
if (zero_len) memset(a_buf->tail, '0', zero_len);
memcpy(a_buf->tail + zero_len, p, num_len);
a_buf->tail = q;
//*(a_buf->tail) = '\0';
return 0;
}
/*******************************************************************************/
int zlog_buf_append(zlog_buf_t * a_buf, const char *str, size_t str_len)
{
char *p;
#if 0
if (str_len <= 0 || str == NULL) {
return 0;
}
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
#endif
if ((p = a_buf->tail + str_len) > a_buf->end) {
int rc;
//zc_debug("size_left not enough, resize");
rc = zlog_buf_resize(a_buf, str_len - (a_buf->end - a_buf->tail));
if (rc > 0) {
size_t len_left;
zc_error("conf limit to %ld, can't extend, so output",
a_buf->size_max);
len_left = a_buf->end - a_buf->tail;
memcpy(a_buf->tail, str, len_left);
a_buf->tail += len_left;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
p = a_buf->tail + str_len; /* re-calculate p*/
}
}
memcpy(a_buf->tail, str, str_len);
a_buf->tail = p;
// *(a_buf->tail) = '\0';
return 0;
}
/*******************************************************************************/
int zlog_buf_adjust_append(zlog_buf_t * a_buf, const char *str, size_t str_len,
int left_adjust, int zero_pad, size_t in_width, size_t out_width)
{
size_t append_len = 0;
size_t source_len = 0;
size_t space_len = 0;
#if 0
if (str_len <= 0 || str == NULL) {
return 0;
}
#endif
if (!a_buf->start) {
zc_error("pre-use of zlog_buf_resize fail, so can't convert");
return -1;
}
/* calculate how many character will be got from str */
if (out_width == 0 || str_len < out_width) {
source_len = str_len;
} else {
source_len = out_width;
}
/* calculate how many character will be output */
if (in_width == 0 || source_len >= in_width ) {
append_len = source_len;
space_len = 0;
} else {
append_len = in_width;
space_len = in_width - source_len;
}
/* |-----append_len-----------| */
/* |-source_len---|-space_len-| left_adjust */
/* |-space_len---|-source_len-| right_adjust */
/* |-(size_real-1)---| size not enough */
if (append_len > a_buf->end - a_buf->tail) {
int rc = 0;
//zc_debug("size_left not enough, resize");
rc = zlog_buf_resize(a_buf, append_len - (a_buf->end -a_buf->tail));
if (rc > 0) {
zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max);
append_len = (a_buf->end - a_buf->tail);
if (left_adjust) {
if (source_len < append_len) {
space_len = append_len - source_len;
} else {
source_len = append_len;
space_len = 0;
}
if (space_len) memset(a_buf->tail + source_len, ' ', space_len);
memcpy(a_buf->tail, str, source_len);
} else {
if (space_len < append_len) {
source_len = append_len - space_len;
} else {
space_len = append_len;
source_len = 0;
}
if (space_len) {
if (zero_pad) {
memset(a_buf->tail, '0', space_len);
} else {
memset(a_buf->tail, ' ', space_len);
}
}
memcpy(a_buf->tail + space_len, str, source_len);
}
a_buf->tail += append_len;
//*(a_buf->tail) = '\0';
zlog_buf_truncate(a_buf);
return 1;
} else if (rc < 0) {
zc_error("zlog_buf_resize fail");
return -1;
} else {
//zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real);
}
}
if (left_adjust) {
if (space_len) memset(a_buf->tail + source_len, ' ', space_len);
memcpy(a_buf->tail, str, source_len);
} else {
if (space_len) {
if (zero_pad) {
memset(a_buf->tail, '0', space_len);
} else {
memset(a_buf->tail, ' ', space_len);
}
}
memcpy(a_buf->tail + space_len, str, source_len);
}
a_buf->tail += append_len;
//*(a_buf->tail) = '\0';
return 0;
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_buf_h
#define __zlog_buf_h
/* buf, is a dynamic expand buffer for one single log,
* as one single log will interlace if use multiple write() to file.
* and buf is always keep in a thread, to make each thread has its
* own buffer to avoid lock.
*/
#include <stdarg.h>
#include <stdint.h>
typedef struct zlog_buf_s {
char *start;
char *tail;
char *end;
char *end_plus_1;
size_t size_min;
size_t size_max;
size_t size_real;
char truncate_str[MAXLEN_PATH + 1];
size_t truncate_str_len;
} zlog_buf_t;
zlog_buf_t *zlog_buf_new(size_t min, size_t max, const char *truncate_str);
void zlog_buf_del(zlog_buf_t * a_buf);
void zlog_buf_profile(zlog_buf_t * a_buf, int flag);
int zlog_buf_vprintf(zlog_buf_t * a_buf, const char *format, va_list args);
int zlog_buf_append(zlog_buf_t * a_buf, const char *str, size_t str_len);
int zlog_buf_adjust_append(zlog_buf_t * a_buf, const char *str, size_t str_len,
int left_adjust, int zero_pad, size_t in_width, size_t out_width);
int zlog_buf_printf_dec32(zlog_buf_t * a_buf, uint32_t ui32, int width);
int zlog_buf_printf_dec64(zlog_buf_t * a_buf, uint64_t ui64, int width);
int zlog_buf_printf_hex(zlog_buf_t * a_buf, uint32_t ui32, int width);
#define zlog_buf_restart(a_buf) do { \
a_buf->tail = a_buf->start; \
} while(0)
#define zlog_buf_len(a_buf) (a_buf->tail - a_buf->start)
#define zlog_buf_str(a_buf) (a_buf->start)
#define zlog_buf_seal(a_buf) do {*(a_buf)->tail = '\0';} while (0)
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "category.h"
#include "rule.h"
#include "zc_defs.h"
void zlog_category_profile(zlog_category_t *a_category, int flag)
{
int i;
zlog_rule_t *a_rule;
zc_assert(a_category,);
zc_profile(flag, "--category[%p][%s][%p]--",
a_category,
a_category->name,
a_category->fit_rules);
if (a_category->fit_rules) {
zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
zlog_rule_profile(a_rule, flag);
}
}
return;
}
/*******************************************************************************/
void zlog_category_del(zlog_category_t * a_category)
{
zc_assert(a_category,);
if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
zc_debug("zlog_category_del[%p]", a_category);
free(a_category);
return;
}
/* overlap one rule's level bitmap to cateogry,
* so category can judge whether a log level will be output by itself
* It is safe when configure is reloaded, when rule will be released an recreated
*/
static void zlog_cateogry_overlap_bitmap(zlog_category_t * a_category, zlog_rule_t *a_rule)
{
int i;
for(i = 0; i < sizeof(a_rule->level_bitmap); i++) {
a_category->level_bitmap[i] |= a_rule->level_bitmap[i];
}
}
static int zlog_category_obtain_rules(zlog_category_t * a_category, zc_arraylist_t * rules)
{
int i;
int count = 0;
int fit = 0;
zlog_rule_t *a_rule;
zlog_rule_t *wastebin_rule = NULL;
/* before set, clean last fit rules first */
if (a_category->fit_rules) zc_arraylist_del(a_category->fit_rules);
memset(a_category->level_bitmap, 0x00, sizeof(a_category->level_bitmap));
a_category->fit_rules = zc_arraylist_new(NULL);
if (!(a_category->fit_rules)) {
zc_error("zc_arraylist_new fail");
return -1;
}
/* get match rules from all rules */
zc_arraylist_foreach(rules, i, a_rule) {
fit = zlog_rule_match_category(a_rule, a_category->name);
if (fit) {
if (zc_arraylist_add(a_category->fit_rules, a_rule)) {
zc_error("zc_arrylist_add fail");
goto err;
}
zlog_cateogry_overlap_bitmap(a_category, a_rule);
count++;
}
if (zlog_rule_is_wastebin(a_rule)) {
wastebin_rule = a_rule;
}
}
if (count == 0) {
if (wastebin_rule) {
zc_debug("category[%s], no match rules, use wastebin_rule", a_category->name);
if (zc_arraylist_add(a_category->fit_rules, wastebin_rule)) {
zc_error("zc_arrylist_add fail");
goto err;
}
zlog_cateogry_overlap_bitmap(a_category, wastebin_rule);
count++;
} else {
zc_debug("category[%s], no match rules & no wastebin_rule", a_category->name);
}
}
return 0;
err:
zc_arraylist_del(a_category->fit_rules);
a_category->fit_rules = NULL;
return -1;
}
zlog_category_t *zlog_category_new(const char *name, zc_arraylist_t * rules)
{
size_t len;
zlog_category_t *a_category;
zc_assert(name, NULL);
zc_assert(rules, NULL);
len = strlen(name);
if (len > sizeof(a_category->name) - 1) {
zc_error("name[%s] too long", name);
return NULL;
}
a_category = calloc(1, sizeof(zlog_category_t));
if (!a_category) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
strcpy(a_category->name, name);
a_category->name_len = len;
if (zlog_category_obtain_rules(a_category, rules)) {
zc_error("zlog_category_fit_rules fail");
goto err;
}
zlog_category_profile(a_category, ZC_DEBUG);
return a_category;
err:
zlog_category_del(a_category);
return NULL;
}
/*******************************************************************************/
/* update success: fit_rules 1, fit_rules_backup 1 */
/* update fail: fit_rules 0, fit_rules_backup 1 */
int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * new_rules)
{
zc_assert(a_category, -1);
zc_assert(new_rules, -1);
/* 1st, mv fit_rules fit_rules_backup */
if (a_category->fit_rules_backup) zc_arraylist_del(a_category->fit_rules_backup);
a_category->fit_rules_backup = a_category->fit_rules;
a_category->fit_rules = NULL;
memcpy(a_category->level_bitmap_backup, a_category->level_bitmap,
sizeof(a_category->level_bitmap));
/* 2nd, obtain new_rules to fit_rules */
if (zlog_category_obtain_rules(a_category, new_rules)) {
zc_error("zlog_category_obtain_rules fail");
a_category->fit_rules = NULL;
return -1;
}
/* keep the fit_rules_backup not change, return */
return 0;
}
/* commit fail: fit_rules_backup != 0 */
/* commit success: fit_rules 1, fit_rules_backup 0 */
void zlog_category_commit_rules(zlog_category_t * a_category)
{
zc_assert(a_category,);
if (!a_category->fit_rules_backup) {
zc_warn("a_category->fit_rules_backup is NULL, never update before");
return;
}
zc_arraylist_del(a_category->fit_rules_backup);
a_category->fit_rules_backup = NULL;
memset(a_category->level_bitmap_backup, 0x00,
sizeof(a_category->level_bitmap_backup));
return;
}
/* rollback fail: fit_rules_backup != 0 */
/* rollback success: fit_rules 1, fit_rules_backup 0 */
/* so whether update succes or not, make things back to old */
void zlog_category_rollback_rules(zlog_category_t * a_category)
{
zc_assert(a_category,);
if (!a_category->fit_rules_backup) {
zc_warn("a_category->fit_rules_backup in NULL, never update before");
return;
}
if (a_category->fit_rules) {
/* update success, rm new and backup */
zc_arraylist_del(a_category->fit_rules);
a_category->fit_rules = a_category->fit_rules_backup;
a_category->fit_rules_backup = NULL;
} else {
/* update fail, just backup */
a_category->fit_rules = a_category->fit_rules_backup;
a_category->fit_rules_backup = NULL;
}
memcpy(a_category->level_bitmap, a_category->level_bitmap_backup,
sizeof(a_category->level_bitmap));
memset(a_category->level_bitmap_backup, 0x00,
sizeof(a_category->level_bitmap_backup));
return; /* always success */
}
/*******************************************************************************/
int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread)
{
int i;
int rc = 0;
zlog_rule_t *a_rule;
/* go through all match rules to output */
zc_arraylist_foreach(a_category->fit_rules, i, a_rule) {
rc = zlog_rule_output(a_rule, a_thread);
}
return rc;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_category_h
#define __zlog_category_h
#include "zc_defs.h"
#include "thread.h"
typedef struct zlog_category_s {
char name[MAXLEN_PATH + 1];
size_t name_len;
unsigned char level_bitmap[32];
unsigned char level_bitmap_backup[32];
zc_arraylist_t *fit_rules;
zc_arraylist_t *fit_rules_backup;
} zlog_category_t;
zlog_category_t *zlog_category_new(const char *name, zc_arraylist_t * rules);
void zlog_category_del(zlog_category_t * a_category);
void zlog_category_profile(zlog_category_t *a_category, int flag);
int zlog_category_update_rules(zlog_category_t * a_category, zc_arraylist_t * new_rules);
void zlog_category_commit_rules(zlog_category_t * a_category);
void zlog_category_rollback_rules(zlog_category_t * a_category);
int zlog_category_output(zlog_category_t * a_category, zlog_thread_t * a_thread);
#define zlog_category_needless_level(a_category, lv) \
a_category && !((a_category->level_bitmap[lv/8] >> (7 - lv % 8)) & 0x01)
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "zc_defs.h"
#include "category_table.h"
void zlog_category_table_profile(zc_hashtable_t * categories, int flag)
{
zc_hashtable_entry_t *a_entry;
zlog_category_t *a_category;
zc_assert(categories,);
zc_profile(flag, "-category_table[%p]-", categories);
zc_hashtable_foreach(categories, a_entry) {
a_category = (zlog_category_t *) a_entry->value;
zlog_category_profile(a_category, flag);
}
return;
}
/*******************************************************************************/
void zlog_category_table_del(zc_hashtable_t * categories)
{
zc_assert(categories,);
zc_hashtable_del(categories);
zc_debug("zlog_category_table_del[%p]", categories);
return;
}
zc_hashtable_t *zlog_category_table_new(void)
{
zc_hashtable_t *categories;
categories = zc_hashtable_new(20,
(zc_hashtable_hash_fn) zc_hashtable_str_hash,
(zc_hashtable_equal_fn) zc_hashtable_str_equal,
NULL, (zc_hashtable_del_fn) zlog_category_del);
if (!categories) {
zc_error("zc_hashtable_new fail");
return NULL;
} else {
zlog_category_table_profile(categories, ZC_DEBUG);
return categories;
}
}
/*******************************************************************************/
int zlog_category_table_update_rules(zc_hashtable_t * categories, zc_arraylist_t * new_rules)
{
zc_hashtable_entry_t *a_entry;
zlog_category_t *a_category;
zc_assert(categories, -1);
zc_hashtable_foreach(categories, a_entry) {
a_category = (zlog_category_t *) a_entry->value;
if (zlog_category_update_rules(a_category, new_rules)) {
zc_error("zlog_category_update_rules fail, try rollback");
return -1;
}
}
return 0;
}
void zlog_category_table_commit_rules(zc_hashtable_t * categories)
{
zc_hashtable_entry_t *a_entry;
zlog_category_t *a_category;
zc_assert(categories,);
zc_hashtable_foreach(categories, a_entry) {
a_category = (zlog_category_t *) a_entry->value;
zlog_category_commit_rules(a_category);
}
return;
}
void zlog_category_table_rollback_rules(zc_hashtable_t * categories)
{
zc_hashtable_entry_t *a_entry;
zlog_category_t *a_category;
zc_assert(categories,);
zc_hashtable_foreach(categories, a_entry) {
a_category = (zlog_category_t *) a_entry->value;
zlog_category_rollback_rules(a_category);
}
return;
}
/*******************************************************************************/
zlog_category_t *zlog_category_table_fetch_category(zc_hashtable_t * categories,
const char *category_name, zc_arraylist_t * rules)
{
zlog_category_t *a_category;
zc_assert(categories, NULL);
/* 1st find category in global category map */
a_category = zc_hashtable_get(categories, category_name);
if (a_category) return a_category;
/* else not found, create one */
a_category = zlog_category_new(category_name, rules);
if (!a_category) {
zc_error("zc_category_new fail");
return NULL;
}
if(zc_hashtable_put(categories, a_category->name, a_category)) {
zc_error("zc_hashtable_put fail");
goto err;
}
return a_category;
err:
zlog_category_del(a_category);
return NULL;
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_category_table_h
#define __zlog_category_table_h
#include "zc_defs.h"
#include "category.h"
zc_hashtable_t *zlog_category_table_new(void);
void zlog_category_table_del(zc_hashtable_t * categories);
void zlog_category_table_profile(zc_hashtable_t * categories, int flag);
/* if none, create new and return */
zlog_category_t *zlog_category_table_fetch_category(
zc_hashtable_t * categories,
const char *category_name, zc_arraylist_t * rules);
int zlog_category_table_update_rules(zc_hashtable_t * categories, zc_arraylist_t * new_rules);
void zlog_category_table_commit_rules(zc_hashtable_t * categories);
void zlog_category_table_rollback_rules(zc_hashtable_t * categories);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include "conf.h"
#include "rule.h"
#include "format.h"
#include "level_list.h"
#include "rotater.h"
#include "zc_defs.h"
/*******************************************************************************/
#define ZLOG_CONF_DEFAULT_FORMAT "default = \"%D %V [%p:%F:%L] %m%n\""
#define ZLOG_CONF_DEFAULT_RULE "*.* >stdout"
#define ZLOG_CONF_DEFAULT_BUF_SIZE_MIN 1024
#define ZLOG_CONF_DEFAULT_BUF_SIZE_MAX (2 * 1024 * 1024)
#define ZLOG_CONF_DEFAULT_FILE_PERMS 0600
#define ZLOG_CONF_DEFAULT_RELOAD_CONF_PERIOD 0
#define ZLOG_CONF_DEFAULT_FSYNC_PERIOD 0
#define ZLOG_CONF_BACKUP_ROTATE_LOCK_FILE "/tmp/zlog.lock"
/*******************************************************************************/
void zlog_conf_profile(zlog_conf_t * a_conf, int flag)
{
int i;
zlog_rule_t *a_rule;
zlog_format_t *a_format;
zc_assert(a_conf,);
zc_profile(flag, "-conf[%p]-", a_conf);
zc_profile(flag, "--global--");
zc_profile(flag, "---file[%s],mtime[%s]---", a_conf->file, a_conf->mtime);
zc_profile(flag, "---in-memory conf[%s]---", a_conf->cfg_ptr);
zc_profile(flag, "---strict init[%d]---", a_conf->strict_init);
zc_profile(flag, "---buffer min[%ld]---", a_conf->buf_size_min);
zc_profile(flag, "---buffer max[%ld]---", a_conf->buf_size_max);
if (a_conf->default_format) {
zc_profile(flag, "---default_format---");
zlog_format_profile(a_conf->default_format, flag);
}
zc_profile(flag, "---file perms[0%o]---", a_conf->file_perms);
zc_profile(flag, "---reload conf period[%ld]---", a_conf->reload_conf_period);
zc_profile(flag, "---fsync period[%ld]---", a_conf->fsync_period);
zc_profile(flag, "---rotate lock file[%s]---", a_conf->rotate_lock_file);
if (a_conf->rotater) zlog_rotater_profile(a_conf->rotater, flag);
if (a_conf->levels) zlog_level_list_profile(a_conf->levels, flag);
if (a_conf->formats) {
zc_profile(flag, "--format list[%p]--", a_conf->formats);
zc_arraylist_foreach(a_conf->formats, i, a_format) {
zlog_format_profile(a_format, flag);
}
}
if (a_conf->rules) {
zc_profile(flag, "--rule_list[%p]--", a_conf->rules);
zc_arraylist_foreach(a_conf->rules, i, a_rule) {
zlog_rule_profile(a_rule, flag);
}
}
return;
}
/*******************************************************************************/
void zlog_conf_del(zlog_conf_t * a_conf)
{
zc_assert(a_conf,);
if (a_conf->rotater) zlog_rotater_del(a_conf->rotater);
if (a_conf->levels) zlog_level_list_del(a_conf->levels);
if (a_conf->default_format) zlog_format_del(a_conf->default_format);
if (a_conf->formats) zc_arraylist_del(a_conf->formats);
if (a_conf->rules) zc_arraylist_del(a_conf->rules);
free(a_conf);
zc_debug("zlog_conf_del[%p]");
return;
}
static int zlog_conf_build_without_file(zlog_conf_t * a_conf);
static int zlog_conf_build_with_file(zlog_conf_t * a_conf);
static int zlog_conf_build_with_in_memory(zlog_conf_t * a_conf);
enum{
NO_CFG,
FILE_CFG,
IN_MEMORY_CFG
};
zlog_conf_t *zlog_conf_new(const char *config)
{
int nwrite = 0;
int cfg_source = 0;
zlog_conf_t *a_conf = NULL;
a_conf = calloc(1, sizeof(zlog_conf_t));
if (!a_conf) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
// Find content of pointer. If it starts with '[' then content are configurations.
if (config && config[0] != '\0' && config[0] != '[') {
nwrite = snprintf(a_conf->file, sizeof(a_conf->file), "%s", config);
cfg_source = FILE_CFG;
} else if (getenv("ZLOG_CONF_PATH") != NULL) {
nwrite = snprintf(a_conf->file, sizeof(a_conf->file), "%s", getenv("ZLOG_CONF_PATH"));
cfg_source = FILE_CFG;
} else if (config[0]=='[') {
memset(a_conf->file, 0x00, sizeof(a_conf->file));
nwrite = snprintf(a_conf->cfg_ptr, sizeof(a_conf->cfg_ptr), "%s", config);
cfg_source = IN_MEMORY_CFG;
if (nwrite < 0 || nwrite >= sizeof(a_conf->file)) {
zc_error("not enough space for configurations, nwrite=[%d], errno[%d]", nwrite, errno);
goto err;
}
} else {
memset(a_conf->file, 0x00, sizeof(a_conf->file));
cfg_source = NO_CFG;
}
if (nwrite < 0 || nwrite >= sizeof(a_conf->file) && cfg_source == FILE_CFG) {
zc_error("not enough space for path name, nwrite=[%d], errno[%d]", nwrite, errno);
goto err;
}
/* set default configuration start */
a_conf->strict_init = 1;
a_conf->buf_size_min = ZLOG_CONF_DEFAULT_BUF_SIZE_MIN;
a_conf->buf_size_max = ZLOG_CONF_DEFAULT_BUF_SIZE_MAX;
if (cfg_source == FILE_CFG) {
/* configure file as default lock file */
strcpy(a_conf->rotate_lock_file, a_conf->file);
} else {
strcpy(a_conf->rotate_lock_file, ZLOG_CONF_BACKUP_ROTATE_LOCK_FILE);
}
strcpy(a_conf->default_format_line, ZLOG_CONF_DEFAULT_FORMAT);
a_conf->file_perms = ZLOG_CONF_DEFAULT_FILE_PERMS;
a_conf->reload_conf_period = ZLOG_CONF_DEFAULT_RELOAD_CONF_PERIOD;
a_conf->fsync_period = ZLOG_CONF_DEFAULT_FSYNC_PERIOD;
/* set default configuration end */
a_conf->levels = zlog_level_list_new();
if (!a_conf->levels) {
zc_error("zlog_level_list_new fail");
goto err;
}
a_conf->formats = zc_arraylist_new((zc_arraylist_del_fn) zlog_format_del);
if (!a_conf->formats) {
zc_error("zc_arraylist_new fail");
goto err;
}
a_conf->rules = zc_arraylist_new((zc_arraylist_del_fn) zlog_rule_del);
if (!a_conf->rules) {
zc_error("init rule_list fail");
goto err;
}
if (cfg_source == FILE_CFG) {
if (zlog_conf_build_with_file(a_conf)) {
zc_error("zlog_conf_build_with_file fail");
goto err;
}
} else if (cfg_source == IN_MEMORY_CFG) {
if(zlog_conf_build_with_in_memory(a_conf)){
zc_error("zlog_conf_build_with_in_memory fail");
goto err;
}
} else {
if (zlog_conf_build_without_file(a_conf)) {
zc_error("zlog_conf_build_without_file fail");
goto err;
}
}
zlog_conf_profile(a_conf, ZC_DEBUG);
return a_conf;
err:
zlog_conf_del(a_conf);
return NULL;
}
/*******************************************************************************/
static int zlog_conf_build_without_file(zlog_conf_t * a_conf)
{
zlog_rule_t *default_rule;
a_conf->default_format = zlog_format_new(a_conf->default_format_line, &(a_conf->time_cache_count));
if (!a_conf->default_format) {
zc_error("zlog_format_new fail");
return -1;
}
a_conf->rotater = zlog_rotater_new(a_conf->rotate_lock_file);
if (!a_conf->rotater) {
zc_error("zlog_rotater_new fail");
return -1;
}
default_rule = zlog_rule_new(
ZLOG_CONF_DEFAULT_RULE,
a_conf->levels,
a_conf->default_format,
a_conf->formats,
a_conf->file_perms,
a_conf->fsync_period,
&(a_conf->time_cache_count));
if (!default_rule) {
zc_error("zlog_rule_new fail");
return -1;
}
/* add default rule */
if (zc_arraylist_add(a_conf->rules, default_rule)) {
zlog_rule_del(default_rule);
zc_error("zc_arraylist_add fail");
return -1;
}
return 0;
}
/*******************************************************************************/
static int zlog_conf_parse_line(zlog_conf_t * a_conf, char *line, int *section);
static int zlog_conf_build_with_file(zlog_conf_t * a_conf)
{
int rc = 0;
struct zlog_stat a_stat;
struct tm local_time;
FILE *fp = NULL;
char line[MAXLEN_CFG_LINE + 1];
size_t line_len;
char *pline = NULL;
char *p = NULL;
int line_no = 0;
int i = 0;
int in_quotation = 0;
int section = 0;
/* [global:1] [levels:2] [formats:3] [rules:4] */
if (lstat(a_conf->file, &a_stat)) {
zc_error("lstat conf file[%s] fail, errno[%d]", a_conf->file,
errno);
return -1;
}
localtime_r(&(a_stat.st_mtime), &local_time);
strftime(a_conf->mtime, sizeof(a_conf->mtime), "%F %T", &local_time);
if ((fp = fopen(a_conf->file, "r")) == NULL) {
zc_error("open configure file[%s] fail", a_conf->file);
return -1;
}
/* Now process the file.
*/
pline = line;
memset(&line, 0x00, sizeof(line));
while (fgets((char *)pline, sizeof(line) - (pline - line), fp) != NULL) {
++line_no;
line_len = strlen(pline);
if (0 == line_len) {
continue;
}
if (pline[line_len - 1] == '\n') {
pline[line_len - 1] = '\0';
}
/* check for end-of-section, comments, strip off trailing
* spaces and newline character.
*/
p = pline;
while (*p && isspace((int)*p))
++p;
if (*p == '\0' || *p == '#')
continue;
for (i = 0; p[i] != '\0'; ++i) {
pline[i] = p[i];
}
pline[i] = '\0';
for (p = pline + strlen(pline) - 1; isspace((int)*p); --p)
/*EMPTY*/;
if (*p == '\\') {
if ((p - line) > MAXLEN_CFG_LINE - 30) {
/* Oops the buffer is full - what now? */
pline = line;
} else {
for (p--; isspace((int)*p); --p)
/*EMPTY*/;
p++;
*p = 0;
pline = p;
continue;
}
} else
pline = line;
*++p = '\0';
/* clean the tail comments start from # and not in quotation */
in_quotation = 0;
for (p = line; *p != '\0'; p++) {
if (*p == '"') {
in_quotation ^= 1;
continue;
}
if (*p == '#' && !in_quotation) {
*p = '\0';
break;
}
}
/* we now have the complete line,
* and are positioned at the first non-whitespace
* character. So let's process it
*/
rc = zlog_conf_parse_line(a_conf, line, &section);
if (rc < 0) {
zc_error("parse configure file[%s]line_no[%ld] fail", a_conf->file, line_no);
zc_error("line[%s]", line);
goto exit;
} else if (rc > 0) {
zc_warn("parse configure file[%s]line_no[%ld] fail", a_conf->file, line_no);
zc_warn("line[%s]", line);
zc_warn("as strict init is set to false, ignore and go on");
rc = 0;
continue;
}
}
exit:
fclose(fp);
return rc;
}
/**********************************************************************/
static int zlog_conf_build_with_in_memory(zlog_conf_t * a_conf)
{
int rc = 0;
char line[MAXLEN_CFG_LINE + 1];
char *pline = NULL;
int section = 0;
pline = line;
memset(&line, 0x00, sizeof(line));
pline = strtok((char *)a_conf->cfg_ptr, "\n");
while (pline != NULL) {
rc = zlog_conf_parse_line(a_conf, pline, &section);
if (rc < 0) {
zc_error("parse in-memory configurations[%s] line [%s] fail", a_conf->cfg_ptr, pline);
break;
} else if (rc > 0) {
zc_error("parse in-memory configurations[%s] line [%s] fail", a_conf->cfg_ptr, pline);
zc_warn("as strict init is set to false, ignore and go on");
rc = 0;
continue;
}
pline = strtok(NULL, "\n");
}
return rc;
}
/* section [global:1] [levels:2] [formats:3] [rules:4] */
static int zlog_conf_parse_line(zlog_conf_t * a_conf, char *line, int *section)
{
int nscan;
int nread;
char name[MAXLEN_CFG_LINE + 1];
char word_1[MAXLEN_CFG_LINE + 1];
char word_2[MAXLEN_CFG_LINE + 1];
char word_3[MAXLEN_CFG_LINE + 1];
char value[MAXLEN_CFG_LINE + 1];
zlog_format_t *a_format = NULL;
zlog_rule_t *a_rule = NULL;
if (strlen(line) > MAXLEN_CFG_LINE) {
zc_error ("line_len[%ld] > MAXLEN_CFG_LINE[%ld], may cause overflow",
strlen(line), MAXLEN_CFG_LINE);
return -1;
}
/* get and set outer section flag, so it is a closure? haha */
if (line[0] == '[') {
int last_section = *section;
nscan = sscanf(line, "[ %[^] \t]", name);
if (STRCMP(name, ==, "global")) {
*section = 1;
} else if (STRCMP(name, ==, "levels")) {
*section = 2;
} else if (STRCMP(name, ==, "formats")) {
*section = 3;
} else if (STRCMP(name, ==, "rules")) {
*section = 4;
} else {
zc_error("wrong section name[%s]", name);
return -1;
}
/* check the sequence of section, must increase */
if (last_section >= *section) {
zc_error("wrong sequence of section, must follow global->levels->formats->rules");
return -1;
}
if (*section == 4) {
if (a_conf->reload_conf_period != 0
&& a_conf->fsync_period >= a_conf->reload_conf_period) {
/* as all rule will be rebuilt when conf is reload,
* so fsync_period > reload_conf_period will never
* cause rule to fsync it's file.
* fsync_period will be meaningless and down speed,
* so make it zero.
*/
zc_warn("fsync_period[%ld] >= reload_conf_period[%ld],"
"set fsync_period to zero");
a_conf->fsync_period = 0;
}
/* now build rotater and default_format
* from the unchanging global setting,
* for zlog_rule_new() */
a_conf->rotater = zlog_rotater_new(a_conf->rotate_lock_file);
if (!a_conf->rotater) {
zc_error("zlog_rotater_new fail");
return -1;
}
a_conf->default_format = zlog_format_new(a_conf->default_format_line,
&(a_conf->time_cache_count));
if (!a_conf->default_format) {
zc_error("zlog_format_new fail");
return -1;
}
}
return 0;
}
/* process detail */
switch (*section) {
case 1:
memset(name, 0x00, sizeof(name));
memset(value, 0x00, sizeof(value));
nscan = sscanf(line, " %[^=]= %s ", name, value);
if (nscan != 2) {
zc_error("sscanf [%s] fail, name or value is null", line);
return -1;
}
memset(word_1, 0x00, sizeof(word_1));
memset(word_2, 0x00, sizeof(word_2));
memset(word_3, 0x00, sizeof(word_3));
nread = 0;
nscan = sscanf(name, "%s%n%s%s", word_1, &nread, word_2, word_3);
if (STRCMP(word_1, ==, "strict") && STRCMP(word_2, ==, "init")) {
/* if environment variable ZLOG_STRICT_INIT is set
* then always make it strict
*/
if (STRICMP(value, ==, "false") && !getenv("ZLOG_STRICT_INIT")) {
a_conf->strict_init = 0;
} else {
a_conf->strict_init = 1;
}
} else if (STRCMP(word_1, ==, "buffer") && STRCMP(word_2, ==, "min")) {
a_conf->buf_size_min = zc_parse_byte_size(value);
} else if (STRCMP(word_1, ==, "buffer") && STRCMP(word_2, ==, "max")) {
a_conf->buf_size_max = zc_parse_byte_size(value);
} else if (STRCMP(word_1, ==, "file") && STRCMP(word_2, ==, "perms")) {
sscanf(value, "%o", &(a_conf->file_perms));
} else if (STRCMP(word_1, ==, "rotate") &&
STRCMP(word_2, ==, "lock") && STRCMP(word_3, ==, "file")) {
/* may overwrite the inner default value, or last value */
if (STRCMP(value, ==, "self")) {
strcpy(a_conf->rotate_lock_file, a_conf->file);
} else {
strcpy(a_conf->rotate_lock_file, value);
}
} else if (STRCMP(word_1, ==, "default") && STRCMP(word_2, ==, "format")) {
/* so the input now is [format = "xxyy"], fit format's style */
strcpy(a_conf->default_format_line, line + nread);
} else if (STRCMP(word_1, ==, "reload") &&
STRCMP(word_2, ==, "conf") && STRCMP(word_3, ==, "period")) {
a_conf->reload_conf_period = zc_parse_byte_size(value);
} else if (STRCMP(word_1, ==, "fsync") && STRCMP(word_2, ==, "period")) {
a_conf->fsync_period = zc_parse_byte_size(value);
} else {
zc_error("name[%s] is not any one of global options", name);
if (a_conf->strict_init) return -1;
}
break;
case 2:
if (zlog_level_list_set(a_conf->levels, line)) {
zc_error("zlog_level_list_set fail");
if (a_conf->strict_init) return -1;
}
break;
case 3:
a_format = zlog_format_new(line, &(a_conf->time_cache_count));
if (!a_format) {
zc_error("zlog_format_new fail [%s]", line);
if (a_conf->strict_init) return -1;
else break;
}
if (zc_arraylist_add(a_conf->formats, a_format)) {
zlog_format_del(a_format);
zc_error("zc_arraylist_add fail");
return -1;
}
break;
case 4:
a_rule = zlog_rule_new(line,
a_conf->levels,
a_conf->default_format,
a_conf->formats,
a_conf->file_perms,
a_conf->fsync_period,
&(a_conf->time_cache_count));
if (!a_rule) {
zc_error("zlog_rule_new fail [%s]", line);
if (a_conf->strict_init) return -1;
else break;
}
if (zc_arraylist_add(a_conf->rules, a_rule)) {
zlog_rule_del(a_rule);
zc_error("zc_arraylist_add fail");
return -1;
}
break;
default:
zc_error("not in any section");
return -1;
}
return 0;
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_conf_h
#define __zlog_conf_h
#include "zc_defs.h"
#include "format.h"
#include "rotater.h"
typedef struct zlog_conf_s {
char file[MAXLEN_PATH + 1];
char cfg_ptr[MAXLEN_CFG_LINE*MAXLINES_NO];
char mtime[20 + 1];
int strict_init;
size_t buf_size_min;
size_t buf_size_max;
char rotate_lock_file[MAXLEN_CFG_LINE + 1];
zlog_rotater_t *rotater;
char default_format_line[MAXLEN_CFG_LINE + 1];
zlog_format_t *default_format;
unsigned int file_perms;
size_t fsync_period;
size_t reload_conf_period;
zc_arraylist_t *levels;
zc_arraylist_t *formats;
zc_arraylist_t *rules;
int time_cache_count;
} zlog_conf_t;
extern zlog_conf_t * zlog_env_conf;
zlog_conf_t *zlog_conf_new(const char *config);
void zlog_conf_del(zlog_conf_t * a_conf);
void zlog_conf_profile(zlog_conf_t * a_conf, int flag);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#define _GNU_SOURCE // For distros like Centos for syscall interface
#include "fmacros.h"
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include "zc_defs.h"
#include "event.h"
void zlog_event_profile(zlog_event_t * a_event, int flag)
{
zc_assert(a_event,);
zc_profile(flag, "---event[%p][%s,%s][%s(%ld),%s(%ld),%ld,%d][%p,%s][%ld,%ld][%ld,%ld][%d]---",
a_event,
a_event->category_name, a_event->host_name,
a_event->file, a_event->file_len,
a_event->func, a_event->func_len,
a_event->line, a_event->level,
a_event->hex_buf, a_event->str_format,
a_event->time_stamp.tv_sec, a_event->time_stamp.tv_usec,
(long)a_event->pid, (long)a_event->tid,
a_event->time_cache_count);
return;
}
/*******************************************************************************/
void zlog_event_del(zlog_event_t * a_event)
{
zc_assert(a_event,);
if (a_event->time_caches) free(a_event->time_caches);
zc_debug("zlog_event_del[%p]", a_event);
free(a_event);
return;
}
zlog_event_t *zlog_event_new(int time_cache_count)
{
zlog_event_t *a_event;
a_event = calloc(1, sizeof(zlog_event_t));
if (!a_event) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_event->time_caches = calloc(time_cache_count, sizeof(zlog_time_cache_t));
if (!a_event->time_caches) {
zc_error("calloc fail, errno[%d]", errno);
free(a_event);
return NULL;
}
a_event->time_cache_count = time_cache_count;
/*
* at the zlog_init we gethostname,
* u don't always change your hostname, eh?
*/
if (gethostname(a_event->host_name, sizeof(a_event->host_name) - 1)) {
zc_error("gethostname fail, errno[%d]", errno);
goto err;
}
a_event->host_name_len = strlen(a_event->host_name);
/* tid is bound to a_event
* as in whole lifecycle event persists
* even fork to oth pid, tid not change
*/
a_event->tid = pthread_self();
a_event->tid_str_len = sprintf(a_event->tid_str, "%lu", (unsigned long)a_event->tid);
a_event->tid_hex_str_len = sprintf(a_event->tid_hex_str, "%x", (unsigned int)a_event->tid);
#ifdef __linux__
a_event->ktid = syscall(SYS_gettid);
#elif __APPLE__
uint64_t tid64;
pthread_threadid_np(NULL, &tid64);
a_event->tid = (pid_t)tid64;
#endif
#if defined __linux__ || __APPLE__
a_event->ktid_str_len = sprintf(a_event->ktid_str, "%u", (unsigned int)a_event->ktid);
#endif
//zlog_event_profile(a_event, ZC_DEBUG);
return a_event;
err:
zlog_event_del(a_event);
return NULL;
}
/*******************************************************************************/
void zlog_event_set_fmt(zlog_event_t * a_event,
char *category_name, size_t category_name_len,
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
const char *str_format, va_list str_args)
{
/*
* category_name point to zlog_category_output's category.name
*/
a_event->category_name = category_name;
a_event->category_name_len = category_name_len;
a_event->file = (char *) file;
a_event->file_len = file_len;
a_event->func = (char *) func;
a_event->func_len = func_len;
a_event->line = line;
a_event->level = level;
a_event->generate_cmd = ZLOG_FMT;
a_event->str_format = str_format;
va_copy(a_event->str_args, str_args);
/* pid should fetch eveytime, as no one knows,
* when does user fork his process
* so clean here, and fetch at spec.c
*/
a_event->pid = (pid_t) 0;
/* in a event's life cycle, time will be get when spec need,
* and keep unchange though all event's life cycle
* zlog_spec_write_time gettimeofday
*/
a_event->time_stamp.tv_sec = 0;
return;
}
void zlog_event_set_hex(zlog_event_t * a_event,
char *category_name, size_t category_name_len,
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
const void *hex_buf, size_t hex_buf_len)
{
/*
* category_name point to zlog_category_output's category.name
*/
a_event->category_name = category_name;
a_event->category_name_len = category_name_len;
a_event->file = (char *) file;
a_event->file_len = file_len;
a_event->func = (char *) func;
a_event->func_len = func_len;
a_event->line = line;
a_event->level = level;
a_event->generate_cmd = ZLOG_HEX;
a_event->hex_buf = hex_buf;
a_event->hex_buf_len = hex_buf_len;
/* pid should fetch eveytime, as no one knows,
* when does user fork his process
* so clean here, and fetch at spec.c
*/
a_event->pid = (pid_t) 0;
/* in a event's life cycle, time will be get when spec need,
* and keep unchange though all event's life cycle
*/
a_event->time_stamp.tv_sec = 0;
return;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_event_h
#define __zlog_event_h
#include <sys/types.h> /* for pid_t */
#include <sys/time.h> /* for struct timeval */
#include <pthread.h> /* for pthread_t */
#include <stdarg.h> /* for va_list */
#include "zc_defs.h"
typedef enum {
ZLOG_FMT = 0,
ZLOG_HEX = 1,
} zlog_event_cmd;
typedef struct zlog_time_cache_s {
char str[MAXLEN_CFG_LINE + 1];
size_t len;
time_t sec;
} zlog_time_cache_t;
typedef struct {
char *category_name;
size_t category_name_len;
char host_name[256 + 1];
size_t host_name_len;
const char *file;
size_t file_len;
const char *func;
size_t func_len;
long line;
int level;
const void *hex_buf;
size_t hex_buf_len;
const char *str_format;
va_list str_args;
zlog_event_cmd generate_cmd;
struct timeval time_stamp;
time_t time_local_sec;
struct tm time_local;
zlog_time_cache_t *time_caches;
int time_cache_count;
pid_t pid;
pid_t last_pid;
char pid_str[30 + 1];
size_t pid_str_len;
pthread_t tid;
char tid_str[30 + 1];
size_t tid_str_len;
char tid_hex_str[30 + 1];
size_t tid_hex_str_len;
#if defined __linux__ || __APPLE__
pid_t ktid;
char ktid_str[30+1];
size_t ktid_str_len;
#endif
} zlog_event_t;
zlog_event_t *zlog_event_new(int time_cache_count);
void zlog_event_del(zlog_event_t * a_event);
void zlog_event_profile(zlog_event_t * a_event, int flag);
void zlog_event_set_fmt(zlog_event_t * a_event,
char *category_name, size_t category_name_len,
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
const char *str_format, va_list str_args);
void zlog_event_set_hex(zlog_event_t * a_event,
char *category_name, size_t category_name_len,
const char *file, size_t file_len, const char *func, size_t func_len, long line, int level,
const void *hex_buf, size_t hex_buf_len);
#endif
#ifndef __zlog_fmacro_h
#define __zlog_fmacro_h
#define _DEFAULT_SOURCE
#if defined(__linux__) || defined(__OpenBSD__) || defined(_AIX)
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif
#ifndef _XOPEN_SOURCE_EXTENDED
#define _XOPEN_SOURCE_EXTENDED
#endif
#else
#define _XOPEN_SOURCE
#endif
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "zc_defs.h"
#include "thread.h"
#include "spec.h"
#include "format.h"
void zlog_format_profile(zlog_format_t * a_format, int flag)
{
zc_assert(a_format,);
zc_profile(flag, "---format[%p][%s = %s(%p)]---",
a_format,
a_format->name,
a_format->pattern,
a_format->pattern_specs);
#if 0
int i;
zlog_spec_t *a_spec;
zc_arraylist_foreach(a_format->pattern_specs, i, a_spec) {
zlog_spec_profile(a_spec, flag);
}
#endif
return;
}
/*******************************************************************************/
void zlog_format_del(zlog_format_t * a_format)
{
zc_assert(a_format,);
if (a_format->pattern_specs) {
zc_arraylist_del(a_format->pattern_specs);
}
zc_debug("zlog_format_del[%p]", a_format);
free(a_format);
return;
}
zlog_format_t *zlog_format_new(char *line, int * time_cache_count)
{
int nscan = 0;
zlog_format_t *a_format = NULL;
int nread = 0;
const char *p_start;
const char *p_end;
char *p;
char *q;
zlog_spec_t *a_spec;
zc_assert(line, NULL);
a_format = calloc(1, sizeof(zlog_format_t));
if (!a_format) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
/* line default = "%d(%F %X.%l) %-6V (%c:%F:%L) - %m%n"
* name default
* pattern %d(%F %X.%l) %-6V (%c:%F:%L) - %m%n
*/
memset(a_format->name, 0x00, sizeof(a_format->name));
nread = 0;
nscan = sscanf(line, " %[^= \t] = %n", a_format->name, &nread);
if (nscan != 1) {
zc_error("format[%s], syntax wrong", line);
goto err;
}
if (*(line + nread) != '"') {
zc_error("the 1st char of pattern is not \", line+nread[%s]", line+nread);
goto err;
}
for (p = a_format->name; *p != '\0'; p++) {
if ((!isalnum(*p)) && (*p != '_')) {
zc_error("a_format->name[%s] character is not in [a-Z][0-9][_]", a_format->name);
goto err;
}
}
p_start = line + nread + 1;
p_end = strrchr(p_start, '"');
if (!p_end) {
zc_error("there is no \" at end of pattern, line[%s]", line);
goto err;
}
if (p_end - p_start > sizeof(a_format->pattern) - 1) {
zc_error("pattern is too long");
goto err;
}
memset(a_format->pattern, 0x00, sizeof(a_format->pattern));
memcpy(a_format->pattern, p_start, p_end - p_start);
if (zc_str_replace_env(a_format->pattern, sizeof(a_format->pattern))) {
zc_error("zc_str_replace_env fail");
goto err;
}
a_format->pattern_specs =
zc_arraylist_new((zc_arraylist_del_fn) zlog_spec_del);
if (!(a_format->pattern_specs)) {
zc_error("zc_arraylist_new fail");
goto err;
}
for (p = a_format->pattern; *p != '\0'; p = q) {
a_spec = zlog_spec_new(p, &q, time_cache_count);
if (!a_spec) {
zc_error("zlog_spec_new fail");
goto err;
}
if (zc_arraylist_add(a_format->pattern_specs, a_spec)) {
zlog_spec_del(a_spec);
zc_error("zc_arraylist_add fail");
goto err;
}
}
zlog_format_profile(a_format, ZC_DEBUG);
return a_format;
err:
zlog_format_del(a_format);
return NULL;
}
/*******************************************************************************/
/* return 0 success, or buf is full
* return -1 fail
*/
int zlog_format_gen_msg(zlog_format_t * a_format, zlog_thread_t * a_thread)
{
int i;
zlog_spec_t *a_spec;
zlog_buf_restart(a_thread->msg_buf);
zc_arraylist_foreach(a_format->pattern_specs, i, a_spec) {
if (zlog_spec_gen_msg(a_spec, a_thread) == 0) {
continue;
} else {
return -1;
}
}
return 0;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_format_h
#define __zlog_format_h
#include "thread.h"
#include "zc_defs.h"
typedef struct zlog_format_s zlog_format_t;
struct zlog_format_s {
char name[MAXLEN_CFG_LINE + 1];
char pattern[MAXLEN_CFG_LINE + 1];
zc_arraylist_t *pattern_specs;
};
zlog_format_t *zlog_format_new(char *line, int * time_cache_count);
void zlog_format_del(zlog_format_t * a_format);
void zlog_format_profile(zlog_format_t * a_format, int flag);
int zlog_format_gen_msg(zlog_format_t * a_format, zlog_thread_t * a_thread);
#define zlog_format_has_name(a_format, fname) \
STRCMP(a_format->name, ==, fname)
#endif
LIBSO_TARGET := libzlog.so
#LIBA_TARGET := libzlog.a
#include "kk_log.h"
zlog_category_t *g_zlogC;
int kk_zlog_init(char* module)
{
int rc;
rc = zlog_init("zlog.conf");
if (rc) {
printf(" kk_zlog_init init failed\n");
return -1;
}
g_zlogC = zlog_get_category(module);
if (!g_zlogC) {
printf("kk_zlog_init get cat fail\n");
zlog_fini();
return -2;
}
//zlog_info(c, "hello, zlog");
//zlog_debug(c, "debug hello, zlog");
//zlog_fini();
return 0;
}
#ifndef _LOGDEF_H_
#define _LOGDEF_H_
#include "zlog.h"
extern zlog_category_t *g_zlogC;
#define DEBUG_PRINT(info,...) zlog_debug(g_zlogC, info, ##__VA_ARGS__)
#define INFO_PRINT(info,...) zlog_info(g_zlogC, info, ##__VA_ARGS__)
#define ERROR_PRINT(info,...) zlog_error(g_zlogC, info, ##__VA_ARGS__)
#define WARNING_PRINT(info,...) zlog_warn(g_zlogC, info, ##__VA_ARGS__)
int kk_zlog_init(char *module);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "syslog.h"
#include "zc_defs.h"
#include "level.h"
void zlog_level_profile(zlog_level_t *a_level, int flag)
{
zc_assert(a_level,);
zc_profile(flag, "---level[%p][%d,%s,%s,%d,%d]---",
a_level,
a_level->int_level,
a_level->str_uppercase,
a_level->str_lowercase,
(int) a_level->str_len,
a_level->syslog_level);
return;
}
/*******************************************************************************/
void zlog_level_del(zlog_level_t *a_level)
{
zc_assert(a_level,);
zc_debug("zlog_level_del[%p]", a_level);
free(a_level);
return;
}
static int syslog_level_atoi(char *str)
{
/* guess no unix system will choose -187
* as its syslog level, so it is a safe return value
*/
zc_assert(str, -187);
if (STRICMP(str, ==, "LOG_EMERG"))
return LOG_EMERG;
if (STRICMP(str, ==, "LOG_ALERT"))
return LOG_ALERT;
if (STRICMP(str, ==, "LOG_CRIT"))
return LOG_CRIT;
if (STRICMP(str, ==, "LOG_ERR"))
return LOG_ERR;
if (STRICMP(str, ==, "LOG_WARNING"))
return LOG_WARNING;
if (STRICMP(str, ==, "LOG_NOTICE"))
return LOG_NOTICE;
if (STRICMP(str, ==, "LOG_INFO"))
return LOG_INFO;
if (STRICMP(str, ==, "LOG_DEBUG"))
return LOG_DEBUG;
zc_error("wrong syslog level[%s]", str);
return -187;
}
/* line: TRACE = 10, LOG_ERR */
zlog_level_t *zlog_level_new(char *line)
{
zlog_level_t *a_level = NULL;
int i;
int nscan;
char str[MAXLEN_CFG_LINE + 1];
int l = 0;
char sl[MAXLEN_CFG_LINE + 1];
zc_assert(line, NULL);
memset(str, 0x00, sizeof(str));
memset(sl, 0x00, sizeof(sl));
nscan = sscanf(line, " %[^= \t] = %d ,%s", str, &l, sl);
if (nscan < 2) {
zc_error("level[%s], syntax wrong", line);
return NULL;
}
/* check level and str */
if ((l < 0) || (l > 255)) {
zc_error("l[%d] not in [0,255], wrong", l);
return NULL;
}
if (str[0] == '\0') {
zc_error("str[0] = 0");
return NULL;
}
a_level = calloc(1, sizeof(zlog_level_t));
if (!a_level) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_level->int_level = l;
/* fill syslog level */
if (sl[0] == '\0') {
a_level->syslog_level = LOG_DEBUG;
} else {
a_level->syslog_level = syslog_level_atoi(sl);
if (a_level->syslog_level == -187) {
zc_error("syslog_level_atoi fail");
goto err;
}
}
/* strncpy and toupper(str) */
for (i = 0; (i < sizeof(a_level->str_uppercase) - 1) && str[i] != '\0'; i++) {
(a_level->str_uppercase)[i] = toupper(str[i]);
(a_level->str_lowercase)[i] = tolower(str[i]);
}
if (str[i] != '\0') {
/* overflow */
zc_error("not enough space for str, str[%s] > %d", str, i);
goto err;
} else {
(a_level->str_uppercase)[i] = '\0';
(a_level->str_lowercase)[i] = '\0';
}
a_level->str_len = i;
//zlog_level_profile(a_level, ZC_DEBUG);
return a_level;
err:
zc_error("line[%s]", line);
zlog_level_del(a_level);
return NULL;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_level_h
#define __zlog_level_h
#include "zc_defs.h"
typedef struct zlog_level_s {
int int_level;
char str_uppercase[MAXLEN_PATH + 1];
char str_lowercase[MAXLEN_PATH + 1];
size_t str_len;
int syslog_level;
} zlog_level_t;
zlog_level_t *zlog_level_new(char *line);
void zlog_level_del(zlog_level_t *a_level);
void zlog_level_profile(zlog_level_t *a_level, int flag);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "syslog.h"
#include "zc_defs.h"
#include "level.h"
#include "level_list.h"
/* zlog_level_list == zc_arraylist_t<zlog_level_t> */
void zlog_level_list_profile(zc_arraylist_t *levels, int flag)
{
int i;
zlog_level_t *a_level;
zc_assert(levels,);
zc_profile(flag, "--level_list[%p]--", levels);
zc_arraylist_foreach(levels, i, a_level) {
/* skip empty slots */
if (a_level) zlog_level_profile(a_level, flag);
}
return;
}
/*******************************************************************************/
void zlog_level_list_del(zc_arraylist_t *levels)
{
zc_assert(levels,);
zc_arraylist_del(levels);
zc_debug("zc_level_list_del[%p]", levels);
return;
}
static int zlog_level_list_set_default(zc_arraylist_t *levels)
{
return zlog_level_list_set(levels, "* = 0, LOG_INFO")
|| zlog_level_list_set(levels, "DEBUG = 20, LOG_DEBUG")
|| zlog_level_list_set(levels, "INFO = 40, LOG_INFO")
|| zlog_level_list_set(levels, "NOTICE = 60, LOG_NOTICE")
|| zlog_level_list_set(levels, "WARN = 80, LOG_WARNING")
|| zlog_level_list_set(levels, "ERROR = 100, LOG_ERR")
|| zlog_level_list_set(levels, "FATAL = 120, LOG_ALERT")
|| zlog_level_list_set(levels, "UNKNOWN = 254, LOG_ERR")
|| zlog_level_list_set(levels, "! = 255, LOG_INFO");
}
zc_arraylist_t *zlog_level_list_new(void)
{
zc_arraylist_t *levels;
levels = zc_arraylist_new((zc_arraylist_del_fn)zlog_level_del);
if (!levels) {
zc_error("zc_arraylist_new fail");
return NULL;
}
if (zlog_level_list_set_default(levels)) {
zc_error("zlog_level_set_default fail");
goto err;
}
//zlog_level_list_profile(levels, ZC_DEBUG);
return levels;
err:
zc_arraylist_del(levels);
return NULL;
}
/*******************************************************************************/
int zlog_level_list_set(zc_arraylist_t *levels, char *line)
{
zlog_level_t *a_level;
a_level = zlog_level_new(line);
if (!a_level) {
zc_error("zlog_level_new fail");
return -1;
}
if (zc_arraylist_set(levels, a_level->int_level, a_level)) {
zc_error("zc_arraylist_set fail");
goto err;
}
return 0;
err:
zc_error("line[%s]", line);
zlog_level_del(a_level);
return -1;
}
zlog_level_t *zlog_level_list_get(zc_arraylist_t *levels, int l)
{
zlog_level_t *a_level;
#if 0
if ((l <= 0) || (l > 254)) {
/* illegal input from zlog() */
zc_error("l[%d] not in (0,254), set to UNKOWN", l);
l = 254;
}
#endif
a_level = zc_arraylist_get(levels, l);
if (a_level) {
return a_level;
} else {
/* empty slot */
zc_error("l[%d] not in (0,254), or has no level defined,"
"see configure file define, set to UNKOWN", l);
return zc_arraylist_get(levels, 254);
}
}
/*******************************************************************************/
int zlog_level_list_atoi(zc_arraylist_t *levels, char *str)
{
int i;
zlog_level_t *a_level;
if (str == NULL || *str == '\0') {
zc_error("str is [%s], can't find level", str);
return -1;
}
zc_arraylist_foreach(levels, i, a_level) {
if (a_level && STRICMP(str, ==, a_level->str_uppercase)) {
return i;
}
}
zc_error("str[%s] can't found in level list", str);
return -1;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_level_list_h
#define __zlog_level_list_h
#include "zc_defs.h"
#include "level.h"
zc_arraylist_t *zlog_level_list_new(void);
void zlog_level_list_del(zc_arraylist_t *levels);
void zlog_level_list_profile(zc_arraylist_t *levels, int flag);
/* conf init use, slow */
/* if l is wrong or str=="", return -1 */
int zlog_level_list_set(zc_arraylist_t *levels, char *line);
/* spec ouput use, fast */
/* rule output use, fast */
/* if not found, return levels[254] */
zlog_level_t *zlog_level_list_get(zc_arraylist_t *levels, int l);
/* rule init use, slow */
/* if not found, return -1 */
int zlog_level_list_atoi(zc_arraylist_t *levels, char *str);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "mdc.h"
#include "zc_defs.h"
void zlog_mdc_profile(zlog_mdc_t *a_mdc, int flag)
{
zc_hashtable_entry_t *a_entry;
zlog_mdc_kv_t *a_mdc_kv;
zc_assert(a_mdc,);
zc_profile(flag, "---mdc[%p]---", a_mdc);
zc_hashtable_foreach(a_mdc->tab, a_entry) {
a_mdc_kv = a_entry->value;
zc_profile(flag, "----mdc_kv[%p][%s]-[%s]----",
a_mdc_kv,
a_mdc_kv->key, a_mdc_kv->value);
}
return;
}
/*******************************************************************************/
void zlog_mdc_del(zlog_mdc_t * a_mdc)
{
zc_assert(a_mdc,);
if (a_mdc->tab) zc_hashtable_del(a_mdc->tab);
zc_debug("zlog_mdc_del[%p]", a_mdc);
free(a_mdc);
return;
}
static void zlog_mdc_kv_del(zlog_mdc_kv_t * a_mdc_kv)
{
zc_debug("zlog_mdc_kv_del[%p]", a_mdc_kv);
free(a_mdc_kv);
}
static zlog_mdc_kv_t *zlog_mdc_kv_new(const char *key, const char *value)
{
zlog_mdc_kv_t *a_mdc_kv;
a_mdc_kv = calloc(1, sizeof(zlog_mdc_kv_t));
if (!a_mdc_kv) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
snprintf(a_mdc_kv->key, sizeof(a_mdc_kv->key), "%s", key);
a_mdc_kv->value_len = snprintf(a_mdc_kv->value, sizeof(a_mdc_kv->value), "%s", value);
return a_mdc_kv;
}
zlog_mdc_t *zlog_mdc_new(void)
{
zlog_mdc_t *a_mdc;
a_mdc = calloc(1, sizeof(zlog_mdc_t));
if (!a_mdc) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_mdc->tab = zc_hashtable_new(20,
zc_hashtable_str_hash,
zc_hashtable_str_equal, NULL,
(zc_hashtable_del_fn) zlog_mdc_kv_del);
if (!a_mdc->tab) {
zc_error("zc_hashtable_new fail");
goto err;
}
//zlog_mdc_profile(a_mdc, ZC_DEBUG);
return a_mdc;
err:
zlog_mdc_del(a_mdc);
return NULL;
}
/*******************************************************************************/
int zlog_mdc_put(zlog_mdc_t * a_mdc, const char *key, const char *value)
{
zlog_mdc_kv_t *a_mdc_kv;
a_mdc_kv = zlog_mdc_kv_new(key, value);
if (!a_mdc_kv) {
zc_error("zlog_mdc_kv_new failed");
return -1;
}
if (zc_hashtable_put(a_mdc->tab, a_mdc_kv->key, a_mdc_kv)) {
zc_error("zc_hashtable_put fail");
zlog_mdc_kv_del(a_mdc_kv);
return -1;
}
return 0;
}
void zlog_mdc_clean(zlog_mdc_t * a_mdc)
{
zc_hashtable_clean(a_mdc->tab);
return;
}
char *zlog_mdc_get(zlog_mdc_t * a_mdc, const char *key)
{
zlog_mdc_kv_t *a_mdc_kv;
a_mdc_kv = zc_hashtable_get(a_mdc->tab, key);
if (!a_mdc_kv) {
zc_error("zc_hashtable_get fail");
return NULL;
} else {
return a_mdc_kv->value;
}
}
zlog_mdc_kv_t *zlog_mdc_get_kv(zlog_mdc_t * a_mdc, const char *key)
{
zlog_mdc_kv_t *a_mdc_kv;
a_mdc_kv = zc_hashtable_get(a_mdc->tab, key);
if (!a_mdc_kv) {
zc_error("zc_hashtable_get fail");
return NULL;
} else {
return a_mdc_kv;
}
}
void zlog_mdc_remove(zlog_mdc_t * a_mdc, const char *key)
{
zc_hashtable_remove(a_mdc->tab, key);
return;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_mdc_h
#define __zlog_mdc_h
#include "zc_defs.h"
typedef struct zlog_mdc_s zlog_mdc_t;
struct zlog_mdc_s {
zc_hashtable_t *tab;
};
zlog_mdc_t *zlog_mdc_new(void);
void zlog_mdc_del(zlog_mdc_t * a_mdc);
void zlog_mdc_profile(zlog_mdc_t *a_mdc, int flag);
void zlog_mdc_clean(zlog_mdc_t * a_mdc);
int zlog_mdc_put(zlog_mdc_t * a_mdc, const char *key, const char *value);
char *zlog_mdc_get(zlog_mdc_t * a_mdc, const char *key);
void zlog_mdc_remove(zlog_mdc_t * a_mdc, const char *key);
typedef struct zlog_mdc_kv_s {
char key[MAXLEN_PATH + 1];
char value[MAXLEN_PATH + 1];
size_t value_len;
} zlog_mdc_kv_t;
zlog_mdc_kv_t *zlog_mdc_get_kv(zlog_mdc_t * a_mdc, const char *key);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "errno.h"
#include "zc_defs.h"
#include "record.h"
void zlog_record_profile(zlog_record_t *a_record, int flag)
{
zc_assert(a_record,);
zc_profile(flag, "--record:[%p][%s:%p]--", a_record, a_record->name, a_record->output);
return;
}
void zlog_record_del(zlog_record_t *a_record)
{
zc_assert(a_record,);
zc_debug("zlog_record_del[%p]", a_record);
free(a_record);
return;
}
zlog_record_t *zlog_record_new(const char *name, zlog_record_fn output)
{
zlog_record_t *a_record;
zc_assert(name, NULL);
zc_assert(output, NULL);
a_record = calloc(1, sizeof(zlog_record_t));
if (!a_record) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
if (strlen(name) > sizeof(a_record->name) - 1) {
zc_error("name[%s] is too long", name);
goto err;
}
strcpy(a_record->name, name);
a_record->output = output;
zlog_record_profile(a_record, ZC_DEBUG);
return a_record;
err:
zlog_record_del(a_record);
return NULL;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_record_h
#define __zlog_record_h
#include "zc_defs.h"
/* record is user-defined output function and it's name from configure file */
typedef struct zlog_msg_s {
char *buf;
size_t len;
char *path;
} zlog_msg_t; /* 3 of this first, see need thread or not later */
typedef int (*zlog_record_fn)(zlog_msg_t * msg);
typedef struct zlog_record_s {
char name[MAXLEN_PATH + 1];
zlog_record_fn output;
} zlog_record_t;
zlog_record_t *zlog_record_new(const char *name, zlog_record_fn output);
void zlog_record_del(zlog_record_t *a_record);
void zlog_record_profile(zlog_record_t *a_record, int flag);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "zc_defs.h"
#include "record_table.h"
void zlog_record_table_profile(zc_hashtable_t * records, int flag)
{
zc_hashtable_entry_t *a_entry;
zlog_record_t *a_record;
zc_assert(records,);
zc_profile(flag, "-record_table[%p]-", records);
zc_hashtable_foreach(records, a_entry) {
a_record = (zlog_record_t *) a_entry->value;
zlog_record_profile(a_record, flag);
}
return;
}
/*******************************************************************************/
void zlog_record_table_del(zc_hashtable_t * records)
{
zc_assert(records,);
zc_hashtable_del(records);
zc_debug("zlog_record_table_del[%p]", records);
return;
}
zc_hashtable_t *zlog_record_table_new(void)
{
zc_hashtable_t *records;
records = zc_hashtable_new(20,
(zc_hashtable_hash_fn) zc_hashtable_str_hash,
(zc_hashtable_equal_fn) zc_hashtable_str_equal,
NULL, (zc_hashtable_del_fn) zlog_record_del);
if (!records) {
zc_error("zc_hashtable_new fail");
return NULL;
} else {
zlog_record_table_profile(records, ZC_DEBUG);
return records;
}
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_record_table_h
#define __zlog_record_table_h
#include "zc_defs.h"
#include "record.h"
zc_hashtable_t *zlog_record_table_new(void);
void zlog_record_table_del(zc_hashtable_t * records);
void zlog_record_table_profile(zc_hashtable_t * records, int flag);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <string.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include "zc_defs.h"
#include "rotater.h"
#define ROLLING 1 /* aa.02->aa.03, aa.01->aa.02, aa->aa.01 */
#define SEQUENCE 2 /* aa->aa.03 */
typedef struct {
int index;
char path[MAXLEN_PATH + 1];
} zlog_file_t;
void zlog_rotater_profile(zlog_rotater_t * a_rotater, int flag)
{
zc_assert(a_rotater,);
zc_profile(flag, "--rotater[%p][%p,%s,%d][%s,%s,%s,%ld,%ld,%d,%d,%d]--",
a_rotater,
&(a_rotater->lock_mutex),
a_rotater->lock_file,
a_rotater->lock_fd,
a_rotater->base_path,
a_rotater->archive_path,
a_rotater->glob_path,
(long)a_rotater->num_start_len,
(long)a_rotater->num_end_len,
a_rotater->num_width,
a_rotater->mv_type,
a_rotater->max_count
);
if (a_rotater->files) {
int i;
zlog_file_t *a_file;
zc_arraylist_foreach(a_rotater->files, i, a_file) {
zc_profile(flag, "[%s,%d]->", a_file->path, a_file->index);
}
}
return;
}
/*******************************************************************************/
void zlog_rotater_del(zlog_rotater_t *a_rotater)
{
zc_assert(a_rotater,);
if (a_rotater->lock_fd) {
if (close(a_rotater->lock_fd)) {
zc_error("close fail, errno[%d]", errno);
}
}
if (pthread_mutex_destroy(&(a_rotater->lock_mutex))) {
zc_error("pthread_mutex_destroy fail, errno[%d]", errno);
}
zc_debug("zlog_rotater_del[%p]", a_rotater);
free(a_rotater);
return;
}
zlog_rotater_t *zlog_rotater_new(char *lock_file)
{
int fd = 0;
zlog_rotater_t *a_rotater;
zc_assert(lock_file, NULL);
a_rotater = calloc(1, sizeof(zlog_rotater_t));
if (!a_rotater) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
if (pthread_mutex_init(&(a_rotater->lock_mutex), NULL)) {
zc_error("pthread_mutex_init fail, errno[%d]", errno);
free(a_rotater);
return NULL;
}
/* depends on umask of the user here
* if user A create /tmp/zlog.lock 0600
* user B is unable to read /tmp/zlog.lock
* B has to choose another lock file except /tmp/zlog.lock
*/
fd = open(lock_file, O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0) {
zc_error("open file[%s] fail, errno[%d]", lock_file, errno);
goto err;
}
a_rotater->lock_fd = fd;
a_rotater->lock_file = lock_file;
//zlog_rotater_profile(a_rotater, ZC_DEBUG);
return a_rotater;
err:
zlog_rotater_del(a_rotater);
return NULL;
}
/*******************************************************************************/
static void zlog_file_del(zlog_file_t * a_file)
{
zc_debug("del onefile[%p]", a_file);
zc_debug("a_file->path[%s]", a_file->path);
free(a_file);
}
static zlog_file_t *zlog_file_check_new(zlog_rotater_t * a_rotater, const char *path)
{
int nwrite;
int nread;
zlog_file_t *a_file;
/* base_path will not be in list */
if (STRCMP(a_rotater->base_path, ==, path)) {
return NULL;
}
/* omit dirs */
if ((path)[strlen(path) - 1] == '/') {
return NULL;
}
a_file = calloc(1, sizeof(zlog_file_t));
if (!a_file) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
nwrite = snprintf(a_file->path, sizeof(a_file->path), "%s", path);
if (nwrite < 0 || nwrite >= sizeof(a_file->path)) {
zc_error("snprintf fail or overflow, nwrite=[%d], errno[%d]", nwrite, errno);
goto err;
}
nread = 0;
sscanf(a_file->path + a_rotater->num_start_len, "%d%n", &(a_file->index), &(nread));
if (a_rotater->num_width != 0) {
if (nread < a_rotater->num_width) {
zc_warn("aa.1.log is not expect, need aa.01.log");
goto err;
}
} /* else all file is ok */
return a_file;
err:
free(a_file);
return NULL;
}
static int zlog_file_cmp(zlog_file_t * a_file_1, zlog_file_t * a_file_2)
{
return (a_file_1->index > a_file_2->index);
}
static int zlog_rotater_add_archive_files(zlog_rotater_t * a_rotater)
{
int rc = 0;
glob_t glob_buf;
size_t pathc;
char **pathv;
zlog_file_t *a_file;
a_rotater->files = zc_arraylist_new((zc_arraylist_del_fn)zlog_file_del);
if (!a_rotater->files) {
zc_error("zc_arraylist_new fail");
return -1;
}
/* scan file which is aa.*.log and aa */
rc = glob(a_rotater->glob_path, GLOB_ERR | GLOB_MARK | GLOB_NOSORT, NULL, &glob_buf);
if (rc == GLOB_NOMATCH) {
goto exit;
} else if (rc) {
zc_error("glob err, rc=[%d], errno[%d]", rc, errno);
return -1;
}
pathv = glob_buf.gl_pathv;
pathc = glob_buf.gl_pathc;
/* check and find match aa.[0-9]*.log, depend on num_width */
for (; pathc-- > 0; pathv++) {
a_file = zlog_file_check_new(a_rotater, *pathv);
if (!a_file) {
zc_warn("not the expect pattern file");
continue;
}
/* file in list aa.00, aa.01, aa.02... */
rc = zc_arraylist_sortadd(a_rotater->files,
(zc_arraylist_cmp_fn)zlog_file_cmp, a_file);
if (rc) {
zc_error("zc_arraylist_sortadd fail");
goto err;
}
}
exit:
globfree(&glob_buf);
return 0;
err:
globfree(&glob_buf);
return -1;
}
static int zlog_rotater_seq_files(zlog_rotater_t * a_rotater)
{
int rc = 0;
int nwrite = 0;
int i, j;
zlog_file_t *a_file;
char new_path[MAXLEN_PATH + 1];
zc_arraylist_foreach(a_rotater->files, i, a_file) {
if (a_rotater->max_count > 0
&& i < zc_arraylist_len(a_rotater->files) - a_rotater->max_count) {
/* unlink aa.0 aa.1 .. aa.(n-c) */
rc = unlink(a_file->path);
if (rc) {
zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
return -1;
}
continue;
}
}
if (zc_arraylist_len(a_rotater->files) > 0) { /* list is not empty */
a_file = zc_arraylist_get(a_rotater->files, zc_arraylist_len(a_rotater->files)-1);
if (!a_file) {
zc_error("zc_arraylist_get fail");
return -1;
}
j = zc_max(zc_arraylist_len(a_rotater->files)-1, a_file->index) + 1;
} else {
j = 0;
}
/* do the base_path mv */
memset(new_path, 0x00, sizeof(new_path));
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
(int) a_rotater->num_start_len, a_rotater->glob_path,
a_rotater->num_width, j,
a_rotater->glob_path + a_rotater->num_end_len);
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
return -1;
}
if (rename(a_rotater->base_path, new_path)) {
zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
return -1;
}
return 0;
}
static int zlog_rotater_roll_files(zlog_rotater_t * a_rotater)
{
int i;
int rc = 0;
int nwrite;
char new_path[MAXLEN_PATH + 1];
zlog_file_t *a_file;
/* now in the list, aa.0 aa.1 aa.2 aa.02... */
for (i = zc_arraylist_len(a_rotater->files) - 1; i > -1; i--) {
a_file = zc_arraylist_get(a_rotater->files, i);
if (!a_file) {
zc_error("zc_arraylist_get fail");
return -1;
}
if (a_rotater->max_count > 0 && i >= a_rotater->max_count - 1) {
/* remove file.3 >= 3*/
rc = unlink(a_file->path);
if (rc) {
zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
return -1;
}
continue;
}
/* begin rename aa.01.log -> aa.02.log , using i, as index in list maybe repeat */
memset(new_path, 0x00, sizeof(new_path));
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
(int) a_rotater->num_start_len, a_rotater->glob_path,
a_rotater->num_width, i + 1,
a_rotater->glob_path + a_rotater->num_end_len);
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
return -1;
}
if (rename(a_file->path, new_path)) {
zc_error("rename[%s]->[%s] fail, errno[%d]", a_file->path, new_path, errno);
return -1;
}
}
/* do the base_path mv */
memset(new_path, 0x00, sizeof(new_path));
nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
(int) a_rotater->num_start_len, a_rotater->glob_path,
a_rotater->num_width, 0,
a_rotater->glob_path + a_rotater->num_end_len);
if (nwrite < 0 || nwrite >= sizeof(new_path)) {
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
return -1;
}
if (rename(a_rotater->base_path, new_path)) {
zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
return -1;
}
return 0;
}
static int zlog_rotater_parse_archive_path(zlog_rotater_t * a_rotater)
{
int nwrite;
int nread;
char *p;
size_t len;
/* no archive path is set */
if (a_rotater->archive_path[0] == '\0') {
nwrite = snprintf(a_rotater->glob_path, sizeof(a_rotater->glob_path),
"%s.*", a_rotater->base_path);
if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path)) {
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
return -1;
}
a_rotater->mv_type = ROLLING;
a_rotater->num_width = 0;
a_rotater->num_start_len = strlen(a_rotater->base_path) + 1;
a_rotater->num_end_len = strlen(a_rotater->base_path) + 2;
return 0;
} else {
/* find the 1st # */
p = strchr(a_rotater->archive_path, '#');
if (!p) {
zc_error("no # in archive_path[%s]", a_rotater->archive_path);
return -1;
}
nread = 0;
sscanf(p, "#%d%n", &(a_rotater->num_width), &nread);
if (nread == 0) nread = 1;
if (*(p+nread) == 'r') {
a_rotater->mv_type = ROLLING;
} else if (*(p+nread) == 's') {
a_rotater->mv_type = SEQUENCE;
} else {
zc_error("#r or #s not found");
return -1;
}
/* copy and substitue #i to * in glob_path*/
len = p - a_rotater->archive_path;
if (len > sizeof(a_rotater->glob_path) - 1) {
zc_error("sizeof glob_path not enough,len[%ld]", (long) len);
return -1;
}
memcpy(a_rotater->glob_path, a_rotater->archive_path, len);
nwrite = snprintf(a_rotater->glob_path + len, sizeof(a_rotater->glob_path) - len,
"*%s", p + nread + 1);
if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path) - len) {
zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
return -1;
}
a_rotater->num_start_len = len;
a_rotater->num_end_len = len + 1;
}
return 0;
}
static void zlog_rotater_clean(zlog_rotater_t *a_rotater)
{
a_rotater->base_path = NULL;
a_rotater->archive_path = NULL;
a_rotater->max_count = 0;
a_rotater->mv_type = 0;
a_rotater->num_width = 0;
a_rotater->num_start_len = 0;
a_rotater->num_end_len = 0;
memset(a_rotater->glob_path, 0x00, sizeof(a_rotater->glob_path));
if (a_rotater->files) zc_arraylist_del(a_rotater->files);
a_rotater->files = NULL;
}
static int zlog_rotater_lsmv(zlog_rotater_t *a_rotater,
char *base_path, char *archive_path, int archive_max_count)
{
int rc = 0;
a_rotater->base_path = base_path;
a_rotater->archive_path = archive_path;
a_rotater->max_count = archive_max_count;
rc = zlog_rotater_parse_archive_path(a_rotater);
if (rc) {
zc_error("zlog_rotater_parse_archive_path fail");
goto err;
}
rc = zlog_rotater_add_archive_files(a_rotater);
if (rc) {
zc_error("zlog_rotater_add_archive_files fail");
goto err;
}
if (a_rotater->mv_type == ROLLING) {
rc = zlog_rotater_roll_files(a_rotater);
if (rc) {
zc_error("zlog_rotater_roll_files fail");
goto err;
}
} else if (a_rotater->mv_type == SEQUENCE) {
rc = zlog_rotater_seq_files(a_rotater);
if (rc) {
zc_error("zlog_rotater_seq_files fail");
goto err;
}
}
zlog_rotater_clean(a_rotater);
return 0;
err:
zlog_rotater_clean(a_rotater);
return -1;
}
/*******************************************************************************/
static int zlog_rotater_trylock(zlog_rotater_t *a_rotater)
{
int rc;
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
rc = pthread_mutex_trylock(&(a_rotater->lock_mutex));
if (rc == EBUSY) {
zc_warn("pthread_mutex_trylock fail, as lock_mutex is locked by other threads");
return -1;
} else if (rc != 0) {
zc_error("pthread_mutex_trylock fail, rc[%d]", rc);
return -1;
}
if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
if (errno == EAGAIN || errno == EACCES) {
/* lock by other process, that's right, go on */
/* EAGAIN on linux */
/* EACCES on AIX */
zc_warn("fcntl lock fail, as file is lock by other process");
} else {
zc_error("lock fd[%d] fail, errno[%d]", a_rotater->lock_fd, errno);
}
if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
zc_error("pthread_mutex_unlock fail, errno[%d]", errno);
}
return -1;
}
return 0;
}
static int zlog_rotater_unlock(zlog_rotater_t *a_rotater)
{
int rc = 0;
struct flock fl;
fl.l_type = F_UNLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
rc = -1;
zc_error("unlock fd[%s] fail, errno[%d]", a_rotater->lock_fd, errno);
}
if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
rc = -1;
zc_error("pthread_mutext_unlock fail, errno[%d]", errno);
}
return rc;
}
int zlog_rotater_rotate(zlog_rotater_t *a_rotater,
char *base_path, size_t msg_len,
char *archive_path, long archive_max_size, int archive_max_count)
{
int rc = 0;
struct zlog_stat info;
zc_assert(base_path, -1);
if (zlog_rotater_trylock(a_rotater)) {
zc_warn("zlog_rotater_trylock fail, maybe lock by other process or threads");
return 0;
}
if (stat(base_path, &info)) {
rc = -1;
zc_error("stat [%s] fail, errno[%d]", base_path, errno);
goto exit;
}
if (info.st_size + msg_len <= archive_max_size) {
/* file not so big,
* may alread rotate by oth process or thread,
* return */
rc = 0;
goto exit;
}
/* begin list and move files */
rc = zlog_rotater_lsmv(a_rotater, base_path, archive_path, archive_max_count);
if (rc) {
zc_error("zlog_rotater_lsmv [%s] fail, return", base_path);
rc = -1;
} /* else if (rc == 0) */
//zc_debug("zlog_rotater_file_ls_mv success");
exit:
/* unlock file */
if (zlog_rotater_unlock(a_rotater)) {
zc_error("zlog_rotater_unlock fail");
}
return rc;
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_rotater_h
#define __zlog_rotater_h
#include "zc_defs.h"
typedef struct zlog_rotater_s {
pthread_mutex_t lock_mutex;
char *lock_file;
int lock_fd;
/* single-use members */
char *base_path; /* aa.log */
char *archive_path; /* aa.#5i.log */
char glob_path[MAXLEN_PATH + 1]; /* aa.*.log */
size_t num_start_len; /* 3, offset to glob_path */
size_t num_end_len; /* 6, offset to glob_path */
int num_width; /* 5 */
int mv_type; /* ROLLING or SEQUENCE */
int max_count;
zc_arraylist_t *files;
} zlog_rotater_t;
zlog_rotater_t *zlog_rotater_new(char *lock_file);
void zlog_rotater_del(zlog_rotater_t *a_rotater);
/*
* return
* -1 fail
* 0 no rotate, or rotate and success
*/
int zlog_rotater_rotate(zlog_rotater_t *a_rotater,
char *base_path, size_t msg_len,
char *archive_path, long archive_max_size, int archive_max_count);
void zlog_rotater_profile(zlog_rotater_t *a_rotater, int flag);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <string.h>
#include <ctype.h>
#include <syslog.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include "rule.h"
#include "format.h"
#include "buf.h"
#include "thread.h"
#include "level_list.h"
#include "rotater.h"
#include "spec.h"
#include "conf.h"
#include "zc_defs.h"
void zlog_rule_profile(zlog_rule_t * a_rule, int flag)
{
int i;
zlog_spec_t *a_spec;
zc_assert(a_rule,);
zc_profile(flag, "---rule:[%p][%s%c%d]-[%d,%d][%s,%p,%d:%ld*%d~%s][%d][%d][%s:%s:%p];[%p]---",
a_rule,
a_rule->category,
a_rule->compare_char,
a_rule->level,
a_rule->file_perms,
a_rule->file_open_flags,
a_rule->file_path,
a_rule->dynamic_specs,
a_rule->static_fd,
a_rule->archive_max_size,
a_rule->archive_max_count,
a_rule->archive_path,
a_rule->pipe_fd,
a_rule->syslog_facility,
a_rule->record_name,
a_rule->record_path,
a_rule->record_func,
a_rule->format);
if (a_rule->dynamic_specs) {
zc_arraylist_foreach(a_rule->dynamic_specs, i, a_spec) {
zlog_spec_profile(a_spec, flag);
}
}
return;
}
/*******************************************************************************/
static int zlog_rule_output_static_file_single(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
struct stat stb;
int do_file_reload = 0;
int redo_inode_stat = 0;
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
/* check if the output file was changed by an external tool by comparing the inode to our saved off one */
if (stat(a_rule->file_path, &stb)) {
if (errno != ENOENT) {
zc_error("stat fail on [%s], errno[%d]", a_rule->file_path, errno);
return -1;
} else {
do_file_reload = 1;
redo_inode_stat = 1; /* we'll have to restat the newly created file to get the inode info */
}
} else {
do_file_reload = (stb.st_ino != a_rule->static_ino || stb.st_dev != a_rule->static_dev);
}
if (do_file_reload) {
close(a_rule->static_fd);
a_rule->static_fd = open(a_rule->file_path,
O_WRONLY | O_APPEND | O_CREAT | a_rule->file_open_flags,
a_rule->file_perms);
if (a_rule->static_fd < 0) {
zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
return -1;
}
/* save off the new dev/inode info from the stat call we already did */
if (redo_inode_stat) {
if (stat(a_rule->file_path, &stb)) {
zc_error("stat fail on new file[%s], errno[%d]", a_rule->file_path, errno);
return -1;
}
}
a_rule->static_dev = stb.st_dev;
a_rule->static_ino = stb.st_ino;
}
if (write(a_rule->static_fd,
zlog_buf_str(a_thread->msg_buf),
zlog_buf_len(a_thread->msg_buf)) < 0) {
zc_error("write fail, errno[%d]", errno);
return -1;
}
/* not so thread safe here, as multiple thread may ++fsync_count at the same time */
if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
a_rule->fsync_count = 0;
if (fsync(a_rule->static_fd)) {
zc_error("fsync[%d] fail, errno[%d]", a_rule->static_fd, errno);
}
}
return 0;
}
static char * zlog_rule_gen_archive_path(zlog_rule_t *a_rule, zlog_thread_t *a_thread)
{
int i;
zlog_spec_t *a_spec;
if (!a_rule->archive_specs) return a_rule->archive_path;
zlog_buf_restart(a_thread->archive_path_buf);
zc_arraylist_foreach(a_rule->archive_specs, i, a_spec) {
if (zlog_spec_gen_archive_path(a_spec, a_thread)) {
zc_error("zlog_spec_gen_path fail");
return NULL;
}
}
zlog_buf_seal(a_thread->archive_path_buf);
return zlog_buf_str(a_thread->archive_path_buf);
}
static int zlog_rule_output_static_file_rotate(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
size_t len;
struct zlog_stat info;
int fd;
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
fd = open(a_rule->file_path,
a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
if (fd < 0) {
zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
return -1;
}
len = zlog_buf_len(a_thread->msg_buf);
if (write(fd, zlog_buf_str(a_thread->msg_buf), len) < 0) {
zc_error("write fail, errno[%d]", errno);
close(fd);
return -1;
}
if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
a_rule->fsync_count = 0;
if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
}
if (close(fd) < 0) {
zc_error("close fail, maybe cause by write, errno[%d]", errno);
return -1;
}
if (len > a_rule->archive_max_size) {
zc_debug("one msg's len[%ld] > archive_max_size[%ld], no rotate",
(long)len, (long)a_rule->archive_max_size);
return 0;
}
if (stat(a_rule->file_path, &info)) {
zc_warn("stat [%s] fail, errno[%d], maybe in rotating", a_rule->file_path, errno);
return 0;
}
/* file not so big, return */
if (info.st_size + len < a_rule->archive_max_size) return 0;
if (zlog_rotater_rotate(zlog_env_conf->rotater,
a_rule->file_path, len,
zlog_rule_gen_archive_path(a_rule, a_thread),
a_rule->archive_max_size, a_rule->archive_max_count)
) {
zc_error("zlog_rotater_rotate fail");
return -1;
} /* success or no rotation do nothing */
return 0;
}
/* return path success
* return NULL fail
*/
#define zlog_rule_gen_path(a_rule, a_thread) do { \
int i; \
zlog_spec_t *a_spec; \
\
zlog_buf_restart(a_thread->path_buf); \
\
zc_arraylist_foreach(a_rule->dynamic_specs, i, a_spec) { \
if (zlog_spec_gen_path(a_spec, a_thread)) { \
zc_error("zlog_spec_gen_path fail"); \
return -1; \
} \
} \
\
zlog_buf_seal(a_thread->path_buf); \
} while(0)
static int zlog_rule_output_dynamic_file_single(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
int fd;
zlog_rule_gen_path(a_rule, a_thread);
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_output fail");
return -1;
}
fd = open(zlog_buf_str(a_thread->path_buf),
a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
if (fd < 0) {
zc_error("open file[%s] fail, errno[%d]", zlog_buf_str(a_thread->path_buf), errno);
return -1;
}
if (write(fd, zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
zc_error("write fail, errno[%d]", errno);
close(fd);
return -1;
}
if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
a_rule->fsync_count = 0;
if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
}
if (close(fd) < 0) {
zc_error("close fail, maybe cause by write, errno[%d]", errno);
return -1;
}
return 0;
}
static int zlog_rule_output_dynamic_file_rotate(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
int fd;
char *path;
size_t len;
struct zlog_stat info;
zlog_rule_gen_path(a_rule, a_thread);
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_output fail");
return -1;
}
path = zlog_buf_str(a_thread->path_buf);
fd = open(path, a_rule->file_open_flags | O_WRONLY | O_APPEND | O_CREAT, a_rule->file_perms);
if (fd < 0) {
zc_error("open file[%s] fail, errno[%d]", zlog_buf_str(a_thread->path_buf), errno);
return -1;
}
len = zlog_buf_len(a_thread->msg_buf);
if (write(fd, zlog_buf_str(a_thread->msg_buf), len) < 0) {
zc_error("write fail, errno[%d]", errno);
close(fd);
return -1;
}
if (a_rule->fsync_period && ++a_rule->fsync_count >= a_rule->fsync_period) {
a_rule->fsync_count = 0;
if (fsync(fd)) zc_error("fsync[%d] fail, errno[%d]", fd, errno);
}
if (close(fd) < 0) {
zc_error("write fail, maybe cause by write, errno[%d]", errno);
return -1;
}
if (len > a_rule->archive_max_size) {
zc_debug("one msg's len[%ld] > archive_max_size[%ld], no rotate",
(long)len, (long) a_rule->archive_max_size);
return 0;
}
if (stat(path, &info)) {
zc_warn("stat [%s] fail, errno[%d], maybe in rotating", path, errno);
return 0;
}
/* file not so big, return */
if (info.st_size + len < a_rule->archive_max_size) return 0;
if (zlog_rotater_rotate(zlog_env_conf->rotater,
path, len,
zlog_rule_gen_archive_path(a_rule, a_thread),
a_rule->archive_max_size, a_rule->archive_max_count)
) {
zc_error("zlog_rotater_rotate fail");
return -1;
} /* success or no rotation do nothing */
return 0;
}
static int zlog_rule_output_pipe(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
if (write(a_rule->pipe_fd,
zlog_buf_str(a_thread->msg_buf),
zlog_buf_len(a_thread->msg_buf)) < 0) {
zc_error("write fail, errno[%d]", errno);
return -1;
}
return 0;
}
static int zlog_rule_output_syslog(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
zlog_level_t *a_level;
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
/*
msg = a_thread->msg_buf->start;
msg_len = a_thread->msg_buf->end - a_thread->msg_buf->start;
*/
a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
zlog_buf_seal(a_thread->msg_buf);
syslog(a_rule->syslog_facility | a_level->syslog_level,
"%s", zlog_buf_str(a_thread->msg_buf));
return 0;
}
static int zlog_rule_output_static_record(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
zlog_msg_t msg;
if (!a_rule->record_func) {
zc_error("user defined record funcion for [%s] not set, no output",
a_rule->record_name);
return -1;
}
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
zlog_buf_seal(a_thread->msg_buf);
msg.buf = zlog_buf_str(a_thread->msg_buf);
msg.len = zlog_buf_len(a_thread->msg_buf);
msg.path = a_rule->record_path;
if (a_rule->record_func(&msg)) {
zc_error("a_rule->record fail");
return -1;
}
return 0;
}
static int zlog_rule_output_dynamic_record(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
zlog_msg_t msg;
if (!a_rule->record_func) {
zc_error("user defined record funcion for [%s] not set, no output",
a_rule->record_name);
return -1;
}
zlog_rule_gen_path(a_rule, a_thread);
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
zlog_buf_seal(a_thread->msg_buf);
msg.buf = zlog_buf_str(a_thread->msg_buf);
msg.len = zlog_buf_len(a_thread->msg_buf);
msg.path = zlog_buf_str(a_thread->path_buf);
if (a_rule->record_func(&msg)) {
zc_error("a_rule->record fail");
return -1;
}
return 0;
}
static int zlog_rule_output_stdout(zlog_rule_t * a_rule,
zlog_thread_t * a_thread)
{
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
if (write(STDOUT_FILENO,
zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
zc_error("write fail, errno[%d]", errno);
return -1;
}
return 0;
}
static int zlog_rule_output_stderr(zlog_rule_t * a_rule,
zlog_thread_t * a_thread)
{
if (zlog_format_gen_msg(a_rule->format, a_thread)) {
zc_error("zlog_format_gen_msg fail");
return -1;
}
if (write(STDERR_FILENO,
zlog_buf_str(a_thread->msg_buf), zlog_buf_len(a_thread->msg_buf)) < 0) {
zc_error("write fail, errno[%d]", errno);
return -1;
}
return 0;
}
/*******************************************************************************/
static int syslog_facility_atoi(char *facility)
{
/* guess no unix system will choose -187
* as its syslog facility, so it is a safe return value
*/
zc_assert(facility, -187);
if (STRICMP(facility, ==, "LOG_LOCAL0")) return LOG_LOCAL0;
if (STRICMP(facility, ==, "LOG_LOCAL1")) return LOG_LOCAL1;
if (STRICMP(facility, ==, "LOG_LOCAL2")) return LOG_LOCAL2;
if (STRICMP(facility, ==, "LOG_LOCAL3")) return LOG_LOCAL3;
if (STRICMP(facility, ==, "LOG_LOCAL4")) return LOG_LOCAL4;
if (STRICMP(facility, ==, "LOG_LOCAL5")) return LOG_LOCAL5;
if (STRICMP(facility, ==, "LOG_LOCAL6")) return LOG_LOCAL6;
if (STRICMP(facility, ==, "LOG_LOCAL7")) return LOG_LOCAL7;
if (STRICMP(facility, ==, "LOG_USER")) return LOG_USER;
if (STRICMP(facility, ==, "LOG_AUTHPRIV")) return LOG_AUTHPRIV;
if (STRICMP(facility, ==, "LOG_CRON")) return LOG_CRON;
if (STRICMP(facility, ==, "LOG_DAEMON")) return LOG_DAEMON;
if (STRICMP(facility, ==, "LOG_FTP")) return LOG_FTP;
if (STRICMP(facility, ==, "LOG_KERN")) return LOG_KERN;
if (STRICMP(facility, ==, "LOG_LPR")) return LOG_LPR;
if (STRICMP(facility, ==, "LOG_MAIL")) return LOG_MAIL;
if (STRICMP(facility, ==, "LOG_NEWS")) return LOG_NEWS;
if (STRICMP(facility, ==, "LOG_SYSLOG")) return LOG_SYSLOG;
return LOG_AUTHPRIV;
zc_error("wrong syslog facility[%s], must in LOG_LOCAL[0-7] or LOG_USER", facility);
return -187;
}
static int zlog_rule_parse_path(char *path_start, /* start with a " */
char *path_str, size_t path_size, zc_arraylist_t **path_specs,
int *time_cache_count)
{
char *p, *q;
size_t len;
zlog_spec_t *a_spec;
zc_arraylist_t *specs;
p = path_start + 1;
q = strrchr(p, '"');
if (!q) {
zc_error("matching \" not found in conf line[%s]", path_start);
return -1;
}
len = q - p;
if (len > path_size - 1) {
zc_error("file_path too long %ld > %ld", len, path_size - 1);
return -1;
}
memcpy(path_str, p, len);
/* replace any environment variables like %E(HOME) */
if (zc_str_replace_env(path_str, path_size)) {
zc_error("zc_str_replace_env fail");
return -1;
}
if (strchr(path_str, '%') == NULL) {
/* static, no need create specs */
return 0;
}
specs = zc_arraylist_new((zc_arraylist_del_fn)zlog_spec_del);
if (!path_specs) {
zc_error("zc_arraylist_new fail");
return -1;
}
for (p = path_str; *p != '\0'; p = q) {
a_spec = zlog_spec_new(p, &q, time_cache_count);
if (!a_spec) {
zc_error("zlog_spec_new fail");
goto err;
}
if (zc_arraylist_add(specs, a_spec)) {
zc_error("zc_arraylist_add fail");
goto err;
}
}
*path_specs = specs;
return 0;
err:
if (specs) zc_arraylist_del(specs);
if (a_spec) zlog_spec_del(a_spec);
return -1;
}
zlog_rule_t *zlog_rule_new(char *line,
zc_arraylist_t *levels,
zlog_format_t * default_format,
zc_arraylist_t * formats,
unsigned int file_perms,
size_t fsync_period,
int * time_cache_count)
{
int rc = 0;
int nscan = 0;
int nread = 0;
zlog_rule_t *a_rule;
char selector[MAXLEN_CFG_LINE + 1];
char category[MAXLEN_CFG_LINE + 1];
char level[MAXLEN_CFG_LINE + 1];
char *action;
char output[MAXLEN_CFG_LINE + 1];
char format_name[MAXLEN_CFG_LINE + 1];
char file_path[MAXLEN_CFG_LINE + 1];
char archive_max_size[MAXLEN_CFG_LINE + 1];
char *file_limit;
char *p;
char *q;
size_t len;
zc_assert(line, NULL);
zc_assert(default_format, NULL);
zc_assert(formats, NULL);
a_rule = calloc(1, sizeof(zlog_rule_t));
if (!a_rule) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_rule->file_perms = file_perms;
a_rule->fsync_period = fsync_period;
/* line [f.INFO "%H/log/aa.log", 20MB * 12; MyTemplate]
* selector [f.INFO]
* *action ["%H/log/aa.log", 20MB * 12; MyTemplate]
*/
memset(&selector, 0x00, sizeof(selector));
nscan = sscanf(line, "%s %n", selector, &nread);
if (nscan != 1) {
zc_error("sscanf [%s] fail, selector", line);
goto err;
}
action = line + nread;
/*
* selector [f.INFO]
* category [f]
* level [.INFO]
*/
memset(category, 0x00, sizeof(category));
memset(level, 0x00, sizeof(level));
nscan = sscanf(selector, " %[^.].%s", category, level);
if (nscan != 2) {
zc_error("sscanf [%s] fail, category or level is null",
selector);
goto err;
}
/* check and set category */
for (p = category; *p != '\0'; p++) {
if ((!isalnum(*p)) && (*p != '_') && (*p != '-') && (*p != '*') && (*p != '!')) {
zc_error("category name[%s] character is not in [a-Z][0-9][_!*-]", category);
goto err;
}
}
/* as one line can't be longer than MAXLEN_CFG_LINE, same as category */
strcpy(a_rule->category, category);
/* check and set level */
switch (level[0]) {
case '=':
/* aa.=debug */
a_rule->compare_char = '=';
p = level + 1;
break;
case '!':
/* aa.!debug */
a_rule->compare_char = '!';
p = level + 1;
break;
case '*':
/* aa.* */
a_rule->compare_char = '*';
p = level;
break;
default:
/* aa.debug */
a_rule->compare_char = '.';
p = level;
break;
}
a_rule->level = zlog_level_list_atoi(levels, p);
/* level_bit is a bitmap represents which level can be output
* 32bytes, [0-255] levels, see level.c
* which bit field is 1 means allow output and 0 not
*/
switch (a_rule->compare_char) {
case '=':
memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap));
a_rule->level_bitmap[a_rule->level / 8] |= (1 << (7 - a_rule->level % 8));
break;
case '!':
memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap));
a_rule->level_bitmap[a_rule->level / 8] &= ~(1 << (7 - a_rule->level % 8));
break;
case '*':
memset(a_rule->level_bitmap, 0xFF, sizeof(a_rule->level_bitmap));
break;
case '.':
memset(a_rule->level_bitmap, 0x00, sizeof(a_rule->level_bitmap));
a_rule->level_bitmap[a_rule->level / 8] |= ~(0xFF << (8 - a_rule->level % 8));
memset(a_rule->level_bitmap + a_rule->level / 8 + 1, 0xFF,
sizeof(a_rule->level_bitmap) - a_rule->level / 8 - 1);
break;
}
/* action ["%H/log/aa.log", 20MB * 12 ; MyTemplate]
* output ["%H/log/aa.log", 20MB * 12]
* format [MyTemplate]
*/
memset(output, 0x00, sizeof(output));
memset(format_name, 0x00, sizeof(format_name));
nscan = sscanf(action, " %[^;];%s", output, format_name);
if (nscan < 1) {
zc_error("sscanf [%s] fail", action);
goto err;
}
/* check and get format */
if (STRCMP(format_name, ==, "")) {
zc_debug("no format specified, use default");
a_rule->format = default_format;
} else {
int i;
int find_flag = 0;
zlog_format_t *a_format;
zc_arraylist_foreach(formats, i, a_format) {
if (zlog_format_has_name(a_format, format_name)) {
a_rule->format = a_format;
find_flag = 1;
break;
}
}
if (!find_flag) {
zc_error("in conf file can't find format[%s], pls check",
format_name);
goto err;
}
}
/* output [-"%E(HOME)/log/aa.log" , 20MB*12] [>syslog , LOG_LOCAL0 ]
* file_path [-"%E(HOME)/log/aa.log" ] [>syslog ]
* *file_limit [20MB * 12 ~ "aa.#i.log" ] [LOG_LOCAL0]
*/
memset(file_path, 0x00, sizeof(file_path));
nscan = sscanf(output, " %[^,],", file_path);
if (nscan < 1) {
zc_error("sscanf [%s] fail", action);
goto err;
}
file_limit = strchr(output, ',');
if (file_limit) {
file_limit++; /* skip the , */
while( isspace(*file_limit) ) {
file_limit++;
}
}
p = NULL;
switch (file_path[0]) {
case '-' :
/* sync file each time write log */
if (file_path[1] != '"') {
zc_error(" - must set before a file output");
goto err;
}
/* no need to fsync, as file is opened by O_SYNC, write immediately */
a_rule->fsync_period = 0;
p = file_path + 1;
a_rule->file_open_flags = O_SYNC;
/* fall through */
case '"' :
if (!p) p = file_path;
rc = zlog_rule_parse_path(p, a_rule->file_path, sizeof(a_rule->file_path),
&(a_rule->dynamic_specs), time_cache_count);
if (rc) {
zc_error("zlog_rule_parse_path fail");
goto err;
}
if (file_limit) {
memset(archive_max_size, 0x00, sizeof(archive_max_size));
nscan = sscanf(file_limit, " %[0-9MmKkBb] * %d ~",
archive_max_size, &(a_rule->archive_max_count));
if (nscan) {
a_rule->archive_max_size = zc_parse_byte_size(archive_max_size);
}
p = strchr(file_limit, '"');
if (p) { /* archive file path exist */
rc = zlog_rule_parse_path(p,
a_rule->archive_path, sizeof(a_rule->file_path),
&(a_rule->archive_specs), time_cache_count);
if (rc) {
zc_error("zlog_rule_parse_path fail");
goto err;
}
p = strchr(a_rule->archive_path, '#');
if ( (p == NULL) || ((strchr(p, 'r') == NULL) && (strchr(p, 's') == NULL))) {
zc_error("archive_path must contain #r or #s");
goto err;
}
}
}
/* try to figure out if the log file path is dynamic or static */
if (a_rule->dynamic_specs) {
if (a_rule->archive_max_size <= 0) {
a_rule->output = zlog_rule_output_dynamic_file_single;
} else {
a_rule->output = zlog_rule_output_dynamic_file_rotate;
}
} else {
struct stat stb;
if (a_rule->archive_max_size <= 0) {
a_rule->output = zlog_rule_output_static_file_single;
} else {
/* as rotate, so need to reopen everytime */
a_rule->output = zlog_rule_output_static_file_rotate;
}
a_rule->static_fd = open(a_rule->file_path,
O_WRONLY | O_APPEND | O_CREAT | a_rule->file_open_flags,
a_rule->file_perms);
if (a_rule->static_fd < 0) {
zc_error("open file[%s] fail, errno[%d]", a_rule->file_path, errno);
goto err;
}
/* save off the inode information for checking for a changed file later on */
if (fstat(a_rule->static_fd, &stb)) {
zc_error("stat [%s] fail, errno[%d], failing to open static_fd", a_rule->file_path, errno);
goto err;
}
if (a_rule->archive_max_size > 0) {
close(a_rule->static_fd);
a_rule->static_fd = -1;
}
a_rule->static_dev = stb.st_dev;
a_rule->static_ino = stb.st_ino;
}
break;
case '|' :
a_rule->pipe_fp = popen(output + 1, "w");
if (!a_rule->pipe_fp) {
zc_error("popen fail, errno[%d]", errno);
goto err;
}
a_rule->pipe_fd = fileno(a_rule->pipe_fp);
if (a_rule->pipe_fd < 0 ) {
zc_error("fileno fail, errno[%d]", errno);
goto err;
}
a_rule->output = zlog_rule_output_pipe;
break;
case '>' :
if (STRNCMP(file_path + 1, ==, "syslog", 6)) {
a_rule->syslog_facility = syslog_facility_atoi(file_limit);
if (a_rule->syslog_facility == -187) {
zc_error("-187 get");
goto err;
}
a_rule->output = zlog_rule_output_syslog;
openlog(NULL, LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_USER);
} else if (STRNCMP(file_path + 1, ==, "stdout", 6)) {
a_rule->output = zlog_rule_output_stdout;
} else if (STRNCMP(file_path + 1, ==, "stderr", 6)) {
a_rule->output = zlog_rule_output_stderr;
} else {
zc_error
("[%s]the string after is not syslog, stdout or stderr", output);
goto err;
}
break;
case '$' :
sscanf(file_path + 1, "%s", a_rule->record_name);
if (file_limit) { /* record path exists */
p = strchr(file_limit, '"');
if (!p) {
zc_error("record_path not start with \", [%s]", file_limit);
goto err;
}
p++; /* skip 1st " */
q = strrchr(p, '"');
if (!q) {
zc_error("matching \" not found in conf line[%s]", p);
goto err;
}
len = q - p;
if (len > sizeof(a_rule->record_path) - 1) {
zc_error("record_path too long %ld > %ld", len, sizeof(a_rule->record_path) - 1);
goto err;
}
memcpy(a_rule->record_path, p, len);
}
/* replace any environment variables like %E(HOME) */
rc = zc_str_replace_env(a_rule->record_path, sizeof(a_rule->record_path));
if (rc) {
zc_error("zc_str_replace_env fail");
goto err;
}
/* try to figure out if the log file path is dynamic or static */
if (strchr(a_rule->record_path, '%') == NULL) {
a_rule->output = zlog_rule_output_static_record;
} else {
zlog_spec_t *a_spec;
a_rule->output = zlog_rule_output_dynamic_record;
a_rule->dynamic_specs = zc_arraylist_new((zc_arraylist_del_fn)zlog_spec_del);
if (!(a_rule->dynamic_specs)) {
zc_error("zc_arraylist_new fail");
goto err;
}
for (p = a_rule->record_path; *p != '\0'; p = q) {
a_spec = zlog_spec_new(p, &q, time_cache_count);
if (!a_spec) {
zc_error("zlog_spec_new fail");
goto err;
}
rc = zc_arraylist_add(a_rule->dynamic_specs, a_spec);
if (rc) {
zlog_spec_del(a_spec);
zc_error("zc_arraylist_add fail");
goto err;
}
}
}
break;
default :
zc_error("the 1st char[%c] of file_path[%s] is wrong",
file_path[0], file_path);
goto err;
}
return a_rule;
err:
zlog_rule_del(a_rule);
return NULL;
}
void zlog_rule_del(zlog_rule_t * a_rule)
{
zc_assert(a_rule,);
if (a_rule->dynamic_specs) {
zc_arraylist_del(a_rule->dynamic_specs);
a_rule->dynamic_specs = NULL;
}
if (a_rule->static_fd > 0) {
if (close(a_rule->static_fd)) {
zc_error("close fail, maybe cause by write, errno[%d]", errno);
}
}
if (a_rule->pipe_fp) {
if (pclose(a_rule->pipe_fp) == -1) {
zc_error("pclose fail, errno[%d]", errno);
}
}
if (a_rule->archive_specs) {
zc_arraylist_del(a_rule->archive_specs);
a_rule->archive_specs = NULL;
}
zc_debug("zlog_rule_del[%p]", a_rule);
free(a_rule);
return;
}
/*******************************************************************************/
int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread)
{
switch (a_rule->compare_char) {
case '*' :
return a_rule->output(a_rule, a_thread);
break;
case '.' :
if (a_thread->event->level >= a_rule->level) {
return a_rule->output(a_rule, a_thread);
} else {
return 0;
}
break;
case '=' :
if (a_thread->event->level == a_rule->level) {
return a_rule->output(a_rule, a_thread);
} else {
return 0;
}
break;
case '!' :
if (a_thread->event->level != a_rule->level) {
return a_rule->output(a_rule, a_thread);
} else {
return 0;
}
break;
}
return 0;
}
/*******************************************************************************/
int zlog_rule_is_wastebin(zlog_rule_t * a_rule)
{
zc_assert(a_rule, -1);
if (STRCMP(a_rule->category, ==, "!")) {
return 1;
}
return 0;
}
/*******************************************************************************/
int zlog_rule_match_category(zlog_rule_t * a_rule, char *category)
{
zc_assert(a_rule, -1);
zc_assert(category, -1);
if (STRCMP(a_rule->category, ==, "*")) {
/* '*' match anything, so go on */
return 1;
} else if (STRCMP(a_rule->category, ==, category)) {
/* accurate compare */
return 1;
} else {
/* aa_ match aa_xx & aa, but not match aa1_xx */
size_t len;
len = strlen(a_rule->category);
if (a_rule->category[len - 1] == '_') {
if (strlen(category) == len - 1) {
len--;
}
if (STRNCMP(a_rule->category, ==, category, len)) {
return 1;
}
}
}
return 0;
}
/*******************************************************************************/
int zlog_rule_set_record(zlog_rule_t * a_rule, zc_hashtable_t *records)
{
zlog_record_t *a_record;
if (a_rule->output != zlog_rule_output_static_record
&& a_rule->output != zlog_rule_output_dynamic_record) {
return 0; /* fliter, may go through not record rule */
}
a_record = zc_hashtable_get(records, a_rule->record_name);
if (a_record) {
a_rule->record_func = a_record->output;
}
return 0;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
/**
* @file rule.h
* @brief rule decide to output in format by category & level
*/
#ifndef __zlog_rule_h
#define __zlog_rule_h
#include <stdio.h>
#include <pthread.h>
#include "zc_defs.h"
#include "format.h"
#include "thread.h"
#include "rotater.h"
#include "record.h"
typedef struct zlog_rule_s zlog_rule_t;
typedef int (*zlog_rule_output_fn) (zlog_rule_t * a_rule, zlog_thread_t * a_thread);
struct zlog_rule_s {
char category[MAXLEN_CFG_LINE + 1];
char compare_char;
/*
* [*] log all level
* [.] log level >= rule level, default
* [=] log level == rule level
* [!] log level != rule level
*/
int level;
unsigned char level_bitmap[32]; /* for category determine whether ouput or not */
unsigned int file_perms;
int file_open_flags;
char file_path[MAXLEN_PATH + 1];
zc_arraylist_t *dynamic_specs;
int static_fd;
dev_t static_dev;
ino_t static_ino;
long archive_max_size;
int archive_max_count;
char archive_path[MAXLEN_PATH + 1];
zc_arraylist_t *archive_specs;
FILE *pipe_fp;
int pipe_fd;
size_t fsync_period;
size_t fsync_count;
zc_arraylist_t *levels;
int syslog_facility;
zlog_format_t *format;
zlog_rule_output_fn output;
char record_name[MAXLEN_PATH + 1];
char record_path[MAXLEN_PATH + 1];
zlog_record_fn record_func;
};
zlog_rule_t *zlog_rule_new(char * line,
zc_arraylist_t * levels,
zlog_format_t * default_format,
zc_arraylist_t * formats,
unsigned int file_perms,
size_t fsync_period,
int * time_cache_count);
void zlog_rule_del(zlog_rule_t * a_rule);
void zlog_rule_profile(zlog_rule_t * a_rule, int flag);
int zlog_rule_match_category(zlog_rule_t * a_rule, char *category);
int zlog_rule_is_wastebin(zlog_rule_t * a_rule);
int zlog_rule_set_record(zlog_rule_t * a_rule, zc_hashtable_t *records);
int zlog_rule_output(zlog_rule_t * a_rule, zlog_thread_t * a_thread);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include "conf.h"
#include "spec.h"
#include "level_list.h"
#include "zc_defs.h"
#define ZLOG_DEFAULT_TIME_FMT "%F %T"
#define ZLOG_HEX_HEAD \
"\n 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF"
/*******************************************************************************/
void zlog_spec_profile(zlog_spec_t * a_spec, int flag)
{
zc_assert(a_spec,);
zc_profile(flag, "----spec[%p][%.*s][%s|%d][%s,%ld,%ld,%s][%s]----",
a_spec,
a_spec->len, a_spec->str,
a_spec->time_fmt,
a_spec->time_cache_index,
a_spec->print_fmt, (long)a_spec->max_width, (long)a_spec->min_width, a_spec->left_fill_zeros ? "true" : "false",
a_spec->mdc_key);
return;
}
/*******************************************************************************/
/* implementation of write function */
static int zlog_spec_write_time(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
zlog_time_cache_t * a_cache = a_thread->event->time_caches + a_spec->time_cache_index;
time_t now_sec = a_thread->event->time_stamp.tv_sec;
struct tm *time_local = &(a_thread->event->time_local);
/* the event meet the 1st time_spec in his life cycle */
if (!now_sec) {
gettimeofday(&(a_thread->event->time_stamp), NULL);
now_sec = a_thread->event->time_stamp.tv_sec;
}
/* When this event's last cached time_local is not now */
if (a_thread->event->time_local_sec != now_sec) {
localtime_r(&(now_sec), time_local);
a_thread->event->time_local_sec = now_sec;
}
/* When this spec's last cache time string is not now */
if (a_cache->sec != now_sec) {
a_cache->len = strftime(a_cache->str, sizeof(a_cache->str), a_spec->time_fmt, time_local);
a_cache->sec = now_sec;
}
return zlog_buf_append(a_buf, a_cache->str, a_cache->len);
}
#if 0
static int zlog_spec_write_time_D(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (!a_thread->event->time_stamp.tv_sec) {
gettimeofday(&(a_thread->event->time_stamp), NULL);
}
/*
* It is modified when time slips one second.
* So it is a strong cache, as Default time format is always %F %T.
* That's why I said %D is faster than %d()
*/
if (a_thread->event->time_stamp.tv_sec != a_thread->event->time_last_D) {
a_thread->event->time_last_D = a_thread->event->time_stamp.tv_sec;
localtime_r(&(a_thread->event->time_stamp.tv_sec),
&(a_thread->event->time_local));
strftime(a_thread->event->time_cache_D,
sizeof(a_thread->event->time_cache_D),
ZLOG_DEFAULT_TIME_FMT, &(a_thread->event->time_local) );
}
return zlog_buf_append(a_buf, a_thread->event->time_cache_D, sizeof(a_thread->event->time_cache_D) - 1);
}
#endif
static int zlog_spec_write_ms(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (!a_thread->event->time_stamp.tv_sec) {
gettimeofday(&(a_thread->event->time_stamp), NULL);
}
return zlog_buf_printf_dec32(a_buf, (a_thread->event->time_stamp.tv_usec / 1000), 3);
}
static int zlog_spec_write_us(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (!a_thread->event->time_stamp.tv_sec) {
gettimeofday(&(a_thread->event->time_stamp), NULL);
}
return zlog_buf_printf_dec32(a_buf, a_thread->event->time_stamp.tv_usec, 6);
}
static int zlog_spec_write_mdc(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
zlog_mdc_kv_t *a_mdc_kv;
a_mdc_kv = zlog_mdc_get_kv(a_thread->mdc, a_spec->mdc_key);
if (!a_mdc_kv) {
zc_error("zlog_mdc_get_kv key[%s] fail", a_spec->mdc_key);
return 0;
}
return zlog_buf_append(a_buf, a_mdc_kv->value, a_mdc_kv->value_len);
}
static int zlog_spec_write_str(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, a_spec->str, a_spec->len);
}
static int zlog_spec_write_category(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, a_thread->event->category_name, a_thread->event->category_name_len);
}
static int zlog_spec_write_srcfile(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (!a_thread->event->file) {
return zlog_buf_append(a_buf, "(file=null)", sizeof("(file=null)") - 1);
} else {
return zlog_buf_append(a_buf, a_thread->event->file, a_thread->event->file_len);
}
}
static int zlog_spec_write_srcfile_neat(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
char *p;
if ((p = strrchr(a_thread->event->file, '/')) != NULL) {
return zlog_buf_append(a_buf, p + 1,
(char*)a_thread->event->file + a_thread->event->file_len - p - 1);
} else {
if (!a_thread->event->file) {
return zlog_buf_append(a_buf, "(file=null)", sizeof("(file=null)") - 1);
} else {
return zlog_buf_append(a_buf, a_thread->event->file, a_thread->event->file_len);
}
}
}
static int zlog_spec_write_srcline(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_printf_dec64(a_buf, a_thread->event->line, 0);
}
static int zlog_spec_write_srcfunc(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (!a_thread->event->file) {
return zlog_buf_append(a_buf, "(func=null)", sizeof("(func=null)") - 1);
} else {
return zlog_buf_append(a_buf, a_thread->event->func, a_thread->event->func_len);
}
}
static int zlog_spec_write_hostname(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, a_thread->event->host_name, a_thread->event->host_name_len);
}
static int zlog_spec_write_newline(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, FILE_NEWLINE, FILE_NEWLINE_LEN);
}
static int zlog_spec_write_cr(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, "\r", 1);
}
static int zlog_spec_write_percent(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
return zlog_buf_append(a_buf, "%", 1);
}
static int zlog_spec_write_pid(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
/* 1st in event lifecycle */
if (!a_thread->event->pid) {
a_thread->event->pid = getpid();
/* compare with previous event */
if (a_thread->event->pid != a_thread->event->last_pid) {
a_thread->event->last_pid = a_thread->event->pid;
a_thread->event->pid_str_len
= sprintf(a_thread->event->pid_str, "%u", a_thread->event->pid);
}
}
return zlog_buf_append(a_buf, a_thread->event->pid_str, a_thread->event->pid_str_len);
}
static int zlog_spec_write_tid_hex(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
/* don't need to get tid again, as tmap_new_thread fetched it already */
/* and fork not change tid */
return zlog_buf_append(a_buf, a_thread->event->tid_hex_str, a_thread->event->tid_hex_str_len);
}
static int zlog_spec_write_tid_long(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
/* don't need to get tid again, as tmap_new_thread fetched it already */
/* and fork not change tid */
return zlog_buf_append(a_buf, a_thread->event->tid_str, a_thread->event->tid_str_len);
}
static int zlog_spec_write_ktid(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
/* don't need to get ktid again, as tmap_new_thread fetched it already */
/* and fork not change tid */
return zlog_buf_append(a_buf, a_thread->event->ktid_str, a_thread->event->ktid_str_len);
}
static int zlog_spec_write_level_lowercase(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
zlog_level_t *a_level;
a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
return zlog_buf_append(a_buf, a_level->str_lowercase, a_level->str_len);
}
static int zlog_spec_write_level_uppercase(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
zlog_level_t *a_level;
a_level = zlog_level_list_get(zlog_env_conf->levels, a_thread->event->level);
return zlog_buf_append(a_buf, a_level->str_uppercase, a_level->str_len);
}
static int zlog_spec_write_usrmsg(zlog_spec_t * a_spec, zlog_thread_t * a_thread, zlog_buf_t * a_buf)
{
if (a_thread->event->generate_cmd == ZLOG_FMT) {
if (a_thread->event->str_format) {
return zlog_buf_vprintf(a_buf,
a_thread->event->str_format,
a_thread->event->str_args);
} else {
return zlog_buf_append(a_buf, "format=(null)", sizeof("format=(null)")-1);
}
} else if (a_thread->event->generate_cmd == ZLOG_HEX) {
int rc;
long line_offset;
long byte_offset;
/* thread buf start == null or len <= 0 */
if (a_thread->event->hex_buf == NULL) {
rc = zlog_buf_append(a_buf, "buf=(null)", sizeof("buf=(null)")-1);
goto zlog_hex_exit;
}
rc = zlog_buf_append(a_buf, ZLOG_HEX_HEAD, sizeof(ZLOG_HEX_HEAD)-1);
if (rc) {
goto zlog_hex_exit;
}
line_offset = 0;
//byte_offset = 0;
while (1) {
unsigned char c;
rc = zlog_buf_append(a_buf, "\n", 1);
if (rc) goto zlog_hex_exit;
rc = zlog_buf_printf_dec64(a_buf, line_offset + 1, 10);
if (rc) goto zlog_hex_exit;
rc = zlog_buf_append(a_buf, " ", 3);
if (rc) goto zlog_hex_exit;
for (byte_offset = 0; byte_offset < 16; byte_offset++) {
if (line_offset * 16 + byte_offset < a_thread->event->hex_buf_len) {
c = *((unsigned char *)a_thread->event->hex_buf
+ line_offset * 16 + byte_offset);
rc = zlog_buf_printf_hex(a_buf, c, 2);
if (rc) goto zlog_hex_exit;
rc = zlog_buf_append(a_buf, " ", 1);
if (rc) goto zlog_hex_exit;
} else {
rc = zlog_buf_append(a_buf, " ", 3);
if (rc) goto zlog_hex_exit;
}
}
rc = zlog_buf_append(a_buf, " ", 2);
if (rc) goto zlog_hex_exit;
for (byte_offset = 0; byte_offset < 16; byte_offset++) {
if (line_offset * 16 + byte_offset < a_thread->event->hex_buf_len) {
c = *((unsigned char *)a_thread->event->hex_buf
+ line_offset * 16 + byte_offset);
if (c >= 32 && c <= 126) {
rc = zlog_buf_append(a_buf,(char*)&c, 1);
if (rc) goto zlog_hex_exit;
} else {
rc = zlog_buf_append(a_buf, ".", 1);
if (rc) goto zlog_hex_exit;
}
} else {
rc = zlog_buf_append(a_buf, " ", 1);
if (rc) goto zlog_hex_exit;
}
}
if (line_offset * 16 + byte_offset >= a_thread->event->hex_buf_len) {
break;
}
line_offset++;
}
zlog_hex_exit:
if (rc < 0) {
zc_error("write hex msg fail");
return -1;
} else if (rc > 0) {
zc_error("write hex msg, buf is full");
return 1;
}
return 0;
}
return 0;
}
/*******************************************************************************/
/* implementation of gen function */
static int zlog_spec_gen_msg_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
/* no need to reprint %1.2d here */
return a_spec->write_buf(a_spec, a_thread, a_thread->msg_buf);
}
static int zlog_spec_gen_msg_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
int rc;
zlog_buf_restart(a_thread->pre_msg_buf);
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_msg_buf);
if (rc < 0) {
zc_error("a_spec->gen_buf fail");
return -1;
} else if (rc > 0) {
/* buf is full, try printf */
}
return zlog_buf_adjust_append(a_thread->msg_buf,
zlog_buf_str(a_thread->pre_msg_buf), zlog_buf_len(a_thread->pre_msg_buf),
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
}
/*******************************************************************************/
static int zlog_spec_gen_path_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
/* no need to reprint %1.2d here */
return a_spec->write_buf(a_spec, a_thread, a_thread->path_buf);
}
static int zlog_spec_gen_path_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
int rc;
zlog_buf_restart(a_thread->pre_path_buf);
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_path_buf);
if (rc < 0) {
zc_error("a_spec->gen_buf fail");
return -1;
} else if (rc > 0) {
/* buf is full, try printf */
}
return zlog_buf_adjust_append(a_thread->path_buf,
zlog_buf_str(a_thread->pre_path_buf), zlog_buf_len(a_thread->pre_path_buf),
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
}
/*******************************************************************************/
static int zlog_spec_gen_archive_path_direct(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
/* no need to reprint %1.2d here */
return a_spec->write_buf(a_spec, a_thread, a_thread->archive_path_buf);
}
static int zlog_spec_gen_archive_path_reformat(zlog_spec_t * a_spec, zlog_thread_t * a_thread)
{
int rc;
zlog_buf_restart(a_thread->pre_path_buf);
rc = a_spec->write_buf(a_spec, a_thread, a_thread->pre_path_buf);
if (rc < 0) {
zc_error("a_spec->gen_buf fail");
return -1;
} else if (rc > 0) {
/* buf is full, try printf */
}
return zlog_buf_adjust_append(a_thread->archive_path_buf,
zlog_buf_str(a_thread->pre_path_buf), zlog_buf_len(a_thread->pre_path_buf),
a_spec->left_adjust, a_spec->left_fill_zeros, a_spec->min_width, a_spec->max_width);
}
/*******************************************************************************/
static int zlog_spec_parse_print_fmt(zlog_spec_t * a_spec)
{
/* -12.35 12 .35 */
char *p, *q;
long i, j;
p = a_spec->print_fmt;
if (*p == '-') {
a_spec->left_adjust = 1;
p++;
} else {
if (*p == '0') {
a_spec->left_fill_zeros = 1;
}
a_spec->left_adjust = 0;
}
i = j = 0;
sscanf(p, "%ld.", &i);
q = strchr(p, '.');
if (q) sscanf(q, ".%ld", &j);
a_spec->min_width = (size_t) i;
a_spec->max_width = (size_t) j;
return 0;
}
/*******************************************************************************/
void zlog_spec_del(zlog_spec_t * a_spec)
{
zc_assert(a_spec,);
zc_debug("zlog_spec_del[%p]", a_spec);
free(a_spec);
}
/* a spec may consist of
* a const string: /home/bb
* a string begin with %: %12.35d(%F %X,%l)
*/
zlog_spec_t *zlog_spec_new(char *pattern_start, char **pattern_next, int *time_cache_count)
{
char *p;
int nscan = 0;
int nread = 0;
zlog_spec_t *a_spec;
zc_assert(pattern_start, NULL);
zc_assert(pattern_next, NULL);
a_spec = calloc(1, sizeof(zlog_spec_t));
if (!a_spec) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_spec->str = p = pattern_start;
switch (*p) {
case '%':
/* a string begin with %: %12.35d(%F %X) */
/* process width and precision char in %-12.35P */
nread = 0;
nscan = sscanf(p, "%%%[.0-9-]%n", a_spec->print_fmt, &nread);
if (nscan == 1) {
a_spec->gen_msg = zlog_spec_gen_msg_reformat;
a_spec->gen_path = zlog_spec_gen_path_reformat;
a_spec->gen_archive_path = zlog_spec_gen_archive_path_reformat;
if (zlog_spec_parse_print_fmt(a_spec)) {
zc_error("zlog_spec_parse_print_fmt fail");
goto err;
}
} else {
nread = 1; /* skip the % char */
a_spec->gen_msg = zlog_spec_gen_msg_direct;
a_spec->gen_path = zlog_spec_gen_path_direct;
a_spec->gen_archive_path = zlog_spec_gen_archive_path_direct;
}
p += nread;
if (*p == 'd') {
if (*(p+1) != '(') {
/* without '(' , use default */
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
p++;
} else if (STRNCMP(p, ==, "d()", 3)) {
/* with () but without detail time format,
* keep a_spec->time_fmt=="" */
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
p += 3;
} else {
nread = 0;
nscan = sscanf(p, "d(%[^)])%n", a_spec->time_fmt, &nread);
if (nscan != 1) {
nread = 0;
}
p += nread;
if (*(p - 1) != ')') {
zc_error("in string[%s] can't find match \')\'", a_spec->str);
goto err;
}
}
a_spec->time_cache_index = *time_cache_count;
(*time_cache_count)++;
a_spec->write_buf = zlog_spec_write_time;
*pattern_next = p;
a_spec->len = p - a_spec->str;
break;
}
if (*p == 'M') {
nread = 0;
nscan = sscanf(p, "M(%[^)])%n", a_spec->mdc_key, &nread);
if (nscan != 1) {
nread = 0;
if (STRNCMP(p, ==, "M()", 3)) {
nread = 3;
}
}
p += nread;
if (*(p - 1) != ')') {
zc_error("in string[%s] can't find match \')\'", a_spec->str);
goto err;
}
*pattern_next = p;
a_spec->len = p - a_spec->str;
a_spec->write_buf = zlog_spec_write_mdc;
break;
}
if (STRNCMP(p, ==, "ms", 2)) {
p += 2;
*pattern_next = p;
a_spec->len = p - a_spec->str;
a_spec->write_buf = zlog_spec_write_ms;
break;
} else if (STRNCMP(p, ==, "us", 2)) {
p += 2;
*pattern_next = p;
a_spec->len = p - a_spec->str;
a_spec->write_buf = zlog_spec_write_us;
break;
}
*pattern_next = p + 1;
a_spec->len = p - a_spec->str + 1;
switch (*p) {
case 'c':
a_spec->write_buf = zlog_spec_write_category;
break;
case 'D':
strcpy(a_spec->time_fmt, ZLOG_DEFAULT_TIME_FMT);
a_spec->time_cache_index = *time_cache_count;
(*time_cache_count)++;
a_spec->write_buf = zlog_spec_write_time;
break;
case 'F':
a_spec->write_buf = zlog_spec_write_srcfile;
break;
case 'f':
a_spec->write_buf = zlog_spec_write_srcfile_neat;
break;
case 'H':
a_spec->write_buf = zlog_spec_write_hostname;
break;
case 'k':
a_spec->write_buf = zlog_spec_write_ktid;
break;
case 'L':
a_spec->write_buf = zlog_spec_write_srcline;
break;
case 'm':
a_spec->write_buf = zlog_spec_write_usrmsg;
break;
case 'n':
a_spec->write_buf = zlog_spec_write_newline;
break;
case 'r':
a_spec->write_buf = zlog_spec_write_cr;
break;
case 'p':
a_spec->write_buf = zlog_spec_write_pid;
break;
case 'U':
a_spec->write_buf = zlog_spec_write_srcfunc;
break;
case 'v':
a_spec->write_buf = zlog_spec_write_level_lowercase;
break;
case 'V':
a_spec->write_buf = zlog_spec_write_level_uppercase;
break;
case 't':
a_spec->write_buf = zlog_spec_write_tid_hex;
break;
case 'T':
a_spec->write_buf = zlog_spec_write_tid_long;
break;
case '%':
a_spec->write_buf = zlog_spec_write_percent;
break;
default:
zc_error("str[%s] in wrong format, p[%c]", a_spec->str, *p);
goto err;
}
break;
default:
/* a const string: /home/bb */
*pattern_next = strchr(p, '%');
if (*pattern_next) {
a_spec->len = *pattern_next - p;
} else {
a_spec->len = strlen(p);
*pattern_next = p + a_spec->len;
}
a_spec->write_buf = zlog_spec_write_str;
a_spec->gen_msg = zlog_spec_gen_msg_direct;
a_spec->gen_path = zlog_spec_gen_path_direct;
a_spec->gen_archive_path = zlog_spec_gen_archive_path_direct;
}
zlog_spec_profile(a_spec, ZC_DEBUG);
return a_spec;
err:
zlog_spec_del(a_spec);
return NULL;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_spec_h
#define __zlog_spec_h
#include "event.h"
#include "buf.h"
#include "thread.h"
typedef struct zlog_spec_s zlog_spec_t;
/* write buf, according to each spec's Conversion Characters */
typedef int (*zlog_spec_write_fn) (zlog_spec_t * a_spec,
zlog_thread_t * a_thread,
zlog_buf_t * a_buf);
/* gen a_thread->msg or gen a_thread->path by using write_fn */
typedef int (*zlog_spec_gen_fn) (zlog_spec_t * a_spec,
zlog_thread_t * a_thread);
struct zlog_spec_s {
char *str;
int len;
char time_fmt[MAXLEN_CFG_LINE + 1];
int time_cache_index;
char mdc_key[MAXLEN_PATH + 1];
char print_fmt[MAXLEN_CFG_LINE + 1];
int left_adjust;
int left_fill_zeros;
size_t max_width;
size_t min_width;
zlog_spec_write_fn write_buf;
zlog_spec_gen_fn gen_msg;
zlog_spec_gen_fn gen_path;
zlog_spec_gen_fn gen_archive_path;
};
zlog_spec_t *zlog_spec_new(char *pattern_start, char **pattern_end, int * time_cache_count);
void zlog_spec_del(zlog_spec_t * a_spec);
void zlog_spec_profile(zlog_spec_t * a_spec, int flag);
#define zlog_spec_gen_msg(a_spec, a_thread) \
a_spec->gen_msg(a_spec, a_thread)
#define zlog_spec_gen_path(a_spec, a_thread) \
a_spec->gen_path(a_spec, a_thread)
#define zlog_spec_gen_archive_path(a_spec, a_thread) \
a_spec->gen_archive_path(a_spec, a_thread)
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <pthread.h>
#include <errno.h>
#include "zc_defs.h"
#include "event.h"
#include "buf.h"
#include "thread.h"
#include "mdc.h"
void zlog_thread_profile(zlog_thread_t * a_thread, int flag)
{
zc_assert(a_thread,);
zc_profile(flag, "--thread[%p][%p][%p][%p,%p,%p,%p,%p]--",
a_thread,
a_thread->mdc,
a_thread->event,
a_thread->pre_path_buf,
a_thread->path_buf,
a_thread->archive_path_buf,
a_thread->pre_msg_buf,
a_thread->msg_buf);
zlog_mdc_profile(a_thread->mdc, flag);
zlog_event_profile(a_thread->event, flag);
zlog_buf_profile(a_thread->pre_path_buf, flag);
zlog_buf_profile(a_thread->path_buf, flag);
zlog_buf_profile(a_thread->archive_path_buf, flag);
zlog_buf_profile(a_thread->pre_msg_buf, flag);
zlog_buf_profile(a_thread->msg_buf, flag);
return;
}
/*******************************************************************************/
void zlog_thread_del(zlog_thread_t * a_thread)
{
zc_assert(a_thread,);
if (a_thread->mdc)
zlog_mdc_del(a_thread->mdc);
if (a_thread->event)
zlog_event_del(a_thread->event);
if (a_thread->pre_path_buf)
zlog_buf_del(a_thread->pre_path_buf);
if (a_thread->path_buf)
zlog_buf_del(a_thread->path_buf);
if (a_thread->archive_path_buf)
zlog_buf_del(a_thread->archive_path_buf);
if (a_thread->pre_msg_buf)
zlog_buf_del(a_thread->pre_msg_buf);
if (a_thread->msg_buf)
zlog_buf_del(a_thread->msg_buf);
zc_debug("zlog_thread_del[%p]", a_thread);
free(a_thread);
return;
}
zlog_thread_t *zlog_thread_new(int init_version, size_t buf_size_min, size_t buf_size_max, int time_cache_count)
{
zlog_thread_t *a_thread;
a_thread = calloc(1, sizeof(zlog_thread_t));
if (!a_thread) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_thread->init_version = init_version;
a_thread->mdc = zlog_mdc_new();
if (!a_thread->mdc) {
zc_error("zlog_mdc_new fail");
goto err;
}
a_thread->event = zlog_event_new(time_cache_count);
if (!a_thread->event) {
zc_error("zlog_event_new fail");
goto err;
}
a_thread->pre_path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
if (!a_thread->pre_path_buf) {
zc_error("zlog_buf_new fail");
goto err;
}
a_thread->path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
if (!a_thread->path_buf) {
zc_error("zlog_buf_new fail");
goto err;
}
a_thread->archive_path_buf = zlog_buf_new(MAXLEN_PATH + 1, MAXLEN_PATH + 1, NULL);
if (!a_thread->archive_path_buf) {
zc_error("zlog_buf_new fail");
goto err;
}
a_thread->pre_msg_buf = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
if (!a_thread->pre_msg_buf) {
zc_error("zlog_buf_new fail");
goto err;
}
a_thread->msg_buf = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
if (!a_thread->msg_buf) {
zc_error("zlog_buf_new fail");
goto err;
}
//zlog_thread_profile(a_thread, ZC_DEBUG);
return a_thread;
err:
zlog_thread_del(a_thread);
return NULL;
}
/*******************************************************************************/
int zlog_thread_rebuild_msg_buf(zlog_thread_t * a_thread, size_t buf_size_min, size_t buf_size_max)
{
zlog_buf_t *pre_msg_buf_new = NULL;
zlog_buf_t *msg_buf_new = NULL;
zc_assert(a_thread, -1);
if ( (a_thread->msg_buf->size_min == buf_size_min)
&& (a_thread->msg_buf->size_max == buf_size_max)) {
zc_debug("buf size not changed, no need rebuild");
return 0;
}
pre_msg_buf_new = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
if (!pre_msg_buf_new) {
zc_error("zlog_buf_new fail");
goto err;
}
msg_buf_new = zlog_buf_new(buf_size_min, buf_size_max, "..." FILE_NEWLINE);
if (!msg_buf_new) {
zc_error("zlog_buf_new fail");
goto err;
}
zlog_buf_del(a_thread->pre_msg_buf);
a_thread->pre_msg_buf = pre_msg_buf_new;
zlog_buf_del(a_thread->msg_buf);
a_thread->msg_buf = msg_buf_new;
return 0;
err:
if (pre_msg_buf_new) zlog_buf_del(pre_msg_buf_new);
if (msg_buf_new) zlog_buf_del(msg_buf_new);
return -1;
}
int zlog_thread_rebuild_event(zlog_thread_t * a_thread, int time_cache_count)
{
zlog_event_t *event_new = NULL;
zc_assert(a_thread, -1);
event_new = zlog_event_new(time_cache_count);
if (!event_new) {
zc_error("zlog_event_new fail");
goto err;
}
zlog_event_del(a_thread->event);
a_thread->event = event_new;
return 0;
err:
if (event_new) zlog_event_del(event_new);
return -1;
}
/*******************************************************************************/
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_thread_h
#define __zlog_thread_h
#include "zc_defs.h"
#include "event.h"
#include "buf.h"
#include "mdc.h"
typedef struct {
int init_version;
zlog_mdc_t *mdc;
zlog_event_t *event;
zlog_buf_t *pre_path_buf;
zlog_buf_t *path_buf;
zlog_buf_t *archive_path_buf;
zlog_buf_t *pre_msg_buf;
zlog_buf_t *msg_buf;
} zlog_thread_t;
void zlog_thread_del(zlog_thread_t * a_thread);
void zlog_thread_profile(zlog_thread_t * a_thread, int flag);
zlog_thread_t *zlog_thread_new(int init_version,
size_t buf_size_min, size_t buf_size_max, int time_cache_count);
int zlog_thread_rebuild_msg_buf(zlog_thread_t * a_thread, size_t buf_size_min, size_t buf_size_max);
int zlog_thread_rebuild_event(zlog_thread_t * a_thread, int time_cache_count);
#endif
#define ZLOG_VERSION "1.2.12"
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include "zc_defs.h"
zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del)
{
zc_arraylist_t *a_list;
a_list = (zc_arraylist_t *) calloc(1, sizeof(zc_arraylist_t));
if (!a_list) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_list->size = ARRAY_LIST_DEFAULT_SIZE;
a_list->len = 0;
/* this could be NULL */
a_list->del = del;
a_list->array = (void **)calloc(a_list->size, sizeof(void *));
if (!a_list->array) {
zc_error("calloc fail, errno[%d]", errno);
free(a_list);
return NULL;
}
return a_list;
}
void zc_arraylist_del(zc_arraylist_t * a_list)
{
int i;
if (!a_list)
return;
if (a_list->del) {
for (i = 0; i < a_list->len; i++) {
if (a_list->array[i])
a_list->del(a_list->array[i]);
}
}
if (a_list->array)
free(a_list->array);
free(a_list);
return;
}
static int zc_arraylist_expand_inner(zc_arraylist_t * a_list, int max)
{
void *tmp;
int new_size;
int diff_size;
new_size = zc_max(a_list->size * 2, max);
tmp = realloc(a_list->array, new_size * sizeof(void *));
if (!tmp) {
zc_error("realloc fail, errno[%d]", errno);
return -1;
}
a_list->array = (void **)tmp;
diff_size = new_size - a_list->size;
if (diff_size) memset(a_list->array + a_list->size, 0x00, diff_size * sizeof(void *));
a_list->size = new_size;
return 0;
}
int zc_arraylist_set(zc_arraylist_t * a_list, int idx, void *data)
{
if (idx > a_list->size - 1) {
if (zc_arraylist_expand_inner(a_list, idx)) {
zc_error("expand_internal fail");
return -1;
}
}
if (a_list->array[idx] && a_list->del) a_list->del(a_list->array[idx]);
a_list->array[idx] = data;
if (a_list->len <= idx)
a_list->len = idx + 1;
return 0;
}
int zc_arraylist_add(zc_arraylist_t * a_list, void *data)
{
return zc_arraylist_set(a_list, a_list->len, data);
}
/* assum idx < len */
static int zc_arraylist_insert_inner(zc_arraylist_t * a_list, int idx,
void *data)
{
if (a_list->array[idx] == NULL) {
a_list->array[idx] = data;
return 0;
}
if (a_list->len > a_list->size - 1) {
if (zc_arraylist_expand_inner(a_list, 0)) {
zc_error("expand_internal fail");
return -1;
}
}
memmove(a_list->array + idx + 1, a_list->array + idx,
(a_list->len - idx) * sizeof(void *));
a_list->array[idx] = data;
a_list->len++;
return 0;
}
int zc_arraylist_sortadd(zc_arraylist_t * a_list, zc_arraylist_cmp_fn cmp,
void *data)
{
int i;
for (i = 0; i < a_list->len; i++) {
if ((*cmp) (a_list->array[i], data) > 0)
break;
}
if (i == a_list->len)
return zc_arraylist_add(a_list, data);
else
return zc_arraylist_insert_inner(a_list, i, data);
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_arraylist_h
#define __zc_arraylist_h
#define ARRAY_LIST_DEFAULT_SIZE 32
typedef void (*zc_arraylist_del_fn) (void *data);
typedef int (*zc_arraylist_cmp_fn) (void *data1, void *data2);
/* make zc_arraylist_foreach speed up, so keep struct defination here */
typedef struct {
void **array;
int len;
int size;
zc_arraylist_del_fn del;
} zc_arraylist_t;
zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del);
void zc_arraylist_del(zc_arraylist_t * a_list);
int zc_arraylist_set(zc_arraylist_t * a_list, int i, void *data);
int zc_arraylist_add(zc_arraylist_t * a_list, void *data);
int zc_arraylist_sortadd(zc_arraylist_t * a_list, zc_arraylist_cmp_fn cmp,
void *data);
#define zc_arraylist_len(a_list) (a_list->len)
#define zc_arraylist_get(a_list, i) \
((i >= a_list->len) ? NULL : a_list->array[i])
#define zc_arraylist_foreach(a_list, i, a_unit) \
for(i = 0, a_unit = a_list->array[0]; (i < a_list->len) && (a_unit = a_list->array[i], 1) ; i++)
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_defs_h
#define __zc_defs_h
#include "zc_profile.h"
#include "zc_arraylist.h"
#include "zc_hashtable.h"
#include "zc_xplatform.h"
#include "zc_util.h"
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include "zc_defs.h"
#include "zc_hashtable.h"
struct zc_hashtable_s {
size_t nelem;
zc_hashtable_entry_t **tab;
size_t tab_size;
zc_hashtable_hash_fn hash;
zc_hashtable_equal_fn equal;
zc_hashtable_del_fn key_del;
zc_hashtable_del_fn value_del;
};
zc_hashtable_t *zc_hashtable_new(size_t a_size,
zc_hashtable_hash_fn hash,
zc_hashtable_equal_fn equal,
zc_hashtable_del_fn key_del,
zc_hashtable_del_fn value_del)
{
zc_hashtable_t *a_table;
a_table = calloc(1, sizeof(*a_table));
if (!a_table) {
zc_error("calloc fail, errno[%d]", errno);
return NULL;
}
a_table->tab = calloc(a_size, sizeof(*(a_table->tab)));
if (!a_table->tab) {
zc_error("calloc fail, errno[%d]", errno);
free(a_table);
return NULL;
}
a_table->tab_size = a_size;
a_table->nelem = 0;
a_table->hash = hash;
a_table->equal = equal;
/* these two could be NULL */
a_table->key_del = key_del;
a_table->value_del = value_del;
return a_table;
}
void zc_hashtable_del(zc_hashtable_t * a_table)
{
size_t i;
zc_hashtable_entry_t *p;
zc_hashtable_entry_t *q;
if (!a_table) {
zc_error("a_table[%p] is NULL, just do nothing", a_table);
return;
}
for (i = 0; i < a_table->tab_size; i++) {
for (p = (a_table->tab)[i]; p; p = q) {
q = p->next;
if (a_table->key_del) {
a_table->key_del(p->key);
}
if (a_table->value_del) {
a_table->value_del(p->value);
}
free(p);
}
}
if (a_table->tab)
free(a_table->tab);
free(a_table);
return;
}
void zc_hashtable_clean(zc_hashtable_t * a_table)
{
size_t i;
zc_hashtable_entry_t *p;
zc_hashtable_entry_t *q;
for (i = 0; i < a_table->tab_size; i++) {
for (p = (a_table->tab)[i]; p; p = q) {
q = p->next;
if (a_table->key_del) {
a_table->key_del(p->key);
}
if (a_table->value_del) {
a_table->value_del(p->value);
}
free(p);
}
(a_table->tab)[i] = NULL;
}
a_table->nelem = 0;
return;
}
static int zc_hashtable_rehash(zc_hashtable_t * a_table)
{
size_t i;
size_t j;
size_t tab_size;
zc_hashtable_entry_t **tab;
zc_hashtable_entry_t *p;
zc_hashtable_entry_t *q;
tab_size = 2 * a_table->tab_size;
tab = calloc(tab_size, sizeof(*tab));
if (!tab) {
zc_error("calloc fail, errno[%d]", errno);
return -1;
}
for (i = 0; i < a_table->tab_size; i++) {
for (p = (a_table->tab)[i]; p; p = q) {
q = p->next;
p->next = NULL;
p->prev = NULL;
j = p->hash_key % tab_size;
if (tab[j]) {
tab[j]->prev = p;
p->next = tab[j];
}
tab[j] = p;
}
}
free(a_table->tab);
a_table->tab = tab;
a_table->tab_size = tab_size;
return 0;
}
zc_hashtable_entry_t *zc_hashtable_get_entry(zc_hashtable_t * a_table, const void *a_key)
{
unsigned int i;
zc_hashtable_entry_t *p;
i = a_table->hash(a_key) % a_table->tab_size;
for (p = (a_table->tab)[i]; p; p = p->next) {
if (a_table->equal(a_key, p->key))
return p;
}
return NULL;
}
void *zc_hashtable_get(zc_hashtable_t * a_table, const void *a_key)
{
unsigned int i;
zc_hashtable_entry_t *p;
i = a_table->hash(a_key) % a_table->tab_size;
for (p = (a_table->tab)[i]; p; p = p->next) {
if (a_table->equal(a_key, p->key))
return p->value;
}
return NULL;
}
int zc_hashtable_put(zc_hashtable_t * a_table, void *a_key, void *a_value)
{
int rc = 0;
unsigned int i;
zc_hashtable_entry_t *p = NULL;
i = a_table->hash(a_key) % a_table->tab_size;
for (p = (a_table->tab)[i]; p; p = p->next) {
if (a_table->equal(a_key, p->key))
break;
}
if (p) {
if (a_table->key_del) {
a_table->key_del(p->key);
}
if (a_table->value_del) {
a_table->value_del(p->value);
}
p->key = a_key;
p->value = a_value;
return 0;
} else {
if (a_table->nelem > a_table->tab_size * 1.3) {
rc = zc_hashtable_rehash(a_table);
if (rc) {
zc_error("rehash fail");
return -1;
}
}
p = calloc(1, sizeof(*p));
if (!p) {
zc_error("calloc fail, errno[%d]", errno);
return -1;
}
p->hash_key = a_table->hash(a_key);
p->key = a_key;
p->value = a_value;
p->next = NULL;
p->prev = NULL;
i = p->hash_key % a_table->tab_size;
if ((a_table->tab)[i]) {
(a_table->tab)[i]->prev = p;
p->next = (a_table->tab)[i];
}
(a_table->tab)[i] = p;
a_table->nelem++;
}
return 0;
}
void zc_hashtable_remove(zc_hashtable_t * a_table, const void *a_key)
{
zc_hashtable_entry_t *p;
unsigned int i;
if (!a_table || !a_key) {
zc_error("a_table[%p] or a_key[%p] is NULL, just do nothing", a_table, a_key);
return;
}
i = a_table->hash(a_key) % a_table->tab_size;
for (p = (a_table->tab)[i]; p; p = p->next) {
if (a_table->equal(a_key, p->key))
break;
}
if (!p) {
zc_error("p[%p] not found in hashtable", p);
return;
}
if (a_table->key_del) {
a_table->key_del(p->key);
}
if (a_table->value_del) {
a_table->value_del(p->value);
}
if (p->next) {
p->next->prev = p->prev;
}
if (p->prev) {
p->prev->next = p->next;
} else {
unsigned int i;
i = p->hash_key % a_table->tab_size;
a_table->tab[i] = p->next;
}
free(p);
a_table->nelem--;
return;
}
zc_hashtable_entry_t *zc_hashtable_begin(zc_hashtable_t * a_table)
{
size_t i;
zc_hashtable_entry_t *p;
for (i = 0; i < a_table->tab_size; i++) {
for (p = (a_table->tab)[i]; p; p = p->next) {
if (p)
return p;
}
}
return NULL;
}
zc_hashtable_entry_t *zc_hashtable_next(zc_hashtable_t * a_table, zc_hashtable_entry_t * a_entry)
{
size_t i;
size_t j;
if (a_entry->next)
return a_entry->next;
i = a_entry->hash_key % a_table->tab_size;
for (j = i + 1; j < a_table->tab_size; j++) {
if ((a_table->tab)[j]) {
return (a_table->tab)[j];
}
}
return NULL;
}
/*******************************************************************************/
unsigned int zc_hashtable_str_hash(const void *str)
{
unsigned int h = 5381;
const char *p = (const char *)str;
while (*p != '\0')
h = ((h << 5) + h) + (*p++); /* hash * 33 + c */
return h;
}
int zc_hashtable_str_equal(const void *key1, const void *key2)
{
return (STRCMP((const char *)key1, ==, (const char *)key2));
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_hashtalbe_h
#define __zc_hashtalbe_h
#include <stdlib.h>
typedef struct zc_hashtable_entry_s {
unsigned int hash_key;
void *key;
void *value;
struct zc_hashtable_entry_s *prev;
struct zc_hashtable_entry_s *next;
} zc_hashtable_entry_t;
typedef struct zc_hashtable_s zc_hashtable_t;
typedef unsigned int (*zc_hashtable_hash_fn) (const void *key);
typedef int (*zc_hashtable_equal_fn) (const void *key1, const void *key2);
typedef void (*zc_hashtable_del_fn) (void *kv);
zc_hashtable_t *zc_hashtable_new(size_t a_size,
zc_hashtable_hash_fn hash_fn,
zc_hashtable_equal_fn equal_fn,
zc_hashtable_del_fn key_del_fn,
zc_hashtable_del_fn value_del_fn);
void zc_hashtable_del(zc_hashtable_t * a_table);
void zc_hashtable_clean(zc_hashtable_t * a_table);
int zc_hashtable_put(zc_hashtable_t * a_table, void *a_key, void *a_value);
zc_hashtable_entry_t *zc_hashtable_get_entry(zc_hashtable_t * a_table, const void *a_key);
void *zc_hashtable_get(zc_hashtable_t * a_table, const void *a_key);
void zc_hashtable_remove(zc_hashtable_t * a_table, const void *a_key);
zc_hashtable_entry_t *zc_hashtable_begin(zc_hashtable_t * a_table);
zc_hashtable_entry_t *zc_hashtable_next(zc_hashtable_t * a_table, zc_hashtable_entry_t * a_entry);
#define zc_hashtable_foreach(a_table, a_entry) \
for(a_entry = zc_hashtable_begin(a_table); a_entry; a_entry = zc_hashtable_next(a_table, a_entry))
unsigned int zc_hashtable_str_hash(const void *str);
int zc_hashtable_str_equal(const void *key1, const void *key2);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include "zc_profile.h"
#include "zc_xplatform.h"
static void zc_time(char *time_str, size_t time_str_size)
{
time_t tt;
struct tm local_time;
time(&tt);
localtime_r(&tt, &local_time);
strftime(time_str, time_str_size, "%m-%d %T", &local_time);
return;
}
int zc_profile_inner(int flag, const char *file, const long line, const char *fmt, ...)
{
va_list args;
char time_str[20 + 1];
FILE *fp = NULL;
static char *debug_log = NULL;
static char *error_log = NULL;
static size_t init_flag = 0;
if (!init_flag) {
init_flag = 1;
debug_log = getenv("ZLOG_PROFILE_DEBUG");
error_log = getenv("ZLOG_PROFILE_ERROR");
}
switch (flag) {
case ZC_DEBUG:
if (debug_log == NULL) return 0;
fp = fopen(debug_log, "a");
if (!fp) return -1;
zc_time(time_str, sizeof(time_str));
fprintf(fp, "%s DEBUG (%d:%s:%ld) ", time_str, getpid(), file, line);
break;
case ZC_WARN:
if (error_log == NULL) return 0;
fp = fopen(error_log, "a");
if (!fp) return -1;
zc_time(time_str, sizeof(time_str));
fprintf(fp, "%s WARN (%d:%s:%ld) ", time_str, getpid(), file, line);
break;
case ZC_ERROR:
if (error_log == NULL) return 0;
fp = fopen(error_log, "a");
if (!fp) return -1;
zc_time(time_str, sizeof(time_str));
fprintf(fp, "%s ERROR (%d:%s:%ld) ", time_str, getpid(), file, line);
break;
}
/* writing file twice(time & msg) is not atomic
* may cause cross
* but avoid log size limit */
va_start(args, fmt);
vfprintf(fp, fmt, args);
va_end(args);
fprintf(fp, "\n");
fclose(fp);
return 0;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_profile_h
#define __zc_profile_h
#include <stdarg.h>
#define EMPTY()
#define zc_assert(expr, rv) \
if(!(expr)) { \
zc_error(#expr" is null or 0"); \
return rv; \
}
enum zc_profile_flag {
ZC_DEBUG = 0,
ZC_WARN = 1,
ZC_ERROR = 2
};
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#define zc_debug(...) \
zc_profile_inner(ZC_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define zc_warn(...) \
zc_profile_inner(ZC_WARN, __FILE__, __LINE__, __VA_ARGS__)
#define zc_error(...) \
zc_profile_inner(ZC_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define zc_profile(flag, ...) \
zc_profile_inner(flag, __FILE__, __LINE__, __VA_ARGS__)
#elif defined __GNUC__
#define zc_debug(fmt, args...) \
zc_profile_inner(ZC_DEBUG, __FILE__, __LINE__, fmt, ## args)
#define zc_warn(fmt, args...) \
zc_profile_inner(ZC_WARN, __FILE__, __LINE__, fmt, ## args)
#define zc_error(fmt, args...) \
zc_profile_inner(ZC_ERROR, __FILE__, __LINE__, fmt, ## args)
#define zc_profile(flag, fmt, args...) \
zc_profile_inner(flag, __FILE__, __LINE__, fmt, ## args)
#endif
int zc_profile_inner(int flag,
const char *file, const long line,
const char *fmt, ...);
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include "zc_defs.h"
size_t zc_parse_byte_size(char *astring)
{
/* Parse size in bytes depending on the suffix. Valid suffixes are KB, MB and GB */
char *p;
char *q;
size_t sz;
long res;
int c, m;
zc_assert(astring, 0);
/* clear space */
for (p = q = astring; *p != '\0'; p++) {
if (isspace(*p)) {
continue;
} else {
*q = *p;
q++;
}
}
*q = '\0';
sz = strlen(astring);
res = strtol(astring, (char **)NULL, 10);
if (res <= 0)
return 0;
if (astring[sz - 1] == 'B' || astring[sz - 1] == 'b') {
c = astring[sz - 2];
m = 1024;
} else {
c = astring[sz - 1];
m = 1000;
}
switch (c) {
case 'K':
case 'k':
res *= m;
break;
case 'M':
case 'm':
res *= m * m;
break;
case 'G':
case 'g':
res *= m * m * m;
break;
default:
if (!isdigit(c)) {
zc_error("Wrong suffix parsing " "size in bytes for string [%s], ignoring suffix",
astring);
}
break;
}
return (res);
}
/*******************************************************************************/
int zc_str_replace_env(char *str, size_t str_size)
{
char *p;
char *q;
char fmt[MAXLEN_CFG_LINE + 1];
char env_key[MAXLEN_CFG_LINE + 1];
char env_value[MAXLEN_CFG_LINE + 1];
int str_len;
int env_value_len;
int nscan;
int nread;
str_len = strlen(str);
q = str;
do {
p = strchr(q, '%');
if (!p) {
/* can't find more % */
break;
}
memset(fmt, 0x00, sizeof(fmt));
memset(env_key, 0x00, sizeof(env_key));
memset(env_value, 0x00, sizeof(env_value));
nread = 0;
nscan = sscanf(p + 1, "%[.0-9-]%n", fmt + 1, &nread);
if (nscan == 1) {
fmt[0] = '%';
fmt[nread + 1] = 's';
} else {
nread = 0;
strcpy(fmt, "%s");
}
q = p + 1 + nread;
nscan = sscanf(q, "E(%[^)])%n", env_key, &nread);
if (nscan == 0) {
continue;
}
q += nread;
if (*(q - 1) != ')') {
zc_error("in string[%s] can't find match )", p);
return -1;
}
env_value_len = snprintf(env_value, sizeof(env_value), fmt, getenv(env_key));
if (env_value_len < 0 || env_value_len >= sizeof(env_value)) {
zc_error("snprintf fail, errno[%d], evn_value_len[%d]",
errno, env_value_len);
return -1;
}
str_len = str_len - (q - p) + env_value_len;
if (str_len > str_size - 1) {
zc_error("repalce env_value[%s] cause overlap", env_value);
return -1;
}
memmove(p + env_value_len, q, strlen(q) + 1);
memcpy(p, env_value, env_value_len);
} while (1);
return 0;
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_util_h
#define __zc_util_h
size_t zc_parse_byte_size(char *astring);
int zc_str_replace_env(char *str, size_t str_size);
#define zc_max(a,b) ((a) > (b) ? (a) : (b))
#define zc_min(a,b) ((a) < (b) ? (a) : (b))
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zc_xplatform_h
#define __zc_xplatform_h
#include <limits.h>
#define ZLOG_INT32_LEN sizeof("-2147483648") - 1
#define ZLOG_INT64_LEN sizeof("-9223372036854775808") - 1
#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8))
#define ZLOG_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL
#else
#define ZLOG_MAX_UINT32_VALUE (uint32_t) 0xffffffff
#endif
#define ZLOG_MAX_INT32_VALUE (uint32_t) 0x7fffffff
#define MAXLEN_PATH 1024
#define MAXLEN_CFG_LINE (MAXLEN_PATH * 4)
#define MAXLINES_NO 128
#define FILE_NEWLINE "\n"
#define FILE_NEWLINE_LEN 1
#include <string.h>
#include <strings.h>
#define STRCMP(_a_,_C_,_b_) ( strcmp(_a_,_b_) _C_ 0 )
#define STRNCMP(_a_,_C_,_b_,_n_) ( strncmp(_a_,_b_,_n_) _C_ 0 )
#define STRICMP(_a_,_C_,_b_) ( strcasecmp(_a_,_b_) _C_ 0 )
#define STRNICMP(_a_,_C_,_b_,_n_) ( strncasecmp(_a_,_b_,_n_) _C_ 0 )
#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
/* Define zlog_fstat to fstat or fstat64() */
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
#define zlog_fstat fstat64
#define zlog_stat stat64
#else
#define zlog_fstat fstat
#define zlog_stat stat
#endif
/* Define zlog_fsync to fdatasync() in Linux and fsync() for all the rest */
#ifdef __linux__
#define zlog_fsync fdatasync
#else
#define zlog_fsync fsync
#endif
#endif
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include "zlog.h"
#include "version.h"
int main(int argc, char *argv[])
{
int rc = 0;
int op;
int quiet = 0;
static const char *help =
"usage: zlog-chk-conf [conf files]...\n"
"\t-q,\tsuppress non-error message\n"
"\t-h,\tshow help message\n"
"zlog version: " ZLOG_VERSION "\n";
while((op = getopt(argc, argv, "qhv")) > 0) {
if (op == 'h') {
fputs(help, stdout);
return 0;
} else if (op == 'q') {
quiet = 1;
}
}
argc -= optind;
argv += optind;
if (argc == 0) {
fputs(help, stdout);
return -1;
}
setenv("ZLOG_PROFILE_ERROR", "/dev/stderr", 1);
setenv("ZLOG_CHECK_FORMAT_RULE", "1", 1);
while (argc > 0) {
rc = zlog_init(*argv);
if (rc) {
printf("\n---[%s] syntax error, see error message above\n",
*argv);
exit(2);
} else {
zlog_fini();
if (!quiet) {
printf("--[%s] syntax right\n", *argv);
}
}
argc--;
argv++;
}
exit(0);
}
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#include "fmacros.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <pthread.h>
#include "conf.h"
#include "category_table.h"
#include "record_table.h"
#include "mdc.h"
#include "zc_defs.h"
#include "rule.h"
#include "version.h"
/*******************************************************************************/
extern char *zlog_git_sha1;
/*******************************************************************************/
static pthread_rwlock_t zlog_env_lock = PTHREAD_RWLOCK_INITIALIZER;
zlog_conf_t *zlog_env_conf;
static pthread_key_t zlog_thread_key;
static zc_hashtable_t *zlog_env_categories;
static zc_hashtable_t *zlog_env_records;
static zlog_category_t *zlog_default_category;
static size_t zlog_env_reload_conf_count;
static int zlog_env_is_init = 0;
static int zlog_env_init_version = 0;
/*******************************************************************************/
/* inner no need thread-safe */
static void zlog_fini_inner(void)
{
/* pthread_key_delete(zlog_thread_key); */
/* never use pthread_key_delete,
* it will cause other thread can't release zlog_thread_t
* after one thread call pthread_key_delete
* also key not init will cause a core dump
*/
if (zlog_env_categories) zlog_category_table_del(zlog_env_categories);
zlog_env_categories = NULL;
zlog_default_category = NULL;
if (zlog_env_records) zlog_record_table_del(zlog_env_records);
zlog_env_records = NULL;
if (zlog_env_conf) zlog_conf_del(zlog_env_conf);
zlog_env_conf = NULL;
return;
}
static void zlog_clean_rest_thread(void)
{
zlog_thread_t *a_thread;
a_thread = pthread_getspecific(zlog_thread_key);
if (!a_thread) return;
zlog_thread_del(a_thread);
return;
}
static int zlog_init_inner(const char *config)
{
int rc = 0;
/* the 1st time in the whole process do init */
if (zlog_env_init_version == 0) {
/* clean up is done by OS when a thread call pthread_exit */
rc = pthread_key_create(&zlog_thread_key, (void (*) (void *)) zlog_thread_del);
if (rc) {
zc_error("pthread_key_create fail, rc[%d]", rc);
goto err;
}
/* if some thread do not call pthread_exit, like main thread
* atexit will clean it
*/
rc = atexit(zlog_clean_rest_thread);
if (rc) {
zc_error("atexit fail, rc[%d]", rc);
goto err;
}
zlog_env_init_version++;
} /* else maybe after zlog_fini() and need not create pthread_key */
zlog_env_conf = zlog_conf_new(config);
if (!zlog_env_conf) {
zc_error("zlog_conf_new[%s] fail", config);
goto err;
}
zlog_env_categories = zlog_category_table_new();
if (!zlog_env_categories) {
zc_error("zlog_category_table_new fail");
goto err;
}
zlog_env_records = zlog_record_table_new();
if (!zlog_env_records) {
zc_error("zlog_record_table_new fail");
goto err;
}
return 0;
err:
zlog_fini_inner();
return -1;
}
/*******************************************************************************/
int zlog_init(const char *config)
{
int rc;
zc_debug("------zlog_init start------");
zc_debug("------compile time[%s %s], version[%s]------", __DATE__, __TIME__, ZLOG_VERSION);
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return -1;
}
if (zlog_env_is_init) {
zc_error("already init, use zlog_reload pls");
goto err;
}
if (zlog_init_inner(config)) {
zc_error("zlog_init_inner[%s] fail", config);
goto err;
}
zlog_env_is_init = 1;
zlog_env_init_version++;
zc_debug("------zlog_init success end------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
err:
zc_error("------zlog_init fail end------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return -1;
}
int dzlog_init(const char *config, const char *cname)
{
int rc = 0;
zc_debug("------dzlog_init start------");
zc_debug("------compile time[%s %s], version[%s]------",
__DATE__, __TIME__, ZLOG_VERSION);
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return -1;
}
if (zlog_env_is_init) {
zc_error("already init, use zlog_reload pls");
goto err;
}
if (zlog_init_inner(config)) {
zc_error("zlog_init_inner[%s] fail", config);
goto err;
}
zlog_default_category = zlog_category_table_fetch_category(
zlog_env_categories,
cname,
zlog_env_conf->rules);
if (!zlog_default_category) {
zc_error("zlog_category_table_fetch_category[%s] fail", cname);
goto err;
}
zlog_env_is_init = 1;
zlog_env_init_version++;
zc_debug("------dzlog_init success end------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
err:
zc_error("------dzlog_init fail end------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return -1;
}
/*******************************************************************************/
int zlog_reload(const char *config)
{
int rc = 0;
int i = 0;
zlog_conf_t *new_conf = NULL;
zlog_rule_t *a_rule;
int c_up = 0;
zc_debug("------zlog_reload start------");
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return -1;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto quit;
}
/* use last conf file */
if (config == NULL) config = zlog_env_conf->file;
/* reach reload period */
if (config == (char*)-1) {
/* test again, avoid other threads already reloaded */
if (zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period) {
config = zlog_env_conf->file;
} else {
/* do nothing, already done */
goto quit;
}
}
/* reset counter, whether automaticlly or mannually */
zlog_env_reload_conf_count = 0;
new_conf = zlog_conf_new(config);
if (!new_conf) {
zc_error("zlog_conf_new fail");
goto err;
}
zc_arraylist_foreach(new_conf->rules, i, a_rule) {
zlog_rule_set_record(a_rule, zlog_env_records);
}
if (zlog_category_table_update_rules(zlog_env_categories, new_conf->rules)) {
c_up = 0;
zc_error("zlog_category_table_update fail");
goto err;
} else {
c_up = 1;
}
zlog_env_init_version++;
if (c_up) zlog_category_table_commit_rules(zlog_env_categories);
zlog_conf_del(zlog_env_conf);
zlog_env_conf = new_conf;
zc_debug("------zlog_reload success, total init verison[%d] ------", zlog_env_init_version);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
err:
/* fail, roll back everything */
zc_warn("zlog_reload fail, use old conf file, still working");
if (new_conf) zlog_conf_del(new_conf);
if (c_up) zlog_category_table_rollback_rules(zlog_env_categories);
zc_error("------zlog_reload fail, total init version[%d] ------", zlog_env_init_version);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return -1;
quit:
zc_debug("------zlog_reload do nothing------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
}
/*******************************************************************************/
void zlog_fini(void)
{
int rc = 0;
zc_debug("------zlog_fini start------");
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return;
}
if (!zlog_env_is_init) {
zc_error("before finish, must zlog_init() or dzlog_init() first");
goto exit;
}
zlog_fini_inner();
zlog_env_is_init = 0;
exit:
zc_debug("------zlog_fini end------");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return;
}
return;
}
/*******************************************************************************/
zlog_category_t *zlog_get_category(const char *cname)
{
int rc = 0;
zlog_category_t *a_category = NULL;
zc_assert(cname, NULL);
zc_debug("------zlog_get_category[%s] start------", cname);
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return NULL;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
a_category = NULL;
goto err;
}
a_category = zlog_category_table_fetch_category(
zlog_env_categories,
cname,
zlog_env_conf->rules);
if (!a_category) {
zc_error("zlog_category_table_fetch_category[%s] fail", cname);
goto err;
}
zc_debug("------zlog_get_category[%s] success, end------ ", cname);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return NULL;
}
return a_category;
err:
zc_error("------zlog_get_category[%s] fail, end------ ", cname);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return NULL;
}
return NULL;
}
int dzlog_set_category(const char *cname)
{
int rc = 0;
zc_assert(cname, -1);
zc_debug("------dzlog_set_category[%s] start------", cname);
rc = pthread_rwlock_wrlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return -1;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto err;
}
zlog_default_category = zlog_category_table_fetch_category(
zlog_env_categories,
cname,
zlog_env_conf->rules);
if (!zlog_default_category) {
zc_error("zlog_category_table_fetch_category[%s] fail", cname);
goto err;
}
zc_debug("------dzlog_set_category[%s] end, success------ ", cname);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
err:
zc_error("------dzlog_set_category[%s] end, fail------ ", cname);
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return -1;
}
/*******************************************************************************/
#define zlog_fetch_thread(a_thread, fail_goto) do { \
int rd = 0; \
a_thread = pthread_getspecific(zlog_thread_key); \
if (!a_thread) { \
a_thread = zlog_thread_new(zlog_env_init_version, \
zlog_env_conf->buf_size_min, zlog_env_conf->buf_size_max, \
zlog_env_conf->time_cache_count); \
if (!a_thread) { \
zc_error("zlog_thread_new fail"); \
goto fail_goto; \
} \
\
rd = pthread_setspecific(zlog_thread_key, a_thread); \
if (rd) { \
zlog_thread_del(a_thread); \
zc_error("pthread_setspecific fail, rd[%d]", rd); \
goto fail_goto; \
} \
} \
\
if (a_thread->init_version != zlog_env_init_version) { \
/* as mdc is still here, so can not easily del and new */ \
rd = zlog_thread_rebuild_msg_buf(a_thread, \
zlog_env_conf->buf_size_min, \
zlog_env_conf->buf_size_max); \
if (rd) { \
zc_error("zlog_thread_resize_msg_buf fail, rd[%d]", rd); \
goto fail_goto; \
} \
\
rd = zlog_thread_rebuild_event(a_thread, zlog_env_conf->time_cache_count); \
if (rd) { \
zc_error("zlog_thread_resize_msg_buf fail, rd[%d]", rd); \
goto fail_goto; \
} \
a_thread->init_version = zlog_env_init_version; \
} \
} while (0)
/*******************************************************************************/
int zlog_put_mdc(const char *key, const char *value)
{
int rc = 0;
zlog_thread_t *a_thread;
zc_assert(key, -1);
zc_assert(value, -1);
rc = pthread_rwlock_rdlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return -1;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto err;
}
zlog_fetch_thread(a_thread, err);
if (zlog_mdc_put(a_thread->mdc, key, value)) {
zc_error("zlog_mdc_put fail, key[%s], value[%s]", key, value);
goto err;
}
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return 0;
err:
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return -1;
}
return -1;
}
char *zlog_get_mdc(char *key)
{
int rc = 0;
char *value = NULL;
zlog_thread_t *a_thread;
zc_assert(key, NULL);
rc = pthread_rwlock_rdlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
return NULL;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto err;
}
a_thread = pthread_getspecific(zlog_thread_key);
if (!a_thread) {
zc_error("thread not found, maybe not use zlog_put_mdc before");
goto err;
}
value = zlog_mdc_get(a_thread->mdc, key);
if (!value) {
zc_error("key[%s] not found in mdc", key);
goto err;
}
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return NULL;
}
return value;
err:
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return NULL;
}
return NULL;
}
void zlog_remove_mdc(char *key)
{
int rc = 0;
zlog_thread_t *a_thread;
zc_assert(key, );
rc = pthread_rwlock_rdlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
return;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
a_thread = pthread_getspecific(zlog_thread_key);
if (!a_thread) {
zc_error("thread not found, maybe not use zlog_put_mdc before");
goto exit;
}
zlog_mdc_remove(a_thread->mdc, key);
exit:
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return;
}
return;
}
void zlog_clean_mdc(void)
{
int rc = 0;
zlog_thread_t *a_thread;
rc = pthread_rwlock_rdlock(&zlog_env_lock);
if (rc) {;
zc_error("pthread_rwlock_rdlock fail, rc[%d]", rc);
return;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
a_thread = pthread_getspecific(zlog_thread_key);
if (!a_thread) {
zc_error("thread not found, maybe not use zlog_put_mdc before");
goto exit;
}
zlog_mdc_clean(a_thread->mdc);
exit:
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return;
}
return;
}
int zlog_level_switch(zlog_category_t * category, int level)
{
// This is NOT thread safe.
memset(category->level_bitmap, 0x00, sizeof(category->level_bitmap));
category->level_bitmap[level / 8] |= ~(0xFF << (8 - level % 8));
memset(category->level_bitmap + level / 8 + 1, 0xFF,
sizeof(category->level_bitmap) - level / 8 - 1);
return 0;
}
/*******************************************************************************/
void vzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args)
{
zlog_thread_t *a_thread;
/* The bitmap determination here is not under the protection of rdlock.
* It may be changed by other CPU by zlog_reload() halfway.
*
* Old or strange value may be read here,
* but it is safe, the bitmap is valid as long as category exist,
* And will be the right value after zlog_reload()
*
* For speed up, if one log will not be ouput,
* There is no need to aquire rdlock.
*/
if (zlog_category_needless_level(category, level)) return;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
zlog_fetch_thread(a_thread, exit);
zlog_event_set_fmt(a_thread->event,
category->name, category->name_len,
file, filelen, func, funclen, line, level,
format, args);
if (zlog_category_output(category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
goto exit;
}
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
void hzlog(zlog_category_t *category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen)
{
zlog_thread_t *a_thread;
if (zlog_category_needless_level(category, level)) return;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
zlog_fetch_thread(a_thread, exit);
zlog_event_set_hex(a_thread->event,
category->name, category->name_len,
file, filelen, func, funclen, line, level,
buf, buflen);
if (zlog_category_output(category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
goto exit;
}
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
/*******************************************************************************/
/* for speed up, copy from vzlog */
void vdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args)
{
zlog_thread_t *a_thread;
if (zlog_category_needless_level(zlog_default_category, level)) return;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
/* that's the differnce, must judge default_category in lock */
if (!zlog_default_category) {
zc_error("zlog_default_category is null,"
"dzlog_init() or dzlog_set_cateogry() is not called above");
goto exit;
}
zlog_fetch_thread(a_thread, exit);
zlog_event_set_fmt(a_thread->event,
zlog_default_category->name, zlog_default_category->name_len,
file, filelen, func, funclen, line, level,
format, args);
if (zlog_category_output(zlog_default_category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
goto exit;
}
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
void hdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen)
{
zlog_thread_t *a_thread;
if (zlog_category_needless_level(zlog_default_category, level)) return;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
/* that's the differnce, must judge default_category in lock */
if (!zlog_default_category) {
zc_error("zlog_default_category is null,"
"dzlog_init() or dzlog_set_cateogry() is not called above");
goto exit;
}
zlog_fetch_thread(a_thread, exit);
zlog_event_set_hex(a_thread->event,
zlog_default_category->name, zlog_default_category->name_len,
file, filelen, func, funclen, line, level,
buf, buflen);
if (zlog_category_output(zlog_default_category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
goto exit;
}
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
/*******************************************************************************/
void zlog(zlog_category_t * category,
const char *file, size_t filelen, const char *func, size_t funclen,
long line, const int level,
const char *format, ...)
{
zlog_thread_t *a_thread;
va_list args;
if (category && zlog_category_needless_level(category, level)) return;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
zlog_fetch_thread(a_thread, exit);
va_start(args, format);
zlog_event_set_fmt(a_thread->event, category->name, category->name_len,
file, filelen, func, funclen, line, level,
format, args);
if (zlog_category_output(category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
va_end(args);
goto exit;
}
va_end(args);
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
/*******************************************************************************/
void dzlog(const char *file, size_t filelen, const char *func, size_t funclen, long line, int level,
const char *format, ...)
{
zlog_thread_t *a_thread;
va_list args;
pthread_rwlock_rdlock(&zlog_env_lock);
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto exit;
}
/* that's the differnce, must judge default_category in lock */
if (!zlog_default_category) {
zc_error("zlog_default_category is null,"
"dzlog_init() or dzlog_set_cateogry() is not called above");
goto exit;
}
if (zlog_category_needless_level(zlog_default_category, level)) goto exit;
zlog_fetch_thread(a_thread, exit);
va_start(args, format);
zlog_event_set_fmt(a_thread->event,
zlog_default_category->name, zlog_default_category->name_len,
file, filelen, func, funclen, line, level,
format, args);
if (zlog_category_output(zlog_default_category, a_thread)) {
zc_error("zlog_output fail, srcfile[%s], srcline[%ld]", file, line);
va_end(args);
goto exit;
}
va_end(args);
if (zlog_env_conf->reload_conf_period &&
++zlog_env_reload_conf_count > zlog_env_conf->reload_conf_period ) {
/* under the protection of lock read env conf */
goto reload;
}
exit:
pthread_rwlock_unlock(&zlog_env_lock);
return;
reload:
pthread_rwlock_unlock(&zlog_env_lock);
/* will be wrlock, so after unlock */
if (zlog_reload((char *)-1)) {
zc_error("reach reload-conf-period but zlog_reload fail, zlog-chk-conf [file] see detail");
}
return;
}
/*******************************************************************************/
void zlog_profile(void)
{
int rc = 0;
rc = pthread_rwlock_rdlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_wrlock fail, rc[%d]", rc);
return;
}
zc_warn("------zlog_profile start------ ");
zc_warn("is init:[%d]", zlog_env_is_init);
zc_warn("init version:[%d]", zlog_env_init_version);
zlog_conf_profile(zlog_env_conf, ZC_WARN);
zlog_record_table_profile(zlog_env_records, ZC_WARN);
zlog_category_table_profile(zlog_env_categories, ZC_WARN);
if (zlog_default_category) {
zc_warn("-default_category-");
zlog_category_profile(zlog_default_category, ZC_WARN);
}
zc_warn("------zlog_profile end------ ");
rc = pthread_rwlock_unlock(&zlog_env_lock);
if (rc) {
zc_error("pthread_rwlock_unlock fail, rc=[%d]", rc);
return;
}
return;
}
/*******************************************************************************/
int zlog_set_record(const char *rname, zlog_record_fn record_output)
{
int rc = 0;
int rd = 0;
zlog_rule_t *a_rule;
zlog_record_t *a_record;
int i = 0;
zc_assert(rname, -1);
zc_assert(record_output, -1);
rd = pthread_rwlock_wrlock(&zlog_env_lock);
if (rd) {
zc_error("pthread_rwlock_rdlock fail, rd[%d]", rd);
return -1;
}
if (!zlog_env_is_init) {
zc_error("never call zlog_init() or dzlog_init() before");
goto zlog_set_record_exit;
}
a_record = zlog_record_new(rname, record_output);
if (!a_record) {
rc = -1;
zc_error("zlog_record_new fail");
goto zlog_set_record_exit;
}
rc = zc_hashtable_put(zlog_env_records, a_record->name, a_record);
if (rc) {
zlog_record_del(a_record);
zc_error("zc_hashtable_put fail");
goto zlog_set_record_exit;
}
zc_arraylist_foreach(zlog_env_conf->rules, i, a_rule) {
zlog_rule_set_record(a_rule, zlog_env_records);
}
zlog_set_record_exit:
rd = pthread_rwlock_unlock(&zlog_env_lock);
if (rd) {
zc_error("pthread_rwlock_unlock fail, rd=[%d]", rd);
return -1;
}
return rc;
}
/*******************************************************************************/
int zlog_level_enabled(zlog_category_t *category, const int level)
{
return category && (zlog_category_needless_level(category, level) == 0);
}
const char *zlog_version(void) { return ZLOG_VERSION; }
/*
* This file is part of the zlog Library.
*
* Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
*
* Licensed under the LGPL v2.1, see the file COPYING in base directory.
*/
#ifndef __zlog_h
#define __zlog_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h> /* for va_list */
#include <stdio.h> /* for size_t */
# if defined __GNUC__
# define ZLOG_CHECK_PRINTF(m,n) __attribute__((format(printf,m,n)))
# else
# define ZLOG_CHECK_PRINTF(m,n)
# endif
typedef struct zlog_category_s zlog_category_t;
int zlog_init(const char *config);
int zlog_reload(const char *config);
void zlog_fini(void);
void zlog_profile(void);
zlog_category_t *zlog_get_category(const char *cname);
int zlog_level_enabled(zlog_category_t *category, const int level);
int zlog_put_mdc(const char *key, const char *value);
char *zlog_get_mdc(const char *key);
void zlog_remove_mdc(const char *key);
void zlog_clean_mdc(void);
int zlog_level_switch(zlog_category_t * category, int level);
int zlog_level_enabled(zlog_category_t * category, int level);
void zlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, ...) ZLOG_CHECK_PRINTF(8,9);
void vzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args);
void hzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen);
int dzlog_init(const char *confpath, const char *cname);
int dzlog_set_category(const char *cname);
void dzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, ...) ZLOG_CHECK_PRINTF(7,8);
void vdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args);
void hdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen);
typedef struct zlog_msg_s {
char *buf;
size_t len;
char *path;
} zlog_msg_t;
typedef int (*zlog_record_fn)(zlog_msg_t *msg);
int zlog_set_record(const char *rname, zlog_record_fn record);
const char *zlog_version(void);
/******* useful macros, can be redefined at user's h file **********/
typedef enum {
ZLOG_LEVEL_DEBUG = 20,
ZLOG_LEVEL_INFO = 40,
ZLOG_LEVEL_NOTICE = 60,
ZLOG_LEVEL_WARN = 80,
ZLOG_LEVEL_ERROR = 100,
ZLOG_LEVEL_FATAL = 120
} zlog_level;
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
# if defined __GNUC__ && __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
/* zlog macros */
#define zlog_fatal(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, __VA_ARGS__)
#define zlog_error(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, __VA_ARGS__)
#define zlog_warn(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, __VA_ARGS__)
#define zlog_notice(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, __VA_ARGS__)
#define zlog_info(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, __VA_ARGS__)
#define zlog_debug(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, __VA_ARGS__)
/* dzlog macros */
#define dzlog_fatal(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, __VA_ARGS__)
#define dzlog_error(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, __VA_ARGS__)
#define dzlog_warn(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, __VA_ARGS__)
#define dzlog_notice(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, __VA_ARGS__)
#define dzlog_info(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, __VA_ARGS__)
#define dzlog_debug(...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, __VA_ARGS__)
#elif defined __GNUC__
/* zlog macros */
#define zlog_fatal(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, format, ##args)
#define zlog_error(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, format, ##args)
#define zlog_warn(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, format, ##args)
#define zlog_notice(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, format, ##args)
#define zlog_info(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, format, ##args)
#define zlog_debug(cat, format, args...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, format, ##args)
/* dzlog macros */
#define dzlog_fatal(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, format, ##args)
#define dzlog_error(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, format, ##args)
#define dzlog_warn(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, format, ##args)
#define dzlog_notice(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, format, ##args)
#define dzlog_info(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, format, ##args)
#define dzlog_debug(format, args...) \
dzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, format, ##args)
#endif
/* vzlog macros */
#define vzlog_fatal(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, format, args)
#define vzlog_error(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, format, args)
#define vzlog_warn(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, format, args)
#define vzlog_notice(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, format, args)
#define vzlog_info(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, format, args)
#define vzlog_debug(cat, format, args) \
vzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, format, args)
/* hzlog macros */
#define hzlog_fatal(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, buf, buf_len)
#define hzlog_error(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, buf, buf_len)
#define hzlog_warn(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, buf, buf_len)
#define hzlog_notice(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, buf, buf_len)
#define hzlog_info(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, buf, buf_len)
#define hzlog_debug(cat, buf, buf_len) \
hzlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, buf, buf_len)
/* vdzlog macros */
#define vdzlog_fatal(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, format, args)
#define vdzlog_error(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, format, args)
#define vdzlog_warn(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, format, args)
#define vdzlog_notice(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, format, args)
#define vdzlog_info(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, format, args)
#define vdzlog_debug(format, args) \
vdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, format, args)
/* hdzlog macros */
#define hdzlog_fatal(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, buf, buf_len)
#define hdzlog_error(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_ERROR, buf, buf_len)
#define hdzlog_warn(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_WARN, buf, buf_len)
#define hdzlog_notice(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_NOTICE, buf, buf_len)
#define hdzlog_info(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_INFO, buf, buf_len)
#define hdzlog_debug(buf, buf_len) \
hdzlog(__FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_DEBUG, buf, buf_len)
/* enabled macros */
#define zlog_fatal_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_FATAL)
#define zlog_error_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_ERROR)
#define zlog_warn_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_WARN)
#define zlog_notice_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_NOTICE)
#define zlog_info_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_INFO)
#define zlog_debug_enabled(zc) zlog_level_enabled(zc, ZLOG_LEVEL_DEBUG)
#ifdef __cplusplus
}
#endif
#endif
...@@ -19,7 +19,7 @@ SUBDIRS += common/nanomsg ...@@ -19,7 +19,7 @@ SUBDIRS += common/nanomsg
SUBDIRS += common/ev SUBDIRS += common/ev
SUBDIRS += common/sqlite SUBDIRS += common/sqlite
SUBDIRS += common/hal SUBDIRS += common/hal
SUBDIRS += common/zlog #SUBDIRS += common/zlog
#SUBDIRS += platform/zigbee #SUBDIRS += platform/zigbee
$(call Append_Conditional, SUBDIRS) $(call Append_Conditional, SUBDIRS)
......
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "kk_dm_mng.h" #include "kk_dm_mng.h"
#include "kk_dm_msg.h" #include "kk_dm_msg.h"
#include "kk_tsl_api.h" #include "kk_tsl_api.h"
#include "kk_tsl_load.h" #include "kk_tsl_load.h"
#include "iot_export_linkkit.h" #include "iot_export_linkkit.h"
#include "kk_product.h" #include "kk_product.h"
#include "kk_log.h" #include "kk_log.h"
#include "kk_property_db.h" #include "kk_property_db.h"
//const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/"; //const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/";
const char DM_URI_EXT_SESSION_PREFIX[] DM_READ_ONLY = "/ext/session/%s/%s/"; const char DM_URI_EXT_SESSION_PREFIX[] DM_READ_ONLY = "/ext/session/%s/%s/";
const char DM_URI_EXT_NTP_PREFIX[] DM_READ_ONLY = "/ext/ntp/%s/%s/"; const char DM_URI_EXT_NTP_PREFIX[] DM_READ_ONLY = "/ext/ntp/%s/%s/";
const char DM_URI_EXT_ERROR_PREFIX[] DM_READ_ONLY = "/ext/error/%s/%s"; const char DM_URI_EXT_ERROR_PREFIX[] DM_READ_ONLY = "/ext/error/%s/%s";
const char DM_URI_REPLY_SUFFIX[] DM_READ_ONLY = "_reply"; const char DM_URI_REPLY_SUFFIX[] DM_READ_ONLY = "_reply";
const char DM_URI_OTA_DEVICE_INFORM[] DM_READ_ONLY = "/ota/device/inform/%s/%s"; const char DM_URI_OTA_DEVICE_INFORM[] DM_READ_ONLY = "/ota/device/inform/%s/%s";
const char DM_URI_THING_EVENT_PROPERTY_POST_METHOD[] DM_READ_ONLY = "thing.event.property.post"; const char DM_URI_THING_EVENT_PROPERTY_POST_METHOD[] DM_READ_ONLY = "thing.event.property.post";
static dm_mgr_ctx g_dm_mgr = {0}; static dm_mgr_ctx g_dm_mgr = {0};
static dm_mgr_ctx *_dm_mgr_get_ctx(void) static dm_mgr_ctx *_dm_mgr_get_ctx(void)
{ {
return &g_dm_mgr; return &g_dm_mgr;
} }
static void _dm_mgr_mutex_lock(void) static void _dm_mgr_mutex_lock(void)
{ {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
if (ctx->mutex) { if (ctx->mutex) {
kk_MutexLock(ctx->mutex); kk_MutexLock(ctx->mutex);
} }
} }
static void _dm_mgr_mutex_unlock(void) static void _dm_mgr_mutex_unlock(void)
{ {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
if (ctx->mutex) { if (ctx->mutex) {
kk_MutexUnLock(ctx->mutex); kk_MutexUnLock(ctx->mutex);
} }
} }
int dm_mgr_search_dev_by_devid(_IN_ int devid, _OU_ dm_mgr_dev_node_t **node) int dm_mgr_search_dev_by_devid(_IN_ int devid, _OU_ dm_mgr_dev_node_t **node)
{ {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL; dm_mgr_dev_node_t *search_node = NULL;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if (search_node->devid == devid) { if (search_node->devid == devid) {
/* dm_log_debug("Device Found, devid: %d", devid); */ /* dm_log_debug("Device Found, devid: %d", devid); */
if (node) { if (node) {
*node = search_node; *node = search_node;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
ERROR_PRINT("Device Not Found, devid: %d", devid); ERROR_PRINT("Device Not Found, devid: %d", devid);
return FAIL_RETURN; return FAIL_RETURN;
} }
static int _dm_mgr_search_dev_by_pkdn(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node) static int _dm_mgr_search_dev_by_pkdn(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node)
{ {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL; dm_mgr_dev_node_t *search_node = NULL;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) && if ( (strlen(search_node->deviceCode) == strlen(deviceCode)) &&
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) { (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */ /* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
if (node) { if (node) {
*node = search_node; *node = search_node;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
ERROR_PRINT("Device Not Found, Device Code: %s", deviceCode); ERROR_PRINT("Device Not Found, Device Code: %s", deviceCode);
return FAIL_RETURN; return FAIL_RETURN;
} }
static int _dm_mgr_next_devid(void) static int _dm_mgr_next_devid(void)
{ {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
return ctx->global_devid++; return ctx->global_devid++;
} }
static int _dm_init_tsl_params(int devId) static int _dm_init_tsl_params(kk_tsl_t * dev_shadow)
{ {
int res = 0; int res = 0;
char version[VERSION_MAXLEN] = {0}; char version[VERSION_MAXLEN] = {0};
char s_IP[NETWORK_ADDR_LEN] = {0}; char s_IP[NETWORK_ADDR_LEN] = {0};
char s_mac[MAC_ADDR_LEN] = {0}; char s_mac[MAC_ADDR_LEN] = {0};
char s_SN[SN_ADDR_LEN] = {0}; char s_SN[SN_ADDR_LEN] = {0};
int port = 0; int port = 0;
/*******set version***********/ /*******set version***********/
HAL_GetVersion(version); HAL_GetVersion(version);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_VERSION_IDENTIFIER,NULL,version); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_VERSION_IDENTIFIER,NULL,version);
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
/*******set IP*************/ /*******set IP*************/
//HAL_Get_IP(s_IP,NULL); //HAL_Get_IP(s_IP,NULL);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_CCU_LANIP_IDENTIFIER,NULL,"0.0.0.0"); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_CCU_LANIP_IDENTIFIER,NULL,"0.0.0.0");
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_CCU_WANIP_IDENTIFIER,NULL,"0.0.0.0"); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_CCU_WANIP_IDENTIFIER,NULL,"0.0.0.0");
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
/*******set MAC*************/ /*******set MAC*************/
HAL_Get_mac(s_mac); HAL_Get_mac(s_mac);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_GATAWAY_MAC_IDENTIFIER,NULL,s_mac); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_GATAWAY_MAC_IDENTIFIER,NULL,s_mac);
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
int wanState = 0; int wanState = 0;
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_CCU_WANSTATE_IDENTIFIER,&wanState,NULL); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_CCU_WANSTATE_IDENTIFIER,&wanState,NULL);
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
int IOTCloudState = 0; int IOTCloudState = 0;
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_CCU_IOTCLOUD_IDENTIFIER,&IOTCloudState,NULL); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_CCU_IOTCLOUD_IDENTIFIER,&IOTCloudState,NULL);
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
/*******set sn*************/ /*******set sn*************/
HAL_Get_SN(s_SN); HAL_Get_SN(s_SN);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,KK_TSL_GATAWAY_SN_IDENTIFIER,NULL,s_SN); res = kk_tsl_set_value(kk_tsl_set_property_value,dev_shadow,KK_TSL_GATAWAY_SN_IDENTIFIER,NULL,s_SN);
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} }
return res; return res;
} }
int dm_mgr_properities_db_create(kk_tsl_t* dev_shadow,char *deviceCode,int devType ) /*目前支持到三级结构体的属性解析保存到数据库*/
{ int dm_mgr_properities_db_create(kk_tsl_t* dev_shadow,char *deviceCode,int devType )
int num = 0,idx = 0; {
kk_tsl_data_t *pProperty = NULL; int num = 0,idx = 0,index = 0,index1 = 0;
if(dev_shadow == NULL || deviceCode == NULL){ kk_tsl_data_t *pProperty = NULL;
ERROR_PRINT("dm_mgr_properities_db_create fail!!\n"); kk_tsl_data_t *current_data = NULL;
return INVALID_PARAMETER; char tmp_identifiers[256] = {0};
} if(dev_shadow == NULL || deviceCode == NULL){
num = dev_shadow->property_number; ERROR_PRINT("dm_mgr_properities_db_create fail!!\n");
INFO_PRINT("dm_mgr_properities_db_create num:%d!!\n",num); return INVALID_PARAMETER;
for(idx = 0; idx < num; idx++){ }
num = dev_shadow->property_number;
pProperty = dev_shadow->properties+idx; INFO_PRINT("dm_mgr_properities_db_create num:%d!!\n",num);
INFO_PRINT("dm_mgr_properities_db_create pProperty->identifier:%s!!\n",pProperty->identifier); for(idx = 0; idx < num; idx++){
if(pProperty){
kk_property_db_insert(deviceCode,pProperty->identifier,pProperty->data_value.type,devType); pProperty = dev_shadow->properties+idx;
} INFO_PRINT("dm_mgr_properities_db_create pProperty->identifier:%s!!\n",pProperty->identifier);
} if(pProperty){
} if(pProperty->data_value.type == KK_TSL_DATA_TYPE_STRUCT){
int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN], kk_tsl_data_value_complex_t *complex_struct = NULL;
_IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN], _OU_ int *devid) complex_struct = pProperty->data_value.value;
{ for (index = 0; index < complex_struct->size; index++) {
int res = 0; current_data = (kk_tsl_data_t *)complex_struct->value + index;
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); if(current_data->data_value.type != KK_TSL_DATA_TYPE_STRUCT ){
dm_mgr_dev_node_t *node = NULL; memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
char *tsl_str = NULL; sprintf(tmp_identifiers,"%s.%s",pProperty->identifier,current_data->identifier);
int idx = 0; INFO_PRINT("dm_mgr_properities_db_create tmp_identifiers:%s!!\n",tmp_identifiers);
kk_property_db_insert(deviceCode,tmp_identifiers,current_data->data_value.type,devType);
}
if (deviceCode != NULL && strlen(deviceCode) >= DEVICE_CODE_MAXLEN) { else{
return INVALID_PARAMETER; kk_tsl_data_value_complex_t *complex_struct_1 = NULL;
} complex_struct_1 = current_data->data_value.value;
for(index1 = 0; index1 < complex_struct_1->size; index1++){
res = _dm_mgr_search_dev_by_pkdn(deviceCode, &node); kk_tsl_data_t *current_data_1 = NULL;
if (res == SUCCESS_RETURN) { current_data_1 = (kk_tsl_data_t *)complex_struct_1->value + index1;
if (devid) { if(current_data_1->data_value.type != KK_TSL_DATA_TYPE_STRUCT ){
*devid = node->devid; memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
} sprintf(tmp_identifiers,"%s.%s.%s",pProperty->identifier,current_data->identifier,current_data_1->identifier);
return TSL_ALREADY_EXIST; INFO_PRINT("dm_mgr_properities_db_create tmp_identifiers:%s!!\n",tmp_identifiers);
} kk_property_db_insert(deviceCode,tmp_identifiers,current_data_1->data_value.type,devType);
node = malloc(sizeof(dm_mgr_dev_node_t)); }
if (node == NULL) { }
return MEMORY_NOT_ENOUGH;
} }
memset(node, 0, sizeof(dm_mgr_dev_node_t)); }
}else
if(dev_type == KK_DM_DEVICE_CCU) {
node->devid = KK_DM_DEVICE_CCU_DEVICEID; kk_property_db_insert(deviceCode,pProperty->identifier,pProperty->data_value.type,devType);
else }
node->devid = _dm_mgr_next_devid(); }
node->dev_type = dev_type; }
node->dev_shadow = NULL; }
if (productCode != NULL) { int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN],
memcpy(node->productCode, productCode, strlen(productCode)); _IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN], _OU_ int *devid)
} {
if (deviceCode != NULL) { int res = 0;
memcpy(node->deviceCode, deviceCode, strlen(deviceCode)); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
} dm_mgr_dev_node_t *node = NULL;
if (mac != NULL) { char *tsl_str = NULL;
memcpy(node->mac, mac, strlen(mac)); int idx = 0;
}
if (dev_type != KK_DM_DEVICE_CCU && fatherDeviceCode != NULL) {
memcpy(node->fatherDeviceCode, fatherDeviceCode, strlen(fatherDeviceCode)); if (deviceCode != NULL && strlen(deviceCode) >= DEVICE_CODE_MAXLEN) {
} return INVALID_PARAMETER;
node->timestamp = HAL_UptimeMs(); }
//node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED;
tsl_str = kk_load_json(productCode, dev_type); res = _dm_mgr_search_dev_by_pkdn(deviceCode, &node);
if(tsl_str != NULL) if (res == SUCCESS_RETURN) {
{ if (devid) {
res = kk_tsl_create(tsl_str,strlen(tsl_str),&node->dev_shadow); *devid = node->devid;
free(tsl_str); }
if(res != 0){ return TSL_ALREADY_EXIST;
return FAIL_RETURN; }
}
} node = malloc(sizeof(dm_mgr_dev_node_t));
dm_mgr_properities_db_create(node->dev_shadow,deviceCode,dev_type); if (node == NULL) {
INIT_LIST_HEAD(&node->linked_list); return MEMORY_NOT_ENOUGH;
list_add_tail(&node->linked_list, &ctx->dev_list); }
memset(node, 0, sizeof(dm_mgr_dev_node_t));
if(dev_type == KK_DM_DEVICE_CCU){
//_dm_init_tsl_params(node->devid); if(dev_type == KK_DM_DEVICE_CCU)
} node->devid = KK_DM_DEVICE_CCU_DEVICEID;
else
if (devid) { node->devid = _dm_mgr_next_devid();
*devid = node->devid; node->dev_type = dev_type;
} node->dev_shadow = NULL;
if (productCode != NULL) {
return SUCCESS_RETURN; memcpy(node->productCode, productCode, strlen(productCode));
} }
int dm_mgr_search_device_by_pkdn( _IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid) if (deviceCode != NULL) {
{ memcpy(node->deviceCode, deviceCode, strlen(deviceCode));
int res = 0; }
dm_mgr_dev_node_t *node = NULL; if (mac != NULL) {
memcpy(node->mac, mac, strlen(mac));
if (deviceCode == NULL) { }
return INVALID_PARAMETER; if (dev_type != KK_DM_DEVICE_CCU && fatherDeviceCode != NULL) {
} memcpy(node->fatherDeviceCode, fatherDeviceCode, strlen(fatherDeviceCode));
}
res = _dm_mgr_search_dev_by_pkdn(deviceCode, &node); node->timestamp = HAL_UptimeMs();
if (res != SUCCESS_RETURN) { //node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED;
return FAIL_RETURN; tsl_str = kk_load_json(productCode, dev_type);
} if(tsl_str != NULL)
{
if (devid) { res = kk_tsl_create(tsl_str,strlen(tsl_str),&node->dev_shadow);
*devid = node->devid; free(tsl_str);
} if(res != 0){
return FAIL_RETURN;
return SUCCESS_RETURN; }
} }
else{
return FAIL_RETURN;
}
int dm_mgr_get_devicetype_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ int* deviceType) dm_mgr_properities_db_create(node->dev_shadow,deviceCode,dev_type);
{ INIT_LIST_HEAD(&node->linked_list);
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); list_add_tail(&node->linked_list, &ctx->dev_list);
dm_mgr_dev_node_t *node = NULL;
if(dev_type == KK_DM_DEVICE_CCU){
list_for_each_entry(node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { _dm_init_tsl_params(node->dev_shadow);
if ((strlen(node->deviceCode) == strlen(deviceCode)) && }
(memcmp(node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */ if (devid) {
if (node) { *devid = node->devid;
*deviceType = node->dev_type; }
}
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} int dm_mgr_search_device_by_pkdn( _IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid)
{
ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode); int res = 0;
return FAIL_RETURN; dm_mgr_dev_node_t *node = NULL;
}
if (deviceCode == NULL) {
return INVALID_PARAMETER;
int dm_mgr_get_device_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node) }
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); res = _dm_mgr_search_dev_by_pkdn(deviceCode, &node);
dm_mgr_dev_node_t *search_node = NULL; if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { }
if ((strlen(search_node->deviceCode) == strlen(deviceCode)) &&
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) { if (devid) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */ *devid = node->devid;
if (node) { }
*node = search_node;
} return SUCCESS_RETURN;
return SUCCESS_RETURN; }
}
}
ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode); int dm_mgr_get_devicetype_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ int* deviceType)
return FAIL_RETURN; {
} dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],uint64_t timestamp) dm_mgr_dev_node_t *node = NULL;
{
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); list_for_each_entry(node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
dm_mgr_dev_node_t *search_node = NULL; if ((strlen(node->deviceCode) == strlen(deviceCode)) &&
(memcmp(node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
_dm_mgr_mutex_lock(); /* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { if (node) {
if ((strlen(search_node->deviceCode) == strlen(deviceCode)) && *deviceType = node->dev_type;
(memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) { }
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */ return SUCCESS_RETURN;
search_node->timestamp = timestamp; }
_dm_mgr_mutex_unlock(); }
return SUCCESS_RETURN;
} ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
} return FAIL_RETURN;
_dm_mgr_mutex_unlock(); }
ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode); int dm_mgr_get_device_shadow_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ kk_tsl_t **shadow)
return FAIL_RETURN; {
} dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
#define TEST_TIMEOUT 600000 // ten minutes dm_mgr_dev_node_t *search_node = NULL;
int dm_mgr_check_heartbeat_timeout(uint64_t timestamp)
{ list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); if ((strlen(search_node->deviceCode) == strlen(deviceCode)) &&
dm_mgr_dev_node_t *search_node = NULL; (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
/* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
_dm_mgr_mutex_lock(); if (shadow) {
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) { *shadow = search_node->dev_shadow;
if(search_node->dev_type == KK_DM_DEVICE_CCU){ }
continue; return SUCCESS_RETURN;
} }
if((timestamp - search_node->timestamp) >= TEST_TIMEOUT/*search_node->hb_timeout*/){ }
if(search_node->isOffline == 0){ ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
INFO_PRINT("---------->dev timeout,send offline\n"); return FAIL_RETURN;
search_node->isOffline = 1; }
iotx_dm_dev_offline(search_node->devid);
kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode);
} int dm_mgr_get_device_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node)
{
//_dm_mgr_mutex_unlock(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
//return DEVICE_HEARTBEAT_TIMEOUT; dm_mgr_dev_node_t *search_node = NULL;
}
else{ list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if(search_node->isOffline == 1){//need send online if ((strlen(search_node->deviceCode) == strlen(deviceCode)) &&
INFO_PRINT("---------->dev online again,send online\n"); (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
search_node->isOffline = 0; /* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
iotx_dm_dev_online(search_node->devid); if (node) {
kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode); *node = search_node;
} }
} return SUCCESS_RETURN;
} }
_dm_mgr_mutex_unlock(); }
return SUCCESS_RETURN;
} ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
return FAIL_RETURN;
int dm_mgr_get_devId_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid) }
{
int res = 0;
dm_mgr_dev_node_t *node = NULL; int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],uint64_t timestamp)
{
if (deviceCode == NULL) { dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
return INVALID_PARAMETER; dm_mgr_dev_node_t *search_node = NULL;
}
_dm_mgr_mutex_lock();
res = dm_mgr_get_device_by_devicecode(deviceCode, &node); list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
if (res != SUCCESS_RETURN) { if ((strlen(search_node->deviceCode) == strlen(deviceCode)) &&
return FAIL_RETURN; (memcmp(search_node->deviceCode, deviceCode, strlen(deviceCode)) == 0)) {
} /* dm_log_debug("Device Found, Product Key: %s, Device Name: %s", product_key, device_name); */
search_node->timestamp = timestamp;
if (devid) { _dm_mgr_mutex_unlock();
*devid = node->devid; return SUCCESS_RETURN;
} }
}
return SUCCESS_RETURN; _dm_mgr_mutex_unlock();
} ERROR_PRINT("Device Not Found, deviceCode: %s\n", deviceCode);
return FAIL_RETURN;
static void _dm_mgr_destroy_devlist(void) }
{ #define TEST_TIMEOUT 600000 // ten minutes
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); int dm_mgr_check_heartbeat_timeout(uint64_t timestamp)
dm_mgr_dev_node_t *del_node = NULL; {
dm_mgr_dev_node_t *next_node = NULL; dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_dev_node_t *search_node = NULL;
list_for_each_entry_safe(del_node, next_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
list_del(&del_node->linked_list); _dm_mgr_mutex_lock();
list_for_each_entry(search_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
//dm_shw_destroy(&del_node->dev_shadow); if(search_node->dev_type == KK_DM_DEVICE_CCU){
continue;
free(del_node); }
} if((timestamp - search_node->timestamp) >= TEST_TIMEOUT/*search_node->hb_timeout*/){
}
if(search_node->isOffline == 0){
int dm_mgr_init(void) INFO_PRINT("---------->dev timeout,send offline\n");
{ search_node->isOffline = 1;
int res = 0; iotx_dm_dev_offline(search_node->devid);
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode);
char productCode[PRODUCT_CODE_MAXLEN] = {0}; }
char deviceCode[DEVICE_CODE_MAXLEN]= {0};
char mac[DEVICE_MAC_MAXLEN]= {0}; //_dm_mgr_mutex_unlock();
int devId = 0; //return DEVICE_HEARTBEAT_TIMEOUT;
memset(ctx, 0, sizeof(dm_mgr_ctx)); }
else{
/* Create Mutex */ if(search_node->isOffline == 1){//need send online
ctx->mutex = kk_MutexCreate(); INFO_PRINT("---------->dev online again,send online\n");
if (ctx->mutex == NULL) { search_node->isOffline = 0;
goto ERROR; iotx_dm_dev_online(search_node->devid);
} kk_subDev_update_offline(search_node->isOffline,search_node->deviceCode);
/* Init Device Id*/ }
ctx->global_devid = 1; }
kk_property_db_init(); }
/* Init Device List */ _dm_mgr_mutex_unlock();
INIT_LIST_HEAD(&ctx->dev_list); return SUCCESS_RETURN;
}
//HAL_GetProduct_Type(product_key);
//HAL_GetProduct_Code(device_name); int dm_mgr_get_devId_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid)
HAL_Get_mac(mac); {
res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",&devId); int res = 0;
if (res != SUCCESS_RETURN) { dm_mgr_dev_node_t *node = NULL;
goto ERROR;
} if (deviceCode == NULL) {
else{ return INVALID_PARAMETER;
_dm_init_tsl_params(devId); }
kk_property_db_update("CCU_66666");
res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
} if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
return SUCCESS_RETURN; }
ERROR: if (devid) {
if (ctx->mutex) { *devid = node->devid;
kk_MutexDestroy(ctx->mutex); }
}
memset(ctx, 0, sizeof(dm_mgr_ctx)); return SUCCESS_RETURN;
return FAIL_RETURN; }
}
static void _dm_mgr_destroy_devlist(void)
int dm_mgr_deinit(void) {
{ dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_dev_node_t *del_node = NULL;
dm_mgr_dev_node_t *next_node = NULL;
_dm_mgr_mutex_lock();
_dm_mgr_destroy_devlist(); list_for_each_entry_safe(del_node, next_node, &ctx->dev_list, linked_list, dm_mgr_dev_node_t) {
_dm_mgr_mutex_unlock(); list_del(&del_node->linked_list);
if (ctx->mutex) { //dm_shw_destroy(&del_node->dev_shadow);
HAL_MutexDestroy(ctx->mutex);
} free(del_node);
}
return SUCCESS_RETURN; }
}
int dm_mgr_init(void)
const char DM_URI_THING_EVENT_POST[] = "/thing/event/%s/post"; {
const char DM_MSG_THING_UPSTREAM_REQUEST_PARAMS[] DM_READ_ONLY = "%s"; int res = 0;
static int _dm_mgr_upstream_request_assemble(_IN_ int msgid, _IN_ int devid, dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
_IN_ char *identify, char productCode[PRODUCT_CODE_MAXLEN] = {0};
_IN_ char *params, _IN_ int params_len, _IN_ char *method, _OU_ dm_msg_request_t *request) char deviceCode[DEVICE_CODE_MAXLEN]= {0};
{ char mac[DEVICE_MAC_MAXLEN]= {0};
int res = 0; int devId = 0;
dm_mgr_dev_node_t *node = NULL; memset(ctx, 0, sizeof(dm_mgr_ctx));
int paramLen = 0;
int msgTypeLen = 0; /* Create Mutex */
char *payload_param = NULL; ctx->mutex = kk_MutexCreate();
res = dm_mgr_search_dev_by_devid(devid, &node); if (ctx->mutex == NULL) {
if (res != SUCCESS_RETURN) { goto ERROR;
return FAIL_RETURN; }
} /* Init Device Id*/
ctx->global_devid = 1;
/* dm_log_debug("Time Stamp: %s", timestamp); */ kk_property_db_init();
paramLen = strlen(DM_MSG_THING_UPSTREAM_REQUEST_PARAMS) + /* Init Device List */
params_len + 1; INIT_LIST_HEAD(&ctx->dev_list);
payload_param = malloc(paramLen);
if (payload_param == NULL) { HAL_Get_mac(mac);
return MEMORY_NOT_ENOUGH;
} res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",&devId);
if (res != SUCCESS_RETURN) {
memset(payload_param, 0, paramLen); goto ERROR;
HAL_Snprintf(payload_param, paramLen, DM_MSG_THING_UPSTREAM_REQUEST_PARAMS, params); }
else{
request->msgid = msgid;
request->devid = devid; kk_property_db_update("CCU_66666");
msgTypeLen = strlen(DM_URI_THING_EVENT_POST) + strlen(identify) + 1;
request->msgTypeStr = malloc(msgTypeLen); }
if(request->msgTypeStr == NULL){
return MEMORY_NOT_ENOUGH; return SUCCESS_RETURN;
}
memset(request->msgTypeStr,0x0,msgTypeLen); ERROR:
snprintf(request->msgTypeStr,msgTypeLen,DM_URI_THING_EVENT_POST,identify); return FAIL_RETURN;
memcpy(request->productCode, node->productCode, strlen(node->productCode)); }
memcpy(request->deviceCode, node->deviceCode, strlen(node->deviceCode));
request->params = payload_param; int dm_mgr_deinit(void)
request->params_len = paramLen; {
request->method = method; dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
return SUCCESS_RETURN; _dm_mgr_mutex_lock();
} _dm_mgr_destroy_devlist();
static unsigned int g_report_id = 1; _dm_mgr_mutex_unlock();
int iotx_report_id(void) if (ctx->mutex) {
{ HAL_MutexDestroy(ctx->mutex);
return g_report_id++; }
}
return SUCCESS_RETURN;
int dm_mgr_upstream_thing_property_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len,_IN_ int isAsync) }
{
int res = 0; const char DM_URI_THING_EVENT_POST[] = "/thing/event/%s/post";
dm_msg_request_t request; const char DM_MSG_THING_UPSTREAM_REQUEST_PARAMS[] DM_READ_ONLY = "%s";
static int _dm_mgr_upstream_request_assemble(_IN_ int msgid, _IN_ int devid,
if (devid < 0 || payload == NULL || payload_len <= 0) { _IN_ char *identify,
return INVALID_PARAMETER; _IN_ char *params, _IN_ int params_len, _IN_ char *method, _OU_ dm_msg_request_t *request)
} {
int res = 0;
memset(&request, 0, sizeof(dm_msg_request_t)); dm_mgr_dev_node_t *node = NULL;
res = _dm_mgr_upstream_request_assemble(iotx_report_id(), devid, "property", int paramLen = 0;
payload, payload_len, DM_URI_THING_EVENT_PROPERTY_POST_METHOD, &request); int msgTypeLen = 0;
if (res != SUCCESS_RETURN) { char *payload_param = NULL;
return FAIL_RETURN; res = dm_mgr_search_dev_by_devid(devid, &node);
} if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
/* Callback */ }
//request.callback = dm_client_thing_event_post_reply;
/* dm_log_debug("Time Stamp: %s", timestamp); */
/* Send Message To Cloud */ paramLen = strlen(DM_MSG_THING_UPSTREAM_REQUEST_PARAMS) +
res = dm_msg_request(&request,isAsync); params_len + 1;
free(request.msgTypeStr); payload_param = malloc(paramLen);
free(request.params); if (payload_param == NULL) {
return res; return MEMORY_NOT_ENOUGH;
} }
int dm_mgr_upstream_thing_event_post(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
_IN_ char *payload, _IN_ int payload_len) memset(payload_param, 0, paramLen);
{ HAL_Snprintf(payload_param, paramLen, DM_MSG_THING_UPSTREAM_REQUEST_PARAMS, params);
int res = 0;
request->msgid = msgid;
dm_msg_request_t request; request->devid = devid;
msgTypeLen = strlen(DM_URI_THING_EVENT_POST) + strlen(identify) + 1;
if (devid < 0 || identifier == NULL || identifier_len <= 0 || request->msgTypeStr = malloc(msgTypeLen);
method == NULL || payload == NULL || payload_len <= 0) { if(request->msgTypeStr == NULL){
return INVALID_PARAMETER; return MEMORY_NOT_ENOUGH;
} }
memset(&request, 0, sizeof(dm_msg_request_t)); memset(request->msgTypeStr,0x0,msgTypeLen);
res = _dm_mgr_upstream_request_assemble(iotx_report_id(), devid,identifier, snprintf(request->msgTypeStr,msgTypeLen,DM_URI_THING_EVENT_POST,identify);
payload, payload_len, method, &request); memcpy(request->productCode, node->productCode, strlen(node->productCode));
if (res != SUCCESS_RETURN) { memcpy(request->deviceCode, node->deviceCode, strlen(node->deviceCode));
return FAIL_RETURN; request->params = payload_param;
} request->params_len = paramLen;
request->method = method;
/* Callback */
//request.callback = dm_client_thing_event_post_reply; return SUCCESS_RETURN;
}
/* Send Message To Cloud */ static unsigned int g_report_id = 1;
res = dm_msg_request(&request,0);
free(request.msgTypeStr); int iotx_report_id(void)
free(request.params); {
return res; return g_report_id++;
} }
const char DM_URI_THING_SERVICE_RESPONSE[] = "/thing/service/%.*s_reply"; int dm_mgr_upstream_thing_property_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len,_IN_ int isAsync)
static int _kk_mgr_upstream_response_assemble(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len, {
_IN_ const char *identfy, _IN_ int code, _OU_ kk_msg_request_payload_t *request, _OU_ kk_msg_response_t *response) int res = 0;
{ dm_msg_request_t request;
int res = 0;
int msgTypeLen = 0; if (devid < 0 || payload == NULL || payload_len <= 0) {
dm_mgr_dev_node_t *node = NULL; return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) { memset(&request, 0, sizeof(dm_msg_request_t));
return FAIL_RETURN; res = _dm_mgr_upstream_request_assemble(iotx_report_id(), devid, "property",
} payload, payload_len, DM_URI_THING_EVENT_PROPERTY_POST_METHOD, &request);
if (res != SUCCESS_RETURN) {
request->id.value = msgid; return FAIL_RETURN;
request->id.value_length = msgid_len; }
msgTypeLen = strlen(DM_URI_THING_SERVICE_RESPONSE) + strlen(identfy) + 1; /* Callback */
//request.callback = dm_client_thing_event_post_reply;
response->msgTypeStr = malloc(msgTypeLen);
if(response->msgTypeStr == NULL){ /* Send Message To Cloud */
return MEMORY_NOT_ENOUGH; res = dm_msg_request(&request,isAsync);
} free(request.msgTypeStr);
memset(response->msgTypeStr,0x0,msgTypeLen); free(request.params);
snprintf(response->msgTypeStr,msgTypeLen,DM_URI_THING_SERVICE_RESPONSE,identfy); return res;
memcpy(response->productCode, node->productCode, strlen(node->productCode)); }
memcpy(response->deviceCode, node->deviceCode, strlen(node->deviceCode)); int dm_mgr_upstream_thing_event_post(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
response->code = code; _IN_ char *payload, _IN_ int payload_len)
{
return SUCCESS_RETURN; int res = 0;
}
dm_msg_request_t request;
int dm_mgr_deprecated_upstream_thing_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
_IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len) if (devid < 0 || identifier == NULL || identifier_len <= 0 ||
{ method == NULL || payload == NULL || payload_len <= 0) {
int res = 0, service_name_len = 0; return INVALID_PARAMETER;
char *msgid_str = NULL; }
kk_msg_request_payload_t request; memset(&request, 0, sizeof(dm_msg_request_t));
kk_msg_response_t response; res = _dm_mgr_upstream_request_assemble(iotx_report_id(), devid,identifier,
payload, payload_len, method, &request);
memset(&request, 0, sizeof(kk_msg_request_payload_t)); if (res != SUCCESS_RETURN) {
memset(&response, 0, sizeof(kk_msg_response_t)); return FAIL_RETURN;
}
if (devid < 0 || msgid < 0 || identifier == NULL || identifier_len <= 0 ||
payload == NULL || payload_len <= 0) { /* Callback */
return INVALID_PARAMETER; //request.callback = dm_client_thing_event_post_reply;
}
/* Send Message To Cloud */
/* Response Msg ID */ res = dm_msg_request(&request,0);
res = kk_utils_itoa(msgid, &msgid_str); free(request.msgTypeStr);
if (res != SUCCESS_RETURN) { free(request.params);
return FAIL_RETURN; return res;
} }
request.id.value = msgid_str;
request.id.value_length = strlen(msgid_str); const char DM_URI_THING_SERVICE_RESPONSE[] = "/thing/service/%.*s_reply";
static int _kk_mgr_upstream_response_assemble(_IN_ int devid, _IN_ char *msgid, _IN_ int msgid_len,
/* Service Name */ _IN_ const char *identfy, _IN_ int code, _OU_ kk_msg_request_payload_t *request, _OU_ kk_msg_response_t *response)
{
res = _kk_mgr_upstream_response_assemble(devid, msgid_str, strlen(msgid_str), identifier, code, int res = 0;
&request, int msgTypeLen = 0;
&response); dm_mgr_dev_node_t *node = NULL;
if (res != SUCCESS_RETURN) {
return FAIL_RETURN; res = dm_mgr_search_dev_by_devid(devid, &node);
} if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
dm_msg_response(&request, &response, payload, payload_len, NULL);
free(response.msgTypeStr); request->id.value = msgid;
free(msgid_str); request->id.value_length = msgid_len;
return SUCCESS_RETURN;
} msgTypeLen = strlen(DM_URI_THING_SERVICE_RESPONSE) + strlen(identfy) + 1;
const char DM_URI_THING_SUB_REGISTER[] = "/thing/sub/register"; response->msgTypeStr = malloc(msgTypeLen);
int dm_mgr_upstream_thing_sub_register(_IN_ int devid) if(response->msgTypeStr == NULL){
{ return MEMORY_NOT_ENOUGH;
int res = 0; }
dm_mgr_dev_node_t *node = NULL; memset(response->msgTypeStr,0x0,msgTypeLen);
dm_mgr_dev_node_t *gw_node = NULL; snprintf(response->msgTypeStr,msgTypeLen,DM_URI_THING_SERVICE_RESPONSE,identfy);
dm_msg_request_t request; memcpy(response->productCode, node->productCode, strlen(node->productCode));
memcpy(response->deviceCode, node->deviceCode, strlen(node->deviceCode));
if (devid < 0) { response->code = code;
return INVALID_PARAMETER;
} return SUCCESS_RETURN;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) { int dm_mgr_deprecated_upstream_thing_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len)
return FAIL_RETURN; {
} int res = 0, service_name_len = 0;
char *msgid_str = NULL;
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); kk_msg_request_payload_t request;
if (res != SUCCESS_RETURN) { kk_msg_response_t response;
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN; memset(&request, 0, sizeof(kk_msg_request_payload_t));
} memset(&response, 0, sizeof(kk_msg_response_t));
memset(&request, 0, sizeof(dm_msg_request_t));
request.msgTypeStr = DM_URI_THING_SUB_REGISTER; if (devid < 0 || msgid < 0 || identifier == NULL || identifier_len <= 0 ||
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); payload == NULL || payload_len <= 0) {
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); return INVALID_PARAMETER;
/* Get Params And Method */ }
res = dm_msg_thing_sub_register( node->productCode,node->deviceCode, &request);
if (res != SUCCESS_RETURN) { /* Response Msg ID */
return FAIL_RETURN; res = kk_utils_itoa(msgid, &msgid_str);
} if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
/* Get Msg ID */ }
request.msgid = iotx_report_id(); request.id.value = msgid_str;
request.id.value_length = strlen(msgid_str);
/* Get Dev ID */
request.devid = devid; /* Service Name */
/* Callback */ res = _kk_mgr_upstream_response_assemble(devid, msgid_str, strlen(msgid_str), identifier, code,
//request.callback = dm_client_thing_sub_register_reply; &request,
&response);
/* Send Message To Cloud */ if (res != SUCCESS_RETURN) {
res = dm_msg_request(&request,0); return FAIL_RETURN;
if (res == SUCCESS_RETURN) { }
res = request.msgid;
}
free(request.params); dm_msg_response(&request, &response, payload, payload_len, NULL);
free(response.msgTypeStr);
return res; free(msgid_str);
} return SUCCESS_RETURN;
}
const char DM_URI_THING_SUB_UNREGISTER[] = "/thing/sub/unregister";
int dm_mgr_upstream_thing_sub_unregister(_IN_ int devid) const char DM_URI_THING_SUB_REGISTER[] = "/thing/sub/register";
{ int dm_mgr_upstream_thing_sub_register(_IN_ int devid)
int res = 0; {
dm_mgr_dev_node_t *node = NULL; int res = 0;
dm_mgr_dev_node_t *gw_node = NULL; dm_mgr_dev_node_t *node = NULL;
dm_msg_request_t request; dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request;
if (devid < 0) {
return INVALID_PARAMETER; if (devid < 0) {
} return INVALID_PARAMETER;
}
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) { res = dm_mgr_search_dev_by_devid(devid, &node);
return FAIL_RETURN; if (res != SUCCESS_RETURN) {
} ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); return FAIL_RETURN;
if (res != SUCCESS_RETURN) { }
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN; res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
} if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
memset(&request, 0, sizeof(dm_msg_request_t)); return FAIL_RETURN;
request.msgTypeStr = DM_URI_THING_SUB_UNREGISTER; }
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); memset(&request, 0, sizeof(dm_msg_request_t));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); request.msgTypeStr = DM_URI_THING_SUB_REGISTER;
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
/* Get Params And Method */ /* Get Params And Method */
res = dm_msg_thing_sub_unregister(node->deviceCode, &request); res = dm_msg_thing_sub_register( node->productCode,node->deviceCode, &request);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
/* Get Msg ID */ /* Get Msg ID */
request.msgid = iotx_report_id(); request.msgid = iotx_report_id();
/* Get Dev ID */ /* Get Dev ID */
request.devid = devid; request.devid = devid;
/* Callback */ /* Callback */
//request.callback = dm_client_thing_sub_unregister_reply; //request.callback = dm_client_thing_sub_register_reply;
/* Send Message To Cloud */
/* Send Message To Cloud */ res = dm_msg_request(&request,0);
res = dm_msg_request(&request,0); if (res == SUCCESS_RETURN) {
res = request.msgid;
if (res == SUCCESS_RETURN) { }
res = request.msgid; free(request.params);
}
free(request.params); return res;
}
return res;
} const char DM_URI_THING_SUB_UNREGISTER[] = "/thing/sub/unregister";
int dm_mgr_upstream_thing_sub_unregister(_IN_ int devid)
const char DM_URI_THING_TOPO_ADD[] = "/thing/topo/add"; {
int dm_mgr_upstream_thing_topo_add(_IN_ int devid) int res = 0;
{ dm_mgr_dev_node_t *node = NULL;
int res = 0; dm_mgr_dev_node_t *gw_node = NULL;
dm_mgr_dev_node_t *node = NULL; dm_msg_request_t request;
dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request; if (devid < 0) {
return INVALID_PARAMETER;
if (devid < 0) { }
return INVALID_PARAMETER;
} res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
res = dm_mgr_search_dev_by_devid(devid, &node); return FAIL_RETURN;
}
if (res != SUCCESS_RETURN) { res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
ERROR_PRINT("ERROR res:%d\n",res); if (res != SUCCESS_RETURN) {
return FAIL_RETURN; ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} return FAIL_RETURN;
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); }
if (res != SUCCESS_RETURN) { memset(&request, 0, sizeof(dm_msg_request_t));
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); request.msgTypeStr = DM_URI_THING_SUB_UNREGISTER;
return FAIL_RETURN; memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
} memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
memset(&request, 0, sizeof(dm_msg_request_t));
request.msgTypeStr = DM_URI_THING_TOPO_ADD; /* Get Params And Method */
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); res = dm_msg_thing_sub_unregister(node->deviceCode, &request);
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
/* Get Params And Method */
res = dm_msg_thing_topo_add( node->productCode, node->deviceCode, node->mac,&request); /* Get Msg ID */
if (res != SUCCESS_RETURN) { request.msgid = iotx_report_id();
return FAIL_RETURN;
} /* Get Dev ID */
request.devid = devid;
/* Get Msg ID */
request.msgid = iotx_report_id(); /* Callback */
//request.callback = dm_client_thing_sub_unregister_reply;
/* Get Dev ID */
request.devid = devid;
/* Send Message To Cloud */
/* Callback */ res = dm_msg_request(&request,0);
//request.callback = dm_client_thing_topo_add_reply;
if (res == SUCCESS_RETURN) {
res = request.msgid;
/* Send Message To Cloud */ }
res = dm_msg_request(&request,0); free(request.params);
if (res == SUCCESS_RETURN) { return res;
res = request.msgid; }
}
free(request.params); const char DM_URI_THING_TOPO_ADD[] = "/thing/topo/add";
int dm_mgr_upstream_thing_topo_add(_IN_ int devid)
return res; {
} int res = 0;
dm_mgr_dev_node_t *node = NULL;
const char DM_URI_THING_TOPO_DELETE[] = "/thing/topo/delete"; dm_mgr_dev_node_t *gw_node = NULL;
int dm_mgr_upstream_thing_topo_delete(_IN_ int devid) dm_msg_request_t request;
{
int res = 0; if (devid < 0) {
dm_mgr_dev_node_t *node = NULL; return INVALID_PARAMETER;
dm_mgr_dev_node_t *gw_node = NULL; }
dm_msg_request_t request;
res = dm_mgr_search_dev_by_devid(devid, &node);
if (devid < 0) {
return DM_INVALID_PARAMETER; if (res != SUCCESS_RETURN) {
} ERROR_PRINT("ERROR res:%d\n",res);
return FAIL_RETURN;
res = dm_mgr_search_dev_by_devid(devid, &node); }
if (res != SUCCESS_RETURN) { res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
return FAIL_RETURN;
} if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); return FAIL_RETURN;
if (res != SUCCESS_RETURN) { }
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN; memset(&request, 0, sizeof(dm_msg_request_t));
} request.msgTypeStr = DM_URI_THING_TOPO_ADD;
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memset(&request, 0, sizeof(dm_msg_request_t)); memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
request.msgTypeStr = DM_URI_THING_TOPO_DELETE;
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); /* Get Params And Method */
res = dm_msg_thing_topo_add( node->productCode, node->deviceCode, node->mac,&request);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
/* Get Params And Method */ }
res = dm_msg_thing_topo_delete( node->deviceCode, &request);
if (res != SUCCESS_RETURN) { /* Get Msg ID */
return FAIL_RETURN; request.msgid = iotx_report_id();
}
/* Get Dev ID */
/* Get Msg ID */ request.devid = devid;
request.msgid = iotx_report_id();
/* Callback */
/* Get Dev ID */ //request.callback = dm_client_thing_topo_add_reply;
request.devid = devid;
/* Callback */ /* Send Message To Cloud */
//request.callback = dm_client_thing_topo_delete_reply; res = dm_msg_request(&request,0);
if (res == SUCCESS_RETURN) {
/* Send Message To Cloud */ res = request.msgid;
res = dm_msg_request(&request,0); }
free(request.params);
if (res == SUCCESS_RETURN) {
res = request.msgid; return res;
} }
free(request.params);
const char DM_URI_THING_TOPO_DELETE[] = "/thing/topo/delete";
return res; int dm_mgr_upstream_thing_topo_delete(_IN_ int devid)
} {
int res = 0;
const char DM_URI_THING_TOPO_GET[] = "/thing/topo/get"; dm_mgr_dev_node_t *node = NULL;
int dm_mgr_upstream_thing_topo_get(void) dm_mgr_dev_node_t *gw_node = NULL;
{ dm_msg_request_t request;
int res = 0;
dm_mgr_dev_node_t *node = NULL; if (devid < 0) {
return DM_INVALID_PARAMETER;
dm_msg_request_t request; }
memset(&request, 0, sizeof(dm_msg_request_t)); res = dm_mgr_search_dev_by_devid(devid, &node);
request.msgTypeStr = DM_URI_THING_TOPO_GET; if (res != SUCCESS_RETURN) {
HAL_GetProduct_Code(request.deviceCode); return FAIL_RETURN;
}
res = _dm_mgr_search_dev_by_pkdn(request.deviceCode, &node); res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
} return FAIL_RETURN;
}
/* Get Params And Method */
res = dm_msg_thing_topo_get(&request); memset(&request, 0, sizeof(dm_msg_request_t));
if (res != SUCCESS_RETURN) { request.msgTypeStr = DM_URI_THING_TOPO_DELETE;
return FAIL_RETURN; memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
} memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
/* Get Msg ID */
request.msgid = iotx_report_id();
/* Get Params And Method */
/* Get Dev ID */ res = dm_msg_thing_topo_delete( node->deviceCode, &request);
request.devid = node->devid; if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
/* Callback */ }
//request.callback = dm_client_thing_topo_get_reply;
/* Get Msg ID */
/* Send Message To Cloud */ request.msgid = iotx_report_id();
res = dm_msg_request(&request,0);
if (res == SUCCESS_RETURN) { /* Get Dev ID */
res = request.msgid; request.devid = devid;
}
free(request.params); /* Callback */
//request.callback = dm_client_thing_topo_delete_reply;
return res;
}
const char DM_URI_THING_LIST_FOUND[] = "/thing/list/found"; /* Send Message To Cloud */
res = dm_msg_request(&request,0);
int dm_mgr_upstream_thing_list_found(_IN_ int devid)
{ if (res == SUCCESS_RETURN) {
int res = 0; res = request.msgid;
dm_mgr_dev_node_t *node = NULL; }
dm_mgr_dev_node_t *gw_node = NULL; free(request.params);
dm_msg_request_t request;
return res;
if (devid < 0) { }
return INVALID_PARAMETER;
} const char DM_URI_THING_TOPO_GET[] = "/thing/topo/get";
int dm_mgr_upstream_thing_topo_get(void)
res = dm_mgr_search_dev_by_devid(devid, &node); {
if (res != SUCCESS_RETURN) { int res = 0;
return FAIL_RETURN; dm_mgr_dev_node_t *node = NULL;
}
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); dm_msg_request_t request;
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); memset(&request, 0, sizeof(dm_msg_request_t));
return FAIL_RETURN; request.msgTypeStr = DM_URI_THING_TOPO_GET;
} HAL_GetProduct_Code(request.deviceCode);
memset(&request, 0, sizeof(dm_msg_request_t));
request.msgTypeStr = DM_URI_THING_LIST_FOUND; res = _dm_mgr_search_dev_by_pkdn(request.deviceCode, &node);
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); if (res != SUCCESS_RETURN) {
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); return FAIL_RETURN;
}
/* Get Params And Method */ /* Get Params And Method */
res = dm_msg_thing_list_found( node->deviceCode, &request); res = dm_msg_thing_topo_get(&request);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
/* Get Msg ID */ /* Get Msg ID */
request.msgid = iotx_report_id(); request.msgid = iotx_report_id();
/* Get Dev ID */ /* Get Dev ID */
request.devid = devid; request.devid = node->devid;
/* Callback */ /* Callback */
//request.callback = dm_client_thing_list_found_reply; //request.callback = dm_client_thing_topo_get_reply;
/* Send Message To Cloud */ /* Send Message To Cloud */
res = dm_msg_request(&request,0); res = dm_msg_request(&request,0);
if (res == SUCCESS_RETURN) { if (res == SUCCESS_RETURN) {
res = request.msgid; res = request.msgid;
} }
free(request.params); free(request.params);
return res; return res;
} }
const char DM_URI_THING_LIST_FOUND[] = "/thing/list/found";
const char DM_URI_STATUS_CLOUD[] = "/thing/ccu/cloudstate";
int dm_mgr_ccu_status_cloud(_IN_ int devid) int dm_mgr_upstream_thing_list_found(_IN_ int devid)
{ {
int res = 0; int res = 0;
dm_mgr_dev_node_t *node = NULL; dm_mgr_dev_node_t *node = NULL;
dm_mgr_dev_node_t *gw_node = NULL; dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request; dm_msg_request_t request;
if (devid < 0) { if (devid < 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
memset(&request, 0, sizeof(dm_msg_request_t));
res = dm_mgr_search_dev_by_devid(devid, &node);
res = dm_mgr_search_dev_by_devid(devid, &node); if (res != SUCCESS_RETURN) {
if (res != SUCCESS_RETURN) { return FAIL_RETURN;
return FAIL_RETURN; }
} res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
if (res != SUCCESS_RETURN) {
memcpy(request.productCode,node->productCode,strlen(node->productCode)); ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode)); return FAIL_RETURN;
}
request.msgTypeStr = DM_URI_STATUS_CLOUD;
memset(&request, 0, sizeof(dm_msg_request_t));
request.msgTypeStr = DM_URI_THING_LIST_FOUND;
/* Get Params And Method */ memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
res = dm_msg_status_cloud( node->productCode, node->deviceCode, &request); memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
} /* Get Params And Method */
printf("[%s][%d]\n",__FUNCTION__,__LINE__); res = dm_msg_thing_list_found( node->deviceCode, &request);
if (res != SUCCESS_RETURN) {
/* Get Msg ID */ return FAIL_RETURN;
request.msgid = iotx_report_id(); }
/* Get Dev ID */ /* Get Msg ID */
request.devid = devid; request.msgid = iotx_report_id();
/* Callback */ /* Get Dev ID */
//request.callback = dm_client_combine_login_reply; request.devid = devid;
/* Callback */
/* Send Message To Cloud */ //request.callback = dm_client_thing_list_found_reply;
res = dm_msg_request(&request,0);
/* Send Message To Cloud */
if (res == SUCCESS_RETURN) { res = dm_msg_request(&request,0);
res = request.msgid; if (res == SUCCESS_RETURN) {
} res = request.msgid;
free(request.params); }
free(request.params);
return res;
} return res;
}
const char DM_URI_STATUS_ONLINE[] = "/thing/status/online";
int dm_mgr_upstream_status_online(_IN_ int devid) const char DM_URI_STATUS_CLOUD[] = "/thing/ccu/cloudstate";
{ int dm_mgr_ccu_status_cloud(_IN_ int devid)
int res = 0; {
dm_mgr_dev_node_t *node = NULL; int res = 0;
dm_mgr_dev_node_t *gw_node = NULL; dm_mgr_dev_node_t *node = NULL;
dm_msg_request_t request; dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request;
if (devid < 0) {
return INVALID_PARAMETER; if (devid < 0) {
} return INVALID_PARAMETER;
memset(&request, 0, sizeof(dm_msg_request_t)); }
memset(&request, 0, sizeof(dm_msg_request_t));
res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) { res = dm_mgr_search_dev_by_devid(devid, &node);
return FAIL_RETURN; if (res != SUCCESS_RETURN) {
} return FAIL_RETURN;
if(strlen(node->fatherDeviceCode) > 0){ }
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
if (res != SUCCESS_RETURN) { memcpy(request.productCode,node->productCode,strlen(node->productCode));
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode));
return FAIL_RETURN;
} request.msgTypeStr = DM_URI_STATUS_CLOUD;
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
/* Get Params And Method */
}else{ res = dm_msg_status_cloud( node->productCode, node->deviceCode, &request);
memcpy(request.productCode,node->productCode,strlen(node->productCode)); if (res != SUCCESS_RETURN) {
memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode)); return FAIL_RETURN;
} }
printf("[%s][%d]\n",__FUNCTION__,__LINE__);
/* Get Msg ID */
request.msgTypeStr = DM_URI_STATUS_ONLINE; request.msgid = iotx_report_id();
/* Get Dev ID */
/* Get Params And Method */ request.devid = devid;
res = dm_msg_status_online( node->productCode, node->deviceCode, &request);
if (res != SUCCESS_RETURN) { /* Callback */
return FAIL_RETURN; //request.callback = dm_client_combine_login_reply;
}
/* Get Msg ID */ /* Send Message To Cloud */
request.msgid = iotx_report_id(); res = dm_msg_request(&request,0);
/* Get Dev ID */ if (res == SUCCESS_RETURN) {
request.devid = devid; res = request.msgid;
}
/* Callback */ free(request.params);
//request.callback = dm_client_combine_login_reply;
return res;
}
/* Send Message To Cloud */
res = dm_msg_request(&request,0); const char DM_URI_STATUS_ONLINE[] = "/thing/status/online";
int dm_mgr_upstream_status_online(_IN_ int devid)
if (res == SUCCESS_RETURN) { {
res = request.msgid; int res = 0;
} dm_mgr_dev_node_t *node = NULL;
free(request.params); dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request;
return res;
} if (devid < 0) {
return INVALID_PARAMETER;
const char DM_URI_STATUS_OFFLINE[] = "/thing/status/offline"; }
int dm_mgr_upstream_status_offline(_IN_ int devid) memset(&request, 0, sizeof(dm_msg_request_t));
{
int res = 0; res = dm_mgr_search_dev_by_devid(devid, &node);
dm_mgr_dev_node_t *node = NULL; if (res != SUCCESS_RETURN) {
dm_mgr_dev_node_t *gw_node = NULL; return FAIL_RETURN;
dm_msg_request_t request; }
if(strlen(node->fatherDeviceCode) > 0){
if (devid < 0) { res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
return INVALID_PARAMETER; if (res != SUCCESS_RETURN) {
} ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
memset(&request, 0, sizeof(dm_msg_request_t)); return FAIL_RETURN;
}
res = dm_mgr_search_dev_by_devid(devid, &node); memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
if (res != SUCCESS_RETURN) { memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
return FAIL_RETURN;
} }else{
if(strlen(node->fatherDeviceCode) > 0){ memcpy(request.productCode,node->productCode,strlen(node->productCode));
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode));
if (res != SUCCESS_RETURN) { }
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); request.msgTypeStr = DM_URI_STATUS_ONLINE;
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
}else{ /* Get Params And Method */
memcpy(request.productCode,node->productCode,strlen(node->productCode)); res = dm_msg_status_online( node->productCode, node->deviceCode, &request);
memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode)); if (res != SUCCESS_RETURN) {
} return FAIL_RETURN;
}
request.msgTypeStr = DM_URI_STATUS_OFFLINE;
/* Get Msg ID */
/* Get Params And Method */ request.msgid = iotx_report_id();
res = dm_msg_status_offline( node->productCode, node->deviceCode, &request);
if (res != SUCCESS_RETURN) { /* Get Dev ID */
return FAIL_RETURN; request.devid = devid;
}
/* Callback */
/* Get Msg ID */ //request.callback = dm_client_combine_login_reply;
request.msgid = iotx_report_id();
/* Get Dev ID */ /* Send Message To Cloud */
request.devid = devid; res = dm_msg_request(&request,0);
/* Callback */ if (res == SUCCESS_RETURN) {
//request.callback = dm_client_combine_login_reply; res = request.msgid;
}
free(request.params);
/* Send Message To Cloud */
res = dm_msg_request(&request,0); return res;
}
if (res == SUCCESS_RETURN) {
res = request.msgid; const char DM_URI_STATUS_OFFLINE[] = "/thing/status/offline";
} int dm_mgr_upstream_status_offline(_IN_ int devid)
free(request.params); {
int res = 0;
return res; dm_mgr_dev_node_t *node = NULL;
} dm_mgr_dev_node_t *gw_node = NULL;
dm_msg_request_t request;
const char DM_URI_COMBINE_LOGIN[] = "/thing/combine/login"; if (devid < 0) {
int dm_mgr_upstream_combine_login(_IN_ int devid) return INVALID_PARAMETER;
{ }
int res = 0; memset(&request, 0, sizeof(dm_msg_request_t));
dm_mgr_dev_node_t *node = NULL;
dm_mgr_dev_node_t *gw_node = NULL; res = dm_mgr_search_dev_by_devid(devid, &node);
dm_msg_request_t request; if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
if (devid < 0) { }
return INVALID_PARAMETER; if(strlen(node->fatherDeviceCode) > 0){
} res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
if (res != SUCCESS_RETURN) {
res = dm_mgr_search_dev_by_devid(devid, &node); ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
if (res != SUCCESS_RETURN) { return FAIL_RETURN;
return FAIL_RETURN; }
} memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); }else{
return FAIL_RETURN; memcpy(request.productCode,node->productCode,strlen(node->productCode));
} memcpy(request.deviceCode,node->deviceCode,strlen(node->deviceCode));
}
memset(&request, 0, sizeof(dm_msg_request_t));
request.msgTypeStr = DM_URI_COMBINE_LOGIN; request.msgTypeStr = DM_URI_STATUS_OFFLINE;
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode)); /* Get Params And Method */
res = dm_msg_status_offline( node->productCode, node->deviceCode, &request);
if (res != SUCCESS_RETURN) {
/* Get Params And Method */ return FAIL_RETURN;
res = dm_msg_combine_login( node->productCode, node->deviceCode, &request); }
if (res != SUCCESS_RETURN) {
return FAIL_RETURN; /* Get Msg ID */
} request.msgid = iotx_report_id();
/* Get Msg ID */ /* Get Dev ID */
request.msgid = iotx_report_id(); request.devid = devid;
/* Get Dev ID */ /* Callback */
request.devid = devid; //request.callback = dm_client_combine_login_reply;
/* Callback */
//request.callback = dm_client_combine_login_reply; /* Send Message To Cloud */
res = dm_msg_request(&request,0);
/* Send Message To Cloud */ if (res == SUCCESS_RETURN) {
res = dm_msg_request(&request,0); res = request.msgid;
}
if (res == SUCCESS_RETURN) { free(request.params);
res = request.msgid;
} return res;
free(request.params); }
return res;
} const char DM_URI_COMBINE_LOGIN[] = "/thing/combine/login";
const char DM_URI_COMBINE_LOGOUT[] = "/thing/combine/logout"; int dm_mgr_upstream_combine_login(_IN_ int devid)
int dm_mgr_upstream_combine_logout(_IN_ int devid) {
{ int res = 0;
int res = 0; dm_mgr_dev_node_t *node = NULL;
dm_mgr_dev_node_t *node = NULL; dm_mgr_dev_node_t *gw_node = NULL;
dm_mgr_dev_node_t *gw_node = NULL; dm_msg_request_t request;
dm_msg_request_t request;
if (devid < 0) {
if (devid < 0) { return INVALID_PARAMETER;
return INVALID_PARAMETER; }
}
res = dm_mgr_search_dev_by_devid(devid, &node);
res = dm_mgr_search_dev_by_devid(devid, &node); if (res != SUCCESS_RETURN) {
if (res != SUCCESS_RETURN) { return FAIL_RETURN;
return FAIL_RETURN; }
} res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node); if (res != SUCCESS_RETURN) {
if (res != SUCCESS_RETURN) { ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); return FAIL_RETURN;
return FAIL_RETURN; }
}
memset(&request, 0, sizeof(dm_msg_request_t));
memset(&request, 0, sizeof(dm_msg_request_t)); request.msgTypeStr = DM_URI_COMBINE_LOGIN;
request.msgTypeStr = DM_URI_COMBINE_LOGOUT; memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode)); memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
/* Get Params And Method */
/* Get Params And Method */ res = dm_msg_combine_login( node->productCode, node->deviceCode, &request);
res = dm_msg_combine_logout( node->deviceCode, &request); if (res != SUCCESS_RETURN) {
if (res != SUCCESS_RETURN) { return FAIL_RETURN;
return FAIL_RETURN; }
}
/* Get Msg ID */
/* Get Msg ID */ request.msgid = iotx_report_id();
request.msgid = iotx_report_id();
/* Get Dev ID */
/* Get Dev ID */ request.devid = devid;
request.devid = devid;
/* Callback */
/* Callback */ //request.callback = dm_client_combine_login_reply;
//request.callback = dm_client_combine_logout_reply;
/* Send Message To Cloud */ /* Send Message To Cloud */
res = dm_msg_request(&request,0);
/* Send Message To Cloud */
res = dm_msg_request(&request,0); if (res == SUCCESS_RETURN) {
res = request.msgid;
if (res == SUCCESS_RETURN) { }
res = request.msgid; free(request.params);
}
free(request.params); return res;
}
return res; const char DM_URI_COMBINE_LOGOUT[] = "/thing/combine/logout";
} int dm_mgr_upstream_combine_logout(_IN_ int devid)
{
const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s"; int res = 0;
int dm_mgr_ota_report_version(_IN_ int devid, char *version) dm_mgr_dev_node_t *node = NULL;
{ dm_mgr_dev_node_t *gw_node = NULL;
int res = 0; dm_msg_request_t request;
dm_mgr_dev_node_t *node = NULL;
dm_msg_request_t request; if (devid < 0) {
return INVALID_PARAMETER;
if (devid < 0) { }
return INVALID_PARAMETER;
} res = dm_mgr_search_dev_by_devid(devid, &node);
if (res != SUCCESS_RETURN) {
res = dm_mgr_search_dev_by_devid(devid, &node); return FAIL_RETURN;
if (res != SUCCESS_RETURN) { }
return FAIL_RETURN; res = dm_mgr_get_device_by_devicecode(node->fatherDeviceCode,&gw_node);
} if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
memset(&request, 0, sizeof(dm_msg_request_t)); return FAIL_RETURN;
request.msgTypeStr = malloc(strlen(KK_URI_OTA_INFORM)+strlen(node->productCode)+strlen(node->deviceCode)+1); }
if(request.msgTypeStr == NULL){
return MEMORY_NOT_ENOUGH; memset(&request, 0, sizeof(dm_msg_request_t));
} request.msgTypeStr = DM_URI_COMBINE_LOGOUT;
sprintf(request.msgTypeStr,KK_URI_OTA_INFORM,node->productCode,node->deviceCode); memcpy(request.productCode,gw_node->productCode,strlen(gw_node->productCode));
memcpy(request.productCode, node->productCode, PRODUCT_CODE_MAXLEN); memcpy(request.deviceCode,gw_node->deviceCode,strlen(gw_node->deviceCode));
memcpy(request.deviceCode, node->deviceCode, DEVICE_CODE_MAXLEN);
/* Get Params And Method */ /* Get Params And Method */
res = dm_msg_ota_report_version(version, &request); res = dm_msg_combine_logout( node->deviceCode, &request);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
/* Get Msg ID */ /* Get Msg ID */
request.msgid = iotx_report_id(); request.msgid = iotx_report_id();
/* Get Dev ID */ /* Get Dev ID */
request.devid = devid; request.devid = devid;
/* Callback */ /* Callback */
//request.callback = dm_client_combine_logout_reply; //request.callback = dm_client_combine_logout_reply;
/* Send Message To Cloud */ /* Send Message To Cloud */
/* Send Message To Cloud */ /* Send Message To Cloud */
res = dm_msg_request(&request,0); res = dm_msg_request(&request,0);
if (res == SUCCESS_RETURN) { if (res == SUCCESS_RETURN) {
res = request.msgid; res = request.msgid;
} }
free(request.params); free(request.params);
free(request.msgTypeStr);
return res;
return res; }
}
const char KK_URI_OTA_INFORM[] = "/ota/device/inform/%s/%s";
int dm_mgr_ota_report_version(_IN_ int devid, char *version)
{
int dm_mgr_subdev_create(int devtype,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN], int res = 0;
_IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN], _OU_ int *devid){ dm_mgr_dev_node_t *node = NULL;
int res = 0; dm_msg_request_t request;
res = dm_mgr_device_create(devtype,productCode,deviceCode,mac,fatherDeviceCode, devid); if (devid < 0) {
if(TSL_ALREADY_EXIST == res) return INVALID_PARAMETER;
{ }
ERROR_PRINT("SUBDEV ALREADY EXIST!!!\n");
} res = dm_mgr_search_dev_by_devid(devid, &node);
return res; if (res != SUCCESS_RETURN) {
} return FAIL_RETURN;
}
int dm_mgr_subdev_delete(_IN_ char deviceCode[DEVICE_CODE_MAXLEN])
{ memset(&request, 0, sizeof(dm_msg_request_t));
int res = 0; request.msgTypeStr = malloc(strlen(KK_URI_OTA_INFORM)+strlen(node->productCode)+strlen(node->deviceCode)+1);
dm_mgr_dev_node_t *node = NULL; if(request.msgTypeStr == NULL){
if(deviceCode == NULL || strlen(deviceCode) <=0){ return MEMORY_NOT_ENOUGH;
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); }
return FAIL_RETURN; sprintf(request.msgTypeStr,KK_URI_OTA_INFORM,node->productCode,node->deviceCode);
} memcpy(request.productCode, node->productCode, PRODUCT_CODE_MAXLEN);
INFO_PRINT("dm_mgr_subdev_delete deviceCode:%s\n",deviceCode); memcpy(request.deviceCode, node->deviceCode, DEVICE_CODE_MAXLEN);
res = kk_subDev_delete_by_dcode(deviceCode);//delete sub db data
if (res != SUCCESS_RETURN) { /* Get Params And Method */
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); res = dm_msg_ota_report_version(version, &request);
return FAIL_RETURN; if (res != SUCCESS_RETURN) {
} return FAIL_RETURN;
}
res = kk_property_delete_by_dcode(deviceCode);//delete properties db data
if (res != SUCCESS_RETURN) { /* Get Msg ID */
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); request.msgid = iotx_report_id();
return FAIL_RETURN;
} /* Get Dev ID */
request.devid = devid;
res = dm_mgr_get_device_by_devicecode(deviceCode,&node);
if (res != SUCCESS_RETURN) { /* Callback */
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res); //request.callback = dm_client_combine_logout_reply;
return FAIL_RETURN;
} /* Send Message To Cloud */
if(node->dev_type == KK_DM_DEVICE_CCU){ /* Send Message To Cloud */
ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__); res = dm_msg_request(&request,0);
return FAIL_RETURN;
} if (res == SUCCESS_RETURN) {
res = request.msgid;
list_del(&node->linked_list); }
free(request.params);
if (node->dev_shadow) { free(request.msgTypeStr);
kk_tsl_destroy(&node->dev_shadow);
} return res;
}
free(node);
node = NULL;
return SUCCESS_RETURN;
int dm_mgr_subdev_create(int devtype,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN],
} _IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN], _OU_ int *devid){
int res = 0;
res = dm_mgr_device_create(devtype,productCode,deviceCode,mac,fatherDeviceCode, devid);
if(TSL_ALREADY_EXIST == res)
{
ERROR_PRINT("SUBDEV ALREADY EXIST!!!\n");
}
return res;
}
int dm_mgr_subdev_delete(_IN_ char deviceCode[DEVICE_CODE_MAXLEN])
{
int res = 0;
dm_mgr_dev_node_t *node = NULL;
if(deviceCode == NULL || strlen(deviceCode) <=0){
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
INFO_PRINT("dm_mgr_subdev_delete deviceCode:%s\n",deviceCode);
res = kk_subDev_delete_by_dcode(deviceCode);//delete sub db data
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
res = kk_property_delete_by_dcode(deviceCode);//delete properties db data
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
res = dm_mgr_get_device_by_devicecode(deviceCode,&node);
if (res != SUCCESS_RETURN) {
ERROR_PRINT("ERROR [%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
if(node->dev_type == KK_DM_DEVICE_CCU){
ERROR_PRINT("ERROR [%s][%d]\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
list_del(&node->linked_list);
if (node->dev_shadow) {
kk_tsl_destroy(&node->dev_shadow);
}
free(node);
node = NULL;
return SUCCESS_RETURN;
}
...@@ -321,7 +321,7 @@ const char DM_MSG_COMBINE_STATUS_ONLINE[] DM_READ_ONLY = ...@@ -321,7 +321,7 @@ const char DM_MSG_COMBINE_STATUS_ONLINE[] DM_READ_ONLY =
} }
/* TimeStamp */ /* TimeStamp */
HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%llu", (unsigned long long)HAL_GetTimeMs()); HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
/* dm_log_debug("Time Stamp: %s", timestamp); */ /* dm_log_debug("Time Stamp: %s", timestamp); */
...@@ -365,7 +365,7 @@ int dm_msg_status_offline(_IN_ char productCode[PRODUCT_CODE_MAXLEN], ...@@ -365,7 +365,7 @@ int dm_msg_status_offline(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
} }
/* TimeStamp */ /* TimeStamp */
HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%llu", (unsigned long long)HAL_GetTimeMs()); HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
/* dm_log_debug("Time Stamp: %s", timestamp); */ /* dm_log_debug("Time Stamp: %s", timestamp); */
...@@ -411,7 +411,7 @@ int dm_msg_combine_login(_IN_ char productCode[PRODUCT_CODE_MAXLEN], ...@@ -411,7 +411,7 @@ int dm_msg_combine_login(_IN_ char productCode[PRODUCT_CODE_MAXLEN],
} }
/* TimeStamp */ /* TimeStamp */
HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%llu", (unsigned long long)HAL_GetTimeMs()); HAL_Snprintf(timestamp, DM_UTILS_UINT64_STRLEN, "%d", HAL_GetTime());
/* dm_log_debug("Time Stamp: %s", timestamp); */ /* dm_log_debug("Time Stamp: %s", timestamp); */
/* Client ID */ /* Client ID */
...@@ -548,7 +548,7 @@ int dm_msg_request (_IN_ dm_msg_request_t *request,_IN_ int isAsync) ...@@ -548,7 +548,7 @@ int dm_msg_request (_IN_ dm_msg_request_t *request,_IN_ int isAsync)
} }
memset(payload, 0, payload_len); memset(payload, 0, payload_len);
snprintf(payload, payload_len, DM_MSG_REQUEST, request->msgid, snprintf(payload, payload_len, DM_MSG_REQUEST, request->msgid,
DM_MSG_VERSION, request->params,HAL_GetTimeMs(), request->method); DM_MSG_VERSION, request->params,HAL_GetTime(), request->method);
req_info_len = strlen(DM_MSG_INFO)+10+strlen(request->productCode)+strlen(request->deviceCode)+strlen(request->msgTypeStr)+1; req_info_len = strlen(DM_MSG_INFO)+10+strlen(request->productCode)+strlen(request->deviceCode)+strlen(request->msgTypeStr)+1;
req_info = malloc(req_info_len); req_info = malloc(req_info_len);
...@@ -738,11 +738,78 @@ int dm_msg_thing_property_set_reply(char deviceCode[DEVICE_CODE_MAXLEN],char *pa ...@@ -738,11 +738,78 @@ int dm_msg_thing_property_set_reply(char deviceCode[DEVICE_CODE_MAXLEN],char *pa
dm_msg_response(&request, &response, "{}", strlen("{}"), NULL); dm_msg_response(&request, &response, "{}", strlen("{}"), NULL);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int dm_msg_thing_event_post(const char *deviceCode, const char *identifier)
{
int res = 0;
int nums = 0;
int idx = 0;
char *payload = NULL;
dm_mgr_dev_node_t *node = NULL;
void *event = NULL;
char *method = NULL;
if(deviceCode == NULL){
return FAIL_RETURN;
}
res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
payload = kk_tsl_get_post_event_str(node->dev_shadow,identifier,strlen(identifier));
if(payload != NULL){
res = kk_tsl_get_event_by_identifier(node->dev_shadow, identifier, &event);
if (res != SUCCESS_RETURN) {
free(payload);
return FAIL_RETURN;
}
res = kk_tsl_get_event_method(event, &method);
if (res != SUCCESS_RETURN) {
free(payload);
return FAIL_RETURN;
}
dm_mgr_upstream_thing_event_post(node->devid, identifier, strlen(identifier), method, payload, strlen(payload));
free(method);
method = NULL;
free(payload);
payload = NULL;
}
return SUCCESS_RETURN;
}
int dm_msg_thing_service_post(const char *deviceCode, const char *identifier,int response_id,int code)
{
int res = 0;
int nums = 0;
int idx = 0;
char *payload = NULL;
dm_mgr_dev_node_t *node = NULL;
if(deviceCode == NULL){
return FAIL_RETURN;
}
res = dm_mgr_get_device_by_devicecode(deviceCode, &node);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN;
}
payload = kk_tsl_get_post_service_str(node->dev_shadow,identifier);
if(payload != NULL){
dm_mgr_deprecated_upstream_thing_service_response(node->devid,response_id,code, identifier, strlen(identifier), payload, strlen(payload));
free(payload);
payload = NULL;
}
return SUCCESS_RETURN;
}
int dm_msg_thing_property_post_all(char *deviceCode) int dm_msg_thing_property_post_all(char *deviceCode)
{ {
int res = 0; int res = 0;
int nums = 0; int nums = 0;
int idx = 0; int idx = 0;
char *payload = NULL;
dm_mgr_dev_node_t *node = NULL; dm_mgr_dev_node_t *node = NULL;
if(deviceCode == NULL){ if(deviceCode == NULL){
...@@ -753,7 +820,12 @@ int dm_msg_thing_property_post_all(char *deviceCode) ...@@ -753,7 +820,12 @@ int dm_msg_thing_property_post_all(char *deviceCode)
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
kk_tsl_post_property(node->devid,NULL,1);//here need async post payload = kk_tsl_get_post_property_str(node->dev_shadow,NULL);//here need async post
if(payload != NULL){
dm_mgr_upstream_thing_property_post(node->devid, payload, strlen(payload),1);
free(payload);
payload = NULL;
}
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
...@@ -784,7 +856,6 @@ int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params) ...@@ -784,7 +856,6 @@ int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params)
} }
propertyItem = cJSON_GetObjectItem(params, property->identifier); propertyItem = cJSON_GetObjectItem(params, property->identifier);
if(propertyItem != NULL){ if(propertyItem != NULL){
//kk_tsl_post_property(node->devid,property->identifier,0);
/*update the db data */ /*update the db data */
if(property->data_value.type == KK_TSL_DATA_TYPE_INT || if(property->data_value.type == KK_TSL_DATA_TYPE_INT ||
...@@ -805,7 +876,83 @@ int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params) ...@@ -805,7 +876,83 @@ int dm_msg_thing_property_post_by_identify(char *deviceCode,cJSON *params)
property->data_value.type == KK_TSL_DATA_TYPE_DATE){ property->data_value.type == KK_TSL_DATA_TYPE_DATE){
kk_property_db_update_value(deviceCode,property->identifier,property->data_value.value); kk_property_db_update_value(deviceCode,property->identifier,property->data_value.value);
} }
else if(property->data_value.type == KK_TSL_DATA_TYPE_STRUCT){
kk_tsl_data_value_complex_t *complex_struct = NULL;
int index = 0;
kk_tsl_data_t *current_data = NULL;
cJSON *propertyItem_1 = NULL;
char tmp_identifiers[256] = {0};
complex_struct = property->data_value.value;
for (index = 0; index < complex_struct->size; index++) {
current_data = (kk_tsl_data_t *)complex_struct->value + index;
propertyItem_1 = cJSON_GetObjectItem(propertyItem, current_data->identifier);
if(propertyItem_1 != NULL){
memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
sprintf(tmp_identifiers,"%s.%s",property->identifier,current_data->identifier);
if(current_data->data_value.type == KK_TSL_DATA_TYPE_INT ||
current_data->data_value.type == KK_TSL_DATA_TYPE_ENUM||
current_data->data_value.type == KK_TSL_DATA_TYPE_BOOL){
sprintf(tmpValue,"%d",current_data->data_value.value_int);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
sprintf(tmpValue,"%d",current_data->data_value.value_float);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
sprintf(tmpValue,"%d",current_data->data_value.value_double);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data->data_value.type == KK_TSL_DATA_TYPE_TEXT||
current_data->data_value.type == KK_TSL_DATA_TYPE_DATE){
kk_property_db_update_value(deviceCode,tmp_identifiers,current_data->data_value.value);
}
else if(current_data->data_value.type == KK_TSL_DATA_TYPE_STRUCT){
kk_tsl_data_value_complex_t *complex_struct_1 = NULL;
complex_struct_1 = current_data->data_value.value;
int index1 = 0;
kk_tsl_data_t *current_data_1 = NULL;
cJSON *propertyItem_2 = NULL;
for(index1 = 0; index1 < complex_struct_1->size; index1++){
current_data_1 = (kk_tsl_data_t *)complex_struct_1->value + index1;
propertyItem_2 = cJSON_GetObjectItem(propertyItem_1, current_data_1->identifier);
if(propertyItem_2 != NULL){
memset(tmp_identifiers,0x0,sizeof(tmp_identifiers));
sprintf(tmp_identifiers,"%s.%s.%s",property->identifier,current_data->identifier,current_data_1->identifier);
if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_INT ||
current_data_1->data_value.type == KK_TSL_DATA_TYPE_ENUM||
current_data_1->data_value.type == KK_TSL_DATA_TYPE_BOOL){
sprintf(tmpValue,"%d",current_data_1->data_value.value_int);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_FLOAT){
sprintf(tmpValue,"%d",current_data_1->data_value.value_float);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_DOUBLE){
sprintf(tmpValue,"%d",current_data_1->data_value.value_double);
kk_property_db_update_value(deviceCode,tmp_identifiers,tmpValue);
}
else if(current_data_1->data_value.type == KK_TSL_DATA_TYPE_TEXT||
current_data_1->data_value.type == KK_TSL_DATA_TYPE_DATE){
kk_property_db_update_value(deviceCode,tmp_identifiers,current_data_1->data_value.value);
}
else{
ERROR_PRINT("Unsupport Type ~~\n");
}
}
}
}
else{
ERROR_PRINT("Unsupport Type\n");
}
}
}
}
else{ else{
ERROR_PRINT("Unkonwn Number Type"); ERROR_PRINT("Unkonwn Number Type");
} }
......
...@@ -46,11 +46,13 @@ const char DM_MSG_INFO[] DM_READ_ONLY; ...@@ -46,11 +46,13 @@ const char DM_MSG_INFO[] DM_READ_ONLY;
#define KK_LOGIN_TOPIC_REPLY "/thing/combine/login_reply" #define KK_LOGIN_TOPIC_REPLY "/thing/combine/login_reply"
#define KK_ONLINE_TOPIC_REPLY "/thing/status/online_reply" #define KK_ONLINE_TOPIC_REPLY "/thing/status/online_reply"
#define KK_THING_SERVICE_PROPERTY_SET "/thing/service/property/set" #define KK_THING_SERVICE_PROPERTY_SET "/thing/service/property/set"
#define KK_THING_SERVICE_PROPERTY_GET "/thing/service/property/get"
#define KK_THING_OTA_DEVICE_UPGRADE "/ota/device/upgrade" #define KK_THING_OTA_DEVICE_UPGRADE "/ota/device/upgrade"
#define KK_THING_CLOUDSTATE_MSG "/thing/ccu/cloudstate_reply" #define KK_THING_CLOUDSTATE_MSG "/thing/ccu/cloudstate_reply"
#define KK_THING_TOPO_ADD_MSG "/thing/topo/add" #define KK_THING_TOPO_ADD_MSG "/thing/topo/add"
#define KK_THING_PROPERTY_POST "property/post" #define KK_THING_PROPERTY_POST "property/post"
#define KK_THING_TOPO_DELETE_MSG "/thing/topo/delete" #define KK_THING_TOPO_DELETE_MSG "/thing/topo/delete"
#define KK_THING_TOPO_CHANGE_MSG "/thing/topo/change"
//const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/"; //const char DM_URI_SYS_PREFIX[] DM_READ_ONLY = "/sys/%s/%s/";
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -327,11 +327,12 @@ int kk_property_sync_values(const char *deviceCode) ...@@ -327,11 +327,12 @@ int kk_property_sync_values(const char *deviceCode)
char *pIdentifier = NULL; char *pIdentifier = NULL;
char *valueStr = NULL; char *valueStr = NULL;
int valueType = 0; int valueType = 0;
int devId = 0;
kk_property_db_ctx_t *ctx = _kk_property_db_get_ctx(); kk_property_db_ctx_t *ctx = _kk_property_db_get_ctx();
char *searchCmd = "select * from PropertiesInfo;"; char *searchCmd = "select * from PropertiesInfo;";
dm_mgr_dev_node_t *node = NULL;
dm_mgr_get_devId_by_devicecode(deviceCode,&devId); dm_mgr_get_device_by_devicecode(deviceCode,&node);
sqlCmd = sqlite3_mprintf(searchCmd,deviceCode); sqlCmd = sqlite3_mprintf(searchCmd,deviceCode);
...@@ -350,18 +351,18 @@ int kk_property_sync_values(const char *deviceCode) ...@@ -350,18 +351,18 @@ int kk_property_sync_values(const char *deviceCode)
valueType == KK_TSL_DATA_TYPE_ENUM|| valueType == KK_TSL_DATA_TYPE_ENUM||
valueType == KK_TSL_DATA_TYPE_BOOL){ valueType == KK_TSL_DATA_TYPE_BOOL){
int value_int = atoi(valueStr); int value_int = atoi(valueStr);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,pIdentifier,&value_int,NULL); res = kk_tsl_set_value(kk_tsl_set_property_value,node->dev_shadow,pIdentifier,&value_int,NULL);
} }
else if(valueType == KK_TSL_DATA_TYPE_FLOAT){ else if(valueType == KK_TSL_DATA_TYPE_FLOAT){
float value_float = atoi(valueStr); float value_float = atoi(valueStr);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,pIdentifier,&value_float,NULL); res = kk_tsl_set_value(kk_tsl_set_property_value,node->dev_shadow,pIdentifier,&value_float,NULL);
} }
else if(valueType == KK_TSL_DATA_TYPE_DOUBLE){ else if(valueType == KK_TSL_DATA_TYPE_DOUBLE){
double value_double = atoi(valueStr); double value_double = atoi(valueStr);
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,pIdentifier,&value_double,NULL); res = kk_tsl_set_value(kk_tsl_set_property_value,node->dev_shadow,pIdentifier,&value_double,NULL);
} }
else{ else{
res = kk_tsl_set_value(kk_tsl_set_property_value,devId,pIdentifier,NULL,valueStr); res = kk_tsl_set_value(kk_tsl_set_property_value,node->dev_shadow,pIdentifier,NULL,valueStr);
} }
if(res != SUCCESS_RETURN) if(res != SUCCESS_RETURN)
{ {
...@@ -401,5 +402,28 @@ int kk_property_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN]) ...@@ -401,5 +402,28 @@ int kk_property_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN])
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int kk_property_delete_by_identify(char *identify)
{
const char *deleteCmd = "delete from PropertiesInfo where identifier = '%s';";
char *sqlCmd = NULL;
int rc = 0;
char *zErrMsg = 0;
kk_property_db_ctx_t *ctx = _kk_property_db_get_ctx();
_kk_property_db_lock();
sqlCmd = sqlite3_mprintf(deleteCmd,identify);
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_property_db_unlock();
return SUCCESS_RETURN;
}
......
#include <stdio.h>
#include "kk_tsl_api.h"
#include "kk_wlist_mng.h"
#include "sqlite3.h"
#include "kk_log.h"
#define KK_TSL_GATAWAY_ADDWHITELIST_IDENTIFIER "addWhiteList"
#define KK_TSL_GATAWAY_WHITELISTDEVICE_IDENTIFIER "Devices"
#define KK_TSL_GATAWAY_WHITELISTMAC_IDENTIFIER "getWhiteListNotification.Devices[%d].MACAddress"
#define KK_TSL_GATAWAY_WHITELISTPRODUCTID_IDENTIFIER "getWhiteListNotification.Devices[%d].ProductId"
#define KK_TSL_GATAWAY_WHITELISTSN_IDENTIFIER "getWhiteListNotification.Devices[%d].SN"
#define KK_TSL_GATAWAY_WHITELISTDEVICEID_IDENTIFIER "getWhiteListNotification.Devices[%d].deviceId"
#define KK_WLIST_DB_FILE "wlist.db"
typedef struct {
void *mutex;
int isOpened;
int isInited;
int wlistNum;
sqlite3 *pDb;
} kk_wlist_ctx_t;
static kk_wlist_ctx_t s_kk_wlist_ctx = {NULL,0,0,NULL};
static kk_wlist_ctx_t *_kk_wlist_get_ctx(void)
{
return &s_kk_wlist_ctx;
}
static void _kk_wlist_lock(void)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if (ctx->mutex) {
HAL_MutexLock(ctx->mutex);
}
}
static void _kk_wlist_unlock(void)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if (ctx->mutex) {
HAL_MutexUnlock(ctx->mutex);
}
}
static int kk_wlist_db_Init(void)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
//eUtils_LockLock(&sLock);
_kk_wlist_lock();
if (sqlite3_open_v2(KK_WLIST_DB_FILE, &ctx->pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL) != SQLITE_OK)
{
ERROR_PRINT("Error initialising linkage database (%s)", sqlite3_errmsg(ctx->pDb));
_kk_wlist_unlock();
return FAIL_RETURN;
}
INFO_PRINT("wlist Database opened\n");
{
const char *pwListTable = "CREATE TABLE IF NOT EXISTS WhiteList(idx INTEGER, deviceMac varchar(17),productId varchar(33), deviceSN varchar(33), deviceId varchar(33))";
char *pcErr;
// DBG_vPrintf(DBG_SQL, "Execute SQL: '%s'\n", pConditionTableDef);
if (sqlite3_exec(ctx->pDb, pwListTable, NULL, NULL, &pcErr) != SQLITE_OK)
{
ERROR_PRINT("Error creating table (%s)\n", pcErr);
sqlite3_free(pcErr);
//eUtils_LockUnlock(&sLock);
_kk_wlist_unlock();
return FAIL_RETURN;
}
}
//eUtils_LockUnlock(&sLock);
_kk_wlist_unlock();
return SUCCESS_RETURN;
}
static int _kk_check_exist(const char* device_mac)
{
int isExist = 0;
sqlite3_stmt *stmt;
char *pmac = NULL;
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
const char *searchCmd = "select * from WhiteList;";
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 = sqlite3_column_text(stmt, 1);
if(!strcmp(device_mac,pmac))
{
isExist = 1;
break;
}
}
INFO_PRINT("\n");
sqlite3_finalize(stmt);
return isExist;
}
static int kk_wlist_insert_db(int index,char device_mac[DEVICE_MAC_MAXLEN],char product_Id[PRODUCT_CODE_MAXLEN], \
char device_SN[DEVICE_SN_MAXLEN],char device_Id[DEVICE_CODE_MAXLEN])
{
const char *insertCmd = "insert into WhiteList (idx, deviceMac, productId,deviceSN,deviceId) values ('%d', '%s', '%s','%s','%s');";
char *sqlCmd = NULL;
int rc = 0;
char *zErrMsg = 0;
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
_kk_wlist_lock();
sqlCmd = sqlite3_mprintf(insertCmd, index,device_mac,product_Id,device_SN,device_Id);
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 insert data successfully\n");
}
sqlite3_free(sqlCmd);
_kk_wlist_unlock();
return SUCCESS_RETURN;
}
static int _kk_wlist_delete_db_byMac(char device_mac[DEVICE_MAC_MAXLEN])
{
const char *deleteCmd = "delete from WhiteList where deviceMac = %s;";
char *sqlCmd = NULL;
int rc = 0;
char *zErrMsg = 0;
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
_kk_wlist_lock();
sqlCmd = sqlite3_mprintf( deleteCmd,device_mac);
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_wlist_unlock();
return SUCCESS_RETURN;
}
int kk_wlist_status_open(int isOpen)
{
int res = 0;
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if(ctx->isOpened)
{
printf("[%s][%d] ALREADY OPENED\n",__FUNCTION__,__LINE__,res);
return SUCCESS_RETURN;
}
res = kk_tsl_set_value(kk_tsl_set_property_value,0,KK_TSL_GATAWAY_WHITELIST_IDENTIFIER,&isOpen,NULL);
if(res != SUCCESS_RETURN){
ERROR_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
ctx->isOpened = isOpen;
if(ctx->isOpened){
kk_wlist_init();
}
return SUCCESS_RETURN;
}
int kk_load_wlist(void)
{
const char *searchCmd = "select * from WhiteList;";
sqlite3_stmt *stmt;
char *pmac = NULL,*pPID = NULL,*pSN = NULL,pDID = NULL;
kk_wlist_dev_t wlist = {0};
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if(ctx->isOpened != 1){
return FAIL_RETURN;
}
sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
INFO_PRINT("kk_load_wlist total_column = %d\n", sqlite3_column_count(stmt));
while(sqlite3_step(stmt) == SQLITE_ROW){
memset(&wlist,0x0,sizeof(kk_wlist_dev_t));
strcpy(wlist.device_mac,sqlite3_column_text(stmt, 1));
strcpy(wlist.product_id,sqlite3_column_text(stmt, 2));
strcpy(wlist.device_sn,sqlite3_column_text(stmt, 3));
strcpy(wlist.device_id,sqlite3_column_text(stmt, 4));
// kk_add_wlist(&wlist);
kk_set_wlist_byIdx(ctx->wlistNum,&wlist);
ctx->wlistNum++;
}
sqlite3_finalize(stmt);
return SUCCESS_RETURN;
}
int kk_wlist_init(void)
{
int res = 0;
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if(ctx->isInited)
{
return SUCCESS_RETURN;
}
/* Create Mutex */
ctx->mutex = HAL_MutexCreate();
if (ctx->mutex == NULL) {
return FAIL_RETURN;
}
res = kk_wlist_db_Init();
if(res != SUCCESS_RETURN){
ERROR_PRINT("[%s][%d]kk_wlist_db_Init FAIL!!!\n",__FUNCTION__,__LINE__);
}
kk_load_wlist();
ctx->isInited = 1;
return SUCCESS_RETURN;
}
int kk_set_wlist_byIdx(int idx,kk_wlist_dev_t * wlist_dev)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
int res = 0;
char identifier_name[64] = {0};
if(wlist_dev == NULL)
{
ERROR_PRINT("[%s][%d] wlist_dev == NULL!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
_kk_wlist_lock();
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTMAC_IDENTIFIER,idx);
res = kk_tsl_set_value(kk_tsl_set_event_output_value,0,identifier_name,NULL,wlist_dev->device_mac);
if(res != SUCCESS_RETURN){
goto fail_return;
}
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTPRODUCTID_IDENTIFIER,idx);
res = kk_tsl_set_value(kk_tsl_set_event_output_value,0,identifier_name,NULL,wlist_dev->product_id);
if(res != SUCCESS_RETURN){
goto fail_return;
}
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTSN_IDENTIFIER,idx);
res = kk_tsl_set_value(kk_tsl_set_event_output_value,0,identifier_name,NULL,wlist_dev->device_sn);
if(res != SUCCESS_RETURN){
goto fail_return;
}
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTDEVICEID_IDENTIFIER,idx);
res = kk_tsl_set_value(kk_tsl_set_event_output_value,0,identifier_name,NULL,wlist_dev->device_id);
if(res != SUCCESS_RETURN){
goto fail_return;
}
_kk_wlist_unlock();
return SUCCESS_RETURN;
fail_return:
_kk_wlist_unlock();
INFO_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
int kk_add_wlist(kk_wlist_dev_t *wlist_dev)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
int res = 0;
if(ctx->isOpened != 1){
ERROR_PRINT("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
if(ctx->wlistNum >= 512){
ERROR_PRINT("[%s][%d] WHITELIST FULL!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
if(wlist_dev == NULL){
ERROR_PRINT("[%s][%d] wlist_dev == NULL!!!\n",__FUNCTION__,__LINE__);
return INVALID_PARAMETER;
}
if(_kk_check_exist(wlist_dev->device_mac) == 1)
{
ERROR_PRINT("[%s][%d] DATA ALREADY EXIST!!!\n",__FUNCTION__,__LINE__);
return SUCCESS_RETURN;
}
res = kk_wlist_insert_db(ctx->wlistNum,wlist_dev->device_mac,wlist_dev->product_id,wlist_dev->device_sn,wlist_dev->device_id);
res |= kk_set_wlist_byIdx(ctx->wlistNum,wlist_dev);
ctx->wlistNum++;
return res;
}
int kk_get_wlist_num(void)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
if(ctx->isOpened != 1)
{
ERROR_PRINT("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
return ctx->wlistNum;
}
int kk_getwlist_ByIdx(int idx,kk_wlist_dev_t* wlist_dev)
{
char *macs = NULL;
char *PID = NULL;
char *DID = NULL;
char *SN = NULL;
char identifier_name[64] = {0};
int res = 0;
_kk_wlist_lock();
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTMAC_IDENTIFIER,idx);
res = kk_tsl_get_value(kk_tsl_get_event_output_value,0,identifier_name,NULL,&macs);
if(res != SUCCESS_RETURN){
goto fail_return;
}
strcpy(wlist_dev->device_mac,macs);
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTPRODUCTID_IDENTIFIER,idx);
res = kk_tsl_get_value(kk_tsl_get_event_output_value,0,identifier_name,NULL,&PID);
if(res != SUCCESS_RETURN){
goto fail_return;
}
strcpy(wlist_dev->product_id,PID);
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTSN_IDENTIFIER,idx);
res = kk_tsl_get_value(kk_tsl_get_event_output_value,0,identifier_name,NULL,&SN);
if(res != SUCCESS_RETURN){
goto fail_return;
}
strcpy(wlist_dev->device_sn,SN);
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTDEVICEID_IDENTIFIER,idx);
res = kk_tsl_get_value(kk_tsl_get_event_output_value,0,identifier_name,NULL,&DID);
if(res != SUCCESS_RETURN){
goto fail_return;
}
strcpy(wlist_dev->device_id,DID);
_kk_wlist_unlock();
return SUCCESS_RETURN;
fail_return:
_kk_wlist_unlock();
INFO_PRINT("[%s][%d] res:%d\n",__FUNCTION__,__LINE__,res);
return FAIL_RETURN;
}
int kk_get_wlistIdx_byMac(const char* device_mac)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
int res = 0;
char *pmac = NULL;
char identifier_name[64] = {0};
int idx = 0,findIdx = 0;
if(ctx->isOpened != 1)
{
ERROR_PRINT("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
if(idx >= 512)
{
ERROR_PRINT("[%s][%d]Invalid idx!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
_kk_wlist_lock();
for(idx = 0; idx < ctx->wlistNum;idx++)
{
memset(identifier_name,0x0,sizeof(identifier_name));
sprintf(identifier_name,KK_TSL_GATAWAY_WHITELISTMAC_IDENTIFIER,idx);
res = kk_tsl_get_value(kk_tsl_get_event_output_value,0,identifier_name,NULL,&pmac);
if(res != SUCCESS_RETURN){
continue;
}
if(!strcmp(device_mac,pmac))
{
findIdx = idx;
ERROR_PRINT("[%s][%d]find the delete index\n",__FUNCTION__,__LINE__);
_kk_wlist_unlock();
return findIdx;
}
}
if(idx == ctx->wlistNum)
{
_kk_wlist_unlock();
return TSL_EVENT_NOT_EXIST;
}
_kk_wlist_unlock();
return FAIL_RETURN;
}
static int _kk_delete_wlist_byIdx(int idx)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
int res = 0;
kk_wlist_dev_t dWlist = {0};
if(idx >= 512)
{
ERROR_PRINT("[%s][%d]Invalid idx!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
strcpy(dWlist.product_id,"");
strcpy(dWlist.device_mac,"");
strcpy(dWlist.device_sn,"");
strcpy(dWlist.device_id,"");
res = kk_set_wlist_byIdx(idx,&dWlist);
return res;
}
int kk_delete_wlist_byMac(const char* device_mac)
{
kk_wlist_ctx_t *ctx = _kk_wlist_get_ctx();
char identifier_name[64] = {0};
int res;
int idx = 0;
char *pmac = NULL;
int findIdx = 0;
if(ctx->isOpened != 1)
{
ERROR_PRINT("[%s][%d] PLEASE OPNE THE WHITELIST FUNCTION FIRST!!!\n",__FUNCTION__,__LINE__);
return FAIL_RETURN;
}
findIdx = kk_get_wlistIdx_byMac(device_mac);
if(findIdx < 0)
{
return FAIL_RETURN;
}
res = _kk_delete_wlist_byIdx(findIdx);
res |= _kk_wlist_delete_db_byMac(device_mac);
if(res != SUCCESS_RETURN)
{
return FAIL_RETURN;
}
ctx->wlistNum--;
return SUCCESS_RETURN;
}
#ifndef __KK_WHITELIST_MNG_H__
#define __KK_WHITELIST_MNG_H__
#include "kk_tsl_common.h"
typedef struct {
char device_mac[DEVICE_MAC_MAXLEN];
char product_id[PRODUCT_TYPE_MAXLEN];
char device_sn[DEVICE_SN_MAXLEN];
char device_id[DEVICE_CODE_MAXLEN];
int index;
} kk_wlist_dev_t;
int kk_wlist_init(void);
int kk_wlist_status_open(int isOpen);
int kk_add_wlist(kk_wlist_dev_t *wlist_dev);
int kk_get_wlist_num(void);
int kk_delete_wlist_byMac(const char* device_mac);
#endif
\ No newline at end of file
LIBA_TARGET := libmid.a LIBA_TARGET := libmid.a
$(call Append_Conditional, LIB_SRCS_EXCLUDE, midware.c) $(call Append_Conditional, LIB_SRCS_EXCLUDE, midware.c)
$(call Append_Conditional, SRCS_midware, midware.c) $(call Append_Conditional, SRCS_kk_midware, midware.c)
$(call Append_Conditional, TARGET, midware) $(call Append_Conditional, TARGET, kk_midware)
CFLAGS += -I$(TOP_DIR)/common/nanomsg/include CFLAGS += -I$(TOP_DIR)/common/nanomsg/include
CFLAGS += -I$(TOP_DIR)/common/ev/include CFLAGS += -I$(TOP_DIR)/common/ev/include
...@@ -11,7 +11,7 @@ CFLAGS += -I$(TOP_DIR)/common/sqlite ...@@ -11,7 +11,7 @@ CFLAGS += -I$(TOP_DIR)/common/sqlite
CFLAGS += -I$(TOP_DIR)/common/zlog CFLAGS += -I$(TOP_DIR)/common/zlog
CFLAGS += -I$(TOP_DIR)/src/tsl/tsl_handle CFLAGS += -I$(TOP_DIR)/src/tsl/tsl_handle
LDFLAGS += -lapi_com -liot_cjson -lkk_tsl LDFLAGS += -lapi_com -liot_cjson -lkk_tsl
LDFLAGS += -lm -lkk_hal -lzlog LDFLAGS += -lm -lkk_hal
LDFLAGS += -lsqlite -ldl LDFLAGS += -lsqlite -ldl
ifeq ($(CONFIG_VENDOR),ubuntu) ifeq ($(CONFIG_VENDOR),ubuntu)
LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg_ubuntu -lanl LDFLAGS += -L$(TOP_DIR)/common/nanomsg -lnanomsg_ubuntu -lanl
......
...@@ -27,8 +27,8 @@ char * g_filerToPlatTable[] = ...@@ -27,8 +27,8 @@ char * g_filerToPlatTable[] =
{KK_REGISTER_TOPIC_REPLY}, {KK_REGISTER_TOPIC_REPLY},
{KK_ADD_TOPIC_REPLY}, {KK_ADD_TOPIC_REPLY},
{KK_LOGIN_TOPIC_REPLY}, {KK_LOGIN_TOPIC_REPLY},
{KK_THING_OTA_DEVICE_UPGRADE}, {KK_THING_SERVICE_PROPERTY_GET},
{KK_THING_CLOUDSTATE_MSG}, {KK_THING_CLOUDSTATE_MSG},
}; };
static int _kk_filter_to_plat(const char* msgtype) static int _kk_filter_to_plat(const char* msgtype)
...@@ -61,38 +61,42 @@ void kk_sendData2gw(void* data, int len, char* chalMark){ ...@@ -61,38 +61,42 @@ void kk_sendData2gw(void* data, int len, char* chalMark){
void mid_cb(void* data, int len){ void mid_cb(void* data, int len){
if (data != NULL){ if (data != NULL){
char *out;
cJSON *json; cJSON *json;
cJSON *info_root,*info,*type; cJSON *info_root,*type;
cJSON*payload;
cJSON*deviceCode; cJSON*deviceCode;
int res; int res;
void* buf = malloc(len);
memcpy(buf, data, len);
res = dm_queue_msg_insert((void *)buf);
if (res != SUCCESS_RETURN) {
free(buf);
//return FAIL_RETURN;
}
json=cJSON_Parse(data); json=cJSON_Parse(data);
if (!json) { if (!json) {
printf("Error before: [%s]\n","cJSON_Parse"); ERROR_PRINT("Error before: [%s]\n","cJSON_Parse");
} }
else else
{ {
info_root = cJSON_GetObjectItem(json, MSG_INFO_STR); info_root = cJSON_GetObjectItem(json, MSG_INFO_STR);
if (info_root == NULL){
ERROR_PRINT(" params [%s] can't find \n",MSG_INFO_STR);
cJSON_Delete(json);
return;
}
deviceCode = cJSON_GetObjectItem(info_root, MSG_DEVICE_CODE_STR); deviceCode = cJSON_GetObjectItem(info_root, MSG_DEVICE_CODE_STR);
type = cJSON_GetObjectItem(info_root, MSG_TYPE_STR); type = cJSON_GetObjectItem(info_root, MSG_TYPE_STR);
if(_kk_filter_to_plat(type->valuestring)){ if (deviceCode == NULL || type == NULL){
cJSON_Delete(json); ERROR_PRINT(" params [%s] or [%s] can't find \n",MSG_DEVICE_CODE_STR, MSG_TYPE_STR);
cJSON_Delete(info); cJSON_Delete(json);
return; return;
} }
int devType = 0; int devType = 0;
dm_mgr_get_devicetype_by_devicecode(deviceCode->valuestring,&devType); dm_mgr_get_devicetype_by_devicecode(deviceCode->valuestring,&devType);
if(devType == KK_DM_DEVICE_GATEWAY){ //主机的device或过滤的
if(devType == KK_DM_DEVICE_CCU ||_kk_filter_to_plat(type->valuestring)){
void* buf = malloc(len);
memcpy(buf, data, len);
res = dm_queue_msg_insert((void *)buf);
if (res != SUCCESS_RETURN) {
free(buf);
}
}else if(devType == KK_DM_DEVICE_GATEWAY){
kk_sendData2gw(data, strlen(data), deviceCode->valuestring);//send to gw itself kk_sendData2gw(data, strlen(data), deviceCode->valuestring);//send to gw itself
}else if(devType == KK_DM_DEVICE_SUBDEV){ }else if(devType == KK_DM_DEVICE_SUBDEV){
dm_mgr_dev_node_t *gw_node = NULL; dm_mgr_dev_node_t *gw_node = NULL;
...@@ -100,7 +104,6 @@ void mid_cb(void* data, int len){ ...@@ -100,7 +104,6 @@ void mid_cb(void* data, int len){
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
ERROR_PRINT("res:%d\n",res); ERROR_PRINT("res:%d\n",res);
cJSON_Delete(json); cJSON_Delete(json);
cJSON_Delete(info);
return; return;
} }
kk_sendData2gw(data, strlen(data), gw_node->fatherDeviceCode);//send to sub device kk_sendData2gw(data, strlen(data), gw_node->fatherDeviceCode);//send to sub device
...@@ -109,7 +112,6 @@ void mid_cb(void* data, int len){ ...@@ -109,7 +112,6 @@ void mid_cb(void* data, int len){
ERROR_PRINT("wrong type\n"); ERROR_PRINT("wrong type\n");
} }
cJSON_Delete(json); cJSON_Delete(json);
cJSON_Delete(info);
} }
} }
...@@ -221,7 +223,9 @@ void kk_platMsg_handle(void* data, char* chalMark){ ...@@ -221,7 +223,9 @@ void kk_platMsg_handle(void* data, char* chalMark){
}else if (strstr(msgType->valuestring, KK_THING_PROPERTY_POST) != NULL){ }else if (strstr(msgType->valuestring, KK_THING_PROPERTY_POST) != NULL){
INFO_PRINT("save property and send to cloud \n"); INFO_PRINT("save property and send to cloud \n");
char* outstr = cJSON_Print(payload); char* outstr = cJSON_Print(payload);
kk_tsl_property_set_by_devicecode(info_dcode->valuestring, outstr, strlen(outstr)+1); 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_msg_thing_property_post_by_identify(info_dcode->valuestring,jsonPay); dm_msg_thing_property_post_by_identify(info_dcode->valuestring,jsonPay);
free(outstr); free(outstr);
...@@ -234,7 +238,6 @@ void kk_platMsg_handle(void* data, char* chalMark){ ...@@ -234,7 +238,6 @@ void kk_platMsg_handle(void* data, char* chalMark){
}else{ }else{
INFO_PRINT("kk_platMsg_handle data: don't handle it [%s]\n",data); INFO_PRINT("kk_platMsg_handle data: don't handle it [%s]\n",data);
//kk_tsl_service_property_set(topic->valuestring, payload->valuestring, strlen(payload->valuestring), NULL);
} }
error: error:
cJSON_Delete(json); cJSON_Delete(json);
...@@ -574,10 +577,12 @@ void *ccu_property_monitor(void *args) ...@@ -574,10 +577,12 @@ void *ccu_property_monitor(void *args)
{ {
mid_ctx_t *mid_ctx = kk_mid_get_ctx(); mid_ctx_t *mid_ctx = kk_mid_get_ctx();
char s_IP[NETWORK_ADDR_LEN]; char s_IP[NETWORK_ADDR_LEN];
char *s_IP_TSL = NULL; char s_IP_TSL[NETWORK_ADDR_LEN] = {0};
int res = 0; int res = 0;
int needReport = 0; int needReport = 0;
int time_second = 60; 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) { while (mid_ctx->g_ccuProChg_dispatch_thread_running) {
if(kk_get_cloud_recv_status() == 0){ if(kk_get_cloud_recv_status() == 0){
...@@ -585,23 +590,29 @@ void *ccu_property_monitor(void *args) ...@@ -585,23 +590,29 @@ void *ccu_property_monitor(void *args)
sleep(10); sleep(10);
continue; continue;
} }
//dm_ota_yield(MID_YIELD_TIMEOUT_MS);
HAL_Get_IP(s_IP,NULL); HAL_Get_IP(s_IP,NULL);
res = kk_tsl_get_value(kk_tsl_get_property_value,0,KK_TSL_CCU_WANIP_IDENTIFIER,NULL,&s_IP_TSL); 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){ if(res != SUCCESS_RETURN){
ERROR_PRINT("kk_tsl_get_value Failed\n"); ERROR_PRINT("kk_tsl_get_value Failed\n");
} }
else{ else{
if(strcmp(s_IP,s_IP_TSL)){ if(strcmp(s_IP,s_IP_TSL)){
kk_tsl_set_value(kk_tsl_set_property_value,0,KK_TSL_CCU_WANIP_IDENTIFIER,NULL,s_IP); 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); INFO_PRINT("current ip:%s,before ip:%s\n",s_IP,s_IP_TSL);
kk_property_db_update("CCU_66666"); kk_property_db_update("CCU_66666");
needReport = 1; needReport = 1;
} }
} }
if(needReport&&(kk_get_cloudstatus() == 1)){ if(needReport&&(kk_get_cloudstatus() == 1)){
needReport = 0; needReport = 0;
kk_tsl_post_property(KK_DM_DEVICE_CCU_DEVICEID,NULL,0); char *postStr = kk_tsl_get_post_property_str(node->dev_shadow,NULL);
if(postStr != NULL){
dm_mgr_upstream_thing_property_post(node->devid, postStr, strlen(postStr),0);
free(postStr);
postStr = NULL;
}
} }
sleep(time_second); sleep(time_second);
} }
...@@ -609,14 +620,6 @@ void *ccu_property_monitor(void *args) ...@@ -609,14 +620,6 @@ void *ccu_property_monitor(void *args)
} }
static int kk_set_product_info(void)
{
HAL_SetProduct_Type(PRODUCT_TPYE);
HAL_SetProduct_Code(PRODUCT_CODE);
return 0;
}
int main(const int argc, const char **argv) int main(const int argc, const char **argv)
{ {
...@@ -626,10 +629,9 @@ int main(const int argc, const char **argv) ...@@ -626,10 +629,9 @@ int main(const int argc, const char **argv)
kk_tsl_t *dev_shadow[30] = {NULL}; kk_tsl_t *dev_shadow[30] = {NULL};
mid_ctx_t *mid_ctx = kk_mid_get_ctx(); mid_ctx_t *mid_ctx = kk_mid_get_ctx();
kk_zlog_init("midware"); open("midware",LOG_PID,LOG_USER);
memset(mid_ctx, 0, sizeof(mid_ctx_t)); memset(mid_ctx, 0, sizeof(mid_ctx_t));
kk_set_product_info();
kk_tsl_api_init(); kk_tsl_api_init();
kk_ipc_init(IPC_MID2APP, mid_cb, NULL, NULL); kk_ipc_init(IPC_MID2APP, mid_cb, NULL, NULL);
kk_ipc_init(IPC_MID2PLAT, mid2p_cb, NULL, "*"); kk_ipc_init(IPC_MID2PLAT, mid2p_cb, NULL, "*");
......
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef _TSL_API_H__ #ifndef _TSL_API_H__
#define _TSL_API_H__ #define _TSL_API_H__
#include "lite-cjson.h" #include "lite-cjson.h"
#include "kk_tsl_common.h" #include "kk_tsl_common.h"
#include "../../midware/dm/iotx_dm.h" #include "../../midware/dm/iotx_dm.h"
#define KK_MSG_KEY_ID "msgId" #define KK_MSG_KEY_ID "msgId"
#define KK_MSG_KEY_VERSION "version" #define KK_MSG_KEY_VERSION "version"
#define KK_MSG_KEY_METHOD "method" #define KK_MSG_KEY_METHOD "method"
#define KK_MSG_KEY_PARAMS "params" #define KK_MSG_KEY_PARAMS "params"
#define KK_MSG_KEY_CODE "code" #define KK_MSG_KEY_CODE "code"
#define KK_MSG_KEY_DATA "data" #define KK_MSG_KEY_DATA "data"
#define KK_MSG_KEY_MESSAGE "message" #define KK_MSG_KEY_MESSAGE "message"
/*typedef enum { /*typedef enum {
IOTX_DM_ERR_CODE_SUCCESS = 200, IOTX_DM_ERR_CODE_SUCCESS = 200,
IOTX_DM_ERR_CODE_REQUEST_ERROR = 400, IOTX_DM_ERR_CODE_REQUEST_ERROR = 400,
IOTX_DM_ERR_CODE_REQUEST_PARAMS_ERROR = 460, IOTX_DM_ERR_CODE_REQUEST_PARAMS_ERROR = 460,
IOTX_DM_ERR_CODE_REQUEST_TOO_MANY = 429, IOTX_DM_ERR_CODE_REQUEST_TOO_MANY = 429,
IOTX_DM_ERR_CODE_NO_ACTIVE_SESSION = 520, IOTX_DM_ERR_CODE_NO_ACTIVE_SESSION = 520,
IOTX_DM_ERR_CODE_TIMEOUT = 100000 IOTX_DM_ERR_CODE_TIMEOUT = 100000
} iotx_dm_error_code_t;*/ } iotx_dm_error_code_t;*/
typedef struct { typedef struct {
const char *uri; const char *uri;
unsigned char *payload; unsigned char *payload;
unsigned int payload_len; unsigned int payload_len;
void *context; void *context;
} kk_msg_source_t; } kk_msg_source_t;
typedef struct { typedef struct {
const char *uri_name; const char *uri_name;
} kk_msg_dest_t; } kk_msg_dest_t;
typedef struct { typedef struct {
lite_cjson_t id; lite_cjson_t id;
lite_cjson_t version; lite_cjson_t version;
lite_cjson_t method; lite_cjson_t method;
lite_cjson_t params; lite_cjson_t params;
} kk_msg_request_payload_t; } kk_msg_request_payload_t;
typedef struct { typedef struct {
lite_cjson_t id; lite_cjson_t id;
lite_cjson_t code; lite_cjson_t code;
lite_cjson_t data; lite_cjson_t data;
lite_cjson_t message; lite_cjson_t message;
} kk_msg_response_payload_t; } kk_msg_response_payload_t;
typedef enum { typedef enum {
kk_tsl_set_property_value = 0, kk_tsl_set_property_value = 0,
kk_tsl_set_event_output_value, kk_tsl_set_event_output_value,
kk_tsl_set_service_output_value, kk_tsl_set_service_output_value,
kk_tsl_set_number, kk_tsl_set_number,
} kk_tsl_set_t; } kk_tsl_set_t;
typedef enum { typedef enum {
kk_tsl_get_property_value = 0, kk_tsl_get_property_value = 0,
kk_tsl_get_event_output_value, kk_tsl_get_event_output_value,
kk_tsl_get_service_input_value, kk_tsl_get_service_input_value,
kk_tsl_get_service_output_value, kk_tsl_get_service_output_value,
kk_tsl_get_number, kk_tsl_get_number,
} kk_tsl_get_t; } kk_tsl_get_t;
typedef struct { typedef struct {
int devid; kk_tsl_t * shadow;
lite_cjson_item_t *lite; lite_cjson_item_t *lite;
} dm_api_property_t; } dm_api_property_t;
extern int kk_tsl_api_init(void); extern int kk_tsl_api_init(void);
extern int kk_tsl_set_value(kk_tsl_set_t set, int devId, const char *identifier, \ extern int kk_tsl_set_value(kk_tsl_set_t set, kk_tsl_t *dev_shadow, const char *identifier, \
const void *value, \ const void *value, \
const char *value_str); const char *value_str);
extern int kk_tsl_get_value(kk_tsl_get_t method_get, int devId, const char *identifier, \ extern int kk_tsl_get_value(kk_tsl_get_t method_get, kk_tsl_t * dev_shadow, const char *identifier, \
void *value, \ void *value, \
char **value_str); char **value_str);
extern int kk_msg_uri_parse_pkdn(_IN_ char *uri, _IN_ int uri_len, _IN_ int start_deli, _IN_ int end_deli, \ extern int kk_msg_uri_parse_pkdn(_IN_ char *uri, _IN_ int uri_len, _IN_ int start_deli, _IN_ int end_deli, \
_OU_ char productType[PRODUCT_TYPE_MAXLEN], _OU_ char deviceCode[DEVICE_CODE_MAXLEN]); _OU_ char productType[PRODUCT_TYPE_MAXLEN], _OU_ char deviceCode[DEVICE_CODE_MAXLEN]);
extern int kk_tsl_service_property_set(const char *topic, const char *payload, unsigned int payload_len,
void *context); extern char* kk_tsl_get_post_property_str(kk_tsl_t *dev_shadow, const char *property_identifier);
extern int kk_tsl_post_property(int devId, const char *property_identifier,int isAsync); extern char* kk_tsl_get_post_event_str(_IN_ kk_tsl_t *dev_shadow, _IN_ char *identifier, _IN_ int identifier_len);
extern int kk_tsl_post_event(int devId, const char *event_identifier); extern char * kk_tsl_get_post_service_str(kk_tsl_t *dev_shadow, const char *service_identifier);
extern int kk_tsl_post_service(int devId, const char *service_identifier, int response_id,int code);
#endif #endif
...@@ -4,11 +4,9 @@ ...@@ -4,11 +4,9 @@
#include "kk_tsl_common.h" #include "kk_tsl_common.h"
#include "kk_dm_mng.h" #include "kk_dm_mng.h"
#include "kk_log.h" #include "kk_log.h"
#define TSL_SUBDEVICE_PATH_FILE "/home/kk/tsl/product_%s.json"
#define TSL_GATEWAY_PATH_FILE "/home/kk/tsl/gateway-%s.json"
#define TSL_SUBDEVICE_PATH_FILE "/home/tsl/product_%s.json" #define TSL_CCU_PATH_FILE "/home/kk/tsl/ccu-%s.json"
#define TSL_GATEWAY_PATH_FILE "/home/tsl/gateway-%s.json"
#define TSL_CCU_PATH_FILE "/home/tsl/ccu-%s.json"
char* kk_load_json(const char *productCode,int type) char* kk_load_json(const char *productCode,int type)
{ {
...@@ -48,13 +46,12 @@ char* kk_load_json(const char *productCode,int type) ...@@ -48,13 +46,12 @@ char* kk_load_json(const char *productCode,int type)
INFO_PRINT("\n[%s][%d]tslPath:%s!!!\n",__FUNCTION__,__LINE__,tslPath); INFO_PRINT("\n[%s][%d]tslPath:%s!!!\n",__FUNCTION__,__LINE__,tslPath);
if(!(fp = fopen(tslPath,"a+"))) if(!(fp = fopen(tslPath,"a+")))
{ {
ERROR_PRINT("can't open the file account.txt\n"); ERROR_PRINT("can't open the file tslPath:%s\n",tslPath);
free(tslPath); free(tslPath);
return NULL; return NULL;
} }
fseek(fp, 0L, SEEK_END); fseek(fp, 0L, SEEK_END);
filesize = ftell(fp); filesize = ftell(fp);
INFO_PRINT("filesize :%d\n",filesize);
buf = malloc(filesize+1); buf = malloc(filesize+1);
if(buf == NULL) if(buf == NULL)
{ {
...@@ -68,6 +65,7 @@ char* kk_load_json(const char *productCode,int type) ...@@ -68,6 +65,7 @@ char* kk_load_json(const char *productCode,int type)
fread(buf, 1, filesize, fp); fread(buf, 1, filesize, fp);
//printf("%s!!!\n",buf); //printf("%s!!!\n",buf);
free(tslPath); free(tslPath);
fclose(fp);
return buf; return buf;
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -87,6 +87,8 @@ INCLUDES= \ ...@@ -87,6 +87,8 @@ INCLUDES= \
-I./../../../platform/base/hal/micro/unix/host \ -I./../../../platform/base/hal/micro/unix/host \
-I../../../platform/base/hal/micro/unix/host/board \ -I../../../platform/base/hal/micro/unix/host/board \
-I./rpc_api/inc \ -I./rpc_api/inc \
-I../../../../../common/sqlite/ \
-I../../../../../common/curl/include \
-I./ZB -I./ZB
\ \
...@@ -284,9 +286,12 @@ APPLICATION_FILES= \ ...@@ -284,9 +286,12 @@ APPLICATION_FILES= \
./ZB/kk_zigbee_api.c\ ./ZB/kk_zigbee_api.c\
./ZB/kk_tsl_property_report.c\ ./ZB/kk_tsl_property_report.c\
./ZB/kk_tsl_property_set.c\ ./ZB/kk_tsl_property_set.c\
./ZB/kk_device_table_db.c\
./ZB/kk_msg_report.c\
./ZB/kk_plat_ota.c\
./ZB/kk_rgb_hsl_convert.c\
./kk_test.c\ ./kk_test.c\
./kk_sub_tsl.c\ ./kk_sub_tsl.c\
./kk_tsl_zigbee_map.c\
./rpc_api/src/rpc_common.c\ ./rpc_api/src/rpc_common.c\
./rpc_api/src/rpc_onoff.c\ ./rpc_api/src/rpc_onoff.c\
./rpc_api/src/rpc_global_cmd.c\ ./rpc_api/src/rpc_global_cmd.c\
...@@ -373,10 +378,10 @@ $(TARGET_FILE): $(APPLICATION_OBJECTS) $(LIBRARIES) ...@@ -373,10 +378,10 @@ $(TARGET_FILE): $(APPLICATION_OBJECTS) $(LIBRARIES)
else else
$(TARGET_FILE): $(APPLICATION_OBJECTS) $(LIBRARIES) $(TARGET_FILE): $(APPLICATION_OBJECTS) $(LIBRARIES)
ifeq ($(CONFIG_VENDOR),ubuntu) ifeq ($(CONFIG_VENDOR),ubuntu)
$(LD) $^ $(LINKER_FLAGS) -lm -L. -lapi_com_ubuntu -lnanomsg_ubuntu -lanl -pthread -lev_ubuntu -lsqlite3 -lkk_hal_ubuntu -o $(TARGET_FILE) $(LD) $^ $(LINKER_FLAGS) -lm -L. -lapi_com_ubuntu -lnanomsg_ubuntu -lanl -pthread -lev_ubuntu -lkk_hal_ubuntu -lsqlite_ubuntu -lcurl_ubuntu -ldl -o $(TARGET_FILE)
@echo -e '\n$@ build success' @echo -e '\n$@ build success'
else else
$(LD) $^ $(LINKER_FLAGS) -lm -L. -lapi_com -lnanomsg -lanl -pthread -lev -lkk_hal -lsqlite3 -o $(TARGET_FILE) $(LD) $^ $(LINKER_FLAGS) -lm -L. -lapi_com -lnanomsg -lanl -pthread -lev -lkk_hal -lsqlite -lcurl -o $(TARGET_FILE)
@echo -e '\n$@ build success' @echo -e '\n$@ build success'
endif endif
endif endif
......
{
"productCode":"1022",
"config":[
{
"identity":"PowerSwitch",
"endpoint":1,
"cluster":"0x0006",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff"
},{
"identity":"RGBColor.red",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_red"
},{
"identity":"RGBColor.green",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_green"
},{
"identity":"RGBColor.blue",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_blue"
},{
"identity":"CurrentHue",
"endpoint":1,
"cluster":"0x0300",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":""
},{
"identity":"CurrentSaturation",
"endpoint":1,
"cluster":"0x0300",
"attribute":"0x0001",
"reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":""
},{
"identity":"Brightness",
"endpoint":1,
"cluster":"0x0008",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_Brightness",
"controlFunc":"kk_tsl_set_colorlight_Brightness"
},{
"identity":"WhiteBrightness",
"endpoint":2,
"cluster":"0x0008",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_Brightness",
"controlFunc":"kk_tsl_set_colorlight_Brightness"
},{
"identity":"Mode",
"endpoint":1,
"cluster":"0xFCC0",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_mode",
"controlFunc":"kk_tsl_set_colorlight_mode"
}
]
}
\ No newline at end of file
...@@ -3,19 +3,8 @@ ...@@ -3,19 +3,8 @@
"config":[ "config":[
{ {
"identity":"PowerSwitch_1", "identity":"PowerSwitch_1",
"endpoint":18, "endpoint":1,
"cluster":"0x0011", "cluster":"0x0006",
"attribute":"0x0022", "attribute":"0x0000",
"reportFunc":"A", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"B" "controlFunc":"zclOnOff"
},{
"identity":"PowerSwitch_2",
"endpoint":19,
"cluster":"0x0033",
"attribute":"0x0044",
"reportFunc":"C",
"controlFunc":"D"
}
]
}
\ No newline at end of file
...@@ -2,19 +2,19 @@ ...@@ -2,19 +2,19 @@
"productCode":"3002", "productCode":"3002",
"config":[ "config":[
{ {
"identity":"AAA", "identity":"PowerSwitch_1",
"endpoint":11, "endpoint":1,
"cluster":"0x1111", "cluster":"0x0006",
"attribute":"0x2222", "attribute":"0x0000",
"reportFunc":"zclOnOff_On", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff_On" "controlFunc":"zclOnOff"
},{ },{
"identity":"BBB", "identity":"PowerSwitch_2",
"endpoint":22, "endpoint":2,
"cluster":"0x3333", "cluster":"0x0006",
"attribute":"0x4444", "attribute":"0x0000",
"reportFunc":"zclOnOff_Off", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff_Off" "controlFunc":"zclOnOff"
} }
] ]
} }
...@@ -2,26 +2,26 @@ ...@@ -2,26 +2,26 @@
"productCode":"3003", "productCode":"3003",
"config":[ "config":[
{ {
"identity":"AAA", "identity":"PowerSwitch_1",
"endpoint":11, "endpoint":1,
"cluster":"0x1111", "cluster":"0x0006",
"attribute":"0x2222", "attribute":"0x0000",
"reportFunc":"zclOnOff_On", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff_On" "controlFunc":"zclOnOff"
},{ },{
"identity":"BBB", "identity":"PowerSwitch_2",
"endpoint":22, "endpoint":2,
"cluster":"0x3333", "cluster":"0x0006",
"attribute":"0x4444", "attribute":"0x0000",
"reportFunc":"zclOnOff_Off", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff_Off" "controlFunc":"zclOnOff"
},{ },{
"identity":"CCCC", "identity":"PowerSwitch_3",
"endpoint":33, "endpoint":3,
"cluster":"0x5555", "cluster":"0x0006",
"attribute":"0x6666", "attribute":"0x0000",
"reportFunc":"zclOnOff_Off", "reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff_Off" "controlFunc":"zclOnOff"
} }
] ]
} }
{
"productCode":"3073",
"config":[
{
"identity":"PowerSwitch",
"endpoint":1,
"cluster":"0x0006",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_global_onoff",
"controlFunc":"zclOnOff"
},{
"identity":"RGBColor.red",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_red"
},{
"identity":"RGBColor.green",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_green"
},{
"identity":"RGBColor.blue",
"endpoint":1,
"cluster":"0xFFFF",
"attribute":"0xFFFF",
"reportFunc":"",
"controlFunc":"kk_tsl_set_colorlight_RGB_blue"
},{
"identity":"CurrentHue",
"endpoint":1,
"cluster":"0x0300",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":""
},{
"identity":"CurrentSaturation",
"endpoint":1,
"cluster":"0x0300",
"attribute":"0x0001",
"reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":""
},{
"identity":"Brightness",
"endpoint":1,
"cluster":"0x0008",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_Brightness",
"controlFunc":"kk_tsl_set_colorlight_Brightness"
},{
"identity":"WhiteBrightness",
"endpoint":2,
"cluster":"0x0008",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_Brightness",
"controlFunc":"kk_tsl_set_colorlight_Brightness"
},{
"identity":"Mode",
"endpoint":1,
"cluster":"0xFCC0",
"attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_mode",
"controlFunc":"kk_tsl_set_colorlight_mode"
}
]
}
\ No newline at end of file
...@@ -12,10 +12,206 @@ ...@@ -12,10 +12,206 @@
"modleId": "00068613", "modleId": "00068613",
"productCode": "3003", "productCode": "3003",
"productName": "星辰系列.白色零火线三路灯控面板Z3S(KONKE)" "productName": "星辰系列.白色零火线三路灯控面板Z3S(KONKE)"
},{
"modleId": "00048611",
"productCode": "3004",
"productName": "星辰系列.白色零火线情景面板Z3S(KONKE)"
},{
"modleId": "00038611",
"productCode": "3005",
"productName": "星辰系列.白色零火线单路窗帘面板Z3S(KONKE)"
},{
"modleId": "00038612",
"productCode": "3006",
"productName": "星辰系列.白色零火线双路窗帘面板Z3S(KONKE)"
},{
"modleId": "00038613",
"productCode": "3007",
"productName": "星辰系列·白色干触点单路窗帘面板Z3S(KONKE)"
},{
"modleId": "00038614",
"productCode": "3008",
"productName": "星辰系列·白色干触点双路窗帘面板Z3S(KONKE)"
},{
"modleId": "00068601",
"productCode": "3009",
"productName": "铂金系列.白色零火线单路灯控面板Z3S(KONKE)"
},{
"modleId": "00068602",
"productCode": "3010",
"productName": "铂金系列.白色零火线双路灯控面板Z3S(KONKE)"
},{
"modleId": "00068603",
"productCode": "3011",
"productName": "铂金系列.白色零火线三路灯控面板Z3S(KONKE)"
},{
"modleId": "00038601",
"productCode": "3012",
"productName": "铂金系列.白色零火线窗帘面板Z3S(KONKE)"
},{
"modleId": "00048601",
"productCode": "3013",
"productName": "铂金系列.白色零火线情景面板Z3S(KONKE)"
},{
"modleId": "00048602",
"productCode": "3014",
"productName": "铂金系列.白色快捷面板Z3S(KONKE)"
},{
"modleId": "0402812C",
"productCode": "3016",
"productName": "铂金系列.白色紧急呼叫按钮Z3S(KONKE)"
},{
"modleId": "0402802C",
"productCode": "3015",
"productName": "铂金系列.白色零火线SOS紧急呼叫面板Z3S(KONKE)"
},{
"modleId": "00038603",
"productCode": "3017",
"productName": "铂金系列.白色零火线推窗器面板Z3S(KONKE)"
},{
"modleId": "01018601",
"productCode": "3018",
"productName": "铂金系列.白色零火线调光面板Z3S(KONKE)"
},{
"modleId": "3019",
"productCode": "00518610",
"productName": "铂金系列.白色10A智能插座Z3S(KONKE)"
},{
"modleId": "00518616",
"productCode": "3020",
"productName": "铂金系列.白色16A智能插座Z3S(KONKE)"
},{
"modleId": "00038602",
"productCode": "3021",
"productName": "铂金系列·白色干触点窗帘面板Z3S(安心加)"
},{
"modleId": "00068621",
"productCode": "3022",
"productName": "肖邦系列.白色零火线单路灯控面板Z3S(KONKE)"
},{
"modleId": "00068622",
"productCode": "3023",
"productName": "肖邦系列.白色零火线双路灯控面板Z3S(KONKE)"
},{
"modleId": "00068623",
"productCode": "3024",
"productName": "肖邦系列.白色零火线三路灯控面板Z3S(KONKE)"
},{
"modleId": "00048621",
"productCode": "3025",
"productName": "肖邦系列.白色零火线情景面板Z3S(KONKE)"
},{
"modleId": "00038621",
"productCode": "3026",
"productName": "肖邦系列.白色零火线单路窗帘面板Z3S(KONKE)"
},{
"modleId": "00038622",
"productCode": "3027",
"productName": "肖邦系列.白色零火线双路窗帘面板Z3S(KONKE)"
},{
"modleId": "00518620",
"productCode": "3037",
"productName": "肖邦系列.白色10A智能插座Z3S(KONKE)"
},{
"modleId": "00518626",
"productCode": "3038",
"productName": "肖邦系列.白色16A智能插座Z3S(KONKE)"
},{
"modleId": "0402002A",
"productCode": "3039",
"productName": "水浸传感器-HZB30S版(KONKE)"
},{
"modleId": "0402002B",
"productCode": "3040",
"productName": "燃气报警器-HZ3S版(KONKE)"
},{
"modleId": "04020028",
"productCode": "3041",
"productName": "烟雾报警器-HZ3S版(KONKE)"
},{
"modleId": "3041",
"productCode": "3080",
"productName": "燃气报警器-豪恩版(iHORN)"
},{
"modleId": "3050",
"productCode": "3081",
"productName": "烟雾报警器-豪恩版(iHORN)"
},{
"modleId": "3043",
"productCode": "0402010D",
"productName": "红外幕帘探测器HZ3S版(KONKE)"
},{
"modleId": "03020001",
"productCode": "3076",
"productName": "环境传感器KZ3S(KONKE)"
},{
"modleId": "00510001",
"productCode": "3046",
"productName": "KIT系列.白色快捷情景按钮"
},{
"modleId": "03020000",
"productCode": "3048",
"productName": "KIT系列.白色温湿度传感器"
},{
"modleId": "0402000D",
"productCode": "3049",
"productName": "KIT系列.白色人体传感器"
},{
"modleId": "04020015",
"productCode": "3050",
"productName": "KIT系列.白色门窗传感器"
},{
"modleId": "04021015",
"productCode": "3051",
"productName": "邦德系列.白色门窗传感器(KONKE)"
},{
"modleId": "0402102C",
"productCode": "3054",
"productName": "邦德系列.白色SOS按钮(KONKE)"
},{
"modleId": "0402102A",
"productCode": "3055",
"productName": "邦德系列.白色水浸传感器(KONKE)"
},{
"modleId": "00040002",
"productCode": "3056",
"productName": "邦德系列.白色快捷按键(KONKE)"
},{
"modleId": "04031225",
"productCode": "3057",
"productName": "邦德系列.白色声光传感器(KONKE)"
},{
"modleId": "02020000",
"productCode": "3067",
"productName": "智能窗帘电机Z3S(KONKE)(说明:杜亚款)"
},{
"modleId": "02020001",
"productCode": "3068",
"productName": "威刚系列.智能窗帘电机Z3S(KONKE)(说明:威士达款)"
},{
"modleId": "01000002",
"productCode": "3069",
"productName": "双路智能灯控模块Z3S(KONKE)"
},{
"modleId": "04028301",
"productCode": "3070",
"productName": "传感器模块Z3S(KONKE)"
},{
"modleId": "03300001",
"productCode": "3071",
"productName": "智能水阀控制器Z3S(KONKE)"
},{
"modleId": "03310001",
"productCode": "3072",
"productName": "智能燃气机械臂控制器Z3S(KONKE)"
},{ },{
"modleId": "01020001", "modleId": "01020001",
"productCode": "3073", "productCode": "3073",
"productName": "幻彩灯带控制器Z3S(KONKE)" "productName": "幻彩灯带控制器Z3S(KONKE)"
},{
"modleId": "00648631",
"productCode": "3077",
"productName": "多功能面板(亚运村临时项目)"
} }
] ]
} }
#include "kk_device_manager.h" #include "kk_device_manager.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -24,7 +22,6 @@ static const char *kk_match_tsl_productCode(const char* modelId) ...@@ -24,7 +22,6 @@ static const char *kk_match_tsl_productCode(const char* modelId)
UTIL_LOG_INFO("device model id:%s,%d\n",modelId,strlen(modelId)); UTIL_LOG_INFO("device model id:%s,%d\n",modelId,strlen(modelId));
for(i=0;i<num && kk_product_code[i].modelId!=NULL;i++){ for(i=0;i<num && kk_product_code[i].modelId!=NULL;i++){
emberAfDebugPrint("i=%d,%s\n",i,kk_product_code[i].modelId);
if(strstr(modelId,kk_product_code[i].modelId)!=NULL){ if(strstr(modelId,kk_product_code[i].modelId)!=NULL){
UTIL_LOG_INFO("match model id:%s\n",kk_product_code[i].modelId); UTIL_LOG_INFO("match model id:%s\n",kk_product_code[i].modelId);
UTIL_LOG_INFO("tsl product code:%s\n",kk_product_code[i].code); UTIL_LOG_INFO("tsl product code:%s\n",kk_product_code[i].code);
...@@ -418,24 +415,7 @@ char *kk_match_productCode(const char* modelId) ...@@ -418,24 +415,7 @@ char *kk_match_productCode(const char* modelId)
return NULL; return NULL;
} }
typedef struct kk_dev_config_item{
char * identity;
char * reportFuncName;
char * controlFuncName;
kk_rpc_report * reportFunc;
kk_rpc_set * controlFunc;
uint8_t endpoint;
uint16_t cluster;
uint16_t attribute;
struct kk_dev_config_item * next;
}kk_dev_config_item;
typedef struct kk_dev_config_map{
char * productCode;
kk_dev_config_item item;
struct kk_dev_config_map *next;
}kk_dev_config_map;
static kk_dev_config_map *dev_config_map = NULL; static kk_dev_config_map *dev_config_map = NULL;
#define KK_DEVICE_CONFIG_MAP_TABLE_FILE_PREFIX "./ZB/dev_config_table/device_%s.json" #define KK_DEVICE_CONFIG_MAP_TABLE_FILE_PREFIX "./ZB/dev_config_table/device_%s.json"
...@@ -450,6 +430,7 @@ kk_dev_config_item *kk_device_config_item_find_by_identity(kk_dev_config_map * m ...@@ -450,6 +430,7 @@ kk_dev_config_item *kk_device_config_item_find_by_identity(kk_dev_config_map * m
if(!strcmp(item->identity,identity)){ if(!strcmp(item->identity,identity)){
return item; return item;
} }
item = item->next;
} }
return NULL; return NULL;
} }
...@@ -483,7 +464,7 @@ void kk_device_config_item_report(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId c ...@@ -483,7 +464,7 @@ void kk_device_config_item_report(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId c
kk_dev_config_item *item; kk_dev_config_item *item;
kk_dev_config_map * cfgMap; kk_dev_config_map * cfgMap;
char *pCode; char *pCode;
kk_zigbee_property_report func; kk_rpc_report func;
pCode = kk_device_find_productCode(eui64); pCode = kk_device_find_productCode(eui64);
cfgMap = kk_device_config_find(pCode); cfgMap = kk_device_config_find(pCode);
...@@ -573,8 +554,8 @@ bool kk_device_config_add(const char *productCode,const char *identity,uint8_t e ...@@ -573,8 +554,8 @@ bool kk_device_config_add(const char *productCode,const char *identity,uint8_t e
memcpy(ptr->item.controlFuncName, controlFuncName,len); memcpy(ptr->item.controlFuncName, controlFuncName,len);
ptr->item.controlFuncName[len] = '\0'; ptr->item.controlFuncName[len] = '\0';
newItem->reportFunc = kk_find_rpc_report_function_api(reportFuncName); ptr->item.reportFunc = kk_find_rpc_report_function_api(reportFuncName);
newItem->controlFunc = kk_find_rpc_set_function_api(controlFuncName); ptr->item.controlFunc = kk_find_rpc_set_function_api(controlFuncName);
if(dev_config_map==NULL){ if(dev_config_map==NULL){
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
#define __KK_DEVICE_MANAGER_H #define __KK_DEVICE_MANAGER_H
#include "kk_test.h" #include "kk_test.h"
#include "kk_sub_tsl.h" #include "kk_sub_tsl.h"
#include "kk_tsl_zigbee_map.h"
#include "kk_product_code.h" #include "kk_product_code.h"
#include "kk_zb_com.h" #include "kk_zb_com.h"
/****************** ****************************************************************** /****************** ******************************************************************
* File Name : kk_device_manager.h * File Name : kk_device_manager.h
* Author : yjq * Author : yjq
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#define KK_NETWORK_PARAMETER_TX_POWER 10 #define KK_NETWORK_PARAMETER_TX_POWER 10
#define KK_NETWORK_PARAMETER_CHANNEL 0x0B #define KK_NETWORK_PARAMETER_CHANNEL 0x0B
#define KK_EP(x) (x)
#define KK_DUMMY_EP KK_EP(0)
#define KK_PRIMARY_EP KK_EP(1)
void kk_productCode_tick(); void kk_productCode_tick();
...@@ -41,9 +44,29 @@ char *kk_match_productCode(const char* modelId); ...@@ -41,9 +44,29 @@ char *kk_match_productCode(const char* modelId);
bool kk_device_config_map_add(const char *productCode); bool kk_device_config_map_add(const char *productCode);
typedef int (*kk_rpc_set)(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
typedef int(*kk_rpc_report)(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
typedef struct kk_dev_config_item{
char * identity;
char * reportFuncName;
char * controlFuncName;
kk_rpc_report * reportFunc;
kk_rpc_set * controlFunc;
uint8_t endpoint;
uint16_t cluster;
uint16_t attribute;
struct kk_dev_config_item * next;
}kk_dev_config_item;
typedef struct kk_dev_config_map{
char * productCode;
kk_dev_config_item item;
struct kk_dev_config_map *next;
}kk_dev_config_map;
......
...@@ -521,7 +521,7 @@ void kk_device_config_load_from_db(void) ...@@ -521,7 +521,7 @@ void kk_device_config_load_from_db(void)
kk_device_table_s *ptr = kk_zb_device_table; kk_device_table_s *ptr = kk_zb_device_table;
while(ptr!=NULL){ while(ptr!=NULL){
if(ptr->productCode!=NULL){ if(ptr->productCode!=NULL&&strlen(ptr->productCode)!=0){
kk_device_config_map_add(ptr->productCode); kk_device_config_map_add(ptr->productCode);
} }
ptr = ptr->next; ptr = ptr->next;
...@@ -538,9 +538,3 @@ void emberAfPluginDeviceTableInitialized(void) ...@@ -538,9 +538,3 @@ void emberAfPluginDeviceTableInitialized(void)
kk_device_config_load_from_db(); kk_device_config_load_from_db();
} }
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include "curl.h"
#include "./jsonrpc/rpccJSON.h"
static int s_ota_server_init = 0;
size_t kk_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
return fwrite(ptr, size, nmemb, stream);
}
int kk_progress_func(char *progress_data,
double t, /* dltotal */
double d, /* dlnow */
double ultotal,
double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
int kk_http_download(char* url, char* filename)
{
CURL *curl;
CURLcode res;
FILE *outfile;
char *progress_data = "* ";
if (url == NULL || filename == NULL){
printf("params error url or filename \n");
return -1;
}
curl = curl_easy_init();
if(curl)
{
outfile = fopen(filename, "wb");//fopen("test.jpg", "wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, kk_write_func);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, kk_progress_func);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, progress_data);
res = curl_easy_perform(curl);
fclose(outfile);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
static const char oatStorageDirectory[] = "ota-files";
int kk_ota_process(cJSON* root){
cJSON *params;
cJSON *id;
cJSON *mac;
cJSON *info;
cJSON *msgType;
cJSON *payload;
cJSON *url;
cJSON *md5;
cJSON *size;
int ret = 0;
struct stat st;
int iFileSize;
char fileName[100] = {0};
info = rpc_cJSON_GetObjectItem(root, "info");
if(info != NULL){
msgType = rpc_cJSON_GetObjectItem(info, "msgType");
mac = rpc_cJSON_GetObjectItem(info, "deviceCode");
}
payload = rpc_cJSON_GetObjectItem(root, "payload");
if(payload != NULL){
params = rpc_cJSON_GetObjectItem(payload, "data");
//id = rpc_cJSON_GetObjectItem(payload, "msgId");
url = rpc_cJSON_GetObjectItem(params, "url");
md5 = rpc_cJSON_GetObjectItem(params, "md5");
size = rpc_cJSON_GetObjectItem(params, "size");
printf("===============kk_ota_process ===========[%s][%s][%s]\n", url->valuestring,mac->valuestring,size->valuestring);
sprintf(fileName, "%s/%s.%s", oatStorageDirectory, mac->valuestring, "ota");
kk_http_download(url->valuestring, fileName);
if(stat(mac->valuestring, &st))
printf("读取出错!\n");
iFileSize = st.st_size;
if (iFileSize != atoi(size->valuestring)){
printf("check file size failed [%d][%s] \n", iFileSize, size->valuestring);
return -1;
}
char md5File[21] = {0};
char cmd[100] = {0};
char md5str[34] = {0};
FILE *fp;
sprintf(md5File, "%s.md5", mac->valuestring);
sprintf(cmd, "md5sum %s|cut -d\" \" -f1 > %s", fileName, md5File);
system(cmd);
//snprintf(filepath, sizeof(filepath), "./%s", "alinkconf");
fp = fopen(md5File, "r");
if (!fp) {
printf("open file failed \n");
return -1;
}
int readlen = fread(md5str, 1, 32, fp);
printf("md5sum readlen=%d, md5str=%s,md5->valuestring=%s \n", readlen, md5str,md5->valuestring);
if (readlen > 0 && strcmp(md5str, md5->valuestring) == 0){
printf("check md5sum succees\n");
ret = 0;
}else{
printf("check md5sum failed \n");
ret = -1;
}
fclose(fp);
remove(md5File);
kk_ota_notify(fileName);
return ret;
}
return -1;
}
#include <stdio.h>
#include "kk_rgb_hsl_convert.h"
#define min3v(v1, v2, v3) ((v1)>(v2)? ((v2)>(v3)?(v3):(v2)):((v1)>(v3)?(v3):(v2)))
#define max3v(v1, v2, v3) ((v1)<(v2)? ((v2)<(v3)?(v3):(v2)):((v1)<(v3)?(v3):(v1)))
// Converts RGB to HSL
void RGBtoHSL(const COLOR_RGB *rgb, COLOR_HSL *hsl)
{
float h=0, s=0, l=0;
// normalizes red-green-blue values
float r = rgb->red/255.0f;
float g = rgb->green/255.0f;
float b = rgb->blue/255.0f;
float maxVal = max3v(r, g, b);
float minVal = min3v(r, g, b);
// hue
if(maxVal == minVal)
{
h = 0; // undefined
}
else if(maxVal==r && g>=b)
{
h = 60.0f*(g-b)/(maxVal-minVal);
}
else if(maxVal==r && g<b)
{
h = 60.0f*(g-b)/(maxVal-minVal) + 360.0f;
}
else if(maxVal==g)
{
h = 60.0f*(b-r)/(maxVal-minVal) + 120.0f;
}
else if(maxVal==b)
{
h = 60.0f*(r-g)/(maxVal-minVal) + 240.0f;
}
// luminance
l = (maxVal+minVal)/2.0f;
// saturation
if(l == 0 || maxVal == minVal)
{
s = 0;
}
else if(0<l && l<=0.5f)
{
s = (maxVal-minVal)/(maxVal+minVal);
}
else if(l>0.5f)
{
s = (maxVal-minVal)/(2 - (maxVal+minVal)); //(maxVal-minVal > 0)?
}
hsl->hue = (h>360)? 360 : ((h<0)?0:h);
hsl->saturation = ((s>1)? 1 : ((s<0)?0:s))*100;
hsl->luminance = ((l>1)? 1 : ((l<0)?0:l))*100;
}
// Converts HSL to RGB
void HSLtoRGB(const COLOR_HSL *hsl, COLOR_RGB *rgb)
{
float h = hsl->hue; // h must be [0, 360]
float s = hsl->saturation/100.f; // s must be [0, 1]
float l = hsl->luminance/100.f; // l must be [0, 1]
float R, G, B;
if(hsl->saturation == 0)
{
// achromatic color (gray scale)
R = G = B = l*255.0f;
}
else
{
float q = (l<0.5f)?(l * (1.0f+s)):(l+s - (l*s));
float p = (2.0f * l) - q;
float Hk = h/360.0f;
float T[3];
T[0] = Hk + 0.3333333f; // Tr 0.3333333f=1.0/3.0
T[1] = Hk; // Tb
T[2] = Hk - 0.3333333f; // Tg
for(int i=0; i<3; i++)
{
if(T[i] < 0) T[i] += 1.0f;
if(T[i] > 1) T[i] -= 1.0f;
if((T[i]*6) < 1)
{
T[i] = p + ((q-p)*6.0f*T[i]);
}
else if((T[i]*2.0f) < 1) //(1.0/6.0)<=T[i] && T[i]<0.5
{
T[i] = q;
}
else if((T[i]*3.0f) < 2) // 0.5<=T[i] && T[i]<(2.0/3.0)
{
T[i] = p + (q-p) * ((2.0f/3.0f) - T[i]) * 6.0f;
}
else T[i] = p;
}
R = T[0]*255.0f;
G = T[1]*255.0f;
B = T[2]*255.0f;
}
rgb->red = (int)((R>255)? 255 : ((R<0)?0 : R));
rgb->green = (int)((G>255)? 255 : ((G<0)?0 : G));
rgb->blue = (int)((B>255)? 255 : ((B<0)?0 : B));
}
#ifndef _RGB_HSL_CONVERT_H_
#define _RGB_HSL_CONVERT_H_
typedef struct
{
int red; // [0,255]
int green; // [0,255]
int blue; // [0,255]
}COLOR_RGB;
typedef struct
{
float hue; // [0,360]
float saturation; // [0,100]
float luminance; // [0,100]
}COLOR_HSL;
void RGBtoHSL(const COLOR_RGB *rgb, COLOR_HSL *hsl);
void HSLtoRGB(const COLOR_HSL *hsl, COLOR_RGB *rgb);
#endif
#include "kk_tsl_property_report.h" #include "kk_tsl_property_report.h"
#include "kk_tsl_zigbee_map.h" #include "kk_device_manager.h"
#include "kk_rgb_hsl_convert.h"
const char *kk_tsl_rpt_status_string[] = { const char *kk_tsl_rpt_status_string[] = {
"Success", "Success",
...@@ -9,41 +10,97 @@ const char *kk_tsl_rpt_status_string[] = { ...@@ -9,41 +10,97 @@ const char *kk_tsl_rpt_status_string[] = {
"Invaild Type" "Invaild Type"
}; };
//todo: fix it //todo: fix it
static cJSON* kk_check_identify(const char * identify,cJSON* root,int index,int status)
{
int rev = 0,startIdx2 = 0,startIdx1 = 0;
char *Identify_str;
char tmp_Identity[64] = {0};
rev = kk_tsl_utils_memtok(identify,'.',2,&startIdx2);
if(!rev){
cJSON* str = NULL;
cJSON* str_r = NULL;
kk_tsl_utils_memtok(identify,'.',1,&startIdx1);
str = rpc_cJSON_CreateObject();
Identify_str = identify + 1 + startIdx2;
memset(tmp_Identity,0x0,sizeof(tmp_Identity));
memcpy(tmp_Identity,identify+startIdx1+1,startIdx2-startIdx1);
rpc_cJSON_AddNumberToObject(str, Identify_str,status);
str_r = rpc_cJSON_CreateObject();
rpc_cJSON_AddItemToObject(str_r,tmp_Identity,str);
memset(tmp_Identity,0x0,sizeof(tmp_Identity));
memcpy(tmp_Identity,identify,startIdx1);
rpc_cJSON_AddItemToObject(root,tmp_Identity,str_r);
return root;
}
else{
rev = kk_tsl_utils_memtok(identify,'.',1,&startIdx1);
if(!rev){
cJSON* str = NULL;
str = rpc_cJSON_CreateObject();
Identify_str = identify + 1 + startIdx1;
memset(tmp_Identity,0x0,sizeof(tmp_Identity));
memcpy(tmp_Identity,identify,startIdx1);
rpc_cJSON_AddNumberToObject(str, Identify_str,status);
rpc_cJSON_AddItemToObject(root,tmp_Identity,str);
return root;
}
}
return NULL;
}
static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId,uint16_t attributeId) static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId,uint16_t attributeId)
{ {
cJSON* root; cJSON* root,*root_tmp;
int index; int index;
char *Identify; char *Identify;
sub_dev_node_t *node = NULL;
kk_device_table_s *dev; kk_device_table_s *dev;
kk_dev_config_map *dev_info = NULL;
kk_dev_config_item *item = NULL;
char macString[RPC_EUI64_STRING_LENGTH]; char macString[RPC_EUI64_STRING_LENGTH];
rpc_eui64ToString(mac,macString); rpc_eui64ToString(mac,macString);
root = rpc_cJSON_CreateObject(); root = rpc_cJSON_CreateObject();
index = kk_get_tsl_index(EP,clusterId,attributeId); dev = kk_device_find_by_mac(mac);
if(dev == NULL){
return tsl_rpt_err;
}
printf("[%s][%d]dev->productCode:%s\n",__FUNCTION__,__LINE__,dev->productCode);
dev_info = kk_device_config_find(dev->productCode);
if(dev_info == NULL){
return tsl_rpt_err;
}
if(index < 0){ item = &dev_info->item;
dev = kk_device_find_by_mac(mac); while(item!=NULL){
if(dev!=NULL){ if(EP == item->endpoint &&
index = kk_get_tsl_glb_index(dev->productCode,EP,clusterId,attributeId); clusterId == item->cluster&&
} attributeId == item->attribute){
Identify = item->identity;
if(index < 0){
return tsl_rpt_err; break;
}else{
Identify = g_tsl_zigbee_map_glb[index].map.Identity;
} }
}else{ item = item->next;
Identify = g_tsl_zigbee_map[index].Identity; }
root_tmp = kk_check_identify(Identify,root,index,status);
if(root_tmp != NULL){
kk_rpc_report_status(root_tmp,mac);
}
else{
rpc_cJSON_AddNumberToObject(root, Identify,status);
kk_msg_report_property(root,mac);
} }
rpc_cJSON_AddNumberToObject(root, Identify,status);
kk_msg_report_property(root,mac);
return tsl_rpt_success; return tsl_rpt_success;
} }
//typedef int(*kk_rpc_report)(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
void kk_tsl_report_attribute(EmberEUI64 eui64, void kk_tsl_report_attribute(EmberEUI64 eui64,
uint8_t EP, uint8_t EP,
...@@ -53,44 +110,48 @@ void kk_tsl_report_attribute(EmberEUI64 eui64, ...@@ -53,44 +110,48 @@ void kk_tsl_report_attribute(EmberEUI64 eui64,
uint8_t len, uint8_t len,
uint8_t *data) uint8_t *data)
{ {
int i,j,num,status; int i,j,num,status;
char macString[19] = {0};
sub_dev_node_t *node = NULL; sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
char macString[RPC_EUI64_STRING_LENGTH];
kk_device_table_s *dev;
kk_dev_config_map *dev_info = NULL;
kk_dev_config_item *item = NULL;
kk_rpc_report func;
UTIL_LOG_INFO("\n********************kk tsl report attribute********************\n"); UTIL_LOG_INFO("\n********************kk tsl report attribute********************\n");
emberAfDebugPrint("mac:"); emberAfDebugPrint("mac:");
emberAfDebugPrintln(",ep:%d,clu:0x%04X,attr:0x%04X,dataType=0x%02x,len=%d,data:", emberAfDebugPrintln(",ep:%d,clu:0x%04X,attr:0x%04X,dataType=0x%02x,len=%d,data:",
EP,clusterId,attributeId,dataType,len); EP,clusterId,attributeId,dataType,len);
emberAfDebugPrintBuffer(data,len,true); emberAfDebugPrintBuffer(data,len,true);
//rpc_eui64ToString(eui64,macString);
dev = kk_device_find_by_mac(eui64);
if(dev == NULL){
return;
}
num = kk_get_tsl_num(); dev_info = kk_device_config_find(dev->productCode);
for(i=0;i<num;i++){ if(dev_info == NULL){
if( g_tsl_zigbee_map[i].clusterId == clusterId &&
g_tsl_zigbee_map[i].attributeId == attributeId &&
g_tsl_zigbee_map[i].zigbee_report!=NULL){
status = g_tsl_zigbee_map[i].zigbee_report(eui64,EP,clusterId,attributeId,dataType,len,data);
emberAfDebugPrintln("report status:%s",kk_tsl_rpt_status_string[status]);
return ;
}
}
rpc_eui64ToString(eui64,macString);
res = kk_sub_tsl_get_device_by_mac(macString,&node);
if(res != tsl_rpt_success){
emberAfAppPrintln("[kk_tsl_report_attribute] error~~~~~~~~~\n");
return; return;
} }
num = kk_get_tsl_glb_num();
for(i=0;i<num;i++){ item = &dev_info->item;
if( g_tsl_zigbee_map_glb[i].map.clusterId == clusterId && while(item!=NULL){
g_tsl_zigbee_map_glb[i].map.attributeId == attributeId && if(EP == item->endpoint &&
strncmp(node->productCode,g_tsl_zigbee_map_glb[i].ProductCode,strlen(node->productCode)) == 0 && clusterId == item->cluster&&
g_tsl_zigbee_map_glb[i].map.zigbee_report!=NULL){ attributeId == item->attribute){
status = g_tsl_zigbee_map_glb[i].map.zigbee_report(eui64,EP,clusterId,attributeId,dataType,len,data);
emberAfDebugPrintln("--report status:%s",kk_tsl_rpt_status_string[status]); func = item->reportFunc;
return ; if(func != NULL){
func(eui64,EP,clusterId,attributeId,dataType,len,data);
}else{
}
return;
} }
item = item->next;
} }
} }
...@@ -308,8 +369,107 @@ int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,Emb ...@@ -308,8 +369,107 @@ int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,Emb
} }
int kk_tsl_report_colorControl_Brightness(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data)
{
uint8_t value = data[0];
emberAfAppPrintln("[tsl report:kk_tsl_report_global_Brightness] value:%d\n",value);
if(dataType == ZCL_INT8U_ATTRIBUTE_TYPE){
if(len==1){
kk_tsl_report(eui64,EP,value,clusterId,attributeId);
return tsl_rpt_success;
}
return tsl_rpt_invaild_len;
}
return tsl_rpt_invaild_type;
}
static int s_HSLCount = 0;
COLOR_HSL g_hsl = {0,0,0};
int kk_tsl_report_colorControl_RGB(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data)
{
uint8_t value = data[0];
kk_device_table_s *dev;
kk_dev_config_map *dev_info = NULL;
kk_dev_config_item *item = NULL;
cJSON *root;
int rev = 0;
int startIdx = 0;
cJSON* root_color = NULL;
char tmp_Identity[64] = {0};
COLOR_RGB g_rgb = {0,0,0};
emberAfAppPrintln("[tsl report:kk_tsl_report_global_RGB] value:%d\n",value);
if(dataType == ZCL_INT8U_ATTRIBUTE_TYPE){
if(attributeId == 0x0001){
g_hsl.saturation = value;
s_HSLCount++;
}
else if(attributeId == 0x0){
g_hsl.hue = value;
s_HSLCount++;
}
}
if(s_HSLCount >= 2){
s_HSLCount = 0;
HSLtoRGB(&g_hsl,&g_rgb);
dev = kk_device_find_by_mac(eui64);
if(dev == NULL){
return tsl_rpt_err;
}
dev_info = kk_device_config_find(dev->productCode);
if(dev_info == NULL){
return tsl_rpt_err;
}
item = &dev_info->item;
while(item!=NULL){
if(strstr(item->identity,".red") != NULL){
if(root_color == NULL){
root_color = rpc_cJSON_CreateObject();
}
rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx);
if(!rev){
memcpy(tmp_Identity,item->identity,startIdx);
rpc_cJSON_AddNumberToObject(root_color, item->identity + 1 + startIdx,g_rgb.red);
}
}
else if(strstr(item->identity,".green") != NULL){
if(root_color == NULL){
root_color = rpc_cJSON_CreateObject();
}
rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx);
if(!rev){
memcpy(tmp_Identity,item->identity,startIdx);
rpc_cJSON_AddNumberToObject(root_color, item->identity + 1 + startIdx,g_rgb.green);
}
}
else if(strstr(item->identity,".blue") != NULL){
if(root_color == NULL){
root_color = rpc_cJSON_CreateObject();
}
rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx);
if(!rev){
memcpy(tmp_Identity,item->identity,startIdx);
rpc_cJSON_AddNumberToObject(root_color, item->identity + 1 + startIdx,g_rgb.blue);
}
}
item = item->next;
}
if(root_color != NULL){
root = rpc_cJSON_CreateObject();
rpc_cJSON_AddItemToObject(root,tmp_Identity,root_color);
kk_msg_report_property(root,eui64);
return tsl_rpt_success;
}
}
return tsl_rpt_err;
}
...@@ -40,7 +40,8 @@ int kk_tsl_report_OccupiedHeatingSetpoint(EmberEUI64 eui64,uint8_t EP,EmberAfClu ...@@ -40,7 +40,8 @@ int kk_tsl_report_OccupiedHeatingSetpoint(EmberEUI64 eui64,uint8_t EP,EmberAfClu
int kk_tsl_report_Formaldehyde(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data); int kk_tsl_report_Formaldehyde(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_PM2_5(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data); int kk_tsl_report_PM2_5(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data); int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_Brightness(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
int kk_tsl_report_colorControl_RGB(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
......
#include "kk_tsl_property_set.h" #include "kk_tsl_property_set.h"
#include "kk_rgb_hsl_convert.h"
//emberAfAppPrintln("[tsl report:Gloabl] OnOff~~~~~~~~~");
//emberAfAppPrintln("[tsl report:Gloabl] OnOff~~~~~~~~~");
//cJSON *rpc_Control(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac) //cJSON *rpc_Control(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{ int kk_tsl_utils_memtok(_IN_ char *input, _IN_ char *delimiter, _IN_ int index, _OU_ int *offset)
sub_dev_node_t *node = NULL; {
int res = 0; int item_index = 0;
rpc_nwk_info_s info; int count = 0;
EmberStatus status; int input_len = 0;
int index = 0;
zigbee_property_set *func;
int num; if (input == NULL || offset == NULL) {
uint8_t findFlag = 0xff; return -1;
cJSON *propertyItem = NULL; }
EmberEUI64 eui64; input_len = strlen(input);
EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; for (item_index = 0; item_index < input_len; item_index++) {
UTIL_LOG_INFO("\n********************kk tsl property operation********************\n"); if (input[item_index] == delimiter && (item_index + 1) < input_len) {
count++;
if(params == NULL){ if (count == index) {
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); *offset = item_index;
goto error_return;
}else{ return 0;
res = kk_sub_tsl_get_device_by_mac(mac->valuestring, &node); }
if (res != SUCCESS_RETURN) { }
printf("[%s][%d]\n",__FUNCTION__,__LINE__); }
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return; return -1;
} }
num = kk_get_tsl_num(); cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
for(index = 0; index < num; index++){ {
propertyItem = rpc_cJSON_GetObjectItem(params, g_tsl_zigbee_map[index].Identity); int res = 0;
if(propertyItem != NULL){ EmberStatus status;;
findFlag = 1; kk_device_table_s *dev;
break; kk_dev_config_map *dev_info = NULL;
} kk_dev_config_item *item = NULL;
} cJSON *propertyItem = NULL;
if(findFlag==0xff){ cJSON *propertyItem1 = NULL;
num = kk_get_tsl_glb_num(); cJSON *propertyItem2 = NULL;
for(index = 0; index < num; index++){ kk_rpc_set func;
propertyItem = rpc_cJSON_GetObjectItem(params, g_tsl_zigbee_map_glb[index].map.Identity); int rev = 0,startIdx1 = 0,startIdx2 = 0;
if(propertyItem != NULL){ char tmp_Identity[64] = {0};
findFlag = 2; int findFlag = 0;
break;
} uint8_t eui64[EUI64_SIZE];
} EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
} UTIL_LOG_INFO("\n********************kk tsl property operation********************\n");
if(findFlag!=0xff) if(params == NULL){
{ set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
int value = 0; goto error_return;
if(propertyItem->type != cJSON_Number){ }else{
value = rpc_get_u8(propertyItem->valuestring); rpc_get_mac(mac->valuestring,eui64);
}else{ nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
value = propertyItem->valueint; dev = kk_device_find_by_mac(eui64);
} if(dev == NULL){
goto error_return;
if(rpc_get_mac(mac->valuestring,eui64)==false){ }
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); dev_info = kk_device_config_find(dev->productCode);
goto error_return; if(dev_info == NULL){
} goto error_return;
nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64); }
item = &dev_info->item;
emberAfDebugPrint("mac:"); while(item!=NULL){
emberAfPrintBigEndianEui64(eui64);
emberAfDebugPrintln(",node:0x%04X",nodeId); rev = kk_tsl_utils_memtok(item->identity,'.',2,&startIdx2);
if(findFlag==1) if(!rev){
res = g_tsl_zigbee_map[index].zigbee_set(ctx,nodeId,g_tsl_zigbee_map[index].endpoint,&value); kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
else if(findFlag==2) memset(tmp_Identity,0x0,sizeof(tmp_Identity));
res = g_tsl_zigbee_map_glb[index].map.zigbee_set(ctx,nodeId,g_tsl_zigbee_map_glb[index].map.endpoint,&value); memcpy(tmp_Identity, item->identity, startIdx1);
propertyItem2 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
if(res < 0) if(propertyItem2 != NULL){
{ memset(tmp_Identity,0x0,sizeof(tmp_Identity));
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); memcpy(tmp_Identity, item->identity+startIdx1+1, startIdx2-startIdx1);
goto error_return; propertyItem1 = rpc_cJSON_GetObjectItem(propertyItem2,tmp_Identity);
} if(propertyItem1 != NULL){
else{ propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx2+1);
return rpc_cJSON_CreateNumber(res); if(propertyItem != NULL){
} findFlag = 1;
} }
}
} }
error_return:
return rpc_cJSON_CreateNull(); }
} else{
rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
int kk_tsl_set_gloabl_OnOff(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data) if(!rev){
{ memset(tmp_Identity,0x0,sizeof(tmp_Identity));
uint8_t Onoff = 0; memcpy(tmp_Identity, item->identity, startIdx1);
EmberStatus status = 0; propertyItem1 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
if(propertyItem1 != NULL){
Onoff = *(uint8_t*)data; propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx1+1);
emberAfAppPrintln("[tsl set:OnOff],Onoff=0x%02x",Onoff); if(propertyItem != NULL){
findFlag = 1;
if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){ }
if(ctx) }
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return; }
} else{
propertyItem = rpc_cJSON_GetObjectItem(params, item->identity);
if(Onoff==1){ if(propertyItem != NULL){
status = zclOnOff_On(node,ep); findFlag = 1;
emberAfAppPrintln("On"); }
}else if(Onoff==0){ }
status = zclOnOff_Off(node,ep); }
emberAfAppPrintln("Off"); if(findFlag == 1){
}else{ int value = 0;
if(ctx) if(propertyItem->type != cJSON_Number){
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); value = rpc_get_u8(propertyItem->valuestring);
goto error_return; }else{
} value = propertyItem->valueint;
}
emberAfAppPrintln("status=0x%02x",status); func = item->controlFunc;
return status; res = func(ctx,nodeId,item->endpoint,&value);
error_return: findFlag = 0;
return -1; }
item = item->next;
} }
return rpc_cJSON_CreateNumber(res);
}
int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{ error_return:
uint8_t Operation = 0; return rpc_cJSON_CreateNull();
EmberStatus status = 0; }
Operation = *(uint8_t*)data;
emberAfAppPrintln("[tsl set:Window Covering Operation Mode],mode=0x%02x",Operation); int kk_tsl_set_gloabl_OnOff(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){ uint8_t Onoff = 0;
if(ctx) EmberStatus status = 0;
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return; Onoff = *(uint8_t*)data;
} emberAfAppPrintln("[tsl set:OnOff],Onoff=0x%02x",Onoff);
if(Operation==0){ if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
status = WindowCover_UpOpen(node,ep); if(ctx)
emberAfAppPrintln("Up/Open"); set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
}else if(Operation==1){ goto error_return;
status = WindowCover_DownClose(node,ep); }
emberAfAppPrintln("Down/Close");
}else if(Operation==2){ if(Onoff==1){
status = WindowCover_Stop(node,ep); status = zclOnOff_On(node,ep);
emberAfAppPrintln("Stop"); emberAfAppPrintln("On");
}else{ }else if(Onoff==0){
if(ctx) status = zclOnOff_Off(node,ep);
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); emberAfAppPrintln("Off");
goto error_return; }else{
} if(ctx)
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
emberAfAppPrintln("status=0x%02x",status); goto error_return;
return status; }
error_return:
return -1; emberAfAppPrintln("status=0x%02x",status);
} return status;
error_return:
int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data) return -1;
{
uint8_t mode = 0; }
uint8_t WCmode = 0;
EmberStatus status = 0;
int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
mode = *(uint8_t*)data; {
emberAfAppPrintln("[tsl set:Window Covering Run Mode],mode=0x%02x",mode); uint8_t Operation = 0;
EmberStatus status = 0;
if(mode==WC_calibration_mode){
WCmode |= BIT(1); Operation = *(uint8_t*)data;
emberAfAppPrintln("[tsl set:Window Covering Operation Mode],mode=0x%02x",Operation);
status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
ZCL_MODE_ATTRIBUTE_ID, if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
ZCL_BITMAP8_ATTRIBUTE_TYPE, if(ctx)
1, set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
WCmode, goto error_return;
true); }
emberAfAppPrintln("Calibration Mode");
}else if(mode==WC_reversed_dir){ if(Operation==0){
WCmode |= BIT(0); status = WindowCover_UpOpen(node,ep);
status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID, emberAfAppPrintln("Up/Open");
ZCL_MODE_ATTRIBUTE_ID, }else if(Operation==1){
ZCL_BITMAP8_ATTRIBUTE_TYPE, status = WindowCover_DownClose(node,ep);
1, emberAfAppPrintln("Down/Close");
WCmode, }else if(Operation==2){
true); status = WindowCover_Stop(node,ep);
emberAfAppPrintln("Dir:reversed"); emberAfAppPrintln("Stop");
}else if(mode==WC_normal_dir){ }else{
WCmode = 0; if(ctx)
status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID, set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
ZCL_MODE_ATTRIBUTE_ID, goto error_return;
ZCL_BITMAP8_ATTRIBUTE_TYPE, }
1,
WCmode, emberAfAppPrintln("status=0x%02x",status);
true); return status;
emberAfAppPrintln("Dir:Normal"); error_return:
}else{ return -1;
if(ctx) }
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return; int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
} {
emberAfAppPrintln("status=0x%02x",status); uint8_t mode = 0;
return status; uint8_t WCmode = 0;
error_return: EmberStatus status = 0;
return -1;
} mode = *(uint8_t*)data;
int kk_tsl_set_windowCovering_position(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data) emberAfAppPrintln("[tsl set:Window Covering Run Mode],mode=0x%02x",mode);
{
uint8_t position = 0; if(mode==WC_calibration_mode){
EmberStatus status = 0; WCmode |= BIT(1);
position = *(uint8_t*)data; status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
emberAfAppPrintln("[tsl set:Window Covering Position],position=0x%02x",position); ZCL_MODE_ATTRIBUTE_ID,
ZCL_BITMAP8_ATTRIBUTE_TYPE,
status = WindowCover_GotoLiftPercentage(node,ep,position); 1,
WCmode,
emberAfAppPrintln("status=0x%02x",status); true);
return status; emberAfAppPrintln("Calibration Mode");
error_return: }else if(mode==WC_reversed_dir){
return -1; WCmode |= BIT(0);
} status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
ZCL_MODE_ATTRIBUTE_ID,
ZCL_BITMAP8_ATTRIBUTE_TYPE,
1,
WCmode,
true);
emberAfAppPrintln("Dir:reversed");
}else if(mode==WC_normal_dir){
WCmode = 0;
status = zclGWrite(node,1,ep,false,ZCL_WINDOW_COVERING_CLUSTER_ID,
ZCL_MODE_ATTRIBUTE_ID,
ZCL_BITMAP8_ATTRIBUTE_TYPE,
1,
WCmode,
true);
emberAfAppPrintln("Dir:Normal");
}else{
if(ctx)
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return;
}
emberAfAppPrintln("status=0x%02x",status);
return status;
error_return:
return -1;
}
int kk_tsl_set_windowCovering_position(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
uint8_t position = 0;
EmberStatus status = 0;
position = *(uint8_t*)data;
emberAfAppPrintln("[tsl set:Window Covering Position],position=0x%02x",position);
status = WindowCover_GotoLiftPercentage(node,ep,position);
emberAfAppPrintln("status=0x%02x",status);
return status;
error_return:
return -1;
}
static uint8_t s_RgbCount = 0;
static COLOR_RGB s_rgb;
static int kk_zclColorControlMovetohueandsat(EmberNodeId node,unsigned char ep)
{
int h,s,v;
COLOR_HSL hsl;
EmberStatus status = 0;
if(s_RgbCount >= 3){
RGBtoHSL(&s_rgb,&hsl);
emberAfAppPrintln("[kk_zclColorControlMovetohueandsat]");
status = zclColorControlMovetohueandsat(node,ep,hsl.hue,hsl.saturation,0,0,0,0);
s_RgbCount = 0;
}
return 0;
}
int kk_tsl_set_colorlight_RGB_red(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
int value = *(uint8_t*)data;
EmberStatus status = 0;
emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_red],value=0x%02x",value);
//s_Red = value;
s_rgb.red = value;
s_RgbCount++;
status = kk_zclColorControlMovetohueandsat(node,ep);
return status;
}
int kk_tsl_set_colorlight_RGB_green(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
int value = *(uint8_t*)data;
EmberStatus status = 0;
emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_green],value=0x%02x",value);
//s_Green = value;
s_rgb.green = value;
s_RgbCount++;
status = kk_zclColorControlMovetohueandsat(node,ep);
return status;
}
int kk_tsl_set_colorlight_RGB_blue(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
int value = *(uint8_t*)data;
EmberStatus status = 0;
emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_RGB_blue],value=0x%02x",value);
//s_Blue = value;
s_rgb.blue = value;
s_RgbCount++;
status = kk_zclColorControlMovetohueandsat(node,ep);
return status;
}
int kk_tsl_set_colorlight_Brightness(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data)
{
int value = *(uint8_t*)data;
EmberStatus status = 0;
emberAfAppPrintln("[tsl set:kk_tsl_set_colorloght_Brightness],value=0x%02x",value);
if(node==EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID){
if(ctx)
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
return -1;
}
status = zclLevel_MoveToLevel(node,ep,value,0,NULL,NULL);
return status;
}
...@@ -11,6 +11,12 @@ int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node, ...@@ -11,6 +11,12 @@ int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node,
int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data); int kk_tsl_set_windowCovering_mode(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
int kk_tsl_set_windowCovering_position(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data); int kk_tsl_set_windowCovering_position(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
int kk_tsl_set_colorlight_RGB_red(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
int kk_tsl_set_colorlight_RGB_green(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
int kk_tsl_set_colorlight_RGB_blue(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
int kk_tsl_set_colorlight_Brightness(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
#define RPC_KK_TEST_FUNCTION_TABLE \ #define RPC_KK_TEST_FUNCTION_TABLE \
{(rpc_function*)kk_tsl_property_operation,"/thing/service/property/set"}\ {(rpc_function*)kk_tsl_property_operation,"/thing/service/property/set"}\
......
...@@ -19,13 +19,18 @@ typedef struct{ ...@@ -19,13 +19,18 @@ typedef struct{
void kk_rpc_test(void); void kk_rpc_test(void);
#define KK_RPC_SET_FUNCTION_TABLE {\ #define KK_RPC_SET_FUNCTION_TABLE {\
{"zclOnOff_On",zclOnOff_On},\ {"zclOnOff",kk_tsl_set_gloabl_OnOff},\
{"zclOnOff_Off",zclOnOff_Off}\ {"zclOnOff_Off",zclOnOff_Off},\
{"kk_tsl_set_colorlight_RGB_red",kk_tsl_set_colorlight_RGB_red},\
{"kk_tsl_set_colorlight_RGB_green",kk_tsl_set_colorlight_RGB_green},\
{"kk_tsl_set_colorlight_RGB_blue",kk_tsl_set_colorlight_RGB_blue},\
{"kk_tsl_set_colorlight_Brightness",kk_tsl_set_colorlight_Brightness},\
} }
#define KK_RPC_REPORT_FUNCTION_TABLE {\ #define KK_RPC_REPORT_FUNCTION_TABLE {\
{"kk_tsl_report_global_onoff",kk_tsl_report_global_onoff},\ {"kk_tsl_report_global_onoff",kk_tsl_report_global_onoff},\
{"kk_tsl_report_global_onoff",kk_tsl_report_global_onoff}\ {"kk_tsl_report_colorControl_Brightness",kk_tsl_report_colorControl_Brightness},\
{"kk_tsl_report_colorControl_RGB",kk_tsl_report_colorControl_RGB},\
} }
kk_rpc_set_api_s kk_rpc_set_api[]; kk_rpc_set_api_s kk_rpc_set_api[];
......
...@@ -31,7 +31,7 @@ void emAfTick(void) ...@@ -31,7 +31,7 @@ void emAfTick(void)
{ {
emberAfMainTickCallback(); emberAfMainTickCallback();
emberAfOtaServerTick(); emberAfOtaServerTick();
emberAfPluginGatewayTickCallback(); //emberAfPluginGatewayTickCallback();
emberAfPluginHeartbeatTickCallback(); emberAfPluginHeartbeatTickCallback();
emberAfTick(); emberAfTick();
} }
......
#include "kk_test.h" #include "kk_test.h"
#include "kk_sub_tsl.h" #include "kk_sub_tsl.h"
#include "kk_tsl_zigbee_map.h"
extern kk_tsl_zigbee_map_t g_tsl_zigbee_map [];
static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI64 mac) static void kk_rpc_send_message(cJSON *data,char *msgtype,char *method,EmberEUI64 mac)
{ {
...@@ -95,13 +91,7 @@ void kk_rpc_reportLeftDevices(EmberEUI64 mac) ...@@ -95,13 +91,7 @@ void kk_rpc_reportLeftDevices(EmberEUI64 mac)
} }
int kk_sendData2CCU(char* data, int len){
if (strcmp(GW2CCU_PROTOCOL,"tcp") == 0 ){
kk_tcp_client_send(data, len);
}else{
kk_ipc_send(IPC_PLAT2MID, data, len);
}
}
void kk_rpc_reportDevices(EmberEUI64 mac,const char* productCode) void kk_rpc_reportDevices(EmberEUI64 mac,const char* productCode)
{ {
...@@ -211,14 +201,13 @@ error_return: ...@@ -211,14 +201,13 @@ error_return:
void emberAfMainTickCallback(void) void emberAfMainTickCallback(void)
{ {
static int last_time; static unsigned int last_time;
int time = halCommonGetInt32uMillisecondTick(); unsigned int time = halCommonGetInt32uMillisecondTick();
if((time-last_time)>=1000){ if((time-last_time)>=500){
last_time = time; last_time = time;
kk_productCode_tick(); kk_productCode_tick();
//printf("kk_productCode_tick!\n"); //printf("kk_productCode_tick!\n");
} }
} }
......
#ifndef _KK_TEST_H #ifndef _KK_TEST_H
#define _KK_TEST_H #define _KK_TEST_H
#include "rpc_network_operate.h" #include "rpc_network_operate.h"
#include "network-creator.h" #include "network-creator.h"
#include "network-creator-security.h" #include "network-creator-security.h"
#include "RPC_API.h" #include "RPC_API.h"
#include "com_api.h" #include "com_api.h"
#include "zb_device_id.h" #include "zb_device_id.h"
#include "kk_device_manager.h" #include "kk_device_manager.h"
#include "kk_zigbee_api.h" #include "kk_zigbee_api.h"
#include "kk_tsl_property_report.h" #include "kk_tsl_property_report.h"
#include "kk_tsl_property_set.h" #include "kk_tsl_property_set.h"
#include "kk_msg_report.h"
#define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add" #include "kk_device_table_db.h"
#define KK_REPORT_DEVICE_LEFT_TYPE "/thing/topo/delete"
#define KK_REPORT_ATTRIBUTE_TYPE "/thing/event/property/post"
#define KK_IPC_VERSION "1.0" #define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add"
#define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add" #define KK_REPORT_DEVICE_LEFT_TYPE "/thing/topo/delete"
#define KK_REPORT_DEVICE_LEAVE_METHOD "thing.topo.delete" #define KK_REPORT_ATTRIBUTE_TYPE "/thing/event/property/post"
#define KK_REPORT_ATTRIBUTE_METHOD "thing.event.property.post"
#define KK_READ_ATTRIBUTE_METHOD "thing.service.property.get" #define KK_IPC_VERSION "1.0"
#define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add"
#define ZIGBEE_COO_PRODUCT_CODE "2" #define KK_REPORT_DEVICE_LEAVE_METHOD "thing.topo.delete"
#define KK_REPORT_ATTRIBUTE_METHOD "thing.event.property.post"
#define TEST_PRODUCT_CODE "24" #define KK_READ_ATTRIBUTE_METHOD "thing.service.property.get"
#define GW2CCU_PROTOCOL "tcp"
#define ZIGBEE_COO_PRODUCT_CODE "2"
#define TEST_PRODUCT_CODE "24"
#define GW2CCU_PROTOCOL "tcp"
int kk_zcl_onoff_set(jrpc_context * ctx,const char *mac,unsigned char ep,void* data);
int kk_zcl_onoff_set(jrpc_context * ctx,const char *mac,unsigned char ep,void* data);
int kk_sendData2CCU(char* data, int len);
int kk_sendData2CCU(char* data, int len);
#define RPC_KK_TEST_FUNCTION_TABLE \
{(rpc_function*)kk_tsl_property_operation,"/thing/service/property/set"},\
{(rpc_function*)kk_tsl_property_operation,KK_READ_ATTRIBUTE_METHOD}
#define RPC_KK_TEST_FUNCTION_TABLE \
{(rpc_function*)kk_tsl_property_operation,"/thing/service/property/set"},\
{(rpc_function*)kk_tsl_property_operation,KK_READ_ATTRIBUTE_METHOD}
enum {
WC_normal_dir = 0,//"正转"
WC_reversed_dir = 1,//"反转"
WC_calibration_mode = 2,//"校验"
}windowCoveringMode;
#endif
#endif
#include "kk_tsl_zigbee_map.h"
#include "kk_test.h"
#include "kk_product_code.h"
kk_tsl_zigbee_map_t g_tsl_zigbee_map[] = {
{"NetChannelState",KK_DUMMY_EP,kk_permit_join,0xffff,0xffff,NULL},
{"WorkMode",KK_PRIMARY_EP,kk_tsl_set_windowCovering_mode,ZCL_WINDOW_COVERING_CLUSTER_ID,ZCL_MODE_ATTRIBUTE_ID,kk_tsl_report_windowCovering_mode},
{"Position",KK_PRIMARY_EP,kk_tsl_set_windowCovering_position,ZCL_WINDOW_COVERING_CLUSTER_ID,ZCL_CURRENT_LIFT_PERCENTAGE_ATTRIBUTE_ID,kk_tsl_report_windowCovering_position},
};
kk_tsl_zigbee_map_glb_t g_tsl_zigbee_map_glb[] = {
{"3001","PowerSwitch_1",KK_EP(1),kk_tsl_set_gloabl_OnOff,ZCL_ON_OFF_CLUSTER_ID,ZCL_ON_OFF_ATTRIBUTE_ID,kk_tsl_report_global_onoff},//开
{"3002","PowerSwitch_2",KK_EP(2),kk_tsl_set_gloabl_OnOff,ZCL_ON_OFF_CLUSTER_ID,ZCL_ON_OFF_ATTRIBUTE_ID,kk_tsl_report_global_onoff},//开
{"3003","PowerSwitch_3",KK_EP(3),kk_tsl_set_gloabl_OnOff,ZCL_ON_OFF_CLUSTER_ID,ZCL_ON_OFF_ATTRIBUTE_ID,kk_tsl_report_global_onoff},//开
{"3005","OperationMode",KK_PRIMARY_EP,kk_tsl_set_windowCovering_OperationMode,ZCL_ON_OFF_CLUSTER_ID,ZCL_ON_OFF_ATTRIBUTE_ID,kk_tsl_report_global_onoff},//开
};
int kk_get_tsl_index(unsigned char EP,unsigned short clusterId,unsigned short attributeId)
{
int i;
for(i=0;i<sizeof(g_tsl_zigbee_map)/sizeof(kk_tsl_zigbee_map_t);i++){
if( EP == g_tsl_zigbee_map[i].endpoint &&
clusterId == g_tsl_zigbee_map[i].clusterId &&
attributeId == g_tsl_zigbee_map[i].attributeId){
return i;
}
}
return -1;
}
int kk_get_tsl_glb_index(const char *pCode,unsigned char EP,unsigned short clusterId,unsigned short attributeId)
{
int i;
for(i=0;i<sizeof(g_tsl_zigbee_map_glb)/sizeof(kk_tsl_zigbee_map_glb_t);i++){
if( EP == g_tsl_zigbee_map_glb[i].map.endpoint &&
clusterId == g_tsl_zigbee_map_glb[i].map.clusterId &&
attributeId == g_tsl_zigbee_map_glb[i].map.attributeId &&
strstr(g_tsl_zigbee_map_glb[i].ProductCode,pCode)!=NULL){
return i;
}
}
return -1;
}
int kk_get_tsl_num(void)
{
return sizeof(g_tsl_zigbee_map) / sizeof(kk_tsl_zigbee_map_t);
}
int kk_get_tsl_glb_num(void)
{
return sizeof(g_tsl_zigbee_map_glb) / sizeof(kk_tsl_zigbee_map_glb_t);
}
#ifndef _KK_ZIGBEE_MAP_H_
#define _KK_ZIGBEE_MAP_H_
#include "RPC_API.h"
#include "kk_tsl_common.h"
#define KK_EP(x) (x)
#define KK_DUMMY_EP KK_EP(0)
#define KK_PRIMARY_EP KK_EP(1)
#define KK_DUMMY_CLUSTER_ID 0xffff
#define KK_DUMMY_ATTRIBUTE_ID 0xffff
typedef int (*zigbee_property_set)(jrpc_context * ctx,EmberNodeId node,unsigned char ep,void* data);
typedef int(*kk_zigbee_property_report)(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,EmberAfAttributeId attributeId,uint8_t dataType,uint8_t len,uint8_t *data);
typedef struct{
char* Identity;
unsigned char endpoint;
zigbee_property_set zigbee_set;
unsigned short clusterId;
unsigned short attributeId;
kk_zigbee_property_report zigbee_report;
}kk_tsl_zigbee_map_t;
typedef struct{
char* ProductCode;
kk_tsl_zigbee_map_t map;
}kk_tsl_zigbee_map_glb_t;
extern kk_tsl_zigbee_map_t g_tsl_zigbee_map[];
extern kk_tsl_zigbee_map_glb_t g_tsl_zigbee_map_glb[];
int kk_get_tsl_index(unsigned char EP,unsigned short clusterId,unsigned short attributeId);
int kk_get_tsl_num(void);
int kk_get_tsl_glb_index(const char *pCode,unsigned char EP,unsigned short clusterId,unsigned short attributeId);
int kk_get_tsl_glb_num(void);
#endif
...@@ -222,23 +222,26 @@ static int eval_request(struct jrpc_server *server, cJSON *root) { ...@@ -222,23 +222,26 @@ static int eval_request(struct jrpc_server *server, cJSON *root) {
return -1; return -1;
} }
#define KK_THING_OTA_DEVICE_UPGRADE "/ota/device/upgrade"
void _cb(void* data){
if (data != NULL){
//printf("plat2mid_cb: %s RECEIVED \r\n", data);
void _cb(void* data, int len, char* chlmark){
if (data != NULL){
printf("plat_cb: %s RECEIVED \r\n", data);
cJSON *root; cJSON *root;
char *end_ptr = NULL; char *end_ptr = NULL;
if ((root = rpc_cJSON_Parse_Stream(data, &end_ptr)) != NULL) { if ((root = rpc_cJSON_Parse_Stream(data, &end_ptr)) != NULL) {
if (1) {
char * str_result = rpc_cJSON_Print(root);
printf("Valid JSON Received:\n%s\n", str_result);
free(str_result);
}
if (root->type == cJSON_Object) { if (root->type == cJSON_Object) {
eval_request(&my_server, root); cJSON* info = rpc_cJSON_GetObjectItem(root, "info");
if (info!=NULL&&strstr(rpc_cJSON_GetObjectItem(info, "msgType")->valuestring,KK_THING_OTA_DEVICE_UPGRADE) != NULL){
kk_ota_process(root);
}else{
eval_request(&my_server, root);
}
} }
//shift processed request, discarding it //shift processed request, discarding it
...@@ -459,17 +462,25 @@ int search_ccu(char devcode[33], char ip[16], int* port){ ...@@ -459,17 +462,25 @@ int search_ccu(char devcode[33], char ip[16], int* port){
void* _msg_topo_add(){ void* _msg_topo_add(){
char msgFmt[] = "{\"info\":{\"msgtype\":\"/thing/topo/add\",\"productCode\":\"%s\",\"deviceCode\":\"%s\"},\ char msgFmt[] = "{\"info\":{\"msgtype\":\"/thing/topo/add\",\"productCode\":\"%s\",\"deviceCode\":\"%s\"},\
\"payload\":{\"msgId\":\"%d\",\"version\":\"1.0\",\"params\":{\"deviceCode\":\"%s\",\"productCode\":\"%s\",\"mac\":\"%s\"}}}"; \"payload\":{\"msgId\":\"%d\",\"version\":\"1.0\",\"params\":{\"deviceCode\":\"%s\",\"productCode\":\"%s\",\"mac\":\"%s\"}}}";
char msg[520] = {0}; //char msg[520] = {0};
char* msg = NULL;
char* macString = kk_get_gw_mac(); char* macString = kk_get_gw_mac();
if (macString == NULL){ if (macString == NULL){
printf("[%s] get mac fail\n",__FUNCTION__); printf("[%s] get mac fail\n",__FUNCTION__);
return NULL; return NULL;
} }
msg = malloc(520);
if (msg == NULL){
printf("[%s] msg malloc fail\n",__FUNCTION__);
return NULL;
}
sprintf(msg, msgFmt, GW_PRODUCT_CODE, macString, 1, macString, GW_PRODUCT_CODE,macString); sprintf(msg, msgFmt, GW_PRODUCT_CODE, macString, 1, macString, GW_PRODUCT_CODE,macString);
cJSON* msgObj = cJSON_Parse(msg); //cJSON* msgObj = cJSON_Parse(msg);
char* outbuf = cJSON_Print(msgObj); //char* outbuf = cJSON_Print(msgObj);
cJSON_Delete(msgObj); //cJSON_Delete(msgObj);
return outbuf; //return outbuf;
return msg;
} }
...@@ -480,18 +491,27 @@ void* _msg_event_property_post(char ip[16], int port){ ...@@ -480,18 +491,27 @@ void* _msg_event_property_post(char ip[16], int port){
\"OnlineDetectionState\":%d,\"SN\":\"%s\",\"IPAddress\":\"%s\",\"MACAddress\":\"%s\",\"Port\":%d},\ \"OnlineDetectionState\":%d,\"SN\":\"%s\",\"IPAddress\":\"%s\",\"MACAddress\":\"%s\",\"Port\":%d},\
\"time\":1524448722000,\"method\":\"thing.event.property.post\"}\ \"time\":1524448722000,\"method\":\"thing.event.property.post\"}\
}"; }";
char msg[620] = {0}; //char msg[620] = {0};
char* msg = NULL;
char* macString = kk_get_gw_mac(); char* macString = kk_get_gw_mac();
if (macString == NULL){ if (macString == NULL){
printf("[%s] get mac fail\n",__FUNCTION__); printf("[%s] get mac fail\n",__FUNCTION__);
return NULL; return NULL;
} }
msg = malloc(620);
if (msg == NULL){
printf("[%s] msg malloc fail\n",__FUNCTION__);
return NULL;
}
sprintf(msg, msgFmt, GW_PRODUCT_CODE, macString, sprintf(msg, msgFmt, GW_PRODUCT_CODE, macString,
1, 0, 0, 0, "12345", ip,macString,port); 1, 0, 0, 0, "12345", ip,macString,port);
cJSON* msgObj = cJSON_Parse(msg); //cJSON* msgObj = cJSON_Parse(msg);
char* outbuf = cJSON_Print(msgObj); //char* outbuf = cJSON_Print(msgObj);
cJSON_Delete(msgObj); //cJSON_Delete(msgObj);
return outbuf; //return outbuf;
return msg;
} }
......
...@@ -100,7 +100,6 @@ void kk_message_process(char *messageString) ...@@ -100,7 +100,6 @@ void kk_message_process(char *messageString)
setTxPower(10); setTxPower(10);
} }
if(MEMCOMPARE(messageString,"AT+GETINFO\r\n",len)==0){ if(MEMCOMPARE(messageString,"AT+GETINFO\r\n",len)==0){
kk_print_network_info(); kk_print_network_info();
} }
......
CONFIG_TPL := $(CURDIR)/../../../.config
CONFIG_VENDOR := $(shell grep -m 1 "VENDOR *:" $(CONFIG_TPL) 2>/dev/null|awk '{ print $$NF }')
export CONFIG_VENDOR
TOP_DIR_ZIGBEE ?= $(CURDIR) TOP_DIR_ZIGBEE ?= $(CURDIR)
ZIGBEE_MAKEFILE_PATH ?= $(TOP_DIR_ZIGBEE)/app/builder/Z3GatewayHost/ ZIGBEE_MAKEFILE_PATH ?= $(TOP_DIR_ZIGBEE)/app/builder/Z3GatewayHost/
all: all:
@cd $(ZIGBEE_MAKEFILE_PATH) && $(MAKE); @cd $(ZIGBEE_MAKEFILE_PATH) && $(MAKE);
\ No newline at end of file
// Copyright 2016 Silicon Laboratories, Inc. *80* // Copyright 2016 Silicon Laboratories, Inc. *80*
#include PLATFORM_HEADER #include PLATFORM_HEADER
#ifdef EZSP_HOST #ifdef EZSP_HOST
// Includes needed for functions related to the EZSP host // Includes needed for functions related to the EZSP host
#include "stack/include/error.h" #include "stack/include/error.h"
#include "stack/include/ember-types.h" #include "stack/include/ember-types.h"
#include "app/util/ezsp/ezsp-protocol.h" #include "app/util/ezsp/ezsp-protocol.h"
#include "app/util/ezsp/ezsp.h" #include "app/util/ezsp/ezsp.h"
#include "app/util/ezsp/serial-interface.h" #include "app/util/ezsp/serial-interface.h"
#include "app/util/zigbee-framework/zigbee-device-common.h" #include "app/util/zigbee-framework/zigbee-device-common.h"
#else #else
#include "stack/include/ember.h" #include "stack/include/ember.h"
#endif #endif
#include "af.h" #include "af.h"
#include "af-main.h" #include "af-main.h"
#include "attribute-storage.h" #include "attribute-storage.h"
#include "common.h" #include "common.h"
#include "hal/hal.h" #include "hal/hal.h"
#include "app/util/serial/command-interpreter2.h" #include "app/util/serial/command-interpreter2.h"
#include "stack/include/event.h" #include "stack/include/event.h"
#include "app/framework/plugin/concentrator/source-route-host.h" #include "app/framework/plugin/concentrator/source-route-host.h"
#include "app/framework/plugin/device-table/device-table.h" #include "app/framework/plugin/device-table/device-table.h"
#include "app/framework/plugin/device-table/device-table-internal.h" #include "app/framework/plugin/device-table/device-table-internal.h"
#include "app/framework/util/util.h" #include "app/framework/util/util.h"
#include <stdlib.h> #include <stdlib.h>
#include <kk_test.h> #include <kk_test.h>
void emAfDeviceTableSave(void); void emAfDeviceTableSave(void);
void emAfDeviceTableLoad(void); void emAfDeviceTableLoad(void);
// Framework message send global data // Framework message send global data
extern uint8_t appZclBuffer[]; extern uint8_t appZclBuffer[];
extern uint16_t appZclBufferLen; extern uint16_t appZclBufferLen;
extern bool zclCmdIsBuilt; extern bool zclCmdIsBuilt;
extern EmberApsFrame globalApsFrame; extern EmberApsFrame globalApsFrame;
extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint, extern void emAfApsFrameEndpointSetup(uint8_t srcEndpoint,
uint8_t dstEndpoint); uint8_t dstEndpoint);
static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE]; static EmberAfPluginDeviceTableEntry deviceTable[EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE];
EmberStatus emberAfGetChildData(uint8_t index, EmberStatus emberAfGetChildData(uint8_t index,
EmberChildData *childData); EmberChildData *childData);
// Device discovery global declarations // Device discovery global declarations
void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId); void emAfDeviceTableInitiateRouteRepair(EmberNodeId nodeId);
static void clearDeviceTableIndex(uint16_t index); static void clearDeviceTableIndex(uint16_t index);
EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void) EmberAfPluginDeviceTableEntry* emberAfDeviceTablePointer(void)
{ {
return deviceTable; return deviceTable;
} }
uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index) uint16_t emberAfDeviceTableGetNodeIdFromIndex(uint16_t index)
{ {
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].nodeId; return deviceTable[index].nodeId;
} }
uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index) uint8_t emAfDeviceTableGetFirstEndpointFromIndex(uint16_t index)
{ {
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
return deviceTable[index].endpoint; return deviceTable[index].endpoint;
} }
static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) static void matchReverseEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < EUI64_SIZE; i++) { for (i = 0; i < EUI64_SIZE; i++) {
if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) { if (eui64a[i] != eui64b[(EUI64_SIZE - 1) - i]) {
return; return;
} }
} }
emberAfCorePrintln("MATCH_EUI: EUI matches backwards"); emberAfCorePrintln("MATCH_EUI: EUI matches backwards");
emberAfCorePrint("A:"); emberAfCorePrint("A:");
emAfDeviceTablePrintEUI64(eui64a); emAfDeviceTablePrintEUI64(eui64a);
emberAfCorePrint(" B:"); emberAfCorePrint(" B:");
emAfDeviceTablePrintEUI64(eui64b); emAfDeviceTablePrintEUI64(eui64b);
emberAfCorePrintln(""); emberAfCorePrintln("");
} }
static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) static void checkNullEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < EUI64_SIZE; i++) { for (i = 0; i < EUI64_SIZE; i++) {
if (eui64a[i] != 0xff if (eui64a[i] != 0xff
|| eui64b[i] != 0xff) { || eui64b[i] != 0xff) {
return; return;
} }
} }
emberAfCorePrintln("MatchEUI: two null EUI"); emberAfCorePrintln("MatchEUI: two null EUI");
} }
static bool matchEui64(EmberEUI64 a, EmberEUI64 b) static bool matchEui64(EmberEUI64 a, EmberEUI64 b)
{ {
checkNullEui64(a, b); checkNullEui64(a, b);
if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) { if (MEMCOMPARE(a, b, EUI64_SIZE) == 0) {
return true; return true;
} else { } else {
// Test to see if the EUI64 is backwards // Test to see if the EUI64 is backwards
matchReverseEui64(a, b); matchReverseEui64(a, b);
return false; return false;
} }
} }
bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b) bool emberAfDeviceTableMatchEui64(EmberEUI64 eui64a, EmberEUI64 eui64b)
{ {
return matchEui64(eui64a, eui64b); return matchEui64(eui64a, eui64b);
} }
static void unsetEui64(EmberEUI64 eui64) static void unsetEui64(EmberEUI64 eui64)
{ {
uint8_t i; uint8_t i;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
eui64[i] = 0xff; eui64[i] = 0xff;
} }
} }
static void clearDeviceTableIndex(uint16_t index) static void clearDeviceTableIndex(uint16_t index)
{ {
uint8_t i; uint8_t i;
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; deviceTable[index].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
unsetEui64(deviceTable[index].eui64); unsetEui64(deviceTable[index].eui64);
deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL; deviceTable[index].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_NULL;
deviceTable[index].endpoint = 0; deviceTable[index].endpoint = 0;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; i++) {
deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID; deviceTable[index].clusterIds[i] = ZCL_NULL_CLUSTER_ID;
} }
deviceTable[index].clusterOutStartPosition = 0; deviceTable[index].clusterOutStartPosition = 0;
} }
void emAfPluginDeviceTableDeleteEntry(uint16_t index) void emAfPluginDeviceTableDeleteEntry(uint16_t index)
{ {
uint16_t currentIndex; uint16_t currentIndex;
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
currentIndex = index; currentIndex = index;
// Need to compute the next index before deleting the current one. Or else // Need to compute the next index before deleting the current one. Or else
// the call to next endpoint will yield a bogus result. // the call to next endpoint will yield a bogus result.
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
clearDeviceTableIndex(currentIndex); clearDeviceTableIndex(currentIndex);
emberAfPluginDeviceTableIndexRemovedCallback(currentIndex); emberAfPluginDeviceTableIndexRemovedCallback(currentIndex);
} }
} }
void emAfDeviceTableInit(void) void emAfDeviceTableInit(void)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
clearDeviceTableIndex(i); clearDeviceTableIndex(i);
} }
} }
void emberAfDeviceTableClear(void) void emberAfDeviceTableClear(void)
{ {
emAfDeviceTableInit(); emAfDeviceTableInit();
emAfDeviceTableSave(); emAfDeviceTableSave();
//emberAfPluginDeviceTableClearedCallback(); //emberAfPluginDeviceTableClearedCallback();
} }
uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64, uint16_t emberAfDeviceTableGetIndexFromEui64AndEndpoint(EmberEUI64 eui64,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(deviceTable[i].eui64, eui64) if (matchEui64(deviceTable[i].eui64, eui64)
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emberAfDeviceTableGetNodeIdFromEui64(EmberEUI64 eui64) uint16_t emberAfDeviceTableGetNodeIdFromEui64(EmberEUI64 eui64)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(deviceTable[i].eui64, eui64) ) { if (matchEui64(deviceTable[i].eui64, eui64) ) {
return deviceTable[i].nodeId; return deviceTable[i].nodeId;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
} }
bool emberAfDeviceTableGetEui64FromNodeId(EmberNodeId emberNodeId, EmberEUI64 eui64) bool emberAfDeviceTableGetEui64FromNodeId(EmberNodeId emberNodeId, EmberEUI64 eui64)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId) { if (deviceTable[i].nodeId == emberNodeId) {
MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE); MEMCOPY(eui64, deviceTable[i].eui64, EUI64_SIZE);
return true; return true;
} }
} }
return false; return false;
} }
uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId) uint16_t emberAfDeviceTableGetIndexFromNodeId(EmberNodeId emberNodeId)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId) { if (deviceTable[i].nodeId == emberNodeId) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void) uint16_t emAfDeviceTableFindFreeDeviceTableIndex(void)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId, uint16_t emberAfDeviceTableGetEndpointFromNodeIdAndEndpoint(EmberNodeId emberNodeId,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == emberNodeId if (deviceTable[i].nodeId == emberNodeId
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
void emAfDeviceTableCopyDeviceTableEntry(uint16_t fromIndex, uint16_t toIndex) void emAfDeviceTableCopyDeviceTableEntry(uint16_t fromIndex, uint16_t toIndex)
{ {
EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]); EmberAfPluginDeviceTableEntry* from = &(deviceTable[fromIndex]);
EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]); EmberAfPluginDeviceTableEntry* to = &(deviceTable[toIndex]);
// make sure the fromIndex is in the valud range. // make sure the fromIndex is in the valud range.
assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(fromIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
// make sure the fromIndex has a valid entry // make sure the fromIndex has a valid entry
assert(deviceTable[fromIndex].nodeId assert(deviceTable[fromIndex].nodeId
!= EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
// make sure the toIndex is in the valud range. // make sure the toIndex is in the valud range.
assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE); assert(toIndex < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE);
MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry)); MEMCOPY(to, from, sizeof(EmberAfPluginDeviceTableEntry));
} }
uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index) uint8_t emAfDeviceTableNumberOfEndpointsFromIndex(uint16_t index)
{ {
uint8_t count = 0; uint8_t count = 0;
uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index); uint16_t currentNodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == currentNodeId) { if (deviceTable[i].nodeId == currentNodeId) {
count++; count++;
} }
} }
return count; return count;
} }
static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index) static uint16_t findIndexFromNodeIdAndIndex(uint16_t nodeId, uint16_t index)
{ {
uint16_t i; uint16_t i;
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(i)) { if (nodeId == emberAfDeviceTableGetNodeIdFromIndex(i)) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
static uint16_t findIndexFromEui64AndIndex(EmberEUI64 eui64, uint16_t index) static uint16_t findIndexFromEui64AndIndex(EmberEUI64 eui64, uint16_t index)
{ {
uint16_t i; uint16_t i;
for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = index; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (matchEui64(eui64, deviceTable[i].eui64)) { if (matchEui64(eui64, deviceTable[i].eui64)) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId) uint16_t emAfDeviceTableFindFirstEndpointNodeId(uint16_t nodeId)
{ {
return findIndexFromNodeIdAndIndex(nodeId, 0); return findIndexFromNodeIdAndIndex(nodeId, 0);
} }
uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index) uint16_t emAfDeviceTableFindNextEndpoint(uint16_t index)
{ {
return findIndexFromEui64AndIndex(deviceTable[index].eui64, return findIndexFromEui64AndIndex(deviceTable[index].eui64,
index + 1); index + 1);
} }
uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64) uint16_t emAfDeviceTableFindFirstEndpointIeee(EmberEUI64 eui64)
{ {
return findIndexFromEui64AndIndex(eui64, 0); return findIndexFromEui64AndIndex(eui64, 0);
} }
uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64) uint16_t emberAfDeviceTableGetFirstIndexFromEui64(EmberEUI64 eui64)
{ {
return emAfDeviceTableFindFirstEndpointIeee(eui64); return emAfDeviceTableFindFirstEndpointIeee(eui64);
} }
EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint) EmberAfStatus emAfDeviceTableAddNewEndpoint(uint16_t index, uint8_t newEndpoint)
{ {
uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex(); uint16_t newIndex = emAfDeviceTableFindFreeDeviceTableIndex();
if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { if (newIndex == EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
return EMBER_ZCL_STATUS_FAILURE; return EMBER_ZCL_STATUS_FAILURE;
} }
emAfDeviceTableCopyDeviceTableEntry(index, newIndex); emAfDeviceTableCopyDeviceTableEntry(index, newIndex);
deviceTable[newIndex].endpoint = newEndpoint; deviceTable[newIndex].endpoint = newEndpoint;
return EMBER_ZCL_STATUS_SUCCESS; return EMBER_ZCL_STATUS_SUCCESS;
} }
uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId, uint16_t emAfDeviceTableFindIndexNodeIdEndpoint(uint16_t nodeId,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t i; uint16_t i;
for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (i = 0; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
if (deviceTable[i].nodeId == nodeId if (deviceTable[i].nodeId == nodeId
&& deviceTable[i].endpoint == endpoint) { && deviceTable[i].endpoint == endpoint) {
return i; return i;
} }
} }
return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX; return EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX;
} }
EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index) EmberAfPluginDeviceTableEntry *emberAfDeviceTableFindDeviceTableEntry(uint16_t index)
{ {
assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID); assert(index < EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID);
return &(deviceTable[index]); return &(deviceTable[index]);
} }
void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId) void emAfDeviceTableUpdateNodeId(uint16_t currentNodeId, uint16_t newNodeId)
{ {
uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId); uint16_t index = emAfDeviceTableFindFirstEndpointNodeId(currentNodeId);
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
deviceTable[index].nodeId = newNodeId; deviceTable[index].nodeId = newNodeId;
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
} }
} }
void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState) void emAfDeviceTableUpdateDeviceState(uint16_t index, uint8_t newState)
{ {
while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { while (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
deviceTable[index].state = newState; deviceTable[index].state = newState;
index = emAfDeviceTableFindNextEndpoint(index); index = emAfDeviceTableFindNextEndpoint(index);
} }
} }
uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index) uint32_t emberAfDeviceTableTimeSinceLastMessage(uint16_t index)
{ {
uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick(); uint32_t timeSinceLastMessage = halCommonGetInt32uMillisecondTick();
timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp; timeSinceLastMessage -= deviceTable[index].lastMsgTimestamp;
timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND; timeSinceLastMessage /= MILLISECOND_TICKS_PER_SECOND;
return timeSinceLastMessage; return timeSinceLastMessage;
} }
// AF Framework callbacks. This is where the plugin implements the callbacks. // AF Framework callbacks. This is where the plugin implements the callbacks.
void emberAfPluginDeviceTableInitCallback(void) void emberAfPluginDeviceTableInitCallback(void)
{ {
emAfDeviceTableInit(); emAfDeviceTableInit();
// Load on Init // Load on Init
emAfDeviceTableLoad(); emAfDeviceTableLoad();
emberAfPluginDeviceTableInitialized(); emberAfPluginDeviceTableInitialized();
} }
void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status) void emberAfPluginDeviceTableStackStatusCallback(EmberStatus status)
{ {
// If we leave the network, this plugin needs to clear out all of its device // If we leave the network, this plugin needs to clear out all of its device
// state. // state.
emberAfCorePrintln("%d %d", status, emberNetworkState()); emberAfCorePrintln("%d %d", status, emberNetworkState());
if (status == EMBER_NETWORK_DOWN if (status == EMBER_NETWORK_DOWN
&& emberNetworkState() == EMBER_NO_NETWORK) { && emberNetworkState() == EMBER_NO_NETWORK) {
emberAfCorePrintln("DeviceTable: Clear State"); emberAfCorePrintln("DeviceTable: Clear State");
emberAfDeviceTableClear(); emberAfDeviceTableClear();
// //kk_device_table_clear();
} }
} }
// -------------------------------- // --------------------------------
// Save/Load the devices // Save/Load the devices
void emAfDeviceTableSave(void) void emAfDeviceTableSave(void)
{ {
#if defined(EZSP_HOST) && !defined(EMBER_TEST) #if defined(EZSP_HOST) && !defined(EMBER_TEST)
FILE *fp; FILE *fp;
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
uint8_t i; uint8_t i;
uint8_t j; uint8_t j;
// Save device table // Save device table
fp = fopen("devices.txt", "w"); fp = fopen("devices.txt", "w");
for (i = 0; for (i = 0;
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE;
i++) { i++) {
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
fprintf(fp, fprintf(fp,
"%x %x %x ", "%x %x %x ",
deviceTable[i].nodeId, deviceTable[i].nodeId,
deviceTable[i].endpoint, deviceTable[i].endpoint,
deviceTable[i].deviceId); deviceTable[i].deviceId);
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
fprintf(fp, "%x ", deviceTable[i].eui64[j]); fprintf(fp, "%x ", deviceTable[i].eui64[j]);
} }
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
fprintf(fp, "%x ", deviceTable[i].clusterIds[j]); fprintf(fp, "%x ", deviceTable[i].clusterIds[j]);
} }
fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition); fprintf(fp, "%d ", deviceTable[i].clusterOutStartPosition);
} }
} }
// Write ffffffff to mark the end // Write ffffffff to mark the end
fprintf(fp, "\r\nffffffff\r\n"); fprintf(fp, "\r\nffffffff\r\n");
fclose(fp); fclose(fp);
#endif // defined(EZSP_HOST) && !defined(EMBER_TEST) #endif // defined(EZSP_HOST) && !defined(EMBER_TEST)
} }
void emAfDeviceTableLoad(void) void emAfDeviceTableLoad(void)
{ {
#if defined(EZSP_HOST) && !defined(EMBER_TEST) #if defined(EZSP_HOST) && !defined(EMBER_TEST)
uint16_t i; uint16_t i;
uint16_t j; uint16_t j;
FILE *fp; FILE *fp;
unsigned int data, data2, data3; unsigned int data, data2, data3;
EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer(); EmberAfPluginDeviceTableEntry *deviceTable = emberAfDeviceTablePointer();
fp = fopen("devices.txt", "r"); fp = fopen("devices.txt", "r");
if (!fp) { if (!fp) {
return; return;
} }
for (i = 0; for (i = 0;
i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE && feof(fp) == false;
i++) { i++) {
fscanf(fp, "%x %x %x", &data2, &data, &data3); fscanf(fp, "%x %x %x", &data2, &data, &data3);
deviceTable[i].endpoint = (uint8_t) data; deviceTable[i].endpoint = (uint8_t) data;
deviceTable[i].nodeId = (uint16_t) data2; deviceTable[i].nodeId = (uint16_t) data2;
deviceTable[i].deviceId = (uint16_t) data3; deviceTable[i].deviceId = (uint16_t) data3;
if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) { if (deviceTable[i].nodeId != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
fscanf(fp, "%x", &data); fscanf(fp, "%x", &data);
deviceTable[i].eui64[j] = (uint8_t) data; deviceTable[i].eui64[j] = (uint8_t) data;
} }
for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) { for (j = 0; j < EMBER_AF_PLUGIN_DEVICE_TABLE_CLUSTER_SIZE; j++) {
fscanf(fp, "%x", &data); fscanf(fp, "%x", &data);
deviceTable[i].clusterIds[j] = (uint16_t) data; deviceTable[i].clusterIds[j] = (uint16_t) data;
} }
fscanf(fp, "%d", &data); fscanf(fp, "%d", &data);
deviceTable[i].clusterOutStartPosition = (uint16_t) data; deviceTable[i].clusterOutStartPosition = (uint16_t) data;
deviceTable[i].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_JOINED; deviceTable[i].state = EMBER_AF_PLUGIN_DEVICE_TABLE_STATE_JOINED;
//kk_sub_tsl_add(deviceTable[i].eui64,TEST_PRODUCT_CODE); //kk_sub_tsl_add(deviceTable[i].eui64,TEST_PRODUCT_CODE);
} }
deviceTable[i].lastMsgTimestamp = halCommonGetInt32uMillisecondTick(); deviceTable[i].lastMsgTimestamp = halCommonGetInt32uMillisecondTick();
} }
fclose(fp); fclose(fp);
// Set the rest of the device table to null. // Set the rest of the device table to null.
for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) { for (; i < EMBER_AF_PLUGIN_DEVICE_TABLE_DEVICE_TABLE_SIZE; i++) {
deviceTable[i].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; deviceTable[i].nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
} }
#endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST) #endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST)
} }
// -------------------------------- // --------------------------------
// Message send section // Message send section
// Command to send the CIE IEEE address to the IAS Zone cluster // Command to send the CIE IEEE address to the IAS Zone cluster
void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint) void emAfDeviceTableSendCieAddressWrite(EmberNodeId nodeId, uint8_t endpoint)
{ {
EmberEUI64 eui64; EmberEUI64 eui64;
uint8_t outgoingBuffer[15]; uint8_t outgoingBuffer[15];
uint32_t i; uint32_t i;
emberAfGetEui64(eui64); emberAfGetEui64(eui64);
globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS; globalApsFrame.options = EMBER_AF_DEFAULT_APS_OPTIONS;
globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID; globalApsFrame.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
globalApsFrame.sourceEndpoint = 0x01; globalApsFrame.sourceEndpoint = 0x01;
globalApsFrame.destinationEndpoint = endpoint; globalApsFrame.destinationEndpoint = endpoint;
outgoingBuffer[0] = 0x00; outgoingBuffer[0] = 0x00;
outgoingBuffer[1] = emberAfNextSequence(); outgoingBuffer[1] = emberAfNextSequence();
outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID; outgoingBuffer[2] = ZCL_WRITE_ATTRIBUTES_COMMAND_ID;
outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[3] = LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID); outgoingBuffer[4] = HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID);
outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE; outgoingBuffer[5] = ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
outgoingBuffer[6 + i] = eui64[i]; outgoingBuffer[6 + i] = eui64[i];
} }
emberAfSendUnicast(EMBER_OUTGOING_DIRECT, emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
nodeId, nodeId,
&globalApsFrame, &globalApsFrame,
14, 14,
outgoingBuffer); outgoingBuffer);
} }
void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index, void emberAfDeviceTableCliIndexSendWithEndpoint(uint16_t index,
uint8_t endpoint) uint8_t endpoint)
{ {
EmberNodeId nodeId; EmberNodeId nodeId;
EmberStatus status; EmberStatus status;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index); nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint); emAfApsFrameEndpointSetup(emberAfPrimaryEndpoint(), endpoint);
status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT, status = emberAfSendUnicast(EMBER_OUTGOING_DIRECT,
nodeId, nodeId,
&globalApsFrame, &globalApsFrame,
appZclBufferLen, appZclBufferLen,
appZclBuffer); appZclBuffer);
zclCmdIsBuilt = false; zclCmdIsBuilt = false;
} }
void emberAfDeviceTableCliIndexSend(uint16_t index) void emberAfDeviceTableCliIndexSend(uint16_t index)
{ {
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint); emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
} }
void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint) void emberAfDeviceTableSend(EmberEUI64 eui64, uint8_t endpoint)
{ {
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64); uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) { if (index != EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_INDEX) {
emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint); emberAfDeviceTableCliIndexSendWithEndpoint(index, endpoint);
} }
} }
void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index, void emberAfDeviceTableCommandIndexSendWithEndpoint(uint16_t index,
uint8_t endpoint) uint8_t endpoint)
{ {
EmberNodeId nodeId; EmberNodeId nodeId;
EmberStatus status; EmberStatus status;
nodeId = emberAfDeviceTableGetNodeIdFromIndex(index); nodeId = emberAfDeviceTableGetNodeIdFromIndex(index);
if (emberAfCurrentCommand() == NULL) { if (emberAfCurrentCommand() == NULL) {
emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint(); emAfCommandApsFrame->sourceEndpoint = emberAfPrimaryEndpoint();
} else { } else {
emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint(); emAfCommandApsFrame->sourceEndpoint = emberAfCurrentEndpoint();
} }
emAfCommandApsFrame->destinationEndpoint = endpoint; emAfCommandApsFrame->destinationEndpoint = endpoint;
emberAfCorePrintln("device table send with ep: 0x%2X, %d", emberAfCorePrintln("device table send with ep: 0x%2X, %d",
nodeId, nodeId,
endpoint); endpoint);
status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId); status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, nodeId);
zclCmdIsBuilt = false; zclCmdIsBuilt = false;
} }
void emberAfDeviceTableCommandIndexSend(uint16_t index) void emberAfDeviceTableCommandIndexSend(uint16_t index)
{ {
uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index); uint8_t endpoint = emAfDeviceTableGetFirstEndpointFromIndex(index);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
} }
void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64, void emberAfDeviceTableCommandSendWithEndpoint(EmberEUI64 eui64,
uint8_t endpoint) uint8_t endpoint)
{ {
uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64); uint16_t index = emberAfDeviceTableGetFirstIndexFromEui64(eui64);
emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint); emberAfDeviceTableCommandIndexSendWithEndpoint(index, endpoint);
} }
...@@ -570,3 +570,42 @@ void emberAfOtaServerSendUpgradeCommandCallback(EmberNodeId dest, ...@@ -570,3 +570,42 @@ void emberAfOtaServerSendUpgradeCommandCallback(EmberNodeId dest,
"error 0x%x", status); "error 0x%x", status);
} }
} }
static int s_ota_server_init = 0;
EmberAfOtaImageId kk_get_imageId(char* filename){
char* oatfile = NULL;
EmberAfOtaImageId id = emberAfOtaStorageIteratorFirstCallback();
do {
oatfile = emAfOtaStorageGetFilepath(&id);
if (oatfile != NULL && strcmp(oatfile, filename) == 0){
return id;
}
id = emberAfOtaStorageIteratorNextCallback();
} while (emberAfIsOtaImageIdValid(&id));
return emberAfInvalidImageId;
}
void kk_ota_notify(char* filepath){
if (s_ota_server_init == 0){
s_ota_server_init = 1;
emberAfOtaBootloadClusterServerInitCallback(0x00);
}
//add file
emAfOtaReloadStorageDevice();
//TODO:开启通知, 通过mac地址获取dest,endpoint
EmberNodeId dest;
uint8_t endpoint;
EmberAfOtaImageId id;
id = kk_get_imageId(filepath);
emberAfOtaServerSendUpgradeCommandCallback(dest, endpoint, &id);
}
#! /bin/bash #! /bin/sh
#export LD_LIBRARY_PATH=/home/kk/lib
export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):./lib/ #cd /home/kk/lib
./midware & #ln libnanomsg.so libnanomsg.so.5
./kcloud & #ln libev.so libev.so.4
./Z3GatewayHost & /home/kk/kk_midware >/dev/null 2>&1 &
/home/kk/kcloud >/dev/null 2>&1 &
#/home/kk/Z3GatewayHost >/dev/null 2>&1 &
.PHONY: doc detect config reconfig toolchain sub-mods final-out env cmake one help package .PHONY: doc detect config reconfig toolchain sub-mods final-out env cmake one help package
all: detect config toolchain sub-mods final-out all: detect config toolchain sub-mods final-out
$(TOP_Q) \ $(TOP_Q) \
if [ -f $(STAMP_PRJ_CFG) ]; then \ if [ -f $(STAMP_PRJ_CFG) ]; then \
$(RECURSIVE_MAKE) toolchain; \ $(RECURSIVE_MAKE) toolchain; \
rm -f $(STAMP_PRJ_CFG); \ rm -f $(STAMP_PRJ_CFG); \
fi fi
@rm -rf $(STAMP_DIR) @rm -rf $(STAMP_DIR)
RESET_ENV_VARS := \ RESET_ENV_VARS := \
CROSS_PREFIX \ CROSS_PREFIX \
CFLAGS \ CFLAGS \
HOST \ HOST \
LDFLAGS \ LDFLAGS \
help: help:
@echo -e "\033[1;37m[$(RULE_DIR)/docs]\e[0m" @echo -e "\033[1;37m[$(RULE_DIR)/docs]\e[0m"
@echo "" @echo ""
@cat $(RULE_DIR)/docs/Help.md @cat $(RULE_DIR)/docs/Help.md
@echo "" @echo ""
doc: doc:
$(TOP_Q)rm -rf $(DOXYGEN_DIR)/html; mkdir -p $(DOXYGEN_DIR) $(TOP_Q)rm -rf $(DOXYGEN_DIR)/html; mkdir -p $(DOXYGEN_DIR)
$(TOP_Q) \ $(TOP_Q) \
$(SED) \ $(SED) \
-e 's:^PROJECT_NAME.*:PROJECT_NAME = $(PRJ_NAME):g;' \ -e 's:^PROJECT_NAME.*:PROJECT_NAME = $(PRJ_NAME):g;' \
-e 's:^PROJECT_NUMBER.*:PROJECT_NUMBER = $(PRJ_VERSION):g;' \ -e 's:^PROJECT_NUMBER.*:PROJECT_NUMBER = $(PRJ_VERSION):g;' \
-e 's:^OUTPUT_DIRECTORY.*:OUTPUT_DIRECTORY = $(DOXYGEN_DIR):g;' \ -e 's:^OUTPUT_DIRECTORY.*:OUTPUT_DIRECTORY = $(DOXYGEN_DIR):g;' \
build-rules/misc/Doxyfile.tpl > $(OUTPUT_DIR)/.doxygen.cfg build-rules/misc/Doxyfile.tpl > $(OUTPUT_DIR)/.doxygen.cfg
$(TOP_Q)doxygen $(OUTPUT_DIR)/.doxygen.cfg $(TOP_Q)doxygen $(OUTPUT_DIR)/.doxygen.cfg
detect: detect:
@if [ -d .git ]; then \ @if [ -d .git ]; then \
mkdir -p .git/hooks; \ mkdir -p .git/hooks; \
for i in $(RULE_DIR)/hooks/*; do \ for i in $(RULE_DIR)/hooks/*; do \
cp -f $$i .git/hooks && chmod a+x .git/hooks/$$(basename $$i); \ cp -f $$i .git/hooks && chmod a+x .git/hooks/$$(basename $$i); \
done; \ done; \
fi fi
prune: prune:
@echo "$(TOP_DIR).pkgs directory removed!"|grep --color ".*" @echo "$(TOP_DIR).pkgs directory removed!"|grep --color ".*"
@rm -rf $(TOP_DIR).pkgs @rm -rf $(TOP_DIR).pkgs
@$(MAKE) --no-print-directory distclean @$(MAKE) --no-print-directory distclean
unzip: config $(STAMP_BLD_VAR) unzip: config $(STAMP_BLD_VAR)
@echo "Components: " @echo "Components: "
@echo "" @echo ""
@for i in $(ALL_SUB_DIRS); do \ @for i in $(ALL_SUB_DIRS); do \
$(MAKE) --no-print-directory pre-build target-$${i} ; \ $(MAKE) --no-print-directory pre-build target-$${i} ; \
echo -ne "\r. $${i}"; \ echo -ne "\r. $${i}"; \
echo -e " "; \ echo -e " "; \
done done
@echo "" @echo ""
cmake: cmake:
$(TOP_Q)$(MAKE) -s distclean $(TOP_Q)$(MAKE) -s distclean
$(TOP_Q)$(MAKE) -s DEFAULT_BLD=$(RULE_DIR)/misc/config.generic.cmake config $(TOP_Q)$(MAKE) -s DEFAULT_BLD=$(RULE_DIR)/misc/config.generic.cmake config
$(TOP_Q)$(foreach V,$(INFO_ENV_VARS),$(V)="$($(V))") CFLAGS=$(CFLAGS) \ $(TOP_Q)$(foreach V,$(INFO_ENV_VARS),$(V)="$($(V))") CFLAGS=$(CFLAGS) \
SEP_LIBS="$$(grep -m 1 '^COMP_LIB_FILES' $(STAMP_BLD_ENV) | cut -d' ' -f3-)" \ SEP_LIBS="$$(grep -m 1 '^COMP_LIB_FILES' $(STAMP_BLD_ENV) | cut -d' ' -f3-)" \
bash $(if $(TOP_Q),,-x) $(RULE_DIR)/scripts/gen_top_cmake.sh $(TOP_DIR)/CMakeLists.txt bash $(if $(TOP_Q),,-x) $(RULE_DIR)/scripts/gen_top_cmake.sh $(TOP_DIR)/CMakeLists.txt
$(TOP_Q)for D in $(ALL_SUB_DIRS); do \ $(TOP_Q)for D in $(ALL_SUB_DIRS); do \
echo "+ $${D}"; \ echo "+ $${D}"; \
$(MAKE) --no-print-directory -C $(OUTPUT_DIR)/$${D} cmake; \ $(MAKE) --no-print-directory -C $(OUTPUT_DIR)/$${D} cmake; \
done done
$(TOP_Q)echo "" $(TOP_Q)echo ""
one: COMP_LIB_OBJS = $(foreach V,$(COMP_LIB_COMPONENTS),$(foreach U,$(LIB_OBJS_$(V)),$(V)/$(U))) one: COMP_LIB_OBJS = $(foreach V,$(COMP_LIB_COMPONENTS),$(foreach U,$(LIB_OBJS_$(V)),$(V)/$(U)))
one: one:
$(TOP_Q)$(foreach V,$(INFO_ENV_VARS),$(V)="$($(V))") \ $(TOP_Q)$(foreach V,$(INFO_ENV_VARS),$(V)="$($(V))") \
CFLAGS="$(subst ",,$(CFLAGS))" \ CFLAGS="$(subst ",,$(CFLAGS))" \
ALL_LIBS="$(strip $(foreach V,$(SUBDIRS),$(LIBA_TARGET_$(V))))" \ ALL_LIBS="$(strip $(foreach V,$(SUBDIRS),$(LIBA_TARGET_$(V))))" \
ALL_LIBSO="$(strip $(foreach V,$(SUBDIRS),$(LIBSO_TARGET_$(V))))" \ ALL_LIBSO="$(strip $(foreach V,$(SUBDIRS),$(LIBSO_TARGET_$(V))))" \
ALL_PROG="$(strip $(foreach V,$(SUBDIRS) $(COMP_LIB_COMPONENTS),$(TARGET_$(V))))" \ ALL_PROG="$(strip $(foreach V,$(SUBDIRS) $(COMP_LIB_COMPONENTS),$(TARGET_$(V))))" \
COMP_LIB_OBJS="$(COMP_LIB_OBJS)" \ COMP_LIB_OBJS="$(COMP_LIB_OBJS)" \
bash $(RULE_DIR)/scripts/gen_one_makefile.sh bash $(RULE_DIR)/scripts/gen_one_makefile.sh
config: config:
@mkdir -p $(OUTPUT_DIR) $(STAMP_DIR) $(INSTALL_DIR) @mkdir -p $(OUTPUT_DIR) $(STAMP_DIR) $(INSTALL_DIR)
@mkdir -p $(SYSROOT_BIN) $(SYSROOT_INC) $(SYSROOT_LIB) @mkdir -p $(SYSROOT_BIN) $(SYSROOT_INC) $(SYSROOT_LIB)
$(TOP_Q) \ $(TOP_Q) \
if [ -f $(STAMP_BLD_VAR) ]; then \ if [ -f $(STAMP_BLD_VAR) ]; then \
if [ "$$($(SED) '/[-_/a-zA-Z0-9]* = *..*/d' $(STAMP_BLD_VAR)|wc -l|$(SED) 's:^ *::g')" != "0" ]; then \ if [ "$$($(SED) '/[-_/a-zA-Z0-9]* = *..*/d' $(STAMP_BLD_VAR)|wc -l|$(SED) 's:^ *::g')" != "0" ]; then \
rm -vf $(STAMP_BLD_VAR); \ rm -vf $(STAMP_BLD_VAR); \
fi \ fi \
fi fi
$(TOP_Q)+( \ $(TOP_Q)+( \
if [ -f $(CONFIG_TPL) ]; then \ if [ -f $(CONFIG_TPL) ]; then \
if [ "$(filter comp-lib,$(MAKECMDGOALS))" = "" ]; then \ if [ "$(filter comp-lib,$(MAKECMDGOALS))" = "" ]; then \
printf "BUILDING WITH EXISTING CONFIGURATION:\n\n"; \ printf "BUILDING WITH EXISTING CONFIGURATION:\n\n"; \
command grep -m 1 "VENDOR *:" $(CONFIG_TPL)|cut -c 3-; \ command grep -m 1 "VENDOR *:" $(CONFIG_TPL)|cut -c 3-; \
command grep -m 1 "MODEL *:" $(CONFIG_TPL)|cut -c 3-; \ command grep -m 1 "MODEL *:" $(CONFIG_TPL)|cut -c 3-; \
echo ""; \ echo ""; \
fi \ fi \
else \ else \
if ([ "$(MAKECMDGOALS)" = "all" ]) || ([ "$(DEFAULT_BLD)" != "" ] && [ -f $(DEFAULT_BLD) ] && \ if ([ "$(MAKECMDGOALS)" = "all" ]) || ([ "$(DEFAULT_BLD)" != "" ] && [ -f $(DEFAULT_BLD) ] && \
([ "$(DEFAULT_BLD)" = "$(RULE_DIR)/misc/config.generic.default" ] \ ([ "$(DEFAULT_BLD)" = "$(RULE_DIR)/misc/config.generic.default" ] \
|| [ "$(MAKECMDGOALS)" = "" ] || [ "$(MAKECMDGOALS)" = "config" ])); then \ || [ "$(MAKECMDGOALS)" = "" ] || [ "$(MAKECMDGOALS)" = "config" ])); then \
printf "# Automatically Generated Section End\n\n" >> $(CONFIG_TPL); \ printf "# Automatically Generated Section End\n\n" >> $(CONFIG_TPL); \
printf "# %-10s %s\n" "VENDOR :" $$(basename $(DEFAULT_BLD)|cut -d. -f2) >> $(CONFIG_TPL); \ printf "# %-10s %s\n" "VENDOR :" $$(basename $(DEFAULT_BLD)|cut -d. -f2) >> $(CONFIG_TPL); \
printf "# %-10s %s\n" "MODEL :" $$(basename $(DEFAULT_BLD)|cut -d. -f3) >> $(CONFIG_TPL); \ printf "# %-10s %s\n" "MODEL :" $$(basename $(DEFAULT_BLD)|cut -d. -f3) >> $(CONFIG_TPL); \
cat $(DEFAULT_BLD) >> $(CONFIG_TPL); \ cat $(DEFAULT_BLD) >> $(CONFIG_TPL); \
else \ else \
printf "SELECT A CONFIGURATION:\n\n"; \ printf "SELECT A CONFIGURATION:\n\n"; \
LIST=$$(for i in $(CONFIG_DIR)/config.*.*; do basename $${i}; done|sort); \ LIST=$$(for i in $(CONFIG_DIR)/config.*.*; do basename $${i}; done|sort); \
select V in $${LIST}; do \ select V in $${LIST}; do \
echo ""; \ echo ""; \
printf "# Automatically Generated Section End\n\n" >> $(CONFIG_TPL); \ printf "# Automatically Generated Section End\n\n" >> $(CONFIG_TPL); \
printf "# %-10s %s\n" "VENDOR :" $$(echo $${V}|cut -d. -f2) >> $(CONFIG_TPL); \ printf "# %-10s %s\n" "VENDOR :" $$(echo $${V}|cut -d. -f2) >> $(CONFIG_TPL); \
printf "# %-10s %s\n" "MODEL :" $$(echo $${V}|cut -d. -f3) >> $(CONFIG_TPL); \ printf "# %-10s %s\n" "MODEL :" $$(echo $${V}|cut -d. -f3) >> $(CONFIG_TPL); \
cp -f -P $(IMPORT_DIR)/$$(echo $${V}|cut -d. -f2)/$(PREBUILT_LIBDIR)/*.so* $(SYSROOT_LIB) 2>/dev/null; \ cp -f -P $(IMPORT_DIR)/$$(echo $${V}|cut -d. -f2)/$(PREBUILT_LIBDIR)/*.so* $(SYSROOT_LIB) 2>/dev/null; \
cat $(CONFIG_DIR)/$${V} >> $(CONFIG_TPL); \ cat $(CONFIG_DIR)/$${V} >> $(CONFIG_TPL); \
break; \ break; \
done; \ done; \
fi && \ fi && \
printf "SELECTED CONFIGURATION:\n\n" && \ printf "SELECTED CONFIGURATION:\n\n" && \
command grep -m 1 "VENDOR *:" $(CONFIG_TPL)|cut -c 3- && \ command grep -m 1 "VENDOR *:" $(CONFIG_TPL)|cut -c 3- && \
command grep -m 1 "MODEL *:" $(CONFIG_TPL)|cut -c 3- && \ command grep -m 1 "MODEL *:" $(CONFIG_TPL)|cut -c 3- && \
echo ""; \ echo ""; \
if [ "$(MAKECMDGOALS)" = "config" ]; then true; else \ if [ "$(MAKECMDGOALS)" = "config" ]; then true; else \
if [ "$(DEFAULT_BLD)" = "" ]; then \ if [ "$(DEFAULT_BLD)" = "" ]; then \
touch $(STAMP_PRJ_CFG); \ touch $(STAMP_PRJ_CFG); \
fi; \ fi; \
fi; \ fi; \
for i in $(RESET_ENV_VARS); do unset $${i}; done; \ for i in $(RESET_ENV_VARS); do unset $${i}; done; \
$(MAKE) --no-print-directory -f $(TOP_MAKEFILE) $(STAMP_BLD_VAR) unzip; \ $(MAKE) --no-print-directory -f $(TOP_MAKEFILE) $(STAMP_BLD_VAR); \
fi) fi)
@$(MAKE) --no-print-directory one @$(MAKE) --no-print-directory one
DL_TOOLCHAIN_VARS = \ DL_TOOLCHAIN_VARS = \
TOOLCHAIN_DLDIR \ TOOLCHAIN_DLDIR \
OUTPUT_DIR \ OUTPUT_DIR \
toolchain: toolchain:
@$(foreach V,$(DL_TOOLCHAIN_VARS),$(V)=$($(V))) \ @$(foreach V,$(DL_TOOLCHAIN_VARS),$(V)=$($(V))) \
CC=$(shell basename $(CC)) \ CC=$(shell basename $(CC)) \
AR=$(shell basename $(AR)) \ AR=$(shell basename $(AR)) \
RELPATH=` $(call Relative_TcPath,$(shell basename $(CC))) ` \ RELPATH=` $(call Relative_TcPath,$(shell basename $(CC))) ` \
GITPATH=` $(call Gitrepo_TcPath,$(shell basename $(CC))) ` \ GITPATH=` $(call Gitrepo_TcPath,$(shell basename $(CC))) ` \
bash $(RULE_DIR)/scripts/gen_cross_toolchain.sh bash $(RULE_DIR)/scripts/gen_cross_toolchain.sh
reconfig: distclean reconfig: distclean
$(TOP_Q)+( \ $(TOP_Q)+( \
if [ -d $(CONFIG_DIR) ]; then \ if [ -d $(CONFIG_DIR) ]; then \
$(RECURSIVE_MAKE) config DEFAULT_BLD=not-exist-actually; \ $(RECURSIVE_MAKE) config DEFAULT_BLD=not-exist-actually; \
else \ else \
$(RECURSIVE_MAKE) config; \ $(RECURSIVE_MAKE) config; \
fi) fi)
$(TOP_Q)rm -f $(STAMP_PRJ_CFG) $(TOP_Q)rm -f $(STAMP_PRJ_CFG)
clean: clean:
$(TOP_Q) \ $(TOP_Q) \
$(TOP_Q) \ $(TOP_Q) \
rm -rf \ rm -rf \
$(LIBOBJ_TMPDIR) \ $(LIBOBJ_TMPDIR) \
$(COMPILE_LOG) \ $(COMPILE_LOG) \
$(DIST_DIR)/* \ $(DIST_DIR)/* \
$(STAMP_DIR) \ $(STAMP_DIR) \
$(STAMP_LCOV) \ $(STAMP_LCOV) \
$(SYSROOT_INC)/* $(SYSROOT_LIB)/* $(SYSROOT_LIB)/../bin/* \ $(SYSROOT_INC)/* $(SYSROOT_LIB)/* $(SYSROOT_LIB)/../bin/* \
$(shell $(SHELL_DBG) find $(OUTPUT_DIR) -name "$(COMPILE_LOG)" \ $(shell $(SHELL_DBG) find $(OUTPUT_DIR) -name "$(COMPILE_LOG)" \
-or -name "$(WARNING_LOG)" \ -or -name "$(WARNING_LOG)" \
-or -name "$(STAMP_BUILD)" \ -or -name "$(STAMP_BUILD)" \
-or -name "$(STAMP_INSTALL)" \ -or -name "$(STAMP_INSTALL)" \
-or -name "$(STAMP_POSTINS)" \ -or -name "$(STAMP_POSTINS)" \
-or -name "*.so" \ -or -name "*.so" \
-or -name "*.a" \ -or -name "*.a" \
-or -name "*.o" \ -or -name "*.o" \
-or -name "*.d" \ -or -name "*.d" \
-or -name "*.gc*" \ -or -name "*.gc*" \
| grep -v '$(OUTPUT_DIR)/compiler' \ | grep -v '$(OUTPUT_DIR)/compiler' \
2>/dev/null) 2>/dev/null)
distclean: distclean:
$(TOP_Q) \ $(TOP_Q) \
rm -rf \ rm -rf \
$(CONFIG_TPL) $(COMPILE_LOG) \ $(CONFIG_TPL) $(COMPILE_LOG) \
$(STAMP_PRJ_CFG) $(STAMP_BLD_ENV) $(STAMP_BLD_VAR) $(STAMP_POST_RULE) $(STAMP_LCOV) \ $(STAMP_PRJ_CFG) $(STAMP_BLD_ENV) $(STAMP_BLD_VAR) $(STAMP_POST_RULE) $(STAMP_LCOV) \
$(DIST_DIR) $(STAMP_DIR) *.gcda \ $(DIST_DIR) $(STAMP_DIR) *.gcda \
$(TOP_Q) \ $(TOP_Q) \
if [ -d $(OUTPUT_DIR) ]; then \ if [ -d $(OUTPUT_DIR) ]; then \
cd $(OUTPUT_DIR); \ cd $(OUTPUT_DIR); \
if [ "$(CONFIG_TOOLCHAIN_NAME)" = "" ]; then \ if [ "$(CONFIG_TOOLCHAIN_NAME)" = "" ]; then \
rm -rf *; \ rm -rf *; \
else \ else \
rm -rf $$(ls -I $(CONFIG_TOOLCHAIN_NAME)); \ rm -rf $$(ls -I $(CONFIG_TOOLCHAIN_NAME)); \
fi \ fi \
fi fi
buildDate=$(shell date "+%Y.%m.%d") #buildDate=$(shell date "+%Y.%m.%d")
releaseDir=release$(buildDate) releaseDir=kk
package: package:
@echo "$(buildDate)" @echo "$(buildDate)"
echo "$(releaseDir)" echo "$(releaseDir)"
rm -rf $(releaseDir) rm -rf $(releaseDir)
mkdir $(releaseDir) mkdir $(releaseDir)
mkdir $(releaseDir)/lib mkdir $(releaseDir)/lib
mkdir $(releaseDir)/tsl cp zlog.conf $(TOP_DIR)/$(releaseDir)
cp zlog.conf $(TOP_DIR)/$(releaseDir) cp -rf $(TOP_DIR)/tsl $(TOP_DIR)/$(releaseDir)
-cp -rf $(TOP_DIR)/tsl $(TOP_DIR)/$(releaseDir)/tsl cp -rf $(TOP_DIR)/output/release/lib/*.so $(TOP_DIR)/$(releaseDir)/lib
cp -rf $(TOP_DIR)/output/release/lib/*.so $(TOP_DIR)/$(releaseDir)/lib cp -rf $(TOP_DIR)/output/release/bin/* $(TOP_DIR)/$(releaseDir)/
cp -rf $(TOP_DIR)/output/release/bin/* $(TOP_DIR)/$(releaseDir)/ cp -rf $(TOP_DIR)/run.sh $(TOP_DIR)/$(releaseDir)/
cp -rf $(TOP_DIR)/run.sh $(TOP_DIR)/$(releaseDir)/ cp -rf $(TOP_DIR)/process_check.sh $(TOP_DIR)/$(releaseDir)/
ifeq ($(CONFIG_VENDOR),ubuntu) cp -rf $(TOP_DIR)/rc.local $(TOP_DIR)/$(releaseDir)/
cp -rf $(TOP_DIR)/common/nanomsg/libnanomsg_ubuntu.so $(TOP_DIR)/$(releaseDir)/lib/libnanomsg.so.5 ifeq ($(CONFIG_VENDOR),ubuntu)
cp -rf $(TOP_DIR)/common/ev/libev_ubuntu.so $(TOP_DIR)/$(releaseDir)/lib cp -rf $(TOP_DIR)/common/nanomsg/libnanomsg_ubuntu.so $(TOP_DIR)/$(releaseDir)/lib/libnanomsg.so.5
else cp -rf $(TOP_DIR)/common/ev/libev_ubuntu.so $(TOP_DIR)/$(releaseDir)/lib
cp -rf $(TOP_DIR)/common/nanomsg/libnanomsg.so $(TOP_DIR)/$(releaseDir)/lib else
cp -rf $(TOP_DIR)/common/ev/libev.so $(TOP_DIR)/$(releaseDir)/lib cp -rf $(TOP_DIR)/common/nanomsg/libnanomsg.so $(TOP_DIR)/$(releaseDir)/lib
endif cp -rf $(TOP_DIR)/common/ev/libev.so $(TOP_DIR)/$(releaseDir)/lib
cp -rf $(TOP_DIR)/platform/zigbee/app/builder/Z3GatewayHost/build/exe/Z3GatewayHost $(TOP_DIR)/$(releaseDir)/ endif
echo $(PWD) cp -rf $(TOP_DIR)/platform/zigbee/app/builder/Z3GatewayHost/build/exe/Z3GatewayHost $(TOP_DIR)/$(releaseDir)/
fromdos $(releaseDir)/*.sh
ifeq ($(shell uname),Darwin) fromdos $(releaseDir)/rc.local
KCONFIG_MCONF := tools/prebuilt/macos/kconfig-frontends-mac/kconfig-mconf echo $(PWD)
else
KCONFIG_MCONF := tools/prebuilt/ubuntu/bin/kconfig-mconf ifeq ($(shell uname),Darwin)
endif KCONFIG_MCONF := tools/prebuilt/macos/kconfig-frontends-mac/kconfig-mconf
else
COMMON_CONFIG_ENV = \ KCONFIG_MCONF := tools/prebuilt/ubuntu/bin/kconfig-mconf
KCONFIG_CONFIG=mconf.config \ endif
KCONFIG_AUTOCONFIG=$(OUTPUT_DIR)/auto.conf \
KCONFIG_AUTOHEADER=$(OUTPUT_DIR)/autoconf.h \ COMMON_CONFIG_ENV = \
CONFIG_=FEATURE_ \ KCONFIG_CONFIG=mconf.config \
KCONFIG_AUTOCONFIG=$(OUTPUT_DIR)/auto.conf \
menuconfig: $(KCONFIG_MCONF) KCONFIG_AUTOHEADER=$(OUTPUT_DIR)/autoconf.h \
$(TOP_Q)chmod a+x $(KCONFIG_MCONF) $(if $(TOP_Q),2>/dev/null) || true CONFIG_=FEATURE_ \
$(TOP_Q)$(COMMON_CONFIG_ENV) $^ -s $(TOP_DIR)/tools/Config.in $(if $(TOP_Q),2>/dev/null)
$(TOP_Q) \ menuconfig: $(KCONFIG_MCONF)
( \ $(TOP_Q)chmod a+x $(KCONFIG_MCONF) $(if $(TOP_Q),2>/dev/null) || true
if [ ! -f mconf.config ]; then exit 0; fi; \ $(TOP_Q)$(COMMON_CONFIG_ENV) $^ -s $(TOP_DIR)/tools/Config.in $(if $(TOP_Q),2>/dev/null)
\ $(TOP_Q) \
cp -Lf mconf.config make.settings; \ ( \
rm -f mconf.config*; \ if [ ! -f mconf.config ]; then exit 0; fi; \
) \
cp -Lf mconf.config make.settings; \
rm -f mconf.config*; \
)
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