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)
{
(void) 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)
{
(void) 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)
{
(void) 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();
}
app_scheduler_res_e App_Scheduler_addTask_execTime(task_cb_f cb, uint32_t delay_ms, uint32_t exec_time_us)
Add a task.
#define LOG_INIT()
Definition debug_log.h:66
#define LVL_DEBUG
Macros to define several log levels: Debug, Info, Warning, Error.
Definition debug_log.h:82
#define LVL_INFO
Definition debug_log.h:83
#define LVL_ERROR
Definition debug_log.h:85
#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
__STATIC_INLINE app_res_e configureNodeFromBuildParameters()
Wrapper on top of configureNode to get parameters from build system and hardcoded values from chip (f...
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.
#define SHARED_APP_CONFIG_ALL_TYPE_FILTER
Value to use to receive all types.
#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...
shared_app_config_received_cb_f cb
Structure holding all parameters for app config type filtering.
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_ADDR_ANYSINK
Definition wms_app.h:236
@ APP_RES_OK
Definition wms_app.h:204
List of global functions, passed to App_entrypoint()
Definition wms_app.h:158
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition wms_data.h:100
#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_lib_data_tracking_id_t tracking_id
Definition wms_data.h:340
app_lib_data_qos_e qos
Definition wms_data.h:342
@ APP_LIB_DATA_QOS_HIGH
Definition wms_data.h:91
app_addr_t dest_address
Definition wms_data.h:336
const uint8_t * bytes
Definition wms_data.h:332
A struct for lib_data->sendData().
Definition wms_data.h:330