Fix build break for rpm
[framework/connectivity/bluez.git] / input / manager.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <errno.h>
29
30 #include <bluetooth/bluetooth.h>
31 #include <bluetooth/hci.h>
32 #include <bluetooth/sdp.h>
33 #include <bluetooth/sdp_lib.h>
34 #include <bluetooth/uuid.h>
35
36 #include <gdbus.h>
37
38 #include "log.h"
39 #include "../src/adapter.h"
40 #include "../src/device.h"
41
42 #include "device.h"
43 #include "server.h"
44 #include "manager.h"
45
46 static int idle_timeout = 0;
47
48 static DBusConnection *connection = NULL;
49 static GSList *adapters = NULL;
50
51 static void input_remove(struct btd_device *device, const char *uuid)
52 {
53         const gchar *path = device_get_path(device);
54
55         DBG("path %s", path);
56
57         input_device_unregister(path, uuid);
58 }
59
60 static int hid_device_probe(struct btd_device *device, GSList *uuids)
61 {
62         const gchar *path = device_get_path(device);
63         const sdp_record_t *rec = btd_device_get_record(device, uuids->data);
64
65         DBG("path %s", path);
66
67         if (!rec)
68                 return -1;
69
70         return input_device_register(connection, device, path, HID_UUID, rec,
71                                                         idle_timeout * 60);
72 }
73
74 static void hid_device_remove(struct btd_device *device)
75 {
76         input_remove(device, HID_UUID);
77 }
78
79 static int headset_probe(struct btd_device *device, GSList *uuids)
80 {
81         const gchar *path = device_get_path(device);
82         const sdp_record_t *record;
83         sdp_list_t *protos;
84         int ch;
85
86         DBG("path %s", path);
87
88         if (!g_slist_find_custom(uuids, HSP_HS_UUID,
89                                         (GCompareFunc) strcasecmp))
90                 return -EINVAL;
91
92         record = btd_device_get_record(device, uuids->data);
93
94         if (!record || sdp_get_access_protos(record, &protos) < 0) {
95                 error("Invalid record");
96                 return -EINVAL;
97         }
98
99         ch = sdp_get_proto_port(protos, RFCOMM_UUID);
100         sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
101         sdp_list_free(protos, NULL);
102
103         if (ch <= 0) {
104                 error("Invalid RFCOMM channel");
105                 return -EINVAL;
106         }
107
108         return fake_input_register(connection, device, path, HSP_HS_UUID, ch);
109 }
110
111 static void headset_remove(struct btd_device *device)
112 {
113         input_remove(device, HSP_HS_UUID);
114 }
115
116 static int hid_server_probe(struct btd_adapter *adapter)
117 {
118         bdaddr_t src;
119         int ret;
120
121         adapter_get_address(adapter, &src);
122
123         ret = server_start(&src);
124         if (ret < 0)
125                 return ret;
126
127         adapters = g_slist_append(adapters, btd_adapter_ref(adapter));
128
129         return 0;
130 }
131
132 static void hid_server_remove(struct btd_adapter *adapter)
133 {
134         bdaddr_t src;
135
136         adapter_get_address(adapter, &src);
137
138         server_stop(&src);
139
140         adapters = g_slist_remove(adapters, adapter);
141         btd_adapter_unref(adapter);
142 }
143
144 static struct btd_device_driver input_hid_driver = {
145         .name   = "input-hid",
146         .uuids  = BTD_UUIDS(HID_UUID),
147         .probe  = hid_device_probe,
148         .remove = hid_device_remove,
149 };
150
151 static struct btd_device_driver input_headset_driver = {
152         .name   = "input-headset",
153         .uuids  = BTD_UUIDS(HSP_HS_UUID),
154         .probe  = headset_probe,
155         .remove = headset_remove,
156 };
157
158 static struct btd_adapter_driver input_server_driver = {
159         .name   = "input-server",
160         .probe  = hid_server_probe,
161         .remove = hid_server_remove,
162 };
163
164 int input_manager_init(DBusConnection *conn, GKeyFile *config)
165 {
166         GError *err = NULL;
167
168         if (config) {
169                 idle_timeout = g_key_file_get_integer(config, "General",
170                                                 "IdleTimeout", &err);
171                 if (err) {
172                         DBG("input.conf: %s", err->message);
173                         g_error_free(err);
174                 }
175         }
176
177         connection = dbus_connection_ref(conn);
178
179         btd_register_adapter_driver(&input_server_driver);
180
181         btd_register_device_driver(&input_hid_driver);
182         btd_register_device_driver(&input_headset_driver);
183
184         return 0;
185 }
186
187 void input_manager_exit(void)
188 {
189         btd_unregister_device_driver(&input_hid_driver);
190         btd_unregister_device_driver(&input_headset_driver);
191
192         btd_unregister_adapter_driver(&input_server_driver);
193
194         dbus_connection_unref(connection);
195
196         connection = NULL;
197 }