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