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 <sys/util.h>
13 
14 #include <bluetooth/addr.h>
15 #include <bluetooth/crypto.h>
16 
create_random_addr(bt_addr_le_t * addr)17 static inline int create_random_addr(bt_addr_le_t *addr)
18 {
19 	addr->type = BT_ADDR_LE_RANDOM;
20 
21 	return bt_rand(addr->a.val, 6);
22 }
23 
bt_addr_le_create_nrpa(bt_addr_le_t * addr)24 int bt_addr_le_create_nrpa(bt_addr_le_t *addr)
25 {
26 	int err;
27 
28 	err = create_random_addr(addr);
29 	if (err) {
30 		return err;
31 	}
32 
33 	BT_ADDR_SET_NRPA(&addr->a);
34 
35 	return 0;
36 }
37 
bt_addr_le_create_static(bt_addr_le_t * addr)38 int bt_addr_le_create_static(bt_addr_le_t *addr)
39 {
40 	int err;
41 
42 	err = create_random_addr(addr);
43 	if (err) {
44 		return err;
45 	}
46 
47 	BT_ADDR_SET_STATIC(&addr->a);
48 
49 	return 0;
50 }
51 
bt_addr_from_str(const char * str,bt_addr_t * addr)52 int bt_addr_from_str(const char *str, bt_addr_t *addr)
53 {
54 	int i, j;
55 	uint8_t tmp;
56 
57 	if (strlen(str) != 17U) {
58 		return -EINVAL;
59 	}
60 
61 	for (i = 5, j = 1; *str != '\0'; str++, j++) {
62 		if (!(j % 3) && (*str != ':')) {
63 			return -EINVAL;
64 		} else if (*str == ':') {
65 			i--;
66 			continue;
67 		}
68 
69 		addr->val[i] = addr->val[i] << 4;
70 
71 		if (char2hex(*str, &tmp) < 0) {
72 			return -EINVAL;
73 		}
74 
75 		addr->val[i] |= tmp;
76 	}
77 
78 	return 0;
79 }
80 
bt_addr_le_from_str(const char * str,const char * type,bt_addr_le_t * addr)81 int bt_addr_le_from_str(const char *str, const char *type, bt_addr_le_t *addr)
82 {
83 	int err;
84 
85 	err = bt_addr_from_str(str, &addr->a);
86 	if (err < 0) {
87 		return err;
88 	}
89 
90 	if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
91 		addr->type = BT_ADDR_LE_PUBLIC;
92 	} else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
93 		addr->type = BT_ADDR_LE_RANDOM;
94 	} else if (!strcmp(type, "public-id") || !strcmp(type, "(public-id)")) {
95 		addr->type = BT_ADDR_LE_PUBLIC_ID;
96 	} else if (!strcmp(type, "random-id") || !strcmp(type, "(random-id)")) {
97 		addr->type = BT_ADDR_LE_RANDOM_ID;
98 	} else {
99 		return -EINVAL;
100 	}
101 
102 	return 0;
103 }
104