Skip to content

Commit

Permalink
Bluetooth: host: Avoid use of array compound literals in API
Browse files Browse the repository at this point in the history
Attempt to fix C++ error: taking address of temporary array.

According to GCC documentation:
  In C++, a compound literal designates a temporary object that only
  lives until the end of its full-expression.

Finishing with this recommendation:
  As an optimization, G++ sometimes gives array compound literals
  longer lifetimes: when the array either appears outside a function
  or has a const-qualified type.
  But it is probably safest just to avoid the use of array compound
  literals in C++ code.

Fix the issue by introducing INIT macros as an alternative, and use
these in the inline functions to avoid the use of array compound
literals in Bluetooth headers.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
  • Loading branch information
joerchan authored and jhedberg committed May 2, 2020
1 parent 45e6921 commit 78a6cdb
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 39 deletions.
66 changes: 46 additions & 20 deletions include/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ struct bt_data {
/** @brief Helper to declare elements of bt_data arrays
*
* This macro is mainly for creating an array of struct bt_data
* elements which is then passed to bt_le_adv_start().
* elements which is then passed to e.g. @ref bt_le_adv_start().
*
* @param _type Type of advertising data field
* @param _data Pointer to the data field payload
Expand All @@ -293,7 +293,7 @@ struct bt_data {
/** @brief Helper to declare elements of bt_data arrays
*
* This macro is mainly for creating an array of struct bt_data
* elements which is then passed to bt_le_adv_start().
* elements which is then passed to e.g. @ref bt_le_adv_start().
*
* @param _type Type of advertising data field
* @param _bytes Variable number of single-byte parameters
Expand Down Expand Up @@ -495,6 +495,25 @@ struct bt_le_adv_param {
const bt_addr_le_t *peer;
};

/** @brief Initialize advertising parameters
*
* @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_INIT(_options, _int_min, _int_max, _peer) \
{ \
.id = BT_ID_DEFAULT, \
.sid = 0, \
.secondary_max_skip = 0, \
.options = (_options), \
.interval_min = (_int_min), \
.interval_max = (_int_max), \
.peer = (_peer), \
}

/** @brief Helper to declare advertising parameters inline
*
* @param _options Advertising Options
Expand All @@ -504,15 +523,9 @@ struct bt_le_adv_param {
* address of peer for directed advertising.
*/
#define BT_LE_ADV_PARAM(_options, _int_min, _int_max, _peer) \
((struct bt_le_adv_param[]) { { \
.id = BT_ID_DEFAULT, \
.sid = 0, \
.secondary_max_skip = 0, \
.options = (_options), \
.interval_min = (_int_min), \
.interval_max = (_int_max), \
.peer = (_peer), \
} })
((struct bt_le_adv_param[]) { \
BT_LE_ADV_PARAM_INIT(_options, _int_min, _int_max, _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,\
Expand Down Expand Up @@ -878,6 +891,25 @@ struct bt_le_scan_cb {
sys_snode_t node;
};

/** @brief Initialize scan parameters
*
* @param _type Scan Type, BT_LE_SCAN_TYPE_ACTIVE or
* BT_LE_SCAN_TYPE_PASSIVE.
* @param _options Scan options
* @param _interval Scan Interval (N * 0.625 ms)
* @param _window Scan Window (N * 0.625 ms)
*/
#define BT_LE_SCAN_PARAM_INIT(_type, _options, _interval, _window) \
{ \
.type = (_type), \
.options = (_options), \
.interval = (_interval), \
.window = (_window), \
.timeout = 0, \
.interval_coded = 0, \
.window_coded = 0, \
}

/** @brief Helper to declare scan parameters inline
*
* @param _type Scan Type, BT_LE_SCAN_TYPE_ACTIVE or
Expand All @@ -887,15 +919,9 @@ struct bt_le_scan_cb {
* @param _window Scan Window (N * 0.625 ms)
*/
#define BT_LE_SCAN_PARAM(_type, _options, _interval, _window) \
((struct bt_le_scan_param[]) { { \
.type = (_type), \
.options = (_options), \
.interval = (_interval), \
.window = (_window), \
.timeout = 0, \
.interval_coded = 0, \
.window_coded = 0, \
} })
((struct bt_le_scan_param[]) { \
BT_LE_SCAN_PARAM_INIT(_type, _options, _interval, _window) \
})

/** Helper macro to enable active scanning to discover new devices. */
#define BT_LE_SCAN_ACTIVE BT_LE_SCAN_PARAM(BT_LE_SCAN_TYPE_ACTIVE, \
Expand Down
79 changes: 60 additions & 19 deletions include/bluetooth/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ struct bt_le_conn_param {
u16_t timeout;
};

/** @brief Initialize connection parameters
*
* @param int_min Minimum Connection Interval (N * 1.25 ms)
* @param int_max Maximum Connection Interval (N * 1.25 ms)
* @param lat Connection Latency
* @param to Supervision Timeout (N * 10 ms)
*/
#define BT_LE_CONN_PARAM_INIT(int_min, int_max, lat, to) \
{ \
.interval_min = (int_min), \
.interval_max = (int_max), \
.latency = (lat), \
.timeout = (to), \
}

/** Helper to declare connection parameters inline
*
* @param int_min Minimum Connection Interval (N * 1.25 ms)
Expand All @@ -47,12 +62,9 @@ struct bt_le_conn_param {
* @param to Supervision Timeout (N * 10 ms)
*/
#define BT_LE_CONN_PARAM(int_min, int_max, lat, to) \
((struct bt_le_conn_param[]) { { \
.interval_min = (int_min), \
.interval_max = (int_max), \
.latency = (lat), \
.timeout = (to), \
} })
((struct bt_le_conn_param[]) { \
BT_LE_CONN_PARAM_INIT(int_min, int_max, lat, to) \
})

/** Default LE connection parameters:
* Connection Interval: 30-50 ms
Expand Down Expand Up @@ -334,21 +346,32 @@ struct bt_conn_le_create_param {
u16_t timeout;
};

/** @brief Initialize create connection parameters
*
* @param _options Create connection options.
* @param _interval Create connection scan interval (N * 0.625 ms).
* @param _window Create connection scan window (N * 0.625 ms).
*/
#define BT_CONN_LE_CREATE_PARAM_INIT(_options, _interval, _window) \
{ \
.options = (_options), \
.interval = (_interval), \
.window = (_window), \
.interval_coded = 0, \
.window_coded = 0, \
.timeout = 0, \
}

/** Helper to declare create connection parameters inline
*
* @param _options Create connection options.
* @param _interval Create connection scan interval (N * 0.625 ms).
* @param _window Create connection scan window (N * 0.625 ms).
*/
#define BT_CONN_LE_CREATE_PARAM(_options, _interval, _window) \
((struct bt_conn_le_create_param[]) { { \
.options = (_options), \
.interval = (_interval), \
.window = (_window), \
.interval_coded = 0, \
.window_coded = 0, \
.timeout = 0, \
} })
((struct bt_conn_le_create_param[]) { \
BT_CONN_LE_CREATE_PARAM_INIT(_options, _interval, _window) \
})

/** Default LE create connection parameters.
* Scan continuously by setting scan interval equal to scan window.
Expand Down Expand Up @@ -393,8 +416,12 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
const struct bt_le_conn_param *conn_param)
{
struct bt_conn *conn;
struct bt_conn_le_create_param param = BT_CONN_LE_CREATE_PARAM_INIT(
BT_LE_CONN_OPT_NONE,
BT_GAP_SCAN_FAST_INTERVAL,
BT_GAP_SCAN_FAST_INTERVAL);

if (bt_conn_le_create(peer, BT_CONN_LE_CREATE_CONN, conn_param,
if (bt_conn_le_create(peer, &param, conn_param,
&conn)) {
return NULL;
}
Expand Down Expand Up @@ -423,7 +450,12 @@ int bt_conn_le_create_auto(const struct bt_conn_le_create_param *create_param,
__deprecated static inline
int bt_conn_create_auto_le(const struct bt_le_conn_param *conn_param)
{
return bt_conn_le_create_auto(BT_CONN_LE_CREATE_CONN_AUTO, conn_param);
struct bt_conn_le_create_param param = BT_CONN_LE_CREATE_PARAM_INIT(
BT_LE_CONN_OPT_NONE,
BT_GAP_SCAN_FAST_INTERVAL,
BT_GAP_SCAN_FAST_WINDOW);

return bt_conn_le_create_auto(&param, conn_param);
}

/** @brief Stop automatic connect creation.
Expand Down Expand Up @@ -1151,14 +1183,23 @@ struct bt_br_conn_param {
bool allow_role_switch;
};

/** @brief Initialize BR/EDR connection parameters
*
* @param role_switch True if role switch is allowed
*/
#define BT_BR_CONN_PARAM_INIT(role_switch) \
{ \
.allow_role_switch = (role_switch), \
}

/** Helper to declare BR/EDR connection parameters inline
*
* @param role_switch True if role switch is allowed
*/
#define BT_BR_CONN_PARAM(role_switch) \
((struct bt_br_conn_param[]) { { \
.allow_role_switch = (role_switch), \
} })
((struct bt_br_conn_param[]) { \
BT_BR_CONN_PARAM_INIT(role_switch) \
})

/** Default BR/EDR connection parameters:
* Role switch allowed
Expand Down

0 comments on commit 78a6cdb

Please sign in to comment.