293 static int decode_status(
unsigned char code) {
297 case 0x15:
return ENODEV;
309 if (!ctx)
return NULL;
324 static uint64_t uint64_from_msg(uint8_t *msg) {
326 tmp = msg[7]; tmp <<=8;
327 tmp |= msg[6]; tmp <<=8;
328 tmp |= msg[5]; tmp <<=8;
329 tmp |= msg[4]; tmp <<=8;
330 tmp |= msg[3]; tmp <<=8;
331 tmp |= msg[2]; tmp <<=8;
332 tmp |= msg[1]; tmp <<=8;
337 static void msg_from_uint64(
unsigned char *pmsg, uint64_t mac) {
338 *pmsg++ = mac & 0xff;
339 *pmsg++ = mac >> 8 & 0xff;
340 *pmsg++ = mac >> 16 & 0xff;
341 *pmsg++ = mac >> 24 & 0xff;
342 *pmsg++ = mac >> 32 & 0xff;
343 *pmsg++ = mac >> 40 & 0xff;
344 *pmsg++ = mac >> 48 & 0xff;
345 *pmsg++ = mac >> 56 & 0xff;
353 static uint16_t uint16_from_msg(uint8_t *msg) {
355 tmp = msg[0] | (msg[1]<<8);
369 static void fill_telegram_header(
unsigned char *msg,
unsigned int len, uint32_t token,
unsigned char flags,
unsigned char command)
383 static int check_header_response(
unsigned char *msg, uint32_t token,
391 if (token != token2)
return -EPROTO;
399 if(!ctx)
return NULL;
407 if(!ctx)
return NULL;
413 if (!ctx)
return NULL;
419 if (!ctx)
return -EINVAL;
427 if (!ctx)
return -EINVAL;
444 if (!c)
return -ENOMEM;
449 #ifdef HAVE_SECURE_GETENV 452 env = secure_getenv(
"lightify_LOG");
457 info(c,
"ctx %p created\n", c);
475 dbg(ctx,
"freeing node %p.\n", ctx->
nodes);
483 dbg(ctx,
"freeing group %p.\n", ctx->
groups);
489 if (!ctx)
return -EINVAL;
492 free_all_groups(ctx);
494 dbg(ctx,
"context %p freed.\n", ctx);
506 if (!ctx)
return -EINVAL;
530 info(ctx,
"socket_write_fn error %d\n", n);
541 info(ctx,
"socket_read_fn error %d\n", n);
551 n = check_header_response(msg, token, 0x13);
553 info(ctx,
"Invalid response (header)\n");
560 if (!no_of_nodes)
return 0;
569 dbg(ctx,
"0x13: Dec-15 GW protocol\n");
574 dbg(ctx,
"0x13: Old GW protocol\n");
576 info(ctx,
"Reponse len unexpected for %d nodes: %d.\n", no_of_nodes, m);
581 info(ctx,
"strange byte at PAYLOAD_START: %d\n", msg[HEADER_PAYLOAD_START]);
586 while(no_of_nodes--) {
591 if (read_size != n ) {
592 info(ctx,
"read node info: short read %d!=%d\n", read_size, n);
598 info(ctx,
"create node error %d", n);
690 static int lightify_request_set_onoff(
struct lightify_ctx *ctx, uint64_t adr,
int isgroup,
int onoff) {
691 unsigned char msg[32];
693 if (!ctx)
return -EINVAL;
696 onoff = (onoff != 0);
697 isgroup = (isgroup) ? 2 : 0;
699 uint32_t token = ++ctx->
cnt;
707 info(ctx,
"socket_write_fn error %d\n", n);
718 info(ctx,
"socket_read_fn error %d\n", n);
725 info(ctx,
" %d => %x\n ",i, msg[i]);
733 n = check_header_response(msg, token, 0x32);
735 info(ctx,
"Invalid response (header)\n");
742 info(ctx,
"unexected node mac / group adr %llx!=%llx", adr, adr2 );
748 info(ctx,
"state %d indicates error.\n", n);
753 static int lightify_request_set_cct(
struct lightify_ctx *ctx, uint64_t adr,
int isgroup,
unsigned int cct,
unsigned int fadetime) {
754 unsigned char msg[32];
756 if (!ctx)
return -EINVAL;
758 uint32_t token = ++ctx->
cnt;
759 isgroup = (isgroup) ? 2 : 0;
769 info(ctx,
"socket_write_fn error %d\n", n);
780 info(ctx,
"socket_read_fn error %d\n", n);
789 n = check_header_response(msg, token, 0x33);
791 info(ctx,
"Invalid response (header)\n");
798 info(ctx,
"unexected node mac / group adr %llx!=%llx", adr, adr2 );
806 static int lightify_request_set_rgbw(
struct lightify_ctx *ctx, uint64_t adr,
807 int isgroup,
unsigned int r,
unsigned int g,
808 unsigned int b,
unsigned int w,
unsigned int fadetime) {
809 unsigned char msg[32];
811 if (!ctx)
return -EINVAL;
814 uint32_t token = ++ctx->
cnt;
815 isgroup = (isgroup) ? 2 : 0;
827 info(ctx,
"socket_write_fn error %d\n", n);
843 n = check_header_response(msg, token, 0x36);
845 info(ctx,
"Invalid response (header)\n");
852 info(ctx,
"unexected node mac / group adr %llx!=%llx", adr, adr2 );
860 static int lightify_request_set_brightness(
struct lightify_ctx *ctx, uint64_t adr,
861 int isgroup,
unsigned int level,
unsigned int fadetime) {
862 unsigned char msg[32];
864 if (!ctx)
return -EINVAL;
866 uint32_t token = ++ctx->
cnt;
867 isgroup = (isgroup) ? 2 : 0;
878 info(ctx,
"socket_write_fn error %d\n", n);
889 info(ctx,
"socket_read_fn error %d\n", n);
897 n = check_header_response(msg, token, 0x31);
899 info(ctx,
"Invalid response (header)\n");
906 info(ctx,
"unexected node mac / group adr %llx!=%llx", adr, adr2 );
917 if (!ctx)
return -EINVAL;
921 onoff = (onoff != 0);
922 int ret = lightify_request_set_onoff(ctx, adr, 0, onoff);
942 if (!ctx || !node )
return -EINVAL;
944 int ret = lightify_request_set_cct(ctx, adr, 0 , cct, fadetime);
955 if (!ctx || !node )
return -EINVAL;
957 int ret = lightify_request_set_rgbw(ctx, adr, 0, r, g ,b ,w ,fadetime);
970 if (!ctx || !node )
return -EINVAL;
972 int ret = lightify_request_set_brightness(ctx, adr, 0, level, fadetime);
988 if (!ctx)
return -EINVAL;
989 if (!node)
return -EINVAL;
992 uint32_t token = ++ctx->
cnt;
998 info(ctx,
"socket_write_fn error %d\n", n);
1009 info(ctx,
"socket_read_fn error %d\n", n);
1017 n = check_header_response(msg, token, 0x68);
1019 info(ctx,
"Invalid response (header)\n");
1026 dbg_proto(ctx,
"Node count expected 1 but is %u\n", (
unsigned int)n);
1032 dbg_proto(ctx,
"Node address not matching! %lx != %lx\n",
1033 node_adr, uint64_from_msg(&msg[ANSWER_0x68_NODEADR64_B0]));
1052 info(ctx,
"socket_read_fn error %d\n", n);
1055 if (n != read_size) {
1056 info(ctx,
"body short read %d!=%d\n", read_size, n);
1082 if (!ctx)
return -EINVAL;
1092 free_all_groups(ctx);
1105 info(ctx,
"socket_write_fn error %d\n", n);
1116 info(ctx,
"socket_read_fn error %d\n", n);
1126 n = check_header_response(msg, token, 0x1e);
1128 info(ctx,
"Invalid response (header)\n");
1135 info(ctx,
"0x1e: received %d bytes\n",m);
1137 info(ctx,
"Reponse len unexpected for %d groups: %d!=%d.\n", no_of_grps,
1143 info(ctx,
"strange byte at PAYLOAD_START: %d\n", msg[HEADER_PAYLOAD_START]);
1148 while(no_of_grps--) {
1159 info(ctx,
"create group error %d", n);
1173 if (!ctx || !group)
return -EINVAL;
1175 onoff = (onoff != 0);
1187 if (!ctx || !group)
return -EINVAL;
1201 unsigned int b,
unsigned int w,
unsigned int fadetime) {
1202 if (!ctx || !group)
return -EINVAL;
1219 if (!ctx || !group)
return -EINVAL;
int lightify_node_new(struct lightify_ctx *ctx, struct lightify_node **newnode)
LIGHTIFY_EXPORT int lightify_node_request_rgbw(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int r, unsigned int g, unsigned int b, unsigned int w, unsigned int fadetime)
LIGHTIFY_EXPORT int lightify_free(struct lightify_ctx *ctx)
int lightify_node_set_grpadr(struct lightify_node *node, uint16_t adr)
int lightify_node_set_onoff(struct lightify_node *node, uint8_t on)
LIGHTIFY_EXPORT int lightify_node_request_scan(struct lightify_ctx *ctx)
#define info(ctx, arg...)
int(* read_from_socket_fn)(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
const char * lightify_node_get_name(struct lightify_node *node)
LIGHTIFY_EXPORT int lightify_group_request_onoff(struct lightify_ctx *ctx, struct lightify_group *group, int onoff)
LIGHTIFY_EXPORT int lightify_node_request_onoff(struct lightify_ctx *ctx, struct lightify_node *node, int onoff)
int lightify_node_remove(struct lightify_node *node)
int lightify_set_log_priority(struct lightify_ctx *ctx, int priority)
LIGHTIFY_EXPORT int lightify_group_request_scan(struct lightify_ctx *ctx)
int write_to_socket(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
int(* socket_read_fn)(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
Function pointer to the I/O handling – read from.
struct lightify_node * nodes
int lightify_node_set_brightness(struct lightify_node *node, int brightness)
uint64_t lightify_node_get_nodeadr(struct lightify_node *node)
struct lightify_node * lightify_node_get_prevnode(struct lightify_node *node)
LIGHTIFY_EXPORT void * lightify_get_userdata(struct lightify_ctx *ctx)
LIGHTIFY_EXPORT int lightify_group_request_cct(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int cct, unsigned int fadetime)
LIGHTIFY_EXPORT int lightify_group_get_id(struct lightify_group *grp)
int lightify_node_set_stale(struct lightify_node *node, int stale)
LIGHTIFY_EXPORT int lightify_set_socket_fn(struct lightify_ctx *ctx, write_to_socket_fn fpw, read_from_socket_fn fpr)
void * userdata
Function pointer to the I/O handling – write to.
int lightify_node_set_zoneadr(struct lightify_node *node, uint16_t adr)
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_next(struct lightify_ctx *ctx, struct lightify_node *node)
int(* write_to_socket_fn)(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
int lightify_node_set_lamptype(struct lightify_node *node, enum lightify_node_type type)
int lightify_node_set_cct(struct lightify_node *node, int cct)
int(* socket_write_fn)(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
Function pointer to the I/O handling – read from.
LIGHTIFY_EXPORT int lightify_group_request_brightness(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int level, unsigned int fadetime)
int lightify_node_set_blue(struct lightify_node *node, int blue)
int lightify_node_set_red(struct lightify_node *node, int red)
LIGHTIFY_EXPORT struct lightify_node * lightify_group_get_next_node(struct lightify_group *grp, struct lightify_node *lastnode)
int lightify_node_set_green(struct lightify_node *node, int green)
int lightify_node_set_online_status(struct lightify_node *node, uint8_t state)
LIGHTIFY_EXPORT int lightify_node_request_brightness(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int level, unsigned int fadetime)
LIGHTIFY_EXPORT int lightify_set_userdata(struct lightify_ctx *ctx, void *userdata)
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_previous(struct lightify_ctx *ctx, struct lightify_node *node)
int lightify_group_set_id(struct lightify_group *grp, int id)
void(* log_fn)(struct lightify_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, va_list args)
LIGHTIFY_EXPORT int lightify_new(struct lightify_ctx **ctx, void *reserved)
int read_from_socket(struct lightify_ctx *ctx, unsigned char *msg, size_t size)
int lightify_node_set_nodeadr(struct lightify_node *node, uint64_t adr)
int lightify_group_new(struct lightify_ctx *ctx, struct lightify_group **newgroup)
struct lightify_node * lightify_node_get_nextnode(struct lightify_node *node)
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_from_mac(struct lightify_ctx *ctx, uint64_t mac)
#define dbg_proto(ctx, arg...)
int log_priority(const char *priority)
LIGHTIFY_EXPORT int lightify_node_request_update(struct lightify_ctx *ctx, struct lightify_node *node)
int lightify_group_remove(struct lightify_group *grp)
LIGHTIFY_EXPORT int lightify_node_request_cct(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int cct, unsigned int fadetime)
void log_stderr(struct lightify_ctx *ctx, int priority, const char *file, int line, const char *fn, const char *format, va_list args)
struct lightify_ctx * ctx
LIGHTIFY_EXPORT int lightify_group_request_rgbw(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int r, unsigned int g, unsigned int b, unsigned int w, unsigned int fadetime)
int lightify_node_set_white(struct lightify_node *node, int white)
int lightify_node_set_name(struct lightify_node *node, char *name)
int lightify_group_set_name(struct lightify_group *grp, const unsigned char *name)
struct lightify_group * groups