From 75eccd0447626df7be5c0372033655884b56d81a Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Thu, 1 Nov 2018 20:57:24 +0100 Subject: [PATCH] Move to a struct with args in channel_set_cb() --- src/channel.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/channel.c b/src/channel.c index 0714fad..542fc22 100644 --- a/src/channel.c +++ b/src/channel.c @@ -144,26 +144,37 @@ uint8_t channel_idx_by_gpio(int gpio) { return GPIO_INVALID; } -// Slightly tricky callback (installed on a timer by channel_set and -// channel_toggle carries information in the arg pointer -- top 16 bits are -// the channel idx, LSB is boolean value to set the channel to. +struct channel_set_cb_args { + uint8_t idx; + bool value; +}; + static void channel_set_cb(void *arg) { - uint32_t input=(uint32_t) arg; - int idx = input>>16; - int value = input & 0x1; - LOG(LL_INFO, ("Channel callback for channel %d value %d", idx, value)); - channel_set(idx, (bool)value); + struct channel_set_cb_args *cb_args = (struct channel_set_cb_args *)arg; + if (!arg) { + LOG(LL_ERROR, ("Callback arg is NULL")); + return; + } + LOG(LL_INFO, ("Channel callback for channel %d value %d", cb_args->idx, cb_args->value)); + channel_set(cb_args->idx, cb_args->value); + free(arg); } void channel_set_duration(int idx, bool state, uint16_t seconds) { - uint32_t val; + struct channel_set_cb_args *cb_args = calloc(1, sizeof(struct channel_set_cb_args)); + + if (!cb_args) { + LOG(LL_ERROR, ("Could not calloc() the callback args struct, aborting")); + return; + } + channel_set(idx, state); - // Pass an argument to the channel_set_cb callback, top 16 bits is channel, - // bottom bit is what to set it to - val = idx<<16+(!state); - LOG(LL_INFO, ("Setting timer for %d seconds on channel %d with future value %d", seconds, idx, !state)); - mgos_set_timer (1000 * seconds, false /* oneshot */, channel_set_cb, (void *)val); + // Set a timer to call back with the new intended state on the channel. + cb_args->value = !state; + cb_args->idx = idx; + LOG(LL_INFO, ("Setting timer for %d seconds on channel %d with future value %d", seconds, cb_args->idx, cb_args->value)); + mgos_set_timer (1000 * seconds, false /* oneshot */, channel_set_cb, cb_args); } void channel_set(int idx, bool state) {