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>
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;
}
static app_lib_data_receive_res_e dataReceivedFunc(
{
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;
lib_data->sendData(&data_to_send);
}
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;
}
lib_data->setDataReceivedCb(dataReceivedFunc);
lib_data->setBcastDataReceivedCb(dataReceivedFunc);
lib_state->startStack();
}
APP_LIB_BEACON_TX_MAX_NUM_BYTES
#define APP_LIB_BEACON_TX_MAX_NUM_BYTES
Definition: beacon_tx.h:85
app_lib_data_received_t::num_bytes
size_t num_bytes
Definition: data.h:249
APP_LIB_BEACON_TX_CHANNELS_ALL
@ APP_LIB_BEACON_TX_CHANNELS_ALL
Definition: beacon_tx.h:109
app_lib_data_to_send_t
A struct for lib_data->sendData().
Definition: data.h:288
node_configuration.h
app_addr_t
uint32_t app_addr_t
Definition: app.h:228
app_lib_data_to_send_t::dest_address
app_addr_t dest_address
Definition: data.h:295
APP_RES_OK
@ APP_RES_OK
Definition: app.h:204
app_lib_data_to_send_t::tracking_id
app_lib_data_tracking_id_t tracking_id
Definition: data.h:303
app_lib_data_to_send_t::qos
app_lib_data_qos_e qos
Definition: data.h:305
APP_LIB_DATA_RECEIVE_RES_NOT_FOR_APP
@ APP_LIB_DATA_RECEIVE_RES_NOT_FOR_APP
Definition: data.h:191
APP_LIB_DATA_RECEIVE_RES_HANDLED
@ APP_LIB_DATA_RECEIVE_RES_HANDLED
Definition: data.h:188
app_lib_data_to_send_t::delay
uint32_t delay
Definition: data.h:299
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_to_send_t::flags
uint8_t flags
Definition: data.h:307
app_lib_data_receive_res_e
app_lib_data_receive_res_e
Return value of data reception callback.
Definition: data.h:184
app_lib_data_to_send_t::src_endpoint
uint8_t src_endpoint
Definition: data.h:309
APP_LIB_DATA_QOS_NORMAL
@ APP_LIB_DATA_QOS_NORMAL
Definition: data.h:90
app_lib_data_to_send_t::dest_endpoint
uint8_t dest_endpoint
Definition: data.h:311
app_lib_data_received_t::bytes
const uint8_t * bytes
Definition: data.h:247
APP_ADDR_ANYSINK
@ APP_ADDR_ANYSINK
Definition: app.h:236
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: data.h:60
app_lib_data_received_t
Struct passed to data reception callback functions.
Definition: data.h:244
app_global_functions_t
List of global functions, passed to App_entrypoint()
Definition: app.h:157
app_res_e
app_res_e
Definition: app.h:201
APP_LIB_DATA_SEND_FLAG_NONE
@ APP_LIB_DATA_SEND_FLAG_NONE
Definition: data.h:102
api.h