diff options
author | Christopher Collins <ccollins@apache.org> | 2016-05-09 16:36:33 -0700 |
---|---|---|
committer | Christopher Collins <ccollins@apache.org> | 2016-05-09 16:36:33 -0700 |
commit | 2fa4773eed19764a7d6ec19e053ca37d2d947dea (patch) | |
tree | ef5dce7d12c53f92f5288b09a782e4b6a809e903 /net | |
parent | e1cf9e648403ac9ee2b21a1efd1c695cfe53b06d (diff) |
BLE host - eddystone advertisements.
Diffstat (limited to 'net')
-rw-r--r-- | net/nimble/host/include/host/ble_eddystone.h | 56 | ||||
-rw-r--r-- | net/nimble/host/src/ble_eddystone.c | 187 |
2 files changed, 243 insertions, 0 deletions
diff --git a/net/nimble/host/include/host/ble_eddystone.h b/net/nimble/host/include/host/ble_eddystone.h new file mode 100644 index 00000000..89d62c12 --- /dev/null +++ b/net/nimble/host/include/host/ble_eddystone.h @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_EDDYSTONE_ +#define H_BLE_EDDYSTONE_ + +#include <inttypes.h> +struct ble_hs_adv_fields; + +#define BLE_EDDYSTONE_MAX_UUIDS16 3 +#define BLE_EDDYSTONE_URL_MAX_LEN 17 + +#define BLE_EDDYSTONE_URL_SCHEME_HTTP_WWW 0 +#define BLE_EDDYSTONE_URL_SCHEME_HTTPS_WWW 1 +#define BLE_EDDYSTONE_URL_SCHEME_HTTP 2 +#define BLE_EDDYSTONE_URL_SCHEME_HTTPS 3 + +#define BLE_EDDYSTONE_URL_SUFFIX_COM_SLASH 0x00 +#define BLE_EDDYSTONE_URL_SUFFIX_ORG_SLASH 0x01 +#define BLE_EDDYSTONE_URL_SUFFIX_EDU_SLASH 0x02 +#define BLE_EDDYSTONE_URL_SUFFIX_NET_SLASH 0x03 +#define BLE_EDDYSTONE_URL_SUFFIX_INFO_SLASH 0x04 +#define BLE_EDDYSTONE_URL_SUFFIX_BIZ_SLASH 0x05 +#define BLE_EDDYSTONE_URL_SUFFIX_GOV_SLASH 0x06 +#define BLE_EDDYSTONE_URL_SUFFIX_COM 0x07 +#define BLE_EDDYSTONE_URL_SUFFIX_ORG 0x08 +#define BLE_EDDYSTONE_URL_SUFFIX_EDU 0x09 +#define BLE_EDDYSTONE_URL_SUFFIX_NET 0x0a +#define BLE_EDDYSTONE_URL_SUFFIX_INFO 0x0b +#define BLE_EDDYSTONE_URL_SUFFIX_BIZ 0x0c +#define BLE_EDDYSTONE_URL_SUFFIX_GOV 0x0d +#define BLE_EDDYSTONE_URL_SUFFIX_NONE 0xff + +int ble_eddystone_set_adv_data_uid(struct ble_hs_adv_fields *adv_fields, + void *uid); +int ble_eddystone_set_adv_data_url(struct ble_hs_adv_fields *adv_fields, + uint8_t url_scheme, char *url_body, + uint8_t url_body_len, uint8_t suffix); + +#endif diff --git a/net/nimble/host/src/ble_eddystone.c b/net/nimble/host/src/ble_eddystone.c new file mode 100644 index 00000000..453094a0 --- /dev/null +++ b/net/nimble/host/src/ble_eddystone.c @@ -0,0 +1,187 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string.h> +#include "host/ble_eddystone.h" +#include "ble_hs_priv.h" + +#define BLE_EDDYSTONE_MAX_SVC_DATA_LEN 23 +#define BLE_EDDYSTONE_SVC_DATA_BASE_SZ 3 + +#define BLE_EDDYSTONE_SERVICE_UUID 0xfeaa + +#define BLE_EDDYSTONE_FRAME_TYPE_UID 0x00 +#define BLE_EDDYSTONE_FRAME_TYPE_URL 0x10 + +static uint16_t ble_eddystone_uuids16[BLE_EDDYSTONE_MAX_UUIDS16 + 1]; +static uint8_t ble_eddystone_svc_data[BLE_EDDYSTONE_MAX_SVC_DATA_LEN]; + +/** + * Writes an eddystone header to the global service data buffer. + * + * @param frame_type The eddystone frame type; one of the + * BLE_EDDYSTONE_FRAME_TYPE_[...] values. + * + * @return A pointer to where the service data payload + * should be written. + */ +static void * +ble_eddystone_set_svc_data_base(uint8_t frame_type) +{ + htole16(ble_eddystone_svc_data, BLE_EDDYSTONE_SERVICE_UUID); + ble_eddystone_svc_data[2] = frame_type; + + return ble_eddystone_svc_data + BLE_EDDYSTONE_SVC_DATA_BASE_SZ; +} + +/** + * Populates the supplied advertisement fields struct to represent an eddystone + * advertisement. Prior to calling this function, you must write the service + * data header and payload using the ble_eddystone_set_svc_data_base() + * function. + * + * @param adv_fields The base advertisement fields to transform into + * an eddystone beacon. All configured fields + * are preserved; you probably want to clear + * this struct before calling this function. + * @param svc_data_len The amount of data written to the global + * service data buffer. + * + * @return 0 on success; BLE_HS_E... on failure. + */ +static int +ble_eddystone_set_adv_data_gen(struct ble_hs_adv_fields *adv_fields, + uint8_t svc_data_len) +{ + if (adv_fields->num_uuids16 > BLE_EDDYSTONE_MAX_UUIDS16) { + return BLE_HS_EINVAL; + } + if (svc_data_len > BLE_EDDYSTONE_MAX_SVC_DATA_LEN) { + return BLE_HS_EINVAL; + } + if (adv_fields->num_uuids16 > 0 && !adv_fields->uuids16_is_complete) { + return BLE_HS_EINVAL; + } + if (adv_fields->svc_data_uuid16_len != 0) { + return BLE_HS_EINVAL; + } + + ble_eddystone_uuids16[0] = BLE_EDDYSTONE_SERVICE_UUID; + memcpy(ble_eddystone_uuids16 + 1, adv_fields->uuids16, + adv_fields->num_uuids16 * 2); + adv_fields->uuids16 = ble_eddystone_uuids16; + adv_fields->num_uuids16++; + adv_fields->uuids16_is_complete = 1; + + adv_fields->svc_data_uuid16 = ble_eddystone_svc_data; + adv_fields->svc_data_uuid16_len = svc_data_len + + BLE_EDDYSTONE_SVC_DATA_BASE_SZ; + + rc = ble_gap_adv_set_fields(adv_fields); + if (rc != 0) { + return rc; + } + + return 0; +} + +/** + * Configures the device to advertise eddystone UID beacons. + * + * @param adv_fields The base advertisement fields to transform into + * an eddystone beacon. All configured fields + * are preserved; you probably want to clear + * this struct before calling this function. + * @param uid The 16-byte UID to advertise. + * + * @return 0 on success; BLE_HS_E... on failure. + */ +int +ble_eddystone_set_adv_data_uid(struct ble_hs_adv_fields *adv_fields, void *uid) +{ + void *svc_data; + int rc; + + svc_data = ble_eddystone_set_svc_data_base(BLE_EDDYSTONE_FRAME_TYPE_UID); + memcpy(svc_data, uid, 16); + rc = ble_eddystone_set_adv_data_gen(adv_fields, 16); + if (rc != 0) { + return rc; + } + + return 0; +} + +/** + * Configures the device to advertise eddystone URL beacons. + * + * @param adv_fields The base advertisement fields to transform into + * an eddystone beacon. All configured fields + * are preserved; you probably want to clear + * this struct before calling this function. + * @param url_scheme The prefix of the URL; one of the + * BLE_EDDYSTONE_URL_SCHEME values. + * @param url_body The middle of the URL. Don't include the + * suffix if there is a suitable suffix code. + * @param url_body_len The string length of the url_body argument. + * @param url_suffix The suffix of the URL; one of the + * BLE_EDDYSTONE_URL_SUFFIX values; use + * BLE_EDDYSTONE_URL_SUFFIX_NONE if the suffix + * is embeded in the body argument. + * + * @return 0 on success; BLE_HS_E... on failure. + */ +int +ble_eddystone_set_adv_data_url(struct ble_hs_adv_fields *adv_fields, + uint8_t url_scheme, char *url_body, + uint8_t url_body_len, uint8_t url_suffix) +{ + uint8_t *svc_data; + int8_t tx_pwr; + int url_len; + int rc; + + url_len = url_body_len; + if (url_suffix != BLE_EDDYSTONE_URL_SUFFIX_NONE) { + url_len++; + } + if (url_len > BLE_EDDYSTONE_URL_MAX_LEN) { + return BLE_HS_EINVAL; + } + + svc_data = ble_eddystone_set_svc_data_base(BLE_EDDYSTONE_FRAME_TYPE_URL); + + rc = ble_hci_util_read_adv_tx_pwr(&tx_pwr); + if (rc != 0) { + return rc; + } + svc_data[0] = tx_pwr; + svc_data[1] = url_scheme; + memcpy(svc_data + 2, url_body, url_body_len); + if (url_suffix != BLE_EDDYSTONE_URL_SUFFIX_NONE) { + svc_data[2 + url_body_len] = url_suffix; + } + + rc = ble_eddystone_set_adv_data_gen(adv_fields, url_len + 2); + if (rc != 0) { + return rc; + } + + return 0; +} |