device.c revision 9b953c8757093b51eb86e6593d514e9839fd8d7d
1dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann/* 2dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 3dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * BlueZ - Bluetooth protocol stack for Linux 4dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 5f1659f19cfb3ef0c0c09b5f5b7e2b06d90d079abMarcel Holtmann * Copyright (C) 2006-2007 Nokia Corporation 6e823c15e43a6f924779e466d434c51157002d9eeMarcel Holtmann * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> 7dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 8dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 9dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * This program is free software; you can redistribute it and/or modify 10dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * it under the terms of the GNU General Public License as published by 11dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * the Free Software Foundation; either version 2 of the License, or 12dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * (at your option) any later version. 13dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 14dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * This program is distributed in the hope that it will be useful, 15dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 16dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * GNU General Public License for more details. 18dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 19dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * You should have received a copy of the GNU General Public License 20dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * along with this program; if not, write to the Free Software 21dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 23dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann */ 24dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 25dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#ifdef HAVE_CONFIG_H 26dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <config.h> 27dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#endif 28dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 29dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdio.h> 30dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <stdlib.h> 315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#include <unistd.h> 326a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include <sys/stat.h> 331af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg#include <errno.h> 34dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 35dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h> 36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h> 37dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h> 385d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h> 395d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h> 40dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h> 4286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4315ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h> 4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h" 466a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h" 47dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 48506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "hcid.h" 492c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h" 5086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h" 51da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h" 524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h" 537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h" 543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h" 55fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h" 563d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h" 57506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "storage.h" 5886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 59c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz#define DEFAULT_XML_BUF_SIZE 1024 605d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER 2 617ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz#define DISCOVERY_TIMER 2 62dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 63e3afaa0b7ff373d89fd3fa257110a34df7495df7Luiz Augusto von Dentzstruct btd_driver_data { 64b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver; 65b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode void *priv; 66b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode}; 67b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 68555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device { 69cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t bdaddr; 70ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gchar *path; 7118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter; 72ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode GSList *uuids; 73b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode GSList *drivers; /* List of driver_data */ 74ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gboolean temporary; 75ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode struct agent *agent; 76ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint disconn_timer; 77ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode int discov_active; /* Service discovery active */ 78ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode char *discov_requestor; /* discovery requestor unique name */ 79ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint discov_listener; 80013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg guint discov_timer; 81ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 82ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode /* For Secure Simple Pairing */ 83ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t cap; 84ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t auth; 85e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 86e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg gboolean connected; 87e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 88e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg /* Whether were creating a security mode 3 connection */ 89e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg gboolean secmode3; 90548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 91548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *tmp_records; 92ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode}; 93ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req { 953d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusConnection *conn; 963d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusMessage *msg; 97555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 980dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *match_uuids; 990dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_added; 1000dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_removed; 101681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_list_t *records; 102d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann int search_uuid; 1033d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}; 1043d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 105d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = { 1060dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP_UUID, 1071c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PNP_INFO_SVCLASS_ID, 1080dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg PUBLIC_BROWSE_GROUP, 109d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 0 110d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann}; 111d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 112c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL; 113c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 114e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data) 11586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 116555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 1172f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1182f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct agent *agent = adapter_get_agent(adapter); 119e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 120fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite if (device->agent) 121fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite agent_destroy(device->agent, FALSE); 122f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1232f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz if (agent && agent_is_busy(agent, device)) 1242f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz agent_cancel(agent); 1252f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz 126ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_foreach(device->uuids, (GFunc) g_free, NULL); 127ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_free(device->uuids); 128f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1295d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (device->disconn_timer) 1305d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_source_remove(device->disconn_timer); 1315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 132401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz if (device->discov_timer) 133401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz g_source_remove(device->discov_timer); 134401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz 13586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 13686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 13786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 13886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 139555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device) 140769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{ 14118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 142cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char filename[PATH_MAX + 1], *str; 143cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 144769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz gboolean ret; 145cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1462a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 147cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 148cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 149cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 150769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 151769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, 152cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode srcaddr, "linkkeys"); 153cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str = textfile_caseget(filename, dstaddr); 154769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz ret = str ? TRUE : FALSE; 155769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(str); 156769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 157769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz return ret; 158769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz} 159769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 160e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn, 161e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *user_data) 1622c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 163555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 16418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 1654e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessage *reply; 1664e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter iter; 1674e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter dict; 168cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 169cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char name[248], srcaddr[18], dstaddr[18]; 1708a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi char **uuids; 1712a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode const char *ptr; 1724e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_bool_t boolean; 1734e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz uint32_t class; 174769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz int i; 175769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz GSList *l; 176bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode struct active_conn_info *dev; 1774e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 178cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 179cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 1804e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz reply = dbus_message_new_method_return(msg); 1814e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz if (!reply) 182e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return NULL; 1834e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1844e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 1854e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1864e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 1874e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 1884e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 1894e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 1904e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1914e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Address */ 192cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ptr = dstaddr; 1931262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr); 1944e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1954e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Name */ 196506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = NULL; 197506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi memset(name, 0, sizeof(name)); 1982a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 199cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 2008a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi 201cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_device_name(srcaddr, dstaddr, name) == 0) { 202506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 2031262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr); 2044e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2054e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 206afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann /* Alias (fallback to name or address) */ 207afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) { 208afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (!ptr) { 209afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann g_strdelimit(dstaddr, ":", '-'); 210afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann ptr = dstaddr; 211afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } 212afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } else 213506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 214506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 215506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (ptr) 2161262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); 217506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 2184e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Class */ 219cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_remote_class(&src, &device->bdaddr, &class) == 0) { 220e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann const char *icon = class_to_icon(class); 221e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 2221262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class); 223e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 224e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann if (icon) 2251262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Icon", 226e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann DBUS_TYPE_STRING, &icon); 2274e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2284e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2294e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Paired */ 230769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz boolean = device_is_paired(device); 2311262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean); 2324e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2334e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Trusted */ 234cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode boolean = read_trust(&src, dstaddr, GLOBAL_TRUST); 2351262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean); 2364e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2374e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Connected */ 238cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr); 239bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (dev) 2404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz boolean = TRUE; 2414e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz else 2424e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz boolean = FALSE; 2434e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2441262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &boolean); 2454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 246ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi /* UUIDs */ 247769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 248769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 249769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids[i] = l->data; 2503a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i); 251769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(uuids); 2524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 25374fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz /* Adapter */ 2548a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi ptr = adapter_get_path(adapter); 2551262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr); 25674fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz 2574e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 2584e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 259e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return reply; 2602c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 2612c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 262e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, 2637fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *alias, void *data) 2647fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 265555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 26618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 267cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 268cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 269506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi int err; 2707fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 271cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 272cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 273cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 2742a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 275cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode /* Remove alias if empty string */ 276cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode err = write_device_alias(srcaddr, dstaddr, 277506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi g_str_equal(alias, "") ? NULL : alias); 278506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (err < 0) 279e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 280e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".Failed", 281506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi strerror(-err)); 2827fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 283c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 284c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Alias", 285c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_STRING, &alias); 2867fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 287e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 2887fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 2897fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 290e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, 2917fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value, void *data) 2927fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 293555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 29418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 295cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 296cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 2972a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 2987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 299cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 300cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 301cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3022a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 303cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value); 3047fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 305c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 306c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Trusted", 307c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_BOOLEAN, &value); 3087fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 309e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3107fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3117fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 312e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg) 313e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{ 314e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 315e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".InvalidArguments", 316e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi "Invalid arguments in method call"); 317e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi} 318e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 319e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn, 320e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *data) 3212c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 3227fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter iter; 3237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter sub; 3247fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *property; 3257fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3267fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (!dbus_message_iter_init(msg, &iter)) 327e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3287fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3297fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 330e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3317fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3327fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&iter, &property); 3337fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_next(&iter); 3347fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3357fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) 336e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_recurse(&iter, &sub); 3387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (g_str_equal("Trusted", property)) { 3407fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value; 3417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 343e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3447fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &value); 3457fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3467fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_trust(conn, msg, value, data); 3477fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } else if (g_str_equal("Alias", property)) { 348506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi const char *alias; 3497fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3507fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) 351e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &alias); 3537fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3547fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_alias(conn, msg, alias, data); 3557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } 3567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 357e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3582c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 3592c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 3601f5107e65f9786bd6b84ecfb4d84691e9b34529aMarcel Holtmannstatic void discover_services_req_exit(DBusConnection *conn, void *user_data) 361342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{ 362555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 36318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 364cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 3652a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 3662a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 367342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 368342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz debug("DiscoverDevices requestor exited"); 369342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 370cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_cancel_discovery(&src, &device->bdaddr); 371342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz} 372342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 37394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn, 37494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 37594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 376555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 37794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann const char *pattern; 378342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz int err; 379342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 380342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (device->discov_active) 381342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", 382342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discover in progress"); 38394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 38494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 38594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBUS_TYPE_INVALID) == FALSE) 386342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 38794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 388a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (strlen(pattern) == 0) { 38969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, NULL, FALSE); 390342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 391342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 392342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } else { 393040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi uuid_t uuid; 394040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi 395040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi if (bt_string2uuid(&uuid, pattern) < 0) 396342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return invalid_args(msg); 397a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann 3984b1914903cb105acf843b84833e81d5470133879Johan Hedberg sdp_uuid128_to_uuid(&uuid); 3994b1914903cb105acf843b84833e81d5470133879Johan Hedberg 40069adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, &uuid, FALSE); 401342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 402342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 403342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } 40494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 40594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return NULL; 406342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 407342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail: 408342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", 409342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discovery Failed"); 41094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 41194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 41294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn, 41394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 41494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 415555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 41618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 417cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4182a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4192a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 42019b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann 421342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_active) 422342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 423342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 424342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "No pending discovery"); 425342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 426342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz /* only the discover requestor can cancel the inquiry process */ 427342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_requestor || 428342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz strcmp(device->discov_requestor, dbus_message_get_sender(msg))) 429342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 430342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".NotAuthorized", 431342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Not Authorized"); 432342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 433cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (bt_cancel_discovery(&src, &device->bdaddr) < 0) 434289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz return g_dbus_create_error(msg, 435289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 436289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz "No pending discover"); 43794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 43894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 43994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 44094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 4415d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data) 4425d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{ 443555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 4445d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi struct active_conn_info *ci; 4455d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_cp cp; 4465d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi int dd; 447661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode uint16_t dev_id = adapter_get_dev_id(device->adapter); 4485d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4495d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = 0; 4505d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 451cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ci = adapter_search_active_conn_by_bdaddr(device->adapter, 452cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode &device->bdaddr); 453bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode 454bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (!ci) 4555d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 4565d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 457661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode dd = hci_open_dev(dev_id); 4585d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (dd < 0) 4595d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi goto fail; 4605d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4615d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi memset(&cp, 0, sizeof(cp)); 4625d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.handle = htobs(ci->handle); 4635d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.reason = HCI_OE_USER_ENDED_CONNECTION; 4645d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4655d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, 4665d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DISCONNECT_CP_SIZE, &cp); 4675d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4685d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi close(dd); 4695d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4705d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail: 4715d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 4725d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi} 4735d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 47494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *disconnect(DBusConnection *conn, 47594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 47694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 477555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 478bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode struct active_conn_info *dev; 4795d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 480cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode dev = adapter_search_active_conn_by_bdaddr(device->adapter, 481cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode &device->bdaddr); 482bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode 483bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (!dev) 4845d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return g_dbus_create_error(msg, 4855d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi ERROR_INTERFACE ".NotConnected", 4865d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi "Device is not connected"); 4875d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4885d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_dbus_emit_signal(conn, device->path, 4895d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DEVICE_INTERFACE, "DisconnectRequested", 4905d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DBUS_TYPE_INVALID); 4915d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4925d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, 4935d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_timeout, device); 49494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 49594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 49694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 49794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 498e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = { 499e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "GetProperties", "", "a{sv}", get_properties }, 500e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "SetProperty", "sv", "", set_property }, 501e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann { "DiscoverServices", "s", "a{us}", discover_services, 50294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann G_DBUS_METHOD_FLAG_ASYNC}, 50394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "CancelDiscovery", "", "", cancel_discover }, 504e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "Disconnect", "", "", disconnect }, 50594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5062c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5072c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 508e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = { 50994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "PropertyChanged", "sv" }, 51094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "DisconnectRequested", "" }, 51194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5122c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5132c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 514e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberggboolean device_get_connected(struct btd_device *device) 515e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 516e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg return device->connected; 517e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 518e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 519013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergvoid device_set_connected(DBusConnection *conn, struct btd_device *device, 520013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg gboolean connected) 521013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 522e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->connected = connected; 523e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 524c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, 525c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg "Connected", DBUS_TYPE_BOOLEAN, &connected); 526e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 527e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg if (connected && device->secmode3) { 528e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg struct btd_adapter *adapter = device_get_adapter(device); 529e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg bdaddr_t sba; 530e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 531e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg adapter_get_address(adapter, &sba); 532e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 533e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = FALSE; 534e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 535e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0); 536e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg } 537e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 538e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 539e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedbergvoid device_set_secmode3_conn(struct btd_device *device, gboolean enable) 540e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 541e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = enable; 542013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 543013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 54418614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, 54536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const gchar *address) 54686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 547ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite gchar *address_up; 548555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 549139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann const gchar *adapter_path = adapter_get_path(adapter); 55086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 551555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode device = g_try_malloc0(sizeof(struct btd_device)); 55286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 55386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 55486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 555ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite address_up = g_ascii_strup(address, -1); 556139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up); 55786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 558ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite g_free(address_up); 55986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 56086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 56186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 562e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, 563e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device_methods, device_signals, NULL, 564e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device, device_free) == FALSE) { 56586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 56686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 56786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 568da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 569cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str2ba(address, &device->bdaddr); 570da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 571da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 5726bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi return device; 57386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 57486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 575555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_remove(DBusConnection *conn, struct btd_device *device) 57675add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{ 5776061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann GSList *list; 5786061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann struct btd_device_driver *driver; 579f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann gchar *path = g_strdup(device->path); 580f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 581f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann debug("Removing device %s", path); 582f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 5836061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann for (list = device->drivers; list; list = list->next) { 584b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 585b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver = driver_data->driver; 5866061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 587e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 588b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 5896061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann } 5906061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 591f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); 59275add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi 593f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_free(path); 59486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 595ff296428a08dee619db1cc702146faefa91087faCidorvan Leite 596555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address) 597ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{ 598cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char addr[18]; 599cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 600cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, addr); 601cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return strcasecmp(addr, address); 602ff296428a08dee619db1cc702146faefa91087faCidorvan Leite} 6033d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 6043870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedbergstatic gboolean record_has_uuid(const sdp_record_t *rec, 6053870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg const char *profile_uuid) 606f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 6073870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg sdp_list_t *pat; 608f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6093870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg for (pat = rec->pattern; pat != NULL; pat = pat->next) { 610f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz char *uuid; 6113870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg int ret; 612f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6133870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg uuid = bt_uuid2string(pat->data); 614f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!uuid) 615f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 616f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6173870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg ret = strcasecmp(uuid, profile_uuid); 618f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6193870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg g_free(uuid); 6203870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg 6213870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg if (ret == 0) 6223870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return TRUE; 623f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 624f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6253870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return FALSE; 626f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 627f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 628f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_pattern(struct btd_device *device, 629878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg const char *match_uuid, 630f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 631f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 632f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *l, *uuids = NULL; 633f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 634f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (l = profiles; l; l = l->next) { 635878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg char *profile_uuid = l->data; 636f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz const sdp_record_t *rec; 6373bb7c1527ce3ec67127200b54a8fbc01a196ebadJohan Hedberg 638878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg rec = btd_device_get_record(device, profile_uuid); 639f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!rec) 640f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 641f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 642a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg if (record_has_uuid(rec, match_uuid)) 643878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg uuids = g_slist_append(uuids, profile_uuid); 644cdfe8a8246013031f55c647092e41adbb29ace81Johan Hedberg } 645f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 646f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 647f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 648f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 649f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_driver(struct btd_device *device, 650f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_device_driver *driver, 651f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 652f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{ 6536061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann const char **uuid; 654f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *uuids = NULL; 655f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 656f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 657f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *match; 658f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 6599b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz /* skip duplicated uuids */ 6609b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz if (g_slist_find_custom(uuids, *uuid, 6619b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz (GCompareFunc) strcasecmp)) 6629b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz continue; 6639b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz 664f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match profile driver */ 665f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = g_slist_find_custom(profiles, *uuid, 666f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz (GCompareFunc) strcasecmp); 667f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (match) { 668f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 669f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 670f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 671f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 672f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match pattern driver */ 673f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = device_match_pattern(device, *uuid, profiles); 674a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg for (; match; match = match->next) 675f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 676f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 677f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 678f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 679f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 680f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 681f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzvoid device_probe_drivers(struct btd_device *device, GSList *profiles) 682f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 683f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *list; 684f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann int err; 685f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 686f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann debug("Probe drivers for %s", device->path); 687f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 688c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz for (list = device_drivers; list; list = list->next) { 689e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann struct btd_device_driver *driver = list->data; 690f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *probe_uuids; 691f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_driver_data *driver_data; 692f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 693f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz probe_uuids = device_match_driver(device, driver, profiles); 6944b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 695f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!probe_uuids) 696f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 697081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 698f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data = g_new0(struct btd_driver_data, 1); 699b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 700f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz err = driver->probe(device, probe_uuids); 701f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (err < 0) { 702f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz error("probe failed with driver %s for device %s", 703f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver->name, device->path); 704b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 705f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_free(driver_data); 706548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg g_slist_free(probe_uuids); 707f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 708f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 709f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 710f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data->driver = driver; 711f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz device->drivers = g_slist_append(device->drivers, driver_data); 712f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_slist_free(probe_uuids); 713f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 71436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 715f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (list = profiles; list; list = list->next) { 716c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann GSList *l = g_slist_find_custom(device->uuids, list->data, 717548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg (GCompareFunc) strcasecmp); 718c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann if (l) 719c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann continue; 720c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann 72136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_insert_sorted(device->uuids, 7220e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_strdup(list->data), 7230e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg (GCompareFunc) strcasecmp); 724548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 725548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 726548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) { 727548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(device->tmp_records, 728548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg (sdp_free_func_t) sdp_record_free); 729548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = NULL; 730c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann } 73136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 73236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 733548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedbergvoid device_remove_drivers(struct btd_device *device, GSList *uuids) 73436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 73518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 736352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg GSList *list, *next; 737cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 7382a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 739548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *records; 7402a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 7412a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 742cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 743cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 74436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 745548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = read_records(&src, &device->bdaddr); 746548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 74736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz debug("Remove drivers for %s", device->path); 74836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 749352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg for (list = device->drivers; list; list = next) { 750b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 751b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver = driver_data->driver; 75236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const char **uuid; 75336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 754352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg next = list->next; 755352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg 75636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 7579b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz sdp_record_t *rec; 75836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 7599b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 7609b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz (GCompareFunc) strcasecmp)) 76136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 76236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 763548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg debug("UUID %s was removed from device %s", dstaddr); 764548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 765e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 76636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->drivers = g_slist_remove(device->drivers, 767b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data); 768b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 769b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 770b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 771548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 772548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg rec = find_record_in_list(records, *uuid); 7739b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!rec) 7749b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz continue; 7759b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz 776cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode delete_record(srcaddr, dstaddr, rec->handle); 777548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 778548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = sdp_list_remove(records, rec); 779548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_record_free(rec); 78036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 78136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 78236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 783548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (records) 784548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(records, (sdp_free_func_t) sdp_record_free); 785548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 78636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = uuids; list; list = list->next) 78736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_remove(device->uuids, list->data); 788f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann} 789f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 790bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle, 791bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann const char *record) 792bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{ 793bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann DBusMessageIter entry; 794bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 795bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, 796bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann NULL, &entry); 797bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 798bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); 799bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 800bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); 801bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 802bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_close_container(dict, &entry); 803bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann} 804bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 805730775d1226a30c37ff551955f093ddfcd18e600Claudio Takahasistatic void append_and_grow_string(void *data, const char *str) 806c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{ 807c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz sdp_buf_t *buff = data; 808c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz int len; 809c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 810c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz len = strlen(str); 811c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 812c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) { 813c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = malloc(DEFAULT_XML_BUF_SIZE); 814c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) 815c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 816c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = DEFAULT_XML_BUF_SIZE; 817c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 818c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 819c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow string */ 820c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz while (buff->buf_size < (buff->data_size + len + 1)) { 821c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz void *tmp; 822c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz uint32_t new_size; 823c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 824c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow buffer by a factor of 2 */ 825c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz new_size = (buff->buf_size << 1); 826c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 827c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz tmp = realloc(buff->data, new_size); 828c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!tmp) 829c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 830c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 831c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = tmp; 832c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = new_size; 833c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 834c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 835c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Include the NULL character */ 836c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz memcpy(buff->data + buff->data_size, str, len + 1); 837c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data_size += len; 838c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz} 839c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 8401e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs) 8411e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{ 8421e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessage *reply; 8431e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessageIter iter, dict; 8441e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_list_t *seq; 8451e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8461e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 8471e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!reply) 8481e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz return; 8491e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8501e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 8511e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8521e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 8531e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 8541e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING 8551e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 8561e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8571e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 8581e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 8591e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_buf_t result; 8601e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8611e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!rec) 8621e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz break; 8631e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8641e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz memset(&result, 0, sizeof(sdp_buf_t)); 8651e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8661e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz convert_sdp_record_to_xml(rec, &result, 8671e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz append_and_grow_string); 8681e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8691e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (result.data) { 8701e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz const char *val = (char *) result.data; 8711e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz iter_append_record(&dict, rec->handle, val); 8721e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz free(result.data); 8731e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 8741e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 8751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 8761e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 8771e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 878a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 8791e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz} 8801e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 88117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void services_changed(struct btd_device *device) 8823d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 883533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg DBusConnection *conn = get_dbus_connection(); 8843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz char **uuids; 8853d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz GSList *l; 88636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz int i; 8873d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 88836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 88936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 89036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids[i] = l->data; 89136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 89258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg emit_array_property_changed(conn, device->path, DEVICE_INTERFACE, 89358f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg "UUIDs", DBUS_TYPE_STRING, &uuids); 89436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 89536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuids); 89636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 89736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 8988b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b) 8998b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{ 9008b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r1 = a; 9018b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r2 = b; 9028b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 9038b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg return r1->handle - r2->handle; 9048b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg} 9058b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 90636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs) 90736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 908555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 90918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 91036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *seq; 911cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 9122a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 9132a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 9142a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 915cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 916cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 9173d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 91836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 9193d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 92036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *svcclass = NULL; 9210dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg gchar *profile_uuid; 92236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *l; 9233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 9243d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!rec) 9253d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz break; 9263d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 92736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (sdp_get_service_classes(rec, &svcclass) < 0) 92836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 92936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 93036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Extract the first element and skip the remainning */ 9310dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid = bt_uuid2string(svcclass->data); 9320dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!profile_uuid) { 933aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 93436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 935aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg } 93636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 9370dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!strcasecmp(profile_uuid, PNP_UUID)) { 938fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann uint16_t source, vendor, product, version; 939e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse sdp_data_t *pdlist; 940e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 941fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE); 942fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann source = pdlist ? pdlist->val.uint16 : 0x0000; 943fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann 944e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); 945e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse vendor = pdlist ? pdlist->val.uint16 : 0x0000; 946e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 947e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); 948e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse product = pdlist ? pdlist->val.uint16 : 0x0000; 949e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 950e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); 951e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version = pdlist ? pdlist->val.uint16 : 0x0000; 952e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 953fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann if (source || vendor || product || version) 954fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann store_device_id(srcaddr, dstaddr, source, 955fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann vendor, product, version); 956e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse } 957e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 95837a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg /* Check for duplicates */ 959981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg if (sdp_list_find(req->records, rec, rec_cmp)) { 9600dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 961aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 96237a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg continue; 963981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg } 96437a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 965cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode store_record(srcaddr, dstaddr, rec); 96637a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 967681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Copy record */ 968204180c7dc2e20b9b701275a3fefb52707720f54Luiz Augusto von Dentz req->records = sdp_list_append(req->records, sdp_copy_record(rec)); 969681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 9700dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l = g_slist_find_custom(device->uuids, profile_uuid, 971c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann (GCompareFunc) strcmp); 97236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!l) 9730dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_added = 9740dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_append(req->profiles_added, 9750dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid); 97636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz else { 9770dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = 9780dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_remove(req->profiles_removed, 9790dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l->data); 9800dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 9813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 9823d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 98336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_free(svcclass, free); 9843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 98536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 98636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 98717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void store_profiles(struct btd_device *device) 98836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 98918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 990cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 99136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz char *str; 9923d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 9932a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 9943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 99536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!device->uuids) { 996cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, ""); 99736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz return; 99836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 99936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 100036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz str = bt_list2string(device->uuids); 1001cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, str); 100236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(str); 100336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 100436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1005a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentzstatic void browse_req_free(struct browse_req *req) 1006a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz{ 1007a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz struct btd_device *device = req->device; 1008a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1009a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_active = 0; 1010a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1011a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (device->discov_requestor) { 1012a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_dbus_remove_watch(req->conn, device->discov_listener); 1013a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_listener = 0; 1014a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(device->discov_requestor); 1015a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_requestor = NULL; 1016a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz } 1017a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1018a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->msg) 1019a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_message_unref(req->msg); 1020a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->conn) 1021a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_connection_unref(req->conn); 10220dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL); 10230dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_added); 10240dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_removed); 1025a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->records) 1026a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); 1027a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(req); 1028a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz} 1029a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1030da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data) 103136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 103236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz struct browse_req *req = user_data; 1033555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 103436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DBusMessage *reply; 10352a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 1036681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (err < 0) { 1037681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz error("%s: error updating services: %s (%d)", 1038681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device->path, strerror(-err), -err); 103936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1040681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 104136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 104236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz update_services(req, recs); 104336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 10440dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!req->profiles_added && !req->profiles_removed) { 1045e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz debug("%s: No service update", device->path); 104636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1047681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 10482efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 1049548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records && req->records) { 1050548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(device->tmp_records, (sdp_free_func_t) sdp_record_free); 1051548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = req->records; 1052548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg req->records = NULL; 1053548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 1054548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 105536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Probe matching drivers for services added */ 10560dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_added) 10570dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_probe_drivers(device, req->profiles_added); 10582efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 105936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Remove drivers for services removed */ 10600dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_removed) 10610dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_remove_drivers(device, req->profiles_removed); 10622efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 106336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Propagate services changes */ 106417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(req->device); 1065f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 10667b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed: 1067681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Store the device's profiles in the filesystem */ 106817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg store_profiles(device); 1069681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 10702ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg if (!req->msg) 10712ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg goto cleanup; 10722ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg 1073438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, 1074438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz "DiscoverServices")) { 1075438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz discover_device_reply(req, req->records); 1076438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz goto cleanup; 1077438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz } 1078438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 10793d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz /* Reply create device request */ 10803d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 10813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!reply) 10821e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz goto cleanup; 10833d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 10843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, 1085a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann DBUS_TYPE_INVALID); 10863d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1087a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 10883d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 10891e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup: 1090a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1091da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1092da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1093da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data) 1094da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1095da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct browse_req *req = user_data; 1096da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_device *device = req->device; 1097da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1098cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1099da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz uuid_t uuid; 1100da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 11010dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg /* If we have a valid response and req->search_uuid == 2, then 11020dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP UUID & PNP searching was successful -- we are done */ 11030dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (err < 0 || (req->search_uuid == 2 && req->records)) 1104da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz goto done; 1105da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1106da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz update_services(req, recs); 1107da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1108da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz adapter_get_address(adapter, &src); 1109da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1110da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz /* Search for mandatory uuids */ 11117d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (uuid_list[req->search_uuid]) { 11127d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1113c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann bt_search_service(&src, &device->bdaddr, &uuid, 1114c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann browse_cb, user_data, NULL); 1115da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz return; 1116da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz } 1117da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1118da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone: 1119da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz search_cb(recs, err, user_data); 1120da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1121da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 112269adac833c5633714b84bf840c75aa814193b8a6Johan Hedbergstatic void init_browse(struct browse_req *req, gboolean reverse) 1123da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1124da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz GSList *l; 1125da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 112669adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg /* If we are doing reverse-SDP don't try to detect removed profiles 112769adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * since some devices hide their service records while they are 112869adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * connected 112969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg */ 113069adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg if (reverse) 113169adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg return; 113269adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg 1133da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz for (l = req->device->uuids; l; l = l->next) 11340dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = g_slist_append(req->profiles_removed, 1135da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz l->data); 11363d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 11373d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1138555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn, 113969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg DBusMessage *msg, uuid_t *search, gboolean reverse) 11403d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 114118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 11423d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz struct browse_req *req; 1143cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1144d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann uuid_t uuid; 1145da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz bt_callback_t cb; 1146a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz int err; 11472a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 11481af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg if (device->discov_active) 11491af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg return -EBUSY; 11501af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg 11512a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 11523d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 11533d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req = g_new0(struct browse_req, 1); 1154438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 1155438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz req->conn = conn ? dbus_connection_ref(conn) : get_dbus_connection(); 1156438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 11573d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->device = device; 11583d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1159a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (search) { 1160040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi memcpy(&uuid, search, sizeof(uuid_t)); 1161da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = search_cb; 1162a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } else { 11637d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 116469adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg init_browse(req, reverse); 1165da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = browse_cb; 1166a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } 1167d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 116895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_active = 1; 1169d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg 1170d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg if (msg) { 11715c6426eff87049c9f8e49877f650772840907239Luiz Augusto von Dentz req->msg = dbus_message_ref(msg); 1172d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); 1173d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg /* Track the request owner to cancel it 1174d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg * automatically if the owner exits */ 1175d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg device->discov_listener = g_dbus_add_disconnect_watch(conn, 117695e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz dbus_message_get_sender(msg), 117795e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz discover_services_req_exit, 117895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device, NULL); 1179d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg } 118095e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz 1181a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz err = bt_search_service(&src, &device->bdaddr, 1182a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz &uuid, cb, req, NULL); 1183a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (err < 0) 1184a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1185a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1186a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz return err; 11873d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 118824cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann 118918614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device) 1190dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{ 1191dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode if (!device) 1192dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return NULL; 1193dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 1194dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return device->adapter; 1195dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode} 1196dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 119719ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr) 1198aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{ 1199cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bacpy(bdaddr, &device->bdaddr); 1200aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode} 1201aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode 1202555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device) 120346fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{ 120446fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode if (!device) 120546fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return NULL; 120646fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 120746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return device->path; 120846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode} 120946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 1210555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device) 1211a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{ 1212a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode if (!device) 1213a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return NULL; 1214a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1215a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return device->agent; 1216a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode} 1217a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1218555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent) 1219d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{ 1220d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode if (!device) 1221d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode return; 1222d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1223d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode device->agent = agent; 1224d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode} 1225d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1226555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device) 12279f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{ 12289f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode return device->discov_active ? TRUE : FALSE; 12299f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode} 12309f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode 1231555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device) 1232f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{ 1233f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode return device->temporary; 1234f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode} 1235f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode 1236555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary) 1237595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{ 1238595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode if (!device) 1239595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode return; 1240595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1241595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode device->temporary = temporary; 1242595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode} 1243595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1244555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap) 1245491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{ 1246491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode if (!device) 1247491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode return; 1248491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1249491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode device->cap = cap; 1250491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode} 1251491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1252555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth) 125329227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{ 125429227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode if (!device) 125529227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode return; 125629227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 125729227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode device->auth = auth; 125829227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode} 125929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 1260555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device) 12612203f153c53189ec1c30df99b717e035681196e6Alok Barsode{ 12622203f153c53189ec1c30df99b717e035681196e6Alok Barsode return device->auth; 12632203f153c53189ec1c30df99b717e035681196e6Alok Barsode} 1264c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1265013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergstatic gboolean start_discovery(gpointer user_data) 1266013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 1267013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg struct btd_device *device = user_data; 1268013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 126969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg device_browse(device, NULL, NULL, NULL, TRUE); 1270013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1271013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg device->discov_timer = 0; 1272013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1273013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg return FALSE; 1274013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 1275013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1276e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedbergint device_set_paired(DBusConnection *conn, struct btd_device *device, 127768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg struct bonding_request_info *bonding) 1278013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 127968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg dbus_bool_t paired = TRUE; 128068b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 128168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg device_set_temporary(device, FALSE); 128268b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 1283c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired", 1284c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_BOOLEAN, &paired); 128568b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 128668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg /* If we were initiators start service discovery immediately. 128768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * However if the other end was the initator wait a few seconds 128868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * before SDP. This is due to potential IOP issues if the other 128968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * end starts doing SDP at the same time as us */ 1290e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (bonding) { 1291e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg /* If we are initiators remove any discovery timer and just 1292e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg * start discovering services directly */ 1293e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (device->discov_timer) { 1294e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg g_source_remove(device->discov_timer); 1295e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg device->discov_timer = 0; 1296e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1297e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 1298e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg return device_browse(device, bonding->conn, bonding->msg, 129969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg NULL, FALSE); 1300e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1301e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 1302e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg /* If we are not initiators and there is no currently active discovery 1303e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg * or discovery timer, set the discovery timer */ 1304e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (!device->discov_active && !device->discov_timer) 13057ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz device->discov_timer = g_timeout_add_seconds(DISCOVERY_TIMER, 130668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg start_discovery, 130768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg device); 1308e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 1309e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg return 0; 1310013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 1311013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 131217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergvoid btd_device_add_uuid(struct btd_device *device, const char *uuid) 131317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg{ 131417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg GSList *uuid_list; 131517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg char *new_uuid; 131617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 131717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg if (g_slist_find_custom(device->uuids, uuid, 131817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg (GCompareFunc) strcasecmp)) 131917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg return; 132017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 132117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg new_uuid = g_strdup(uuid); 132217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg uuid_list = g_slist_append(NULL, new_uuid); 132317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 132417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg device_probe_drivers(device, uuid_list); 132517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 13260e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_free(new_uuid); 132717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg g_slist_free(uuid_list); 132817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 13290e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg store_profiles(device); 133017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(device); 133117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg} 133217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 1333548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedbergconst sdp_record_t *btd_device_get_record(struct btd_device *device, 1334548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg const char *uuid) 1335548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg{ 1336548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg bdaddr_t src; 1337548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1338548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) 1339548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 1340548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1341548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg adapter_get_address(device->adapter, &src); 1342548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1343548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = read_records(&src, &device->bdaddr); 1344548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (!device->tmp_records) 1345548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return NULL; 1346548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1347548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 1348548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg} 1349548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1350c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver) 1351c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 1352c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_append(device_drivers, driver); 1353c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1354c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz return 0; 1355c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 1356c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1357c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver) 1358c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 1359c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_remove(device_drivers, driver); 1360c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 1361