device.c revision e2a5786af8c8278eeeb0bedccda32c7422e9a2b7
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> 33dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 34dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h> 35dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h> 36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h> 375d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h> 385d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h> 39dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h> 4186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4215ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h> 4386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h" 456a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h" 46dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 47506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "hcid.h" 482c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h" 4986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h" 50da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h" 514e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h" 527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h" 533d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h" 54fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h" 553d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h" 56506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "storage.h" 5786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 58c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz#define DEFAULT_XML_BUF_SIZE 1024 595d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER 2 60dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 61e3afaa0b7ff373d89fd3fa257110a34df7495df7Luiz Augusto von Dentzstruct btd_driver_data { 62b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver; 63b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode void *priv; 64b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode}; 65b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 66555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device { 67cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t bdaddr; 68ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gchar *path; 6918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter; 70ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode GSList *uuids; 71b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode GSList *drivers; /* List of driver_data */ 72ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gboolean temporary; 73ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode struct agent *agent; 74ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint disconn_timer; 75ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode int discov_active; /* Service discovery active */ 76ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode char *discov_requestor; /* discovery requestor unique name */ 77ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint discov_listener; 78ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 79ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode /* For Secure Simple Pairing */ 80ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t cap; 81ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t auth; 82ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode}; 83ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req { 853d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusConnection *conn; 863d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusMessage *msg; 87555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 8858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz GSList *uuids; 8936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *uuids_added; 9036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *uuids_removed; 91681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_list_t *records; 92d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann int search_uuid; 933d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}; 943d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 95d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = { 96d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann PUBLIC_BROWSE_GROUP, 971c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PNP_INFO_SVCLASS_ID, 98f22b20c3d40bd7571944af6a4946f756dc39f812Marcel Holtmann HID_SVCLASS_ID, 99d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann GENERIC_AUDIO_SVCLASS_ID, 100d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann ADVANCED_AUDIO_SVCLASS_ID, 101d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann AV_REMOTE_SVCLASS_ID, 1021c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PANU_SVCLASS_ID, 1031c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz GN_SVCLASS_ID, 1041c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz NAP_SVCLASS_ID, 1051c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz SERIAL_PORT_SVCLASS_ID, 106d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 0 107d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann}; 108d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 109c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL; 110c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 111e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data) 11286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 113555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 1142f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1152f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct agent *agent = adapter_get_agent(adapter); 116e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 117fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite if (device->agent) 118fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite agent_destroy(device->agent, FALSE); 119f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1202f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz if (agent && agent_is_busy(agent, device)) 1212f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz agent_cancel(agent); 1222f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz 123ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_foreach(device->uuids, (GFunc) g_free, NULL); 124ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_free(device->uuids); 125f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1265d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (device->disconn_timer) 1275d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_source_remove(device->disconn_timer); 1285d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 12986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 13086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 13186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 13286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 133555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device) 134769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{ 13518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 136cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char filename[PATH_MAX + 1], *str; 137cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 138769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz gboolean ret; 139cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1402a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 141cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 142cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 143cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 144769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 145769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, 146cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode srcaddr, "linkkeys"); 147cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str = textfile_caseget(filename, dstaddr); 148769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz ret = str ? TRUE : FALSE; 149769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(str); 150769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 151769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz return ret; 152769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz} 153769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 154e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn, 155e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *user_data) 1562c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 157555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 15818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 1594e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessage *reply; 1604e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter iter; 1614e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter dict; 162cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 163cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char name[248], srcaddr[18], dstaddr[18]; 1648a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi char **uuids; 1652a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode const char *ptr; 1664e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_bool_t boolean; 1674e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz uint32_t class; 168769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz int i; 169769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz GSList *l; 170bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode struct active_conn_info *dev; 1714e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 172cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 173cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 1744e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz reply = dbus_message_new_method_return(msg); 1754e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz if (!reply) 176e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return NULL; 1774e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1784e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 1794e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1804e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 1814e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 1824e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 1834e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 1844e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1854e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Address */ 186cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ptr = dstaddr; 1874e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Address", DBUS_TYPE_STRING, 188cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode &ptr); 1894e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 1904e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Name */ 191506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = NULL; 192506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi memset(name, 0, sizeof(name)); 1932a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 194cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 1958a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi 196cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_device_name(srcaddr, dstaddr, name) == 0) { 197506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 1984e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Name", 199506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi DBUS_TYPE_STRING, &ptr); 2004e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2014e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 202cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) > 0) 203506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 204506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 205506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi /* Alias: use Name if Alias doesn't exist */ 206506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (ptr) 207506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi dbus_message_iter_append_dict_entry(&dict, "Alias", 208506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi DBUS_TYPE_STRING, &ptr); 209506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 2104e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Class */ 211cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_remote_class(&src, &device->bdaddr, &class) == 0) { 2124e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Class", 2134e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_UINT32, &class); 2144e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2154e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2164e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Paired */ 217769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz boolean = device_is_paired(device); 2184e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Paired", 2194e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &boolean); 2204e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2214e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Trusted */ 222cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode boolean = read_trust(&src, dstaddr, GLOBAL_TRUST); 2234e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Trusted", 2244e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &boolean); 2254e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2264e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Connected */ 227cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr); 228bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (dev) 2294e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz boolean = TRUE; 2304e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz else 2314e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz boolean = FALSE; 2324e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2334e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Connected", 2344e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &boolean); 2354e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 236ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi /* UUIDs */ 237769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 238769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 239769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids[i] = l->data; 2408afa46e246f1598ebfac26725606823cee2dd0ecLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "UUIDs", 241769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz DBUS_TYPE_ARRAY, &uuids); 242769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(uuids); 2434e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 24474fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz /* Adapter */ 2458a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi ptr = adapter_get_path(adapter); 24674fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz dbus_message_iter_append_dict_entry(&dict, "Adapter", 2478a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi DBUS_TYPE_OBJECT_PATH, &ptr); 24874fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz 2494e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 2504e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 251e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return reply; 2522c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 2532c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 254e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, 2557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *alias, void *data) 2567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 257555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 25818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 259cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 260cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 261506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi int err; 2627fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 263cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 264cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 265cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 2662a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 267cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode /* Remove alias if empty string */ 268cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode err = write_device_alias(srcaddr, dstaddr, 269506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi g_str_equal(alias, "") ? NULL : alias); 270506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (err < 0) 271e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 272e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".Failed", 273506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi strerror(-err)); 2747fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 2757fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), 2767fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DEVICE_INTERFACE, "Alias", 277506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi DBUS_TYPE_STRING, &alias); 2787fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 279e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 2807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 2817fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 282e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, 2837fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value, void *data) 2847fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 285555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 28618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 287cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 288cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 2892a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 2907fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 291cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 292cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 293cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 2942a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 295cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value); 2967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 2977fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_connection_emit_property_changed(conn, dbus_message_get_path(msg), 2987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DEVICE_INTERFACE, "Trusted", 2997fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &value); 3007fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 301e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3027fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3037fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 304e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg) 305e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{ 306e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 307e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".InvalidArguments", 308e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi "Invalid arguments in method call"); 309e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi} 310e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 311e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn, 312e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *data) 3132c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 3147fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter iter; 3157fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter sub; 3167fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *property; 3177fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3187fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (!dbus_message_iter_init(msg, &iter)) 319e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3207fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3217fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 322e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3247fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&iter, &property); 3257fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_next(&iter); 3267fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3277fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) 328e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3297fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_recurse(&iter, &sub); 3307fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3317fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (g_str_equal("Trusted", property)) { 3327fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value; 3337fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3347fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 335e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3367fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &value); 3377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_trust(conn, msg, value, data); 3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } else if (g_str_equal("Alias", property)) { 340506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi const char *alias; 3417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) 343e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3447fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &alias); 3457fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3467fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_alias(conn, msg, alias, data); 3477fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } 3487fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 349e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3502c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 3512c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 352342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzstatic void discover_services_req_exit(void *user_data) 353342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{ 354555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 35518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 356cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 3572a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 3582a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 359342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 360342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz debug("DiscoverDevices requestor exited"); 361342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 362cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_cancel_discovery(&src, &device->bdaddr); 363342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz} 364342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 36594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn, 36694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 36794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 368555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 36994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann const char *pattern; 370342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz int err; 371342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 372342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (device->discov_active) 373342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", 374342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discover in progress"); 37594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 37694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 37794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBUS_TYPE_INVALID) == FALSE) 378342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 37994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 380a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (strlen(pattern) == 0) { 381040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi err = device_browse(device, conn, msg, NULL); 382342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 383342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 384342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } else { 385040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi uuid_t uuid; 386040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi 387040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi if (bt_string2uuid(&uuid, pattern) < 0) 388342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return invalid_args(msg); 389a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann 390040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi err = device_browse(device, conn, msg, &uuid); 391342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 392342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 393342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } 39494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 39594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return NULL; 396342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 397342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail: 398342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", 399342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discovery Failed"); 40094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 40194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 40294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn, 40394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 40494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 405555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 40618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 407cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4082a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4092a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 41019b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann 411342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_active) 412342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 413342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 414342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "No pending discovery"); 415342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 416342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz /* only the discover requestor can cancel the inquiry process */ 417342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_requestor || 418342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz strcmp(device->discov_requestor, dbus_message_get_sender(msg))) 419342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 420342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".NotAuthorized", 421342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Not Authorized"); 422342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 423cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (bt_cancel_discovery(&src, &device->bdaddr) < 0) 424289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz return g_dbus_create_error(msg, 425289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 426289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz "No pending discover"); 42794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 42894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 42994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 43094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 4315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data) 4325d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{ 433555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 4345d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi struct active_conn_info *ci; 4355d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_cp cp; 4365d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi int dd; 437661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode uint16_t dev_id = adapter_get_dev_id(device->adapter); 4385d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4395d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = 0; 4405d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 441cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ci = adapter_search_active_conn_by_bdaddr(device->adapter, 442cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode &device->bdaddr); 443bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode 444bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (!ci) 4455d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 4465d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 447661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode dd = hci_open_dev(dev_id); 4485d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (dd < 0) 4495d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi goto fail; 4505d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4515d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi memset(&cp, 0, sizeof(cp)); 4525d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.handle = htobs(ci->handle); 4535d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.reason = HCI_OE_USER_ENDED_CONNECTION; 4545d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4555d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, 4565d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DISCONNECT_CP_SIZE, &cp); 4575d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4585d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi close(dd); 4595d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4605d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail: 4615d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 4625d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi} 4635d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 46494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *disconnect(DBusConnection *conn, 46594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 46694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 467555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 468bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode struct active_conn_info *dev; 4695d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 470cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode dev = adapter_search_active_conn_by_bdaddr(device->adapter, 471cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode &device->bdaddr); 472bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode 473bcb5f7e4d5e570c1acfd5364547d36e970408394Alok Barsode if (!dev) 4745d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return g_dbus_create_error(msg, 4755d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi ERROR_INTERFACE ".NotConnected", 4765d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi "Device is not connected"); 4775d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4785d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_dbus_emit_signal(conn, device->path, 4795d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DEVICE_INTERFACE, "DisconnectRequested", 4805d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DBUS_TYPE_INVALID); 4815d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4825d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, 4835d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_timeout, device); 48494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 48594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 48694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 48794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 488e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = { 489e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "GetProperties", "", "a{sv}", get_properties }, 490e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "SetProperty", "sv", "", set_property }, 491e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann { "DiscoverServices", "s", "a{us}", discover_services, 49294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann G_DBUS_METHOD_FLAG_ASYNC}, 49394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "CancelDiscovery", "", "", cancel_discover }, 494e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "Disconnect", "", "", disconnect }, 49594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 4962c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 4972c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 498e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = { 49994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "PropertyChanged", "sv" }, 50094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "DisconnectRequested", "" }, 50194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5022c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5032c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 50418614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, 50536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const gchar *address) 50686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 507ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite gchar *address_up; 508555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 509661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode uint16_t dev_id = adapter_get_dev_id(adapter); 51086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 511555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode device = g_try_malloc0(sizeof(struct btd_device)); 51286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 51386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 51486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 515ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite address_up = g_ascii_strup(address, -1); 51693fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann device->path = g_strdup_printf("%s/hci%d/dev_%s", "/org/bluez", 51793fbf4400a81f68cd3642084bd6d2aa51a173250Marcel Holtmann dev_id, address_up); 51886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 519ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite g_free(address_up); 52086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 52186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 52286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 523e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, 524e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device_methods, device_signals, NULL, 525e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device, device_free) == FALSE) { 52686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 52786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 52886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 529da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 530cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str2ba(address, &device->bdaddr); 531da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 532da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 5336bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi return device; 53486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 53586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 536555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_remove(DBusConnection *conn, struct btd_device *device) 53775add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{ 5386061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann GSList *list; 5396061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann struct btd_device_driver *driver; 540f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann gchar *path = g_strdup(device->path); 541f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 542f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann debug("Removing device %s", path); 543f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 5446061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann for (list = device->drivers; list; list = list->next) { 545b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 546b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver = driver_data->driver; 5476061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 548e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 549b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 5506061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann } 5516061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 552f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); 55375add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi 554f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_free(path); 55586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 556ff296428a08dee619db1cc702146faefa91087faCidorvan Leite 557555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address) 558ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{ 559cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char addr[18]; 560cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 561cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, addr); 562cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return strcasecmp(addr, address); 563ff296428a08dee619db1cc702146faefa91087faCidorvan Leite} 5643d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 5654b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodesdp_record_t *get_record(sdp_list_t *recs, const char *uuid) 566dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann{ 5674b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode sdp_list_t *seq; 5684b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 5694b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode for (seq = recs; seq; seq = seq->next) { 5704b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode sdp_record_t *rec = (sdp_record_t *) seq->data; 5714b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode sdp_list_t *svcclass = NULL; 5724b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode char *uuid_str; 5734b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 5744b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode if (sdp_get_service_classes(rec, &svcclass) < 0) 5754b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode continue; 5764b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 5774b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode /* Extract the uuid */ 5784b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode uuid_str = bt_uuid2string(svcclass->data); 5794b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode if (!uuid_str) 5804b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode continue; 581dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann 5824b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode if (!strcasecmp(uuid_str, uuid)) { 5834b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode sdp_list_free(svcclass, free); 5844b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode free(uuid_str); 5854b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode return rec; 5864b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode } 5874b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode sdp_list_free(svcclass, free); 5884b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode free(uuid_str); 5894b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode } 5904b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode return NULL; 591dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann} 592dde6ea8284f922181318ee84fd58144e06ee39b2Marcel Holtmann 5934b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_probe_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) 594f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{ 595c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz GSList *list; 5966061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann const char **uuid; 597f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann int err; 598f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 599f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann debug("Probe drivers for %s", device->path); 600f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 601c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz for (list = device_drivers; list; list = list->next) { 602e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann struct btd_device_driver *driver = list->data; 6034b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode GSList *records = NULL; 604f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 6056061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann for (uuid = driver->uuids; *uuid; uuid++) { 606081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz sdp_record_t *rec; 6074b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 608081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 609081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz (GCompareFunc) strcasecmp)) 610081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz continue; 611081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 612081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz rec = get_record(recs, *uuid); 613081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz if (!rec) 614081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz continue; 615081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 616081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz records = g_slist_append(records, rec); 617f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 618f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 6194b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode if (records) { 620b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = g_new0(struct btd_driver_data, 1); 621b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 622e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz err = driver->probe(device, records); 623fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann if (err < 0) { 624f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann error("probe failed for driver %s", 625f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann driver->name); 626b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 627b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 628fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann continue; 629fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann } 630fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann 631b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data->driver = driver; 632fad3b8ad7a07de0c96c34b9d624ec174c2754817Marcel Holtmann device->drivers = g_slist_append(device->drivers, 633b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data); 634f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 635f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 63636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 63736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = uuids; list; list = list->next) 63836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_insert_sorted(device->uuids, 63936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz list->data, (GCompareFunc) strcmp); 64036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 64136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 6424b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsodevoid device_remove_drivers(struct btd_device *device, GSList *uuids, sdp_list_t *recs) 64336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 64418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 64536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *list; 646cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 6472a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 6482a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 6492a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 650cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 651cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 65236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 65336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz debug("Remove drivers for %s", device->path); 65436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 65536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = device->drivers; list; list = list->next) { 656b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 657b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver = driver_data->driver; 65836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const char **uuid; 65936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 66036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 6619b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz sdp_record_t *rec; 66236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 6639b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 6649b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz (GCompareFunc) strcasecmp)) 66536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 66636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 667e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 66836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->drivers = g_slist_remove(device->drivers, 669b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data); 670b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 671b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 672b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 6739b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz rec = get_record(recs, *uuid); 6749b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!rec) 6759b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz continue; 6769b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz 677cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode delete_record(srcaddr, dstaddr, rec->handle); 67836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 67936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 68036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 68136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = uuids; list; list = list->next) 68236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_remove(device->uuids, list->data); 683f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann} 684f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 685bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle, 686bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann const char *record) 687bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{ 688bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann DBusMessageIter entry; 689bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 690bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, 691bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann NULL, &entry); 692bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 693bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); 694bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 695bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); 696bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 697bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_close_container(dict, &entry); 698bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann} 699bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 700730775d1226a30c37ff551955f093ddfcd18e600Claudio Takahasistatic void append_and_grow_string(void *data, const char *str) 701c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{ 702c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz sdp_buf_t *buff = data; 703c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz int len; 704c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 705c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz len = strlen(str); 706c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 707c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) { 708c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = malloc(DEFAULT_XML_BUF_SIZE); 709c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) 710c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 711c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = DEFAULT_XML_BUF_SIZE; 712c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 713c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 714c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow string */ 715c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz while (buff->buf_size < (buff->data_size + len + 1)) { 716c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz void *tmp; 717c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz uint32_t new_size; 718c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 719c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow buffer by a factor of 2 */ 720c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz new_size = (buff->buf_size << 1); 721c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 722c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz tmp = realloc(buff->data, new_size); 723c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!tmp) 724c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 725c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 726c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = tmp; 727c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = new_size; 728c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 729c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 730c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Include the NULL character */ 731c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz memcpy(buff->data + buff->data_size, str, len + 1); 732c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data_size += len; 733c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz} 734c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 7351e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs) 7361e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{ 7371e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessage *reply; 7381e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessageIter iter, dict; 7391e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_list_t *seq; 7401e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7411e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 7421e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!reply) 7431e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz return; 7441e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7451e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 7461e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7471e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 7481e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 7491e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING 7501e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 7511e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7521e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 7531e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 7541e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_buf_t result; 7551e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7561e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!rec) 7571e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz break; 7581e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7591e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz memset(&result, 0, sizeof(sdp_buf_t)); 7601e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7611e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz convert_sdp_record_to_xml(rec, &result, 7621e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz append_and_grow_string); 7631e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7641e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (result.data) { 7651e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz const char *val = (char *) result.data; 7661e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz iter_append_record(&dict, rec->handle, val); 7671e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz free(result.data); 7681e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 7691e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 7701e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7711e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 7721e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 7731e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_connection_send(req->conn, reply, NULL); 7741e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_unref(reply); 7751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz} 7761e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 77736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void services_changed(struct browse_req *req) 7783d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 779555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 7803d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz char **uuids; 7813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz GSList *l; 78236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz int i; 7833d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 78436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 78536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 78636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids[i] = l->data; 78736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 78836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz dbus_connection_emit_property_changed(req->conn, device->path, 78936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DEVICE_INTERFACE, "UUIDs", 79036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DBUS_TYPE_ARRAY, &uuids); 79136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 79236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuids); 79336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 79436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 7958b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b) 7968b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{ 7978b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r1 = a; 7988b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r2 = b; 7998b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 8008b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg return r1->handle - r2->handle; 8018b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg} 8028b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 80336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs) 80436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 805555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 80618614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 80736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *seq; 808cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 8092a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 8102a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 8112a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 812cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 813cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 8143d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 81536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 8163d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 817681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_buf_t pdu; 81836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *svcclass = NULL; 81936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz gchar *uuid_str; 82036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *l; 8213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 8223d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!rec) 8233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz break; 8243d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 82536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (sdp_get_service_classes(rec, &svcclass) < 0) 82636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 82736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 82836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Extract the first element and skip the remainning */ 82936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuid_str = bt_uuid2string(svcclass->data); 83036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!uuid_str) 83136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 83236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 833e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse if (!strcasecmp(uuid_str, PNP_UUID)) { 834e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse uint16_t vendor, product, version; 835e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse sdp_data_t *pdlist; 836e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 837e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); 838e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse vendor = pdlist ? pdlist->val.uint16 : 0x0000; 839e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 840e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); 841e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse product = pdlist ? pdlist->val.uint16 : 0x0000; 842e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 843e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); 844e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version = pdlist ? pdlist->val.uint16 : 0x0000; 845e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 846e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse if (vendor || product || version) 847e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse store_pnp(srcaddr, dstaddr, vendor, product, 848e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version); 849e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse } 850e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 85158d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz /* Driver uuid found */ 85258d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz l = g_slist_find_custom(req->uuids, uuid_str, 85358d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz (GCompareFunc) strcasecmp); 854e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz if (l) { 855e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz char *uuid = l->data; 856e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz 857e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz req->uuids = g_slist_remove(req->uuids, uuid); 858e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz g_free(uuid); 859e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz } 86058d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz 86137a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg /* Check for duplicates */ 8628b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg if (sdp_list_find(req->records, rec, rec_cmp)) 86337a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg continue; 86437a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 865cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode store_record(srcaddr, dstaddr, rec); 86637a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 867681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Copy record */ 868681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (sdp_gen_record_pdu(rec, &pdu) == 0) { 869681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_record_t *record; 870681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz int scanned; 871681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 872681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz record = sdp_extract_pdu(pdu.data, pdu.data_size, 873681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz &scanned); 8741d40bababe8114b88ec654b7764ff20c22a258c1Johan Hedberg free(pdu.data); 875681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz req->records = sdp_list_append(req->records, record); 876681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 877681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 87836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz l = g_slist_find_custom(device->uuids, uuid_str, 87936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz (GCompareFunc) strcmp); 88036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!l) 88136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz req->uuids_added = g_slist_append(req->uuids_added, 88236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuid_str); 88336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz else { 88436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz req->uuids_removed = g_slist_remove(req->uuids_removed, 88536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz l->data); 88636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuid_str); 8873d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 8883d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 88936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_free(svcclass, free); 8903d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 89136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 89236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 893555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic void store(struct btd_device *device) 89436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 89518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 896cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 89736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz char *str; 8983d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 8992a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 9003d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 90136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!device->uuids) { 902cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, ""); 90336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz return; 90436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 90536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 90636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz str = bt_list2string(device->uuids); 907cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, str); 90836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(str); 90936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 91036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 911da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data) 91236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 91336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz struct browse_req *req = user_data; 914555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 91536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DBusMessage *reply; 9162a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 917681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (err < 0) { 918681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz error("%s: error updating services: %s (%d)", 919681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device->path, strerror(-err), -err); 92036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 921681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 92236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 92336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz update_services(req, recs); 92436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 925681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (!req->uuids_added && !req->uuids_removed) { 926e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz debug("%s: No service update", device->path); 92736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 928681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 9292efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 93036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Probe matching drivers for services added */ 93136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (req->uuids_added) 932681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device_probe_drivers(device, req->uuids_added, req->records); 9332efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 93436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Remove drivers for services removed */ 93536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (req->uuids_removed) 936681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device_remove_drivers(device, req->uuids_removed, req->records); 9372efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 93836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Propagate services changes */ 93936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz services_changed(req); 940f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 9417b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed: 942681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 943681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Store the device's profiles in the filesystem */ 944681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz store(device); 945681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 9461e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, 9471e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz "DiscoverServices")) { 948681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz discover_device_reply(req, req->records); 9491e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz goto cleanup; 950a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann } 951a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann 952f80a7215275b229a597cf8d2bbc7e4e208af522cMarcel Holtmann g_dbus_emit_signal(req->conn, dbus_message_get_path(req->msg), 9538d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz ADAPTER_INTERFACE, "DeviceCreated", 9548d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz DBUS_TYPE_OBJECT_PATH, &device->path, 9558d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz DBUS_TYPE_INVALID); 9568d8f45c98ddabe1ffb5b2b4f93fa3983027ba740Luiz Augusto von Dentz 9573d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz /* Reply create device request */ 9583d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 9593d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!reply) 9601e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz goto cleanup; 9613d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 9623d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, 963a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann DBUS_TYPE_INVALID); 9643d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 9650472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann dbus_connection_send(req->conn, reply, NULL); 9660472470e5059e702f0e7e69ee0155dfea11baa25Marcel Holtmann dbus_message_unref(reply); 9673d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 9681e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup: 9692efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz device->discov_active = 0; 9702efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 9712efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz if (device->discov_requestor) { 9722efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz g_dbus_remove_watch(req->conn, device->discov_listener); 9732efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz device->discov_listener = 0; 9742efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz g_free(device->discov_requestor); 9752efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz device->discov_requestor = NULL; 9762efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz } 9772efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 9783d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_message_unref(req->msg); 9793d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_connection_unref(req->conn); 98036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_slist_free(req->uuids_added); 98136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_slist_free(req->uuids_removed); 982681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (req->records) 983681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); 9843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz g_free(req); 985da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 986da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 987da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 988da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data) 989da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 990da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct browse_req *req = user_data; 991da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_device *device = req->device; 992da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 993cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 994da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz uuid_t uuid; 995da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 9967d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse /* If we have a valid response and req->search_uuid == 1, then 9977d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse public browsing was successful -- we don't need any more */ 9987d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (err < 0 || (req->search_uuid == 1 && recs)) 999da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz goto done; 1000da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1001da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz update_services(req, recs); 1002da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1003da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz adapter_get_address(adapter, &src); 1004da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1005da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz /* Search for mandatory uuids */ 10067d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (uuid_list[req->search_uuid]) { 10077d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1008cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_search_service(&src, &device->bdaddr, &uuid, browse_cb, user_data, NULL); 1009da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz return; 1010da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz } 1011da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 101258d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz /* Search for drivers uuids */ 101358d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz if (req->uuids) { 1014e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz char *uuid_str = req->uuids->data; 1015e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz 1016e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz bt_string2uuid(&uuid, uuid_str); 1017e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz req->uuids = g_slist_remove(req->uuids, uuid_str); 1018e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz g_free(uuid_str); 1019cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_search_service(&src, &device->bdaddr, &uuid, browse_cb, user_data, NULL); 102058d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz return; 102178eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz } 102278eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz 102378eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz /* Search for l2cap uuid */ 102478eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz if (!req->records) { 102578eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz sdp_uuid16_create(&uuid, L2CAP_UUID); 1026cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_search_service(&src, &device->bdaddr, &uuid, search_cb, user_data, NULL); 102778eadf19bbee1f52b738d39133296186b3e944feLuiz Augusto von Dentz return; 102858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz } 102958d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz 1030da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone: 1031da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz search_cb(recs, err, user_data); 1032da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1033da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1034da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void init_browse(struct browse_req *req) 1035da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1036da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz GSList *l; 1037da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 103858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz for (l = device_drivers; l; l = l->next) { 103958d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz struct btd_device_driver *driver = l->data; 104058d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz int i; 104158d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz 104258d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz for (i = 0; driver->uuids[i]; i++) { 1043e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz char *uuid; 10440144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse int j; 10450144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse 10460144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse /* Eliminate duplicates of UUIDs in uuid_list[]... */ 10470144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse if (strlen(driver->uuids[i]) == 36 && 10480144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse !strncmp(driver->uuids[i], "0000", 4) && 10490144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse !strcasecmp(driver->uuids[i] + 8, 10500144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse "-0000-1000-8000-00805F9B34FB")) { 10510144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse uint16_t uuid16 = strtol(driver->uuids[i], 10520144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse NULL, 16); 10530144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse for (j = 0; uuid_list[j]; j++) { 10540144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse if (uuid16 == uuid_list[j]) 10550144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse continue; 10560144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse } 10570144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse 10580144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse } 10590144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse /* ... and of UUIDs another driver already asked for */ 106058d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz if (g_slist_find_custom(req->uuids, driver->uuids[i], 106158d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz (GCompareFunc) strcasecmp)) 10620144612a3d800c5d657cf141634f6b6cd47b4128David Woodhouse continue; 1063e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz 1064e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz uuid = g_strdup(driver->uuids[i]); 1065e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz req->uuids = g_slist_append(req->uuids, uuid); 106658d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz } 106758d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz } 106858d8ea3c3a8ea69e652d8a39649a19426f31933bLuiz Augusto von Dentz 1069da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz for (l = req->device->uuids; l; l = l->next) 1070da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz req->uuids_removed = g_slist_append(req->uuids_removed, 1071da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz l->data); 10723d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 10733d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1074555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn, 1075040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi DBusMessage *msg, uuid_t *search) 10763d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 107718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 10783d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz struct browse_req *req; 1079cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1080d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann uuid_t uuid; 1081da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz bt_callback_t cb; 10822a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 10832a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 10843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 10853d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req = g_new0(struct browse_req, 1); 10863d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->conn = dbus_connection_ref(conn); 10873d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->msg = dbus_message_ref(msg); 10883d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->device = device; 10893d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1090a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (search) { 1091040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi memcpy(&uuid, search, sizeof(uuid_t)); 1092da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = search_cb; 1093a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } else { 10947d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1095da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz init_browse(req); 1096da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = browse_cb; 1097a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } 1098d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 109995e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_active = 1; 110095e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); 1101040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi /* Track the request owner to cancel it 1102040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi * automatically if the owner exits */ 110395e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_listener = g_dbus_add_disconnect_watch(conn, 110495e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz dbus_message_get_sender(msg), 110595e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz discover_services_req_exit, 110695e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device, NULL); 110795e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz 1108cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return bt_search_service(&src, &device->bdaddr, 11097d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse &uuid, cb, req, NULL); 11103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 111124cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann 111218614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device) 1113dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{ 1114dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode if (!device) 1115dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return NULL; 1116dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 1117dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return device->adapter; 1118dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode} 1119dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 112019ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr) 1121aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{ 1122cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bacpy(bdaddr, &device->bdaddr); 1123aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode} 1124aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode 1125555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device) 112646fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{ 112746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode if (!device) 112846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return NULL; 112946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 113046fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return device->path; 113146fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode} 113246fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 1133555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device) 1134a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{ 1135a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode if (!device) 1136a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return NULL; 1137a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1138a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return device->agent; 1139a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode} 1140a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1141555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent) 1142d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{ 1143d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode if (!device) 1144d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode return; 1145d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1146d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode device->agent = agent; 1147d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode} 1148d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1149555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device) 11509f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{ 11519f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode return device->discov_active ? TRUE : FALSE; 11529f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode} 11539f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode 1154555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device) 1155f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{ 1156f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode return device->temporary; 1157f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode} 1158f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode 1159555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary) 1160595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{ 1161595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode if (!device) 1162595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode return; 1163595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1164595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode device->temporary = temporary; 1165595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode} 1166595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1167555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap) 1168491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{ 1169491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode if (!device) 1170491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode return; 1171491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1172491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode device->cap = cap; 1173491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode} 1174491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1175555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth) 117629227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{ 117729227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode if (!device) 117829227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode return; 117929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 118029227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode device->auth = auth; 118129227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode} 118229227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 1183555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device) 11842203f153c53189ec1c30df99b717e035681196e6Alok Barsode{ 11852203f153c53189ec1c30df99b717e035681196e6Alok Barsode return device->auth; 11862203f153c53189ec1c30df99b717e035681196e6Alok Barsode} 1187c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1188c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver) 1189c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 1190c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_append(device_drivers, driver); 1191c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1192c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz return 0; 1193c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 1194c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1195c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver) 1196c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 1197c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_remove(device_drivers, driver); 1198c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 1199