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
The following commit(s) were added to refs/heads/master by this push:
new 18203cca nimble/host: Add HCI Commands/ events for connection subrating
18203cca is described below
commit 18203ccafc31b9d7580c2eddf48029dabe489c0e
Author: Rahul Tank <[email protected]>
AuthorDate: Tue Sep 27 18:15:39 2022 +0530
nimble/host: Add HCI Commands/ events for connection subrating
---
nimble/host/include/host/ble_gap.h | 68 ++++++++++++++++++++++
nimble/host/src/ble_gap.c | 60 +++++++++++++++++++
nimble/host/src/ble_gap_priv.h | 4 +-
nimble/host/src/ble_hs_hci_evt.c | 26 ++++++++-
nimble/host/src/ble_hs_startup.c | 10 ++++
nimble/syscfg.yml | 5 ++
porting/examples/linux/include/syscfg/syscfg.h | 4 ++
.../examples/linux_blemesh/include/syscfg/syscfg.h | 4 ++
porting/examples/nuttx/include/syscfg/syscfg.h | 4 ++
porting/nimble/include/syscfg/syscfg.h | 4 ++
porting/npl/riot/include/syscfg/syscfg.h | 4 ++
11 files changed, 190 insertions(+), 3 deletions(-)
diff --git a/nimble/host/include/host/ble_gap.h
b/nimble/host/include/host/ble_gap.h
index 5ff34f58..37ac7974 100644
--- a/nimble/host/include/host/ble_gap.h
+++ b/nimble/host/include/host/ble_gap.h
@@ -138,6 +138,7 @@ struct hci_conn_update;
#define BLE_GAP_EVENT_PATHLOSS_THRESHOLD 25
#define BLE_GAP_EVENT_TRANSMIT_POWER 26
#define BLE_GAP_EVENT_PARING_COMPLETE 27
+#define BLE_GAP_EVENT_SUBRATE_CHANGE 28
/*** Reason codes for the subscribe GAP event. */
@@ -1042,6 +1043,34 @@ struct ble_gap_event {
/** The handle of the relevant connection. */
uint16_t conn_handle;
} pairing_complete;
+
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+ /**
+ * Represents a subrate change event that indicates connection subrate
update procedure
+ * has completed and some parameters have changed Valid for
+ * the following event types:
+ * o BLE_GAP_EVENT_SUBRATE_CHANGE
+ */
+ struct {
+ /** BLE_ERR_SUCCESS on success or error code on failure */
+ uint8_t status;
+
+ /** Connection Handle */
+ uint16_t conn_handle;
+
+ /** Subrate Factor */
+ uint16_t subrate_factor;
+
+ /** Peripheral Latency */
+ uint16_t periph_latency;
+
+ /** Continuation Number */
+ uint16_t cont_num;
+
+ /** Supervision Timeout */
+ uint16_t supervision_tmo;
+ } subrate_change;
+#endif
};
};
@@ -2167,6 +2196,45 @@ int ble_gap_set_prefered_default_le_phy(uint8_t
tx_phys_mask,
int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask,
uint8_t rx_phys_mask, uint16_t phy_opts);
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+/**
+ * Set default subrate
+ *
+ * @param subrate_min Min subrate factor allowed in request by a
peripheral
+ * @param subrate_max Max subrate factor allowed in request by a
peripheral
+ * @param max_latency Max peripheral latency allowed in units of
+ * subrated conn interval.
+ *
+ * @param cont_num Min number of underlying conn event to remain
active
+ * after a packet containing PDU with non-zero length
field
+ * is sent or received in request by a peripheral.
+ *
+ * @param supervision_timeout Max supervision timeout allowed in request by a
peripheral
+ */
+int ble_gap_set_default_subrate(uint16_t subrate_min, uint16_t subrate_max,
uint16_t max_latency,
+ uint16_t cont_num, uint16_t
supervision_timeout);
+
+/**
+ * Subrate Request
+ *
+ * @param conn_handle Connection Handle of the ACL.
+ * @param subrate_min Min subrate factor to be applied
+ * @param subrate_max Max subrate factor to be applied
+ * @param max_latency Max peripheral latency allowed in units of
+ * subrated conn interval.
+ *
+ * @param cont_num Min number of underlying conn event to remain
active
+ * after a packet containing PDU with non-zero length
field
+ * is sent or received in request by a peripheral.
+ *
+ * @param supervision_timeout Max supervision timeout allowed for this
connection
+ */
+
+int
+ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t
subrate_max,
+ uint16_t max_latency, uint16_t cont_num,
+ uint16_t supervision_timeout);
+#endif
/**
* Event listener structure
*
diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c
index d8a944a8..952b59b0 100644
--- a/nimble/host/src/ble_gap.c
+++ b/nimble/host/src/ble_gap.c
@@ -1777,6 +1777,26 @@ ble_gap_rx_periodic_adv_sync_transfer(const struct
ble_hci_ev_le_subev_periodic_
}
#endif
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+void
+ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change *ev)
+{
+ struct ble_gap_event event;
+
+ memset(&event, 0x0, sizeof event);
+
+ event.type = BLE_GAP_EVENT_SUBRATE_CHANGE;
+ event.subrate_change.status = ev->status;
+ event.subrate_change.conn_handle = le16toh(ev->conn_handle);
+ event.subrate_change.subrate_factor = le16toh(ev->subrate_factor);
+ event.subrate_change.periph_latency = le16toh(ev->periph_latency);
+ event.subrate_change.cont_num = le16toh(ev->cont_num);
+ event.subrate_change.supervision_tmo = le16toh(ev->supervision_tmo);
+
+ ble_gap_event_listener_call(&event);
+}
+#endif
+
#if NIMBLE_BLE_CONNECT
static int
ble_gap_rd_rem_sup_feat_tx(uint16_t handle)
@@ -4663,6 +4683,46 @@ ble_gap_conn_create_tx(uint8_t own_addr_type, const
ble_addr_t *peer_addr,
}
#endif
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+int
+ble_gap_set_default_subrate(uint16_t subrate_min, uint16_t subrate_max,
uint16_t max_latency,
+ uint16_t cont_num, uint16_t supervision_tmo)
+{
+ struct ble_hci_le_set_default_subrate_cp cmd;
+ uint16_t opcode;
+
+ cmd.subrate_min = htole16(subrate_min);
+ cmd.subrate_max = htole16(subrate_max);
+ cmd.max_latency = htole16(max_latency);
+ cmd.cont_num = htole16(cont_num);
+ cmd.supervision_tmo = htole16(supervision_tmo);
+
+ opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE);
+
+ return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0);
+}
+
+int
+ble_gap_subrate_req(uint16_t conn_handle, uint16_t subrate_min, uint16_t
subrate_max,
+ uint16_t max_latency, uint16_t cont_num,
+ uint16_t supervision_tmo)
+{
+ struct ble_hci_le_subrate_req_cp cmd;
+ uint16_t opcode;
+
+ cmd.conn_handle = htole16(conn_handle);
+ cmd.subrate_min = htole16(subrate_min);
+ cmd.subrate_max = htole16(subrate_max);
+ cmd.max_latency = htole16(max_latency);
+ cmd.cont_num = htole16(cont_num);
+ cmd.supervision_tmo = htole16(supervision_tmo);
+
+ opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SUBRATE_REQ);
+
+ return ble_hs_hci_cmd_tx(opcode, &cmd, sizeof(cmd), NULL, 0);
+}
+#endif
+
#if MYNEWT_VAL(BLE_EXT_ADV)
#if MYNEWT_VAL(BLE_ROLE_CENTRAL)
static int
diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h
index d6051b73..0e4947f1 100644
--- a/nimble/host/src/ble_gap_priv.h
+++ b/nimble/host/src/ble_gap_priv.h
@@ -92,7 +92,9 @@ void ble_gap_rx_scan_req_rcvd(const struct
ble_hci_ev_le_subev_scan_req_rcvd *ev
#endif
void ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc);
void ble_gap_rx_rd_rem_sup_feat_complete(const struct
ble_hci_ev_le_subev_rd_rem_used_feat *ev);
-
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+void ble_gap_rx_subrate_change(const struct ble_hci_ev_le_subev_subrate_change
*ev);
+#endif
#if MYNEWT_VAL(BLE_POWER_CONTROL)
void ble_gap_rx_transmit_power_report(const struct
ble_hci_ev_le_subev_transmit_power_report *ev);
void ble_gap_rx_le_pathloss_threshold(const struct
ble_hci_ev_le_subev_path_loss_threshold *ev);
diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c
index be64a3d3..f7113f63 100644
--- a/nimble/host/src/ble_hs_hci_evt.c
+++ b/nimble/host/src/ble_hs_hci_evt.c
@@ -64,10 +64,12 @@ static ble_hs_hci_evt_le_fn
ble_hs_hci_evt_le_periodic_adv_sync_transfer;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_pathloss_threshold;
static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_transmit_power_report;
#endif
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_subrate_change;
+#endif
/* Statistics */
-struct host_hci_stats
-{
+struct host_hci_stats {
uint32_t events_rxd;
uint32_t good_acks_rxd;
uint32_t bad_acks_rxd;
@@ -124,6 +126,9 @@ static ble_hs_hci_evt_le_fn * const
ble_hs_hci_evt_le_dispatch[] = {
[BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD] =
ble_hs_hci_evt_le_pathloss_threshold,
[BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT] =
ble_hs_hci_evt_le_transmit_power_report,
#endif
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+ [BLE_HCI_LE_SUBEV_SUBRATE_CHANGE] = ble_hs_hci_evt_le_subrate_change,
+#endif
};
#define BLE_HS_HCI_EVT_LE_DISPATCH_SZ \
@@ -750,6 +755,23 @@ ble_hs_hci_evt_le_scan_req_rcvd(uint8_t subevent, const
void *data,
return 0;
}
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+static int
+ble_hs_hci_evt_le_subrate_change(uint8_t subevent, const void *data,
+ unsigned int len)
+{
+ const struct ble_hci_ev_le_subev_subrate_change *ev = data;
+
+ if (len != sizeof(*ev)) {
+ return BLE_HS_ECONTROLLER;
+ }
+
+ ble_gap_rx_subrate_change(ev);
+
+ return 0;
+}
+#endif
+
#if NIMBLE_BLE_CONNECT
static int
ble_hs_hci_evt_le_conn_upd_complete(uint8_t subevent, const void *data,
diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c
index 96e4e655..03f3d2e4 100644
--- a/nimble/host/src/ble_hs_startup.c
+++ b/nimble/host/src/ble_hs_startup.c
@@ -240,6 +240,16 @@ ble_hs_startup_le_set_evmask_tx(void)
}
#endif
+#if MYNEWT_VAL(BLE_CONN_SUBRATING)
+ if (version >= BLE_HCI_VER_BCS_5_3) {
+ /**
+ * Enable the following LE events:
+ * 0x0000000400000000 LE Subrate change event
+ */
+ mask |= 0x0000000400000000;
+ }
+#endif
+
cmd.event_mask = htole64(mask);
rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml
index f8c92ea0..a50bc89e 100644
--- a/nimble/syscfg.yml
+++ b/nimble/syscfg.yml
@@ -113,6 +113,11 @@ syscfg.defs:
This enabled LE Power Control feature
value: 0
+ BLE_CONN_SUBRATING:
+ description: >
+ This enables LE Connection Subrating feature
+ value: 0
+
# Allow periodic sync transfer only if 5.1 or higher
syscfg.restrictions:
- "'BLE_PERIODIC_ADV_SYNC_TRANSFER == 0' || 'BLE_VERSION >= 51'"
diff --git a/porting/examples/linux/include/syscfg/syscfg.h
b/porting/examples/linux/include/syscfg/syscfg.h
index c98da2ab..a74ff46b 100644
--- a/porting/examples/linux/include/syscfg/syscfg.h
+++ b/porting/examples/linux/include/syscfg/syscfg.h
@@ -478,6 +478,10 @@
#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
#endif
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
#endif
diff --git a/porting/examples/linux_blemesh/include/syscfg/syscfg.h
b/porting/examples/linux_blemesh/include/syscfg/syscfg.h
index 851337c7..a5ee9029 100644
--- a/porting/examples/linux_blemesh/include/syscfg/syscfg.h
+++ b/porting/examples/linux_blemesh/include/syscfg/syscfg.h
@@ -479,6 +479,10 @@
#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
#endif
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
#endif
diff --git a/porting/examples/nuttx/include/syscfg/syscfg.h
b/porting/examples/nuttx/include/syscfg/syscfg.h
index e0f07349..741695d8 100644
--- a/porting/examples/nuttx/include/syscfg/syscfg.h
+++ b/porting/examples/nuttx/include/syscfg/syscfg.h
@@ -478,6 +478,10 @@
#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
#endif
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
#endif
diff --git a/porting/nimble/include/syscfg/syscfg.h
b/porting/nimble/include/syscfg/syscfg.h
index 0184055e..dcd5acc0 100644
--- a/porting/nimble/include/syscfg/syscfg.h
+++ b/porting/nimble/include/syscfg/syscfg.h
@@ -477,6 +477,10 @@
#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
#endif
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
#endif
diff --git a/porting/npl/riot/include/syscfg/syscfg.h
b/porting/npl/riot/include/syscfg/syscfg.h
index 1945d28a..b732e00f 100644
--- a/porting/npl/riot/include/syscfg/syscfg.h
+++ b/porting/npl/riot/include/syscfg/syscfg.h
@@ -842,6 +842,10 @@
#define MYNEWT_VAL_BLE_POWER_CONTROL (0)
#endif
+#ifndef MYNEWT_VAL_BLE_CONN_SUBRATING
+#define MYNEWT_VAL_BLE_CONN_SUBRATING (0)
+#endif
+
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
#endif