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