You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2021/11/23 08:11:11 UTC
[mynewt-nimble] 02/02: nimble/ll: Add support for vs hci commands registration
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit b8ddf0fe06dfc7c717d183c9202eab2283421d06
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Fri Nov 5 11:42:06 2021 +0100
nimble/ll: Add support for vs hci commands registration
This adds API to allow registration of custom HCI VS commands.
---
nimble/controller/include/controller/ble_ll_hci.h | 18 ++++
nimble/controller/src/ble_ll.c | 5 +
nimble/controller/src/ble_ll_hci.c | 44 +-------
nimble/controller/src/ble_ll_hci_priv.h | 37 +++++++
nimble/controller/src/ble_ll_hci_vs.c | 119 ++++++++++++++++++++++
nimble/controller/syscfg.yml | 5 +
6 files changed, 186 insertions(+), 42 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_hci.h b/nimble/controller/include/controller/ble_ll_hci.h
index 6a9e48e..9f3fc95 100644
--- a/nimble/controller/include/controller/ble_ll_hci.h
+++ b/nimble/controller/include/controller/ble_ll_hci.h
@@ -43,6 +43,20 @@ extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN];
typedef void (*ble_ll_hci_post_cmd_complete_cb)(void);
+#if MYNEWT_VAL(BLE_HCI_VS)
+typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf,
+ const uint8_t *cmdbuf, uint8_t cmdlen,
+ uint8_t *rspbuf, uint8_t *rsplen);
+
+#define BLE_LL_HCI_VS_CMD(_ocf, _cb) { .ocf = (_ocf), .cb = (_cb) }
+
+struct ble_ll_hci_vs_cmd {
+ uint16_t ocf;
+ ble_ll_hci_vs_cb_t cb;
+ SLIST_ENTRY(ble_ll_hci_vs_cmd) link;
+};
+#endif
+
/* Initialize LL HCI */
void ble_ll_hci_init(void);
@@ -68,6 +82,10 @@ bool ble_ll_hci_adv_mode_ext(void);
/* Get TX power compensation rounded to integer dB */
int8_t ble_ll_get_tx_pwr_compensation(void);
+#if MYNEWT_VAL(BLE_HCI_VS)
+void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c
index 5305e16..16c2242 100644
--- a/nimble/controller/src/ble_ll.c
+++ b/nimble/controller/src/ble_ll.c
@@ -45,6 +45,7 @@
#include "controller/ble_ll_trace.h"
#include "controller/ble_ll_sync.h"
#include "ble_ll_conn_priv.h"
+#include "ble_ll_hci_priv.h"
#include "ble_ll_priv.h"
#if MYNEWT_VAL(BLE_LL_DTM)
@@ -1731,6 +1732,10 @@ ble_ll_init(void)
ble_ll_dtm_init();
#endif
+#if MYNEWT_VAL(BLE_HCI_VS)
+ ble_ll_hci_vs_init();
+#endif
+
#if MYNEWT
/* Initialize the LL task */
os_task_init(&g_ble_ll_task, "ble_ll", ble_ll_task, NULL,
diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c
index c2603c9..0e92939 100644
--- a/nimble/controller/src/ble_ll_hci.c
+++ b/nimble/controller/src/ble_ll_hci.c
@@ -36,6 +36,7 @@
#include "controller/ble_ll_iso.h"
#include "ble_ll_priv.h"
#include "ble_ll_conn_priv.h"
+#include "ble_ll_hci_priv.h"
#if MYNEWT_VAL(BLE_LL_DTM)
#include "ble_ll_dtm_priv.h"
@@ -1525,47 +1526,6 @@ ble_ll_hci_status_params_cmd_proc(const uint8_t *cmdbuf, uint8_t len,
return rc;
}
-#if MYNEWT_VAL(BLE_HCI_VS)
-static int
-ble_ll_hci_vs_rd_static_addr(uint8_t *rspbuf, uint8_t *rsplen)
-{
- struct ble_hci_vs_rd_static_addr_rp *rsp = (void *) rspbuf;
- ble_addr_t addr;
-
- if (ble_hw_get_static_addr(&addr) < 0) {
- return BLE_ERR_UNSPECIFIED;
- }
-
- memcpy(rsp->addr, addr.val, sizeof(rsp->addr));
-
- *rsplen = sizeof(*rsp);
- return BLE_ERR_SUCCESS;
-}
-
-static int
-ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
- uint8_t *rspbuf, uint8_t *rsplen)
-{
- int rc;
-
- /* Assume error; if all pass rc gets set to 0 */
- rc = BLE_ERR_INV_HCI_CMD_PARMS;
-
- switch (ocf) {
- case BLE_HCI_OCF_VS_RD_STATIC_ADDR:
- if (len == 0) {
- rc = ble_ll_hci_vs_rd_static_addr(rspbuf, rsplen);
- }
- break;
- default:
- rc = BLE_ERR_UNKNOWN_HCI_CMD;
- break;
- }
-
- return rc;
-}
-#endif
-
/**
* Called to process an HCI command from the host.
*
@@ -1625,7 +1585,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev)
case BLE_HCI_OGF_LE:
rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen, &post_cb);
break;
-#if MYNEWT_VAL(BLE_HCI_VS)
+#if MYNEWT_VAL(BLE_LL_HCI_VS)
case BLE_HCI_OGF_VENDOR:
rc = ble_ll_hci_vs_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen);
break;
diff --git a/nimble/controller/src/ble_ll_hci_priv.h b/nimble/controller/src/ble_ll_hci_priv.h
new file mode 100644
index 0000000..f289dc1
--- /dev/null
+++ b/nimble/controller/src/ble_ll_hci_priv.h
@@ -0,0 +1,37 @@
+/*
+ * 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_LL_HCI_PRIV_
+#define H_BLE_LL_HCI_PRIV_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if MYNEWT_VAL(BLE_HCI_VS)
+void ble_ll_hci_vs_init(void);
+int ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t cmdlen, uint16_t ocf,
+ uint8_t *rspbuf, uint8_t *rsplen);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_BLE_LL_HCI_ */
diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c
new file mode 100644
index 0000000..8903525
--- /dev/null
+++ b/nimble/controller/src/ble_ll_hci_vs.c
@@ -0,0 +1,119 @@
+/*
+ * 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 <stdint.h>
+#include "syscfg/syscfg.h"
+#include "controller/ble_ll.h"
+#include "controller/ble_ll_hci.h"
+#include "controller/ble_hw.h"
+
+#if MYNEWT_VAL(BLE_LL_HCI_VS)
+
+SLIST_HEAD(ble_ll_hci_vs_list, ble_ll_hci_vs_cmd);
+static struct ble_ll_hci_vs_list g_ble_ll_hci_vs_list;
+
+static int
+ble_ll_hci_vs_rd_static_addr(uint16_t ocf,
+ const uint8_t *cmdbuf, uint8_t cmdlen,
+ uint8_t *rspbuf, uint8_t *rsplen)
+{
+ struct ble_hci_vs_rd_static_addr_rp *rsp = (void *) rspbuf;
+ ble_addr_t addr;
+
+ if (cmdlen != 0) {
+ return BLE_ERR_INV_HCI_CMD_PARMS;
+ }
+
+ if (ble_hw_get_static_addr(&addr) < 0) {
+ return BLE_ERR_UNSPECIFIED;
+ }
+
+ memcpy(rsp->addr, addr.val, sizeof(rsp->addr));
+
+ *rsplen = sizeof(*rsp);
+
+ return BLE_ERR_SUCCESS;
+}
+
+static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = {
+ BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR,
+ ble_ll_hci_vs_rd_static_addr),
+};
+
+static struct ble_ll_hci_vs_cmd *
+ble_ll_hci_vs_find_by_ocf(uint16_t ocf)
+{
+ struct ble_ll_hci_vs_cmd *entry;
+
+ entry = SLIST_FIRST(&g_ble_ll_hci_vs_list);
+ while (entry) {
+ if (entry->ocf == ocf) {
+ return entry;
+ }
+
+ entry = SLIST_NEXT(entry, link);
+ }
+
+ return NULL;
+}
+
+int
+ble_ll_hci_vs_cmd_proc(const uint8_t *cmdbuf, uint8_t cmdlen, uint16_t ocf,
+ uint8_t *rspbuf, uint8_t *rsplen)
+{
+ struct ble_ll_hci_vs_cmd *cmd;
+ int rc;
+
+ cmd = ble_ll_hci_vs_find_by_ocf(ocf);
+ if (!cmd) {
+ rc = BLE_ERR_UNKNOWN_HCI_CMD;
+ } else {
+ rc = cmd->cb(ocf, cmdbuf, cmdlen, rspbuf, rsplen);
+ }
+
+ return rc;
+}
+
+void
+ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds)
+{
+ uint32_t i;
+
+ /* Assume all cmds are registered early on init, so just assert in case of
+ * invalid request since it means something is wrong with the code itself.
+ */
+
+ for (i = 0; i < num_cmds; i++, cmds++) {
+ BLE_LL_ASSERT(cmds->cb != NULL);
+ BLE_LL_ASSERT(ble_ll_hci_vs_find_by_ocf(cmds->ocf) == NULL);
+
+ SLIST_INSERT_HEAD(&g_ble_ll_hci_vs_list, cmds, link);
+ }
+}
+
+void
+ble_ll_hci_vs_init(void)
+{
+ SLIST_INIT(&g_ble_ll_hci_vs_list);
+
+ ble_ll_hci_vs_register(g_ble_ll_hci_vs_cmds,
+ ARRAY_SIZE(g_ble_ll_hci_vs_cmds));
+}
+
+#endif
diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml
index d60e18f..d799e1c 100644
--- a/nimble/controller/syscfg.yml
+++ b/nimble/controller/syscfg.yml
@@ -348,6 +348,11 @@ syscfg.defs:
depending on specified HCI command length.
value: 0
+ BLE_LL_HCI_VS:
+ description: >
+ Enables support for vendor-specific HCI commands.
+ value: MYNEWT_VAL(BLE_HCI_VS)
+
BLE_LL_HCI_VS_EVENT_ON_ASSERT:
description: >
This options enables controller to send a vendor-specific event on