Wirepas SDK
appconfig/app.c
/* Copyright 2019 Wirepas Ltd. All Rights Reserved.
*
* See file LICENSE.txt for full license details.
*
*/
/*
* \file app.c
* \brief This is an example of receiving application configuration from
* the network and change application behavior accordingly.
*
* Configuration messages are sent by the sink(s) and spread to the
* whole network. Also every new node joining the network receives
* the configuration data from its neighbors without the need for
* end-to-end polling.
*/
#include <stdlib.h>
#include <string.h>
#include "api.h"
#include "shared_data.h"
#include "app_scheduler.h"
#define DEBUG_LOG_MODULE_NAME "MAIN_APP"
#define DEBUG_LOG_MAX_LEVEL LVL_INFO
#include "debug_log.h"
#define DEFAULT_PERIOD_S 10
#define DEFAULT_PERIOD_MS (DEFAULT_PERIOD_S*1000)
#define EXECUTION_TIME_US 500
#define DATA_EP 1
static uint32_t m_period_ms;
#define CUSTOM_TLV_TYPE 0x12
static uint16_t m_filter_id;
static uint16_t m_raw_filter_id;
static uint16_t m_all_filter_id;
typedef struct __attribute__((packed))
{
uint8_t seq; // sequence number (app specific)
uint16_t interval; // period in second for app to send data
} custom_app_config_t;
static uint32_t send_data(void)
{
// This function will be called every period_us microseconds by the stack.
// You can do anything you want for EXECUTION_TIME_US. In this example, a
// monotonically increasing 32-bit value is sent to the sink.
static uint32_t id = 0; // Value to send
// Create a data packet to send
app_lib_data_to_send_t data_to_send;
data_to_send.bytes = (const uint8_t *) &id;
data_to_send.num_bytes = sizeof(id);
data_to_send.src_endpoint = DATA_EP;
data_to_send.dest_endpoint = DATA_EP;
data_to_send.qos = APP_LIB_DATA_QOS_HIGH;
// Send the data packet
Shared_Data_sendData(&data_to_send, NULL);
// Increment value to send
id++;
// Inform the stack that this function should be called again in
// period_us microseconds. By returning APP_LIB_SYSTEM_STOP_PERIODIC,
// the stack won't call this function again.
return m_period_ms;
}
static void appConfigTLVReceivedCb(uint16_t type,
uint8_t length,
uint8_t * value_p)
{
custom_app_config_t * config;
if (type != CUSTOM_TLV_TYPE)
{
// It should never happen as we registered only this type with this cb
LOG(LVL_ERROR, "Wrong app config type");
return;
}
if (length == 0)
{
LOG(LVL_INFO, "App config received but not for us");
return;
}
if (length != sizeof(custom_app_config_t))
{
// Wrong size
LOG(LVL_ERROR, "Wrong app config size");
return;
}
config = (custom_app_config_t *) value_p;
"New app configuration seq=%d, interval_s=%d",
config->seq,
config->interval);
// Set new periodic data transfer interval
m_period_ms = config->interval * 1000;
}
static void appConfigRawReceivedCb(uint16_t type,
uint8_t length,
uint8_t * value_p)
{
{
// It should never happen as we register for raw type only with this cb
LOG(LVL_ERROR, "Wrong app config raw type");
return;
}
LOG(LVL_INFO, "New RAW app configuration len=%d\n", length);
}
static void appConfigTLVAllReceivedCb(uint16_t type,
uint8_t length,
uint8_t * value_p)
{
LOG(LVL_INFO, "New app configuration all filters type=%d len=%d\n", type, length);
}
void App_init(const app_global_functions_t * functions)
{
shared_app_config_filter_t app_config_filter;
// 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;
}
LOG(LVL_DEBUG, "App starting");
// Prepare the app_config filter
app_config_filter.type = CUSTOM_TLV_TYPE;
app_config_filter.cb = appConfigTLVReceivedCb;
app_config_filter.call_cb_always = true;
Shared_Appconfig_addFilter(&app_config_filter, &m_filter_id);
LOG(LVL_INFO, "Filter added for TLV with id=%d\n", m_filter_id);
// Prepare a second app_config filter
app_config_filter.cb = appConfigRawReceivedCb;
app_config_filter.call_cb_always = false;
Shared_Appconfig_addFilter(&app_config_filter, &m_raw_filter_id);
LOG(LVL_INFO, "Filter added for TLV with id=%d\n", m_raw_filter_id);
// Prepare a third app_config filter
app_config_filter.cb = appConfigTLVAllReceivedCb;
app_config_filter.call_cb_always = false;
Shared_Appconfig_addFilter(&app_config_filter, &m_all_filter_id);
LOG(LVL_INFO, "Filter added for TLV with id=%d\n", m_all_filter_id);
// Set a periodic callback to be called after DEFAULT_PERIOD_MS
m_period_ms = DEFAULT_PERIOD_MS;
m_period_ms,
EXECUTION_TIME_US);
// Start the stack
lib_state->startStack();
}
LVL_INFO
#define LVL_INFO
Definition: debug_log.h:83
LVL_ERROR
#define LVL_ERROR
Definition: debug_log.h:85
app_lib_data_to_send_t::tracking_id
app_lib_data_tracking_id_t tracking_id
Definition: wms_data.h:344
app_lib_data_to_send_t::src_endpoint
uint8_t src_endpoint
Definition: wms_data.h:350
APP_LIB_DATA_SEND_FLAG_NONE
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition: wms_data.h:100
app_lib_data_to_send_t::dest_address
app_addr_t dest_address
Definition: wms_data.h:340
app_lib_data_to_send_t::num_bytes
size_t num_bytes
Definition: wms_data.h:338
node_configuration.h
App_Scheduler_addTask_execTime
app_scheduler_res_e App_Scheduler_addTask_execTime(task_cb_f cb, uint32_t delay_ms, uint32_t exec_time_us)
Add a task.
shared_app_config_filter_t::cb
shared_app_config_received_cb_f cb
Definition: shared_appconfig.h:73
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
app_lib_data_to_send_t::dest_endpoint
uint8_t dest_endpoint
Definition: wms_data.h:352
SHARED_APP_CONFIG_INCOMPATIBLE_FILTER
#define SHARED_APP_CONFIG_INCOMPATIBLE_FILTER
Value to use to receive incompatible raw app_config Ie, if the app config is not recognized by this l...
Definition: shared_appconfig.h:43
app_scheduler.h
app_lib_data_to_send_t
A struct for lib_data->sendData().
Definition: wms_data.h:333
app_global_functions_t
List of global functions, passed to App_entrypoint()
Definition: wms_app.h:157
Shared_Appconfig_addFilter
shared_app_config_res_e Shared_Appconfig_addFilter(shared_app_config_filter_t *filter, uint16_t *filter_id)
Add a new app config type filter to the list. If the item is already in the list it is only updated.
debug_log.h
APP_LIB_DATA_QOS_HIGH
@ APP_LIB_DATA_QOS_HIGH
Definition: wms_data.h:91
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:223
shared_appconfig.h
LVL_DEBUG
#define LVL_DEBUG
Macros to define several log levels: Debug, Info, Warning, Error.
Definition: debug_log.h:82
app_lib_data_to_send_t::flags
uint8_t flags
Definition: wms_data.h:348
APP_ADDR_ANYSINK
@ APP_ADDR_ANYSINK
Definition: wms_app.h:236
app_lib_data_to_send_t::qos
app_lib_data_qos_e qos
Definition: wms_data.h:346
LOG_INIT
#define LOG_INIT()
Definition: debug_log.h:66
shared_data.h
shared_app_config_filter_t
Structure holding all parameters for app config type filtering.
Definition: shared_appconfig.h:64
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
Shared_Data_sendData
app_lib_data_send_res_e Shared_Data_sendData(app_lib_data_to_send_t *data, app_lib_data_data_sent_cb_f sent_cb)
Send data. The packet to send is represented as a app_lib_data_to_send_t struct.
app_lib_data_to_send_t::bytes
const uint8_t * bytes
Definition: wms_data.h:336
SHARED_APP_CONFIG_ALL_TYPE_FILTER
#define SHARED_APP_CONFIG_ALL_TYPE_FILTER
Value to use to receive all types.
Definition: shared_appconfig.h:36
shared_app_config_filter_t::call_cb_always
bool call_cb_always
Definition: shared_appconfig.h:78
shared_app_config_filter_t::type
uint16_t type
Definition: shared_appconfig.h:68
api.h