device.c revision a721957f20ec79b1a19537e5c43d3a12e4286c6c
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; 90a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz char name[248]; 9118614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter; 92ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode GSList *uuids; 93b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode GSList *drivers; /* List of driver_data */ 94ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode gboolean temporary; 95ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode struct agent *agent; 96ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint disconn_timer; 97ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode int discov_active; /* Service discovery active */ 987c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg char *discov_requestor; /* discovery requestor unique 997c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg * name */ 100ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode guint discov_listener; 101013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg guint discov_timer; 1022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 1032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *authr; /* authentication request */ 104ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 105ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode /* For Secure Simple Pairing */ 106ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t cap; 107ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode uint8_t auth; 108e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 109c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle; /* Connection handle */ 110e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 111e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg /* Whether were creating a security mode 3 connection */ 112e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg gboolean secmode3; 113548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 114548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *tmp_records; 115bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 116bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg gboolean renewed_key; 117ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode}; 118ea245383ac6650cbf34c327ed095d956b84ac5fbAlok Barsode 1193d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentzstruct browse_req { 1203d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusConnection *conn; 1213d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz DBusMessage *msg; 122555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 1230dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *match_uuids; 1240dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_added; 1250dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg GSList *profiles_removed; 126681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz sdp_list_t *records; 127d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann int search_uuid; 1283d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz}; 1293d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 130d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmannstatic uint16_t uuid_list[] = { 1310dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg L2CAP_UUID, 1321c284b3ba427638179d936286f4c4866fff99e28Luiz Augusto von Dentz PNP_INFO_SVCLASS_ID, 1330dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg PUBLIC_BROWSE_GROUP, 134d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 0 135d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann}; 136d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 137c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzstatic GSList *device_drivers = NULL; 138c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn, 1402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, int err) 1412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_common_reply(conn, msg, 1432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".ConnectionAttemptFailed", 1442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz err > 0 ? strerror(err) : "Connection attempt failed"); 1452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_failed(DBusConnection *conn, 1482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, const char * desc) 1492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc); 1512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic DBusHandlerResult error_failed_errno(DBusConnection *conn, 1542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, int err) 1552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *desc = strerror(err); 1572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return error_failed(conn, msg, desc); 1592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic inline DBusMessage *no_such_adapter(DBusMessage *msg) 1622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".NoSuchAdapter", 1642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "No such adapter"); 1652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic inline DBusMessage *in_progress(DBusMessage *msg, const char *str) 1682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 1692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", str); 1702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 172e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic void device_free(gpointer user_data) 17386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 174555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 1752f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1762f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz struct agent *agent = adapter_get_agent(adapter); 177e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 178fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite if (device->agent) 179fb27732e05fb7b69c3b784ed8a6aaed2d9d939aeCidorvan Leite agent_destroy(device->agent, FALSE); 180f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1812f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz if (agent && agent_is_busy(agent, device)) 1822f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz agent_cancel(agent); 1832f9fbeeb5931cda983aa72ed9a53b1f22d0aa85dLuiz Augusto von Dentz 184ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_foreach(device->uuids, (GFunc) g_free, NULL); 185ea00a446dbacead62040dd2bd7e663774c205c04Claudio Takahasi g_slist_free(device->uuids); 186f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 1875d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (device->disconn_timer) 1885d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_source_remove(device->disconn_timer); 1895d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 190401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz if (device->discov_timer) 191401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz g_source_remove(device->discov_timer); 192401374312bdc966bf386a1d89bf6cd0f74a4314cLuiz Augusto von Dentz 19386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device->path); 19486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_free(device); 19586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 19686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 197555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestatic gboolean device_is_paired(struct btd_device *device) 198769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz{ 19918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 200cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char filename[PATH_MAX + 1], *str; 201cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 202769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz gboolean ret; 203cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 2042a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 205cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 206cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 207cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 208769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 209769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, 210cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode srcaddr, "linkkeys"); 211cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str = textfile_caseget(filename, dstaddr); 212769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz ret = str ? TRUE : FALSE; 213769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(str); 214769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 215769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz return ret; 216769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz} 217769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz 218e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *get_properties(DBusConnection *conn, 219e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *user_data) 2202c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 221555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 22218614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 2234e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessage *reply; 2244e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter iter; 2254e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBusMessageIter dict; 226cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 227cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char name[248], srcaddr[18], dstaddr[18]; 2288a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi char **uuids; 2292a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode const char *ptr; 2304e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_bool_t boolean; 2314e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz uint32_t class; 232769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz int i; 233769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz GSList *l; 2344e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 235cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 236cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 2374e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz reply = dbus_message_new_method_return(msg); 2384e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz if (!reply) 239e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return NULL; 2404e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2414e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 2424e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2434e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 2444e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 2454e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 2464e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 2474e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2484e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Address */ 249cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ptr = dstaddr; 2501262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &ptr); 2514e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2524e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Name */ 253506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = NULL; 254506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi memset(name, 0, sizeof(name)); 2552a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 256cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 2578a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi 258a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz if (device->name) { 259a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz ptr = device->name; 2601262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ptr); 2614e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2624e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 263afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann /* Alias (fallback to name or address) */ 264afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (read_device_alias(srcaddr, dstaddr, name, sizeof(name)) < 1) { 265afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann if (!ptr) { 266afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann g_strdelimit(dstaddr, ":", '-'); 267afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann ptr = dstaddr; 268afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } 269afda5bee3495e4fe070cf59e2f240127c341faf4Marcel Holtmann } else 270506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi ptr = name; 271506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 272506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (ptr) 2731262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Alias", DBUS_TYPE_STRING, &ptr); 274506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi 2754e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Class */ 276cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (read_remote_class(&src, &device->bdaddr, &class) == 0) { 277e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann const char *icon = class_to_icon(class); 278e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 2791262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32, &class); 280e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann 281e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann if (icon) 2821262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Icon", 283e1a6c133d7a7fd2acf6d3462d200f47ff6124c1bMarcel Holtmann DBUS_TYPE_STRING, &icon); 2844e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz } 2854e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2864e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Paired */ 287769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz boolean = device_is_paired(device); 2881262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Paired", DBUS_TYPE_BOOLEAN, &boolean); 2894e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2904e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Trusted */ 291cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode boolean = read_trust(&src, dstaddr, GLOBAL_TRUST); 2921262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean); 2934e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 2944e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz /* Connected */ 295c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz boolean = (device->handle != 0); 296c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, 297c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz &boolean); 2984e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 299ba93fb91ea81a35be0834ac395650e020a6b3fd3Claudio Takahasi /* UUIDs */ 300769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 301769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 302769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz uuids[i] = l->data; 3033a11e84a573785024b11d89ed4f9b06e43b06ca6Johan Hedberg dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i); 304769c4b021665a26c9a6c20457ef9b7ded54c8ad6Luiz Augusto von Dentz g_free(uuids); 3054e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 30674fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz /* Adapter */ 3078a68b5fe931db5a432f924b0de22ed3acee024baClaudio Takahasi ptr = adapter_get_path(adapter); 3081262c4767c74f084d37c84bec778513f3d862a3eJohan Hedberg dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr); 30974fdac28eafca963c8081ea39dcf057459cf491aLuiz Augusto von Dentz 3104e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 3114e6726e8029f20be3e08b44760c56fc7a419090bLuiz Augusto von Dentz 312e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return reply; 3132c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 3142c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 315e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg, 3167fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *alias, void *data) 3177fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 318555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 31918614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 320cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 321cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 322506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi int err; 3237fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 324cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 325cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 326cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3272a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 328cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode /* Remove alias if empty string */ 329cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode err = write_device_alias(srcaddr, dstaddr, 330506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi g_str_equal(alias, "") ? NULL : alias); 331506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi if (err < 0) 332e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 333e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".Failed", 334506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi strerror(-err)); 3357fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 336c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 337c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Alias", 338c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_STRING, &alias); 3397fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 340e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3417fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3427fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 343e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg, 3447fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value, void *data) 3457fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz{ 346555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = data; 34718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 348cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 349cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 3502a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 351cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode adapter_get_address(adapter, &src); 352cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 353cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 3542a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 355cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value); 3567fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 357c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, dbus_message_get_path(msg), 358c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DEVICE_INTERFACE, "Trusted", 359c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg DBUS_TYPE_BOOLEAN, &value); 3607fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 361e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return dbus_message_new_method_return(msg); 3627fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz} 3637fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 364e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic inline DBusMessage *invalid_args(DBusMessage *msg) 365e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi{ 366e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return g_dbus_create_error(msg, 367e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi ERROR_INTERFACE ".InvalidArguments", 368e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi "Invalid arguments in method call"); 369e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi} 370e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi 371e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic DBusMessage *set_property(DBusConnection *conn, 372e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi DBusMessage *msg, void *data) 3732c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes{ 3747fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter iter; 3757fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz DBusMessageIter sub; 3767fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz const char *property; 3777fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3787fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (!dbus_message_iter_init(msg, &iter)) 379e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3807fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3817fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 382e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3837fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3847fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&iter, &property); 3857fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_next(&iter); 3867fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3877fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) 388e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3897fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_recurse(&iter, &sub); 3907fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3917fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (g_str_equal("Trusted", property)) { 3927fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_bool_t value; 3937fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3947fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) 395e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 3967fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &value); 3977fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 3987fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_trust(conn, msg, value, data); 3997fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } else if (g_str_equal("Alias", property)) { 400506c95298346d318304aa7e2211dfba5dbe6e3e0Claudio Takahasi const char *alias; 4017fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 4027fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) 403e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 4047fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz dbus_message_iter_get_basic(&sub, &alias); 4057fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 4067fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz return set_alias(conn, msg, alias, data); 4077fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz } 4087fe6ac58638e86d11494f5a785bcf1d074ca2c37Luiz Augusto von Dentz 409e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi return invalid_args(msg); 4102c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes} 4112c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 4121f5107e65f9786bd6b84ecfb4d84691e9b34529aMarcel Holtmannstatic void discover_services_req_exit(DBusConnection *conn, void *user_data) 413342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz{ 414555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 41518614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 416cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4172a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4182a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 419342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 420342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz debug("DiscoverDevices requestor exited"); 421342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 422cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bt_cancel_discovery(&src, &device->bdaddr); 423342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz} 424342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 42594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *discover_services(DBusConnection *conn, 42694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 42794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 428555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 42994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann const char *pattern; 430342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz int err; 431342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 432342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (device->discov_active) 433342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", 4347c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg "Discover in progress"); 43594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 43694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, 43794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBUS_TYPE_INVALID) == FALSE) 438342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 43994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 440a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (strlen(pattern) == 0) { 44169adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, NULL, FALSE); 442342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 443342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 444342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } else { 445040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi uuid_t uuid; 446040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi 447040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi if (bt_string2uuid(&uuid, pattern) < 0) 448342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return invalid_args(msg); 449a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann 4504b1914903cb105acf843b84833e81d5470133879Johan Hedberg sdp_uuid128_to_uuid(&uuid); 4514b1914903cb105acf843b84833e81d5470133879Johan Hedberg 45269adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg err = device_browse(device, conn, msg, &uuid, FALSE); 453342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (err < 0) 454342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz goto fail; 455342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz } 45694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 45794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return NULL; 458342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 459342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentzfail: 460342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", 461342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Discovery Failed"); 46294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 46394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 46494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmannstatic DBusMessage *cancel_discover(DBusConnection *conn, 46594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann DBusMessage *msg, void *user_data) 46694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 467555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 46818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 4697c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg const char *sender = dbus_message_get_sender(msg); 470cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 4712a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 4722a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 47319b4c8b0e51a20a1b95ede34b092ebc56e1183aeMarcel Holtmann 474342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_active) 475342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 476342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 477342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "No pending discovery"); 478342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 479342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz /* only the discover requestor can cancel the inquiry process */ 480342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz if (!device->discov_requestor || 4817c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg !g_str_equal(device->discov_requestor, sender)) 482342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz return g_dbus_create_error(msg, 483342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz ERROR_INTERFACE ".NotAuthorized", 484342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz "Not Authorized"); 485342293a80657406a02003452e3a23d097dd9c73eLuiz Augusto von Dentz 486cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode if (bt_cancel_discovery(&src, &device->bdaddr) < 0) 487289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz return g_dbus_create_error(msg, 488289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz ERROR_INTERFACE ".Failed", 489289e29c6c4a073569c7e7aa3c8fc51ed5c46993fLuiz Augusto von Dentz "No pending discover"); 49094c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 49194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 49294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 49394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 4945d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasistatic gboolean disconnect_timeout(gpointer user_data) 4955d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi{ 496555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 4975d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_cp cp; 4985d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi int dd; 499661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode uint16_t dev_id = adapter_get_dev_id(device->adapter); 5005d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5015d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = 0; 5025d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 503661a10565362c5ae0aad6a2ebf6513390cba868eAlok Barsode dd = hci_open_dev(dev_id); 5045d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi if (dd < 0) 5055d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi goto fail; 5065d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5075d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi memset(&cp, 0, sizeof(cp)); 508c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz cp.handle = htobs(device->handle); 5095d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi cp.reason = HCI_OE_USER_ENDED_CONNECTION; 5105d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5115d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, 5125d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DISCONNECT_CP_SIZE, &cp); 5135d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5145d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi close(dd); 5155d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5165d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasifail: 5175d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return FALSE; 5185d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi} 5195d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5207c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstatic DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, 5217c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg void *user_data) 52294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann{ 523555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = user_data; 5245d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 525c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (!device->handle) 5265d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi return g_dbus_create_error(msg, 5275d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi ERROR_INTERFACE ".NotConnected", 5285d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi "Device is not connected"); 5295d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5305d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi g_dbus_emit_signal(conn, device->path, 5315d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DEVICE_INTERFACE, "DisconnectRequested", 5325d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi DBUS_TYPE_INVALID); 5335d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi 5345d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER, 5355d49d848060b0809a25acb9a20b176600f52e66dClaudio Takahasi disconnect_timeout, device); 53694c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 53794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann return dbus_message_new_method_return(msg); 53894c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann} 53994c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann 540e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusMethodTable device_methods[] = { 541e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "GetProperties", "", "a{sv}", get_properties }, 542e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "SetProperty", "sv", "", set_property }, 543e0d13d6da4b527ee02838af6b9dd7d53615e4896Marcel Holtmann { "DiscoverServices", "s", "a{us}", discover_services, 54494c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann G_DBUS_METHOD_FLAG_ASYNC}, 54594c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "CancelDiscovery", "", "", cancel_discover }, 546e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi { "Disconnect", "", "", disconnect }, 54794c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5482c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5492c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 550e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasistatic GDBusSignalTable device_signals[] = { 55194c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "PropertyChanged", "sv" }, 55294c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { "DisconnectRequested", "" }, 55394c199911b1dc1395a8025647f0686f58e6bf4f6Marcel Holtmann { } 5542c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes}; 5552c1effee41e974f97b21aec1bdd1a232ba48056aVinicius Costa Gomes 556c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzgboolean device_is_connected(struct btd_device *device) 557e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 558c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return (device->handle != 0); 559e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 560e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 5617c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstatic void device_set_connected(struct btd_device *device, 5627c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg DBusConnection *conn, 5637c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg gboolean connected) 564013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 565c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, 566c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg "Connected", DBUS_TYPE_BOOLEAN, &connected); 567e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 568e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg if (connected && device->secmode3) { 569e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg struct btd_adapter *adapter = device_get_adapter(device); 570e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg bdaddr_t sba; 571e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 572e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg adapter_get_address(adapter, &sba); 573e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 574e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = FALSE; 575e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 576e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0); 577e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg } 578e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg} 579e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 580c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzvoid device_add_connection(struct btd_device *device, DBusConnection *conn, 581c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle) 582c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 583c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle) { 584c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz error("%s: Unable to add connection %u, %u already exist)", 585c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->path, handle, device->handle); 586c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 587c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 588c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 589c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->handle = handle; 590c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 591c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device_set_connected(device, conn, TRUE); 592c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 593c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 594c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzvoid device_remove_connection(struct btd_device *device, DBusConnection *conn, 595c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz uint16_t handle) 596c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 597c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle != handle) { 598c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz error("%s: Unable to remove connection %u, handle mismatch (%u)", 599c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->path, handle, device->handle); 600c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return; 601c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz } 602c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 603c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device->handle = 0; 604c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 605c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz device_set_connected(device, conn, FALSE); 606c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 607c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 608c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentzgboolean device_has_connection(struct btd_device *device, uint16_t handle) 609c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz{ 610c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz return (handle == device->handle); 611c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz} 612c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz 613e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedbergvoid device_set_secmode3_conn(struct btd_device *device, gboolean enable) 614e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg{ 615e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg device->secmode3 = enable; 616013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 617013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 6187c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstruct btd_device *device_create(DBusConnection *conn, 6197c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg struct btd_adapter *adapter, 62036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const gchar *address) 62186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann{ 622ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite gchar *address_up; 623555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device; 624139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann const gchar *adapter_path = adapter_get_path(adapter); 625a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz bdaddr_t src; 626a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz char srcaddr[18]; 62786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 628555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode device = g_try_malloc0(sizeof(struct btd_device)); 62986892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann if (device == NULL) 63086892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 63186892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 632ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite address_up = g_ascii_strup(address, -1); 633139c2014be451848fcc3fa31cdc07653148f596eMarcel Holtmann device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up); 63486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann g_strdelimit(device->path, ":", '_'); 635ecbcc749831ab86da7ed8d15c36f1bd1fb380be8Cidorvan Leite g_free(address_up); 63686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 63786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann debug("Creating device %s", device->path); 63886892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 639e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi if (g_dbus_register_interface(conn, device->path, DEVICE_INTERFACE, 640e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device_methods, device_signals, NULL, 641e2731d4c2e3ef7d1677a73aca5fa58f044075980Claudio Takahasi device, device_free) == FALSE) { 64286892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann device_free(device); 64386892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann return NULL; 64486892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann } 645da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 646cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode str2ba(address, &device->bdaddr); 647da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi device->adapter = adapter; 648a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz adapter_get_address(adapter, &src); 649a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz ba2str(&src, srcaddr); 650a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz read_device_name(srcaddr, address, device->name); 651da0e7105811dc046d13d0365404efc1189ee4a8cClaudio Takahasi 6528493d6363e61f1ef68763aab8e65f75be7f67facJohan Hedberg device->auth = 0xff; 6538493d6363e61f1ef68763aab8e65f75be7f67facJohan Hedberg 6546bfa88d706cc57a0c975c980dabec5d8ed67dcc0Claudio Takahasi return device; 65586892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 65686892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann 657a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentzvoid device_set_name(struct btd_device *device, const char *name) 658a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz{ 659a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 660a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz char alias[248]; 661a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz char srcaddr[18], dstaddr[18]; 662a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz bdaddr_t src; 663a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 664a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz if (strncmp(name, device->name, 248) == 0) 665a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz return; 666a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 667a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz strncpy(device->name, name, 248); 668a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 669a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz emit_property_changed(conn, device->path, 670a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DEVICE_INTERFACE, "Name", 671a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBUS_TYPE_STRING, &name); 672a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 673a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz adapter_get_address(device->adapter, &src); 674a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz ba2str(&src, srcaddr); 675a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 676a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 677a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz if (read_device_alias(srcaddr, dstaddr, alias, sizeof(alias)) == 0) 678a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz return; 679a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 680a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz emit_property_changed(conn, device->path, 681a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DEVICE_INTERFACE, "Alias", 682a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz DBUS_TYPE_STRING, &name); 683a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz} 684a721957f20ec79b1a19537e5c43d3a12e4286c6cLuiz Augusto von Dentz 6857c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedbergstatic void device_remove_bonding(struct btd_device *device, 6867c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg DBusConnection *conn) 6872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 6882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 6892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char *str, srcaddr[18], dstaddr[18]; 6902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int dd, dev_id; 6912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t bdaddr; 6922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz gboolean paired; 6932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(device->adapter, &bdaddr); 6952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&bdaddr, srcaddr); 6962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 6972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 6982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dev_id = adapter_get_dev_id(device->adapter); 6992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dd = hci_open_dev(dev_id); 7012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (dd < 0) 7022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 7032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 7052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 7062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* textfile_del doesn't return an error when the key is not found */ 7082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz str = textfile_caseget(filename, dstaddr); 7092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz paired = str ? TRUE : FALSE; 7102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(str); 7112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!paired) 7132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 7142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Delete the link key from storage */ 7162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz textfile_casedel(filename, dstaddr); 7172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Delete the link key from the Bluetooth chip */ 7192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT); 7202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* Send the HCI disconnect command */ 722c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz if (device->handle) { 723c4338c0b7a46d6288e350b8c05fc02ee28b4bdbcLuiz Augusto von Dentz int err = hci_disconnect(dd, htobs(device->handle), 7242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz HCI_OE_USER_ENDED_CONNECTION, 7252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz HCI_REQ_TIMEOUT); 7262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (err < 0) 7272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Disconnect: %s (%d)", strerror(-err), -err); 7282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 7292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 7312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz paired = FALSE; 7332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz emit_property_changed(conn, device->path, DEVICE_INTERFACE, 7342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Paired", DBUS_TYPE_BOOLEAN, &paired); 7352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 7362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7377dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentzstatic void device_remove_stored(struct btd_device *device, 7387dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz DBusConnection *conn) 7397dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz{ 7407dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz bdaddr_t src; 7417dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz char addr[18]; 7427dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz 7437dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz adapter_get_address(device->adapter, &src); 7447dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz ba2str(&device->bdaddr, addr); 7457dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz device_remove_bonding(device, conn); 7467dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz delete_entry(&src, "profiles", addr); 7477dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz delete_entry(&src, "trusts", addr); 7487dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz} 7497dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz 75058c15493922277539cca11e8b55776c5d0fbccbaJohan Hedbergvoid device_remove(struct btd_device *device, DBusConnection *conn, 7517dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz gboolean remove_stored) 75275add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi{ 7536061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann GSList *list; 7546061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann struct btd_device_driver *driver; 755f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann gchar *path = g_strdup(device->path); 756f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 757f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann debug("Removing device %s", path); 758f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann 7592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 7602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION); 7612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7627dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz if (!device->temporary && remove_stored) 7637dfdd472eed6368bbae14aa989e712a49f3e7f12Luiz Augusto von Dentz device_remove_stored(device, conn); 7642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 7656061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann for (list = device->drivers; list; list = list->next) { 766b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 767b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver = driver_data->driver; 7686061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 769e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 770b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 7716061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann } 7726061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann 77367d8c4fbc43e4e72174da96734572c3c2291bc4bJohan Hedberg 774f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_dbus_unregister_interface(conn, path, DEVICE_INTERFACE); 77575add5651e5dbc49c9c144acceac7e2c32d9bd16Claudio Takahasi 776f62f8d892b5d5cc5aedef83779671c1ed54a35daMarcel Holtmann g_free(path); 77786892be8d38960096f9b9c5613ba28fc9003d288Marcel Holtmann} 778ff296428a08dee619db1cc702146faefa91087faCidorvan Leite 779555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegint device_address_cmp(struct btd_device *device, const gchar *address) 780ff296428a08dee619db1cc702146faefa91087faCidorvan Leite{ 781cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char addr[18]; 782cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode 783cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, addr); 784cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode return strcasecmp(addr, address); 785ff296428a08dee619db1cc702146faefa91087faCidorvan Leite} 7863d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 7873870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedbergstatic gboolean record_has_uuid(const sdp_record_t *rec, 7883870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg const char *profile_uuid) 789f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 7903870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg sdp_list_t *pat; 791f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7923870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg for (pat = rec->pattern; pat != NULL; pat = pat->next) { 793f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz char *uuid; 7943870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg int ret; 795f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 7963870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg uuid = bt_uuid2string(pat->data); 797f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!uuid) 798f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 799f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 8003870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg ret = strcasecmp(uuid, profile_uuid); 801f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 8023870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg g_free(uuid); 8033870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg 8043870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg if (ret == 0) 8053870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return TRUE; 806f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 807f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 8083870d6ab80711042b0c9224eac34293cb6b16aeaJohan Hedberg return FALSE; 809f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 810f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 811f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_pattern(struct btd_device *device, 812878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg const char *match_uuid, 813f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 814f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 815f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *l, *uuids = NULL; 816f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 817f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (l = profiles; l; l = l->next) { 818878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg char *profile_uuid = l->data; 819f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz const sdp_record_t *rec; 8203bb7c1527ce3ec67127200b54a8fbc01a196ebadJohan Hedberg 821878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg rec = btd_device_get_record(device, profile_uuid); 822f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!rec) 823f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 824f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 825a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg if (record_has_uuid(rec, match_uuid)) 826878dee664d16eb6643e0ba2d5d9c2452f98f172eJohan Hedberg uuids = g_slist_append(uuids, profile_uuid); 827cdfe8a8246013031f55c647092e41adbb29ace81Johan Hedberg } 828f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 829f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 830f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 831f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 832f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzstatic GSList *device_match_driver(struct btd_device *device, 833f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_device_driver *driver, 834f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *profiles) 835f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann{ 8366061f1a889c90d4d408ca12b63b2db6235c73baeMarcel Holtmann const char **uuid; 837f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *uuids = NULL; 838f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 839f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 840f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *match; 841f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 8429b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz /* skip duplicated uuids */ 8439b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz if (g_slist_find_custom(uuids, *uuid, 8449b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz (GCompareFunc) strcasecmp)) 8459b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz continue; 8469b953c8757093b51eb86e6593d514e9839fd8d7dLuiz Augusto von Dentz 847f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match profile driver */ 848f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = g_slist_find_custom(profiles, *uuid, 849f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz (GCompareFunc) strcasecmp); 850f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (match) { 851f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 852f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 853f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 854f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 855f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz /* match pattern driver */ 856f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz match = device_match_pattern(device, *uuid, profiles); 857a01801fd21056ef6f7fffc6a205b6c2b9e99899fJohan Hedberg for (; match; match = match->next) 858f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz uuids = g_slist_append(uuids, match->data); 859f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz } 860f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 861f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz return uuids; 862f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz} 863f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 864f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentzvoid device_probe_drivers(struct btd_device *device, GSList *profiles) 865f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz{ 866f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *list; 867f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann int err; 868f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 869f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann debug("Probe drivers for %s", device->path); 870f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 871c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz for (list = device_drivers; list; list = list->next) { 872e0863545e6239ac338fa7fbe9647a5748a60b436Marcel Holtmann struct btd_device_driver *driver = list->data; 873f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz GSList *probe_uuids; 874f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz struct btd_driver_data *driver_data; 875f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 876f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz probe_uuids = device_match_driver(device, driver, profiles); 8774b0ab7e43f4fa555641902b07f2f7ab3821f2b75Alok Barsode 878f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (!probe_uuids) 879f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 880081d9d1df3cde11e3e3833201f4cadac6f355da0Luiz Augusto von Dentz 881f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data = g_new0(struct btd_driver_data, 1); 882b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 883f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz err = driver->probe(device, probe_uuids); 884f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz if (err < 0) { 885f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz error("probe failed with driver %s for device %s", 886f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver->name, device->path); 887b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 888f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_free(driver_data); 889548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg g_slist_free(probe_uuids); 890f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz continue; 891f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 892f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz 893f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz driver_data->driver = driver; 894f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz device->drivers = g_slist_append(device->drivers, driver_data); 895f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz g_slist_free(probe_uuids); 896f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann } 89736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 898f1c3d8c1fabd801eac34c9069038d3f4cadcb58dLuiz Augusto von Dentz for (list = profiles; list; list = list->next) { 899c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann GSList *l = g_slist_find_custom(device->uuids, list->data, 9007c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (GCompareFunc) strcasecmp); 901c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann if (l) 902c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann continue; 903c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann 90436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_insert_sorted(device->uuids, 9057c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg g_strdup(list->data), 9067c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (GCompareFunc) strcasecmp); 907548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 908548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 909548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) { 910548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(device->tmp_records, 911548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg (sdp_free_func_t) sdp_record_free); 912548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = NULL; 913c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann } 91436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 91536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 91699bc055edc4b9ba8ccda791757a6439fb03ff8f2Marcel Holtmannstatic void device_remove_drivers(struct btd_device *device, GSList *uuids) 91736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 91818614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 919352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg GSList *list, *next; 920cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 9212a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 922548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_t *records; 9232a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 9242a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 925cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 926cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 92736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 928548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = read_records(&src, &device->bdaddr); 929548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 93036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz debug("Remove drivers for %s", device->path); 93136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 932352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg for (list = device->drivers; list; list = next) { 933b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_driver_data *driver_data = list->data; 934b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode struct btd_device_driver *driver = driver_data->driver; 93536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz const char **uuid; 93636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 937352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg next = list->next; 938352a65d3de4fdf6e1e507f958685097f33e3b899Johan Hedberg 93936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (uuid = driver->uuids; *uuid; uuid++) { 9409b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz sdp_record_t *rec; 94136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 9429b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!g_slist_find_custom(uuids, *uuid, 9439b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz (GCompareFunc) strcasecmp)) 94436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 94536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 9467c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg debug("UUID %s was removed from device %s", 9477c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg *uuid, dstaddr); 948548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 949e780c7bd8ec0527723db3c19f28365063bbe7d93Luiz Augusto von Dentz driver->remove(device); 95036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->drivers = g_slist_remove(device->drivers, 951b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode driver_data); 952b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode g_free(driver_data); 953b76fbc7d29f28a95a9ea25aae1f6f2d9c10adb19Alok Barsode 954548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg rec = find_record_in_list(records, *uuid); 9559b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz if (!rec) 9562d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg break; 9579b4bfa74d25e360932402994a32305bf2145eb34Luiz Augusto von Dentz 958cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode delete_record(srcaddr, dstaddr, rec->handle); 959548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 960548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg records = sdp_list_remove(records, rec); 961548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_record_free(rec); 9622d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg 9632d370d5d678973644c2c3c75b22d5f24b7a2c638Johan Hedberg break; 96436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 96536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 96636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 967548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (records) 968548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg sdp_list_free(records, (sdp_free_func_t) sdp_record_free); 969548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 97036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (list = uuids; list; list = list->next) 97136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz device->uuids = g_slist_remove(device->uuids, list->data); 972f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann} 973f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 974bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmannstatic void iter_append_record(DBusMessageIter *dict, uint32_t handle, 975bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann const char *record) 976bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann{ 977bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann DBusMessageIter entry; 978bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 979bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, 980bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann NULL, &entry); 981bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 982bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle); 983bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 984bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record); 985bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 986bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann dbus_message_iter_close_container(dict, &entry); 987bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann} 988bbe56de7715cf62e37026711a6eb3f1c5be6d1cdMarcel Holtmann 989730775d1226a30c37ff551955f093ddfcd18e600Claudio Takahasistatic void append_and_grow_string(void *data, const char *str) 990c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz{ 991c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz sdp_buf_t *buff = data; 992c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz int len; 993c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 994c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz len = strlen(str); 995c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 996c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) { 997c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = malloc(DEFAULT_XML_BUF_SIZE); 998c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!buff->data) 999c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 1000c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = DEFAULT_XML_BUF_SIZE; 1001c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 1002c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 1003c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow string */ 1004c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz while (buff->buf_size < (buff->data_size + len + 1)) { 1005c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz void *tmp; 1006c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz uint32_t new_size; 1007c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 1008c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Grow buffer by a factor of 2 */ 1009c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz new_size = (buff->buf_size << 1); 1010c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 1011c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz tmp = realloc(buff->data, new_size); 1012c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz if (!tmp) 1013c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz return; 1014c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 1015c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data = tmp; 1016c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->buf_size = new_size; 1017c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz } 1018c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 1019c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz /* Include the NULL character */ 1020c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz memcpy(buff->data + buff->data_size, str, len + 1); 1021c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz buff->data_size += len; 1022c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz} 1023c36942e998cd6187181df3033e53f1d624a5fd1aLuiz Augusto von Dentz 10241e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzstatic void discover_device_reply(struct browse_req *req, sdp_list_t *recs) 10251e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz{ 10261e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessage *reply; 10271e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBusMessageIter iter, dict; 10281e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_list_t *seq; 10291e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10301e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 10311e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!reply) 10321e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz return; 10331e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10341e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_init_append(reply, &iter); 10351e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10361e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 10371e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 10381e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING 10391e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 10401e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10411e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 10421e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 10431e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz sdp_buf_t result; 10441e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10451e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (!rec) 10461e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz break; 10471e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10481e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz memset(&result, 0, sizeof(sdp_buf_t)); 10491e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10501e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz convert_sdp_record_to_xml(rec, &result, 10511e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz append_and_grow_string); 10521e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10531e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz if (result.data) { 10541e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz const char *val = (char *) result.data; 10551e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz iter_append_record(&dict, rec->handle, val); 10561e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz free(result.data); 10571e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 10581e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz } 10591e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 10601e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz dbus_message_iter_close_container(&iter, &dict); 10611e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 1062a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 10631e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz} 10641e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz 106517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void services_changed(struct btd_device *device) 10663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 1067533655873c4978091edf3698b20d2b96c43dafc8Johan Hedberg DBusConnection *conn = get_dbus_connection(); 10683d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz char **uuids; 10693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz GSList *l; 107036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz int i; 10713d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 107236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids = g_new0(char *, g_slist_length(device->uuids) + 1); 107336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (i = 0, l = device->uuids; l; l = l->next, i++) 107436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz uuids[i] = l->data; 107536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 107658f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg emit_array_property_changed(conn, device->path, DEVICE_INTERFACE, 107758f06324289d7d343a52a9104d02121cb8db1047Johan Hedberg "UUIDs", DBUS_TYPE_STRING, &uuids); 107836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 107936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(uuids); 108036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 108136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 10828b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedbergstatic int rec_cmp(const void *a, const void *b) 10838b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg{ 10848b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r1 = a; 10858b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg const sdp_record_t *r2 = b; 10868b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 10878b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg return r1->handle - r2->handle; 10888b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg} 10898b2e688eaf5b71006c72cf91a8e4df3c0c41c306Johan Hedberg 109036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentzstatic void update_services(struct browse_req *req, sdp_list_t *recs) 109136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 1092555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 109318614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device_get_adapter(device); 109436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *seq; 1095cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode char srcaddr[18], dstaddr[18]; 10962a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode bdaddr_t src; 10972a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 10982a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 1099cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&src, srcaddr); 1100cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode ba2str(&device->bdaddr, dstaddr); 11013d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 110236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz for (seq = recs; seq; seq = seq->next) { 11033d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz sdp_record_t *rec = (sdp_record_t *) seq->data; 110436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_t *svcclass = NULL; 11050dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg gchar *profile_uuid; 110636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz GSList *l; 11073d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 11083d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!rec) 11093d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz break; 11103d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 111136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (sdp_get_service_classes(rec, &svcclass) < 0) 111236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 111336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 111436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Extract the first element and skip the remainning */ 11150dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid = bt_uuid2string(svcclass->data); 11160dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!profile_uuid) { 1117aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 111836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz continue; 1119aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg } 112036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 11210dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!strcasecmp(profile_uuid, PNP_UUID)) { 1122fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann uint16_t source, vendor, product, version; 1123e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse sdp_data_t *pdlist; 1124e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1125fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE); 1126fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann source = pdlist ? pdlist->val.uint16 : 0x0000; 1127fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann 1128e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); 1129e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse vendor = pdlist ? pdlist->val.uint16 : 0x0000; 1130e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1131e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); 1132e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse product = pdlist ? pdlist->val.uint16 : 0x0000; 1133e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1134e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse pdlist = sdp_data_get(rec, SDP_ATTR_VERSION); 1135e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse version = pdlist ? pdlist->val.uint16 : 0x0000; 1136e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 1137fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann if (source || vendor || product || version) 1138fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann store_device_id(srcaddr, dstaddr, source, 1139fce6db565f747ca9ad560f7d8bff6a45522d905cMarcel Holtmann vendor, product, version); 1140e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse } 1141e2a5786af8c8278eeeb0bedccda32c7422e9a2b7David Woodhouse 114237a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg /* Check for duplicates */ 1143981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg if (sdp_list_find(req->records, rec, rec_cmp)) { 11440dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 1145aaf0f75d2a18a86bca3c418ddd63e936627c4446Johan Hedberg sdp_list_free(svcclass, free); 114637a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg continue; 1147981f4416220e01a3eab92aa3c8d03c16dcad450dJohan Hedberg } 114837a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1149cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode store_record(srcaddr, dstaddr, rec); 115037a7d2aba17bcb47a3e9bfba78ad23a8a3cbe420Johan Hedberg 1151681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Copy record */ 11527c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg req->records = sdp_list_append(req->records, 11537c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sdp_copy_record(rec)); 1154681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 11550dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l = g_slist_find_custom(device->uuids, profile_uuid, 1156c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann (GCompareFunc) strcmp); 115736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!l) 11580dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_added = 11590dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_append(req->profiles_added, 11600dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg profile_uuid); 116136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz else { 11620dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = 11630dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_remove(req->profiles_removed, 11640dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg l->data); 11650dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_free(profile_uuid); 11663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 11673d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 116836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz sdp_list_free(svcclass, free); 11693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz } 117036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 117136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 117217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergstatic void store_profiles(struct btd_device *device) 117336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 117418614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 1175cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 117636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz char *str; 11773d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 11782a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 11793d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 118036dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz if (!device->uuids) { 1181cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, ""); 118236dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz return; 118336dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz } 118436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 118536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz str = bt_list2string(device->uuids); 1186cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode write_device_profiles(&src, &device->bdaddr, str); 118736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz g_free(str); 118836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz} 118936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 1190a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentzstatic void browse_req_free(struct browse_req *req) 1191a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz{ 1192a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz struct btd_device *device = req->device; 1193a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1194a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_active = 0; 1195a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1196a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (device->discov_requestor) { 1197a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_dbus_remove_watch(req->conn, device->discov_listener); 1198a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_listener = 0; 1199a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(device->discov_requestor); 1200a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz device->discov_requestor = NULL; 1201a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz } 1202a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1203a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->msg) 1204a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_message_unref(req->msg); 1205a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->conn) 1206a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz dbus_connection_unref(req->conn); 12070dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL); 12080dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_added); 12090dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg g_slist_free(req->profiles_removed); 1210a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (req->records) 1211a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); 1212a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz g_free(req); 1213a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz} 1214a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1215da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void search_cb(sdp_list_t *recs, int err, gpointer user_data) 121636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz{ 121736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz struct browse_req *req = user_data; 1218555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsode struct btd_device *device = req->device; 121936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz DBusMessage *reply; 12202a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 1221681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz if (err < 0) { 1222681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz error("%s: error updating services: %s (%d)", 1223681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz device->path, strerror(-err), -err); 122436dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1225681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 122636dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 122736dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz update_services(req, recs); 122836dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz 12290dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (!req->profiles_added && !req->profiles_removed) { 1230e62d9fec6ad663d335a8f915568e5f35cd0633b1Luiz Augusto von Dentz debug("%s: No service update", device->path); 123136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz goto proceed; 1232681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz } 12332efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 1234548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records && req->records) { 12357c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sdp_list_free(device->tmp_records, 12367c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg (sdp_free_func_t) sdp_record_free); 1237548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = req->records; 1238548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg req->records = NULL; 1239548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg } 1240548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 124136dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Probe matching drivers for services added */ 12420dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_added) 12430dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_probe_drivers(device, req->profiles_added); 12442efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 124536dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Remove drivers for services removed */ 12460dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (req->profiles_removed) 12470dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg device_remove_drivers(device, req->profiles_removed); 12482efdbe3a944fb2c8c6e0f581b899140b4ef84bcbLuiz Augusto von Dentz 124936dedff329b5ced8979a2161075e6a9d38c58785Luiz Augusto von Dentz /* Propagate services changes */ 125017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(req->device); 1251f4eb9e2dea643f41e261bb9e2bff33fc03bd9eccMarcel Holtmann 12527b67507336f98dda5523902806dd2e33684fab6bLuiz Augusto von Dentzproceed: 1253681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz /* Store the device's profiles in the filesystem */ 125417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg store_profiles(device); 1255681e50c618d246483728bca6628a18c1c44c5b36Luiz Augusto von Dentz 12562ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg if (!req->msg) 12572ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg goto cleanup; 12582ba670eae0d7d0d57160b7e5bd387079f86d933cJohan Hedberg 1259438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, 1260438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz "DiscoverServices")) { 1261438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz discover_device_reply(req, req->records); 1262438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz goto cleanup; 1263438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz } 1264438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 12653d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz /* Reply create device request */ 12663d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz reply = dbus_message_new_method_return(req->msg); 12673d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz if (!reply) 12681e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentz goto cleanup; 12693d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 12703d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &device->path, 1271a2529a9b417959a52f5d501cba4bcaf32caf6964Marcel Holtmann DBUS_TYPE_INVALID); 12723d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1273a5883ecb1aa94b09bcf0e7ce4184d262027c5939Johan Hedberg g_dbus_send_message(req->conn, reply); 12743d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 12751e8fbfbfa6fbcf88a668f77e5601bbc505eb483fLuiz Augusto von Dentzcleanup: 1276a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1277da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1278da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1279da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzstatic void browse_cb(sdp_list_t *recs, int err, gpointer user_data) 1280da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1281da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct browse_req *req = user_data; 1282da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_device *device = req->device; 1283da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 1284cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1285da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz uuid_t uuid; 1286da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 12877c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg /* If we have a valid response and req->search_uuid == 2, then L2CAP 12887c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg * UUID & PNP searching was successful -- we are done */ 12890dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg if (err < 0 || (req->search_uuid == 2 && req->records)) 1290da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz goto done; 1291da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1292da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz update_services(req, recs); 1293da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1294da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz adapter_get_address(adapter, &src); 1295da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1296da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz /* Search for mandatory uuids */ 12977d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse if (uuid_list[req->search_uuid]) { 12987d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 1299c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann bt_search_service(&src, &device->bdaddr, &uuid, 1300c4c130d3922dedc992e00fbf94bde64a180306c2Marcel Holtmann browse_cb, user_data, NULL); 1301da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz return; 1302da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz } 1303da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 1304da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentzdone: 1305da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz search_cb(recs, err, user_data); 1306da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz} 1307da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 130869adac833c5633714b84bf840c75aa814193b8a6Johan Hedbergstatic void init_browse(struct browse_req *req, gboolean reverse) 1309da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz{ 1310da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz GSList *l; 1311da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz 131269adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg /* If we are doing reverse-SDP don't try to detect removed profiles 131369adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * since some devices hide their service records while they are 131469adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg * connected 131569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg */ 131669adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg if (reverse) 131769adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg return; 131869adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg 1319da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz for (l = req->device->uuids; l; l = l->next) 13200dabe8201eac11459010694bca66d6b217936fcbJohan Hedberg req->profiles_removed = g_slist_append(req->profiles_removed, 1321da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz l->data); 13223d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 13233d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1324555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeint device_browse(struct btd_device *device, DBusConnection *conn, 132569adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg DBusMessage *msg, uuid_t *search, gboolean reverse) 13263d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz{ 132718614bd2b008cb9f3879990883c569c37b72f195Alok Barsode struct btd_adapter *adapter = device->adapter; 13283d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz struct browse_req *req; 1329cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bdaddr_t src; 1330d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann uuid_t uuid; 1331da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz bt_callback_t cb; 1332a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz int err; 13332a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode 13341af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg if (device->discov_active) 13351af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg return -EBUSY; 13361af86fb9d1717a27b3a776fc0fb62c96045ccb9aJohan Hedberg 13372a8fb41c4c57b24a22f3adaab472b416faae122eAlok Barsode adapter_get_address(adapter, &src); 13383d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 13393d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req = g_new0(struct browse_req, 1); 1340438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 1341d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg if (conn == NULL) 1342d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg conn = get_dbus_connection(); 1343438ab01b43075b715345df0d85447aaf338fd4fcLuiz Augusto von Dentz 1344d2244495dfc50c22ce275f6194c19d3293de70cbJohan Hedberg req->conn = dbus_connection_ref(conn); 13453d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz req->device = device; 13463d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz 1347a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann if (search) { 1348040728e5019fce4eba5790939329fae0aa9104ffClaudio Takahasi memcpy(&uuid, search, sizeof(uuid_t)); 1349da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = search_cb; 1350a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } else { 13517d3301934f1b30d90646c97f40464ed198be91d3David Woodhouse sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); 135269adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg init_browse(req, reverse); 1353da8ef81cf060726782614baeea5b7e2c466b2341Luiz Augusto von Dentz cb = browse_cb; 1354a6f07d2bf12942854072c37c3c42d7447921beeeMarcel Holtmann } 1355d69e08eb0d567b61106ca37e0546402f4ae0c34eMarcel Holtmann 135695e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device->discov_active = 1; 1357d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg 1358d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg if (msg) { 13597c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg const char *sender = dbus_message_get_sender(msg); 13607c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg 13615c6426eff87049c9f8e49877f650772840907239Luiz Augusto von Dentz req->msg = dbus_message_ref(msg); 13627c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg device->discov_requestor = g_strdup(sender); 1363d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg /* Track the request owner to cancel it 1364d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg * automatically if the owner exits */ 1365d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg device->discov_listener = g_dbus_add_disconnect_watch(conn, 13667c9a25e3a7bfbc50d4e7e8c151d08c213076d960Johan Hedberg sender, 136795e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz discover_services_req_exit, 136895e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz device, NULL); 1369d0c0409d8ad37a042539706ff5382899acc81395Johan Hedberg } 137095e5960735be4066d43f77d91ebe78771cd76a43Luiz Augusto von Dentz 1371a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz err = bt_search_service(&src, &device->bdaddr, 1372a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz &uuid, cb, req, NULL); 1373a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz if (err < 0) 1374a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz browse_req_free(req); 1375a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz 1376a4145c63530b4c3575b7da5f117c0df352f939fcLuiz Augusto von Dentz return err; 13773d9966f38f1d6ca12c9e9e2eace5181ba04844b4Luiz Augusto von Dentz} 137824cce397c3479e95f3e525da9285234fbafd2984Marcel Holtmann 137918614bd2b008cb9f3879990883c569c37b72f195Alok Barsodestruct btd_adapter *device_get_adapter(struct btd_device *device) 1380dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode{ 1381dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode if (!device) 1382dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return NULL; 1383dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 1384dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode return device->adapter; 1385dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode} 1386dcf5298e8173e946e3ac2ef6150ad78d030b15d0Alok Barsode 138719ce4933f3dadf3b04a2a9bd84d66d750cc010c3Alok Barsodevoid device_get_address(struct btd_device *device, bdaddr_t *bdaddr) 1388aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode{ 1389cbf6ef965b0db117ec9b762aad9cff995fd3b0bfAlok Barsode bacpy(bdaddr, &device->bdaddr); 1390aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode} 1391aec749f0732638f182c4b50fb59d6c905a80d42dAlok Barsode 1392555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeconst gchar *device_get_path(struct btd_device *device) 139346fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode{ 139446fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode if (!device) 139546fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return NULL; 139646fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 139746fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode return device->path; 139846fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode} 139946fd7beaa5b27f74e64d77449247e5459d7a3084Alok Barsode 1400555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodestruct agent *device_get_agent(struct btd_device *device) 1401a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode{ 1402a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode if (!device) 1403a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return NULL; 1404a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1405a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode return device->agent; 1406a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode} 1407a2335a65bb61313b3e46be861c90ca8bdb786eb8Alok Barsode 1408555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_agent(struct btd_device *device, struct agent *agent) 1409d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode{ 1410d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode if (!device) 1411d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode return; 1412d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1413d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode device->agent = agent; 1414d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode} 1415d8b1e6017c0198bc996f9f9518037d69902b7830Alok Barsode 1416555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_busy(struct btd_device *device) 14179f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode{ 14189f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode return device->discov_active ? TRUE : FALSE; 14199f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode} 14209f94306bcd017a6acb152685c940ed6d027a98c7Alok Barsode 1421555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodegboolean device_is_temporary(struct btd_device *device) 1422f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode{ 1423f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode return device->temporary; 1424f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode} 1425f169545f05c25960c094c12f11a4ee452fb96ba8Alok Barsode 1426555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_temporary(struct btd_device *device, gboolean temporary) 1427595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode{ 1428595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode if (!device) 1429595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode return; 1430595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1431595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode device->temporary = temporary; 1432595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode} 1433595bd38a9fe105ef20d1b0527e04c7d28532d22dAlok Barsode 1434555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_cap(struct btd_device *device, uint8_t cap) 1435491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode{ 1436491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode if (!device) 1437491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode return; 1438491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1439491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode device->cap = cap; 1440491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode} 1441491190e5dde601e4876f24a922f1ba16ae4d2e6dAlok Barsode 1442f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberguint8_t device_get_cap(struct btd_device *device) 1443f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg{ 1444f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg return device->cap; 1445f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg} 1446f6646fcfe84b703d0657a0e827682702d64a4788Johan Hedberg 1447555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodevoid device_set_auth(struct btd_device *device, uint8_t auth) 144829227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode{ 144929227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode if (!device) 145029227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode return; 145129227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 145229227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode device->auth = auth; 145329227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode} 145429227ad09e8996699e1b1d7e1c90d45fc80cab65Alok Barsode 1455555fcc9b4bf67e923708af8de46aa91b7077f050Alok Barsodeuint8_t device_get_auth(struct btd_device *device) 14562203f153c53189ec1c30df99b717e035681196e6Alok Barsode{ 14572203f153c53189ec1c30df99b717e035681196e6Alok Barsode return device->auth; 14582203f153c53189ec1c30df99b717e035681196e6Alok Barsode} 1459c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 1460013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedbergstatic gboolean start_discovery(gpointer user_data) 1461013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 1462013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg struct btd_device *device = user_data; 1463013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 146469adac833c5633714b84bf840c75aa814193b8a6Johan Hedberg device_browse(device, NULL, NULL, NULL, TRUE); 1465013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1466013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg device->discov_timer = 0; 1467013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 1468013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg return FALSE; 1469013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 1470013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 14712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von DentzDBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) 1472013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg{ 14732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (status) { 14742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x00: /* success */ 14752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_method_return(msg); 14762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x04: /* page timeout */ 14782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x08: /* connection timeout */ 14792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x10: /* connection accept timeout */ 14802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x22: /* LMP response timeout */ 14812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x28: /* instant passed - is this a timeout? */ 14822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationTimeout", 14842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Timeout"); 14852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x17: /* too frequent pairing attempts */ 14862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".RepeatedAttempts", 14882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Repeated Attempts"); 14892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x06: 14912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */ 14922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 14932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationRejected", 14942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Rejected"); 14952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 14962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x07: /* memory capacity */ 14972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x09: /* connection limit */ 14982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0a: /* synchronous connection limit */ 14992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0d: /* limited resources */ 15002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x13: /* user ended the connection */ 15012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x14: /* terminated due to low resources */ 15022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 15032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationCanceled", 15042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Canceled"); 15052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x05: /* authentication failure */ 15072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x0E: /* rejected due to security reasons - is this auth failure? */ 15082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x25: /* encryption mode not acceptable - is this auth failure? */ 15092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x26: /* link key cannot be changed - is this auth failure? */ 15102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x29: /* pairing with unit key unsupported - is this auth failure? */ 15112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case 0x2f: /* insufficient security - is this auth failure? */ 15122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 15132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return dbus_message_new_error(msg, 15142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AuthenticationFailed", 15152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Authentication Failed"); 15162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1519fb6feead6323073b28fc8147aae5c211894d139dJohan Hedbergstatic void bonding_request_free(struct bonding_req *bonding, gboolean close) 15202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device; 15222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 15242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 15252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->listener_id) 15272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_remove_watch(bonding->conn, bonding->listener_id); 152868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 15292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->msg) 15302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_unref(bonding->msg); 15312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->conn) 15332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_connection_unref(bonding->conn); 15342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (bonding->io_id) 15362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_source_remove(bonding->io_id); 15372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1538fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg if (bonding->io) { 1539fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg if (close) 1540fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg g_io_channel_close(bonding->io); 15412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_unref(bonding->io); 1542fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg } 15432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device = bonding->device; 15452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device && device->agent) { 15472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent_destroy(device->agent, FALSE); 15482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->agent = NULL; 15492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = NULL; 15522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(bonding); 15532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_set_paired(struct btd_device *device, gboolean value) 15562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn = get_dbus_connection(); 155868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 1559c0736ea762bfea95e98c8b9f118b4e5464f2159cJohan Hedberg emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Paired", 15602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBUS_TYPE_BOOLEAN, &value); 15612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void device_agent_removed(struct agent *agent, void *user_data) 15642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 15662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_set_agent(device, NULL); 15682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 15702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr->agent = NULL; 15712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 15722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic struct bonding_req *bonding_request_new(DBusConnection *conn, 15742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 15752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device, 15762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 15772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 15782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 15792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 15802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *name = dbus_message_get_sender(msg); 15812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 15822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requesting bonding", device->path); 15842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent_path) 15862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto proceed; 15872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = agent_create(device->adapter, name, agent_path, 15892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability, 15902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_agent_removed, 15912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 15922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 15932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Unable to create a new agent"); 15942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 15952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 15962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->agent = agent; 15982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 15992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("Temporary agent registered for %s at %s:%s", 16002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->path, name, agent_path); 16012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzproceed: 16032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = g_new0(struct bonding_req, 1); 16042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->conn = dbus_connection_ref(conn); 16062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->msg = dbus_message_ref(msg); 16072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return bonding; 16092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 16102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond, 16122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device) 16132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 16142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct hci_request rq; 16152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth_requested_cp cp; 16162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz evt_cmd_status rp; 16172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct l2cap_conninfo cinfo; 16182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz socklen_t len; 16192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int sk, dd, ret; 16202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16215331a26b8a3c2d69d30a4334e023238db197080bJohan Hedberg if (!device->bonding) { 16222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(io); 16232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 16242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (cond & G_IO_NVAL) { 16272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) { 16282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply; 16292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz reply = new_authentication_return(device->bonding->msg, 16312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 0x09); 16322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(device->bonding->conn, reply); 16332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto cleanup; 16362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (cond & (G_IO_HUP | G_IO_ERR)) { 16392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("Hangup or error on bonding IO channel"); 16402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 16422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_connection_attempt_failed(device->bonding->conn, 16432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->msg, 16442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ENETDOWN); 16452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz sk = g_io_channel_unix_get_fd(io); 16502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz len = sizeof(ret); 16522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { 16532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Can't get socket error: %s (%d)", 16542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 16552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 16562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 16572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (ret != 0) { 16612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 16622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_connection_attempt_failed(device->bonding->conn, 16632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->msg, 16642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret); 16652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz len = sizeof(cinfo); 16692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) { 16702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Can't get connection info: %s (%d)", 16712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 16722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 16732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 16742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dd = hci_open_dev(adapter_get_dev_id(device->adapter)); 16782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (dd < 0) { 16792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply = no_such_adapter(device->bonding->msg); 16802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(device->bonding->conn, reply); 16812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 16822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 16832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&rp, 0, sizeof(rp)); 16852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&cp, 0, sizeof(cp)); 16872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz cp.handle = htobs(cinfo.hci_handle); 16882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz memset(&rq, 0, sizeof(rq)); 16902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.ogf = OGF_LINK_CTL; 16912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.ocf = OCF_AUTH_REQUESTED; 16922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.cparam = &cp; 16932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.clen = AUTH_REQUESTED_CP_SIZE; 16942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.rparam = &rp; 16952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.rlen = EVT_CMD_STATUS_SIZE; 16962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rq.event = EVT_CMD_STATUS; 16972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 16982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) { 16992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Unable to send HCI request: %s (%d)", 17002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz strerror(errno), errno); 17012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 17022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz errno); 17032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 17042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 17052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 17062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (rp.status) { 17082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("HCI_Authentication_Requested failed with status 0x%02x", 17092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz rp.status); 17102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error_failed_errno(device->bonding->conn, device->bonding->msg, 17112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bt_error(rp.status)); 17122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 17132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 17142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 17152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz hci_close_dev(dd); 17172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->io_id = g_io_add_watch(io, 17192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz G_IO_NVAL | G_IO_HUP | G_IO_ERR, 17202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz (GIOFunc) create_bonding_io_cb, 17212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 17222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 17242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzfailed: 17262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(io); 17272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzcleanup: 17292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->io_id = 0; 1730fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg bonding_request_free(device->bonding, FALSE); 17312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 17332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 17342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void create_bond_req_exit(DBusConnection *conn, void *user_data) 17362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 17372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = user_data; 17382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requestor exited before bonding was completed", device->path); 17402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 1742f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg device_cancel_authentication(device, FALSE); 17432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 17442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) { 17452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding->listener_id = 0; 17462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_io_channel_close(device->bonding->io); 1747fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg bonding_request_free(device->bonding, TRUE); 17482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 17492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 17502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1751f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedbergstatic int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst, 1752f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg gboolean *auth_required) 1753f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg{ 1754f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg struct sockaddr_l2 addr; 1755f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg long arg; 1756d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg int sk, err, opt; 1757f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1758f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); 1759f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (sk < 0) { 1760f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't create socket: %s (%d)", strerror(errno), errno); 1761f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1762f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1763f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1764f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg memset(&addr, 0, sizeof(addr)); 1765f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg addr.l2_family = AF_BLUETOOTH; 1766f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bacpy(&addr.l2_bdaddr, src); 1767f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1768f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1769f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't bind socket: %s (%d)", strerror(errno), errno); 1770f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1771f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1772f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 177397dd9b6963ee0f8517bf8e2633d28b6505f2f7baMarcel Holtmann opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE; 1774f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1775d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg err = setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)); 1776d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg if (err < 0) { 1777d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg error("setsockopt: %s (%d)", strerror(errno), errno); 1778d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg goto failed; 1779d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg } 1780f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1781f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg arg = fcntl(sk, F_GETFL); 1782f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (arg < 0) { 1783f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't get file flags: %s (%d)", strerror(errno), errno); 1784f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1785f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1786f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1787f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg arg |= O_NONBLOCK; 1788f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (fcntl(sk, F_SETFL, arg) < 0) { 1789f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't set file flags: %s (%d)", strerror(errno), errno); 1790f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1791f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1792f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1793f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg memset(&addr, 0, sizeof(addr)); 1794f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg addr.l2_family = AF_BLUETOOTH; 1795f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bacpy(&addr.l2_bdaddr, dst); 1796f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1797f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1798f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg if (errno == EAGAIN || errno == EINPROGRESS) 1799f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1800f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg error("Can't connect socket: %s (%d)", strerror(errno), errno); 1801f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg goto failed; 1802f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg } 1803f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1804d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg if (auth_required) 1805d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg *auth_required = TRUE; 1806d9b5a3fcb122277222b80ff40ac786d2c5ad4ab8Johan Hedberg 1807f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return sk; 1808f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 1809f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedbergfailed: 1810f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg close(sk); 1811f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg return -1; 1812f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg} 1813f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg 18142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von DentzDBusMessage *device_create_bonding(struct btd_device *device, 18152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusConnection *conn, 18162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *msg, 18172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz const char *agent_path, 18182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint8_t capability) 18192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 18202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char filename[PATH_MAX + 1]; 18212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz char *str, srcaddr[18], dstaddr[18]; 18222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_adapter *adapter = device->adapter; 18232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding; 18242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bdaddr_t src; 1825f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg int sk; 1826f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg gboolean auth_required; 18272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz adapter_get_address(adapter, &src); 18292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&src, srcaddr); 18302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ba2str(&device->bdaddr, dstaddr); 18312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->bonding) 18332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return in_progress(msg, "Bonding in progress"); 18342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* check if a link key already exists */ 18362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, 18372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "linkkeys"); 18382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz str = textfile_caseget(filename, dstaddr); 18402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (str) { 18412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz free(str); 18422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, 18432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".AlreadyExists", 18442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Bonding already exists"); 18452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 18462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1847dd10ec5d830d2e2187f93bd2d7e60be947335f0bJohan Hedberg 1848f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg sk = l2raw_connect(&src, &device->bdaddr, &auth_required); 18492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (sk < 0) 18502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_dbus_create_error(msg, 18512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ERROR_INTERFACE ".ConnectionAttemptFailed", 18522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz "Connection attempt failed"); 18532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding = bonding_request_new(conn, msg, device, agent_path, 18552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz capability); 18562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) { 18572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz close(sk); 18582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 18592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 18602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1861f8f494cb4880fa6a3f8b641bf6676acfce659753Johan Hedberg bonding->auth_required = auth_required; 1862dd10ec5d830d2e2187f93bd2d7e60be947335f0bJohan Hedberg 18632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->io = g_io_channel_unix_new(sk); 18642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->io_id = g_io_add_watch(bonding->io, 18652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR, 18662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz (GIOFunc) create_bonding_io_cb, 18672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 18682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->listener_id = g_dbus_add_disconnect_watch(conn, 18702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_message_get_sender(msg), 18712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz create_bond_req_exit, device, 18722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL); 18732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->bonding = bonding; 18752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz bonding->device = device; 18762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return NULL; 18782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 18792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1880e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedbergvoid device_simple_pairing_complete(struct btd_device *device, uint8_t status) 1881e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg{ 1882e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg struct authentication_req *auth = device->authr; 1883e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 1884e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent) 1885e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg agent_cancel(auth->agent); 1886e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg} 1887e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 18882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_bonding_complete(struct btd_device *device, uint8_t status) 18892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 18902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 1891e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg struct authentication_req *auth = device->authr; 1892e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg 1893e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent) 1894e35dd0c0246236371269b79cc28b1a23f4999560Johan Hedberg agent_cancel(auth->agent); 18952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 18962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (status) 18972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz goto failed; 18982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1899f8c2a96432a78aab515e7b4f3cd044f53946d908Marcel Holtmann device->auth = 0xff; 19002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->temporary = FALSE; 190168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg 1902bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg g_free(device->authr); 1903bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg device->authr = NULL; 1904bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 1905bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg if (device->renewed_key) 1906bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg return; 1907bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 190868b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg /* If we were initiators start service discovery immediately. 190968b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * However if the other end was the initator wait a few seconds 191068b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * before SDP. This is due to potential IOP issues if the other 191168b27e68b50b1e68d663142d2b0432c435329ea6Johan Hedberg * end starts doing SDP at the same time as us */ 1912e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (bonding) { 1913e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg /* If we are initiators remove any discovery timer and just 1914e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg * start discovering services directly */ 1915e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg if (device->discov_timer) { 1916e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg g_source_remove(device->discov_timer); 1917e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg device->discov_timer = 0; 1918e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1919e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 19202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_browse(device, bonding->conn, bonding->msg, 19212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz NULL, FALSE); 1922bdf140bd02cee6c39ebb8c6d71ac1d4f6f7eaa07Johan Hedberg } else if (!device->discov_active && !device->discov_timer && 1923bdf140bd02cee6c39ebb8c6d71ac1d4f6f7eaa07Johan Hedberg main_opts.reverse_sdp) { 19242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* If we are not initiators and there is no currently active 19252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz * discovery or discovery timer, set the discovery timer */ 19265fe418c129889a18df976050c68a0dab28dc766cMarcel Holtmann debug("setting timer for reverse service discovery"); 19272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->discov_timer = g_timeout_add_seconds(DISCOVERY_TIMER, 19282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz start_discovery, 19292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device); 1930e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg } 1931e4d0a3b9051923b015ce633f9385e5af126211feJohan Hedberg 19322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_set_paired(device, TRUE); 19332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1934fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg bonding_request_free(bonding, TRUE); 19352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzfailed: 19392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device_cancel_bonding(device, status); 19402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_bonding(struct btd_device *device, const char *sender) 19432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 19452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!device->bonding) 19472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return FALSE; 19482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!sender) 19502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return TRUE; 19512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return g_str_equal(sender, dbus_message_get_sender(bonding->msg)); 19532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 1954e21ec2652c54dbc8abbf84039b43fbd3be0b5ebcJohan Hedberg 19552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzvoid device_cancel_bonding(struct btd_device *device, uint8_t status) 19562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct bonding_req *bonding = device->bonding; 19582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusMessage *reply; 19592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!bonding) 19612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: canceling bonding request", device->path); 19642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (device->authr) 1966f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg device_cancel_authentication(device, FALSE); 19672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz reply = new_authentication_return(bonding->msg, status); 19692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_dbus_send_message(bonding->conn, reply); 19702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 1971fb6feead6323073b28fc8147aae5c211894d139dJohan Hedberg bonding_request_free(bonding, TRUE); 19722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void pincode_cb(struct agent *agent, DBusError *err, const char *pincode, 19752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *data) 19762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 19782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 19792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 19812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 19822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, err, pincode, device); 19852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 19872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 19882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void confirm_cb(struct agent *agent, DBusError *err, void *data) 19902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 19912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 19922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 19932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 19952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 19962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 19972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 19982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, err, device); 19992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 20012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey, 20042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz void *data) 20052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = data; 20072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 20082aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* No need to reply anything if the authentication already failed */ 20102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 20112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 20122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, err, passkey, device); 20142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 20162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzint device_request_authentication(struct btd_device *device, auth_type_t type, 20192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz uint32_t passkey, void *cb) 20202aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20212aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth; 20222aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent; 20232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz int ret; 20242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: requesting agent authentication", device->path); 20262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = device->agent; 20282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) 20302aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent = adapter_get_agent(device->adapter); 20312aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20322aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!agent) { 20332aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("No agent available for %u request", type); 20342aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return -EPERM; 20352aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20362aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20372aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth = g_new0(struct authentication_req, 1); 20382aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->agent = agent; 20392aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->device = device; 20402aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = cb; 20412aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->type = type; 20422aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = auth; 20432aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20442aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (type) { 20452aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 20462aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_pincode(agent, device, pincode_cb, 20472aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth); 20482aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20492aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 20502aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_passkey(agent, device, passkey_cb, 20512aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth); 20522aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20532aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 20542aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_request_confirmation(agent, device, passkey, 20552aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz confirm_cb, auth); 20562aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20572aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 20582aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = agent_display_passkey(agent, device, passkey); 20592aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20602aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_AUTO: 20612aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = 0; 20622aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20632aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz default: 20642aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ret = -EINVAL; 20652aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20662aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20672aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (ret < 0) { 20682aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz error("Failed requesting authentication"); 20692aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(auth); 20702aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = NULL; 20712aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 20722aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20732aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return ret; 20742aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 20752aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20762aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzstatic void cancel_authentication(struct authentication_req *auth) 20772aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 20782aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct btd_device *device = auth->device; 20792aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct agent *agent = auth->agent; 20802aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz DBusError err; 20812aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20822aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth->cb) 20832aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 20842aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20852aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_init(&err); 20862aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_set_error_const(&err, "org.bluez.Error.Canceled", NULL); 20872aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 20882aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz switch (auth->type) { 20892aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PINCODE: 20902aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_pincode_cb) auth->cb)(agent, &err, NULL, device); 20912aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20922aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_CONFIRM: 20932aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_cb) auth->cb)(agent, &err, device); 20942aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20952aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_PASSKEY: 20962aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz ((agent_passkey_cb) auth->cb)(agent, &err, 0, device); 20972aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 20982aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_NOTIFY: 20992aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz case AUTH_TYPE_AUTO: 21002aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz /* User Notify/Auto doesn't require any reply */ 21012aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz break; 21022aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz } 21032aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21042aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz dbus_error_free(&err); 21052aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz auth->cb = NULL; 21062aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 21072aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2108f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedbergvoid device_cancel_authentication(struct btd_device *device, gboolean aborted) 21092aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 21102aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz struct authentication_req *auth = device->authr; 21112aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21122aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (!auth) 21132aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return; 21142aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21152aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz debug("%s: canceling authentication request", device->path); 21162aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21172aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz if (auth->agent) 21182aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz agent_cancel(auth->agent); 21192aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 2120f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg if (!aborted) 2121f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg cancel_authentication(auth); 2122f7d1ee361e410e096929bd3918178af356c50bbdJohan Hedberg 21232aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz device->authr = NULL; 21242aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz g_free(auth); 21252aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz} 21262aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz 21272aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentzgboolean device_is_authenticating(struct btd_device *device) 21282aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz{ 21292aad1cf41acbc69481915d24cef33fa721d4e1fdLuiz Augusto von Dentz return (device->authr != NULL); 2130013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg} 2131013d376e47dc68ec385e9f88d6bc6c07c921ee1aJohan Hedberg 2132bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedbergvoid device_set_renewed_key(struct btd_device *device, gboolean renewed) 2133bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg{ 2134bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg device->renewed_key = renewed; 2135bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg} 2136bcb6af7fc78234948ba1c997825c8859464b170bJohan Hedberg 213717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedbergvoid btd_device_add_uuid(struct btd_device *device, const char *uuid) 213817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg{ 213917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg GSList *uuid_list; 214017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg char *new_uuid; 214117541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 214217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg if (g_slist_find_custom(device->uuids, uuid, 214317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg (GCompareFunc) strcasecmp)) 214417541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg return; 214517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 214617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg new_uuid = g_strdup(uuid); 214717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg uuid_list = g_slist_append(NULL, new_uuid); 214817541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 214917541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg device_probe_drivers(device, uuid_list); 215017541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 21510e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg g_free(new_uuid); 215217541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg g_slist_free(uuid_list); 215317541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 21540e073403c77dd0906cd89dbd2d2b6707f4493188Johan Hedberg store_profiles(device); 215517541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg services_changed(device); 215617541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg} 215717541956196b13ee083852fd4124cd8cfd0928a4Johan Hedberg 2158548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedbergconst sdp_record_t *btd_device_get_record(struct btd_device *device, 2159548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg const char *uuid) 2160548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg{ 2161548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg bdaddr_t src; 2162548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2163548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (device->tmp_records) 2164548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 2165548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2166548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg adapter_get_address(device->adapter, &src); 2167548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2168548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg device->tmp_records = read_records(&src, &device->bdaddr); 2169548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg if (!device->tmp_records) 2170548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return NULL; 2171548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2172548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg return find_record_in_list(device->tmp_records, uuid); 2173548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg} 2174548026e08bd9b83b3685d515a916e2cf674184f3Johan Hedberg 2175c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzint btd_register_device_driver(struct btd_device_driver *driver) 2176c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2177c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_append(device_drivers, driver); 2178c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2179c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz return 0; 2180c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 2181c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz 2182c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentzvoid btd_unregister_device_driver(struct btd_device_driver *driver) 2183c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz{ 2184c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz device_drivers = g_slist_remove(device_drivers, driver); 2185c560d02ccf1dd156f068b1da8a3e7d75d2319dfdLuiz Augusto von Dentz} 2186