Skip to content

Commit ff51d48

Browse files
committed
nimble/ll: Add VS command for setting transmit power
This command allows to override TX power configured with BLE_LL_TX_PWR_DBM syscfg value. If 0xff is provided BLE_LL_TX_PWR_DBM TX power is restored.
1 parent 984e879 commit ff51d48

File tree

6 files changed

+111
-7
lines changed

6 files changed

+111
-7
lines changed

nimble/controller/src/ble_ll.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
* right thing to do.
6666
*/
6767

68+
int8_t g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM);
69+
6870
/* Supported states */
6971
#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER)
7072
#define BLE_LL_S_NCA ((uint64_t)1 << 0)
@@ -1391,7 +1393,7 @@ ble_ll_task(void *arg)
13911393
ble_phy_init();
13921394

13931395
/* Set output power to 1mW (0 dBm) */
1394-
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
1396+
ble_phy_txpwr_set(g_ble_ll_tx_power);
13951397

13961398
/* Register callback for transport */
13971399
ble_hci_trans_cfg_ll(ble_ll_hci_cmd_rx, NULL, ble_ll_hci_acl_rx, NULL);

nimble/controller/src/ble_ll_adv.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "controller/ble_ll_utils.h"
4242
#include "controller/ble_ll_rfmgmt.h"
4343
#include "ble_ll_conn_priv.h"
44+
#include "ble_ll_priv.h"
4445

4546
#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER)
4647

@@ -1023,7 +1024,7 @@ ble_ll_adv_tx_done(void *arg)
10231024
struct ble_ll_adv_sm *advsm;
10241025

10251026
/* reset power to max after advertising */
1026-
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
1027+
ble_phy_txpwr_set(g_ble_ll_tx_power);
10271028

10281029
advsm = (struct ble_ll_adv_sm *)arg;
10291030

@@ -1687,7 +1688,7 @@ ble_ll_adv_halt(void)
16871688

16881689
ble_ll_trace_u32(BLE_LL_TRACE_ID_ADV_HALT, advsm->adv_instance);
16891690

1690-
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
1691+
ble_phy_txpwr_set(g_ble_ll_tx_power);
16911692

16921693
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV)
16931694
if (advsm->flags & BLE_LL_ADV_SM_FLAG_PERIODIC_SYNC_SENDING) {
@@ -2112,8 +2113,8 @@ ble_ll_adv_sync_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
21122113
static void
21132114
ble_ll_adv_sync_tx_done(struct ble_ll_adv_sm *advsm)
21142115
{
2115-
/* reset power to max after advertising */
2116-
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
2116+
/* reset power to default after advertising */
2117+
ble_phy_txpwr_set(g_ble_ll_tx_power);
21172118

21182119
/* for sync we trace a no pri nor sec set */
21192120
ble_ll_trace_u32x2(BLE_LL_TRACE_ID_ADV_TXDONE, advsm->adv_instance, 0);

nimble/controller/src/ble_ll_hci_vs.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
#include "syscfg/syscfg.h"
2222
#include "controller/ble_ll.h"
2323
#include "controller/ble_ll_hci.h"
24+
#include "controller/ble_ll_sync.h"
25+
#include "controller/ble_ll_adv.h"
26+
#include "controller/ble_ll_scan.h"
2427
#include "controller/ble_hw.h"
28+
#include "ble_ll_conn_priv.h"
29+
#include "ble_ll_priv.h"
2530

2631
#if MYNEWT_VAL(BLE_LL_HCI_VS)
2732

@@ -51,9 +56,89 @@ ble_ll_hci_vs_rd_static_addr(uint16_t ocf,
5156
return BLE_ERR_SUCCESS;
5257
}
5358

59+
/* disallow changing TX power if there is any radio activity
60+
* note: we could allow to change it if there is no TX activity (eg only
61+
* passive scan or sync) but lets just keep this simple for now
62+
*/
63+
static int
64+
ble_ll_hci_vs_is_controller_busy(void)
65+
{
66+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
67+
struct ble_ll_conn_sm *cur;
68+
int i = 0;
69+
#endif
70+
71+
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV) && MYNEWT_VAL(BLE_LL_ROLE_OBSERVER)
72+
if (ble_ll_sync_enabled()) {
73+
return 1;
74+
}
75+
#endif
76+
77+
#if MYNEWT_VAL(BLE_LL_ROLE_BROADCASTER)
78+
if (ble_ll_adv_enabled()) {
79+
return 1;
80+
}
81+
#endif
82+
83+
#if MYNEWT_VAL(BLE_LL_ROLE_OBSERVER)
84+
if (ble_ll_scan_enabled()) {
85+
return 1;
86+
}
87+
#endif
88+
89+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
90+
if (g_ble_ll_conn_create_sm.connsm) {
91+
return 1;
92+
}
93+
#endif
94+
95+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL) || MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
96+
STAILQ_FOREACH(cur, &g_ble_ll_conn_free_list, free_stqe) {
97+
i++;
98+
}
99+
100+
/* check if all connection objects are free */
101+
if (i < MYNEWT_VAL(BLE_MAX_CONNECTIONS)) {
102+
return 1;
103+
}
104+
#endif
105+
106+
return 0;
107+
}
108+
109+
static int
110+
ble_ll_hci_vs_set_tx_power(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen,
111+
uint8_t *rspbuf, uint8_t *rsplen)
112+
{
113+
const struct ble_hci_vs_set_tx_pwr_cp *cmd = (const void *) cmdbuf;
114+
struct ble_hci_vs_set_tx_pwr_rp *rsp = (void *) rspbuf;
115+
116+
if (cmdlen != sizeof(*cmd)) {
117+
return BLE_ERR_INV_HCI_CMD_PARMS;
118+
}
119+
120+
if (ble_ll_hci_vs_is_controller_busy()) {
121+
return BLE_ERR_CMD_DISALLOWED;
122+
}
123+
124+
if (cmd->tx_power == 127) {
125+
/* restore reset default */
126+
g_ble_ll_tx_power = MYNEWT_VAL(BLE_LL_TX_PWR_DBM);
127+
} else {
128+
g_ble_ll_tx_power = ble_phy_txpower_round(cmd->tx_power);
129+
}
130+
131+
rsp->tx_power = g_ble_ll_tx_power;
132+
*rsplen = sizeof(*rsp);
133+
134+
return BLE_ERR_SUCCESS;
135+
}
136+
54137
static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = {
55138
BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR,
56139
ble_ll_hci_vs_rd_static_addr),
140+
BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_TX_PWR,
141+
ble_ll_hci_vs_set_tx_power),
57142
};
58143

59144
static struct ble_ll_hci_vs_cmd *

nimble/controller/src/ble_ll_priv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
extern "C" {
2525
#endif
2626

27+
extern int8_t g_ble_ll_tx_power;
28+
2729
#ifdef MYNEWT
2830

2931
#include "syscfg/syscfg.h"

nimble/controller/syscfg.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ syscfg.defs:
6868
range: 0..500
6969

7070
BLE_LL_TX_PWR_DBM:
71-
description: 'Transmit power level.'
71+
description: >
72+
Default Transmit power level (in dBm). Actual transmit power
73+
may be rounded up or down depending on used radio.
7274
value: '0'
7375

7476
BLE_LL_NUM_COMP_PKT_ITVL_MS:

nimble/include/nimble/hci_common.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,11 +1062,23 @@ struct ble_hci_le_set_host_feat_cp {
10621062
} __attribute__((packed));
10631063

10641064
/* --- Vendor specific commands (OGF 0x003F) */
1065-
#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001)
1065+
/* Read Random Static Address */
1066+
#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (0x0001)
10661067
struct ble_hci_vs_rd_static_addr_rp {
10671068
uint8_t addr[6];
10681069
} __attribute__((packed));
10691070

1071+
/* Set default transmit power. Actual selected TX power is returned
1072+
* in reply. Setting 0xff restores controller reset default.
1073+
*/
1074+
#define BLE_HCI_OCF_VS_SET_TX_PWR (0x0002)
1075+
struct ble_hci_vs_set_tx_pwr_cp {
1076+
int8_t tx_power;
1077+
} __attribute__((packed));
1078+
struct ble_hci_vs_set_tx_pwr_rp {
1079+
int8_t tx_power;
1080+
} __attribute__((packed));
1081+
10701082
/* Command Specific Definitions */
10711083
/* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */
10721084
#define BLE_HCI_CTLR_TO_HOST_FC_OFF (0)

0 commit comments

Comments
 (0)