Wirepas SDK
control_node/app.c
/* Copyright 2020 Wirepas Ltd. All Rights Reserved.
*
* See file LICENSE.txt for full license details.
*
*/
/*
* \file app.c
* \brief This file is the control node example application using Directed
* Advertiser.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "api.h"
#include "button.h"
#include "shared_data.h"
#include "control_node.h"
#include "common.h"
#define DEBUG_LOG_MODULE_NAME "NODE APP"
#ifdef DEBUG_LOG_MAX_LEVEL_APP
#define DEBUG_LOG_MAX_LEVEL DEBUG_LOG_MAX_LEVEL_APP
#else
#define DEBUG_LOG_MAX_LEVEL LVL_INFO
#endif
#include "debug_log.h"
typedef struct
{
uint32_t diag_period_ms;
uint32_t packet_ttl_ms;
} control_app_conf_t;
static const control_app_conf_t DEFAULT_CONF =
{
.diag_period_ms = CONF_DIAG_PERIOD_MS,
.packet_ttl_ms = CONF_PKT_TTL_MS,
};
static control_app_conf_t m_conf;
static void data_sent_cb(const app_lib_data_sent_status_t * status)
{
(void) status;
LOG(LVL_DEBUG, "APP - Packet sent (success: %d)", status->success);
}
static void switch_event(uint8_t button_id, button_event_e event)
{
(void) button_id;
(void) event;
control_app_switch_t pkt = {
.type = CTRL_APP_SWITCH_EVENT,
};
static bool light_state = false;
/* This simulate the turn On / turn Off the light event. */
light_state = !light_state;
pkt.button_pressed = light_state;
app_lib_data_to_send_t tx_switch_def =
{
.bytes = (const uint8_t *)&pkt,
.num_bytes = sizeof(control_app_switch_t),
.src_endpoint = SRC_EP_SWITCH,
.dest_endpoint = DEST_EP_SWITCH,
};
LOG(LVL_INFO, "Send switch event (%s)", light_state?"On":"Off");
res = Control_Node_send(&tx_switch_def, data_sent_cb);
if (res != CONTROL_RET_OK)
{
LOG(LVL_ERROR, "Error sending Switch Event (res:%d)", res);
}
}
static void control_node_ack_cb(uint8_t * bytes, uint8_t len)
{
control_app_ack_t * pkt = (control_app_ack_t *) bytes;
control_app_conf_t conf;
control_node_conf_t lib_conf = {
.ack_cb = control_node_ack_cb,
};
LOG(LVL_INFO, "Received ACK");
if (len != sizeof(control_app_ack_t))
{
LOG(LVL_ERROR, " - Invalid ACK length");
/* Invalid packet size. */
return;
}
conf.diag_period_ms = pkt->diag_period_ms;
conf.packet_ttl_ms = pkt->packet_ttl_ms;
if (memcmp(&conf, &m_conf, sizeof(control_app_conf_t)))
{
LOG(LVL_INFO, "Update config.");
LOG(LVL_DEBUG, " - diag_period_ms: %u", conf.diag_period_ms);
LOG(LVL_DEBUG, " - packet_ttl_ms: %u", conf.packet_ttl_ms);
/* Config changed; re-init app and library.*/
memcpy(&m_conf, &conf, sizeof(control_app_conf_t));
lib_conf.diag_period_ms = m_conf.diag_period_ms;
lib_conf.packet_ttl_ms = m_conf.packet_ttl_ms;
ctrl_ret = Control_Node_init(&lib_conf);
if (ctrl_ret != CONTROL_RET_OK)
{
LOG(LVL_ERROR, "Error re-initializing control library (ret:%d)",
ctrl_ret);
return;
}
}
else
{
LOG(LVL_DEBUG, "Keep same config.");
}
}
void App_init(const app_global_functions_t * functions)
{
(void) functions;
app_res_e app_res;
button_res_e button_res;
.ack_cb = control_node_ack_cb,
};
/* Copy defaults to App config struct. */
memcpy(&m_conf, &DEFAULT_CONF, sizeof(control_app_conf_t));
/* Initialize DA library with defaults. */
conf.diag_period_ms = m_conf.diag_period_ms;
conf.packet_ttl_ms = m_conf.packet_ttl_ms;
LOG(LVL_INFO, "Starting Control Node");
LOG(LVL_DEBUG, " - diag_period_ms: %u", m_conf.diag_period_ms);
LOG(LVL_DEBUG, " - packet_ttl_ms: %u", m_conf.packet_ttl_ms);
// Basic configuration of the node with a unique node address
{
// Could not configure the node
// It should not happen except if one of the config value is invalid
return;
}
app_res = lib_settings->setNodeRole(APP_LIB_SETTINGS_ROLE_ADVERTISER);
if (app_res != APP_RES_OK)
{
LOG(LVL_ERROR, "Error setting node role (res:%d)", app_res);
return;
}
ctrl_ret = Control_Node_init(&conf);
if (ctrl_ret != CONTROL_RET_OK)
{
LOG(LVL_ERROR, "Error initializing control library (ret:%d)",
ctrl_ret);
return;
}
/* Button pressed callback. */
button_res = Button_register_for_event(0, BUTTON_PRESSED, switch_event);
if (button_res != BUTTON_RES_OK)
{
// It is likely the board doesn't have any button. The switch event
// functionnality will not work.
LOG(LVL_WARNING, "Error registering button event (res:%d)", button_res);
}
/* Start the stack. */
lib_state->startStack();
}
app_lib_data_sent_status_t
Struct to tracking callback function.
Definition: wms_data.h:360
LVL_INFO
#define LVL_INFO
Definition: debug_log.h:83
APP_LIB_SETTINGS_ROLE_ADVERTISER
@ APP_LIB_SETTINGS_ROLE_ADVERTISER
Definition: wms_settings.h:85
LVL_ERROR
#define LVL_ERROR
Definition: debug_log.h:85
app_res_e
app_res_e
Definition: wms_app.h:201
button.h
Board-independent button functions.
APP_LIB_DATA_SEND_FLAG_NONE
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition: wms_data.h:96
BUTTON_RES_OK
@ BUTTON_RES_OK
Definition: button.h:32
node_configuration.h
app_lib_data_sent_status_t::success
bool success
Definition: wms_data.h:377
button_res_e
button_res_e
List of return code.
Definition: button.h:29
APP_LIB_DATA_NO_TRACKING_ID
#define APP_LIB_DATA_NO_TRACKING_ID
When sending data and no tracking of packet is requested, this ID may be used.
Definition: wms_data.h:60
APP_RES_OK
@ APP_RES_OK
Definition: wms_app.h:204
control_node_conf_t
Configuration structure for Control node.
Definition: control_node.h:26
Control_Node_init
control_node_ret_e Control_Node_init(control_node_conf_t *conf)
Initialize Directed Advertiser libray for control node.
app_lib_data_to_send_t
A struct for lib_data->sendData().
Definition: wms_data.h:323
app_global_functions_t
List of global functions, passed to App_entrypoint()
Definition: wms_app.h:157
debug_log.h
control_node_conf_t::packet_ttl_ms
uint32_t packet_ttl_ms
Definition: control_node.h:36
Button_register_for_event
button_res_e Button_register_for_event(uint8_t button_id, button_event_e event, on_button_event_cb cb)
Register for a button event.
CONTROL_RET_OK
@ CONTROL_RET_OK
Definition: control_node_int.h:24
control_node.h
configureNodeFromBuildParameters
__STATIC_INLINE app_res_e configureNodeFromBuildParameters()
Wrapper on top of configureNode to get parameters from build system and hardcoded values from chip (f...
Definition: node_configuration.h:224
LVL_DEBUG
#define LVL_DEBUG
Macros to define several log levels: Debug, Info, Warning, Error.
Definition: debug_log.h:82
control_node_conf_t::ack_cb
control_node_ack_cb_f ack_cb
Definition: control_node.h:38
Control_Node_send
control_node_ret_e Control_Node_send(app_lib_data_to_send_t *data, app_lib_data_data_sent_cb_f sent_cb)
Send a data packet.
LOG_INIT
#define LOG_INIT()
Definition: debug_log.h:66
shared_data.h
control_node_conf_t::diag_period_ms
uint32_t diag_period_ms
Definition: control_node.h:32
LVL_WARNING
#define LVL_WARNING
Definition: debug_log.h:84
LOG
#define LOG(level, fmt,...)
Print a log message if its severity is lower or equal to DEBUG_LOG_MAX_LEVEL.
Definition: debug_log.h:173
app_lib_data_to_send_t::bytes
const uint8_t * bytes
Definition: wms_data.h:326
BUTTON_PRESSED
@ BUTTON_PRESSED
Definition: button.h:22
APP_LIB_DATA_QOS_NORMAL
@ APP_LIB_DATA_QOS_NORMAL
Definition: wms_data.h:84
control_node_ret_e
control_node_ret_e
Return codes of control functions.
Definition: control_node_int.h:21
api.h
button_event_e
button_event_e
Different events for a button.
Definition: button.h:21