3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2012 Texas Instruments, Inc.
6 * Copyright (C) 2015 Google Inc.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "lib/bluetooth.h"
37 #include "src/plugin.h"
38 #include "src/adapter.h"
39 #include "src/device.h"
40 #include "src/profile.h"
41 #include "src/service.h"
42 #include "attrib/gattrib.h"
43 #include "src/shared/util.h"
44 #include "src/shared/queue.h"
45 #include "src/shared/gatt-db.h"
46 #include "src/shared/gatt-client.h"
47 #include "attrib/att.h"
52 static void read_pnpid_cb(bool success, uint8_t att_ecode, const uint8_t *value,
53 uint16_t length, void *user_data)
55 struct btd_device *device = user_data;
58 error("Error reading PNP_ID value: %s",
59 att_ecode2str(att_ecode));
63 if (length < PNP_ID_SIZE) {
64 error("Error reading PNP_ID: Invalid pdu length received");
68 btd_device_set_pnpid(device, value[0], get_le16(&value[1]),
69 get_le16(&value[3]), get_le16(&value[5]));
72 static void handle_pnpid(struct btd_device *device, uint16_t value_handle)
74 struct bt_gatt_client *client = btd_device_get_gatt_client(device);
76 if (!bt_gatt_client_read_value(client, value_handle,
77 read_pnpid_cb, device, NULL))
78 DBG("Failed to send request to read pnpid");
81 static void handle_characteristic(struct gatt_db_attribute *attr,
84 struct btd_device *device = user_data;
85 uint16_t value_handle;
86 bt_uuid_t uuid, pnpid_uuid;
88 bt_string_to_uuid(&pnpid_uuid, PNPID_UUID);
90 if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
92 error("Failed to obtain characteristic data");
96 if (bt_uuid_cmp(&pnpid_uuid, &uuid) == 0)
97 handle_pnpid(device, value_handle);
99 char uuid_str[MAX_LEN_UUID_STR];
101 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
102 DBG("Unsupported characteristic: %s", uuid_str);
106 static void foreach_deviceinfo_service(struct gatt_db_attribute *attr,
109 struct btd_device *device = user_data;
111 gatt_db_service_foreach_char(attr, handle_characteristic, device);
114 static int deviceinfo_driver_probe(struct btd_service *service)
119 static void deviceinfo_driver_remove(struct btd_service *service)
124 static int deviceinfo_driver_accept(struct btd_service *service)
126 struct btd_device *device = btd_service_get_device(service);
127 struct gatt_db *db = btd_device_get_gatt_db(device);
129 bt_uuid_t deviceinfo_uuid;
131 ba2str(device_get_address(device), addr);
132 DBG("deviceinfo profile accept (%s)", addr);
134 /* Handle the device info service */
135 bt_string_to_uuid(&deviceinfo_uuid, DEVICE_INFORMATION_UUID);
136 gatt_db_foreach_service(db, &deviceinfo_uuid,
137 foreach_deviceinfo_service, device);
142 static struct btd_profile deviceinfo_profile = {
143 .name = "deviceinfo",
144 .remote_uuid = DEVICE_INFORMATION_UUID,
146 .device_probe = deviceinfo_driver_probe,
147 .device_remove = deviceinfo_driver_remove,
148 .accept = deviceinfo_driver_accept,
151 static int deviceinfo_init(void)
153 return btd_profile_register(&deviceinfo_profile);
156 static void deviceinfo_exit(void)
158 btd_profile_unregister(&deviceinfo_profile);
161 BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
162 deviceinfo_init, deviceinfo_exit)