1 /*
2 * Copyright (c) 2017 Nordic Semiconductor ASA
3 * Copyright (c) 2015 Intel Corporation
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <errno.h>
9 #include <stdbool.h>
10 #include <string.h>
11
12 #include <zephyr/bluetooth/addr.h>
13 #include <zephyr/bluetooth/crypto.h>
14 #include <zephyr/sys/util.h>
15
16 #define ADDR_RESOLVED_BITMASK (0x02)
17
create_random_addr(bt_addr_le_t * addr)18 static inline int create_random_addr(bt_addr_le_t *addr)
19 {
20 addr->type = BT_ADDR_LE_RANDOM;
21
22 return bt_rand(addr->a.val, 6);
23 }
24
bt_addr_le_create_nrpa(bt_addr_le_t * addr)25 int bt_addr_le_create_nrpa(bt_addr_le_t *addr)
26 {
27 int err;
28
29 err = create_random_addr(addr);
30 if (err) {
31 return err;
32 }
33
34 BT_ADDR_SET_NRPA(&addr->a);
35
36 return 0;
37 }
38
bt_addr_le_create_static(bt_addr_le_t * addr)39 int bt_addr_le_create_static(bt_addr_le_t *addr)
40 {
41 int err;
42
43 err = create_random_addr(addr);
44 if (err) {
45 return err;
46 }
47
48 BT_ADDR_SET_STATIC(&addr->a);
49
50 return 0;
51 }
52
bt_addr_from_str(const char * str,bt_addr_t * addr)53 int bt_addr_from_str(const char *str, bt_addr_t *addr)
54 {
55 /* Parse a null-terminated string with a Bluetooth address in
56 * canonical "XX:XX:XX:XX:XX:XX" format.
57 */
58
59 const size_t len = strlen(str);
60
61 /* Verify length. */
62 if (len != BT_ADDR_STR_LEN - 1) {
63 return -EINVAL;
64 }
65
66 /* Verify that all the colons are present. */
67 for (size_t i = 2; i < len; i += 3) {
68 if (str[i] != ':') {
69 return -EINVAL;
70 }
71 }
72
73 /* Parse each octet as hex and populate `addr->val`. It must be
74 * reversed since `bt_addr_t` is in 'on-air' format.
75 */
76 for (size_t i = 0; i < ARRAY_SIZE(addr->val); i++) {
77 const size_t reverse_i = ARRAY_SIZE(addr->val) - 1 - i;
78
79 if (!hex2bin(&str[i * 3], 2, &addr->val[reverse_i], 1)) {
80 return -EINVAL;
81 }
82 }
83
84 return 0;
85 }
86
bt_addr_le_from_str(const char * str,const char * type,bt_addr_le_t * addr)87 int bt_addr_le_from_str(const char *str, const char *type, bt_addr_le_t *addr)
88 {
89 int err;
90
91 err = bt_addr_from_str(str, &addr->a);
92 if (err < 0) {
93 return err;
94 }
95
96 if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
97 addr->type = BT_ADDR_LE_PUBLIC;
98 } else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
99 addr->type = BT_ADDR_LE_RANDOM;
100 } else if (!strcmp(type, "public-id") || !strcmp(type, "(public-id)")) {
101 addr->type = BT_ADDR_LE_PUBLIC_ID;
102 } else if (!strcmp(type, "random-id") || !strcmp(type, "(random-id)")) {
103 addr->type = BT_ADDR_LE_RANDOM_ID;
104 } else {
105 return -EINVAL;
106 }
107
108 return 0;
109 }
110
bt_addr_le_copy_resolved(bt_addr_le_t * dst,const bt_addr_le_t * src)111 void bt_addr_le_copy_resolved(bt_addr_le_t *dst, const bt_addr_le_t *src)
112 {
113 bt_addr_le_copy(dst, src);
114 /* translate to "regular" address type */
115 dst->type &= ~ADDR_RESOLVED_BITMASK;
116 }
117
bt_addr_le_is_resolved(const bt_addr_le_t * addr)118 bool bt_addr_le_is_resolved(const bt_addr_le_t *addr)
119 {
120 return (addr->type & ADDR_RESOLVED_BITMASK) != 0;
121 }
122