device.c revision 97dd9b6963ee0f8517bf8e2633d28b6505f2f7ba
1dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann/* 2dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 3dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * BlueZ - Bluetooth protocol stack for Linux 4dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann * 5f1659f19cfb3ef0c0c09b5f5b7e2b06d90d079abMarcel Holtmann * Copyright (C) 2006-2007 Nokia Corporation 6fb333f1c88df9c50529a390297565a6627bcf7adMarcel Holtmann * Copyright (C) 2004-2009 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> 341af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg#include <errno.h> 35dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 36dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/bluetooth.h> 37dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci.h> 38dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann#include <bluetooth/hci_lib.h> 392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz#include <bluetooth/l2cap.h> 405d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp.h> 415d5d89bb2dbc295443900d59d8a7172dc2f279c7Claudio Takahasi#include <bluetooth/sdp_lib.h> 42dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 4386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <glib.h> 4486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include <dbus/dbus.h> 4515ea15b3a752f0487bc50d0ea04925f1b9d33dcbMarcel Holtmann#include <gdbus.h> 4686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 4786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "logging.h" 486a3ea0f9f9aa9dd550f9f2af4a36639961846643Marcel Holtmann#include "textfile.h" 49dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 50506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "hcid.h" 512c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes#include "adapter.h" 5286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann#include "device.h" 53da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi#include "dbus-common.h" 544e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz#include "dbus-hci.h" 557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz#include "error.h" 563d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz#include "glib-helper.h" 57fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite#include "agent.h" 583d3cdef8da6b3e1b14c3cdccda8c099cbad4f3aeMarcel Holtmann#include "sdp-xml.h" 59506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi#include "storage.h" 6086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 61c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz#define DEFAULT_XML_BUF_SIZE 1024 625d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi#define DISCONNECT_TIMER 2 637ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz#define DISCOVERY_TIMER 2 64dfc20857eb381b464b8fd6efdaac59e4a15f5d6dMarcel Holtmann 65e3afaa0b7ff373d89fd3fa257110a34df7495df7Luiz Augusto von Dentzstruct btd_driver_data { 66b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver; 67b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode void *priv; 68b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode}; 69b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstruct bonding_req { 712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn; 722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg; 732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz GIOChannel *io; 742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz guint io_id; 752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz guint listener_id; 76dd10ec5d830d2e2187f93bd2d7e60be947335f0bJohan Hedberg gboolean auth_required; 772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz}; 792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstruct authentication_req { 812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth_type_t type; 822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *cb; 832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz}; 862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 87555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct btd_device { 88cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t bdaddr; 89ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gchar *path; 9018614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter; 91ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode GSList *uuids; 92b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode GSList *drivers; /* List of driver_data */ 93ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gboolean temporary; 94ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode struct agent *agent; 95ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint disconn_timer; 96ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode int discov_active; /* Service discovery active */ 97ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode char *discov_requestor; /* discovery requestor unique name */ 98ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint discov_listener; 99013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg guint discov_timer; 1002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 1012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *authr; /* authentication request */ 102ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 103ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode /* For Secure Simple Pairing */ 104ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t cap; 105ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t auth; 106e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 107c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle; /* Connection handle */ 108e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 109e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg /* Whether were creating a security mode 3 connection */ 110e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg gboolean secmode3; 111548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 112548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *tmp_records; 113bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 114bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg gboolean renewed_key; 115ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode}; 116ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 1173d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req { 1183d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusConnection *conn; 1193d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusMessage *msg; 120555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 1210dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *match_uuids; 1220dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_added; 1230dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_removed; 124681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_list_t *records; 125d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann int search_uuid; 1263d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}; 1273d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 128d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = { 1290dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP_UUID, 1301c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PNP_INFO_SVCLASS_ID, 1310dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg PUBLIC_BROWSE_GROUP, 132d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 0 133d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann}; 134d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 135c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL; 136c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn, 1382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, int err) 1392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_common_reply(conn, msg, 1412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".ConnectionAttemptFailed", 1422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz err > 0 ? strerror(err) : "Connection attempt failed"); 1432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_failed(DBusConnection *conn, 1462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, const char * desc) 1472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc); 1492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_failed_errno(DBusConnection *conn, 1522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, int err) 1532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *desc = strerror(err); 1552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_failed(conn, msg, desc); 1572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic inline DBusMessage *no_such_adapter(DBusMessage *msg) 1602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter", 1622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "No such adapter"); 1632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic inline DBusMessage *in_progress(DBusMessage *msg, const char *str) 1662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str); 1682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 170e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data) 17186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 172555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 1732f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1742f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct agent *agent = adapter_get_agent(adapter); 175e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 176fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite if (device->agent) 177fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite agent_destroy(device->agent, FALSE); 178f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1792f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz if (agent && agent_is_busy(agent, device)) 1802f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz agent_cancel(agent); 1812f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz 182ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_foreach(device->uuids, (GFunc) g_free, NULL); 183ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_free(device->uuids); 184f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1855d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (device->disconn_timer) 1865d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_source_remove(device->disconn_timer); 1875d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 188401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz if (device->discov_timer) 189401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz g_source_remove(device->discov_timer); 190401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz 19186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 19286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 19386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 19486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 195555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device) 196769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{ 19718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 198cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char filename[PATH_MAX + 1], *str; 199cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 200769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz gboolean ret; 201cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 2022a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 203cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 204cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 205cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 206769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 207769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, 208cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode srcaddr, "linkkeys"); 209cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str = textfile_caseget(filename, dstaddr); 210769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz ret = str ? TRUE : FALSE; 211769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(str); 212769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 213769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz return ret; 214769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz} 215769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 216e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn, 217e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *user_data) 2182c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 219555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 22018614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 2214e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessage *reply; 2224e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter iter; 2234e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter dict; 224cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 225cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char name[248], srcaddr[18], dstaddr[18]; 2268a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi char **uuids; 2272a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode const char *ptr; 2284e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_bool_t boolean; 2294e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz uint32_t class; 230769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz int i; 231769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz GSList *l; 2324e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 233cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 234cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 2354e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz reply = dbus_message_new_method_return(msg); 2364e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz if (!reply) 237e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return NULL; 2384e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2394e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 2404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2414e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 2424e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 2434e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 2444e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 2454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2464e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Address */ 247cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ptr = dstaddr; 2481262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr); 2494e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2504e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Name */ 251506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = NULL; 252506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi memset(name, 0, sizeof(name)); 2532a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 254cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 2558a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi 256cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_device_name(srcaddr, dstaddr, name) == 0) { 257506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 2581262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr); 2594e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2604e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 261afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann /* Alias (fallback to name or address) */ 262afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) { 263afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (!ptr) { 264afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann g_strdelimit(dstaddr, ":", '-'); 265afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann ptr = dstaddr; 266afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } 267afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } else 268506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 269506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 270506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (ptr) 2711262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); 272506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 2734e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Class */ 274cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_remote_class(&src, &device->bdaddr, &class) == 0) { 275e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann const char *icon = class_to_icon(class); 276e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 2771262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class); 278e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 279e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann if (icon) 2801262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Icon", 281e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann DBUS_TYPE_STRING, &icon); 2824e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2834e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2844e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Paired */ 285769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz boolean = device_is_paired(device); 2861262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean); 2874e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2884e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Trusted */ 289cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode boolean = read_trust(&src, dstaddr, GLOBAL_TRUST); 2901262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean); 2914e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2924e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Connected */ 293c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz boolean = (device->handle != 0); 294c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, 295c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz &boolean); 2964e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 297ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi /* UUIDs */ 298769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 299769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 300769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids[i] = l->data; 3013a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i); 302769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(uuids); 3034e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 30474fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz /* Adapter */ 3058a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi ptr = adapter_get_path(adapter); 3061262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr); 30774fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz 3084e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 3094e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 310e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return reply; 3112c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 3122c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 313e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, 3147fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *alias, void *data) 3157fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 316555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 31718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 318cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 319cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 320506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi int err; 3217fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 322cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 323cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 324cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3252a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 326cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode /* Remove alias if empty string */ 327cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode err = write_device_alias(srcaddr, dstaddr, 328506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi g_str_equal(alias, "") ? NULL : alias); 329506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (err < 0) 330e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 331e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".Failed", 332506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi strerror(-err)); 3337fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 334c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 335c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Alias", 336c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_STRING, &alias); 3377fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 338e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3407fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 341e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, 3427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value, void *data) 3437fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 344555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 34518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 346cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 347cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 3482a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 3497fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 350cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 351cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 352cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3532a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 354cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value); 3557fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 356c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 357c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Trusted", 358c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_BOOLEAN, &value); 3597fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 360e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3617fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3627fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 363e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg) 364e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{ 365e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 366e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".InvalidArguments", 367e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi "Invalid arguments in method call"); 368e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi} 369e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 370e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn, 371e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *data) 3722c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 3737fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter iter; 3747fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter sub; 3757fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *property; 3767fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3777fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (!dbus_message_iter_init(msg, &iter)) 378e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3797fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 381e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3827fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3837fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&iter, &property); 3847fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_next(&iter); 3857fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3867fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) 387e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3887fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_recurse(&iter, &sub); 3897fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3907fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (g_str_equal("Trusted", property)) { 3917fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value; 3927fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3937fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 394e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3957fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &value); 3967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3977fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_trust(conn, msg, value, data); 3987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } else if (g_str_equal("Alias", property)) { 399506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi const char *alias; 4007fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 4017fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) 402e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 4037fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &alias); 4047fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 4057fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_alias(conn, msg, alias, data); 4067fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } 4077fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 408e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 4092c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 4102c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 4111f5107e65f9786bd6b84ecfb4d84691e9b34529aMarcel Holtmannstatic void discover_services_req_exit(DBusConnection *conn, void *user_data) 412342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{ 413555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 41418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 415cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4162a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4172a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 418342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 419342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz debug("DiscoverDevices requestor exited"); 420342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 421cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_cancel_discovery(&src, &device->bdaddr); 422342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz} 423342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 42494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn, 42594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 42694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 427555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 42894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann const char *pattern; 429342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz int err; 430342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 431342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (device->discov_active) 432342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", 433342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discover in progress"); 43494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 43594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 43694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBUS_TYPE_INVALID) == FALSE) 437342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 43894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 439a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (strlen(pattern) == 0) { 44069adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, NULL, FALSE); 441342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 442342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 443342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } else { 444040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi uuid_t uuid; 445040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi 446040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi if (bt_string2uuid(&uuid, pattern) < 0) 447342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return invalid_args(msg); 448a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann 4494b1914903cb105acf843b84833e81d5470133879Johan Hedberg sdp_uuid128_to_uuid(&uuid); 4504b1914903cb105acf843b84833e81d5470133879Johan Hedberg 45169adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, &uuid, FALSE); 452342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 453342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 454342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } 45594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 45694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return NULL; 457342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 458342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail: 459342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", 460342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discovery Failed"); 46194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 46294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 46394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn, 46494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 46594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 466555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 46718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 468cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4692a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4702a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 47119b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann 472342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_active) 473342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 474342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 475342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "No pending discovery"); 476342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 477342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz /* only the discover requestor can cancel the inquiry process */ 478342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_requestor || 479342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz strcmp(device->discov_requestor, dbus_message_get_sender(msg))) 480342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 481342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".NotAuthorized", 482342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Not Authorized"); 483342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 484cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (bt_cancel_discovery(&src, &device->bdaddr) < 0) 485289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz return g_dbus_create_error(msg, 486289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 487289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz "No pending discover"); 48894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 48994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 49094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 49194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 4925d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data) 4935d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{ 494555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 4955d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_cp cp; 4965d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi int dd; 497661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode uint16_t dev_id = adapter_get_dev_id(device->adapter); 4985d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 4995d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = 0; 5005d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 501661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode dd = hci_open_dev(dev_id); 5025d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (dd < 0) 5035d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi goto fail; 5045d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5055d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi memset(&cp, 0, sizeof(cp)); 506c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz cp.handle = htobs(device->handle); 5075d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.reason = HCI_OE_USER_ENDED_CONNECTION; 5085d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5095d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, 5105d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DISCONNECT_CP_SIZE, &cp); 5115d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5125d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi close(dd); 5135d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5145d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail: 5155d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 5165d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi} 5175d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 51894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *disconnect(DBusConnection *conn, 51994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 52094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 521555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 5225d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 523c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (!device->handle) 5245d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return g_dbus_create_error(msg, 5255d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi ERROR_INTERFACE ".NotConnected", 5265d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi "Device is not connected"); 5275d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5285d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_dbus_emit_signal(conn, device->path, 5295d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DEVICE_INTERFACE, "DisconnectRequested", 5305d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DBUS_TYPE_INVALID); 5315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5325d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, 5335d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_timeout, device); 53494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 53594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 53694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 53794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 538e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = { 539e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "GetProperties", "", "a{sv}", get_properties }, 540e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "SetProperty", "sv", "", set_property }, 541e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann { "DiscoverServices", "s", "a{us}", discover_services, 54294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann G_DBUS_METHOD_FLAG_ASYNC}, 54394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "CancelDiscovery", "", "", cancel_discover }, 544e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "Disconnect", "", "", disconnect }, 54594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5462c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5472c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 548e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = { 54994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "PropertyChanged", "sv" }, 55094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "DisconnectRequested", "" }, 55194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5522c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5532c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 554c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzgboolean device_is_connected(struct btd_device *device) 555e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 556c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return (device->handle != 0); 557e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 558e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 559c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzstatic void device_set_connected(struct btd_device *device, DBusConnection *conn, 560013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg gboolean connected) 561013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 562c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, 563c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg "Connected", DBUS_TYPE_BOOLEAN, &connected); 564e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 565e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg if (connected && device->secmode3) { 566e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg struct btd_adapter *adapter = device_get_adapter(device); 567e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg bdaddr_t sba; 568e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 569e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg adapter_get_address(adapter, &sba); 570e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 571e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = FALSE; 572e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 573e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0); 574e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg } 575e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 576e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 577c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzvoid device_add_connection(struct btd_device *device, DBusConnection *conn, 578c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle) 579c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 580c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle) { 581c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz error("%s: Unable to add connection %u, %u already exist)", 582c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->path, handle, device->handle); 583c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 584c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 585c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 586c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->handle = handle; 587c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 588c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device_set_connected(device, conn, TRUE); 589c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 590c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 591c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzvoid device_remove_connection(struct btd_device *device, DBusConnection *conn, 592c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle) 593c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 594c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle != handle) { 595c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz error("%s: Unable to remove connection %u, handle mismatch (%u)", 596c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->path, handle, device->handle); 597c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 598c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 599c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 600c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->handle = 0; 601c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 602c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device_set_connected(device, conn, FALSE); 603c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 604c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 605c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzgboolean device_has_connection(struct btd_device *device, uint16_t handle) 606c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 607c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return (handle == device->handle); 608c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 609c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 610e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedbergvoid device_set_secmode3_conn(struct btd_device *device, gboolean enable) 611e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 612e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = enable; 613013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 614013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 61518614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, 61636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const gchar *address) 61786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 618ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite gchar *address_up; 619555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 620139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann const gchar *adapter_path = adapter_get_path(adapter); 62186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 622555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode device = g_try_malloc0(sizeof(struct btd_device)); 62386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 62486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 62586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 626ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite address_up = g_ascii_strup(address, -1); 627139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up); 62886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 629ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite g_free(address_up); 63086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 63186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 63286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 633e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, 634e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device_methods, device_signals, NULL, 635e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device, device_free) == FALSE) { 63686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 63786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 63886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 639da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 640cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str2ba(address, &device->bdaddr); 641da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 642da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 6436bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi return device; 64486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 64586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 6462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_remove_bonding(struct btd_device *device, DBusConnection *conn) 6472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 6482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 6492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char *str, srcaddr[18], dstaddr[18]; 6502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int dd, dev_id; 6512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t bdaddr; 6522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz gboolean paired; 6532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(device->adapter, &bdaddr); 6552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&bdaddr, srcaddr); 6562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 6572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dev_id = adapter_get_dev_id(device->adapter); 6592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dd = hci_open_dev(dev_id); 6612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (dd < 0) 6622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 6632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 6652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 6662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* textfile_del doesn't return an error when the key is not found */ 6682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz str = textfile_caseget(filename, dstaddr); 6692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz paired = str ? TRUE : FALSE; 6702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(str); 6712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!paired) 6732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 6742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Delete the link key from storage */ 6762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz textfile_casedel(filename, dstaddr); 6772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Delete the link key from the Bluetooth chip */ 6792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT); 6802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Send the HCI disconnect command */ 682c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle) { 683c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz int err = hci_disconnect(dd, htobs(device->handle), 6842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz HCI_OE_USER_ENDED_CONNECTION, 6852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz HCI_REQ_TIMEOUT); 6862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (err < 0) 6872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Disconnect: %s (%d)", strerror(-err), -err); 6882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 6892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 6912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz paired = FALSE; 6932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz emit_property_changed(conn, device->path, DEVICE_INTERFACE, 6942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Paired", DBUS_TYPE_BOOLEAN, &paired); 6952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 6962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 69758c15493922277539cca11e8b55776c5d0fbccbaJohan Hedbergvoid device_remove(struct btd_device *device, DBusConnection *conn, 69858c15493922277539cca11e8b55776c5d0fbccbaJohan Hedberg gboolean remove_bonding) 69975add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{ 7006061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann GSList *list; 7016061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann struct btd_device_driver *driver; 702f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann gchar *path = g_strdup(device->path); 703f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 704f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann debug("Removing device %s", path); 705f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 7062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 7072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION); 7082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 70958c15493922277539cca11e8b55776c5d0fbccbaJohan Hedberg if (!device->temporary && remove_bonding) 7102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_remove_bonding(device, conn); 7112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7126061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann for (list = device->drivers; list; list = list->next) { 713b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 714b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver = driver_data->driver; 7156061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 716e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 717b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 7186061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann } 7196061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 720f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); 72175add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi 722f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_free(path); 72386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 724ff296428a08dee619db1cc702146faefa91087faCidorvan Leite 725555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address) 726ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{ 727cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char addr[18]; 728cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 729cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, addr); 730cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return strcasecmp(addr, address); 731ff296428a08dee619db1cc702146faefa91087faCidorvan Leite} 7323d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 7333870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedbergstatic gboolean record_has_uuid(const sdp_record_t *rec, 7343870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg const char *profile_uuid) 735f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 7363870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg sdp_list_t *pat; 737f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7383870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg for (pat = rec->pattern; pat != NULL; pat = pat->next) { 739f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz char *uuid; 7403870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg int ret; 741f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7423870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg uuid = bt_uuid2string(pat->data); 743f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!uuid) 744f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 745f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7463870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg ret = strcasecmp(uuid, profile_uuid); 747f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7483870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg g_free(uuid); 7493870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg 7503870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg if (ret == 0) 7513870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return TRUE; 752f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 753f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7543870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return FALSE; 755f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 756f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 757f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_pattern(struct btd_device *device, 758878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg const char *match_uuid, 759f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 760f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 761f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *l, *uuids = NULL; 762f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 763f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (l = profiles; l; l = l->next) { 764878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg char *profile_uuid = l->data; 765f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz const sdp_record_t *rec; 7663bb7c1527ce3ec67127200b54a8fbc01a196ebadJohan Hedberg 767878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg rec = btd_device_get_record(device, profile_uuid); 768f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!rec) 769f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 770f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 771a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg if (record_has_uuid(rec, match_uuid)) 772878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg uuids = g_slist_append(uuids, profile_uuid); 773cdfe8a8246013031f55c647092e41adbb29ace81Johan Hedberg } 774f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 775f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 776f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 777f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 778f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_driver(struct btd_device *device, 779f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_device_driver *driver, 780f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 781f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{ 7826061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann const char **uuid; 783f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *uuids = NULL; 784f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 785f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 786f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *match; 787f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7889b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz /* skip duplicated uuids */ 7899b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz if (g_slist_find_custom(uuids, *uuid, 7909b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz (GCompareFunc) strcasecmp)) 7919b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz continue; 7929b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz 793f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match profile driver */ 794f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = g_slist_find_custom(profiles, *uuid, 795f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz (GCompareFunc) strcasecmp); 796f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (match) { 797f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 798f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 799f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 800f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 801f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match pattern driver */ 802f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = device_match_pattern(device, *uuid, profiles); 803a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg for (; match; match = match->next) 804f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 805f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 806f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 807f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 808f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 809f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 810f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzvoid device_probe_drivers(struct btd_device *device, GSList *profiles) 811f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 812f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *list; 813f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann int err; 814f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 815f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann debug("Probe drivers for %s", device->path); 816f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 817c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz for (list = device_drivers; list; list = list->next) { 818e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann struct btd_device_driver *driver = list->data; 819f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *probe_uuids; 820f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_driver_data *driver_data; 821f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 822f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz probe_uuids = device_match_driver(device, driver, profiles); 8234b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 824f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!probe_uuids) 825f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 826081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 827f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data = g_new0(struct btd_driver_data, 1); 828b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 829f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz err = driver->probe(device, probe_uuids); 830f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (err < 0) { 831f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz error("probe failed with driver %s for device %s", 832f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver->name, device->path); 833b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 834f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_free(driver_data); 835548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg g_slist_free(probe_uuids); 836f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 837f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 838f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 839f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data->driver = driver; 840f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz device->drivers = g_slist_append(device->drivers, driver_data); 841f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_slist_free(probe_uuids); 842f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 84336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 844f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (list = profiles; list; list = list->next) { 845c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann GSList *l = g_slist_find_custom(device->uuids, list->data, 846548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg (GCompareFunc) strcasecmp); 847c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann if (l) 848c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann continue; 849c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann 85036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_insert_sorted(device->uuids, 8510e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_strdup(list->data), 8520e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg (GCompareFunc) strcasecmp); 853548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 854548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 855548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) { 856548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(device->tmp_records, 857548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg (sdp_free_func_t) sdp_record_free); 858548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = NULL; 859c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann } 86036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 86136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 86299bc055edc4b9ba8ccda791757a6439fb03ff8f2Marcel Holtmannstatic void device_remove_drivers(struct btd_device *device, GSList *uuids) 86336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 86418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 865352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg GSList *list, *next; 866cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 8672a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 868548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *records; 8692a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 8702a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 871cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 872cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 87336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 874548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = read_records(&src, &device->bdaddr); 875548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 87636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz debug("Remove drivers for %s", device->path); 87736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 878352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg for (list = device->drivers; list; list = next) { 879b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 880b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver = driver_data->driver; 88136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const char **uuid; 88236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 883352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg next = list->next; 884352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg 88536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 8869b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz sdp_record_t *rec; 88736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 8889b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 8899b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz (GCompareFunc) strcasecmp)) 89036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 89136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 8920e9c10ab506becad2ce0e323ff77813ecb8ce5d8Johan Hedberg debug("UUID %s was removed from device %s", *uuid, dstaddr); 893548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 894e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 89536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->drivers = g_slist_remove(device->drivers, 896b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data); 897b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 898b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 899548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg rec = find_record_in_list(records, *uuid); 9009b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!rec) 9012d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg break; 9029b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz 903cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode delete_record(srcaddr, dstaddr, rec->handle); 904548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 905548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = sdp_list_remove(records, rec); 906548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_record_free(rec); 9072d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg 9082d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg break; 90936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 91036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 91136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 912548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (records) 913548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(records, (sdp_free_func_t) sdp_record_free); 914548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 91536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = uuids; list; list = list->next) 91636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_remove(device->uuids, list->data); 917f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann} 918f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 919bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle, 920bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann const char *record) 921bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{ 922bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann DBusMessageIter entry; 923bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 924bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, 925bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann NULL, &entry); 926bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 927bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); 928bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 929bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); 930bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 931bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_close_container(dict, &entry); 932bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann} 933bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 934730775d1226a30c37ff551955f093ddfcd18e600Claudio Takahasistatic void append_and_grow_string(void *data, const char *str) 935c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{ 936c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz sdp_buf_t *buff = data; 937c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz int len; 938c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 939c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz len = strlen(str); 940c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 941c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) { 942c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = malloc(DEFAULT_XML_BUF_SIZE); 943c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) 944c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 945c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = DEFAULT_XML_BUF_SIZE; 946c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 947c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 948c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow string */ 949c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz while (buff->buf_size < (buff->data_size + len + 1)) { 950c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz void *tmp; 951c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz uint32_t new_size; 952c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 953c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow buffer by a factor of 2 */ 954c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz new_size = (buff->buf_size << 1); 955c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 956c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz tmp = realloc(buff->data, new_size); 957c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!tmp) 958c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 959c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 960c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = tmp; 961c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = new_size; 962c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 963c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 964c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Include the NULL character */ 965c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz memcpy(buff->data + buff->data_size, str, len + 1); 966c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data_size += len; 967c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz} 968c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 9691e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs) 9701e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{ 9711e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessage *reply; 9721e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessageIter iter, dict; 9731e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_list_t *seq; 9741e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 9761e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!reply) 9771e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz return; 9781e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9791e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 9801e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9811e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 9821e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 9831e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING 9841e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 9851e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9861e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 9871e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 9881e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_buf_t result; 9891e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9901e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!rec) 9911e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz break; 9921e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9931e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz memset(&result, 0, sizeof(sdp_buf_t)); 9941e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9951e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz convert_sdp_record_to_xml(rec, &result, 9961e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz append_and_grow_string); 9971e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 9981e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (result.data) { 9991e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz const char *val = (char *) result.data; 10001e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz iter_append_record(&dict, rec->handle, val); 10011e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz free(result.data); 10021e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 10031e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 10041e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10051e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 10061e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 1007a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 10081e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz} 10091e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 101017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void services_changed(struct btd_device *device) 10113d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 1012533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg DBusConnection *conn = get_dbus_connection(); 10133d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz char **uuids; 10143d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz GSList *l; 101536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz int i; 10163d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 101736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 101836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 101936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids[i] = l->data; 102036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 102158f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg emit_array_property_changed(conn, device->path, DEVICE_INTERFACE, 102258f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg "UUIDs", DBUS_TYPE_STRING, &uuids); 102336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 102436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuids); 102536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 102636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 10278b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b) 10288b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{ 10298b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r1 = a; 10308b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r2 = b; 10318b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 10328b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg return r1->handle - r2->handle; 10338b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg} 10348b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 103536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs) 103636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 1037555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 103818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 103936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *seq; 1040cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 10412a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 10422a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 10432a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 1044cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 1045cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 10463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 104736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 10483d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 104936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *svcclass = NULL; 10500dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg gchar *profile_uuid; 105136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *l; 10523d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 10533d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!rec) 10543d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz break; 10553d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 105636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (sdp_get_service_classes(rec, &svcclass) < 0) 105736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 105836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 105936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Extract the first element and skip the remainning */ 10600dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid = bt_uuid2string(svcclass->data); 10610dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!profile_uuid) { 1062aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 106336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 1064aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg } 106536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 10660dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!strcasecmp(profile_uuid, PNP_UUID)) { 1067fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann uint16_t source, vendor, product, version; 1068e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse sdp_data_t *pdlist; 1069e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1070fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE); 1071fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann source = pdlist ? pdlist->val.uint16 : 0x0000; 1072fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann 1073e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); 1074e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse vendor = pdlist ? pdlist->val.uint16 : 0x0000; 1075e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1076e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); 1077e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse product = pdlist ? pdlist->val.uint16 : 0x0000; 1078e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1079e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); 1080e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version = pdlist ? pdlist->val.uint16 : 0x0000; 1081e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1082fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann if (source || vendor || product || version) 1083fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann store_device_id(srcaddr, dstaddr, source, 1084fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann vendor, product, version); 1085e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse } 1086e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 108737a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg /* Check for duplicates */ 1088981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg if (sdp_list_find(req->records, rec, rec_cmp)) { 10890dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 1090aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 109137a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg continue; 1092981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg } 109337a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1094cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode store_record(srcaddr, dstaddr, rec); 109537a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1096681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Copy record */ 1097204180c7dc2e20b9b701275a3fefb52707720f54Luiz Augusto von Dentz req->records = sdp_list_append(req->records, sdp_copy_record(rec)); 1098681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 10990dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l = g_slist_find_custom(device->uuids, profile_uuid, 1100c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann (GCompareFunc) strcmp); 110136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!l) 11020dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_added = 11030dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_append(req->profiles_added, 11040dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid); 110536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz else { 11060dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = 11070dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_remove(req->profiles_removed, 11080dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l->data); 11090dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 11103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 11113d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 111236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_free(svcclass, free); 11133d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 111436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 111536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 111617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void store_profiles(struct btd_device *device) 111736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 111818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 1119cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 112036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz char *str; 11213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 11222a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 11233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 112436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!device->uuids) { 1125cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, ""); 112636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz return; 112736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 112836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 112936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz str = bt_list2string(device->uuids); 1130cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, str); 113136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(str); 113236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 113336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1134a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentzstatic void browse_req_free(struct browse_req *req) 1135a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz{ 1136a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz struct btd_device *device = req->device; 1137a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1138a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_active = 0; 1139a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1140a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (device->discov_requestor) { 1141a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_dbus_remove_watch(req->conn, device->discov_listener); 1142a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_listener = 0; 1143a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(device->discov_requestor); 1144a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_requestor = NULL; 1145a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz } 1146a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1147a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->msg) 1148a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_message_unref(req->msg); 1149a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->conn) 1150a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_connection_unref(req->conn); 11510dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL); 11520dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_added); 11530dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_removed); 1154a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->records) 1155a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); 1156a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(req); 1157a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz} 1158a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1159da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data) 116036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 116136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz struct browse_req *req = user_data; 1162555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 116336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DBusMessage *reply; 11642a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 1165681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (err < 0) { 1166681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz error("%s: error updating services: %s (%d)", 1167681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device->path, strerror(-err), -err); 116836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1169681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 117036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 117136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz update_services(req, recs); 117236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 11730dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!req->profiles_added && !req->profiles_removed) { 1174e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz debug("%s: No service update", device->path); 117536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1176681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 11772efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 1178548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records && req->records) { 1179548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(device->tmp_records, (sdp_free_func_t) sdp_record_free); 1180548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = req->records; 1181548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg req->records = NULL; 1182548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 1183548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 118436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Probe matching drivers for services added */ 11850dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_added) 11860dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_probe_drivers(device, req->profiles_added); 11872efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 118836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Remove drivers for services removed */ 11890dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_removed) 11900dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_remove_drivers(device, req->profiles_removed); 11912efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 119236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Propagate services changes */ 119317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(req->device); 1194f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 11957b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed: 1196681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Store the device's profiles in the filesystem */ 119717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg store_profiles(device); 1198681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 11992ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg if (!req->msg) 12002ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg goto cleanup; 12012ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg 1202438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, 1203438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz "DiscoverServices")) { 1204438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz discover_device_reply(req, req->records); 1205438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz goto cleanup; 1206438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz } 1207438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 12083d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz /* Reply create device request */ 12093d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 12103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!reply) 12111e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz goto cleanup; 12123d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 12133d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, 1214a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann DBUS_TYPE_INVALID); 12153d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1216a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 12173d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 12181e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup: 1219a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1220da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1221da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1222da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data) 1223da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1224da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct browse_req *req = user_data; 1225da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_device *device = req->device; 1226da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1227cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1228da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz uuid_t uuid; 1229da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 12300dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg /* If we have a valid response and req->search_uuid == 2, then 12310dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP UUID & PNP searching was successful -- we are done */ 12320dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (err < 0 || (req->search_uuid == 2 && req->records)) 1233da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz goto done; 1234da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1235da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz update_services(req, recs); 1236da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1237da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz adapter_get_address(adapter, &src); 1238da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1239da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz /* Search for mandatory uuids */ 12407d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (uuid_list[req->search_uuid]) { 12417d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1242c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann bt_search_service(&src, &device->bdaddr, &uuid, 1243c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann browse_cb, user_data, NULL); 1244da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz return; 1245da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz } 1246da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1247da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone: 1248da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz search_cb(recs, err, user_data); 1249da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1250da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 125169adac833c5633714b84bf840c75aa814193b8a6Johan Hedbergstatic void init_browse(struct browse_req *req, gboolean reverse) 1252da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1253da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz GSList *l; 1254da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 125569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg /* If we are doing reverse-SDP don't try to detect removed profiles 125669adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * since some devices hide their service records while they are 125769adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * connected 125869adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg */ 125969adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg if (reverse) 126069adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg return; 126169adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg 1262da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz for (l = req->device->uuids; l; l = l->next) 12630dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = g_slist_append(req->profiles_removed, 1264da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz l->data); 12653d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 12663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1267555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn, 126869adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg DBusMessage *msg, uuid_t *search, gboolean reverse) 12693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 127018614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 12713d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz struct browse_req *req; 1272cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1273d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann uuid_t uuid; 1274da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz bt_callback_t cb; 1275a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz int err; 12762a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 12771af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg if (device->discov_active) 12781af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg return -EBUSY; 12791af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg 12802a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 12813d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 12823d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req = g_new0(struct browse_req, 1); 1283438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 1284d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg if (conn == NULL) 1285d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg conn = get_dbus_connection(); 1286438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 1287d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg req->conn = dbus_connection_ref(conn); 12883d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->device = device; 12893d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1290a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (search) { 1291040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi memcpy(&uuid, search, sizeof(uuid_t)); 1292da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = search_cb; 1293a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } else { 12947d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 129569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg init_browse(req, reverse); 1296da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = browse_cb; 1297a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } 1298d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 129995e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_active = 1; 1300d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg 1301d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg if (msg) { 13025c6426eff87049c9f8e49877f650772840907239Luiz Augusto von Dentz req->msg = dbus_message_ref(msg); 1303d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); 1304d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg /* Track the request owner to cancel it 1305d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg * automatically if the owner exits */ 1306d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg device->discov_listener = g_dbus_add_disconnect_watch(conn, 130795e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz dbus_message_get_sender(msg), 130895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz discover_services_req_exit, 130995e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device, NULL); 1310d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg } 131195e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz 1312a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz err = bt_search_service(&src, &device->bdaddr, 1313a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz &uuid, cb, req, NULL); 1314a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (err < 0) 1315a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1316a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1317a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz return err; 13183d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 131924cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann 132018614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device) 1321dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{ 1322dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode if (!device) 1323dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return NULL; 1324dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 1325dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return device->adapter; 1326dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode} 1327dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 132819ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr) 1329aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{ 1330cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bacpy(bdaddr, &device->bdaddr); 1331aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode} 1332aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode 1333555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device) 133446fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{ 133546fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode if (!device) 133646fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return NULL; 133746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 133846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return device->path; 133946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode} 134046fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 1341555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device) 1342a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{ 1343a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode if (!device) 1344a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return NULL; 1345a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1346a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return device->agent; 1347a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode} 1348a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1349555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent) 1350d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{ 1351d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode if (!device) 1352d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode return; 1353d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1354d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode device->agent = agent; 1355d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode} 1356d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1357555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device) 13589f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{ 13599f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode return device->discov_active ? TRUE : FALSE; 13609f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode} 13619f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode 1362555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device) 1363f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{ 1364f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode return device->temporary; 1365f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode} 1366f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode 1367555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary) 1368595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{ 1369595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode if (!device) 1370595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode return; 1371595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1372595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode device->temporary = temporary; 1373595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode} 1374595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1375555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap) 1376491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{ 1377491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode if (!device) 1378491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode return; 1379491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1380491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode device->cap = cap; 1381491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode} 1382491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1383f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberguint8_t device_get_cap(struct btd_device *device) 1384f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg{ 1385f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg return device->cap; 1386f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg} 1387f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg 1388555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth) 138929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{ 139029227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode if (!device) 139129227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode return; 139229227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 139329227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode device->auth = auth; 139429227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode} 139529227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 1396555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device) 13972203f153c53189ec1c30df99b717e035681196e6Alok Barsode{ 13982203f153c53189ec1c30df99b717e035681196e6Alok Barsode return device->auth; 13992203f153c53189ec1c30df99b717e035681196e6Alok Barsode} 1400c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1401013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergstatic gboolean start_discovery(gpointer user_data) 1402013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 1403013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg struct btd_device *device = user_data; 1404013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 140569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg device_browse(device, NULL, NULL, NULL, TRUE); 1406013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1407013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg device->discov_timer = 0; 1408013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1409013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg return FALSE; 1410013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 1411013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 14122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von DentzDBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) 1413013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 14142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (status) { 14152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x00: /* success */ 14162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_method_return(msg); 14172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x04: /* page timeout */ 14192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x08: /* connection timeout */ 14202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x10: /* connection accept timeout */ 14212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x22: /* LMP response timeout */ 14222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x28: /* instant passed - is this a timeout? */ 14232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationTimeout", 14252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Timeout"); 14262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x17: /* too frequent pairing attempts */ 14272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".RepeatedAttempts", 14292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Repeated Attempts"); 14302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x06: 14322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */ 14332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationRejected", 14352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Rejected"); 14362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x07: /* memory capacity */ 14382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x09: /* connection limit */ 14392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0a: /* synchronous connection limit */ 14402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0d: /* limited resources */ 14412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x13: /* user ended the connection */ 14422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x14: /* terminated due to low resources */ 14432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationCanceled", 14452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Canceled"); 14462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x05: /* authentication failure */ 14482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0E: /* rejected due to security reasons - is this auth failure? */ 14492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x25: /* encryption mode not acceptable - is this auth failure? */ 14502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x26: /* link key cannot be changed - is this auth failure? */ 14512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x29: /* pairing with unit key unsupported - is this auth failure? */ 14522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x2f: /* insufficient security - is this auth failure? */ 14532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 14542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationFailed", 14562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Failed"); 14572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 14582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 14592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void bonding_request_free(struct bonding_req *bonding) 14612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 14622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 14632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 14652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 14662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->listener_id) 14682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_remove_watch(bonding->conn, bonding->listener_id); 146968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 14702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->msg) 14712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_unref(bonding->msg); 14722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->conn) 14742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_connection_unref(bonding->conn); 14752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->io_id) 14772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_source_remove(bonding->io_id); 14782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->io) 14802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_unref(bonding->io); 14812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device = bonding->device; 14832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device && device->agent) { 14852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent_destroy(device->agent, FALSE); 14862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->agent = NULL; 14872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 14882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = NULL; 14902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(bonding); 14912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 14922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_set_paired(struct btd_device *device, gboolean value) 14942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 14952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 149668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 1497c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired", 14982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &value); 14992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_agent_removed(struct agent *agent, void *user_data) 15022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 15042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_set_agent(device, NULL); 15062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 15082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr->agent = NULL; 15092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic struct bonding_req *bonding_request_new(DBusConnection *conn, 15122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 15132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device, 15142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 15152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 15162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 15182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *name = dbus_message_get_sender(msg); 15192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 15202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requesting bonding", device->path); 15222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent_path) 15242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto proceed; 15252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = agent_create(device->adapter, name, agent_path, 15272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability, 15282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_agent_removed, 15292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 15302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 15312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Unable to create a new agent"); 15322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 15332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->agent = agent; 15362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("Temporary agent registered for %s at %s:%s", 15382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->path, name, agent_path); 15392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzproceed: 15412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = g_new0(struct bonding_req, 1); 15432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->conn = dbus_connection_ref(conn); 15452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->msg = dbus_message_ref(msg); 15462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return bonding; 15482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond, 15512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device) 15522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct hci_request rq; 15542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth_requested_cp cp; 15552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz evt_cmd_status rp; 15562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct l2cap_conninfo cinfo; 15572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz socklen_t len; 15582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int sk, dd, ret; 15592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15605331a26b8a3c2d69d30a4334e023238db197080bJohan Hedberg if (!device->bonding) { 15612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(io); 15622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 15632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (cond & G_IO_NVAL) { 15662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) { 15672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply; 15682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz reply = new_authentication_return(device->bonding->msg, 15702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 0x09); 15712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(device->bonding->conn, reply); 15722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto cleanup; 15752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (cond & (G_IO_HUP | G_IO_ERR)) { 15782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("Hangup or error on bonding IO channel"); 15792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 15812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_connection_attempt_failed(device->bonding->conn, 15822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->msg, 15832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ENETDOWN); 15842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 15862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz sk = g_io_channel_unix_get_fd(io); 15892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz len = sizeof(ret); 15912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { 15922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Can't get socket error: %s (%d)", 15932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 15942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 15952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 15962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 15972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (ret != 0) { 16002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 16012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_connection_attempt_failed(device->bonding->conn, 16022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->msg, 16032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret); 16042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz len = sizeof(cinfo); 16082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) { 16092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Can't get connection info: %s (%d)", 16102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 16112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 16122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 16132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dd = hci_open_dev(adapter_get_dev_id(device->adapter)); 16172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (dd < 0) { 16182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply = no_such_adapter(device->bonding->msg); 16192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(device->bonding->conn, reply); 16202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&rp, 0, sizeof(rp)); 16242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp)); 16262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz cp.handle = htobs(cinfo.hci_handle); 16272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&rq, 0, sizeof(rq)); 16292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.ogf = OGF_LINK_CTL; 16302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.ocf = OCF_AUTH_REQUESTED; 16312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.cparam = &cp; 16322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.clen = AUTH_REQUESTED_CP_SIZE; 16332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.rparam = &rp; 16342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.rlen = EVT_CMD_STATUS_SIZE; 16352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.event = EVT_CMD_STATUS; 16362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) { 16382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Unable to send HCI request: %s (%d)", 16392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 16402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 16412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 16422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 16432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (rp.status) { 16472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("HCI_Authentication_Requested failed with status 0x%02x", 16482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rp.status); 16492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 16502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bt_error(rp.status)); 16512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 16522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 16562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->io_id = g_io_add_watch(io, 16582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz G_IO_NVAL | G_IO_HUP | G_IO_ERR, 16592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz (GIOFunc) create_bonding_io_cb, 16602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 16612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 16632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzfailed: 16652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(io); 16662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzcleanup: 16682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->io_id = 0; 16692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding_request_free(device->bonding); 16702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 16722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 16732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void create_bond_req_exit(DBusConnection *conn, void *user_data) 16752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 16762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 16772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requestor exited before bonding was completed", device->path); 16792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 16812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_authentication(device); 16822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) { 16842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->listener_id = 0; 16852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(device->bonding->io); 16862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding_request_free(device->bonding); 16872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 16892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1690f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedbergstatic int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst, 1691f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg gboolean *auth_required) 1692f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg{ 1693f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg struct sockaddr_l2 addr; 1694f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg long arg; 1695d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg int sk, err, opt; 1696f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1697f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); 1698f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (sk < 0) { 1699f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't create socket: %s (%d)", strerror(errno), errno); 1700f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1701f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1702f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1703f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg memset(&addr, 0, sizeof(addr)); 1704f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg addr.l2_family = AF_BLUETOOTH; 1705f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bacpy(&addr.l2_bdaddr, src); 1706f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1707f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1708f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't bind socket: %s (%d)", strerror(errno), errno); 1709f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1710f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1711f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 171297dd9b6963ee0f8517bf8e2633d28b6505f2f7baMarcel Holtmann opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE; 1713f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1714d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg err = setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)); 1715d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg if (err < 0) { 1716d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg error("setsockopt: %s (%d)", strerror(errno), errno); 1717d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg goto failed; 1718d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg } 1719f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1720f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg arg = fcntl(sk, F_GETFL); 1721f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (arg < 0) { 1722f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't get file flags: %s (%d)", strerror(errno), errno); 1723f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1724f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1725f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1726f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg arg |= O_NONBLOCK; 1727f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (fcntl(sk, F_SETFL, arg) < 0) { 1728f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't set file flags: %s (%d)", strerror(errno), errno); 1729f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1730f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1731f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1732f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg memset(&addr, 0, sizeof(addr)); 1733f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg addr.l2_family = AF_BLUETOOTH; 1734f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bacpy(&addr.l2_bdaddr, dst); 1735f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1736f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1737f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (errno == EAGAIN || errno == EINPROGRESS) 1738f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1739f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't connect socket: %s (%d)", strerror(errno), errno); 1740f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1741f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1742f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1743d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg if (auth_required) 1744d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg *auth_required = TRUE; 1745d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg 1746f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1747f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1748f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedbergfailed: 1749f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg close(sk); 1750f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return -1; 1751f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg} 1752f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 17532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von DentzDBusMessage *device_create_bonding(struct btd_device *device, 17542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn, 17552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 17562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 17572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 17582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 17592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 17602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char *str, srcaddr[18], dstaddr[18]; 17612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 17622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 17632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t src; 1764f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg int sk; 1765f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg gboolean auth_required; 17662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(adapter, &src); 17682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&src, srcaddr); 17692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 17702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 17722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return in_progress(msg, "Bonding in progress"); 17732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* check if a link key already exists */ 17752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 17762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 17772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz str = textfile_caseget(filename, dstaddr); 17792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (str) { 17802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz free(str); 17812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, 17822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AlreadyExists", 17832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Bonding already exists"); 17842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 17852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1786dd10ec5d830d2e2187f93bd2d7e60be947335f0bJohan Hedberg 1787f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg sk = l2raw_connect(&src, &device->bdaddr, &auth_required); 17882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (sk < 0) 17892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, 17902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".ConnectionAttemptFailed", 17912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Connection attempt failed"); 17922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = bonding_request_new(conn, msg, device, agent_path, 17942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability); 17952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) { 17962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz close(sk); 17972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 17982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 17992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1800f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bonding->auth_required = auth_required; 1801dd10ec5d830d2e2187f93bd2d7e60be947335f0bJohan Hedberg 18022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->io = g_io_channel_unix_new(sk); 18032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->io_id = g_io_add_watch(bonding->io, 18042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR, 18052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz (GIOFunc) create_bonding_io_cb, 18062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 18072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->listener_id = g_dbus_add_disconnect_watch(conn, 18092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_get_sender(msg), 18102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_bond_req_exit, device, 18112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL); 18122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = bonding; 18142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->device = device; 18152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 18172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 18182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_bonding_complete(struct btd_device *device, uint8_t status) 18202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 18212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 18222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (status) 18242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 18252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->temporary = FALSE; 182768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 1828bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg g_free(device->authr); 1829bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg device->authr = NULL; 1830bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 1831bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg if (device->renewed_key) 1832bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg return; 1833bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 183468b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg /* If we were initiators start service discovery immediately. 183568b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * However if the other end was the initator wait a few seconds 183668b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * before SDP. This is due to potential IOP issues if the other 183768b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * end starts doing SDP at the same time as us */ 1838e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (bonding) { 1839e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg /* If we are initiators remove any discovery timer and just 1840e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg * start discovering services directly */ 1841e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (device->discov_timer) { 1842e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg g_source_remove(device->discov_timer); 1843e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg device->discov_timer = 0; 1844e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1845e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 18462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_browse(device, bonding->conn, bonding->msg, 18472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL, FALSE); 1848bdf140bd02cee6c39ebb8c6d71ac1d4f6f7eaa07Johan Hedberg } else if (!device->discov_active && !device->discov_timer && 1849bdf140bd02cee6c39ebb8c6d71ac1d4f6f7eaa07Johan Hedberg main_opts.reverse_sdp) { 18502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* If we are not initiators and there is no currently active 18512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz * discovery or discovery timer, set the discovery timer */ 18525fe418c129889a18df976050c68a0dab28dc766cMarcel Holtmann debug("setting timer for reverse service discovery"); 18532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->discov_timer = g_timeout_add_seconds(DISCOVERY_TIMER, 18542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz start_discovery, 18552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 1856e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1857e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 18582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_set_paired(device, TRUE); 18592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding_request_free(bonding); 18612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 18632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzfailed: 18652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_bonding(device, status); 18672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 18682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_bonding(struct btd_device *device, const char *sender) 18702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 18712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 18722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!device->bonding) 18742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 18752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!sender) 18772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return TRUE; 18782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_str_equal(sender, dbus_message_get_sender(bonding->msg)); 18802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1881e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 18822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_cancel_bonding(struct btd_device *device, uint8_t status) 18832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 18842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 18852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply; 18862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 18882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 18892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: canceling bonding request", device->path); 18912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 18932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_authentication(device); 18942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz reply = new_authentication_return(bonding->msg, status); 18962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(bonding->conn, reply); 18972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding_request_free(bonding); 18992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void pincode_cb(struct agent *agent, DBusError *err, const char *pincode, 19022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *data) 19032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 19052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 19062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 19082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 19092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, err, pincode, device); 19122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 19142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void confirm_cb(struct agent *agent, DBusError *err, void *data) 19172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 19192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 19202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 19222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 19232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, err, device); 19262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 19282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey, 19312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *data) 19322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 19342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 19352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 19372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 19382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, err, passkey, device); 19412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 19432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzint device_request_authentication(struct btd_device *device, auth_type_t type, 19462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint32_t passkey, void *cb) 19472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth; 19492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 19502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int ret; 19512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requesting agent authentication", device->path); 19532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = device->agent; 19552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) 19572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = adapter_get_agent(device->adapter); 19582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 19602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("No agent available for %u request", type); 19612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return -EPERM; 19622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 19632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth = g_new0(struct authentication_req, 1); 19652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->agent = agent; 19662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->device = device; 19672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = cb; 19682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->type = type; 19692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = auth; 19702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (type) { 19722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 19732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_pincode(agent, device, pincode_cb, 19742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth); 19752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 19762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 19772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_passkey(agent, device, passkey_cb, 19782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth); 19792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 19802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 19812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_confirmation(agent, device, passkey, 19822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz confirm_cb, auth); 19832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 19842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 19852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_display_passkey(agent, device, passkey); 19862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 19872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_AUTO: 19882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = 0; 19892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 19902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 19912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = -EINVAL; 19922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 19932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (ret < 0) { 19952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Failed requesting authentication"); 19962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(auth); 19972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = NULL; 19982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 19992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return ret; 20012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void cancel_authentication(struct authentication_req *auth) 20042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 20062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent = auth->agent; 20072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusError err; 20082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 20102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 20112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_init(&err); 20132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL); 20142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (auth->type) { 20162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 20172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device); 20182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 20202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, &err, device); 20212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 20232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, &err, 0, device); 20242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 20262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_AUTO: 20272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* User Notify/Auto doesn't require any reply */ 20282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_free(&err); 20322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 20332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_cancel_authentication(struct btd_device *device) 20362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = device->authr; 20382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth) 20402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 20412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: canceling authentication request", device->path); 20432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (auth->agent) 20452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent_cancel(auth->agent); 20462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz cancel_authentication(auth); 20482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = NULL; 20492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(auth); 20502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_authenticating(struct btd_device *device) 20532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return (device->authr != NULL); 2055013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 2056013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 2057bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedbergvoid device_set_renewed_key(struct btd_device *device, gboolean renewed) 2058bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg{ 2059bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg device->renewed_key = renewed; 2060bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg} 2061bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 206217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergvoid btd_device_add_uuid(struct btd_device *device, const char *uuid) 206317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg{ 206417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg GSList *uuid_list; 206517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg char *new_uuid; 206617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 206717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg if (g_slist_find_custom(device->uuids, uuid, 206817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg (GCompareFunc) strcasecmp)) 206917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg return; 207017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 207117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg new_uuid = g_strdup(uuid); 207217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg uuid_list = g_slist_append(NULL, new_uuid); 207317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 207417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg device_probe_drivers(device, uuid_list); 207517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 20760e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_free(new_uuid); 207717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg g_slist_free(uuid_list); 207817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 20790e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg store_profiles(device); 208017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(device); 208117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg} 208217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 2083548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedbergconst sdp_record_t *btd_device_get_record(struct btd_device *device, 2084548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg const char *uuid) 2085548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg{ 2086548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg bdaddr_t src; 2087548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2088548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) 2089548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 2090548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2091548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg adapter_get_address(device->adapter, &src); 2092548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2093548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = read_records(&src, &device->bdaddr); 2094548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (!device->tmp_records) 2095548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return NULL; 2096548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2097548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 2098548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg} 2099548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2100c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver) 2101c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2102c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_append(device_drivers, driver); 2103c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2104c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz return 0; 2105c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 2106c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2107c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver) 2108c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2109c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_remove(device_drivers, driver); 2110c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 2111