Commit 1003bad8 authored by 尹佳钦's avatar 尹佳钦
parents 0c4d8ff1 d6172530
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
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#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 "/thing/topo/add"
#define KK_FILTER_ADD_TOPIC_REPLY "/thing/topo/add_reply" #define KK_FILTER_ADD_TOPIC_REPLY "/thing/topo/add_reply"
...@@ -35,6 +36,7 @@ const char DM_MSG_TO_MIDDWARE[] = "{\"msgtype\":\"%s\",\"productCode\":\"%s\",\" ...@@ -35,6 +36,7 @@ const char DM_MSG_TO_MIDDWARE[] = "{\"msgtype\":\"%s\",\"productCode\":\"%s\",\"
#define KK_POWER_SWITCH_3 "PowerSwitch_3" #define KK_POWER_SWITCH_3 "PowerSwitch_3"
static char *s_split_product[] = { static char *s_split_product[] = {
"85", //三路面板 "85", //三路面板
"3002", //双路面板 "3002", //双路面板
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#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)
{ {
...@@ -62,9 +62,7 @@ int main(int argc, char* argv[]) ...@@ -62,9 +62,7 @@ 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*/ /*set the callback to get the device date to cloud*/
kk_ipc_init(IPC_APP2MID,KK_Data_FromDev,NULL,NULL); kk_ipc_init(IPC_APP2MID,KK_Data_FromDev,NULL,NULL);
rc = mqtt_start(); rc = mqtt_start();
......
//=========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
......
/*
* 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)
......
...@@ -202,7 +202,7 @@ int dm_mgr_properities_db_create(kk_tsl_t* dev_shadow,char *deviceCode,int devTy ...@@ -202,7 +202,7 @@ int dm_mgr_properities_db_create(kk_tsl_t* dev_shadow,char *deviceCode,int devTy
} }
} }
int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN], int dm_mgr_device_create(_IN_ int dev_type,_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) _IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN],_IN_ int isOffline, _OU_ int *devid)
{ {
int res = 0; int res = 0;
dm_mgr_ctx *ctx = _dm_mgr_get_ctx(); dm_mgr_ctx *ctx = _dm_mgr_get_ctx();
...@@ -235,6 +235,7 @@ int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MA ...@@ -235,6 +235,7 @@ int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MA
node->devid = _dm_mgr_next_devid(); node->devid = _dm_mgr_next_devid();
node->dev_type = dev_type; node->dev_type = dev_type;
node->dev_shadow = NULL; node->dev_shadow = NULL;
node->isOffline = isOffline;
if (productCode != NULL) { if (productCode != NULL) {
memcpy(node->productCode, productCode, strlen(productCode)); memcpy(node->productCode, productCode, strlen(productCode));
} }
...@@ -247,7 +248,7 @@ int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MA ...@@ -247,7 +248,7 @@ int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MA
if (dev_type != KK_DM_DEVICE_CCU && fatherDeviceCode != NULL) { if (dev_type != KK_DM_DEVICE_CCU && fatherDeviceCode != NULL) {
memcpy(node->fatherDeviceCode, fatherDeviceCode, strlen(fatherDeviceCode)); memcpy(node->fatherDeviceCode, fatherDeviceCode, strlen(fatherDeviceCode));
} }
node->timestamp = HAL_UptimeMs(); node->timestamp = 0;
//node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED; //node->dev_status = IOTX_DM_DEV_STATUS_AUTHORIZED;
tsl_str = kk_load_json(productCode, dev_type); tsl_str = kk_load_json(productCode, dev_type);
if(tsl_str != NULL) if(tsl_str != NULL)
...@@ -402,7 +403,7 @@ int dm_mgr_check_heartbeat_timeout(uint64_t timestamp) ...@@ -402,7 +403,7 @@ int dm_mgr_check_heartbeat_timeout(uint64_t timestamp)
//return DEVICE_HEARTBEAT_TIMEOUT; //return DEVICE_HEARTBEAT_TIMEOUT;
} }
else{ else{
if(search_node->isOffline == 1){//need send online if(search_node->isOffline == 1 && search_node->timestamp != 0) {//need send online
INFO_PRINT("---------->dev online again,send online\n"); INFO_PRINT("---------->dev online again,send online\n");
search_node->isOffline = 0; search_node->isOffline = 0;
iotx_dm_dev_online(search_node->devid); iotx_dm_dev_online(search_node->devid);
...@@ -473,7 +474,7 @@ int dm_mgr_init(void) ...@@ -473,7 +474,7 @@ int dm_mgr_init(void)
HAL_Get_mac(mac); HAL_Get_mac(mac);
res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",&devId); res = dm_mgr_device_create(KK_DM_DEVICE_CCU,KK_DM_CCU_DEVICE_PRODUCT_CODE,"CCU_66666",mac,"",0,&devId);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
goto ERROR; goto ERROR;
} }
...@@ -1340,10 +1341,10 @@ int dm_mgr_ota_report_version(_IN_ int devid, char *version) ...@@ -1340,10 +1341,10 @@ 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 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){ _IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN],_IN_ int isOffline, _OU_ int *devid){
int res = 0; int res = 0;
res = dm_mgr_device_create(devtype,productCode,deviceCode,mac,fatherDeviceCode, devid); res = dm_mgr_device_create(devtype,productCode,deviceCode,mac,fatherDeviceCode,isOffline,devid);
if(TSL_ALREADY_EXIST == res) if(TSL_ALREADY_EXIST == res)
{ {
ERROR_PRINT("SUBDEV ALREADY EXIST!!!\n"); ERROR_PRINT("SUBDEV ALREADY EXIST!!!\n");
......
...@@ -1732,7 +1732,7 @@ int kk_mid_subdev_add(int devType, char productCode[PRODUCT_CODE_MAXLEN], char d ...@@ -1732,7 +1732,7 @@ int kk_mid_subdev_add(int devType, char productCode[PRODUCT_CODE_MAXLEN], char d
int res = 0; int res = 0;
int devid = 0; int devid = 0;
res = dm_mgr_subdev_create(devType,productCode,deviceCode,mac,fatherDeviceCode,&devid); res = dm_mgr_subdev_create(devType,productCode,deviceCode,mac,fatherDeviceCode,0,&devid);
if (res != SUCCESS_RETURN && TSL_ALREADY_EXIST != res) { if (res != SUCCESS_RETURN && TSL_ALREADY_EXIST != res) {
ERROR_PRINT("subdev create Failed\n"); ERROR_PRINT("subdev create Failed\n");
return FAIL_RETURN; return FAIL_RETURN;
......
...@@ -113,7 +113,7 @@ static int _kk_check_property_exist(const char* deviceCode,const char* identifie ...@@ -113,7 +113,7 @@ static int _kk_check_property_exist(const char* deviceCode,const char* identifie
const char *searchCmd = "select * from PropertiesInfo;"; const char *searchCmd = "select * from PropertiesInfo;";
_kk_property_db_lock(); _kk_property_db_lock();
sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL); sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt)); //INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
while(sqlite3_step(stmt) == SQLITE_ROW){ while(sqlite3_step(stmt) == SQLITE_ROW){
pDeviceCode = sqlite3_column_text(stmt, DB_DEVICECODE); pDeviceCode = sqlite3_column_text(stmt, DB_DEVICECODE);
pIdentifier = sqlite3_column_text(stmt, DB_IDENTIFITER); pIdentifier = sqlite3_column_text(stmt, DB_IDENTIFITER);
...@@ -123,7 +123,7 @@ static int _kk_check_property_exist(const char* deviceCode,const char* identifie ...@@ -123,7 +123,7 @@ static int _kk_check_property_exist(const char* deviceCode,const char* identifie
break; break;
} }
} }
INFO_PRINT("\n"); //INFO_PRINT("\n");
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
_kk_property_db_unlock(); _kk_property_db_unlock();
return isExist; return isExist;
...@@ -155,7 +155,7 @@ int kk_property_db_insert(const char *deviceCode,const char *identifier,kk_tsl_d ...@@ -155,7 +155,7 @@ int kk_property_db_insert(const char *deviceCode,const char *identifier,kk_tsl_d
ERROR_PRINT("SQL error: %s\n", zErrMsg); ERROR_PRINT("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg); sqlite3_free(zErrMsg);
}else{ }else{
INFO_PRINT("sub device insert data successfully\n"); //INFO_PRINT("sub device insert data successfully\n");
} }
sqlite3_free(sqlCmd); sqlite3_free(sqlCmd);
_kk_property_db_unlock(); _kk_property_db_unlock();
...@@ -179,7 +179,7 @@ int kk_property_db_update_value(const char *deviceCode,const char *identifier,co ...@@ -179,7 +179,7 @@ int kk_property_db_update_value(const char *deviceCode,const char *identifier,co
ERROR_PRINT("SQL error: %s\n", zErrMsg); ERROR_PRINT("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg); sqlite3_free(zErrMsg);
}else{ }else{
DEBUG_PRINT("kk_property_db_update_value successfully\n"); //DEBUG_PRINT("kk_property_db_update_value successfully\n");
} }
sqlite3_free(sqlCmd); sqlite3_free(sqlCmd);
_kk_property_db_unlock(); _kk_property_db_unlock();
......
...@@ -103,10 +103,12 @@ static int _kk_load_subDevice(void) ...@@ -103,10 +103,12 @@ static int _kk_load_subDevice(void)
_kk_subDb_lock(); _kk_subDb_lock();
sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL); sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
while(sqlite3_step(stmt) == SQLITE_ROW){ while(sqlite3_step(stmt) == SQLITE_ROW){
res = dm_mgr_subdev_create(sqlite3_column_int(stmt, DB_DEVTYPE),
res = dm_mgr_subdev_create(sqlite3_column_int(stmt, DB_DEVTYPE),sqlite3_column_text(stmt, DB_PRODUCTCODE), sqlite3_column_text(stmt, DB_PRODUCTCODE),
sqlite3_column_text(stmt, DB_DEVICECODE), sqlite3_column_text(stmt, DB_DEVICECODE),
sqlite3_column_text(stmt, DB_MAC),sqlite3_column_text(stmt, DB_FATHERDEVICECODE),&devId); sqlite3_column_text(stmt, DB_MAC),
sqlite3_column_text(stmt, DB_FATHERDEVICECODE),
sqlite3_column_int(stmt, DB_ONLINE),&devId);
if(res != SUCCESS_RETURN){ if(res != SUCCESS_RETURN){
ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__); ERROR_PRINT("[%s][%d]dm_mgr_subdev_create FAIL!!!\n",__FUNCTION__,__LINE__);
...@@ -120,8 +122,8 @@ static int _kk_load_subDevice(void) ...@@ -120,8 +122,8 @@ static int _kk_load_subDevice(void)
//sync the data from property db //sync the data from property db
kk_property_sync_values(sqlite3_column_text(stmt, DB_DEVICECODE)); kk_property_sync_values(sqlite3_column_text(stmt, DB_DEVICECODE));
usleep(100000); usleep(100000);
//post the property to cloud //post the property to cloud
dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE)); dm_msg_thing_property_post_all(sqlite3_column_text(stmt, DB_DEVICECODE));
//kk_dm_ota_report_version(devId,sqlite3_column_text(stmt, DB_VERSION));//post version //kk_dm_ota_report_version(devId,sqlite3_column_text(stmt, DB_VERSION));//post version
...@@ -160,7 +162,7 @@ static int _kk_check_subDev_exist(const char* deviceCode) ...@@ -160,7 +162,7 @@ static int _kk_check_subDev_exist(const char* deviceCode)
const char *searchCmd = "select * from SubDeviceInfo;"; const char *searchCmd = "select * from SubDeviceInfo;";
_kk_subDb_lock(); _kk_subDb_lock();
sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL); sqlite3_prepare_v2(ctx->pDb, searchCmd, strlen(searchCmd), &stmt, NULL);
INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt)); //INFO_PRINT("total_column = %d\n", sqlite3_column_count(stmt));
while(sqlite3_step(stmt) == SQLITE_ROW){ while(sqlite3_step(stmt) == SQLITE_ROW){
pmac = sqlite3_column_text(stmt, DB_DEVICECODE); pmac = sqlite3_column_text(stmt, DB_DEVICECODE);
if(!strcmp(deviceCode,pmac)) if(!strcmp(deviceCode,pmac))
...@@ -202,7 +204,7 @@ int kk_subDev_insert_db(int devType,char productCode[PRODUCT_CODE_MAXLEN], \ ...@@ -202,7 +204,7 @@ int kk_subDev_insert_db(int devType,char productCode[PRODUCT_CODE_MAXLEN], \
ERROR_PRINT("SQL error: %s\n", zErrMsg); ERROR_PRINT("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg); sqlite3_free(zErrMsg);
}else{ }else{
INFO_PRINT("sub device insert data successfully\n"); //INFO_PRINT("sub device insert data successfully\n");
} }
sqlite3_free(sqlCmd); sqlite3_free(sqlCmd);
ctx->subDevNum++; ctx->subDevNum++;
...@@ -226,7 +228,7 @@ int kk_subDev_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN]) ...@@ -226,7 +228,7 @@ int kk_subDev_delete_by_dcode(char deviceCode[DEVICE_CODE_MAXLEN])
ERROR_PRINT("SQL error: %s\n", zErrMsg); ERROR_PRINT("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg); sqlite3_free(zErrMsg);
}else{ }else{
INFO_PRINT("Table delete data successfully\n"); //INFO_PRINT("Table delete data successfully\n");
} }
sqlite3_free(sqlCmd); sqlite3_free(sqlCmd);
_kk_subDb_unlock(); _kk_subDb_unlock();
...@@ -241,7 +243,7 @@ int kk_subDev_update_offline(int isOffline,const char *deviceCode) ...@@ -241,7 +243,7 @@ int kk_subDev_update_offline(int isOffline,const char *deviceCode)
char *zErrMsg = 0; char *zErrMsg = 0;
kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx(); kk_subDb_ctx_t *ctx = _kk_subDb_get_ctx();
_kk_subDb_lock(); //_kk_subDb_lock();
sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isOffline=%d WHERE deviceCode= '%s'",isOffline,deviceCode); sqlCmd = sqlite3_mprintf("UPDATE SubDeviceInfo SET isOffline=%d WHERE deviceCode= '%s'",isOffline,deviceCode);
INFO_PRINT("kk_subDev_update_offline sqlCmd:%s\n",sqlCmd); INFO_PRINT("kk_subDev_update_offline sqlCmd:%s\n",sqlCmd);
rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg); rc = sqlite3_exec(ctx->pDb, sqlCmd, NULL, NULL, &zErrMsg);
...@@ -249,10 +251,10 @@ int kk_subDev_update_offline(int isOffline,const char *deviceCode) ...@@ -249,10 +251,10 @@ int kk_subDev_update_offline(int isOffline,const char *deviceCode)
ERROR_PRINT("SQL error: %s\n", zErrMsg); ERROR_PRINT("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg); sqlite3_free(zErrMsg);
}else{ }else{
INFO_PRINT("Table updata data successfully\n"); //INFO_PRINT("Table updata data successfully\n");
} }
sqlite3_free(sqlCmd); sqlite3_free(sqlCmd);
_kk_subDb_unlock(); //_kk_subDb_unlock();
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int kk_subDev_update_auth(int isAuth,const char *deviceCode) int kk_subDev_update_auth(int isAuth,const char *deviceCode)
......
...@@ -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
......
...@@ -629,7 +629,7 @@ int main(const int argc, const char **argv) ...@@ -629,7 +629,7 @@ 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_tsl_api_init(); kk_tsl_api_init();
......
...@@ -5,18 +5,6 @@ ...@@ -5,18 +5,6 @@
#include "kk_dm_msg.h" #include "kk_dm_msg.h"
#include "kk_log.h" #include "kk_log.h"
#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 enum { typedef enum {
KK_MSG_PROPERTY_SET, KK_MSG_PROPERTY_SET,
KK_MSG_SERVICE_SET KK_MSG_SERVICE_SET
......
#include "kk_tsl_common.h" #include "kk_tsl_common.h"
typedef int (*kk_tsl_data_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); typedef int (*kk_tsl_data_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
typedef int (*kk_tsl_array_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, typedef int (*kk_tsl_array_set)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
typedef int (*kk_tsl_data_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); typedef int (*kk_tsl_data_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
typedef int (*kk_tsl_array_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); typedef int (*kk_tsl_array_get)(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
typedef void (*kk_tsl_data_free)(_IN_ kk_tsl_data_value_t *data_value); typedef void (*kk_tsl_data_free)(_IN_ kk_tsl_data_value_t *data_value);
typedef void (*kk_tsl_array_free)(_IN_ kk_tsl_data_value_t *data_value); typedef void (*kk_tsl_array_free)(_IN_ kk_tsl_data_value_t *data_value);
typedef void (*kk_tsl_data_print)(_IN_ kk_tsl_data_value_t *data_value); typedef void (*kk_tsl_data_print)(_IN_ kk_tsl_data_value_t *data_value);
typedef struct { typedef struct {
kk_tsl_data_type_e type; kk_tsl_data_type_e type;
const char *name; const char *name;
kk_tsl_data_set func_set; kk_tsl_data_set func_set;
kk_tsl_array_set func_array_set; kk_tsl_array_set func_array_set;
kk_tsl_data_get func_get; kk_tsl_data_get func_get;
kk_tsl_array_get func_array_get; kk_tsl_array_get func_array_get;
kk_tsl_data_free func_free; kk_tsl_data_free func_free;
kk_tsl_array_free func_array_free; kk_tsl_array_free func_array_free;
} kk_tsl_data_type_mapping_t; } kk_tsl_data_type_mapping_t;
//Data Set //Data Set
static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len); static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len);
//Array Data Set //Array Data Set
static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index); _IN_ int index);
//Data Get //Data Get
static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value); static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value);
//Array Data Get //Array Data Get
static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index); static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index);
//Data Free //Data Free
static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property); static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property);
//Array Data Free //Array Data Free
static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value);
static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value); static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value);
static kk_tsl_data_type_mapping_t g_iotx_data_type_mapping[] = { static kk_tsl_data_type_mapping_t g_iotx_data_type_mapping[] = {
{KK_TSL_DATA_TYPE_NONE, "none", NULL, NULL, NULL, NULL, NULL, NULL }, {KK_TSL_DATA_TYPE_NONE, "none", NULL, NULL, NULL, NULL, NULL, NULL },
{KK_TSL_DATA_TYPE_INT, "int", _kk_tsl_int_set, _kk_tsl_array_int_set, _kk_tsl_int_get, _kk_tsl_array_int_get, _kk_tsl_int_free, _kk_tsl_array_int_free }, {KK_TSL_DATA_TYPE_INT, "int", _kk_tsl_int_set, _kk_tsl_array_int_set, _kk_tsl_int_get, _kk_tsl_array_int_get, _kk_tsl_int_free, _kk_tsl_array_int_free },
{KK_TSL_DATA_TYPE_FLOAT, "float", _kk_tsl_float_set, _kk_tsl_array_float_set, _kk_tsl_float_get, _kk_tsl_array_float_get, _kk_tsl_float_free, _kk_tsl_array_float_free, }, {KK_TSL_DATA_TYPE_FLOAT, "float", _kk_tsl_float_set, _kk_tsl_array_float_set, _kk_tsl_float_get, _kk_tsl_array_float_get, _kk_tsl_float_free, _kk_tsl_array_float_free, },
{KK_TSL_DATA_TYPE_DOUBLE, "double", _kk_tsl_double_set, _kk_tsl_array_double_set, _kk_tsl_double_get, _kk_tsl_array_double_get, _kk_tsl_double_free, _kk_tsl_array_double_free, }, {KK_TSL_DATA_TYPE_DOUBLE, "double", _kk_tsl_double_set, _kk_tsl_array_double_set, _kk_tsl_double_get, _kk_tsl_array_double_get, _kk_tsl_double_free, _kk_tsl_array_double_free, },
{KK_TSL_DATA_TYPE_TEXT, "text", _kk_tsl_text_set, _kk_tsl_array_text_set, _kk_tsl_text_get, _kk_tsl_array_text_get, _kk_tsl_text_free, _kk_tsl_array_text_free, }, {KK_TSL_DATA_TYPE_TEXT, "text", _kk_tsl_text_set, _kk_tsl_array_text_set, _kk_tsl_text_get, _kk_tsl_array_text_get, _kk_tsl_text_free, _kk_tsl_array_text_free, },
{KK_TSL_DATA_TYPE_ENUM, "enum", _kk_tsl_enum_set, _kk_tsl_array_enum_set, _kk_tsl_enum_get, _kk_tsl_array_enum_get, _kk_tsl_enum_free, _kk_tsl_array_enum_free, }, {KK_TSL_DATA_TYPE_ENUM, "enum", _kk_tsl_enum_set, _kk_tsl_array_enum_set, _kk_tsl_enum_get, _kk_tsl_array_enum_get, _kk_tsl_enum_free, _kk_tsl_array_enum_free, },
{KK_TSL_DATA_TYPE_DATE, "date", _kk_tsl_date_set, _kk_tsl_array_date_set, _kk_tsl_date_get, _kk_tsl_array_date_get, _kk_tsl_date_free, _kk_tsl_array_date_free, }, {KK_TSL_DATA_TYPE_DATE, "date", _kk_tsl_date_set, _kk_tsl_array_date_set, _kk_tsl_date_get, _kk_tsl_array_date_get, _kk_tsl_date_free, _kk_tsl_array_date_free, },
{KK_TSL_DATA_TYPE_BOOL, "bool", _kk_tsl_bool_set, _kk_tsl_array_bool_set, _kk_tsl_bool_get, _kk_tsl_array_bool_get, _kk_tsl_bool_free, _kk_tsl_array_bool_free, }, {KK_TSL_DATA_TYPE_BOOL, "bool", _kk_tsl_bool_set, _kk_tsl_array_bool_set, _kk_tsl_bool_get, _kk_tsl_array_bool_get, _kk_tsl_bool_free, _kk_tsl_array_bool_free, },
{KK_TSL_DATA_TYPE_ARRAY, "array", NULL, NULL, NULL, NULL, _kk_tsl_array_free, _kk_tsl_array_array_free, }, {KK_TSL_DATA_TYPE_ARRAY, "array", NULL, NULL, NULL, NULL, _kk_tsl_array_free, _kk_tsl_array_array_free, },
{KK_TSL_DATA_TYPE_STRUCT, "struct", NULL, NULL, NULL, NULL, _kk_tsl_struct_free, _kk_tsl_array_struct_free, } {KK_TSL_DATA_TYPE_STRUCT, "struct", NULL, NULL, NULL, NULL, _kk_tsl_struct_free, _kk_tsl_array_struct_free, }
}; };
static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
float float_set = (value == NULL) ? (0) : (*(float *)value); float float_set = (value == NULL) ? (0) : (*(float *)value);
data_value->value_float = float_set; data_value->value_float = float_set;
printf("Current Float Value Be Set(Float): %f\n", data_value->value_float); //printf("Current Float Value Be Set(Float): %f\n", data_value->value_float);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
double double_set = (value == NULL) ? (0) : (*(double *)value); double double_set = (value == NULL) ? (0) : (*(double *)value);
data_value->value_double = double_set; data_value->value_double = double_set;
printf("Current Double Value Be Set(Double): %f\n", data_value->value_double); //printf("Current Double Value Be Set(Double): %f\n", data_value->value_double);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
int res = 0; int res = 0;
char *value_set = (value == NULL) ? ("NULL") : ((char *)value); char *value_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len); int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (data_value->value) { if (data_value->value) {
free(data_value->value); free(data_value->value);
data_value->value = NULL; data_value->value = NULL;
} }
res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1); res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return MEMORY_NOT_ENOUGH; return MEMORY_NOT_ENOUGH;
} }
printf("Current Text Value Be Set(String): %s\n", data_value->value); //printf("Current Text Value Be Set(String): %s\n", data_value->value);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
int enum_set = (value == NULL) ? (0) : (*(int *)value); int enum_set = (value == NULL) ? (0) : (*(int *)value);
enum_set = (enum_set < 0) ? (0) : (enum_set); enum_set = (enum_set < 0) ? (0) : (enum_set);
data_value->value_int = enum_set; data_value->value_int = enum_set;
printf("Current Enum Value Be Set(Enum): %d\n", data_value->value_int); //printf("Current Enum Value Be Set(Enum): %d\n", data_value->value_int);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
int res = 0; int res = 0;
char *value_set = (value == NULL) ? ("NULL") : ((char *)value); char *value_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len); int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (data_value->value) { if (data_value->value) {
free(data_value->value); free(data_value->value);
data_value->value = NULL; data_value->value = NULL;
} }
res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1); res = kk_utils_copy(value_set, value_set_len, &data_value->value, value_set_len + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return MEMORY_NOT_ENOUGH; return MEMORY_NOT_ENOUGH;
} }
printf("Current Date Value Be Set(String): %s\n", data_value->value); //printf("Current Date Value Be Set(String): %s\n", data_value->value);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
int int_set = (value == NULL) ? (0) : (*(int *)value); int int_set = (value == NULL) ? (0) : (*(int *)value);
int_set = (int_set == 0) ? (int_set) : ((int_set == 1) ? (int_set) : (0)); int_set = (int_set == 0) ? (int_set) : ((int_set == 1) ? (int_set) : (0));
data_value->value_int = int_set; data_value->value_int = int_set;
printf("Current Bool Value Be Set(Bool): %d\n", data_value->value_int); //printf("Current Bool Value Be Set(Bool): %d\n", data_value->value_int);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
int int_set = (value == NULL) ? (0) : (*(int *)value); int int_set = (value == NULL) ? (0) : (*(int *)value);
data_value->value_int = int_set; data_value->value_int = int_set;
printf("Current Int Value Be Set(Int): %d\n", data_value->value_int); //printf("Current Int Value Be Set(Int): %d\n", data_value->value_int);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_text_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
int res = 0; int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
char *text_set = (value == NULL) ? ("NULL") : ((char *)value); char *text_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len); int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (*((char **)(complex_array->value) + index)) { if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index)); free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL; *((char **)(complex_array->value) + index) = NULL;
} }
res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1); res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Current Array Value Be Set(Text String), Index: %d, Value: %s\n", index, //printf("Current Array Value Be Set(Text String), Index: %d, Value: %s\n", index,
*((char **)(complex_array->value) + index)); //*((char **)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_enum_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value); int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set; *((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Enum), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index)); //printf("Current Array Value Be Set(Enum), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_date_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
int res = 0; int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
char *text_set = (value == NULL) ? ("NULL") : ((char *)value); char *text_set = (value == NULL) ? ("NULL") : ((char *)value);
int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len); int value_set_len = (value == NULL) ? (strlen("NULL")) : (value_len);
if (*((char **)(complex_array->value) + index)) { if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index)); free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL; *((char **)(complex_array->value) + index) = NULL;
} }
res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1); res = kk_utils_copy(text_set, value_set_len, (void **)((char **)(complex_array->value) + index), value_set_len + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Current Array Value Be Set(Date String), Index: %d, Value: %s\n", index, //printf("Current Array Value Be Set(Date String), Index: %d, Value: %s\n", index,
*((char **)(complex_array->value) + index)); //*((char **)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
*(float *)(value) = data_value->value_float; *(float *)(value) = data_value->value_float;
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
*(double *)(value) = data_value->value_double; *(double *)(value) = data_value->value_double;
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
int res = 0; int res = 0;
if (*(char **)value != NULL || data_value->value == NULL) { if (*(char **)value != NULL || data_value->value == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1); res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
*(int *)(value) = data_value->value_int; *(int *)(value) = data_value->value_int;
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
int res = 0; int res = 0;
if (*(char **)value != NULL || data_value->value == NULL) { if (*(char **)value != NULL || data_value->value == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1); res = kk_utils_copy_direct(data_value->value, strlen(data_value->value), (void **)value, strlen(data_value->value) + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
*(int *)(value) = data_value->value_int; *(int *)(value) = data_value->value_int;
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) { if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
*((int *)value) = *((int *)(complex_array->value) + index); *((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_float_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((float *)(complex_array->value) + index) == NULL) { if (complex_array->value == NULL || ((float *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
*((float *)value) = *((float *)(complex_array->value) + index); *((float *)value) = *((float *)(complex_array->value) + index);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_double_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((double *)(complex_array->value) + index) == NULL) { if (complex_array->value == NULL || ((double *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
*((double *)value) = *((double *)(complex_array->value) + index); *((double *)value) = *((double *)(complex_array->value) + index);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_text_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
int res = 0; int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) { if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_copy_direct(*((char **)(complex_array->value) + index), res = kk_utils_copy_direct(*((char **)(complex_array->value) + index),
strlen(*((char **)(complex_array->value) + index)), strlen(*((char **)(complex_array->value) + index)),
(void **)value, strlen(*((char **)(complex_array->value) + index)) + 1); (void **)value, strlen(*((char **)(complex_array->value) + index)) + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_enum_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) { if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
*((int *)value) = *((int *)(complex_array->value) + index); *((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_date_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
int res = 0; int res = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) { if (complex_array->value == NULL || *((char **)(complex_array->value) + index) == NULL || *(char **)value != NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_copy_direct(*((char **)(complex_array->value) + index), res = kk_utils_copy_direct(*((char **)(complex_array->value) + index),
strlen(*((char **)(complex_array->value) + index)), strlen(*((char **)(complex_array->value) + index)),
(void **)value, strlen(*((char **)(complex_array->value) + index)) + 1); (void **)value, strlen(*((char **)(complex_array->value) + index)) + 1);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_array_bool_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) { if (complex_array->value == NULL || ((int *)(complex_array->value) + index) == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
*((int *)value) = *((int *)(complex_array->value) + index); *((int *)value) = *((int *)(complex_array->value) + index);
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_int_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;} //if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
} }
static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_float_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;} //if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
} }
static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_double_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;} //if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
} }
static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_text_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
if (data_value->value) { if (data_value->value) {
free(data_value->value); free(data_value->value);
data_value->value = NULL; data_value->value = NULL;
} }
} }
static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_enum_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;} //if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
} }
static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_date_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
if (data_value->value) { if (data_value->value) {
free(data_value->value); free(data_value->value);
data_value->value = NULL; data_value->value = NULL;
} }
} }
static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_bool_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
//Free Value //Free Value
//if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;} //if (data_value->value) {DM_free(data_value->value);data_value->value = NULL;}
} }
static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_int_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_float_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_double_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_text_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
int index = 0; int index = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value //Free Value
if (complex_array) { if (complex_array) {
for (index = 0; index < complex_array->size; index++) { for (index = 0; index < complex_array->size; index++) {
if (*((char **)(complex_array->value) + index)) { if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index)); free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL; *((char **)(complex_array->value) + index) = NULL;
} }
} }
} }
} }
static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_enum_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_date_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
int index = 0; int index = 0;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value //Free Value
if (complex_array) { if (complex_array) {
for (index = 0; index < complex_array->size; index++) { for (index = 0; index < complex_array->size; index++) {
if (*((char **)(complex_array->value) + index)) { if (*((char **)(complex_array->value) + index)) {
free(*((char **)(complex_array->value) + index)); free(*((char **)(complex_array->value) + index));
*((char **)(complex_array->value) + index) = NULL; *((char **)(complex_array->value) + index) = NULL;
} }
} }
} }
} }
static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_bool_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_array_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
} }
static void _kk_tsl_data_free(kk_tsl_data_value_t *data_value) static void _kk_tsl_data_free(kk_tsl_data_value_t *data_value)
{ {
if (g_iotx_data_type_mapping[data_value->type].func_free == NULL) { if (g_iotx_data_type_mapping[data_value->type].func_free == NULL) {
return; return;
} }
g_iotx_data_type_mapping[data_value->type].func_free(data_value); g_iotx_data_type_mapping[data_value->type].func_free(data_value);
} }
static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property) static void _kk_tsl_property_free(_IN_ kk_tsl_data_t *property)
{ {
if (property->identifier) { if (property->identifier) {
free(property->identifier); free(property->identifier);
} }
_kk_tsl_data_free(&property->data_value); _kk_tsl_data_free(&property->data_value);
} }
static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_struct_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
int index = 0; int index = 0;
kk_tsl_data_t *data = NULL; kk_tsl_data_t *data = NULL;
kk_tsl_data_value_complex_t *complex_struct = (kk_tsl_data_value_complex_t *)data_value->value; kk_tsl_data_value_complex_t *complex_struct = (kk_tsl_data_value_complex_t *)data_value->value;
if (complex_struct) { if (complex_struct) {
for (index = 0; index < complex_struct->size; index++) { for (index = 0; index < complex_struct->size; index++) {
data = (kk_tsl_data_t *)complex_struct->value + index; data = (kk_tsl_data_t *)complex_struct->value + index;
_kk_tsl_property_free(data); _kk_tsl_property_free(data);
} }
} }
} }
static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_array_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value //Free Value
if (complex_array) { if (complex_array) {
/* dm_log_err("complex_array->type: %d",complex_array->type); */ /* dm_log_err("complex_array->type: %d",complex_array->type); */
if (g_iotx_data_type_mapping[complex_array->type].func_array_free != NULL) { if (g_iotx_data_type_mapping[complex_array->type].func_array_free != NULL) {
g_iotx_data_type_mapping[complex_array->type].func_array_free(data_value); g_iotx_data_type_mapping[complex_array->type].func_array_free(data_value);
} }
if (complex_array->value) { if (complex_array->value) {
free(complex_array->value); free(complex_array->value);
} }
free(complex_array); free(complex_array);
data_value->value = NULL; data_value->value = NULL;
} }
} }
static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value) static void _kk_tsl_struct_free(_IN_ kk_tsl_data_value_t *data_value)
{ {
int index = 0; int index = 0;
kk_tsl_data_t *property = NULL; kk_tsl_data_t *property = NULL;
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
//Free Value //Free Value
if (complex_array) { if (complex_array) {
for (index = 0; index < complex_array->size; index++) { for (index = 0; index < complex_array->size; index++) {
property = (kk_tsl_data_t *)(complex_array->value) + index; property = (kk_tsl_data_t *)(complex_array->value) + index;
_kk_tsl_property_free(property); _kk_tsl_property_free(property);
} }
if (complex_array->value) { if (complex_array->value) {
free(complex_array->value); free(complex_array->value);
} }
free(complex_array); free(complex_array);
data_value->value = NULL; data_value->value = NULL;
} }
} }
static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_bool_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value); int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set; *((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Bool), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index)); // printf("Current Array Value Be Set(Bool), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_int_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
int int_set = (value == NULL) ? (0) : (*(int *)value); int int_set = (value == NULL) ? (0) : (*(int *)value);
*((int *)(complex_array->value) + index) = int_set; *((int *)(complex_array->value) + index) = int_set;
printf("Current Array Value Be Set(Int), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index)); //printf("Current Array Value Be Set(Int), Index: %d, Value: %d\n", index, *((int *)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_float_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
float float_set = (value == NULL) ? (0) : (*(float *)value); float float_set = (value == NULL) ? (0) : (*(float *)value);
*((float *)(complex_array->value) + index) = float_set; *((float *)(complex_array->value) + index) = float_set;
printf("Current Array Value Be Set(Float), Index: %d, Value: %f\n", index, //printf("Current Array Value Be Set(Float), Index: %d, Value: %f\n", index,
*((float *)(complex_array->value) + index)); // *((float *)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_array_double_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
double double_set = (value == NULL) ? (0) : (*(double *)value); double double_set = (value == NULL) ? (0) : (*(double *)value);
*((double *)(complex_array->value) + index) = double_set; *((double *)(complex_array->value) + index) = double_set;
printf("Current Array Value Be Set(Double), Index: %d, Value: %f\n", index, //printf("Current Array Value Be Set(Double), Index: %d, Value: %f\n", index,
*((double *)(complex_array->value) + index)); // *((double *)(complex_array->value) + index));
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_int_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
*(int *)(value) = data_value->value_int; *(int *)(value) = data_value->value_int;
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_data_array_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len, static int _kk_tsl_data_array_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len,
_IN_ int index) _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array == NULL || index < 0 || index >= complex_array->size) { if (complex_array == NULL || index < 0 || index >= complex_array->size) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
if (g_iotx_data_type_mapping[complex_array->type].func_array_set == NULL) { if (g_iotx_data_type_mapping[complex_array->type].func_array_set == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return g_iotx_data_type_mapping[complex_array->type].func_array_set(data_value, value, value_len, index); return g_iotx_data_type_mapping[complex_array->type].func_array_set(data_value, value, value_len, index);
} }
static int _kk_tsl_data_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len) static int _kk_tsl_data_set(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int value_len)
{ {
if (g_iotx_data_type_mapping[data_value->type].func_set == NULL) { if (g_iotx_data_type_mapping[data_value->type].func_set == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return g_iotx_data_type_mapping[data_value->type].func_set(data_value, value, value_len); return g_iotx_data_type_mapping[data_value->type].func_set(data_value, value, value_len);
} }
int dm_tsl_set_property_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value, int dm_tsl_set_property_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len) _IN_ int value_len)
{ {
int res = 0, array_index = 0; int res = 0, array_index = 0;
kk_tsl_data_t *data = NULL; kk_tsl_data_t *data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return FAIL_RETURN; return FAIL_RETURN;
} }
res = _kk_tsl_property_search(shadow, key, key_len, &data, &array_index); res = _kk_tsl_property_search(shadow, key, key_len, &data, &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
if (data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { if (data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
res = _kk_tsl_data_array_set(&data->data_value, value, value_len, array_index); res = _kk_tsl_data_array_set(&data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_PROPERTY_SET_FAILED; return TSL_PROPERTY_SET_FAILED;
} }
} else { } else {
res = _kk_tsl_data_set(&data->data_value, value, value_len); res = _kk_tsl_data_set(&data->data_value, value, value_len);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_PROPERTY_SET_FAILED; return TSL_PROPERTY_SET_FAILED;
} }
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_event_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_event_t **event) static int _kk_tsl_event_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_event_t **event)
{ {
int index = 0; int index = 0;
kk_tsl_event_t *dtsl_event = NULL; kk_tsl_event_t *dtsl_event = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
for (index = 0; index < shadow->event_number; index++) { for (index = 0; index < shadow->event_number; index++) {
dtsl_event = shadow->events + index; dtsl_event = shadow->events + index;
if ((strlen(dtsl_event->identifier) == key_len) && if ((strlen(dtsl_event->identifier) == key_len) &&
(memcmp(dtsl_event->identifier, key, key_len) == 0)) { (memcmp(dtsl_event->identifier, key, key_len) == 0)) {
/* dm_log_debug("TSL Event Found: %s",dtsl_event->identifier); */ /* dm_log_debug("TSL Event Found: %s",dtsl_event->identifier); */
if (event) { if (event) {
*event = dtsl_event; *event = dtsl_event;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
/* dm_log_debug("TSL Event Not Found: %.*s",key_len,key); */ /* dm_log_debug("TSL Event Not Found: %.*s",key_len,key); */
return FAIL_RETURN; return FAIL_RETURN;
} }
static int _kk_tsl_event_output_search(_IN_ kk_tsl_data_t *outputdatas, _IN_ int number, _IN_ char *key, static int _kk_tsl_event_output_search(_IN_ kk_tsl_data_t *outputdatas, _IN_ int number, _IN_ char *key,
_IN_ int key_len, _OU_ kk_tsl_data_t **event_data, _OU_ int *index) _IN_ int key_len, _OU_ kk_tsl_data_t **event_data, _OU_ int *index)
{ {
int res = 0, item_index = 0; int res = 0, item_index = 0;
kk_tsl_data_t *outputdata = NULL; kk_tsl_data_t *outputdata = NULL;
if (outputdatas == NULL || number <= 0 || key == NULL || key_len <= 0) { if (outputdatas == NULL || number <= 0 || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
for (item_index = 0; item_index < number; item_index++) { for (item_index = 0; item_index < number; item_index++) {
outputdata = outputdatas + item_index; outputdata = outputdatas + item_index;
res = kk_tsl_data_search(outputdata, key, key_len, event_data, index); res = kk_tsl_data_search(outputdata, key, key_len, event_data, index);
if (res == SUCCESS_RETURN) { if (res == SUCCESS_RETURN) {
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int dm_tsl_get_event_output_data(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data) int dm_tsl_get_event_output_data(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void **data)
{ {
int res = 0; int res = 0;
int offset = 0, array_index = 0; int offset = 0, array_index = 0;
char *pos = NULL; char *pos = NULL;
kk_tsl_event_t *event = NULL; kk_tsl_event_t *event = NULL;
kk_tsl_data_t *event_data = NULL; kk_tsl_data_t *event_data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Key: %.*s\n", key_len, key); //printf("Key: %.*s\n", key_len, key);
res = _kk_tsl_event_search(shadow, key, offset, &event); res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
pos = key + offset + 1; pos = key + offset + 1;
/* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */ /* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */
res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data, res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index); &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
if (data) { if (data) {
*data = (void *)event_data; *data = (void *)event_data;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int dm_tls_set_event_output_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value, int dm_tls_set_event_output_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value,
_IN_ int value_len) _IN_ int value_len)
{ {
int res = 0, array_index = 0; int res = 0, array_index = 0;
int offset = 0; int offset = 0;
char *pos = NULL; char *pos = NULL;
kk_tsl_event_t *event = NULL; kk_tsl_event_t *event = NULL;
kk_tsl_data_t *event_data = NULL; kk_tsl_data_t *event_data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Key: %.*s", key_len, key); printf("Key: %.*s", key_len, key);
res = _kk_tsl_event_search(shadow, key, offset, &event); res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
pos = key + offset + 1; pos = key + offset + 1;
/* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */ /* dm_log_debug("TSL Event Output Data Search, Event Data ID: %s",pos); */
res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data, res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index); &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
if (event_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { if (event_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
res = _kk_tsl_data_array_set(&event_data->data_value, value, value_len, array_index); res = _kk_tsl_data_array_set(&event_data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_SET_FAILED; return TSL_EVENT_SET_FAILED;
} }
} else { } else {
res = _kk_tsl_data_set(&event_data->data_value, value, value_len); res = _kk_tsl_data_set(&event_data->data_value, value, value_len);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_SET_FAILED; return TSL_EVENT_SET_FAILED;
} }
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_service_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, static int _kk_tsl_service_search(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len,
_OU_ kk_tsl_service_t **service) _OU_ kk_tsl_service_t **service)
{ {
int index = 0; int index = 0;
kk_tsl_service_t *dtsl_service = NULL; kk_tsl_service_t *dtsl_service = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
for (index = 0; index < shadow->service_number; index++) { for (index = 0; index < shadow->service_number; index++) {
dtsl_service = shadow->services + index; dtsl_service = shadow->services + index;
if ((strlen(dtsl_service->identifier) == key_len) && if ((strlen(dtsl_service->identifier) == key_len) &&
(memcmp(dtsl_service->identifier, key, key_len) == 0)) { (memcmp(dtsl_service->identifier, key, key_len) == 0)) {
/* dm_log_debug("TSL Service Found: %s",dtsl_service->identifier); */ /* dm_log_debug("TSL Service Found: %s",dtsl_service->identifier); */
if (service) { if (service) {
*service = dtsl_service; *service = dtsl_service;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
/* dm_log_debug("TSL Service Not Found: %.*s",key_len,key); */ /* dm_log_debug("TSL Service Not Found: %.*s",key_len,key); */
return FAIL_RETURN; return FAIL_RETURN;
} }
static int _kk_tsl_service_input_output_search(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_service_t *service, static int _kk_tsl_service_input_output_search(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_service_t *service,
_IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_data_t **service_data, _OU_ int *index) _IN_ char *key, _IN_ int key_len, _OU_ kk_tsl_data_t **service_data, _OU_ int *index)
{ {
int res = 0, item_index = 0, datas_number = 0; int res = 0, item_index = 0, datas_number = 0;
kk_tsl_data_t *datas = NULL; kk_tsl_data_t *datas = NULL;
kk_tsl_data_t *data = NULL; kk_tsl_data_t *data = NULL;
if (type == KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA) { if (type == KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA) {
datas = service->input_datas; datas = service->input_datas;
datas_number = service->input_data_number; datas_number = service->input_data_number;
} else { } else {
datas = service->output_datas; datas = service->output_datas;
datas_number = service->output_data_number; datas_number = service->output_data_number;
} }
for (item_index = 0; item_index < datas_number; item_index++) { for (item_index = 0; item_index < datas_number; item_index++) {
data = datas + item_index; data = datas + item_index;
res = kk_tsl_data_search(data, key, key_len, service_data, index); res = kk_tsl_data_search(data, key, key_len, service_data, index);
if (res == SUCCESS_RETURN) { if (res == SUCCESS_RETURN) {
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int dm_tsl_get_service_input_output_data(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key, int dm_tsl_get_service_input_output_data(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
_IN_ int key_len, _OU_ void **data) _IN_ int key_len, _OU_ void **data)
{ {
int res = 0; int res = 0;
int offset = 0, array_index = 0; int offset = 0, array_index = 0;
char *pos = NULL; char *pos = NULL;
kk_tsl_service_t *service = NULL; kk_tsl_service_t *service = NULL;
kk_tsl_data_t *service_data = NULL; kk_tsl_data_t *service_data = NULL;
if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL
|| key == NULL || key_len <= 0) { || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Key: %.*s", key_len, key); //printf("Key: %.*s", key_len, key);
res = _kk_tsl_service_search(shadow, key, offset, &service); res = _kk_tsl_service_search(shadow, key, offset, &service);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
pos = key + offset + 1; pos = key + offset + 1;
printf("TSL Service input/output Data Search, Event Data ID: %s", pos); //printf("TSL Service input/output Data Search, Event Data ID: %s", pos);
res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index); res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_NOT_EXIST; return TSL_EVENT_NOT_EXIST;
} }
if (data) { if (data) {
*data = (void *)service_data; *data = (void *)service_data;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int dm_tsl_set_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key, int dm_tsl_set_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
_IN_ int key_len, _IN_ void *value, _IN_ int value_len) _IN_ int key_len, _IN_ void *value, _IN_ int value_len)
{ {
int res = 0, array_index = 0; int res = 0, array_index = 0;
int offset = 0; int offset = 0;
char *pos = NULL; char *pos = NULL;
kk_tsl_service_t *service = NULL; kk_tsl_service_t *service = NULL;
kk_tsl_data_t *service_data = NULL; kk_tsl_data_t *service_data = NULL;
if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL if (type < KK_TSL_DATA_TARGET_SERVICE_INPUT_DATA || type > KK_TSL_DATA_TARGET_SERVICE_OUTPUT_DATA || shadow == NULL
|| key == NULL || key_len <= 0) { || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Key: %.*s", key_len, key); //printf("Key: %.*s", key_len, key);
res = _kk_tsl_service_search(shadow, key, offset, &service); res = _kk_tsl_service_search(shadow, key, offset, &service);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_SERVICE_NOT_EXIST; return TSL_SERVICE_NOT_EXIST;
} }
pos = key + offset + 1; pos = key + offset + 1;
printf("TSL Service Input/Output Data Search, Event Data ID: %s", pos); //printf("TSL Service Input/Output Data Search, Event Data ID: %s", pos);
res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index); res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_SERVICE_NOT_EXIST; return TSL_SERVICE_NOT_EXIST;
} }
if (service_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { if (service_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
res = _kk_tsl_data_array_set(&service_data->data_value, value, value_len, array_index); res = _kk_tsl_data_array_set(&service_data->data_value, value, value_len, array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_SERVICE_SET_FAILED; return TSL_SERVICE_SET_FAILED;
} }
} else { } else {
res = _kk_tsl_data_set(&service_data->data_value, value, value_len); res = _kk_tsl_data_set(&service_data->data_value, value, value_len);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_SERVICE_SET_FAILED; return TSL_SERVICE_SET_FAILED;
} }
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
int kk_tsl_get_data_type(_IN_ void *data, _OU_ kk_tsl_data_type_e *type) int kk_tsl_get_data_type(_IN_ void *data, _OU_ kk_tsl_data_type_e *type)
{ {
kk_tsl_data_t *data_item = (kk_tsl_data_t *)data; kk_tsl_data_t *data_item = (kk_tsl_data_t *)data;
if (data_item == NULL || type == NULL) { if (data_item == NULL || type == NULL) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
if (data_item->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { if (data_item->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
kk_tsl_data_value_complex_t *complex_value = (kk_tsl_data_value_complex_t *)data_item->data_value.value; kk_tsl_data_value_complex_t *complex_value = (kk_tsl_data_value_complex_t *)data_item->data_value.value;
*type = complex_value->type; *type = complex_value->type;
} else { } else {
*type = data_item->data_value.type; *type = data_item->data_value.type;
} }
return SUCCESS_RETURN; return SUCCESS_RETURN;
} }
static int _kk_tsl_data_array_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index) static int _kk_tsl_data_array_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value, _IN_ int index)
{ {
kk_tsl_data_value_complex_t *complex_array = data_value->value; kk_tsl_data_value_complex_t *complex_array = data_value->value;
if (complex_array == NULL || index < 0 || index >= complex_array->size) { if (complex_array == NULL || index < 0 || index >= complex_array->size) {
return FAIL_RETURN; return FAIL_RETURN;
} }
if (g_iotx_data_type_mapping[complex_array->type].func_array_get == NULL) { if (g_iotx_data_type_mapping[complex_array->type].func_array_get == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return g_iotx_data_type_mapping[complex_array->type].func_array_get(data_value, value, index); return g_iotx_data_type_mapping[complex_array->type].func_array_get(data_value, value, index);
} }
static int _kk_tsl_data_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value) static int _kk_tsl_data_get(_IN_ kk_tsl_data_value_t *data_value, _IN_ void *value)
{ {
if (g_iotx_data_type_mapping[data_value->type].func_get == NULL) { if (g_iotx_data_type_mapping[data_value->type].func_get == NULL) {
return FAIL_RETURN; return FAIL_RETURN;
} }
return g_iotx_data_type_mapping[data_value->type].func_get(data_value, value); return g_iotx_data_type_mapping[data_value->type].func_get(data_value, value);
} }
int kk_tsl_get_property_value_ex(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void *value) int kk_tsl_get_property_value_ex(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _OU_ void *value)
{ {
int res = 0, array_index = 0; int res = 0, array_index = 0;
kk_tsl_data_t *data = NULL; kk_tsl_data_t *data = NULL;
if (shadow == NULL || key == NULL || key_len <= 0) { if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER; return INVALID_PARAMETER;
} }
res = _kk_tsl_property_search(shadow, key, key_len, &data, &array_index); res = _kk_tsl_property_search(shadow, key, key_len, &data, &array_index);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return FAIL_RETURN; return FAIL_RETURN;
} }
printf("Current Found Data: %s\n", data->identifier); if (data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
if (data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { res = _kk_tsl_data_array_get(&data->data_value, value, array_index);
printf("Current Found Data Index: %d\n", array_index); if (res != SUCCESS_RETURN) {
res = _kk_tsl_data_array_get(&data->data_value, value, array_index); return TSL_PROPERTY_GET_FAILED;
if (res != SUCCESS_RETURN) { }
return TSL_PROPERTY_GET_FAILED; } else {
} res = _kk_tsl_data_get(&data->data_value, value);
} else { if (res != SUCCESS_RETURN) {
res = _kk_tsl_data_get(&data->data_value, value); return TSL_PROPERTY_GET_FAILED;
if (res != SUCCESS_RETURN) { }
return TSL_PROPERTY_GET_FAILED; }
}
} return SUCCESS_RETURN;
}
return SUCCESS_RETURN; int kk_tsl_get_event_oput_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value)
} {
int kk_tsl_get_event_oput_value(_IN_ kk_tsl_t *shadow, _IN_ char *key, _IN_ int key_len, _IN_ void *value) int res = 0;
{ int offset = 0, array_index = 0;
int res = 0; char *pos = NULL;
int offset = 0, array_index = 0; kk_tsl_event_t *event = NULL;
char *pos = NULL; kk_tsl_data_t *event_data = NULL;
kk_tsl_event_t *event = NULL;
kk_tsl_data_t *event_data = NULL; if (shadow == NULL || key == NULL || key_len <= 0) {
return INVALID_PARAMETER;
if (shadow == NULL || key == NULL || key_len <= 0) { }
return INVALID_PARAMETER;
} res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (res != SUCCESS_RETURN) {
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); return FAIL_RETURN;
if (res != SUCCESS_RETURN) { }
return FAIL_RETURN;
} res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) {
printf("Key: %.*s\n", key_len, key); return TSL_EVENT_NOT_EXIST;
}
res = _kk_tsl_event_search(shadow, key, offset, &event);
if (res != SUCCESS_RETURN) { pos = key + offset + 1;
return TSL_EVENT_NOT_EXIST;
} res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index);
pos = key + offset + 1; if (res != SUCCESS_RETURN) {
printf("TSL Event Output Data Search, Event Data ID: %s", pos); return TSL_EVENT_NOT_EXIST;
}
res = _kk_tsl_event_output_search(event->output_datas, event->output_data_number, pos, strlen(pos), &event_data,
&array_index); if (event_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
if (res != SUCCESS_RETURN) { res = _kk_tsl_data_array_get(&event_data->data_value, value, array_index);
return TSL_EVENT_NOT_EXIST; if (res != SUCCESS_RETURN) {
} return TSL_EVENT_GET_FAILED;
}
if (event_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { } else {
res = _kk_tsl_data_array_get(&event_data->data_value, value, array_index); res = _kk_tsl_data_get(&event_data->data_value, value);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_EVENT_GET_FAILED; return TSL_EVENT_GET_FAILED;
} }
} else { }
res = _kk_tsl_data_get(&event_data->data_value, value);
if (res != SUCCESS_RETURN) { return SUCCESS_RETURN;
return TSL_EVENT_GET_FAILED; }
} int kk_tsl_get_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key,
} _IN_ int key_len, _IN_ void *value)
{
return SUCCESS_RETURN; int res = 0;
} int offset = 0, array_index = 0;
int kk_tsl_get_service_input_output_value(_IN_ kk_tsl_data_target_e type, _IN_ kk_tsl_t *shadow, _IN_ char *key, char *pos = NULL;
_IN_ int key_len, _IN_ void *value) kk_tsl_service_t *service = NULL;
{ kk_tsl_data_t *service_data = NULL;
int res = 0;
int offset = 0, array_index = 0; if (shadow == NULL || key == NULL || key_len <= 0) {
char *pos = NULL; return INVALID_PARAMETER;
kk_tsl_service_t *service = NULL; }
kk_tsl_data_t *service_data = NULL;
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset);
if (shadow == NULL || key == NULL || key_len <= 0) { if (res != SUCCESS_RETURN) {
return INVALID_PARAMETER; return FAIL_RETURN;
} }
res = kk_utils_memtok(key, key_len, KK_MSG_KEY_DELIMITER, 1, &offset); //printf("key: %.*s\n", key_len, key);
if (res != SUCCESS_RETURN) {
return FAIL_RETURN; res = _kk_tsl_service_search(shadow, key, offset, &service);
} if (res != SUCCESS_RETURN) {
return TSL_SERVICE_NOT_EXIST;
printf("key: %.*s\n", key_len, key); }
res = _kk_tsl_service_search(shadow, key, offset, &service); pos = key + offset + 1;
if (res != SUCCESS_RETURN) { //printf("TSL Service Input/Output Data Search, Event Data ID: %s", pos);
return TSL_SERVICE_NOT_EXIST;
} res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index);
if (res != SUCCESS_RETURN) {
pos = key + offset + 1; return TSL_SERVICE_NOT_EXIST;
printf("TSL Service Input/Output Data Search, Event Data ID: %s", pos); }
res = _kk_tsl_service_input_output_search(type, service, pos, strlen(pos), &service_data, &array_index); if (service_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) {
if (res != SUCCESS_RETURN) { res = _kk_tsl_data_array_get(&service_data->data_value, value, array_index);
return TSL_SERVICE_NOT_EXIST; if (res != SUCCESS_RETURN) {
} return TSL_SERVICE_GET_FAILED;
}
if (service_data->data_value.type == KK_TSL_DATA_TYPE_ARRAY) { } else {
res = _kk_tsl_data_array_get(&service_data->data_value, value, array_index); res = _kk_tsl_data_get(&service_data->data_value, value);
if (res != SUCCESS_RETURN) { if (res != SUCCESS_RETURN) {
return TSL_SERVICE_GET_FAILED; return TSL_SERVICE_GET_FAILED;
} }
} else { }
res = _kk_tsl_data_get(&service_data->data_value, value);
if (res != SUCCESS_RETURN) { return SUCCESS_RETURN;
return TSL_SERVICE_GET_FAILED; }
} void kk_tsl_datavalue_free(kk_tsl_data_value_t *data_value)
} {
if (g_iotx_data_type_mapping[data_value->type].func_free == NULL) {
return SUCCESS_RETURN; return;
} }
void kk_tsl_datavalue_free(kk_tsl_data_value_t *data_value) g_iotx_data_type_mapping[data_value->type].func_free(data_value);
{ }
if (g_iotx_data_type_mapping[data_value->type].func_free == NULL) {
return;
}
g_iotx_data_type_mapping[data_value->type].func_free(data_value);
}
...@@ -3,20 +3,7 @@ ...@@ -3,20 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include "kk_tsl_common.h" #include "kk_tsl_common.h"
#include "kk_dm_mng.h" #include "kk_dm_mng.h"
#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" #include "kk_log.h"
#endif
#define TSL_SUBDEVICE_PATH_FILE "/home/kk/tsl/product_%s.json" #define TSL_SUBDEVICE_PATH_FILE "/home/kk/tsl/product_%s.json"
#define TSL_GATEWAY_PATH_FILE "/home/kk/tsl/gateway-%s.json" #define TSL_GATEWAY_PATH_FILE "/home/kk/tsl/gateway-%s.json"
#define TSL_CCU_PATH_FILE "/home/kk/tsl/ccu-%s.json" #define TSL_CCU_PATH_FILE "/home/kk/tsl/ccu-%s.json"
......
...@@ -289,9 +289,9 @@ APPLICATION_FILES= \ ...@@ -289,9 +289,9 @@ APPLICATION_FILES= \
./ZB/kk_device_table_db.c\ ./ZB/kk_device_table_db.c\
./ZB/kk_msg_report.c\ ./ZB/kk_msg_report.c\
./ZB/kk_plat_ota.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\
......
{
"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
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"productCode":"3073", "productCode":"3073",
"config":[ "config":[
{ {
"identity":"PowerSwitch_1", "identity":"PowerSwitch",
"endpoint":1, "endpoint":1,
"cluster":"0x0006", "cluster":"0x0006",
"attribute":"0x0000", "attribute":"0x0000",
...@@ -11,37 +11,37 @@ ...@@ -11,37 +11,37 @@
},{ },{
"identity":"RGBColor.red", "identity":"RGBColor.red",
"endpoint":1, "endpoint":1,
"cluster":"", "cluster":"0xFFFF",
"attribute":"", "attribute":"0xFFFF",
"reportFunc":"", "reportFunc":"",
"controlFunc":"xxx" "controlFunc":"kk_tsl_set_colorlight_RGB_red"
},{ },{
"identity":"RGBColor.green", "identity":"RGBColor.green",
"endpoint":1, "endpoint":1,
"cluster":"", "cluster":"0xFFFF",
"attribute":"", "attribute":"0xFFFF",
"reportFunc":"", "reportFunc":"",
"controlFunc":"xxx" "controlFunc":"kk_tsl_set_colorlight_RGB_green"
},{ },{
"identity":"RGBColor.blue", "identity":"RGBColor.blue",
"endpoint":1, "endpoint":1,
"cluster":"", "cluster":"0xFFFF",
"attribute":"", "attribute":"0xFFFF",
"reportFunc":"", "reportFunc":"",
"controlFunc":"xxx" "controlFunc":"kk_tsl_set_colorlight_RGB_blue"
},{ },{
"identity":"CurrentHue", "identity":"CurrentHue",
"endpoint":1, "endpoint":1,
"cluster":"0x0300", "cluster":"0x0300",
"attribute":"0x0000", "attribute":"0x0000",
"reportFunc":"kk_tsl_report_global_onoff", "reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":"" "controlFunc":""
},{ },{
"identity":"CurrentSaturation", "identity":"CurrentSaturation",
"endpoint":1, "endpoint":1,
"cluster":"0x0300", "cluster":"0x0300",
"attribute":"0x0001", "attribute":"0x0001",
"reportFunc":"kk_tsl_report_global_onoff", "reportFunc":"kk_tsl_report_colorControl_RGB",
"controlFunc":"" "controlFunc":""
},{ },{
"identity":"Brightness", "identity":"Brightness",
...@@ -55,8 +55,8 @@ ...@@ -55,8 +55,8 @@
"endpoint":2, "endpoint":2,
"cluster":"0x0008", "cluster":"0x0008",
"attribute":"0x0000", "attribute":"0x0000",
"reportFunc":"kk_tsl_report_colorControl_WhiteBrightness", "reportFunc":"kk_tsl_report_colorControl_Brightness",
"controlFunc":"kk_tsl_set_colorlight_WhiteBrightness" "controlFunc":"kk_tsl_set_colorlight_Brightness"
},{ },{
"identity":"Mode", "identity":"Mode",
"endpoint":1, "endpoint":1,
......
...@@ -464,7 +464,7 @@ void kk_device_config_item_report(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId c ...@@ -464,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);
...@@ -554,8 +554,8 @@ bool kk_device_config_add(const char *productCode,const char *identity,uint8_t e ...@@ -554,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,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#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"
...@@ -19,6 +18,9 @@ ...@@ -19,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();
......
#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_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",
...@@ -10,12 +10,54 @@ const char *kk_tsl_rpt_status_string[] = { ...@@ -10,12 +10,54 @@ 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_map *dev_info = NULL;
kk_dev_config_item *item = NULL; kk_dev_config_item *item = NULL;
...@@ -45,13 +87,20 @@ static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId ...@@ -45,13 +87,20 @@ static int kk_tsl_report(EmberEUI64 mac,uint8_t EP,int status,uint16_t clusterId
} }
item = item->next; item = item->next;
} }
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,
...@@ -61,44 +110,48 @@ void kk_tsl_report_attribute(EmberEUI64 eui64, ...@@ -61,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;
} }
} }
...@@ -316,8 +369,107 @@ int kk_tsl_report_CO2(EmberEUI64 eui64,uint8_t EP,EmberAfClusterId clusterId,Emb ...@@ -316,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 *rpc_Control(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{
int res = 0;
cJSON *changeTypeStr = NULL;
uint8_t eui64[EUI64_SIZE];
uint16_t nodeId = 0;
UTIL_LOG_INFO("\n********************kk_topo_change_operation********************\n");
if(params == NULL){
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return;
}else{
changeTypeStr = rpc_cJSON_GetObjectItem(params, MSG_TOPO_CHANGE_TYPE_STR);
if(changeTypeStr != NULL && changeTypeStr->valueint == 1){
cJSON *deviceArray = rpc_cJSON_GetObjectItem(params, MSG_TOPO_CHANGE_DEVICES_STR);
if(deviceArray == NULL){
goto error_return;
}
cJSON * item = deviceArray->child;
while(item != NULL){
char *deviceCode = rpc_cJSON_GetObjectItem(item,MSG_DEVICE_CODE_STR)->valuestring;
rpc_get_mac(deviceCode,eui64);
nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
kk_zdo_leave_request(nodeId,true,false);
item = item->next;
}
}
}
return rpc_cJSON_CreateNumber(res);
error_return:
return rpc_cJSON_CreateNull();
}
int kk_tsl_utils_memtok(_IN_ char *input, _IN_ char *delimiter, _IN_ int index, _OU_ int *offset)
{
int item_index = 0;
int count = 0;
int input_len = 0;
if (input == NULL || offset == NULL) {
return -1;
}
input_len = strlen(input);
for (item_index = 0; item_index < input_len; item_index++) {
if (input[item_index] == delimiter && (item_index + 1) < input_len) {
count++;
if (count == index) {
*offset = item_index;
return 0;
}
}
}
return -1;
}
cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac) cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac)
{ {
sub_dev_node_t *node = NULL;
int res = 0; int res = 0;
rpc_nwk_info_s info; EmberStatus status;;
EmberStatus status; kk_device_table_s *dev;
int index = 0; kk_dev_config_map *dev_info = NULL;
zigbee_property_set *func; kk_dev_config_item *item = NULL;
int num; cJSON *propertyItem = NULL;
uint8_t findFlag = 0xff; cJSON *propertyItem1 = NULL;
cJSON *propertyItem = NULL; cJSON *propertyItem2 = NULL;
EmberEUI64 eui64; kk_rpc_set func;
int rev = 0,startIdx1 = 0,startIdx2 = 0;
char tmp_Identity[64] = {0};
int findFlag = 0;
uint8_t eui64[EUI64_SIZE];
EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID; EmberNodeId nodeId = EMBER_AF_PLUGIN_DEVICE_TABLE_NULL_NODE_ID;
UTIL_LOG_INFO("\n********************kk tsl property operation********************\n"); UTIL_LOG_INFO("\n********************kk tsl property operation********************\n");
...@@ -23,67 +91,77 @@ cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJ ...@@ -23,67 +91,77 @@ cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJ
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return; goto error_return;
}else{ }else{
res = kk_sub_tsl_get_device_by_mac(mac->valuestring, &node); rpc_get_mac(mac->valuestring,eui64);
if (res != SUCCESS_RETURN) { nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
printf("[%s][%d]\n",__FUNCTION__,__LINE__); dev = kk_device_find_by_mac(eui64);
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS); if(dev == NULL){
goto error_return;
}
dev_info = kk_device_config_find(dev->productCode);
if(dev_info == NULL){
goto error_return; goto error_return;
} }
item = &dev_info->item;
num = kk_get_tsl_num(); while(item!=NULL){
for(index = 0; index < num; index++){
propertyItem = rpc_cJSON_GetObjectItem(params, g_tsl_zigbee_map[index].Identity); rev = kk_tsl_utils_memtok(item->identity,'.',2,&startIdx2);
if(propertyItem != NULL){ if(!rev){
findFlag = 1; kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
break; memset(tmp_Identity,0x0,sizeof(tmp_Identity));
} memcpy(tmp_Identity, item->identity, startIdx1);
} propertyItem2 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
if(findFlag==0xff){ if(propertyItem2 != NULL){
num = kk_get_tsl_glb_num(); memset(tmp_Identity,0x0,sizeof(tmp_Identity));
for(index = 0; index < num; index++){ memcpy(tmp_Identity, item->identity+startIdx1+1, startIdx2-startIdx1);
propertyItem = rpc_cJSON_GetObjectItem(params, g_tsl_zigbee_map_glb[index].map.Identity); propertyItem1 = rpc_cJSON_GetObjectItem(propertyItem2,tmp_Identity);
if(propertyItem != NULL){ if(propertyItem1 != NULL){
findFlag = 2; propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx2+1);
break; if(propertyItem != NULL){
findFlag = 1;
}
}
} }
}
}
if(findFlag!=0xff)
{
int value = 0;
if(propertyItem->type != cJSON_Number){
value = rpc_get_u8(propertyItem->valuestring);
}else{
value = propertyItem->valueint;
}
if(rpc_get_mac(mac->valuestring,eui64)==false){
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return;
}
nodeId = emberAfDeviceTableGetNodeIdFromEui64(eui64);
emberAfDebugPrint("mac:");
emberAfPrintBigEndianEui64(eui64);
emberAfDebugPrintln(",node:0x%04X",nodeId);
if(findFlag==1)
res = g_tsl_zigbee_map[index].zigbee_set(ctx,nodeId,g_tsl_zigbee_map[index].endpoint,&value);
else if(findFlag==2)
res = g_tsl_zigbee_map_glb[index].map.zigbee_set(ctx,nodeId,g_tsl_zigbee_map_glb[index].map.endpoint,&value);
if(res < 0)
{
set_json_error_type(ctx,JRPC_INVALID_PARAMS,MSG_INVALID_PARAMS);
goto error_return;
}
else{
return rpc_cJSON_CreateNumber(res);
} }
} else{
rev = kk_tsl_utils_memtok(item->identity,'.',1,&startIdx1);
if(!rev){
memset(tmp_Identity,0x0,sizeof(tmp_Identity));
memcpy(tmp_Identity, item->identity, startIdx1);
propertyItem1 = rpc_cJSON_GetObjectItem(params,tmp_Identity);
if(propertyItem1 != NULL){
propertyItem = rpc_cJSON_GetObjectItem(propertyItem1,item->identity+startIdx1+1);
if(propertyItem != NULL){
findFlag = 1;
}
}
}
else{
propertyItem = rpc_cJSON_GetObjectItem(params, item->identity);
if(propertyItem != NULL){
findFlag = 1;
}
}
}
if(findFlag == 1){
int value = 0;
if(propertyItem->type != cJSON_Number){
value = rpc_get_u8(propertyItem->valuestring);
}else{
value = propertyItem->valueint;
}
func = item->controlFunc;
res = func(ctx,nodeId,item->endpoint,&value);
findFlag = 0;
}
item = item->next;
}
return rpc_cJSON_CreateNumber(res);
} }
error_return: error_return:
return rpc_cJSON_CreateNull(); return rpc_cJSON_CreateNull();
} }
...@@ -221,7 +299,70 @@ error_return: ...@@ -221,7 +299,70 @@ error_return:
return -1; 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;
}
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#define __KK_TSL_PROPERTY_SET_H #define __KK_TSL_PROPERTY_SET_H
#include "kk_test.h" #include "kk_test.h"
cJSON *kk_topo_change_operation(jrpc_context * ctx, cJSON *params, cJSON *id,cJSON *mac);
cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON * params, cJSON *id,cJSON *mac); cJSON *kk_tsl_property_operation(jrpc_context * ctx, cJSON * params, cJSON *id,cJSON *mac);
...@@ -11,6 +13,12 @@ int kk_tsl_set_windowCovering_OperationMode(jrpc_context * ctx,EmberNodeId node, ...@@ -11,6 +13,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"}\
......
...@@ -20,12 +20,17 @@ void kk_rpc_test(void); ...@@ -20,12 +20,17 @@ void kk_rpc_test(void);
#define KK_RPC_SET_FUNCTION_TABLE {\ #define KK_RPC_SET_FUNCTION_TABLE {\
{"zclOnOff",kk_tsl_set_gloabl_OnOff},\ {"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[];
......
#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)
{ {
......
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
#define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add" #define KK_REPORT_DEVICE_JOINED_TYPE "/thing/topo/add"
#define KK_REPORT_DEVICE_LEFT_TYPE "/thing/topo/delete" #define KK_REPORT_DEVICE_LEFT_TYPE "/thing/topo/delete"
#define KK_REPORT_ATTRIBUTE_TYPE "/thing/event/property/post" #define KK_REPORT_ATTRIBUTE_TYPE "/thing/event/property/post"
#define KK_DEVICE_TOPO_CHANGE_TYPE "/thing/topo/change"
#define KK_IPC_VERSION "1.0" #define KK_IPC_VERSION "1.0"
#define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add" #define KK_REPORT_DEVICE_JOINED_METHOD "thing.topo.add"
...@@ -30,7 +31,8 @@ ...@@ -30,7 +31,8 @@
#define TEST_PRODUCT_CODE "24" #define TEST_PRODUCT_CODE "24"
#define GW2CCU_PROTOCOL "tcp" #define GW2CCU_PROTOCOL "tcp"
#define MSG_TOPO_CHANGE_TYPE_STR "changeType"
#define MSG_TOPO_CHANGE_DEVICES_STR "devices"
...@@ -48,7 +50,8 @@ int kk_sendData2CCU(char* data, int len); ...@@ -48,7 +50,8 @@ int kk_sendData2CCU(char* data, int len);
#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"},\
{(rpc_function*)kk_tsl_property_operation,KK_READ_ATTRIBUTE_METHOD} {(rpc_function*)kk_tsl_property_operation,KK_READ_ATTRIBUTE_METHOD},\
{(rpc_function*)kk_topo_change_operation,KK_DEVICE_TOPO_CHANGE_TYPE}
......
#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
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