Wirepas SDK
diradv/app.c
/* Copyright 2020 Wirepas Ltd. All Rights Reserved.
*
* See file LICENSE.txt for full license details.
*
*/
/*
* \file app.c
* \brief This file is a directed advertiser example application.
*
* When application is programmed on device, it has two operating modes which
* are selected by 'button 0' when booting up the device:
* - Button 0 pressed: directed advertiser
* - Button 0 not pressed: CSMA-CA headnode
*
* Directed advertiser sends once per minute unicast packet to CSMA-CA headnodes
* that have route to a sink. If it does not find such CSMA-CA headnodes, it
* will try again after one minute.
*
* CSMA-CA headnode receives the packet sent by directed advertiser and creates
* another data packet that will be sent to backend (@ref APP_ADDR_ANYSINK).
*/
#include <stdlib.h>
#include <stdio.h>
#include "api.h"
#include "led.h"
#include "button.h"
#include "shared_data.h"
#include "app_scheduler.h"
#include "stack_state.h"
// How often diradv scans and sends data (in useconds)
#define SCAN_PERIOD_MS (60*1000)
// Transmission from advertiser
const uint8_t m_adv_tx_data[] = "Hello from advertiser!";
// Source endpoint to send advertiser data
#define DIRADV_EP_SRC_DATA 248
static app_lib_data_to_send_t m_tx_def_adv =
{
.bytes = &m_adv_tx_data[0],
.num_bytes = sizeof(m_adv_tx_data),
.src_endpoint = DIRADV_EP_SRC_DATA,
.dest_endpoint = DIRADV_EP_DEST,
};
// Endpoints that headnode generates
#define HN_SRC_EP 5
#define HN_DST_EP 5
static app_addr_t m_adv_address;
static app_lib_data_to_send_t m_tx_def_hn =
{
.bytes = (const uint8_t *) &m_adv_address,
.num_bytes = sizeof(m_adv_address),
.src_endpoint = HN_SRC_EP,
.dest_endpoint = HN_DST_EP,
.dest_address = APP_ADDR_ANYSINK,
};
const uint8_t m_ack_content[] = "ACK";
static uint8_t m_tracking_id;
static bool m_is_scanning;
static void data_sent_cb(const app_lib_data_sent_status_t * status)
{
(void) status;
// Disable LED
Led_set(0, false);
}
static void beacon_listen_cb(const app_lib_state_beacon_rx_t * beacon)
{
// Skips time-slotted mode devices and devices without route
if (beacon->is_ll &&
(beacon->cost != 255) &&
m_is_scanning)
{
// Simply send data to the first device found
m_tx_def_adv.dest_address = beacon->address;
m_tx_def_adv.tracking_id = m_tracking_id++;
// Send data with callback when data has been sent. Turns off the led.
res = Shared_Data_sendData(&m_tx_def_adv, data_sent_cb);
{
// Only send one device.
m_is_scanning = false;
lib_state->stopScanNbors();
}
}
}
static uint32_t start_scan(void)
{
// Start scanning for stack default time
// Scan will be aborted if we find a neighbor
m_is_scanning = true;
lib_state->startScanNbors();
// Enable led
Led_set(0, true);
// And try again later
return SCAN_PERIOD_MS;
}
static void scan_ended(app_lib_stack_event_e event, void * param_p)
{
(void) event;
scan_info = (app_lib_state_neighbor_scan_info_t *) param_p;
if (scan_info->complete == true &&
{
// Disable LED
Led_set(0, false);
m_is_scanning = false;
}
}
static bool acklistener_cb(const ack_gen_input_t * in,
{
m_adv_address = in->sender;
// Send packet to sink
Shared_Data_sendData(&m_tx_def_hn, NULL);
out->data = (void *) &m_ack_content;
out->length = sizeof(m_ack_content);
return true;
}
void App_init(const app_global_functions_t * functions)
{
(void) functions;
// 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;
}
// Initialize buttons
// Query value of button 1
bool pressed = false;
Button_getState(0, &pressed);
// Initialize leds
// Override node role
if (pressed)
{
// Advertiser
lib_settings->setNodeRole(APP_LIB_SETTINGS_ROLE_ADVERTISER);
// Set scan callback to find CSMA-CA headnode (with route)
lib_state->setOnBeaconCb(beacon_listen_cb);
// Set periodic callback when do scan+transmission
SCAN_PERIOD_MS,
1000);
// Set scan end callback. Turns off the led if nothing was found
}
else
{
lib_settings->setNodeRole(APP_LIB_SETTINGS_ROLE_HEADNODE_LL);
// Set callback to receive packet from advertiser and generate response
// to sink
lib_advertiser->setRouterAckGenCb(acklistener_cb);
}
/*
* Start the stack.
* This is really important step, otherwise the stack will stay stopped and
* will not be part of any network. So the device will not be reachable
* without reflashing it
*/
lib_state->startStack();
}
APP_LIB_DATA_SEND_FLAG_TRACK
@ APP_LIB_DATA_SEND_FLAG_TRACK
Definition: wms_data.h:100
app_lib_data_sent_status_t
Struct to tracking callback function.
Definition: wms_data.h:360
Led_set
led_res_e Led_set(uint8_t led_id, bool state)
Turn the given LED on or off.
app_lib_state_neighbor_scan_info_t::scan_type
app_lib_state_scan_type_e scan_type
Definition: wms_state.h:323
app_lib_data_send_res_e
app_lib_data_send_res_e
A result code returned from lib_data->sendData().
Definition: wms_data.h:136
Button_getState
button_res_e Button_getState(uint8_t button_id, bool *state_p)
Get State of a given button.
APP_LIB_SETTINGS_ROLE_ADVERTISER
@ APP_LIB_SETTINGS_ROLE_ADVERTISER
Definition: wms_settings.h:85
app_lib_data_to_send_t::tracking_id
app_lib_data_tracking_id_t tracking_id
Definition: wms_data.h:334
app_lib_state_beacon_rx_t
Structure to hold the information about received beacons.
Definition: wms_state.h:198
button.h
Board-independent button functions.
APP_LIB_DATA_SEND_FLAG_NONE
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition: wms_data.h:96
stack_state.h
app_lib_data_to_send_t::dest_address
app_addr_t dest_address
Definition: wms_data.h:330
node_configuration.h
ack_gen_output_t::data
void * data
Definition: wms_advertiser.h:99
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.
app_lib_stack_event_e
app_lib_stack_event_e
List of event generated by the stack when registering to app_lib_state_set_stack_event_cb_f.
Definition: wms_state.h:413
ack_gen_output_t
Output structure for for callback function set by lib_advertiser->setRouterAckGenCb().
Definition: wms_advertiser.h:95
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_state_beacon_rx_t::is_ll
bool is_ll
Device is LL.
Definition: wms_state.h:220
DIRADV_EP_DEST
#define DIRADV_EP_DEST
Headnode acknowledges the packet by using this destination endpoint.
Definition: wms_advertiser.h:49
app_scheduler.h
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
SCAN_TYPE_APP_ORIGINATED
@ SCAN_TYPE_APP_ORIGINATED
Definition: wms_state.h:303
led.h
Board-independent LED functions.
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
app_lib_state_beacon_rx_t::address
app_addr_t address
Address of the beacon sender.
Definition: wms_state.h:200
app_addr_t
uint32_t app_addr_t
Definition: wms_app.h:228
APP_ADDR_ANYSINK
@ APP_ADDR_ANYSINK
Definition: wms_app.h:236
ack_gen_output_t::length
uint8_t length
Definition: wms_advertiser.h:102
Led_init
void Led_init(void)
Initialize Led module.
app_lib_state_neighbor_scan_info_t
Information on neighbor scan.
Definition: wms_state.h:320
shared_data.h
APP_LIB_DATA_SEND_RES_SUCCESS
@ APP_LIB_DATA_SEND_RES_SUCCESS
Definition: wms_data.h:139
ack_gen_input_t
Input data structure for callback function set by lib_advertiser->setRouterAckGenCb().
Definition: wms_advertiser.h:69
Button_init
void Button_init(void)
Initialize Button module.
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_state_beacon_rx_t::cost
uint8_t cost
Cost of the device. 255==no route.
Definition: wms_state.h:221
app_lib_state_neighbor_scan_info_t::complete
bool complete
Definition: wms_state.h:325
app_lib_data_to_send_t::bytes
const uint8_t * bytes
Definition: wms_data.h:326
Stack_State_addEventCb
app_res_e Stack_State_addEventCb(stack_state_event_cb_f callback, uint32_t event_bitfield)
Add a new callback about event callback.
APP_LIB_DATA_QOS_NORMAL
@ APP_LIB_DATA_QOS_NORMAL
Definition: wms_data.h:84
APP_LIB_SETTINGS_ROLE_HEADNODE_LL
@ APP_LIB_SETTINGS_ROLE_HEADNODE_LL
Definition: wms_settings.h:75
ack_gen_input_t::sender
app_addr_t sender
Definition: wms_advertiser.h:72
APP_LIB_STATE_STACK_EVENT_SCAN_STOPPED
@ APP_LIB_STATE_STACK_EVENT_SCAN_STOPPED
Definition: wms_state.h:422
api.h