#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#define DEBUG_LOG_MODULE_NAME "EVAL_APP"
#define DEBUG_LOG_MAX_LEVEL LVL_NOLOG
#define COARSE_TO_MS(delay) (1000u * (delay) >> 7)
#define PERIODIC_MSG_DATA_PATTERN_LEN (8u)
#define DEFAULT_PERIOD_S (10u)
#define DEFAULT_PERIOD_MS (DEFAULT_PERIOD_S*1000u)
#define CUSTOM_PERIOD_TYPE 0xC3
#define PERIODIC_WORK_EXECUTION_TIME_US (250u)
#define BUTTON_PRESSED_STATE (2u)
#define TASK_EXEC_TIME_US_SEND_BUTTON_PRESSED_MSG (250u)
typedef struct __attribute__((packed))
{
uint32_t interval;
} app_config_t;
#define PERIODIC_MSG_PERIOD_SET_MIN_VAL_MS (2000ul)
#define PERIODIC_MSG_PERIOD_SET_MAX_VAL_MS (1200000ul)
#define MAX_LED_PER_BOARD (4u)
#define DATA_EP (1u)
static uint16_t m_filter_id;
typedef enum
{
MSG_ID_PERIODIC_MSG = 0,
MSG_ID_BUTTON_EVENT_MSG = 1,
MSG_ID_ECHO_RESPONSE_MSG = 2,
MSG_ID_LED_GET_STATE_RESPONSE_MSG = 3,
MSG_ID_PERIODIC_MSG_PERIOD_SET_MSG = 128,
MSG_ID_LED_SET_STATE_MSG = 129,
MSG_ID_LED_GET_STATE_MSG = 130,
MSG_ID_ECHO_COMMAND_MSG = 131,
} message_id_e;
typedef enum
{
LED_STATE_OFF = 0,
LED_STATE_ON = 1
} led_state_e;
typedef struct __attribute__((packed))
{
uint32_t counter_value;
uint8_t data_pattern[PERIODIC_MSG_DATA_PATTERN_LEN];
} payload_periodic_t;
typedef struct __attribute__((packed))
{
uint32_t new_period_ms;
} payload_periodic_set_t;
typedef struct __attribute__((packed))
{
uint8_t button_id;
uint8_t button_state;
} payload_button_event_t;
typedef struct __attribute__((packed))
{
uint32_t travel_time_ms;
} payload_response_echo_t;
typedef struct __attribute__((packed))
{
uint8_t led_id;
uint8_t led_state;
} payload_led_state_set_t;
typedef struct __attribute__((packed))
{
uint8_t led_id;
} payload_led_state_get_t;
typedef struct __attribute__((packed))
{
uint8_t led_id;
uint8_t led_state;
} payload_response_led_state_get_t;
typedef struct __attribute__((packed))
{
uint8_t id;
union
{
payload_periodic_t periodic;
payload_periodic_set_t periodic_set_period;
payload_button_event_t button_event;
payload_response_echo_t resp_echo;
payload_led_state_set_t led_state_set;
payload_led_state_get_t led_state_get;
payload_response_led_state_get_t resp_led_state_get;
} payload;
} msg_t;
static const uint8_t m_periodic_data_pattern[PERIODIC_MSG_DATA_PATTERN_LEN] =
{0x0A,0x0B,0x0B,0x0A,0x0A,0x0C,0x0D,0x0C};
static volatile uint8_t m_button_pressed_id;
static uint32_t m_period_ms;
static led_state_e m_table_led_state[MAX_LED_PER_BOARD] = {0};
const shared_data_item_t * item,
static shared_data_item_t unicast_packets_filter =
{
.cb = unicast_broadcast_data_received_cb,
.filter = {
.src_endpoint = DATA_EP,
.dest_endpoint = DATA_EP,
.multicast_cb = NULL
}
};
static shared_data_item_t broadcast_packets_filter =
{
.cb = unicast_broadcast_data_received_cb,
.filter = {
.src_endpoint = DATA_EP,
.dest_endpoint = DATA_EP,
.multicast_cb = NULL
}
};
uint8_t * payload)
{
msg_t msg;
size_t msg_byte_size = sizeof(msg.id);
msg.id = (uint8_t)id;
switch (msg.id)
{
case MSG_ID_PERIODIC_MSG:
memcpy(&msg.payload.periodic,
(payload_periodic_t *)payload,
sizeof(payload_periodic_t));
msg_byte_size += sizeof(payload_periodic_t);
break;
case MSG_ID_BUTTON_EVENT_MSG:
memcpy(&msg.payload.button_event,
(payload_button_event_t *)payload,
sizeof(payload_button_event_t));
msg_byte_size += sizeof(payload_button_event_t);
break;
case MSG_ID_ECHO_RESPONSE_MSG:
memcpy(&msg.payload.resp_echo,
(payload_response_echo_t *)payload,
sizeof(payload_response_echo_t));
msg_byte_size += sizeof(payload_response_echo_t);
break;
case MSG_ID_LED_GET_STATE_RESPONSE_MSG:
memcpy(&msg.payload.resp_led_state_get,
(payload_response_led_state_get_t *)payload,
sizeof(payload_response_led_state_get_t));
msg_byte_size += sizeof(payload_response_led_state_get_t);
break;
default:
break;
}
data_to_send.
bytes = (
const uint8_t *) &msg;
}
static uint32_t task_send_periodic_msg(void)
{
static uint32_t counter_value = 0;
payload_periodic_t payload;
payload.counter_value = counter_value;
memcpy(payload.data_pattern,
m_periodic_data_pattern,
sizeof(m_periodic_data_pattern));
if (send_uplink_msg(MSG_ID_PERIODIC_MSG,
{
}
counter_value++;
return m_period_ms;
}
static uint32_t task_send_button_pressed_msg(void)
{
payload_button_event_t payload;
payload.button_id = m_button_pressed_id;
payload.button_state = (uint8_t)BUTTON_PRESSED_STATE;
if (send_uplink_msg(MSG_ID_BUTTON_EVENT_MSG,
{
}
}
static void button_pressed_handler(uint8_t button_id,
button_event_e event)
{
(void) event;
m_button_pressed_id = button_id;
TASK_EXEC_TIME_US_SEND_BUTTON_PRESSED_MSG);
}
static void send_echo_response_msg(uint32_t delay)
{
payload_response_echo_t payload =
{
.travel_time_ms = 0
};
if (delay <= UINT32_MAX/1000u)
{
payload.travel_time_ms = COARSE_TO_MS(delay);
}
if (send_uplink_msg(MSG_ID_ECHO_RESPONSE_MSG,
{
}
}
static void set_periodic_msg_period(uint32_t new_period_ms)
{
if ((new_period_ms >= PERIODIC_MSG_PERIOD_SET_MIN_VAL_MS) &&
(new_period_ms <= PERIODIC_MSG_PERIOD_SET_MAX_VAL_MS))
{
m_period_ms = new_period_ms;
PERIODIC_WORK_EXECUTION_TIME_US);
}
else
{
}
}
static void set_led_state(uint8_t led_id, uint8_t led_state)
{
if ((led_id < MAX_LED_PER_BOARD) && (led_id < leds_num) && (leds_num > 0))
{
if (led_state == LED_STATE_OFF)
{
m_table_led_state[led_id] = LED_STATE_OFF;
}
else if (led_state == LED_STATE_ON)
{
m_table_led_state[led_id] = LED_STATE_ON;
}
else
{
}
}
}
static void send_led_state(uint8_t led_id)
{
payload_response_led_state_get_t payload;
if ((led_id < MAX_LED_PER_BOARD) && (led_id < leds_num) && (leds_num > 0))
{
payload.led_id = led_id;
payload.led_state = (uint8_t)m_table_led_state[led_id];
if (send_uplink_msg(MSG_ID_LED_GET_STATE_RESPONSE_MSG,
{
}
}
}
const shared_data_item_t * item,
{
(void) item;
msg_t msg = *((msg_t *)data->
bytes);
if ((msg_size < sizeof(msg.id)))
{
}
msg_size -= sizeof(msg.id);
switch (msg.id)
{
case MSG_ID_ECHO_COMMAND_MSG:
if (msg_size == 0)
{
send_echo_response_msg(data->
delay);
}
break;
case MSG_ID_PERIODIC_MSG_PERIOD_SET_MSG:
if (msg_size == sizeof(payload_periodic_set_t))
{
set_periodic_msg_period(
msg.payload.periodic_set_period.new_period_ms);
}
break;
case MSG_ID_LED_SET_STATE_MSG:
if (msg_size == sizeof(payload_led_state_set_t))
{
set_led_state(msg.payload.led_state_set.led_id,
msg.payload.led_state_set.led_state);
}
break;
case MSG_ID_LED_GET_STATE_MSG:
if (msg_size == sizeof(payload_led_state_get_t))
{
send_led_state(msg.payload.led_state_get.led_id);
}
break;
default:
break;
}
}
static void appConfigPeriodReceivedCb(uint16_t type,
uint8_t length,
uint8_t * value_p)
{
app_config_t * config;
if (type != CUSTOM_PERIOD_TYPE)
{
return;
}
if (length != sizeof(app_config_t))
{
return;
}
config = (app_config_t *) value_p;
"New app configuration interval_s=%d",
config->interval);
set_periodic_msg_period(config->interval*1000);
}
{
(void) functions;
app_config_period_filter.
type = CUSTOM_PERIOD_TYPE;
app_config_period_filter.
cb = appConfigPeriodReceivedCb;
LOG(
LVL_INFO,
"Filter added for static period with id=%d\n", m_filter_id);
uint8_t num_buttons;
{
return;
}
#ifdef ENABLE_LOW_LATENCY_MODE
#endif
for (uint8_t button_id = 0; button_id < num_buttons; button_id++)
{
button_pressed_handler);
}
m_period_ms = DEFAULT_PERIOD_MS;
PERIODIC_WORK_EXECUTION_TIME_US);
lib_state->startStack();
}