1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <stdlib.h>
#include <string.h>
#include "btd.h"
bdaddr_t *
devinfo_laddr(struct bt_devinfo *info)
{
return &info->baa.bd_laddr;
}
bdaddr_t *
devinfo_raddr(struct bt_devinfo *info)
{
return &info->baa.bd_raddr;
}
int
devinfo_store(const struct bt_devinfo *info, void **data, size_t *datalen)
{
*datalen = sizeof(info->baa);
if (info->baa.bd_type == BTDEV_HID)
*datalen += info->baa.bd_hid.hid_dlen;
if ((*data = malloc(*datalen)) == NULL) {
log_warn("devinfo_store");
return -1;
}
memcpy(*data, &info->baa, sizeof(info->baa));
if (info->baa.bd_type == BTDEV_HID &&
info->baa.bd_hid.hid_dlen > 0)
memcpy((uint8_t *)*data + sizeof(info->baa),
info->baa.bd_hid.hid_desc,
info->baa.bd_hid.hid_dlen);
return 0;
}
int
devinfo_load(struct bt_devinfo *info, void *data, size_t datalen)
{
return devinfo_load_attach_args(&info->baa, data, datalen);
}
void
devinfo_unload(struct bt_devinfo *info)
{
return devinfo_unload_attach_args(&info->baa);
}
int
devinfo_load_attach_args(struct btdev_attach_args *baa, void *data,
size_t datalen)
{
if (datalen < sizeof(*baa)) {
log_warnx("devinfo data too short");
memset(baa, 0, sizeof(*baa));
return -1;
}
memcpy(baa, data, sizeof(*baa));
data = (struct btdev_attach_args *)data + 1;
datalen -= sizeof(*baa);
if (baa->bd_type == BTDEV_HID) {
uint16_t dlen = baa->bd_hid.hid_dlen;
void *desc = NULL;
if (datalen != dlen) {
log_warnx("bad devinfo data length (HID)");
return -1;
}
if (dlen > 0) {
if ((desc = malloc(dlen)) == NULL) {
log_warn("devinfo_load_attach_args");
return -1;
}
memcpy(desc, data, dlen);
}
baa->bd_hid.hid_desc = desc;
} else if (datalen > 0) {
log_warnx("devinfo data too long");
return -1;
}
return 0;
}
void
devinfo_unload_attach_args(struct btdev_attach_args *baa)
{
if (baa->bd_type == BTDEV_HID && baa->bd_hid.hid_desc != NULL) {
free(baa->bd_hid.hid_desc);
baa->bd_hid.hid_desc = NULL;
baa->bd_hid.hid_dlen = 0;
}
}
void
devinfo_dump(const struct bt_devinfo *info)
{
const struct btdev_attach_args *baa = &info->baa;
log_info("laddr %s", bt_ntoa(&baa->bd_laddr, NULL));
log_info("raddr %s", bt_ntoa(&baa->bd_raddr, NULL));
log_info("type %#x", baa->bd_type);
log_info("mode %d", baa->bd_mode);
}
|