Mercurial > louis > mq > lightsd
changeset 242:d23d6fbb50df
Finally fix bulb printing, nice refactor and print ipv4 mapped ipv6 addresses
author | Louis Opter <kalessin@kalessin.fr> |
---|---|
date | Thu, 13 Aug 2015 02:29:45 -0700 |
parents | aaa04a77415b |
children | 1e98f511dc00 |
files | fix_ipv4_address_formatting.patch implement_some_metadata_packet_types.patch series |
diffstat | 3 files changed, 191 insertions(+), 203 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fix_ipv4_address_formatting.patch Thu Aug 13 02:29:45 2015 -0700 @@ -0,0 +1,40 @@ +# HG changeset patch +# Parent 9a3306521fe5002bdaf61c06d6d74ae5abc3d38e +Fix IPv4 address formatting + +diff --git a/core/log.c b/core/log.c +--- a/core/log.c ++++ b/core/log.c +@@ -26,6 +26,7 @@ + #include <stdbool.h> + #include <stdint.h> + #include <stdio.h> ++#include <stdlib.h> + #include <time.h> + + #if LGTD_HAVE_LIBBSD +@@ -93,12 +94,22 @@ + assert(buf); + assert(buflen > 0); + ++ const char *printed; + if (peer->ss_family == AF_INET) { + const struct sockaddr_in *in_peer = (const struct sockaddr_in *)peer; +- inet_ntop(AF_INET, &in_peer->sin_addr, buf, buflen); ++ int i = 0; ++ LGTD_SNPRINTF_APPEND(buf, i, buflen, "::ffff:"); ++ printed = inet_ntop(AF_INET, &in_peer->sin_addr, &buf[i], buflen - i); + } else { + const struct sockaddr_in6 *in6_peer = (const struct sockaddr_in6 *)peer; +- inet_ntop(AF_INET6, &in6_peer->sin6_addr, buf, buflen); ++ printed = inet_ntop(AF_INET6, &in6_peer->sin6_addr, buf, buflen); ++ } ++ if (!printed) { ++ buf[0] = 0; ++ lgtd_warnx("not enough space to log an ip address"); ++#ifndef NDEBUG ++ abort(); ++#endif + } + } +
--- a/implement_some_metadata_packet_types.patch Tue Aug 11 00:37:46 2015 -0700 +++ b/implement_some_metadata_packet_types.patch Thu Aug 13 02:29:45 2015 -0700 @@ -61,7 +61,7 @@ +#define LGTD_SNPRINTF_APPEND(buf, i, bufsz, ...) do { \ + int n = snprintf(&(buf)[(i)], bufsz - i, __VA_ARGS__); \ + (i) = LGTD_MIN((i) + n, bufsz); \ -+while (0) ++} while (0) enum lgtd_verbosity { LGTD_DEBUG = 0, @@ -126,108 +126,61 @@ diff --git a/core/proto.c b/core/proto.c --- a/core/proto.c +++ b/core/proto.c -@@ -196,6 +196,40 @@ +@@ -195,36 +195,108 @@ + return; } - static const char *state_fmt = ("{" -+ "\"_lifx\":{" -+ "\"gateway\":{" -+ "\"url\":\"tcp://%s:[%hu]\"," -+ "\"latency\":%d" -+ "}," -+ "\"mcu\":{" -+ "\"firmware_built_at\":\"%s\"," -+ "\"firmware_installed_at\":\"%s\"," -+ "\"firmware_version\":%u," -+ "\"signal_strength\":%u," -+ "\"tx_bytes\":%u," -+ "\"rx_bytes\":%u," -+ "\"unknown\":%u" -+ "}," -+ "\"wifi\":{" -+ "\"firmware_built_at\":\"%s\"," -+ "\"firmware_installed_at\":\"%s\"," -+ "\"firmware_version\":%u," -+ "\"signal_strength\":%u," -+ "\"tx_bytes\":%u," -+ "\"rx_bytes\":%u," -+ "\"unknown\":%u" -+ "}," -+ "\"product_info\":{" -+ "\"vendor_id\":%#x," -+ "\"product_id\":%#x," -+ "\"version\":%u" -+ "}," -+ "\"runtime_info\":{" -+ "\"time\":\"%s\"," -+ "\"uptime\":%ju," -+ "\"downtime\":%ju" -+ "}" -+ "}," - "\"hsbk\":[%s,%s,%s,%hu]," - "\"power\":%s," - "\"label\":\"%s\"," -@@ -206,6 +240,12 @@ - (src), (start), (stop), (dst), sizeof((dst)) \ - ) - +- static const char *state_fmt = ("{" +- "\"hsbk\":[%s,%s,%s,%hu]," +- "\"power\":%s," +- "\"label\":\"%s\"," +- "\"tags\":["); ++ lgtd_client_start_send_response(client); ++ lgtd_client_write_string(client, "["); ++ struct lgtd_router_device *device; ++ SLIST_FOREACH(device, devices, link) { ++ struct lgtd_lifx_bulb *bulb = device->device; ++ ++ char buf[2048]; ++ int i = 0; ++ ++ LGTD_SNPRINTF_APPEND( ++ buf, i, (int)sizeof(buf), ++ "{" ++ "\"_lifx\":{" ++ "\"gateway\":{" ++ "\"url\":\"tcp://[%s]:%hu\"," ++ "\"latency\":%ju" ++ "},", ++ bulb->gw->ip_addr, bulb->gw->port, ++ (uintmax_t)LGTD_LIFX_GATEWAY_LATENCY(bulb->gw) ++ ); ++ +#define PRINT_LIFX_FW_TIMESTAMPS(fw_info, built_at_buf, installed_at_buf) \ + LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP((fw_info)->built_at, (built_at_buf)); \ + LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP( \ + (fw_info)->installed_at, (installed_at_buf) \ + ) + - lgtd_client_start_send_response(client); - lgtd_client_write_string(client, "["); - struct lgtd_router_device *device; -@@ -217,14 +257,91 @@ - PRINT_COMPONENT(bulb->state.saturation, s, 0, 1); - PRINT_COMPONENT(bulb->state.brightness, b, 0, 1); - -- char buf[3072]; -- int written = snprintf( -- buf, sizeof(buf), state_fmt, -+ char mcu_fw_built_at[64], mcu_fw_installed_at[64], bulb_time[64]; -+ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(bulb->runtime_info.time, bulb_time); -+ PRINT_LIFX_FW_TIMESTAMPS( -+ &bulb->mcu_fw_info, mcu_fw_built_at, mcu_fw_installed_at -+ ); ++ for (int ip = 0; ip != LGTD_LIFX_BULB_IP_COUNT; ip++) { ++ char fw_built_at[64], fw_installed_at[64]; ++ PRINT_LIFX_FW_TIMESTAMPS( ++ &bulb->ips[ip].fw_info, fw_built_at, fw_installed_at ++ ); + -+ char wifi_fw_built_at[64], wifi_fw_installed_at[64]; -+ PRINT_LIFX_FW_TIMESTAMPS( -+ &bulb->wifi_fw_info, wifi_fw_built_at, wifi_fw_installed_at -+ ); -+ -+ char buf[2048]; -+ int i = 0; -+ -+ LGTD_SNPRINTF_APPEND( -+ buf, i, (int)sizeof(buf), "{" -+ "\"_lifx\":{" -+ "\"gateway\":{" -+ "\"url\":\"tcp://%s:[%hu]\"," -+ "\"latency\":%d" -+ "},", -+ bulb->gw->ip_addr, bulb->gw->port, -+ LGTD_LIFX_GATEWAY_LATENCY(bulb->gw) -+ ); -+ -+ for (int ip = 0; ip != LGTD_LIFX_BULB_IP_COUNT; ip++) { + LGTD_SNPRINTF_APPEND( + buf, i, (int)sizeof(buf), + "\"%s\":{" + "\"firmware_built_at\":\"%s\"," + "\"firmware_installed_at\":\"%s\"," + "\"firmware_version\":%u," -+ "\"signal_strength\":%u," ++ "\"signal_strength\":%f," + "\"tx_bytes\":%u," + "\"rx_bytes\":%u," + "\"unknown\":%u" + "},", + lgtd_lifx_bulb_ip_names[ip], -+ bulb->ips[ip].fw_info.built_at, -+ bulb->ips[ip].fw_info.installed_at, -+ bulb->ips[ip].fw_info.version, ++ fw_built_at, fw_installed_at, bulb->ips[ip].fw_info.version, + bulb->ips[ip].state.signal_strength, + bulb->ips[ip].state.tx_bytes, + bulb->ips[ip].state.rx_bytes, @@ -244,9 +197,11 @@ + "},", + bulb->product_info.vendor_id, + bulb->product_info.product_id, -+ bulb->product_info.version, ++ bulb->product_info.version + ); + ++ char bulb_time[64]; ++ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(bulb->runtime_info.time, bulb_time); + LGTD_SNPRINTF_APPEND( + buf, i, (int)sizeof(buf), + "\"runtime_info\":{" @@ -254,12 +209,31 @@ + "\"uptime\":%ju," + "\"downtime\":%ju" + "}" -+ "}," ++ "},", + bulb_time, + LGTD_NSECS_TO_SECS(bulb->runtime_info.uptime), -+ LGTD_NSECS_TO_SECS(bulb->runtime_info.downtime), ++ LGTD_NSECS_TO_SECS(bulb->runtime_info.downtime) + ); -+ + + #define PRINT_COMPONENT(src, dst, start, stop) \ + lgtd_jsonrpc_uint16_range_to_float_string( \ + (src), (start), (stop), (dst), sizeof((dst)) \ + ) + +- lgtd_client_start_send_response(client); +- lgtd_client_write_string(client, "["); +- struct lgtd_router_device *device; +- SLIST_FOREACH(device, devices, link) { +- struct lgtd_lifx_bulb *bulb = device->device; +- + char h[16], s[16], b[16]; + PRINT_COMPONENT(bulb->state.hue, h, 0, 360); + PRINT_COMPONENT(bulb->state.saturation, s, 0, 1); + PRINT_COMPONENT(bulb->state.brightness, b, 0, 1); + +- char buf[3072]; +- int written = snprintf( +- buf, sizeof(buf), state_fmt, + LGTD_SNPRINTF_APPEND( + buf, i, (int)sizeof(buf), + "\"hsbk\":[%s,%s,%s,%hu]," @@ -272,10 +246,22 @@ ); - if (written >= (int)sizeof(buf)) { + -+ if (i == (int)sizeof(buf)) { ++ if (i >= (int)sizeof(buf)) { lgtd_warnx( "can't send state of bulb %s (%s) to client " "[%s]:%hu: output buffer to small", +diff --git a/examples/lightsc.py b/examples/lightsc.py +--- a/examples/lightsc.py ++++ b/examples/lightsc.py +@@ -17,7 +17,7 @@ + "id": str(uuid.uuid4()), + } + socket.send(json.dumps(payload).encode("utf-8")) +- response = socket.recv(2048).decode("utf-8") ++ response = socket.recv(8192).decode("utf-8") + try: + response = json.loads(response) + except ValueError: diff --git a/lifx/bulb.c b/lifx/bulb.c --- a/lifx/bulb.c +++ b/lifx/bulb.c @@ -283,58 +269,42 @@ struct lgtd_lifx_bulb_map lgtd_lifx_bulbs_table = RB_INITIALIZER(&lgtd_lifx_bulbs_table); -+const const char *lgtd_lifx_bulb_ip_names[] = { "mcu", "wifi" }; ++const char * const lgtd_lifx_bulb_ip_names[] = { "mcu", "wifi" }; + struct lgtd_lifx_bulb * lgtd_lifx_bulb_get(const uint8_t *addr) { -@@ -154,3 +156,69 @@ +@@ -154,3 +156,53 @@ bulb->state.tags = tags; } + +void -+lgtd_lifx_bulb_set_mcu_state(struct lgtd_lifx_bulb *bulb, -+ const struct lgtd_lifx_ip_state *state, -+ lgtd_time_mono_t received_at) ++lgtd_lifx_bulb_set_ip_state(struct lgtd_lifx_bulb *bulb, ++ enum lgtd_lifx_bulb_ips ip_id, ++ const struct lgtd_lifx_ip_state *state, ++ lgtd_time_mono_t received_at) +{ + assert(bulb); + assert(state); + -+ bulb->last_mcu_state_at = received_at; -+ memcpy(&bulb->mcu_state, state, sizeof(bulb->mcu_state)); ++ struct lgtd_lifx_bulb_ip *ip = &bulb->ips[ip_id]; ++ ip->state_updated_at = received_at; ++ memcpy(&ip->state, state, sizeof(ip->state)); +} + +void -+lgtd_lifx_bulb_set_mcu_firmware_info(struct lgtd_lifx_bulb *bulb, -+ const struct lgtd_lifx_ip_firmware_info *info) ++lgtd_lifx_bulb_set_ip_firmware_info(struct lgtd_lifx_bulb *bulb, ++ enum lgtd_lifx_bulb_ips ip_id, ++ const struct lgtd_lifx_ip_firmware_info *info, ++ lgtd_time_mono_t received_at) +{ + assert(bulb); + assert(info); + -+ memcpy(&bulb->mcu_fw_info, info, sizeof(bulb->mcu_fw_info)); -+} -+ -+void -+lgtd_lifx_bulb_set_wifi_state(struct lgtd_lifx_bulb *bulb, -+ const struct lgtd_lifx_ip_state *state, -+ lgtd_time_mono_t received_at) -+{ -+ assert(bulb); -+ assert(state); -+ -+ bulb->last_wifi_state_at = received_at; -+ memcpy(&bulb->wifi_state, state, sizeof(bulb->wifi_state)); -+} -+ -+void -+lgtd_lifx_bulb_set_wifi_firmware_info(struct lgtd_lifx_bulb *bulb, -+ const struct lgtd_lifx_ip_firmware_info *info) -+{ -+ assert(bulb); -+ assert(info); -+ -+ memcpy(&bulb->wifi_fw_info, info, sizeof(bulb->wifi_fw_info)); ++ struct lgtd_lifx_bulb_ip *ip = &bulb->ips[ip_id]; ++ ip->fw_info_updated_at = received_at; ++ memcpy(&ip->fw_info, info, sizeof(ip->fw_info)); +} + +void @@ -355,13 +325,13 @@ + assert(bulb); + assert(info); + -+ bulb->last_runtime_info_at = received_at; ++ bulb->runtime_info_updated_at = received_at; + memcpy(&bulb->runtime_info, info, sizeof(bulb->runtime_info)); +} diff --git a/lifx/bulb.h b/lifx/bulb.h --- a/lifx/bulb.h +++ b/lifx/bulb.h -@@ -30,17 +30,58 @@ +@@ -30,17 +30,61 @@ char label[LGTD_LIFX_LABEL_SIZE]; uint64_t tags; }; @@ -393,56 +363,52 @@ #pragma pack(pop) +enum lgtd_lifx_bulb_ips { -+ LGTD_LIFX_BULB_MCU_IP = 0, -+ LGTD_LIFX_BULB_WIFI_IP = 1, -+ LGTD_LIFX_BULB_IP_COUNT = 2 ++ LGTD_LIFX_BULB_MCU_IP = 0, ++ LGTD_LIFX_BULB_WIFI_IP, ++ LGTD_LIFX_BULB_IP_COUNT, +}; + -+extern const char *lgtd_lifx_bulb_ip_names[]; ++extern const char * const lgtd_lifx_bulb_ip_names[]; ++ ++struct lgtd_lifx_bulb_ip { ++ struct lgtd_lifx_ip_state state; ++ lgtd_time_mono_t state_updated_at; ++ struct lgtd_lifx_ip_firmware_info fw_info; ++ lgtd_time_mono_t fw_info_updated_at; ++}; + struct lgtd_lifx_bulb { -- RB_ENTRY(lgtd_lifx_bulb) link; -- SLIST_ENTRY(lgtd_lifx_bulb) link_by_gw; + RB_ENTRY(lgtd_lifx_bulb) link; + SLIST_ENTRY(lgtd_lifx_bulb) link_by_gw; - struct lgtd_lifx_gateway *gw; - uint8_t addr[LGTD_LIFX_ADDR_LENGTH]; - struct lgtd_lifx_light_state state; -- lgtd_time_mono_t last_light_state_at; -- lgtd_time_mono_t dirty_at; -- uint16_t expected_power_on; -+ RB_ENTRY(lgtd_lifx_bulb) link; -+ SLIST_ENTRY(lgtd_lifx_bulb) link_by_gw; -+ lgtd_time_mono_t last_light_state_at; -+ lgtd_time_mono_t last_runtime_info_at; -+ lgtd_time_mono_t dirty_at; -+ uint16_t expected_power_on; -+ uint8_t addr[LGTD_LIFX_ADDR_LENGTH]; -+ struct lgtd_lifx_gateway *gw; -+ struct lgtd_lifx_light_state state; -+ struct { -+ lgtd_time_mono_t updated_at; -+ struct lgtd_lifx_ip_state state; -+ struct lgtd_lifx_ip_firmware_info fw_info; -+ } ips[LGTD_LIFX_BULB_IP_COUNT]; -+ struct lgtd_lifx_product_info product_info; -+ struct lgtd_lifx_runtime_info runtime_info; + lgtd_time_mono_t last_light_state_at; ++ lgtd_time_mono_t runtime_info_updated_at; + lgtd_time_mono_t dirty_at; + uint16_t expected_power_on; ++ uint8_t addr[LGTD_LIFX_ADDR_LENGTH]; ++ struct lgtd_lifx_gateway *gw; ++ struct lgtd_lifx_light_state state; ++ struct lgtd_lifx_bulb_ip ips[LGTD_LIFX_BULB_IP_COUNT]; ++ struct lgtd_lifx_product_info product_info; ++ struct lgtd_lifx_runtime_info runtime_info; }; RB_HEAD(lgtd_lifx_bulb_map, lgtd_lifx_bulb); SLIST_HEAD(lgtd_lifx_bulb_list, lgtd_lifx_bulb); -@@ -69,3 +110,19 @@ +@@ -69,3 +113,17 @@ lgtd_time_mono_t); void lgtd_lifx_bulb_set_power_state(struct lgtd_lifx_bulb *, uint16_t); void lgtd_lifx_bulb_set_tags(struct lgtd_lifx_bulb *, uint64_t); + -+void lgtd_lifx_bulb_set_mcu_state(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_state *, -+ lgtd_time_mono_t); -+void lgtd_lifx_bulb_set_mcu_firmware_info(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_firmware_info *); -+void lgtd_lifx_bulb_set_wifi_state(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_state *, -+ lgtd_time_mono_t); -+void lgtd_lifx_bulb_set_wifi_firmware_info(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_firmware_info *); ++void lgtd_lifx_bulb_set_ip_state(struct lgtd_lifx_bulb *bulb, ++ enum lgtd_lifx_bulb_ips ip_id, ++ const struct lgtd_lifx_ip_state *state, ++ lgtd_time_mono_t received_at); ++void lgtd_lifx_bulb_set_ip_firmware_info(struct lgtd_lifx_bulb *bulb, ++ enum lgtd_lifx_bulb_ips ip_id, ++ const struct lgtd_lifx_ip_firmware_info *info, ++ lgtd_time_mono_t received_at); +void lgtd_lifx_bulb_set_product_info(struct lgtd_lifx_bulb *, + const struct lgtd_lifx_product_info *); +void lgtd_lifx_bulb_set_runtime_info(struct lgtd_lifx_bulb *, @@ -521,7 +487,7 @@ int tag_id; LGTD_LIFX_WIRE_FOREACH_TAG_ID(tag_id, pkt->tags) { -@@ -707,3 +695,142 @@ +@@ -707,3 +695,129 @@ lgtd_lifx_bulb_set_tags(b, pkt->tags); } @@ -534,18 +500,15 @@ + assert(gw && hdr && pkt); + + const char *type; -+ void (*bulb_fn)(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_state *, -+ lgtd_time_mono_t); -+ ++ enum lgtd_lifx_bulb_ips ip_id; + switch (hdr->packet_type) { + case LGTD_LIFX_MESH_INFO: + type = "MCU_STATE"; -+ bulb_fn = lgtd_lifx_bulb_set_mcu_state; ++ ip_id = LGTD_LIFX_BULB_MCU_IP; + break; + case LGTD_LIFX_WIFI_INFO: + type = "WIFI_STATE"; -+ bulb_fn = lgtd_lifx_bulb_set_wifi_state; ++ ip_id = LGTD_LIFX_BULB_WIFI_IP; + break; + default: + lgtd_info("invalid ip state packet_type %#hx", hdr->packet_type); @@ -562,11 +525,9 @@ + pkt->signal_strength, pkt->rx_bytes, pkt->tx_bytes, pkt->reserved + ); + -+ LGTD_LIFX_GATEWAY_SET_BULB_ATTR_WITH_RECV_AT( -+ gw, -+ hdr->target.device_addr, -+ bulb_fn, -+ (const struct lgtd_lifx_ip_state *)pkt ++ LGTD_LIFX_GATEWAY_SET_BULB_ATTR( ++ gw, hdr->target.device_addr, lgtd_lifx_bulb_set_ip_state, ++ ip_id, (const struct lgtd_lifx_ip_state *)pkt, gw->last_pkt_at + ); +} + @@ -577,18 +538,20 @@ +{ + assert(gw && hdr && pkt); + ++ char built_at[64], installed_at[64]; ++ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(pkt->built_at, built_at); ++ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(pkt->installed_at, installed_at); ++ + const char *type; -+ void (*bulb_fn)(struct lgtd_lifx_bulb *, -+ const struct lgtd_lifx_ip_firmware_info *); -+ ++ enum lgtd_lifx_bulb_ips ip_id; + switch (hdr->packet_type) { + case LGTD_LIFX_MESH_FIRMWARE: + type = "MCU_FIRMWARE_INFO"; -+ bulb_fn = lgtd_lifx_bulb_set_mcu_firmware_info; ++ ip_id = LGTD_LIFX_BULB_MCU_IP; + break; + case LGTD_LIFX_WIFI_FIRMWARE_STATE: + type = "WIFI_FIRMWARE_INFO"; -+ bulb_fn = lgtd_lifx_bulb_set_wifi_firmware_info; ++ ip_id = LGTD_LIFX_BULB_WIFI_IP; + break; + default: + lgtd_info("invalid ip firmware packet_type %#hx", hdr->packet_type); @@ -598,10 +561,6 @@ + return; + } + -+ char built_at[64], installed_at[64]; -+ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(pkt->built_at, built_at); -+ LGTD_LIFX_WIRE_PRINT_NSEC_TIMESTAMP(pkt->installed_at, installed_at); -+ + lgtd_debug( + "%s <-- [%s]:%hu - %s " + "built_at=%s, installed_at=%s, version=%u", @@ -610,10 +569,8 @@ + ); + + LGTD_LIFX_GATEWAY_SET_BULB_ATTR( -+ gw, -+ hdr->target.device_addr, -+ bulb_fn, -+ (const struct lgtd_lifx_ip_firmware_info *)pkt ++ gw, hdr->target.device_addr, lgtd_lifx_bulb_set_ip_firmware_info, ++ ip_id, (const struct lgtd_lifx_ip_firmware_info *)pkt, gw->last_pkt_at + ); +} + @@ -632,9 +589,7 @@ + ); + + LGTD_LIFX_GATEWAY_SET_BULB_ATTR( -+ gw, -+ hdr->target.device_addr, -+ lgtd_lifx_bulb_set_product_info, ++ gw, hdr->target.device_addr, lgtd_lifx_bulb_set_product_info, + (const struct lgtd_lifx_product_info *)pkt + ); +} @@ -657,11 +612,9 @@ + device_time, uptime, downtime + ); + -+ LGTD_LIFX_GATEWAY_SET_BULB_ATTR_WITH_RECV_AT( -+ gw, -+ hdr->target.device_addr, -+ lgtd_lifx_bulb_set_runtime_info, -+ (const struct lgtd_lifx_runtime_info *)pkt ++ LGTD_LIFX_GATEWAY_SET_BULB_ATTR( ++ gw, hdr->target.device_addr, lgtd_lifx_bulb_set_runtime_info, ++ (const struct lgtd_lifx_runtime_info *)pkt, gw->last_pkt_at + ); +} diff --git a/lifx/gateway.h b/lifx/gateway.h @@ -688,26 +641,20 @@ struct lgtd_lifx_message pkt_ring[LGTD_LIFX_GATEWAY_PACKET_RING_SIZE]; #define LGTD_LIFX_GATEWAY_INC_MESSAGE_RING_INDEX(idx) do { \ (idx) += 1; \ -@@ -77,6 +84,18 @@ +@@ -77,6 +84,12 @@ extern struct lgtd_lifx_gateway_list lgtd_lifx_gateways; -+#define LGTD_LIFX_GATEWAY_SET_BULB_ATTR(gw, bulb_addr, bulb_fn, payload) do { \ -+ struct lgtd_lifx_bulb *b; \ -+ LGTD_LIFX_GATEWAY_GET_BULB_OR_RETURN(b, gw, bulb_addr); \ -+ (bulb_fn)(b, (payload)); \ -+} while (0) -+ -+#define LGTD_LIFX_GATEWAY_SET_BULB_ATTR_WITH_RECV_AT(gw, bulb_addr, bulb_fn, payload) do { \ -+ struct lgtd_lifx_bulb *b; \ -+ LGTD_LIFX_GATEWAY_GET_BULB_OR_RETURN(b, gw, bulb_addr); \ -+ (bulb_fn)(b, (payload), (gw)->last_pkt_at); \ ++#define LGTD_LIFX_GATEWAY_SET_BULB_ATTR(gw, bulb_addr, bulb_fn, ...) do { \ ++ struct lgtd_lifx_bulb *b; \ ++ LGTD_LIFX_GATEWAY_GET_BULB_OR_RETURN(b, gw, bulb_addr); \ ++ (bulb_fn)(b, __VA_ARGS__); \ +} while (0) + struct lgtd_lifx_gateway *lgtd_lifx_gateway_get(const struct sockaddr_storage *); struct lgtd_lifx_gateway *lgtd_lifx_gateway_open(const struct sockaddr_storage *, ev_socklen_t, -@@ -119,3 +138,15 @@ +@@ -119,3 +132,15 @@ void lgtd_lifx_gateway_handle_tags(struct lgtd_lifx_gateway *, const struct lgtd_lifx_packet_header *, const struct lgtd_lifx_packet_tags *);