mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
114 lines
3.1 KiB
C
114 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2018 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup ble_skald_eddystone
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Skald's Eddystone implementation
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "assert.h"
|
|
#include "net/skald/eddystone.h"
|
|
|
|
#define PREAMBLE_LEN (11U)
|
|
#define PA_LEN (7U)
|
|
#define PB_LEN (3U)
|
|
|
|
#define URL_HDR_LEN (6U)
|
|
|
|
#define UID_LEN (23U)
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
uint8_t txadd[BLE_ADDR_LEN];
|
|
uint8_t pa[PA_LEN];
|
|
uint8_t service_data_len;
|
|
uint8_t pb[PB_LEN];
|
|
uint8_t type;
|
|
} pre_t;
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
pre_t pre;
|
|
uint8_t tx_pwr;
|
|
uint8_t namespace[EDDYSTONE_NAMESPACE_LEN];
|
|
uint8_t instance[EDDYSTONE_INSTANCE_LEN];
|
|
uint8_t reserved[2];
|
|
} eddy_uid_t;
|
|
|
|
typedef struct __attribute__((packed)) {
|
|
pre_t pre;
|
|
uint8_t tx_pwr;
|
|
uint8_t scheme;
|
|
uint8_t url[];
|
|
} eddy_url_t;
|
|
|
|
/* ćonstant GAP data preamble parts, containing the following GAP fields:
|
|
* - flags: BR/EDR not support set
|
|
* - complete list of 16-bit UUIDs: holding the Eddystone UUID only (0xfeaa)
|
|
* - service data of type 0xfeaa (Eddystone) */
|
|
static const uint8_t _pa[PA_LEN] = { 0x02, 0x01, 0x04, 0x03, 0x03, 0xaa, 0xfe };
|
|
static const uint8_t _pb[PB_LEN] = { 0x16, 0xaa, 0xfe };
|
|
|
|
static void _init_pre(pre_t *data, uint8_t type, uint8_t len)
|
|
{
|
|
skald_generate_random_addr(data->txadd);
|
|
memcpy(data->pa, _pa, PA_LEN);
|
|
memcpy(data->pb, _pb, PB_LEN);
|
|
data->service_data_len = len;
|
|
data->type = type;
|
|
}
|
|
|
|
void skald_eddystone_uid_adv(skald_ctx_t *ctx,
|
|
const skald_eddystone_uid_t *uid, uint8_t tx_pwr,
|
|
uint32_t adv_itvl_ms)
|
|
{
|
|
assert(ctx && uid);
|
|
|
|
eddy_uid_t *pdu = (eddy_uid_t *)ctx->pkt.pdu;
|
|
_init_pre(&pdu->pre, EDDYSTONE_UID, UID_LEN);
|
|
|
|
pdu->tx_pwr = tx_pwr;
|
|
memcpy(pdu->namespace, uid->namespace, EDDYSTONE_NAMESPACE_LEN);
|
|
memcpy(pdu->instance, uid->instance, EDDYSTONE_INSTANCE_LEN);
|
|
memset(pdu->reserved, 0, 2);
|
|
|
|
/* start advertising */
|
|
ctx->pkt.len = sizeof(eddy_uid_t);
|
|
ctx->adv_itvl_ms = adv_itvl_ms;
|
|
skald_adv_start(ctx);
|
|
}
|
|
|
|
void skald_eddystone_url_adv(skald_ctx_t *ctx,
|
|
uint8_t scheme, const char *url, uint8_t tx_pwr,
|
|
uint32_t adv_itvl_ms)
|
|
{
|
|
assert(url && ctx);
|
|
size_t len = strlen(url);
|
|
assert(len <= (NETDEV_BLE_PDU_MAXLEN - (URL_HDR_LEN + PREAMBLE_LEN)));
|
|
|
|
eddy_url_t *pdu = (eddy_url_t *)ctx->pkt.pdu;
|
|
_init_pre(&pdu->pre, EDDYSTONE_URL, (URL_HDR_LEN + len));
|
|
|
|
/* set remaining service data fields */
|
|
pdu->tx_pwr = tx_pwr;
|
|
pdu->scheme = scheme;
|
|
memcpy(pdu->url, url, len);
|
|
|
|
/* start advertising */
|
|
ctx->pkt.len = (sizeof(pre_t) + 2 + len);
|
|
ctx->adv_itvl_ms = adv_itvl_ms;
|
|
skald_adv_start(ctx);
|
|
}
|