Skip to content
Permalink
Browse files

Bluetooth: host: Move address string parsing to bluetooth API

Bluetooth address parsing has been duplicated across the different
sub-shell files. Also missing parsing of identity/resolved addresses.
Move parsing of string close to parsing to string for a symmetrical API

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
  • Loading branch information...
joerchan authored and carlescufi committed May 29, 2019
1 parent 7a93e94 commit 0ac83180fda2ca965c303053d434db88a09322da
@@ -683,10 +683,10 @@ static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
strcpy(type, "random");
break;
case BT_ADDR_LE_PUBLIC_ID:
strcpy(type, "public id");
strcpy(type, "public-id");
break;
case BT_ADDR_LE_RANDOM_ID:
strcpy(type, "random id");
strcpy(type, "random-id");
break;
default:
snprintk(type, sizeof(type), "0x%02x", addr->type);
@@ -698,6 +698,27 @@ static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
addr->a.val[2], addr->a.val[1], addr->a.val[0], type);
}

/**
* @brief Convert Bluetooth address from string to binary.
*
* @param[in] str The string representation of a Bluetooth address.
* @param[out] addr Address of buffer to store the Bluetooth address
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_addr_from_str(const char *str, bt_addr_t *addr);

/**
* @brief Convert LE Bluetooth address from string to binary.
*
* @param[in] str The string representation of an LE Bluetooth address.
* @param[in] type The string representation of the LE Bluetooth address type.
* @param[out] addr Address of buffer to store the LE Bluetooth address
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_addr_le_from_str(const char *str, const char *type, bt_addr_le_t *addr);

/** @brief Enable/disable set controller in discoverable state.
*
* Allows make local controller to listen on INQUIRY SCAN channel and responds
@@ -429,6 +429,59 @@ static int set_random_address(const bt_addr_t *addr)
return 0;
}

int bt_addr_from_str(const char *str, bt_addr_t *addr)
{
int i, j;
u8_t tmp;

if (strlen(str) != 17U) {
return -EINVAL;
}

for (i = 5, j = 1; *str != '\0'; str++, j++) {
if (!(j % 3) && (*str != ':')) {
return -EINVAL;
} else if (*str == ':') {
i--;
continue;
}

addr->val[i] = addr->val[i] << 4;

if (char2hex(*str, &tmp) < 0) {
return -EINVAL;
}

addr->val[i] |= tmp;
}

return 0;
}

int bt_addr_le_from_str(const char *str, const char *type, bt_addr_le_t *addr)
{
int err;

err = bt_addr_from_str(str, &addr->a);
if (err < 0) {
return err;
}

if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
addr->type = BT_ADDR_LE_PUBLIC;
} else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
addr->type = BT_ADDR_LE_RANDOM;
} else if (!strcmp(type, "public-id") || !strcmp(type, "(public-id)")) {
addr->type = BT_ADDR_LE_PUBLIC_ID;
} else if (!strcmp(type, "random-id") || !strcmp(type, "(random-id)")) {
addr->type = BT_ADDR_LE_RANDOM_ID;
} else {
return -EINVAL;
}

return 0;
}

#if defined(CONFIG_BT_PRIVACY)
/* this function sets new RPA only if current one is no longer valid */
static int le_set_private_addr(u8_t id)
@@ -83,7 +83,7 @@ static int cmd_connect(const struct shell *shell, size_t argc, char *argv[])
bt_addr_t addr;
int err;

err = str2bt_addr(argv[1], &addr);
err = bt_addr_from_str(argv[1], &addr);
if (err) {
shell_print(shell, "Invalid peer address (err %d)", err);
return -ENOEXEC;
@@ -230,60 +230,6 @@ static struct bt_conn_cb conn_callbacks = {
};
#endif /* CONFIG_BT_CONN */

static int hexstr2array(const char *str, u8_t *array, u8_t size)
{
int i, j;
u8_t tmp;

if (strlen(str) != ((size * 2U) + (size - 1))) {
return -EINVAL;
}

for (i = size - 1, j = 1; *str != '\0'; str++, j++) {
if (!(j % 3) && (*str != ':')) {
return -EINVAL;
} else if (*str == ':') {
i--;
continue;
}

array[i] = array[i] << 4;

if (char2hex(str, &tmp) < 0) {
return -EINVAL;
}

array[i] |= tmp;
}

return 0;
}

int str2bt_addr(const char *str, bt_addr_t *addr)
{
return hexstr2array(str, addr->val, 6);
}

static int str2bt_addr_le(const char *str, const char *type, bt_addr_le_t *addr)
{
int err;

err = str2bt_addr(str, &addr->a);
if (err < 0) {
return err;
}

if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
addr->type = BT_ADDR_LE_PUBLIC;
} else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
addr->type = BT_ADDR_LE_RANDOM;
} else {
return -EINVAL;
}

return 0;
}

static void bt_ready(int err)
{
if (err) {
@@ -377,7 +323,7 @@ static int cmd_id_create(const struct shell *shell, size_t argc, char *argv[])
int err;

if (argc > 1) {
err = str2bt_addr_le(argv[1], "random", &addr);
err = bt_addr_le_from_str(argv[1], "random", &addr);
if (err) {
shell_error(shell, "Invalid address");
}
@@ -411,7 +357,7 @@ static int cmd_id_reset(const struct shell *shell, size_t argc, char *argv[])
id = strtol(argv[1], NULL, 10);

if (argc > 2) {
err = str2bt_addr_le(argv[2], "random", &addr);
err = bt_addr_le_from_str(argv[2], "random", &addr);
if (err) {
shell_print(shell, "Invalid address");
return err;
@@ -677,7 +623,7 @@ static int cmd_directed_adv(const struct shell *shell,
struct bt_conn *conn;
struct bt_le_adv_param *param = BT_LE_ADV_CONN_DIR;

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_error(shell, "Invalid peer address (err %d)", err);
return err;
@@ -720,7 +666,7 @@ static int cmd_connect_le(const struct shell *shell, size_t argc, char *argv[])
bt_addr_le_t addr;
struct bt_conn *conn;

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_error(shell, "Invalid peer address (err %d)", err);
return err;
@@ -747,7 +693,7 @@ static int cmd_auto_conn(const struct shell *shell, size_t argc, char *argv[])
bt_addr_le_t addr;
int err;

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_error(shell, "Invalid peer address (err %d)", err);
return err;
@@ -783,7 +729,7 @@ static int cmd_disconnect(const struct shell *shell, size_t argc, char *argv[])
return SHELL_CMD_HELP_PRINTED;
}

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_error(shell, "Invalid peer address (err %d)",
err);
@@ -815,7 +761,7 @@ static int cmd_select(const struct shell *shell, size_t argc, char *argv[])
bt_addr_le_t addr;
int err;

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_error(shell, "Invalid peer address (err %d)", err);
return err;
@@ -863,11 +809,11 @@ static int cmd_chan_map(const struct shell *shell, size_t argc, char *argv[])
u8_t chan_map[5] = {};
int err;

err = hexstr2array(argv[1], chan_map, 5);
if (err) {
if (hex2bin(argv[1], strlen(argv[1]), chan_map, 5) == 0) {
shell_error(shell, "Invalid channel map");
return -ENOEXEC;
}
sys_mem_swap(chan_map, 5);

err = bt_le_set_chan_map(chan_map);
if (err) {
@@ -921,13 +867,13 @@ static int cmd_clear(const struct shell *shell, size_t argc, char *argv[])
if (argc < 3) {
#if defined(CONFIG_BT_BREDR)
addr.type = BT_ADDR_LE_PUBLIC;
err = str2bt_addr(argv[1], &addr.a);
err = bt_addr_from_str(argv[1], &addr.a);
#else
shell_print(shell, "Both address and address type needed");
return -ENOEXEC;
#endif
} else {
err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
}

if (err) {
@@ -1312,7 +1258,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds,
SHELL_CMD_ARG(conn-update, NULL, "<min> <max> <latency> <timeout>",
cmd_conn_update, 5, 0),
#if defined(CONFIG_BT_CENTRAL)
SHELL_CMD_ARG(channel-map, NULL, "<channel-map: XX:XX:XX:XX:XX> (36-0)",
SHELL_CMD_ARG(channel-map, NULL, "<channel-map: XXXXXXXXXX> (36-0)",
cmd_chan_map, 2, 1),
#endif /* CONFIG_BT_CENTRAL */
SHELL_CMD_ARG(oob, NULL, NULL, cmd_oob, 1, 0),
@@ -16,7 +16,6 @@
extern const struct shell *ctx_shell;
extern struct bt_conn *default_conn;

int str2bt_addr(const char *str, bt_addr_t *addr);
void conn_addr_str(struct bt_conn *conn, char *addr, size_t len);

#endif /* __BT_H */
@@ -25,43 +25,6 @@ LOG_MODULE_REGISTER(net_bt_shell, CONFIG_NET_L2_BT_LOG_LEVEL);
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>

static int str2bt_addr_le(const char *str, const char *type, bt_addr_le_t *addr)
{
int i, j;
u8_t tmp;

if (strlen(str) != 17) {
return -EINVAL;
}

for (i = 5, j = 1; *str != '\0'; str++, j++) {
if (!(j % 3) && (*str != ':')) {
return -EINVAL;
} else if (*str == ':') {
i--;
continue;
}

addr->a.val[i] = addr->a.val[i] << 4;

if (char2hex(str, &tmp) < 0) {
return -EINVAL;
}

addr->a.val[i] |= tmp;
}

if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
addr->type = BT_ADDR_LE_PUBLIC;
} else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
addr->type = BT_ADDR_LE_RANDOM;
} else {
return -EINVAL;
}

return 0;
}

static int shell_cmd_connect(const struct shell *shell,
size_t argc, char *argv[])
{
@@ -74,7 +37,7 @@ static int shell_cmd_connect(const struct shell *shell,
return -ENOEXEC;
}

err = str2bt_addr_le(argv[1], argv[2], &addr);
err = bt_addr_le_from_str(argv[1], argv[2], &addr);
if (err) {
shell_fprintf(shell, SHELL_WARNING,
"Invalid peer address (err %d)\n", err);

0 comments on commit 0ac8318

Please sign in to comment.
You can’t perform that action at this time.