summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorChristopher Collins <ccollins@apache.org>2016-05-09 16:36:33 -0700
committerChristopher Collins <ccollins@apache.org>2016-05-09 16:36:33 -0700
commit2fa4773eed19764a7d6ec19e053ca37d2d947dea (patch)
treeef5dce7d12c53f92f5288b09a782e4b6a809e903 /net
parente1cf9e648403ac9ee2b21a1efd1c695cfe53b06d (diff)
BLE host - eddystone advertisements.
Diffstat (limited to 'net')
-rw-r--r--net/nimble/host/include/host/ble_eddystone.h56
-rw-r--r--net/nimble/host/src/ble_eddystone.c187
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;
+}