1dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann/* 2dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 3dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * BlueZ - Bluetooth protocol stack for Linux 4dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 55592142cb9383df0556b27ac59e96547b380310bJohan Hedberg * Copyright (C) 2006-2010 Nokia Corporation 69184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann * Copyright (C) 2004-2010 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> 32f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg#include <fcntl.h> 336a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include <sys/stat.h> 341e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg#include <sys/ioctl.h> 351af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg#include <errno.h> 36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 37dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h> 38a278db781a26c639267b1d88d5fbe08f99af6c61Elvis Pfützenreuter#include <bluetooth/uuid.h> 395d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h> 405d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h> 41dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h> 4386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4415ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h> 4586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 46e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h" 476a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h" 48dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 49d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario#include "att.h" 50506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "hcid.h" 512c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h" 5286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h" 53da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h" 5416d507e0bb939b1c98f9d5ab14c656339757b878Johan Hedberg#include "event.h" 557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h" 563d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h" 575399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi#include "gattrib.h" 585399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi#include "gatt.h" 59fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h" 603d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h" 61506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "storage.h" 6296762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg#include "btio.h" 6342d618a69af838356edc566d124b39c405da9495Jaikumar Ganesh#include "../attrib/client.h" 6486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 655d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER 2 667ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz#define DISCOVERY_TIMER 2 67dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 680948c4c0e87f2a4179320e903123acbb296935f6Claudio Takahasi/* When all services should trust a remote device */ 690948c4c0e87f2a4179320e903123acbb296935f6Claudio Takahasi#define GLOBAL_TRUST "[all]" 700948c4c0e87f2a4179320e903123acbb296935f6Claudio Takahasi 718d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentzstruct btd_disconnect_data { 728d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz guint id; 738d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz disconnect_watch watch; 748d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz void *user_data; 758d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz GDestroyNotify destroy; 768d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz}; 778d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstruct bonding_req { 792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn; 802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg; 812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz GIOChannel *io; 822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz guint listener_id; 832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz}; 852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstruct authentication_req { 872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth_type_t type; 882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *cb; 892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz}; 922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 93a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstruct browse_req { 94a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBusConnection *conn; 95a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBusMessage *msg; 965399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi GAttrib *attrib; 97a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz struct btd_device *device; 98a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz GSList *match_uuids; 99a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz GSList *profiles_added; 100a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz GSList *profiles_removed; 101a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz sdp_list_t *records; 102a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz int search_uuid; 103a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz int reconnect_attempt; 104a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz guint listener_id; 105a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz}; 106a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 107555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device { 108cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t bdaddr; 109f1beea3e80b6e02f49eeea926d398366b13d291cClaudio Takahasi device_type_t type; 110ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gchar *path; 11108fef64ca40b85782a0de1c1fd098934355b5e24Johan Hedberg char name[MAX_NAME_LENGTH + 1]; 11248a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz char *alias; 11318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter; 114ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode GSList *uuids; 115b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes GSList *services; /* Primary services path */ 11683d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes GSList *primaries; /* List of primary services */ 117521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasi GSList *drivers; /* List of device drivers */ 1188d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz GSList *watches; /* List of disconnect_data */ 119ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gboolean temporary; 120ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode struct agent *agent; 121ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint disconn_timer; 122013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg guint discov_timer; 123a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz struct browse_req *browse; /* service discover request */ 1242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 1252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *authr; /* authentication request */ 126c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz GSList *disconnects; /* disconnects message */ 127ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 128bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg gboolean connected; 129e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 130548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *tmp_records; 131bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 1326da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz gboolean trusted; 1336fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg gboolean paired; 1341e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg gboolean blocked; 1353e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy gboolean bonded; 136837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg 137837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg gboolean authorizing; 1380ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz gint ref; 139ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode}; 140ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 141d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = { 1420dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP_UUID, 1431c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PNP_INFO_SVCLASS_ID, 1440dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg PUBLIC_BROWSE_GROUP, 145d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 0 146d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann}; 147d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 148c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL; 149c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 150a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstatic void browse_request_free(struct browse_req *req) 151a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz{ 152a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (req->listener_id) 153a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_dbus_remove_watch(req->conn, req->listener_id); 154a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (req->msg) 155a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_unref(req->msg); 156a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (req->conn) 157a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_connection_unref(req->conn); 1582499fb1f1775b8afcb374ba3aefc0c5484e78fa4Johan Hedberg if (req->device) 1592499fb1f1775b8afcb374ba3aefc0c5484e78fa4Johan Hedberg btd_device_unref(req->device); 160a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL); 161a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_slist_free(req->profiles_added); 162a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_slist_free(req->profiles_removed); 163a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (req->records) 164a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); 1655399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 1661b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes if (req->attrib) 1675399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi g_attrib_unref(req->attrib); 1685399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 169a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_free(req); 170a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz} 171a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 172a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstatic void browse_request_cancel(struct browse_req *req) 173a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz{ 174a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz struct btd_device *device = req->device; 175a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 176a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz bdaddr_t src; 177a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 1783d8bdaa95b00ee42ecea513ba8d72772c6ffa075Johan Hedberg if (device_is_creating(device, NULL)) 1793d8bdaa95b00ee42ecea513ba8d72772c6ffa075Johan Hedberg device_set_temporary(device, TRUE); 1803d8bdaa95b00ee42ecea513ba8d72772c6ffa075Johan Hedberg 181a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz adapter_get_address(adapter, &src); 182a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 1835c36b74c0b43ae0532e26c03b6ce8a1abba7d874Claudio Takahasi bt_cancel_discovery(&src, &device->bdaddr); 184a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 185a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz device->browse = NULL; 1862499fb1f1775b8afcb374ba3aefc0c5484e78fa4Johan Hedberg browse_request_free(req); 187a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz} 188a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 189e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data) 19086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 191555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 1922f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1932f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct agent *agent = adapter_get_agent(adapter); 194e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 195fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite if (device->agent) 196cc35f24a2a728c4e8c31ea0c6c11c6b701901861Johan Hedberg agent_free(device->agent); 197f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 198929f754fbd780a7e36463fc335f145ed6109ca51Johan Hedberg if (agent && (agent_is_busy(agent, device) || 199929f754fbd780a7e36463fc335f145ed6109ca51Johan Hedberg agent_is_busy(agent, device->authr))) 2002f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz agent_cancel(agent); 2012f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz 202b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes g_slist_foreach(device->services, (GFunc) g_free, NULL); 203b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes g_slist_free(device->services); 204b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes 205ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_foreach(device->uuids, (GFunc) g_free, NULL); 206ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_free(device->uuids); 207f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 20883d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes g_slist_foreach(device->primaries, (GFunc) g_free, NULL); 20983d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes g_slist_free(device->primaries); 21083d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes 2114bec43039626e853489e72149014868f8c8afedcJohan Hedberg if (device->tmp_records) 2124bec43039626e853489e72149014868f8c8afedcJohan Hedberg sdp_list_free(device->tmp_records, 2134bec43039626e853489e72149014868f8c8afedcJohan Hedberg (sdp_free_func_t) sdp_record_free); 2144bec43039626e853489e72149014868f8c8afedcJohan Hedberg 2155d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (device->disconn_timer) 2165d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_source_remove(device->disconn_timer); 2175d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 21832c90b2a21d936d3881a71c137441e4cb7dd1901Luiz Augusto von Dentz if (device->discov_timer) 21932c90b2a21d936d3881a71c137441e4cb7dd1901Luiz Augusto von Dentz g_source_remove(device->discov_timer); 22032c90b2a21d936d3881a71c137441e4cb7dd1901Luiz Augusto von Dentz 2210f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz DBG("%p", device); 2220ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 223929f754fbd780a7e36463fc335f145ed6109ca51Johan Hedberg g_free(device->authr); 22486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 22548a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz g_free(device->alias); 22686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 22786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 22886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 229fee17aefe6b727ec790568aa4994039ff94bf44eJohan Hedberggboolean device_is_paired(struct btd_device *device) 230769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{ 2316fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg return device->paired; 232769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz} 233769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 2346da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentzgboolean device_is_trusted(struct btd_device *device) 2356da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz{ 2366da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz return device->trusted; 2376da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz} 2386da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz 239e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn, 240e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *user_data) 2412c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 242555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 24318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 2444e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessage *reply; 2454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter iter; 2464e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter dict; 247cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 24808fef64ca40b85782a0de1c1fd098934355b5e24Johan Hedberg char name[MAX_NAME_LENGTH + 1], srcaddr[18], dstaddr[18]; 249b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes char **str; 2502a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode const char *ptr; 2514e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_bool_t boolean; 2524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz uint32_t class; 253769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz int i; 254769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz GSList *l; 2554e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 256cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 257cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 2584e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz reply = dbus_message_new_method_return(msg); 2594e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz if (!reply) 260e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return NULL; 2614e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2624e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 2634e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2644e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 2654e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 2664e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 2674e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 2684e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2694e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Address */ 270cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ptr = dstaddr; 2711262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr); 2724e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2734e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Name */ 274506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = NULL; 275506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi memset(name, 0, sizeof(name)); 2762a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 277cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 2788a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi 2794d0426730e110b82b1e2d94d62ce57e4fa1b8382Johan Hedberg ptr = device->name; 2804d0426730e110b82b1e2d94d62ce57e4fa1b8382Johan Hedberg dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr); 2814e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 282e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby#ifdef ANDROID 283e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby /* Alias (Android doesn't fallback to name or address) */ 284e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby if (device->alias != NULL) { 285e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby ptr = device->alias; 286e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); 287e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby } 288e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby#else 289afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann /* Alias (fallback to name or address) */ 29048a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz if (device->alias != NULL) 29148a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz ptr = device->alias; 29248a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz else if (strlen(ptr) == 0) { 29348a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz g_strdelimit(dstaddr, ":", '-'); 29448a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz ptr = dstaddr; 29548a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz } 296506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 2974d0426730e110b82b1e2d94d62ce57e4fa1b8382Johan Hedberg dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); 298e73c02b4397b97f6bc5b7fd862ca3babf18da497Jake Hamby#endif 299506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 3004e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Class */ 301cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_remote_class(&src, &device->bdaddr, &class) == 0) { 302e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann const char *icon = class_to_icon(class); 303e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 3041262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class); 305e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 306e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann if (icon) 3071262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Icon", 308e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann DBUS_TYPE_STRING, &icon); 3094e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 3104e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 3114e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Paired */ 312769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz boolean = device_is_paired(device); 3131262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean); 3144e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 3154e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Trusted */ 3166da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz boolean = device_is_trusted(device); 3171262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean); 3184e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 3191e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg /* Blocked */ 3201e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg boolean = device->blocked; 3211e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg dict_append_entry(&dict, "Blocked", DBUS_TYPE_BOOLEAN, &boolean); 3221e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 3234e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Connected */ 324c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, 325bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg &device->connected); 3264e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 327ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi /* UUIDs */ 328b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes str = g_new0(char *, g_slist_length(device->uuids) + 1); 329769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 330b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes str[i] = l->data; 331b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &str, i); 332b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes g_free(str); 333b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes 334b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes /* Services */ 335b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes str = g_new0(char *, g_slist_length(device->services) + 1); 336b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes for (i = 0, l = device->services; l; l = l->next, i++) 337b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes str[i] = l->data; 338b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes dict_append_array(&dict, "Services", DBUS_TYPE_OBJECT_PATH, &str, i); 339b3d33e592dea372f4e58ed3cf2ad76e7e23aaa10Vinicius Costa Gomes g_free(str); 3404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 34174fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz /* Adapter */ 3428a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi ptr = adapter_get_path(adapter); 3431262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr); 34474fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz 3454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 3464e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 347e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return reply; 3482c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 3492c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 350e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, 3517fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *alias, void *data) 3527fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 353555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 35418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 355cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 356cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 357506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi int err; 3587fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 35948a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz /* No change */ 36048a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz if ((device->alias == NULL && g_str_equal(alias, "")) || 36148a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz g_strcmp0(device->alias, alias) == 0) 36248a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz return dbus_message_new_method_return(msg); 36348a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz 364cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 365cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 366cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3672a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 368cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode /* Remove alias if empty string */ 369cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode err = write_device_alias(srcaddr, dstaddr, 370506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi g_str_equal(alias, "") ? NULL : alias); 371506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (err < 0) 37292a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan return btd_error_failed(msg, strerror(-err)); 3737fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 37448a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz g_free(device->alias); 37548a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias); 37648a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz 377c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 378c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Alias", 379c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_STRING, &alias); 3807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 381e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3827fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3837fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 384e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, 3856da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz gboolean value, void *data) 3867fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 387555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 38818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 389cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 390cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 3916da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz int err; 3926da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz 3936da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz if (device->trusted == value) 3946da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz return dbus_message_new_method_return(msg); 3952a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 396cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 397cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 398cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3992a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4006da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value); 4016da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz if (err < 0) 40292a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan return btd_error_failed(msg, strerror(-err)); 4036da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz 4046da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz device->trusted = value; 4057fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 406c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 407c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Trusted", 408c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_BOOLEAN, &value); 4097fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 410e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 4117fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 4127fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 413521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasistatic void driver_remove(struct btd_device_driver *driver, 4141e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg struct btd_device *device) 4151e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg{ 4161e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg driver->remove(device); 4171e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 418521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasi device->drivers = g_slist_remove(device->drivers, driver); 4191e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg} 4201e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4211e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedbergstatic gboolean do_disconnect(gpointer user_data) 4221e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg{ 4231e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg struct btd_device *device = user_data; 4241e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4251e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device->disconn_timer = 0; 4261e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 427bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg btd_adapter_disconnect_device(device->adapter, &device->bdaddr); 4281e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4291e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return FALSE; 4301e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg} 4311e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4321e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedbergstatic int device_block(DBusConnection *conn, struct btd_device *device) 4331e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg{ 434885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg int err; 4351e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg bdaddr_t src; 4361e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4371e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (device->blocked) 4381e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return 0; 4391e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 440bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (device->connected) 4411e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg do_disconnect(device); 4421e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4431e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg g_slist_foreach(device->drivers, (GFunc) driver_remove, device); 4441e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 445885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg err = btd_adapter_block_address(device->adapter, &device->bdaddr); 446885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg if (err < 0) 4471e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return err; 4481e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4491e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device->blocked = TRUE; 4501e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4511e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg adapter_get_address(device->adapter, &src); 4521e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4531e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg err = write_blocked(&src, &device->bdaddr, TRUE); 4541e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (err < 0) 4551e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg error("write_blocked(): %s (%d)", strerror(-err), -err); 4561e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4571e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device_set_temporary(device, FALSE); 4581e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4591e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Blocked", 4601e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg DBUS_TYPE_BOOLEAN, &device->blocked); 4611e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4621e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return 0; 4631e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg} 4641e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 465e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadiusstatic int device_unblock(DBusConnection *conn, struct btd_device *device, 466e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius gboolean silent) 4671e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg{ 468885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg int err; 4691e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg bdaddr_t src; 4701e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4711e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (!device->blocked) 4721e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return 0; 4731e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 474885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg err = btd_adapter_unblock_address(device->adapter, &device->bdaddr); 475885c513fdf93404aa713ee6bf4ddb089b42dc5dfJohan Hedberg if (err < 0) 4761e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return err; 4771e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4781e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device->blocked = FALSE; 4791e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4801e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg adapter_get_address(device->adapter, &src); 4811e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4821e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg err = write_blocked(&src, &device->bdaddr, FALSE); 4831e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (err < 0) 4841e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg error("write_blocked(): %s (%d)", strerror(-err), -err); 4851e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 486e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius if (!silent) { 487e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius emit_property_changed(conn, device->path, 488e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius DEVICE_INTERFACE, "Blocked", 4891e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg DBUS_TYPE_BOOLEAN, &device->blocked); 490e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius device_probe_drivers(device, device->uuids); 491e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius } 4921e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4931e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return 0; 4941e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg} 4951e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 4961e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedbergstatic DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg, 4971e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg gboolean value, void *data) 4981e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg{ 4991e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg struct btd_device *device = data; 5001e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg int err; 5011e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 5021e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (value) 5031e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg err = device_block(conn, device); 5041e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg else 505e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius err = device_unblock(conn, device, FALSE); 5061e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 5071e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg switch (-err) { 5081e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg case 0: 5091e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return dbus_message_new_method_return(msg); 5101e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg case EINVAL: 51192a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan return btd_error_failed(msg, "Kernel lacks blacklist support"); 5121e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg default: 51392a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan return btd_error_failed(msg, strerror(-err)); 5141e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg } 5151e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg} 5161e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 517e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn, 518e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *data) 5192c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 5207fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter iter; 5217fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter sub; 5227fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *property; 5237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5247fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (!dbus_message_iter_init(msg, &iter)) 525696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5267fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5277fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 528696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5297fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5307fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&iter, &property); 5317fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_next(&iter); 5327fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5337fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) 534696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5357fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_recurse(&iter, &sub); 5367fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (g_str_equal("Trusted", property)) { 5387fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value; 5397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 540696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &value); 5427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5437fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_trust(conn, msg, value, data); 5447fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } else if (g_str_equal("Alias", property)) { 545506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi const char *alias; 5467fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5477fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) 548696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5497fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &alias); 5507fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 5517fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_alias(conn, msg, alias, data); 5521e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg } else if (g_str_equal("Blocked", property)) { 5531e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg dbus_bool_t value; 5541e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 5551e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 556696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5571e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 5581e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg dbus_message_iter_get_basic(&sub, &value); 5591e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 5601e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg return set_blocked(conn, msg, value, data); 5617fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } 5627fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 563696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 5642c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 5652c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 5661f5107e65f9786bd6b84ecfb4d84691e9b34529aMarcel Holtmannstatic void discover_services_req_exit(DBusConnection *conn, void *user_data) 567342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{ 568e8610fcbe0341a4879b8230d97cd27f5f8cf9f58Luiz Augusto von Dentz struct browse_req *req = user_data; 5692a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 5708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("DiscoverServices requestor exited"); 571e8610fcbe0341a4879b8230d97cd27f5f8cf9f58Luiz Augusto von Dentz 572a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz browse_request_cancel(req); 573342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz} 574342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 57594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn, 57694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 57794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 578555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 57994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann const char *pattern; 580342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz int err; 581342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 582a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (device->browse) 583bd3cf4860d056d3044b7eb8a4e03c53934eb20a6Gustavo F. Padovan return btd_error_in_progress(msg); 58494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 58594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 58694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBUS_TYPE_INVALID) == FALSE) 587a78a0693a6ca2c927a7e88adbef8001f72a16ac1Gustavo F. Padovan return btd_error_invalid_args(msg); 58894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 589a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (strlen(pattern) == 0) { 5907e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario err = device_browse_sdp(device, conn, msg, NULL, FALSE); 591342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 592342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 593342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } else { 594040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi uuid_t uuid; 595040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi 596040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi if (bt_string2uuid(&uuid, pattern) < 0) 597696c18c48f9648274c375a77a70a45f5f31053fbGustavo F. Padovan return btd_error_invalid_args(msg); 598a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann 5994b1914903cb105acf843b84833e81d5470133879Johan Hedberg sdp_uuid128_to_uuid(&uuid); 6004b1914903cb105acf843b84833e81d5470133879Johan Hedberg 6017e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario err = device_browse_sdp(device, conn, msg, &uuid, FALSE); 602342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 603342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 604342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } 60594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 60694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return NULL; 607342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 608342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail: 60992a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan return btd_error_failed(msg, strerror(-err)); 61094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 61194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 612a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstatic const char *browse_request_get_requestor(struct browse_req *req) 613a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz{ 614a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!req->msg) 615a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz return NULL; 616a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 617a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz return dbus_message_get_sender(req->msg); 618a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz} 619a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 620a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle, 621a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz const char *record) 622a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz{ 623a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBusMessageIter entry; 624a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 625a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, 626a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz NULL, &entry); 627a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 628a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); 629a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 630a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); 631a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 632a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_close_container(dict, &entry); 633a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz} 634a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 635a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentzstatic void discover_services_reply(struct browse_req *req, int err, 636a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz sdp_list_t *recs) 637a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz{ 638a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBusMessage *reply; 639a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBusMessageIter iter, dict; 640a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz sdp_list_t *seq; 641a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 642a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (err) { 643a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz const char *err_if; 644a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 645a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (err == -EHOSTDOWN) 646a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz err_if = ERROR_INTERFACE ".ConnectionAttemptFailed"; 647a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz else 648a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz err_if = ERROR_INTERFACE ".Failed"; 649a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 650a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz reply = dbus_message_new_error(req->msg, err_if, 651a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz strerror(-err)); 652a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_dbus_send_message(req->conn, reply); 653a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz return; 654a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz } 655a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 656a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 657a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!reply) 658a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz return; 659a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 660a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 661a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 662a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 663a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 664a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING 665a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 666a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 667a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 668a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 669a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz GString *result; 670a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 671a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!rec) 672a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz break; 673a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 674a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz result = g_string_new(NULL); 675a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 676a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz convert_sdp_record_to_xml(rec, result, 677a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz (void *) g_string_append); 678a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 679a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (result->len) 680a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz iter_append_record(&dict, rec->handle, result->str); 681a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 682a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_string_free(result, TRUE); 683a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz } 684a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 685a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 686a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 687a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz g_dbus_send_message(req->conn, reply); 688a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz} 689a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 69094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn, 69194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 69294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 693555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 6947c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg const char *sender = dbus_message_get_sender(msg); 695a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz const char *requestor; 6962a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 697a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!device->browse) 6983df548164d179e08032c82b90cc56edbf83ef9bfGustavo F. Padovan return btd_error_does_not_exist(msg); 699342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 700a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE, 701a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz "DiscoverServices")) 702b7d1fc1f399e6ea445520b93961f3a11243d8b04Gustavo F. Padovan return btd_error_not_authorized(msg); 703342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 704a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz requestor = browse_request_get_requestor(device->browse); 705a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 706a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz /* only the discover requestor can cancel the inquiry process */ 707a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz if (!requestor || !g_str_equal(requestor, sender)) 708b7d1fc1f399e6ea445520b93961f3a11243d8b04Gustavo F. Padovan return btd_error_not_authorized(msg); 709a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 710a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz discover_services_reply(device->browse, -ECANCELED, NULL); 711a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz 712a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz browse_request_cancel(device->browse); 71394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 71494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 71594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 71694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 717c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentzstatic void bonding_request_cancel(struct bonding_req *bonding) 718c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz{ 719b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct btd_device *device = bonding->device; 720b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg struct btd_adapter *adapter = device->adapter; 721c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 722b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg adapter_cancel_bonding(adapter, &device->bdaddr); 723c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz} 724c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 725c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentzvoid device_request_disconnect(struct btd_device *device, DBusMessage *msg) 7268d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz{ 727c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 728c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 729c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz if (device->bonding) 730c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz bonding_request_cancel(device->bonding); 731c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 73288386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi if (device->browse) { 73388386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi discover_services_reply(device->browse, -ECANCELED, NULL); 734c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz browse_request_cancel(device->browse); 73588386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi } 736c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 737c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz if (msg) 738c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz device->disconnects = g_slist_append(device->disconnects, 739c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz dbus_message_ref(msg)); 740c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 741c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz if (device->disconn_timer) 742c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz return; 7438d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 744d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg while (device->watches) { 745d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg struct btd_disconnect_data *data = device->watches->data; 7468d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 7478d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz if (data->watch) 748a381d5342d27b99612fd31dc9cc80b01f412ad39Luiz Augusto von Dentz /* temporary is set if device is going to be removed */ 749a381d5342d27b99612fd31dc9cc80b01f412ad39Luiz Augusto von Dentz data->watch(device, device->temporary, 750d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg data->user_data); 7518d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 752b2b27c53f8d1987be3538b227b6fb45eacb0ed5dLuiz Augusto von Dentz /* Check if the watch has been removed by callback function */ 753b2b27c53f8d1987be3538b227b6fb45eacb0ed5dLuiz Augusto von Dentz if (!g_slist_find(device->watches, data)) 754b2b27c53f8d1987be3538b227b6fb45eacb0ed5dLuiz Augusto von Dentz continue; 755b2b27c53f8d1987be3538b227b6fb45eacb0ed5dLuiz Augusto von Dentz 756d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg device->watches = g_slist_remove(device->watches, data); 757d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg g_free(data); 758d5d0fa3be8f7a20d128dcbaf8fc529c38bc52395Johan Hedberg } 7598d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 7608d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, 761c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz do_disconnect, device); 762c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 763c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz g_dbus_emit_signal(conn, device->path, 764c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz DEVICE_INTERFACE, "DisconnectRequested", 765c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz DBUS_TYPE_INVALID); 7668d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz} 7678d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 7687c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstatic DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, 7697c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg void *user_data) 77094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 771555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 7725d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 773bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (!device->connected) 77457c9bf4d916f8fc0ecb8234404a255f0bdee250bGustavo F. Padovan return btd_error_not_connected(msg); 7755d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 776c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz device_request_disconnect(device, msg); 7775d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 778c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz return NULL; 77994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 78094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 78196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganeshstatic DBusMessage *get_service_attribute_value_reply(DBusMessage *msg, DBusConnection *conn, 78296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_data_t *attr) 78396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh{ 78496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh DBusMessage *reply; 78596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh DBusMessageIter iter; 78696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 78796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh reply = dbus_message_new_method_return(msg); 78896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh if (!reply) 789a8e69319f00c3fe65b5f3bce1ea370e3c3eb3582Jing Yu return NULL; 79096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_data_t *curr; 79196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_list_t *ap = 0; 79296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh for (; attr; attr = attr->next) { 79396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_list_t *pds = 0; 79496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh for (curr = attr->val.dataseq; curr; curr = curr->next) 79596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh pds = sdp_list_append(pds, curr->val.dataseq); 79696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh ap = sdp_list_append(ap, pds); 79796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh } 79896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 79996c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh int ch = sdp_get_proto_port(ap, RFCOMM_UUID); 80096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_list_foreach(ap, (sdp_list_func_t) sdp_list_free, NULL); 80196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_list_free(ap, NULL); 80296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh ap = NULL; 80396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 80496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh dbus_message_append_args(reply, DBUS_TYPE_INT32, &ch, DBUS_TYPE_INVALID); 80596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 80696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh return reply; 80796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh} 80896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 80996c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganeshstatic DBusMessage *get_service_attribute_value(DBusConnection *conn, 81096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh DBusMessage *msg, 81196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh void *user_data) 81296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh{ 81396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh struct btd_device *device = user_data; 81496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh const sdp_record_t *rec; 81596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh sdp_data_t *attr_data; 81696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh const char *pattern; 81796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh uint16_t attrId; 81896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh int err; 81996c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 82096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 82196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh DBUS_TYPE_UINT16, &attrId, 82296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh DBUS_TYPE_INVALID) == FALSE) 82396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh goto fail; 82496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 82596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh if (strlen(pattern) == 0) 82696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh return btd_error_invalid_args(msg); 82796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 82896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh rec = btd_device_get_record(device, pattern); 82996c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh if (rec == NULL) { 83096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh error("rec is NULL"); 83196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh goto fail; 83296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh } 83396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 83496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh attr_data = sdp_data_get(rec, attrId); 83596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 83696c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh if (attr_data == NULL) { 83796c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh error("attr in null"); 83896c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh goto fail; 83996c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh } 84096c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh return get_service_attribute_value_reply(msg, conn, attr_data); 84196c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganeshfail: 84296c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", 84396c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh "GetServiceAttribute Failed"); 84496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh} 84596c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh 846e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = { 847e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "GetProperties", "", "a{sv}", get_properties }, 848e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "SetProperty", "sv", "", set_property }, 849e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann { "DiscoverServices", "s", "a{us}", discover_services, 85094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann G_DBUS_METHOD_FLAG_ASYNC}, 85194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "CancelDiscovery", "", "", cancel_discover }, 852c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz { "Disconnect", "", "", disconnect, 853c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz G_DBUS_METHOD_FLAG_ASYNC}, 85496c354b4b6b1f3480c4129621cf7f82171577057Jaikumar Ganesh { "GetServiceAttributeValue", "sq", "i", get_service_attribute_value}, 85594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 8562c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 8572c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 858e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = { 85994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "PropertyChanged", "sv" }, 86094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "DisconnectRequested", "" }, 86194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 8622c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 8632c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 864c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzgboolean device_is_connected(struct btd_device *device) 865e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 866bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg return device->connected; 867e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 868e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 869bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedbergvoid device_add_connection(struct btd_device *device, DBusConnection *conn) 870c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 871bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (device->connected) { 87216348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 87316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 874bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg error("Device %s is already connected", addr); 875c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 876c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 877c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 878bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg device->connected = TRUE; 879c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 880b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg emit_property_changed(conn, device->path, 881b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DEVICE_INTERFACE, "Connected", 882b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBUS_TYPE_BOOLEAN, &device->connected); 883c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 884c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 885bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedbergvoid device_remove_connection(struct btd_device *device, DBusConnection *conn) 886c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 887bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (!device->connected) { 88816348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 88916348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 890bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg error("Device %s isn't connected", addr); 891c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 892c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 893c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 894bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg device->connected = FALSE; 895c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 896ff0bc3cc49f697bf1d4b84e3d2be1c338b2ddb09Daniel Orstadius if (device->disconn_timer > 0) { 897ff0bc3cc49f697bf1d4b84e3d2be1c338b2ddb09Daniel Orstadius g_source_remove(device->disconn_timer); 898ff0bc3cc49f697bf1d4b84e3d2be1c338b2ddb09Daniel Orstadius device->disconn_timer = 0; 899ff0bc3cc49f697bf1d4b84e3d2be1c338b2ddb09Daniel Orstadius } 900ff0bc3cc49f697bf1d4b84e3d2be1c338b2ddb09Daniel Orstadius 9015c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz while (device->disconnects) { 9025c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz DBusMessage *msg = device->disconnects->data; 9035c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz 9045c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID); 9055c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz device->disconnects = g_slist_remove(device->disconnects, msg); 9065c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz } 9075c60413b3f97c203d164ae717af02de10cfbac34Luiz Augusto von Dentz 9083e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy if (device_is_paired(device) && !device->bonded) 9093e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy device_set_paired(device, FALSE); 9103e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy 911b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg emit_property_changed(conn, device->path, 912b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DEVICE_INTERFACE, "Connected", 913b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBUS_TYPE_BOOLEAN, &device->connected); 914c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 915c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 9168d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentzguint device_add_disconnect_watch(struct btd_device *device, 9178d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz disconnect_watch watch, void *user_data, 9188d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz GDestroyNotify destroy) 9198d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz{ 9208d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz struct btd_disconnect_data *data; 9218d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz static guint id = 0; 9228d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9238d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data = g_new0(struct btd_disconnect_data, 1); 9248d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data->id = ++id; 9258d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data->watch = watch; 9268d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data->user_data = user_data; 9278d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data->destroy = destroy; 9288d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9298d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz device->watches = g_slist_append(device->watches, data); 9308d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9318d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz return data->id; 9328d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz} 9338d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9348d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentzvoid device_remove_disconnect_watch(struct btd_device *device, guint id) 9358d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz{ 9368d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz GSList *l; 9378d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9388d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz for (l = device->watches; l; l = l->next) { 9398d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz struct btd_disconnect_data *data = l->data; 9408d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9418d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz if (data->id == id) { 9428d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz device->watches = g_slist_remove(device->watches, 9438d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data); 9448d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz if (data->destroy) 9458d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz data->destroy(data->user_data); 9468d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz g_free(data); 9478d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz return; 9488d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz } 9498d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz } 9508d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz} 9518d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz 9527c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstruct btd_device *device_create(DBusConnection *conn, 953f1beea3e80b6e02f49eeea926d398366b13d291cClaudio Takahasi struct btd_adapter *adapter, 954f1beea3e80b6e02f49eeea926d398366b13d291cClaudio Takahasi const gchar *address, device_type_t type) 95586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 956ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite gchar *address_up; 957555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 958139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann const gchar *adapter_path = adapter_get_path(adapter); 959a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz bdaddr_t src; 96048a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz char srcaddr[18], alias[MAX_NAME_LENGTH + 1]; 96186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 962555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode device = g_try_malloc0(sizeof(struct btd_device)); 96386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 96486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 96586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 966ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite address_up = g_ascii_strup(address, -1); 967139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up); 96886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 969ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite g_free(address_up); 97086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 9718e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("Creating device %s", device->path); 97286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 973e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, 974e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device_methods, device_signals, NULL, 975e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device, device_free) == FALSE) { 97686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 97786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 97886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 979da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 980cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str2ba(address, &device->bdaddr); 981da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 982f1beea3e80b6e02f49eeea926d398366b13d291cClaudio Takahasi device->type = type; 983a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz adapter_get_address(adapter, &src); 984a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz ba2str(&src, srcaddr); 985a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz read_device_name(srcaddr, address, device->name); 98648a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz if (read_device_alias(srcaddr, address, alias, sizeof(alias)) == 0) 98748a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz device->alias = g_strdup(alias); 9886da6e4e3de7f1800e5b736add0b944d33d3acf37Luiz Augusto von Dentz device->trusted = read_trust(&src, address, GLOBAL_TRUST); 989da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 9901e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (read_blocked(&src, &device->bdaddr)) 9911e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device_block(conn, device); 9921e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 9933e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) { 9946fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg device->paired = TRUE; 9953e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy device_set_bonded(device, TRUE); 9963e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy } 9976fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg 9980ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz return btd_device_ref(device); 99986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 100086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 1001a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentzvoid device_set_name(struct btd_device *device, const char *name) 1002a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz{ 1003a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 1004a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 100508fef64ca40b85782a0de1c1fd098934355b5e24Johan Hedberg if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0) 1006a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz return; 1007a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 100808fef64ca40b85782a0de1c1fd098934355b5e24Johan Hedberg strncpy(device->name, name, MAX_NAME_LENGTH); 1009a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 1010a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz emit_property_changed(conn, device->path, 1011a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DEVICE_INTERFACE, "Name", 1012a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBUS_TYPE_STRING, &name); 1013a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 101448a2c31cdbc1f2ac2a2bbadbd505976f84a9eacaLuiz Augusto von Dentz if (device->alias != NULL) 1015a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz return; 1016a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 1017a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz emit_property_changed(conn, device->path, 1018a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DEVICE_INTERFACE, "Alias", 1019a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBUS_TYPE_STRING, &name); 1020a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz} 1021a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 10225d787d0c25ea650672d93459d7a898491f0b6344Johan Hedbergvoid device_get_name(struct btd_device *device, char *name, size_t len) 10235d787d0c25ea650672d93459d7a898491f0b6344Johan Hedberg{ 10245d787d0c25ea650672d93459d7a898491f0b6344Johan Hedberg strncpy(name, device->name, len); 10255d787d0c25ea650672d93459d7a898491f0b6344Johan Hedberg} 10265d787d0c25ea650672d93459d7a898491f0b6344Johan Hedberg 10277e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demariodevice_type_t device_get_type(struct btd_device *device) 10287e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario{ 10297e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario return device->type; 10307e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario} 10317e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 1032b31576d0de87754f2fa1c3ba2d231cdccbffaee1Luiz Augusto von Dentzvoid device_remove_bonding(struct btd_device *device) 10332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 10342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 1035204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasi char srcaddr[18], dstaddr[18]; 10362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t bdaddr; 10372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 10382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(device->adapter, &bdaddr); 10392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&bdaddr, srcaddr); 10402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 10412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 10422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 10432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 10442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1045204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasi /* Delete the link key from storage */ 1046204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasi textfile_casedel(filename, dstaddr); 10473e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy device_set_bonded(device, FALSE); 10482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 10491bf7ec6b5c5a786775813650a6ef00f47b4d11ecJohan Hedberg btd_adapter_remove_bonding(device->adapter, &device->bdaddr); 10502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 10512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1052204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasistatic void device_remove_stored(struct btd_device *device) 10537dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz{ 10547dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz bdaddr_t src; 10557dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz char addr[18]; 1056e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius DBusConnection *conn = get_dbus_connection(); 10577dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz 10587dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz adapter_get_address(device->adapter, &src); 10597dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz ba2str(&device->bdaddr, addr); 1060e9071e3bfdf24666ff126d0023f3f4cf2ca74b2fJaikumar Ganesh 10616fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg if (device->paired) 10626fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg device_remove_bonding(device); 10637dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz delete_entry(&src, "profiles", addr); 10647dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz delete_entry(&src, "trusts", addr); 10655ae3733f9c81cd590e735a1e2cac1f261e881f9aVinicius Costa Gomes delete_entry(&src, "types", addr); 10665ae3733f9c81cd590e735a1e2cac1f261e881f9aVinicius Costa Gomes delete_entry(&src, "primary", addr); 1067e9071e3bfdf24666ff126d0023f3f4cf2ca74b2fJaikumar Ganesh delete_all_records(&src, &device->bdaddr); 1068727ae28e17be0910c9d5cdba6c8e373a704f7dbfClaudio Takahasi delete_device_service(&src, &device->bdaddr); 1069e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius 1070e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius if (device->blocked) 1071e0eddab0745f605fba545d03e84ed13769d744c8Daniel Orstadius device_unblock(conn, device, TRUE); 10727dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz} 10737dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz 1074204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasivoid device_remove(struct btd_device *device, gboolean remove_stored) 107575add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{ 1076f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 10778e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("Removing device %s", device->path); 1078f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 107950996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg if (device->agent) 108050996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg agent_free(device->agent); 108150996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg 1082253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg if (device->bonding) { 1083253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg uint8_t status; 1084253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg 1085253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg if (device->connected) 1086253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg status = HCI_OE_USER_ENDED_CONNECTION; 1087253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg else 1088253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg status = HCI_PAGE_TIMEOUT; 1089253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg 1090253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg device_cancel_bonding(device, status); 1091253209e37f869638caec4f9ab9a7e45586380c07Johan Hedberg } 10922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 109388386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi if (device->browse) { 109488386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi discover_services_reply(device->browse, -ECANCELED, NULL); 1095c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz browse_request_cancel(device->browse); 109688386d8ee86158137eca2cc849f80136af12f635Claudio Takahasi } 1097c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 1098bda6bb0079268b7db27695f40168aba07e960d8bJohan Hedberg if (device->connected) 109902d1a26d52d077c2b61c740fff96a28a940fee6fLuiz Augusto von Dentz do_disconnect(device); 1100c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz 110104e2e66722dfc8f26b159bdd280c981d9903258cLuiz Augusto von Dentz if (remove_stored) 1102204ab018f03d0d65f07b19cf4f777660b7d54249Claudio Takahasi device_remove_stored(device); 11032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 11046c212766c4e44ea1b47be61c2eb34a02ba50b81aJohan Hedberg g_slist_foreach(device->drivers, (GFunc) driver_remove, device); 11051e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg g_slist_free(device->drivers); 11061e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg device->drivers = NULL; 11076061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 1108279a53827334deab5093876e27261d38937bda36Vinicius Costa Gomes attrib_client_unregister(device); 1109279a53827334deab5093876e27261d38937bda36Vinicius Costa Gomes 11100ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz btd_device_unref(device); 111186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 1112ff296428a08dee619db1cc702146faefa91087faCidorvan Leite 1113555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address) 1114ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{ 1115cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char addr[18]; 1116cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 1117cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, addr); 1118cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return strcasecmp(addr, address); 1119ff296428a08dee619db1cc702146faefa91087faCidorvan Leite} 11203d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 11213870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedbergstatic gboolean record_has_uuid(const sdp_record_t *rec, 11223870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg const char *profile_uuid) 1123f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 11243870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg sdp_list_t *pat; 1125f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11263870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg for (pat = rec->pattern; pat != NULL; pat = pat->next) { 1127f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz char *uuid; 11283870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg int ret; 1129f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11303870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg uuid = bt_uuid2string(pat->data); 1131f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!uuid) 1132f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 1133f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11343870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg ret = strcasecmp(uuid, profile_uuid); 1135f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11363870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg g_free(uuid); 11373870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg 11383870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg if (ret == 0) 11393870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return TRUE; 1140f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 1141f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11423870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return FALSE; 1143f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 1144f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1145f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_pattern(struct btd_device *device, 1146878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg const char *match_uuid, 1147f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 1148f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 1149f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *l, *uuids = NULL; 1150f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1151f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (l = profiles; l; l = l->next) { 1152878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg char *profile_uuid = l->data; 1153f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz const sdp_record_t *rec; 11543bb7c1527ce3ec67127200b54a8fbc01a196ebadJohan Hedberg 1155878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg rec = btd_device_get_record(device, profile_uuid); 1156f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!rec) 1157f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 1158f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1159a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg if (record_has_uuid(rec, match_uuid)) 1160878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg uuids = g_slist_append(uuids, profile_uuid); 1161cdfe8a8246013031f55c647092e41adbb29ace81Johan Hedberg } 1162f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1163f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 1164f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 1165f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1166f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_driver(struct btd_device *device, 1167f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_device_driver *driver, 1168f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 1169f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{ 11706061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann const char **uuid; 1171f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *uuids = NULL; 1172f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1173f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 1174f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *match; 1175f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 11769b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz /* skip duplicated uuids */ 11779b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz if (g_slist_find_custom(uuids, *uuid, 11789b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz (GCompareFunc) strcasecmp)) 11799b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz continue; 11809b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz 1181f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match profile driver */ 1182f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = g_slist_find_custom(profiles, *uuid, 1183f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz (GCompareFunc) strcasecmp); 1184f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (match) { 1185f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 1186f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 1187f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 1188f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1189f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match pattern driver */ 1190f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = device_match_pattern(device, *uuid, profiles); 1191b358f4f350211dfd9d52a0b4fbc611b0c711bcddClaudio Takahasi uuids = g_slist_concat(uuids, match); 1192f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 1193f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1194f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 1195f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 1196f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1197f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzvoid device_probe_drivers(struct btd_device *device, GSList *profiles) 1198f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 1199f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *list; 120016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 1201f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann int err; 1202f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 120316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 120416348199ed59c49a710805a5061c3f22477715bfJohan Hedberg 12051e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg if (device->blocked) { 120616348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Skipping drivers for blocked device %s", addr); 12071e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg goto add_uuids; 12081e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg } 12091e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedberg 121016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Probing drivers for %s", addr); 1211f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 1212c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz for (list = device_drivers; list; list = list->next) { 1213e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann struct btd_device_driver *driver = list->data; 1214f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *probe_uuids; 1215f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 1216f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz probe_uuids = device_match_driver(device, driver, profiles); 12174b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 1218f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!probe_uuids) 1219f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 1220081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 1221f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz err = driver->probe(device, probe_uuids); 1222f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (err < 0) { 122316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg error("%s driver probe failed for device %s", 122416348199ed59c49a710805a5061c3f22477715bfJohan Hedberg driver->name, addr); 1225548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg g_slist_free(probe_uuids); 1226f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 1227f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 1228f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 1229521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasi device->drivers = g_slist_append(device->drivers, driver); 1230f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_slist_free(probe_uuids); 1231f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 123236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 12331e4d4fe0ed499adaf3e61b1e593dccd3c0928158Johan Hedbergadd_uuids: 1234f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (list = profiles; list; list = list->next) { 1235c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann GSList *l = g_slist_find_custom(device->uuids, list->data, 12367c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (GCompareFunc) strcasecmp); 1237c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann if (l) 1238c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann continue; 1239c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann 124036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_insert_sorted(device->uuids, 12417c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg g_strdup(list->data), 12427c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (GCompareFunc) strcasecmp); 1243548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 124436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 124536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 124699bc055edc4b9ba8ccda791757a6439fb03ff8f2Marcel Holtmannstatic void device_remove_drivers(struct btd_device *device, GSList *uuids) 124736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 124818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 1249352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg GSList *list, *next; 1250cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 12512a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 1252548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *records; 12532a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 12542a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 1255cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 1256cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 125736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1258548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = read_records(&src, &device->bdaddr); 1259548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 126016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Removing drivers for %s", dstaddr); 126136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1262352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg for (list = device->drivers; list; list = next) { 1263521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasi struct btd_device_driver *driver = list->data; 126436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const char **uuid; 126536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1266352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg next = list->next; 1267352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg 126836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 12699b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 1270155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh (GCompareFunc) strcasecmp)) 127136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 127236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 12738e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("UUID %s was removed from device %s", 12747c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg *uuid, dstaddr); 1275548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1276e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 127736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->drivers = g_slist_remove(device->drivers, 1278521006ef7b0737739e4e2c66564ed458a348f566Claudio Takahasi driver); 1279155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh break; 1280155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh } 1281155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh } 12829b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz 1283155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh for (list = uuids; list; list = list->next) { 1284155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh sdp_record_t *rec; 1285548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1286155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh device->uuids = g_slist_remove(device->uuids, list->data); 1287155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh 1288155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh rec = find_record_in_list(records, list->data); 1289155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh if (!rec) 1290155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh continue; 1291155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh 1292155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh delete_record(srcaddr, dstaddr, rec->handle); 1293155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh 1294155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh records = sdp_list_remove(records, rec); 1295155e4e6fe2af8d662e26843c5fc15e6814622ddbJaikumar Ganesh sdp_record_free(rec); 12962d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg 129736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 129836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1299548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (records) 1300548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(records, (sdp_free_func_t) sdp_record_free); 1301f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann} 1302f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 130317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void services_changed(struct btd_device *device) 13043d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 1305533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg DBusConnection *conn = get_dbus_connection(); 13063d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz char **uuids; 13073d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz GSList *l; 130836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz int i; 13093d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 131036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 131136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 131236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids[i] = l->data; 131336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 131458f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg emit_array_property_changed(conn, device->path, DEVICE_INTERFACE, 1315d5e700051b1263b2028331d41d60de02a5a6f90eVinicius Costa Gomes "UUIDs", DBUS_TYPE_STRING, &uuids, i); 131636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 131736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuids); 131836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 131936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 13208b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b) 13218b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{ 13228b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r1 = a; 13238b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r2 = b; 13248b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 13258b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg return r1->handle - r2->handle; 13268b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg} 13278b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 132836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs) 132936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 1330555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 133118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 133236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *seq; 1333cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 13342a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 13352a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 13362a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 1337cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 1338cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 13393d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 134036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 13413d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 134236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *svcclass = NULL; 13430dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg gchar *profile_uuid; 134436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *l; 13453d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 13463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!rec) 13473d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz break; 13483d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 134936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (sdp_get_service_classes(rec, &svcclass) < 0) 135036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 135136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 135223844f34167a89b687970d308e2620f8e106f8dfJohan Hedberg /* Check for empty service classes list */ 135323844f34167a89b687970d308e2620f8e106f8dfJohan Hedberg if (svcclass == NULL) { 13548e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("Skipping record with no service classes"); 135523844f34167a89b687970d308e2620f8e106f8dfJohan Hedberg continue; 135623844f34167a89b687970d308e2620f8e106f8dfJohan Hedberg } 135723844f34167a89b687970d308e2620f8e106f8dfJohan Hedberg 135836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Extract the first element and skip the remainning */ 13590dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid = bt_uuid2string(svcclass->data); 13600dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!profile_uuid) { 1361aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 136236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 1363aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg } 136436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 13650dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!strcasecmp(profile_uuid, PNP_UUID)) { 1366fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann uint16_t source, vendor, product, version; 1367e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse sdp_data_t *pdlist; 1368e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1369fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE); 1370fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann source = pdlist ? pdlist->val.uint16 : 0x0000; 1371fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann 1372e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); 1373e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse vendor = pdlist ? pdlist->val.uint16 : 0x0000; 1374e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1375e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); 1376e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse product = pdlist ? pdlist->val.uint16 : 0x0000; 1377e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1378e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); 1379e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version = pdlist ? pdlist->val.uint16 : 0x0000; 1380e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1381fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann if (source || vendor || product || version) 1382fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann store_device_id(srcaddr, dstaddr, source, 1383fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann vendor, product, version); 1384e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse } 1385e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 138637a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg /* Check for duplicates */ 1387981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg if (sdp_list_find(req->records, rec, rec_cmp)) { 13880dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 1389aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 139037a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg continue; 1391981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg } 139237a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1393cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode store_record(srcaddr, dstaddr, rec); 139437a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1395681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Copy record */ 13967c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg req->records = sdp_list_append(req->records, 13977c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sdp_copy_record(rec)); 1398681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 13990dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l = g_slist_find_custom(device->uuids, profile_uuid, 1400c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann (GCompareFunc) strcmp); 140136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!l) 14020dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_added = 14030dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_append(req->profiles_added, 14040dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid); 140536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz else { 14060dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = 14070dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_remove(req->profiles_removed, 14080dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l->data); 14090dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 14103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 14113d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 141236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_free(svcclass, free); 14133d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 141436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 141536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 141617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void store_profiles(struct btd_device *device) 141736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 141818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 1419cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 142036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz char *str; 14213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 14222a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 14233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 142436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!device->uuids) { 1425cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, ""); 142636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz return; 142736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 142836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 142936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz str = bt_list2string(device->uuids); 1430cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, str); 143136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(str); 143236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 143336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 143432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadiusstatic void create_device_reply(struct btd_device *device, struct browse_req *req) 143532c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius{ 143632c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius DBusMessage *reply; 143732c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius 143832c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius reply = dbus_message_new_method_return(req->msg); 143932c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius if (!reply) 144032c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius return; 144132c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius 144232c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, 144332c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius DBUS_TYPE_INVALID); 144432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius 144532c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius g_dbus_send_message(req->conn, reply); 144632c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius} 144732c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius 1448d14f607a0374bc313e410987ddd357581336003eClaudio TakahasiGSList *device_services_from_record(struct btd_device *device, GSList *profiles) 1449612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi{ 1450612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi GSList *l, *prim_list = NULL; 1451612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi char *att_uuid; 1452612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi uuid_t proto_uuid; 1453612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1454612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi sdp_uuid16_create(&proto_uuid, ATT_UUID); 1455612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi att_uuid = bt_uuid2string(&proto_uuid); 1456612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1457612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi for (l = profiles; l; l = l->next) { 1458612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi const char *profile_uuid = l->data; 1459612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi const sdp_record_t *rec; 1460612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi struct att_primary *prim; 1461612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi uint16_t start = 0, end = 0, psm = 0; 1462612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi uuid_t prim_uuid; 1463612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1464612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi rec = btd_device_get_record(device, profile_uuid); 1465612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi if (!rec) 1466612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi continue; 1467612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1468612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi if (!record_has_uuid(rec, att_uuid)) 1469612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi continue; 1470612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1471612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end)) 1472612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi continue; 1473612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1474612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi prim = g_new0(struct att_primary, 1); 1475612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi prim->start = start; 1476612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi prim->end = end; 1477612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid)); 1478612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1479612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi prim_list = g_slist_append(prim_list, prim); 1480612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi } 1481612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1482612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi g_free(att_uuid); 1483612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1484612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi return prim_list; 1485612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi} 1486612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 1487da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data) 148836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 148936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz struct browse_req *req = user_data; 1490555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 149116348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 149216348199ed59c49a710805a5061c3f22477715bfJohan Hedberg 149316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 14942a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 1495681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (err < 0) { 1496681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz error("%s: error updating services: %s (%d)", 149716348199ed59c49a710805a5061c3f22477715bfJohan Hedberg addr, strerror(-err), -err); 149832c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius goto send_reply; 1499681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 150036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 150136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz update_services(req, recs); 150236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 150345bc7305c6e0baeb6d0a3591e8622ef7c7135d74Luiz Augusto von Dentz if (device->tmp_records) 15047c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sdp_list_free(device->tmp_records, 15057c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (sdp_free_func_t) sdp_record_free); 150645bc7305c6e0baeb6d0a3591e8622ef7c7135d74Luiz Augusto von Dentz 150745bc7305c6e0baeb6d0a3591e8622ef7c7135d74Luiz Augusto von Dentz device->tmp_records = req->records; 150845bc7305c6e0baeb6d0a3591e8622ef7c7135d74Luiz Augusto von Dentz req->records = NULL; 1509548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 1510cfea4ccc6fc8e014bfbd5bb80de0a2b854fc373bJaikumar Ganesh if (!req->profiles_added && !req->profiles_removed) { 151116348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("%s: No service update", addr); 151232c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius goto send_reply; 1513cfea4ccc6fc8e014bfbd5bb80de0a2b854fc373bJaikumar Ganesh } 1514cfea4ccc6fc8e014bfbd5bb80de0a2b854fc373bJaikumar Ganesh 151536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Probe matching drivers for services added */ 1516612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi if (req->profiles_added) { 1517612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi GSList *list; 1518612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 15190dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_probe_drivers(device, req->profiles_added); 15202efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 1521d14f607a0374bc313e410987ddd357581336003eClaudio Takahasi list = device_services_from_record(device, req->profiles_added); 1522612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi if (list) 15231f8969c0435f8d49c20f46dba9bece21031997c7Johan Hedberg device_register_services(req->conn, device, list, 15241f8969c0435f8d49c20f46dba9bece21031997c7Johan Hedberg ATT_PSM); 1525612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi } 1526612d0207646064f309edd564a69d30b42de9e26fClaudio Takahasi 152736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Remove drivers for services removed */ 15280dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_removed) 15290dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_remove_drivers(device, req->profiles_removed); 15302efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 153136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Propagate services changes */ 153217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(req->device); 1533f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 153432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadiussend_reply: 15352ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg if (!req->msg) 15362ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg goto cleanup; 15372ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg 1538438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, 153932c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius "DiscoverServices")) 154045bc7305c6e0baeb6d0a3591e8622ef7c7135d74Luiz Augusto von Dentz discover_services_reply(req, err, device->tmp_records); 154132c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE, 154232c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius "CreatePairedDevice")) 154332c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius create_device_reply(device, req); 154432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE, 154532c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius "CreateDevice")) { 154632c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius if (err < 0) { 154792a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan DBusMessage *reply; 154892a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan reply = btd_error_failed(req->msg, strerror(-err)); 154992a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan g_dbus_send_message(req->conn, reply); 155032c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius goto cleanup; 155132c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius } 15523d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 155332c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius create_device_reply(device, req); 155432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius device_set_temporary(device, FALSE); 155532c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius } 1556048cda340a2e17a89cab71e8c40ff9a1c66ea5c1Luiz Augusto von Dentz 15571e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup: 155827b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes if (!device->temporary) { 155927b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes bdaddr_t sba, dba; 156027b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes 156127b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes adapter_get_address(device->adapter, &sba); 156227b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes device_get_address(device, &dba); 156327b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes 156432c43b955601343cbaa041be0ec1c8671071db5cDaniel Orstadius store_profiles(device); 156527b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes write_device_type(&sba, &dba, device->type); 156627b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes } 156727b16a98221951d9fb931e46b8af65bd8d185324Vinicius Costa Gomes 1568a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz device->browse = NULL; 15692499fb1f1775b8afcb374ba3aefc0c5484e78fa4Johan Hedberg browse_request_free(req); 1570da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1571da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1572da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data) 1573da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1574da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct browse_req *req = user_data; 1575da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_device *device = req->device; 1576da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1577cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1578da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz uuid_t uuid; 1579da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 15807c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg /* If we have a valid response and req->search_uuid == 2, then L2CAP 15817c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg * UUID & PNP searching was successful -- we are done */ 15820cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg if (err < 0 || (req->search_uuid == 2 && req->records)) { 15830cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg if (err == -ECONNRESET && req->reconnect_attempt < 1) { 15840cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg req->search_uuid--; 15850cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg req->reconnect_attempt++; 15860cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg } else 15870cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg goto done; 15880cd8e651b6f004bcc64387d59f6bcb29190ffed6Johan Hedberg } 1589da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1590da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz update_services(req, recs); 1591da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1592da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz adapter_get_address(adapter, &src); 1593da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1594da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz /* Search for mandatory uuids */ 15957d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (uuid_list[req->search_uuid]) { 15967d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1597c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann bt_search_service(&src, &device->bdaddr, &uuid, 1598c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann browse_cb, user_data, NULL); 1599da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz return; 1600da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz } 1601da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1602da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone: 1603da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz search_cb(recs, err, user_data); 1604da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1605da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 160669adac833c5633714b84bf840c75aa814193b8a6Johan Hedbergstatic void init_browse(struct browse_req *req, gboolean reverse) 1607da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1608da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz GSList *l; 1609da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 161069adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg /* If we are doing reverse-SDP don't try to detect removed profiles 161169adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * since some devices hide their service records while they are 161269adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * connected 161369adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg */ 161469adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg if (reverse) 161569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg return; 161669adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg 1617da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz for (l = req->device->uuids; l; l = l->next) 16180dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = g_slist_append(req->profiles_removed, 1619da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz l->data); 16203d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 16213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1622d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demariostatic char *primary_list_to_string(GSList *primary_list) 1623d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario{ 1624d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario GString *services; 1625d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario GSList *l; 1626d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1627d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario services = g_string_new(NULL); 1628d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1629d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario for (l = primary_list; l; l = l->next) { 1630d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario struct att_primary *primary = l->data; 1631d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario char service[64]; 1632d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1633d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario memset(service, 0, sizeof(service)); 1634d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1635d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario snprintf(service, sizeof(service), "%04X#%04X#%s ", 1636d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario primary->start, primary->end, primary->uuid); 1637d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1638d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario services = g_string_append(services, service); 1639d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario } 1640d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1641d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario return g_string_free(services, FALSE); 1642d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario} 1643d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1644399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasistatic void store_services(struct btd_device *device) 1645399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi{ 1646399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi struct btd_adapter *adapter = device->adapter; 1647399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi bdaddr_t dba, sba; 16483a4be695834ccfac110c548cf870dc729c00f44cVinicius Costa Gomes char *str = primary_list_to_string(device->primaries); 1649399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi 1650399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi adapter_get_address(adapter, &sba); 1651399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi device_get_address(device, &dba); 1652399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi 1653399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi write_device_type(&sba, &dba, device->type); 1654399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi write_device_services(&sba, &dba, str); 1655399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi 1656399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi g_free(str); 1657399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi} 1658399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi 16595399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasistatic void primary_cb(GSList *services, guint8 status, gpointer user_data) 1660d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi{ 1661d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi struct browse_req *req = user_data; 1662d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi struct btd_device *device = req->device; 1663d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario GSList *l, *uuids = NULL; 1664d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 16655399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi if (status) { 166692a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan DBusMessage *reply; 16675399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi reply = btd_error_failed(req->msg, att_ecode2str(status)); 166892a56b931f72b218e0825f57a9bb8b7a4dbd44e7Gustavo F. Padovan g_dbus_send_message(req->conn, reply); 1669d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi goto done; 1670d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi } 1671d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 16725c36b74c0b43ae0532e26c03b6ce8a1abba7d874Claudio Takahasi services_changed(device); 16735c36b74c0b43ae0532e26c03b6ce8a1abba7d874Claudio Takahasi device_set_temporary(device, FALSE); 1674d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1675d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario for (l = services; l; l = l->next) { 1676d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario struct att_primary *prim = l->data; 1677d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario uuids = g_slist_append(uuids, prim->uuid); 1678d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario } 1679d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1680d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario device_probe_drivers(device, uuids); 1681bb5eda2bc85b68e9cf3908f39972b476afb6633fVinicius Costa Gomes 1682f194be5c746d1ad6f093d1b175b7b0e1ccafad58Bruna Moreira device_register_services(req->conn, device, g_slist_copy(services), -1); 1683bb5eda2bc85b68e9cf3908f39972b476afb6633fVinicius Costa Gomes 1684d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario g_slist_free(uuids); 1685d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 16865c36b74c0b43ae0532e26c03b6ce8a1abba7d874Claudio Takahasi create_device_reply(device, req); 1687d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 1688399ad77a2fc90c8df9ee9deae2cb85ce61639403Claudio Takahasi store_services(device); 1689d3cb258b9b9af0dcacfba0e6aa0db3f280554fb0Sheldon Demario 1690d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasidone: 1691d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi device->browse = NULL; 1692d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi browse_request_free(req); 1693d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi} 1694d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 16955399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasistatic void gatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) 16965399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi{ 16975399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi struct browse_req *req = user_data; 16985399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi struct btd_device *device = req->device; 16995399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17005399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi if (gerr) { 17015399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi DBusMessage *reply; 17025399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17035399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi DBG("%s", gerr->message); 17045399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17055399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi reply = btd_error_failed(req->msg, gerr->message); 17065399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi g_dbus_send_message(req->conn, reply); 17075399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17085399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi device->browse = NULL; 17095399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi browse_request_free(req); 17105399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17115399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi return; 17125399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi } 17135399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17145399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi req->attrib = g_attrib_new(io); 17151b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes g_io_channel_unref(io); 17161b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes 17175399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi gatt_discover_primary(req->attrib, NULL, primary_cb, req); 17185399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi} 17195399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17207e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demarioint device_browse_primary(struct btd_device *device, DBusConnection *conn, 17217e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario DBusMessage *msg, gboolean secure) 17223d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 172318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 17243d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz struct browse_req *req; 17255399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi BtIOSecLevel sec_level; 17261b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes GIOChannel *io; 1727cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 17287e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 17297e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario if (device->browse) 17307e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario return -EBUSY; 17312a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 1732d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi req = g_new0(struct browse_req, 1); 1733d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi req->device = btd_device_ref(device); 17341af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg 17352a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 17363d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 17375399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW; 17385399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17391b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes io = bt_io_connect(BT_IO_L2CAP, gatt_connect_cb, req, NULL, NULL, 17405399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi BT_IO_OPT_SOURCE_BDADDR, &src, 17415399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi BT_IO_OPT_DEST_BDADDR, &device->bdaddr, 17421f8969c0435f8d49c20f46dba9bece21031997c7Johan Hedberg BT_IO_OPT_CID, ATT_CID, 17435399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi BT_IO_OPT_SEC_LEVEL, sec_level, 17445399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi BT_IO_OPT_INVALID); 17455399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi 17461b0d082bf58143aaad02a819037989fddc6c6b95Vinicius Costa Gomes if (io == NULL ) { 1747d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi browse_request_free(req); 17485399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi return -EIO; 17497e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario } 1750438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 17517e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario if (conn == NULL) 17527e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario conn = get_dbus_connection(); 17537e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 17547e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario req->conn = dbus_connection_ref(conn); 17557e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario device->browse = req; 17567e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 17577e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario if (msg) { 17587e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario const char *sender = dbus_message_get_sender(msg); 17597e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 17607e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario req->msg = dbus_message_ref(msg); 17617e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario /* Track the request owner to cancel it 17627e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario * automatically if the owner exits */ 17637e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario req->listener_id = g_dbus_add_disconnect_watch(conn, 17647e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario sender, 17657e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario discover_services_req_exit, 17667e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario req, NULL); 1767d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi } 1768d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 17695399423bd667efa5d15d8dec895250fe5a3bbec2Claudio Takahasi return 0; 1770d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi} 1771d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 17727e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demarioint device_browse_sdp(struct btd_device *device, DBusConnection *conn, 17737e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario DBusMessage *msg, uuid_t *search, gboolean reverse) 1774d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi{ 1775d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi struct btd_adapter *adapter = device->adapter; 1776d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi struct browse_req *req; 1777d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi bt_callback_t cb; 1778d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi bdaddr_t src; 1779d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi uuid_t uuid; 17807e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario int err; 17817e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario 17827e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario if (device->browse) 17837e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario return -EBUSY; 17843d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1785d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi adapter_get_address(adapter, &src); 1786d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 1787d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi req = g_new0(struct browse_req, 1); 1788d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi req->device = btd_device_ref(device); 1789a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (search) { 1790040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi memcpy(&uuid, search, sizeof(uuid_t)); 1791da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = search_cb; 1792a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } else { 17937d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 179469adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg init_browse(req, reverse); 1795da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = browse_cb; 1796a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } 1797d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 17987e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL); 17997e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario if (err < 0) { 1800d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi browse_request_free(req); 1801d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi return err; 18027e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario } 1803d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 1804d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi if (conn == NULL) 1805d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi conn = get_dbus_connection(); 1806d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi 1807d49c4e8457a3169f32c9b7466516b2d2e83b0f6cClaudio Takahasi req->conn = dbus_connection_ref(conn); 1808a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz device->browse = req; 1809d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg 1810d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg if (msg) { 18117c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg const char *sender = dbus_message_get_sender(msg); 18127c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg 18135c6426eff87049c9f8e49877f650772840907239Luiz Augusto von Dentz req->msg = dbus_message_ref(msg); 1814d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg /* Track the request owner to cancel it 1815d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg * automatically if the owner exits */ 1816a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz req->listener_id = g_dbus_add_disconnect_watch(conn, 18177c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sender, 181895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz discover_services_req_exit, 1819e8610fcbe0341a4879b8230d97cd27f5f8cf9f58Luiz Augusto von Dentz req, NULL); 1820d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg } 182195e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz 1822a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz return err; 18233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 182424cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann 182518614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device) 1826dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{ 1827dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode if (!device) 1828dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return NULL; 1829dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 1830dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return device->adapter; 1831dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode} 1832dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 183319ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr) 1834aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{ 1835cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bacpy(bdaddr, &device->bdaddr); 1836aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode} 1837aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode 1838555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device) 183946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{ 184046fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode if (!device) 184146fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return NULL; 184246fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 184346fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return device->path; 184446fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode} 184546fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 1846555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device) 1847a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{ 1848a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode if (!device) 1849a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return NULL; 1850a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 185150996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg if (device->agent) 185250996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg return device->agent; 185350996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg 185450996c3a0b0eb98f3cb1c202257d063992c7220dJohan Hedberg return adapter_get_agent(device->adapter); 1855a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode} 1856a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1857555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device) 18589f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{ 1859a6a65ceb00cf583c8be297b4bf489eec7a92a768Luiz Augusto von Dentz return device->browse ? TRUE : FALSE; 18609f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode} 18619f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode 1862555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device) 1863f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{ 1864f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode return device->temporary; 1865f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode} 1866f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode 1867555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary) 1868595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{ 1869595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode if (!device) 1870595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode return; 1871595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1872b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("temporary %d", temporary); 187329227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 1874b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg device->temporary = temporary; 18752203f153c53189ec1c30df99b717e035681196e6Alok Barsode} 1876c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 18773e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliyvoid device_set_bonded(struct btd_device *device, gboolean bonded) 18783e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy{ 18793e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy if (!device) 18803e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy return; 18813e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy 18823e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy DBG("bonded %d", bonded); 18833e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy 18843e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy device->bonded = bonded; 18853e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy} 18863e28ead202ff45d0fd66876f6a9cd3e8c3dbf42eDmitriy Paliy 1887fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomesvoid device_set_type(struct btd_device *device, device_type_t type) 1888fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes{ 1889fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes if (!device) 1890fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes return; 1891fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes 1892fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes device->type = type; 1893fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes} 1894fba8f0e7d1fdefe35074f808a691e242d19edf92Vinicius Costa Gomes 1895013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergstatic gboolean start_discovery(gpointer user_data) 1896013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 1897013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg struct btd_device *device = user_data; 1898013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 18997e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario device_browse_sdp(device, NULL, NULL, NULL, TRUE); 1900013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1901013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg device->discov_timer = 0; 1902013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1903013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg return FALSE; 1904013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 1905013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 19068b78d14dd4ac9776f5848dee94ce2fcf976fd6d8Luiz Augusto von Dentzstatic DBusMessage *new_authentication_return(DBusMessage *msg, int status) 1907013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 19082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (status) { 19092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x00: /* success */ 19102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_method_return(msg); 19112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x04: /* page timeout */ 191396762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg return dbus_message_new_error(msg, 191496762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg ERROR_INTERFACE ".ConnectionAttemptFailed", 191596762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg "Page Timeout"); 19162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x08: /* connection timeout */ 191796762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg return dbus_message_new_error(msg, 191896762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg ERROR_INTERFACE ".ConnectionAttemptFailed", 191996762463061ffbe566c7f8916d230b4190ec3b6fJohan Hedberg "Connection Timeout"); 19202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x10: /* connection accept timeout */ 19212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x22: /* LMP response timeout */ 19222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x28: /* instant passed - is this a timeout? */ 19232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 19242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationTimeout", 19252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Timeout"); 19262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x17: /* too frequent pairing attempts */ 19272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 19282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".RepeatedAttempts", 19292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Repeated Attempts"); 19302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x06: 19322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */ 19332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 19342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationRejected", 19352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Rejected"); 19362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x07: /* memory capacity */ 19382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x09: /* connection limit */ 19392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0a: /* synchronous connection limit */ 19402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0d: /* limited resources */ 19412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x13: /* user ended the connection */ 19422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x14: /* terminated due to low resources */ 1943922daca3e63d106c8cb8a56575cec0d1d9bd45a5Luiz Augusto von Dentz case 0x16: /* connection terminated */ 19442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 19452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationCanceled", 19462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Canceled"); 19472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x05: /* authentication failure */ 19492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0E: /* rejected due to security reasons - is this auth failure? */ 19502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x25: /* encryption mode not acceptable - is this auth failure? */ 19512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x26: /* link key cannot be changed - is this auth failure? */ 19522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x29: /* pairing with unit key unsupported - is this auth failure? */ 19532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x2f: /* insufficient security - is this auth failure? */ 19542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 19552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 19562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationFailed", 19572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Failed"); 19582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 19592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19618d07c9eea9156c18c9323cb08728566e5f446703Luiz Augusto von Dentzstatic void bonding_request_free(struct bonding_req *bonding) 19622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 19642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 19662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->listener_id) 19692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_remove_watch(bonding->conn, bonding->listener_id); 197068b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 19712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->msg) 19722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_unref(bonding->msg); 19732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->conn) 19752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_connection_unref(bonding->conn); 19762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19778d07c9eea9156c18c9323cb08728566e5f446703Luiz Augusto von Dentz if (bonding->io) 19782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_unref(bonding->io); 19792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device = bonding->device; 19814c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz g_free(bonding); 19822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19834c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz if (!device) 19844c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz return; 19852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = NULL; 19874c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz 19883ba95c2c6e3ae23b385d70e96cd733626ca87244Luiz Augusto von Dentz adapter_resume_discovery(device->adapter); 19893ba95c2c6e3ae23b385d70e96cd733626ca87244Luiz Augusto von Dentz 19904c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz if (!device->agent) 19914c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz return; 19924c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz 19932975f0c78ce85dd5cfa85be196ac14a4d570e48cJohan Hedberg agent_cancel(device->agent); 1994cc35f24a2a728c4e8c31ea0c6c11c6b701901861Johan Hedberg agent_free(device->agent); 19954c736d92510c0a61fa8df49698903676c4e21d4bLuiz Augusto von Dentz device->agent = NULL; 19962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19986fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedbergvoid device_set_paired(struct btd_device *device, gboolean value) 19992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 200168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 20026fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg if (device->paired == value) 20036fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg return; 20046fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg 20056fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg device->paired = value; 20066fe85942c1272ef3d4ef68a35eade7a276219bb6Johan Hedberg 2007c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired", 20082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &value); 20092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_agent_removed(struct agent *agent, void *user_data) 20122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 20142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2015e5e25c761845284c6aca75599bc75c8e0d901311Johan Hedberg device->agent = NULL; 20162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 20182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr->agent = NULL; 20192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic struct bonding_req *bonding_request_new(DBusConnection *conn, 20222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 20232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device, 20242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 20252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 20262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 20282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *name = dbus_message_get_sender(msg); 20292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 203016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 20312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 203216348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 203316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Requesting bonding for %s", addr); 20342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent_path) 20362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto proceed; 20372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = agent_create(device->adapter, name, agent_path, 20392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability, 20402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_agent_removed, 20412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 20422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 20432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Unable to create a new agent"); 20442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 20452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->agent = agent; 20482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20498e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("Temporary agent registered for %s at %s:%s", 205016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg addr, name, agent_path); 20512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzproceed: 20532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = g_new0(struct bonding_req, 1); 20542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->conn = dbus_connection_ref(conn); 20562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->msg = dbus_message_ref(msg); 20572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20583ba95c2c6e3ae23b385d70e96cd733626ca87244Luiz Augusto von Dentz adapter_suspend_discovery(device->adapter); 20593ba95c2c6e3ae23b385d70e96cd733626ca87244Luiz Augusto von Dentz 20602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return bonding; 20612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void create_bond_req_exit(DBusConnection *conn, void *user_data) 20642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 206616348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 20672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 206816348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 206916348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("%s: requestor exited before bonding was completed", addr); 20702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 2072f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg device_cancel_authentication(device, FALSE); 20732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) { 20752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->listener_id = 0; 2076c3cfa26a86a25e35d8b0e7c24978a44f9af80a2aLuiz Augusto von Dentz device_request_disconnect(device, NULL); 20772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von DentzDBusMessage *device_create_bonding(struct btd_device *device, 20812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn, 20822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 20832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 20842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 20852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 20872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char *str, srcaddr[18], dstaddr[18]; 20882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 20892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 20902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t src; 2091b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg int err; 20922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(adapter, &src); 20942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&src, srcaddr); 20952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 20962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 2098bd3cf4860d056d3044b7eb8a4e03c53934eb20a6Gustavo F. Padovan return btd_error_in_progress(msg); 20992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* check if a link key already exists */ 21012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 21022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 21032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz str = textfile_caseget(filename, dstaddr); 21052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (str) { 21062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz free(str); 210773774f1b253c882f9fa2a21b3df4b2bd52fbc3ceGustavo F. Padovan return btd_error_already_exists(msg); 21082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 21092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2110b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg err = adapter_create_bonding(adapter, &device->bdaddr, capability); 2111b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (err < 0) 2112b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg return btd_error_failed(msg, strerror(-err)); 21132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = bonding_request_new(conn, msg, device, agent_path, 21152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability); 21162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) { 2117b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg adapter_cancel_bonding(adapter, &device->bdaddr); 21182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 21192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 21202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->listener_id = g_dbus_add_disconnect_watch(conn, 21222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_get_sender(msg), 21232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_bond_req_exit, device, 21242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL); 21252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = bonding; 21272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->device = device; 21282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 21302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 21312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2132e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedbergvoid device_simple_pairing_complete(struct btd_device *device, uint8_t status) 2133e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg{ 2134e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg struct authentication_req *auth = device->authr; 2135e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 2136e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent) 2137e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg agent_cancel(auth->agent); 2138e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg} 2139e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 2140a53621433ce81981a1fc2e610086ff528f1770efJohan Hedbergstatic void device_auth_req_free(struct btd_device *device) 2141f0ab6f3c4c8de3a49591d484a59c30a021b4e4c1Johan Hedberg{ 2142f0ab6f3c4c8de3a49591d484a59c30a021b4e4c1Johan Hedberg g_free(device->authr); 2143f0ab6f3c4c8de3a49591d484a59c30a021b4e4c1Johan Hedberg device->authr = NULL; 2144f0ab6f3c4c8de3a49591d484a59c30a021b4e4c1Johan Hedberg} 2145f0ab6f3c4c8de3a49591d484a59c30a021b4e4c1Johan Hedberg 21462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_bonding_complete(struct btd_device *device, uint8_t status) 21472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 21482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 2149e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg struct authentication_req *auth = device->authr; 2150f945a68fa973a13a0f57437e291258eb9f05dd7aJaikumar Ganesh bdaddr_t bdaddr; 2151e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 2152b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg DBG("bonding %p status 0x%02x", bonding, status); 2153b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg 2154e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent) 2155e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg agent_cancel(auth->agent); 21562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21578bbc3fa4c0456c39c4174ab4be4bf39efe0de091jhtop.kim // Temporary hack till we move to mgmt interface. 21588bbc3fa4c0456c39c4174ab4be4bf39efe0de091jhtop.kim if (status == 0x06 && auth == NULL) { 2159f945a68fa973a13a0f57437e291258eb9f05dd7aJaikumar Ganesh device_remove_bonding(device); 2160f945a68fa973a13a0f57437e291258eb9f05dd7aJaikumar Ganesh device_get_address(device, &bdaddr); 2161f945a68fa973a13a0f57437e291258eb9f05dd7aJaikumar Ganesh btd_adapter_retry_authentication(device->adapter, &bdaddr); 21628bbc3fa4c0456c39c4174ab4be4bf39efe0de091jhtop.kim return; 2163f945a68fa973a13a0f57437e291258eb9f05dd7aJaikumar Ganesh } else if (status) { 21644a4471e7e071fe8e8ae68d1b130dac6db9748fe2Luiz Augusto von Dentz device_cancel_authentication(device, TRUE); 2165bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg device_cancel_bonding(device, status); 2166bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg return; 2167bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg } 21682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2169a53621433ce81981a1fc2e610086ff528f1770efJohan Hedberg device_auth_req_free(device); 2170bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 2171b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg /* If we're already paired nothing more is needed */ 2172b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg if (device->paired) 2173bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg return; 2174bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 2175b9efb73d372a913dc52b3ba216cb7ac8de9f4cbcJohan Hedberg device_set_paired(device, TRUE); 2176e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 217768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg /* If we were initiators start service discovery immediately. 217868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * However if the other end was the initator wait a few seconds 217968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * before SDP. This is due to potential IOP issues if the other 218068b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * end starts doing SDP at the same time as us */ 2181e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (bonding) { 2182629c9dbe7f161c0c285749bb014f55a2b30fd65cJohan Hedberg DBG("Proceeding with service discovery"); 2183e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg /* If we are initiators remove any discovery timer and just 2184e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg * start discovering services directly */ 2185e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (device->discov_timer) { 2186e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg g_source_remove(device->discov_timer); 2187e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg device->discov_timer = 0; 2188e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 2189e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 21907e6edb65cfabc1b9a7f131f6f51938bb1f57f0f9Sheldon Demario device_browse_sdp(device, bonding->conn, bonding->msg, 21912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL, FALSE); 21925e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz 2193e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg bonding_request_free(bonding); 2194e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg } else { 21955e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz if (!device->browse && !device->discov_timer && 21965e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz main_opts.reverse_sdp) { 21975e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz /* If we are not initiators and there is no currently 21985e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz * active discovery or discovery timer, set discovery 21995e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz * timer */ 22008e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan DBG("setting timer for reverse service discovery"); 22015e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz device->discov_timer = g_timeout_add_seconds( 22025e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz DISCOVERY_TIMER, 22035e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz start_discovery, 22045e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz device); 22055e5fbd39b64ff0ad84e9be9a51daa020638e679bLuiz Augusto von Dentz } 2206e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 22072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 22082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2209e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberggboolean device_is_creating(struct btd_device *device, const char *sender) 2210e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg{ 2211e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg DBusMessage *msg; 2212e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 2213e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg if (device->bonding && device->bonding->msg) 2214e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg msg = device->bonding->msg; 2215e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg else if (device->browse && device->browse->msg) 2216e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg msg = device->browse->msg; 2217e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg else 2218e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg return FALSE; 2219e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 2220e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg if (!dbus_message_is_method_call(msg, ADAPTER_INTERFACE, 2221e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg "CreatePairedDevice") && 2222e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg !dbus_message_is_method_call(msg, ADAPTER_INTERFACE, 2223e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg "CreateDevice")) 2224e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg return FALSE; 2225e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 2226e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg if (sender == NULL) 2227e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg return TRUE; 2228e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 2229e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg return g_str_equal(sender, dbus_message_get_sender(msg)); 2230e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg} 2231e164ff20b95acd2a25c70623212c190abf7eee19Johan Hedberg 22322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_bonding(struct btd_device *device, const char *sender) 22332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 22342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 22352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!device->bonding) 22372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 22382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!sender) 22402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return TRUE; 22412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_str_equal(sender, dbus_message_get_sender(bonding->msg)); 22432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 2244e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 22452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_cancel_bonding(struct btd_device *device, uint8_t status) 22462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 22472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 22482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply; 224916348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 22502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 22522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 22532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 225416348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 225516348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Canceling bonding request for %s", addr); 22562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 2258f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg device_cancel_authentication(device, FALSE); 22592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz reply = new_authentication_return(bonding->msg, status); 22612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(bonding->conn, reply); 22622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22638d07c9eea9156c18c9323cb08728566e5f446703Luiz Augusto von Dentz bonding_request_cancel(bonding); 22648d07c9eea9156c18c9323cb08728566e5f446703Luiz Augusto von Dentz bonding_request_free(bonding); 22652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 22662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2267bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedbergstatic void pincode_cb(struct agent *agent, DBusError *err, 2268bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg const char *pincode, void *data) 22692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 22702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 22712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 22722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 22742bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz if (auth->cb == NULL) 22752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 22762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, err, pincode, device); 22782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2279a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->cb = NULL; 2280a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->agent = NULL; 22812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 22822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void confirm_cb(struct agent *agent, DBusError *err, void *data) 22842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 22852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 22862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 22872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 22892bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz if (auth->cb == NULL) 22902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 22912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 22922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, err, device); 22932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2294a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->cb = NULL; 2295a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->agent = NULL; 22962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 22972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2298bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedbergstatic void passkey_cb(struct agent *agent, DBusError *err, 2299bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg uint32_t passkey, void *data) 23002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 23012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 23022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 23032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 23052bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz if (auth->cb == NULL) 23062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 23072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, err, passkey, device); 23092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2310a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->cb = NULL; 2311a9c4e4a0aec81cecbc2bded149b924028953a952Luiz Augusto von Dentz device->authr->agent = NULL; 23122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 23132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23147050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganeshstatic void pairing_consent_cb(struct agent *agent, DBusError *err, void *data) 23157050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh{ 23167050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh struct authentication_req *auth = data; 23177050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh struct btd_device *device = auth->device; 23187050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh 23197050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh /* No need to reply anything if the authentication already failed */ 23207050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh if (!auth->cb) 23217050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh return; 23227050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh 23237050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh ((agent_cb) auth->cb)(agent, err, device); 23247050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh 23257050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh auth->cb = NULL; 23267050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh} 23277050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh 23282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzint device_request_authentication(struct btd_device *device, auth_type_t type, 2329bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg uint32_t passkey, void *cb) 23302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 23312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth; 23322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 233316348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 2334bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg int err; 23352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 233616348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 233716348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Requesting agent authentication for %s", addr); 233816348199ed59c49a710805a5061c3f22477715bfJohan Hedberg 2339508fdc901e7e1721eef19de5d8ab6e2f1f313dd7Rafal Michalski if (device->authr) { 234016348199ed59c49a710805a5061c3f22477715bfJohan Hedberg error("Authentication already requested for %s", addr); 2341508fdc901e7e1721eef19de5d8ab6e2f1f313dd7Rafal Michalski return -EALREADY; 2342508fdc901e7e1721eef19de5d8ab6e2f1f313dd7Rafal Michalski } 2343508fdc901e7e1721eef19de5d8ab6e2f1f313dd7Rafal Michalski 2344ca0465aff7258cc249e7cba0631fbb11b7829b9eJohan Hedberg agent = device_get_agent(device); 23452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 234616348199ed59c49a710805a5061c3f22477715bfJohan Hedberg error("No agent available for request type %d", type); 23472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return -EPERM; 23482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 23492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth = g_new0(struct authentication_req, 1); 23512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->agent = agent; 23522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->device = device; 23532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = cb; 23542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->type = type; 23552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = auth; 23562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (type) { 23582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 2359bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg err = agent_request_pincode(agent, device, pincode_cb, 2360fc4c6f53f10e4aba7c3183ba294618ec489fc683Johan Hedberg auth, NULL); 23612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 23622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 2363bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg err = agent_request_passkey(agent, device, passkey_cb, 2364fc4c6f53f10e4aba7c3183ba294618ec489fc683Johan Hedberg auth, NULL); 23652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 23662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 2367bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg err = agent_request_confirmation(agent, device, passkey, 2368fc4c6f53f10e4aba7c3183ba294618ec489fc683Johan Hedberg confirm_cb, auth, NULL); 23692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 23702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 2371bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg err = agent_display_passkey(agent, device, passkey); 23722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 23737050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh case AUTH_TYPE_AUTO: 23747050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh err = 0; 23757050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh break; 23767050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh case AUTH_TYPE_PAIRING_CONSENT: 23777050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh err = agent_request_pairing_consent(agent, device, 23787050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh pairing_consent_cb, auth, NULL); 23797050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh break; 23802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 2381bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg err = -EINVAL; 23822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 23832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2384bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg if (err < 0) { 23852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Failed requesting authentication"); 2386a53621433ce81981a1fc2e610086ff528f1770efJohan Hedberg device_auth_req_free(device); 23872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 23882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2389bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg return err; 23902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 23912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 23922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void cancel_authentication(struct authentication_req *auth) 23932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 23942bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz struct btd_device *device; 23952bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz struct agent *agent; 23962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusError err; 23972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 239837b02c1ef9be4f989c9ad5e511f519d35f2bc088Johan Hedberg if (!auth || !auth->cb) 23992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 24002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24012bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz device = auth->device; 24022bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz agent = auth->agent; 24032bf0e14286389430bde40885f1aa6ce51b1e8b8eLuiz Augusto von Dentz 24042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_init(&err); 24052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL); 24062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (auth->type) { 24082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 24092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device); 24102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 24112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 24122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, &err, device); 24132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 24142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 24152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, &err, 0, device); 24162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 24177050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh case AUTH_TYPE_PAIRING_CONSENT: 24187050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh ((agent_cb) auth->cb) (agent, &err, device); 24197050b0c6c21919186cddda6f2286f43cb99798b2Jaikumar Ganesh break; 24202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 24214d21e85715580f468c7f190a3cd25d7fadaba9aaJohan Hedberg /* User Notify doesn't require any reply */ 24222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 24232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 24242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_free(&err); 24262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 24272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 24282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2429f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedbergvoid device_cancel_authentication(struct btd_device *device, gboolean aborted) 24302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 24312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = device->authr; 243216348199ed59c49a710805a5061c3f22477715bfJohan Hedberg char addr[18]; 24332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth) 24352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 24362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 243716348199ed59c49a710805a5061c3f22477715bfJohan Hedberg ba2str(&device->bdaddr, addr); 243816348199ed59c49a710805a5061c3f22477715bfJohan Hedberg DBG("Canceling authentication request for %s", addr); 24392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (auth->agent) 24412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent_cancel(auth->agent); 24422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2443f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg if (!aborted) 2444f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg cancel_authentication(auth); 2445f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg 2446a53621433ce81981a1fc2e610086ff528f1770efJohan Hedberg device_auth_req_free(device); 24472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 24482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 24492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_authenticating(struct btd_device *device) 24502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 24512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return (device->authr != NULL); 2452013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 2453013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 2454837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberggboolean device_is_authorizing(struct btd_device *device) 2455837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg{ 2456837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg return device->authorizing; 2457837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg} 2458837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg 2459837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedbergvoid device_set_authorizing(struct btd_device *device, gboolean auth) 2460837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg{ 2461837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg device->authorizing = auth; 2462837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg} 2463837d65f3a7f94ed4e6fe95f4e845d7ae3242be24Johan Hedberg 24645eb9d13c5b75f3659454466d511533c2f413cbbdClaudio Takahasivoid device_register_services(DBusConnection *conn, struct btd_device *device, 24655eb9d13c5b75f3659454466d511533c2f413cbbdClaudio Takahasi GSList *prim_list, int psm) 246683d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes{ 24678447ce5c943e5b73149321fd4f61ed482c4e9427Claudio Takahasi device->services = attrib_client_register(conn, device, psm, NULL, 24688447ce5c943e5b73149321fd4f61ed482c4e9427Claudio Takahasi prim_list); 24695eb9d13c5b75f3659454466d511533c2f413cbbdClaudio Takahasi device->primaries = g_slist_concat(device->primaries, prim_list); 247083d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes} 247183d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes 247283d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa GomesGSList *btd_device_get_primaries(struct btd_device *device) 247383d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes{ 247483d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes return device->primaries; 247583d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes} 247683d8b6546ccd98ce30c65bc7ec716c42437e569aVinicius Costa Gomes 247717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergvoid btd_device_add_uuid(struct btd_device *device, const char *uuid) 247817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg{ 247917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg GSList *uuid_list; 248017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg char *new_uuid; 248117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 248217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg if (g_slist_find_custom(device->uuids, uuid, 248317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg (GCompareFunc) strcasecmp)) 248417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg return; 248517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 248617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg new_uuid = g_strdup(uuid); 248717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg uuid_list = g_slist_append(NULL, new_uuid); 248817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 248917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg device_probe_drivers(device, uuid_list); 249017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 24910e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_free(new_uuid); 249217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg g_slist_free(uuid_list); 249317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 24940e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg store_profiles(device); 249517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(device); 249617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg} 249717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 2498548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedbergconst sdp_record_t *btd_device_get_record(struct btd_device *device, 2499bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg const char *uuid) 2500548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg{ 2501548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg bdaddr_t src; 2502548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 250382520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz if (device->tmp_records) { 250482520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz const sdp_record_t *record; 250582520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz 250682520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz record = find_record_in_list(device->tmp_records, uuid); 250782520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz if (record != NULL) 250882520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz return record; 250982520ced2eb56caef66cf1265858a76d714fa6c5Luiz Augusto von Dentz } 2510548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2511548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg adapter_get_address(device->adapter, &src); 2512548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2513548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = read_records(&src, &device->bdaddr); 2514548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (!device->tmp_records) 2515548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return NULL; 2516548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2517548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 2518548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg} 2519548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2520c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver) 2521c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2522c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_append(device_drivers, driver); 2523c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2524c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz return 0; 2525c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 2526c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2527c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver) 2528c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2529c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_remove(device_drivers, driver); 2530c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 25310ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25320ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentzstruct btd_device *btd_device_ref(struct btd_device *device) 25330ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz{ 25340ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz device->ref++; 25350ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25360f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz DBG("%p: ref=%d", device, device->ref); 25370ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25380ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz return device; 25390ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz} 25400ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25410ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentzvoid btd_device_unref(struct btd_device *device) 25420ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz{ 25438d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 25440ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz gchar *path; 25450ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25460ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz device->ref--; 25470ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25480f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz DBG("%p: ref=%d", device, device->ref); 25490ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25500ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz if (device->ref > 0) 25510ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz return; 25520ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25530ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz path = g_strdup(device->path); 25540ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25558d7017d8be3305ed828dee928fc2731d0d89a27bLuiz Augusto von Dentz g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); 25560ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz 25570ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz g_free(path); 25580ba18c28575090e30fcb3023ea1b4039a2e27610Luiz Augusto von Dentz} 25591f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario 25601f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demariovoid device_set_class(struct btd_device *device, uint32_t value) 25611f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario{ 25621f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario DBusConnection *conn = get_dbus_connection(); 25631f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario 25641f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Class", 25651f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario DBUS_TYPE_UINT32, &value); 25661f921e01c700151bcac3dc9477d85bfff36e05d3Sheldon Demario} 2567