File: deviceinfo.c

package info (click to toggle)
bluez 5.83-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 25,664 kB
  • sloc: ansic: 471,418; python: 4,751; sh: 4,580; makefile: 1,042; xml: 126
file content (158 lines) | stat: -rw-r--r-- 3,710 bytes parent folder | download | duplicates (2)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2012 Texas Instruments, Inc.
 *  Copyright (C) 2015 Google Inc.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdbool.h>
#include <errno.h>

#include <glib.h>

#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/uuid.h"

#include "src/plugin.h"
#include "src/adapter.h"
#include "src/device.h"
#include "src/profile.h"
#include "src/service.h"
#include "attrib/gattrib.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/shared/gatt-db.h"
#include "src/shared/gatt-client.h"
#include "attrib/att.h"
#include "src/log.h"

#define PNP_ID_SIZE	7

static void read_pnpid_cb(bool success, uint8_t att_ecode, const uint8_t *value,
					uint16_t length, void *user_data)
{
	struct btd_device *device = user_data;

	if (!success) {
		error("Error reading PNP_ID value: %s",
						att_ecode2str(att_ecode));
		return;
	}

	if (length < PNP_ID_SIZE) {
		error("Error reading PNP_ID: Invalid pdu length received");
		return;
	}

	btd_device_set_pnpid(device, value[0], get_le16(&value[1]),
				get_le16(&value[3]), get_le16(&value[5]));
}

static void handle_pnpid(struct btd_device *device, uint16_t value_handle)
{
	struct bt_gatt_client *client = btd_device_get_gatt_client(device);

	if (!bt_gatt_client_read_value(client, value_handle,
						read_pnpid_cb, device, NULL))
		DBG("Failed to send request to read pnpid");
}

static void handle_characteristic(struct gatt_db_attribute *attr,
								void *user_data)
{
	struct btd_device *device = user_data;
	uint16_t value_handle;
	bt_uuid_t uuid, pnpid_uuid;

	bt_string_to_uuid(&pnpid_uuid, PNPID_UUID);

	if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
								NULL, &uuid)) {
		error("Failed to obtain characteristic data");
		return;
	}

	if (bt_uuid_cmp(&pnpid_uuid, &uuid) == 0)
		handle_pnpid(device, value_handle);
	else {
		char uuid_str[MAX_LEN_UUID_STR];

		bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
		DBG("Unsupported characteristic: %s", uuid_str);
	}
}

static void foreach_deviceinfo_service(struct gatt_db_attribute *attr,
								void *user_data)
{
	struct btd_device *device = user_data;

	gatt_db_service_foreach_char(attr, handle_characteristic, device);
}

static int deviceinfo_probe(struct btd_service *service)
{
	return 0;
}

static void deviceinfo_remove(struct btd_service *service)
{
}


static int deviceinfo_accept(struct btd_service *service)
{
	struct btd_device *device = btd_service_get_device(service);
	struct gatt_db *db = btd_device_get_gatt_db(device);
	char addr[18];
	bt_uuid_t deviceinfo_uuid;

	ba2str(device_get_address(device), addr);
	DBG("deviceinfo profile accept (%s)", addr);

	/* Handle the device info service */
	bt_string_to_uuid(&deviceinfo_uuid, DEVICE_INFORMATION_UUID);
	gatt_db_foreach_service(db, &deviceinfo_uuid,
					foreach_deviceinfo_service, device);

	btd_service_connecting_complete(service, 0);

	return 0;
}

static int deviceinfo_disconnect(struct btd_service *service)
{
	btd_service_disconnecting_complete(service, 0);

	return 0;
}

static struct btd_profile deviceinfo_profile = {
	.name		= "deviceinfo",
	.remote_uuid	= DEVICE_INFORMATION_UUID,
	.device_probe	= deviceinfo_probe,
	.device_remove	= deviceinfo_remove,
	.accept		= deviceinfo_accept,
	.disconnect	= deviceinfo_disconnect,
};

static int deviceinfo_init(void)
{
	return btd_profile_register(&deviceinfo_profile);
}

static void deviceinfo_exit(void)
{
	btd_profile_unregister(&deviceinfo_profile);
}

BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
					deviceinfo_init, deviceinfo_exit)