Bluetooth: host: Add non-connectable directed advertising support

This patch introduces two major changes to the directed advertising
feature of the bluetooth host.

Deprecating the bt_conn_create_slave_le, and removing
bt_conn_le_create_slave which has never been released. This behaviour
has now been moved by to providing the peer direct address into the
advertising parameters.

Introducing directed advertising support for nonconnectable
directed extended advertising, both scannable and non-scannable.

A bug was also fixed in the the directed-adv command in the shell
when the argument "low" was given. The advertiseng parameter pointer
declared with BT_LE_ADV_CONN_DIR_LOW_DUTY was declared in a scope that
was no longer valid when it was used to start the advertiser.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-04-09 20:06:02 +02:00 committed by Johan Hedberg
commit 18bee9178f
10 changed files with 267 additions and 219 deletions

View file

@ -321,6 +321,8 @@ enum {
* connection happens. If this option is not set the stack will
* take care of keeping advertising enabled even as connections
* occur.
* If Advertising directed and connectable then this behaviour is
* the default behaviour and this flag has no effect.
*/
BT_LE_ADV_OPT_ONE_TIME = BIT(1),
@ -337,8 +339,7 @@ enum {
BT_LE_ADV_OPT_USE_NAME = BIT(3),
/** Use low duty directed advertising mode, otherwise high duty mode
* will be used. This option is only effective when used with
* bt_conn_create_slave_le().
* will be used.
*/
BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY = BIT(4),
@ -450,13 +451,27 @@ struct bt_le_adv_param {
u8_t secondary_max_skip;
/** Bit-field of advertising options */
u32_t options;
u32_t options;
/** Minimum Advertising Interval (N * 0.625) */
u32_t interval_min;
/** Maximum Advertising Interval (N * 0.625) */
u32_t interval_max;
/** Directed advertising to peer
*
* When this parameter is set the advertiser will send directed
* advertising to the remote device.
*
* The advertising type will either be high duty cycle, or low duty
* cycle if the BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY option is enabled.
*
* In case of connectable high duty cycle if the connection could not
* be established within the timeout the connected() callback will be
* called with the status set to @ref BT_HCI_ERR_ADV_TIMEOUT.
*/
const bt_addr_le_t *peer;
};
/** Helper to declare advertising parameters inline
@ -464,8 +479,10 @@ struct bt_le_adv_param {
* @param _options Advertising Options
* @param _int_min Minimum advertising interval
* @param _int_max Maximum advertising interval
* @param _peer Peer address, set to NULL for undirected advertising or
* address of peer for directed advertising.
*/
#define BT_LE_ADV_PARAM(_options, _int_min, _int_max) \
#define BT_LE_ADV_PARAM(_options, _int_min, _int_max, _peer) \
((struct bt_le_adv_param[]) { { \
.id = BT_ID_DEFAULT, \
.sid = 0, \
@ -473,37 +490,46 @@ struct bt_le_adv_param {
.options = (_options), \
.interval_min = (_int_min), \
.interval_max = (_int_max), \
.peer = (_peer), \
} })
#define BT_LE_ADV_CONN_DIR(_peer) BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
BT_LE_ADV_OPT_ONE_TIME, 0, 0,\
_peer)
#define BT_LE_ADV_CONN BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE, \
BT_GAP_ADV_FAST_INT_MIN_2, \
BT_GAP_ADV_FAST_INT_MAX_2)
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
#define BT_LE_ADV_CONN_NAME BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
BT_LE_ADV_OPT_USE_NAME, \
BT_GAP_ADV_FAST_INT_MIN_2, \
BT_GAP_ADV_FAST_INT_MAX_2)
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
#define BT_LE_ADV_CONN_DIR_LOW_DUTY \
#define BT_LE_ADV_CONN_DIR_LOW_DUTY(_peer) \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME | \
BT_LE_ADV_OPT_DIR_MODE_LOW_DUTY, \
BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2)
#define BT_LE_ADV_CONN_DIR BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
BT_LE_ADV_OPT_ONE_TIME, 0, 0)
BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, \
_peer)
#define BT_LE_ADV_NCONN BT_LE_ADV_PARAM(0, BT_GAP_ADV_FAST_INT_MIN_2, \
BT_GAP_ADV_FAST_INT_MAX_2)
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
#define BT_LE_ADV_NCONN_NAME BT_LE_ADV_PARAM(BT_LE_ADV_OPT_USE_NAME, \
BT_GAP_ADV_FAST_INT_MIN_2, \
BT_GAP_ADV_FAST_INT_MAX_2)
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
/** @brief Start advertising
*
* Set advertisement data, scan response data, advertisement parameters
* and start advertising.
*
* When the advertisement parameter peer address has been set the advertising
* will be directed to the peer. In this case advertisement data and scan
* response data parameters are ignored. If the mode is high duty cycle
* the timeout will be @ref BT_GAP_ADV_HIGH_DUTY_CYCLE_MAX_TIMEOUT.
*
* @param param Advertising parameters.
* @param ad Data to be used in advertisement packets.
* @param ad_len Number of elements in ad
@ -569,6 +595,10 @@ struct bt_le_ext_adv_start_param {
* Application will be notified by the advertiser sent callback.
* Set to zero for no timeout.
*
* When using high duty cycle directed connectable advertising then
* this parameters must be set to a non-zero value less than or equal
* to the maximum of @ref BT_GAP_ADV_HIGH_DUTY_CYCLE_MAX_TIMEOUT.
*
* If privacy :option:`CONFIG_BT_PRIVACY` is enabled then the timeout
* must be less than :option:`CONFIG_BT_RPA_TIMEOUT`.
*/

View file

@ -471,27 +471,26 @@ int bt_le_set_auto_conn(const bt_addr_le_t *addr,
* The caller gets a new reference to the connection object which must be
* released with bt_conn_unref() once done using the object.
*
* @param[in] peer Remote address.
* @param[in] param Directed advertising parameters.
* @param[out] conn Valid connection object on success.
* @param peer Remote address.
* @param param Directed advertising parameters.
*
* @return Zero on success or (negative) error code on failure.
* @return Valid connection object on success or NULL otherwise.
*/
int bt_conn_le_create_slave(const bt_addr_le_t *peer,
const struct bt_le_adv_param *param,
struct bt_conn **conn);
__deprecated static inline
struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,
const struct bt_le_adv_param *param)
{
struct bt_conn *conn;
struct bt_le_adv_param adv_param = *param;
if (bt_conn_le_create_slave(peer, param, &conn)) {
adv_param.options |= (BT_LE_ADV_OPT_CONNECTABLE |
BT_LE_ADV_OPT_ONE_TIME);
adv_param.peer = peer;
if (!bt_le_adv_start(&adv_param, NULL, 0, NULL, 0)) {
return NULL;
}
return conn;
return bt_conn_lookup_addr_le(param->id, peer);
}
/** Security level. */
@ -622,9 +621,9 @@ struct bt_conn_cb {
* @ref bt_conn_disconnect or by the timeout in the host through
* @ref bt_conn_le_create_param timeout parameter, which defaults to
* :option:`CONFIG_BT_CREATE_CONN_TIMEOUT` seconds.
* - @p BT_HCI_ERR_ADV_TIMEOUT Directed advertiser started by @ref
* bt_conn_create_slave_le with high duty cycle timed out after 1.28
* seconds.
* - @p BT_HCI_ERR_ADV_TIMEOUT High duty cycle directed connectable
* advertiser started by @ref bt_le_adv_start or bt_le_ext_adv_start
* failed to be connected within the timeout.
*/
void (*connected)(struct bt_conn *conn, u8_t err);

View file

@ -123,6 +123,11 @@ enum {
#define BT_GAP_SID_INVALID 0xff
#define BT_GAP_NO_TIMEOUT 0x0000
/* The maximum allowed high duty cycle directed advertising timeout, 1.28
* seconds in 10 ms unit.
*/
#define BT_GAP_ADV_HIGH_DUTY_CYCLE_MAX_TIMEOUT 128
#ifdef __cplusplus
}
#endif

View file

@ -1088,12 +1088,6 @@ struct bt_hci_cp_le_set_ext_scan_rsp_data {
u8_t data[251];
} __packed;
/* If the advertising is high duty cycle connectable directed advertising, then
* Duration[i] shall be less than or equal to 1.28 seconds and shall not be
* equal to 0.
*/
#define BT_HCI_LE_EXT_ADV_DURATION_HI_DC_MAX 128
#define BT_HCI_OP_LE_SET_EXT_ADV_ENABLE BT_OP(BT_OGF_LE, 0x0039)
struct bt_hci_ext_adv_set {
u8_t handle;