Wirepas SDK
ble_tx/app.c
/* Copyright 2017 Wirepas Ltd. All Rights Reserved.
*
* See file LICENSE.txt for full license details.
*
*/
/*
* \file app.c
* \brief Bluetooth BLE beacon test application
*
* \note Send "url www.whatever.com" to a device, to start
* transmitting Eddystone URL beacons every 0.333 seconds at
* full power and on every Bluetooth LE advertising channel
*/
#include "api.h"
#include <stdlib.h> // For NULL
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include "shared_data.h"
#define DATA_EP 5
static const uint8_t beacon_hdr[] =
{
0x42, /* Non-connectable beacon */
0x10, 0x32, 0x54, 0x76, 0x00, 0xc0, /* Random addr (top two bits set) */
0x02, 0x01, 0x04, /* Bluetooth LE beacon only */
0x03, 0x03, 0xaa, 0xfe, /* Eddystone URL beacon */
0x06, 0x16, 0xaa, 0xfe, 0x10, 0xf7, /* URL length, URL */
0x00 /* http:// */
};
static size_t makeBeacon(uint8_t * buffer,
const uint8_t * url,
size_t url_num_bytes)
{
// Check URL length
if ((sizeof(beacon_hdr) + url_num_bytes) >= APP_LIB_BEACON_TX_MAX_NUM_BYTES)
{
// URL too long
return 0;
}
// Copy header to beacon
memcpy(buffer, beacon_hdr, sizeof(beacon_hdr));
app_addr_t addr;
app_res_e res = lib_settings->getNodeAddress(&addr);
if (res != APP_RES_OK)
{
// Could not get node address
return 0;
}
// Modify random Bluetooth LE beacon address with node address
buffer[1] = (uint8_t)((addr >> 0) & 0xff);
buffer[2] = (uint8_t)((addr >> 8) & 0xff);
buffer[3] = (uint8_t)((addr >> 16) & 0xff);
buffer[4] = (uint8_t)((addr >> 24) & 0xff);
// Fix URL length
buffer[14] += url_num_bytes;
// Copy URL to beacon
// TODO: Support other than http:// URL scheme
// TODO: Support URL replacements (.com/, etc.)
memcpy(buffer + sizeof(beacon_hdr), url, url_num_bytes);
return sizeof(beacon_hdr) + (size_t)url_num_bytes;
}
/* Generic callback function */
static app_lib_data_receive_res_e dataReceivedFunc(
const shared_data_item_t * item,
{
app_lib_data_to_send_t data_to_send;
// Construct an Eddystone URL beacon
size_t beacon_num_bytes;
// Any endpoint will do, but the message must start with "url "
if ((data->num_bytes <= 4) ||
(strncmp((const char *)(data->bytes), (const char *)"url ", 4) != 0))
{
// Data was not for this application
}
else if ((beacon_num_bytes = makeBeacon(beacon,
&((data->bytes)[4]),
(data->num_bytes - 4))) == 0)
{
// Data was invalid in some way
data_to_send.bytes = (const uint8_t *)"ERR";
data_to_send.num_bytes = 3;
data_to_send.src_endpoint = 0;
data_to_send.dest_endpoint = 0;
data_to_send.qos = APP_LIB_DATA_QOS_NORMAL;
data_to_send.delay = 0;
lib_data->sendData(&data_to_send);
}
// Set default parameters for beacons: one beacon at full
// power on all advertising channels, three times a second
lib_beacon_tx->clearBeacons();
lib_beacon_tx->setBeaconInterval(333); // 333 ms
int8_t power = 8; // 8 dBm
lib_beacon_tx->setBeaconPower(0, &power);
lib_beacon_tx->setBeaconChannels(
0, APP_LIB_BEACON_TX_CHANNELS_ALL); // All channels
lib_beacon_tx->setBeaconContents(0, beacon, beacon_num_bytes);
lib_beacon_tx->enableBeacons(true);
// Send response
data_to_send.bytes = (const uint8_t *)"OK";
data_to_send.num_bytes = 2;
data_to_send.src_endpoint = 0;
data_to_send.dest_endpoint = 0;
data_to_send.qos = APP_LIB_DATA_QOS_NORMAL;
data_to_send.delay = 0;
Shared_Data_sendData(&data_to_send, NULL);
}
static shared_data_item_t all_packets_filter =
{
.cb = dataReceivedFunc,
.filter = {
/* Filtering by source endpoint. */
.src_endpoint = DATA_EP,
/* Filtering by destination endpoint. */
.dest_endpoint = DATA_EP,
.multicast_cb = NULL
}
};
void App_init(const app_global_functions_t * 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;
}
Shared_Data_addDataReceivedCb(&all_packets_filter);
lib_state->startStack();
}
app_lib_data_to_send_t::tracking_id
app_lib_data_tracking_id_t tracking_id
Definition: wms_data.h:346
app_res_e
app_res_e
Definition: wms_app.h:201
app_lib_data_to_send_t::src_endpoint
uint8_t src_endpoint
Definition: wms_data.h:352
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:338
Shared_Data_addDataReceivedCb
app_res_e Shared_Data_addDataReceivedCb(shared_data_item_t *item)
Add a new packet received item to the list. If the item is already in the list it is only updated.
app_lib_data_received_t::num_bytes
size_t num_bytes
Definition: wms_data.h:288
node_configuration.h
APP_LIB_DATA_RECEIVE_RES_HANDLED
@ APP_LIB_DATA_RECEIVE_RES_HANDLED
Definition: wms_data.h:192
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
SHARED_DATA_NET_MODE_ALL
@ SHARED_DATA_NET_MODE_ALL
Definition: shared_data.h:48
app_lib_data_receive_res_e
app_lib_data_receive_res_e
Return value of data reception callback.
Definition: wms_data.h:188
app_lib_data_to_send_t::dest_endpoint
uint8_t dest_endpoint
Definition: wms_data.h:354
app_lib_data_to_send_t
A struct for lib_data->sendData().
Definition: wms_data.h:331
app_global_functions_t
List of global functions, passed to App_entrypoint()
Definition: wms_app.h:157
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:233
app_lib_data_received_t
Struct passed to data reception callback functions.
Definition: wms_data.h:283
app_addr_t
uint32_t app_addr_t
Definition: wms_app.h:228
app_lib_data_to_send_t::flags
uint8_t flags
Definition: wms_data.h:350
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:348
shared_data.h
APP_LIB_DATA_RECEIVE_RES_NOT_FOR_APP
@ APP_LIB_DATA_RECEIVE_RES_NOT_FOR_APP
Definition: wms_data.h:195
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_received_t::bytes
const uint8_t * bytes
Definition: wms_data.h:286
APP_LIB_BEACON_TX_MAX_NUM_BYTES
#define APP_LIB_BEACON_TX_MAX_NUM_BYTES
Definition: wms_beacon_tx.h:85
APP_LIB_BEACON_TX_CHANNELS_ALL
@ APP_LIB_BEACON_TX_CHANNELS_ALL
Definition: wms_beacon_tx.h:109
APP_LIB_DATA_QOS_NORMAL
@ APP_LIB_DATA_QOS_NORMAL
Definition: wms_data.h:88
app_lib_data_to_send_t::delay
uint32_t delay
Definition: wms_data.h:342
api.h