123 lines
2.4 KiB
C
123 lines
2.4 KiB
C
/*
|
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
|
* Copyright (c) 2015 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <zephyr/sys/util.h>
|
|
|
|
#include <zephyr/bluetooth/addr.h>
|
|
#include <zephyr/bluetooth/crypto.h>
|
|
|
|
#define ADDR_RESOLVED_BITMASK (0x02)
|
|
|
|
static inline int create_random_addr(bt_addr_le_t *addr)
|
|
{
|
|
addr->type = BT_ADDR_LE_RANDOM;
|
|
|
|
return bt_rand(addr->a.val, 6);
|
|
}
|
|
|
|
int bt_addr_le_create_nrpa(bt_addr_le_t *addr)
|
|
{
|
|
int err;
|
|
|
|
err = create_random_addr(addr);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
BT_ADDR_SET_NRPA(&addr->a);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_addr_le_create_static(bt_addr_le_t *addr)
|
|
{
|
|
int err;
|
|
|
|
err = create_random_addr(addr);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
BT_ADDR_SET_STATIC(&addr->a);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_addr_from_str(const char *str, bt_addr_t *addr)
|
|
{
|
|
/* Parse a null-terminated string with a Bluetooth address in
|
|
* canonical "XX:XX:XX:XX:XX:XX" format.
|
|
*/
|
|
|
|
const size_t len = strlen(str);
|
|
|
|
/* Verify length. */
|
|
if (len != BT_ADDR_STR_LEN - 1) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Verify that all the colons are present. */
|
|
for (size_t i = 2; i < len; i += 3) {
|
|
if (str[i] != ':') {
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
/* Parse each octet as hex and populate `addr->val`. It must be
|
|
* reversed since `bt_addr_t` is in 'on-air' format.
|
|
*/
|
|
for (size_t i = 0; i < ARRAY_SIZE(addr->val); i++) {
|
|
const size_t reverse_i = ARRAY_SIZE(addr->val) - 1 - i;
|
|
|
|
if (!hex2bin(&str[i * 3], 2, &addr->val[reverse_i], 1)) {
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void bt_addr_le_copy_resolved(bt_addr_le_t *dst, const bt_addr_le_t *src)
|
|
{
|
|
bt_addr_le_copy(dst, src);
|
|
/* translate to "regular" address type */
|
|
dst->type &= ~ADDR_RESOLVED_BITMASK;
|
|
}
|
|
|
|
bool bt_addr_le_is_resolved(const bt_addr_le_t *addr)
|
|
{
|
|
return (addr->type & ADDR_RESOLVED_BITMASK) != 0;
|
|
}
|