Add requirement of python-xml for test subpackage
[profile/ivi/neard.git] / src / manager.c
1 /*
2  *
3  *  neard - Near Field Communication manager
4  *
5  *  Copyright (C) 2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29
30 #include <glib.h>
31
32 #include <gdbus.h>
33
34 #include "near.h"
35
36 static DBusConnection *connection;
37
38 static DBusMessage *get_properties(DBusConnection *conn,
39                                         DBusMessage *msg, void *data)
40 {
41         DBusMessage *reply;
42         DBusMessageIter array, dict;
43
44         DBG("conn %p", conn);
45
46         reply = dbus_message_new_method_return(msg);
47         if (reply == NULL)
48                 return NULL;
49
50         dbus_message_iter_init_append(reply, &array);
51
52         near_dbus_dict_open(&array, &dict);
53
54         near_dbus_dict_append_array(&dict, "Adapters",
55                         DBUS_TYPE_OBJECT_PATH, __near_adapter_list, NULL);
56
57         near_dbus_dict_close(&array, &dict);
58
59         return reply;
60 }
61
62 static DBusMessage *set_property(DBusConnection *conn,
63                                         DBusMessage *msg, void *data)
64 {
65         DBG("conn %p", conn);
66
67         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
68 }
69
70 int __near_manager_adapter_add(uint32_t idx, const char *name,
71                                 uint32_t protocols, near_bool_t powered)
72 {
73         struct near_adapter *adapter;
74         const char *path;
75         int err;
76
77         DBG("idx %d", idx);
78
79         adapter = __near_adapter_create(idx, name, protocols, powered);
80         if (adapter == NULL)
81                 return -ENOMEM;
82
83         path = __near_adapter_get_path(adapter);
84         if (path == NULL) {
85                 __near_adapter_destroy(adapter);
86                 return -EINVAL;
87         }
88
89         err = __near_adapter_add(adapter);
90         if (err < 0) {
91                 __near_adapter_destroy(adapter);
92         } else {
93                 near_dbus_property_changed_array(NFC_MANAGER_PATH,
94                                 NFC_MANAGER_INTERFACE, "Adapters",
95                                 DBUS_TYPE_OBJECT_PATH, __near_adapter_list,
96                                 NULL);
97
98                 g_dbus_emit_signal(connection, "/",
99                         NFC_MANAGER_INTERFACE, "AdapterAdded",
100                         DBUS_TYPE_OBJECT_PATH, &path,
101                         DBUS_TYPE_INVALID);
102         }
103
104         return err;
105 }
106
107 void __near_manager_adapter_remove(uint32_t idx)
108 {
109         struct near_adapter *adapter;
110         const char *path;
111
112         DBG("idx %d", idx);
113
114         adapter = __near_adapter_get(idx);
115         if (adapter == NULL)
116                 return;
117
118         path = __near_adapter_get_path(adapter);
119         if (path == NULL)
120                 return;
121
122
123         g_dbus_emit_signal(connection, "/",
124                         NFC_MANAGER_INTERFACE, "AdapterRemoved",
125                         DBUS_TYPE_OBJECT_PATH, &path,
126                         DBUS_TYPE_INVALID);
127
128         __near_adapter_remove(adapter);
129
130         near_dbus_property_changed_array(NFC_MANAGER_PATH,
131                                 NFC_MANAGER_INTERFACE, "Adapters",
132                                 DBUS_TYPE_OBJECT_PATH, __near_adapter_list,
133                                 NULL);
134 }
135
136 static DBusMessage *register_handover_agent(DBusConnection *conn,
137                                         DBusMessage *msg, void *data)
138 {
139         const char *sender, *path;
140         int err;
141
142         DBG("conn %p", conn);
143
144         sender = dbus_message_get_sender(msg);
145
146         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
147                                                         DBUS_TYPE_INVALID);
148
149         err = __near_agent_handover_register(sender, path);
150         if (err < 0)
151                 return __near_error_failed(msg, -err);
152
153         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
154 }
155
156 static DBusMessage *unregister_handover_agent(DBusConnection *conn,
157                                         DBusMessage *msg, void *data)
158 {
159         const char *sender, *path;
160         int err;
161
162         DBG("conn %p", conn);
163
164         sender = dbus_message_get_sender(msg);
165
166         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
167                                                         DBUS_TYPE_INVALID);
168
169         err = __near_agent_handover_unregister(sender, path);
170         if (err < 0)
171                 return __near_error_failed(msg, -err);
172
173         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
174 }
175
176 static DBusMessage *register_ndef_agent(DBusConnection *conn,
177                                         DBusMessage *msg, void *data)
178 {
179         DBusMessageIter iter;
180         const char *sender, *path, *type;
181         int err;
182
183         DBG("conn %p", conn);
184
185         sender = dbus_message_get_sender(msg);
186
187         if (dbus_message_iter_init(msg, &iter) == FALSE)
188                 return __near_error_invalid_arguments(msg);
189
190         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
191                 return __near_error_invalid_arguments(msg);
192
193         dbus_message_iter_get_basic(&iter, &path);
194         dbus_message_iter_next(&iter);
195
196         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
197                 return __near_error_invalid_arguments(msg);
198
199         dbus_message_iter_get_basic(&iter, &type);
200
201         err = __near_agent_ndef_register(sender, path, type);
202         if (err < 0)
203                 return __near_error_failed(msg, -err);
204
205         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
206 }
207
208 static DBusMessage *unregister_ndef_agent(DBusConnection *conn,
209                                         DBusMessage *msg, void *data)
210 {
211         DBusMessageIter iter;
212         const char *sender, *path, *type;
213         int err;
214
215         DBG("conn %p", conn);
216
217         sender = dbus_message_get_sender(msg);
218
219         if (dbus_message_iter_init(msg, &iter) == FALSE)
220                 return __near_error_invalid_arguments(msg);
221
222         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
223                 return __near_error_invalid_arguments(msg);
224
225         dbus_message_iter_get_basic(&iter, &path);
226         dbus_message_iter_next(&iter);
227
228         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
229                 return __near_error_invalid_arguments(msg);
230
231         dbus_message_iter_get_basic(&iter, &type);
232
233         err = __near_agent_ndef_unregister(sender, path, type);
234         if (err < 0)
235                 return __near_error_failed(msg, -err);
236
237         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
238 }
239
240 static const GDBusMethodTable manager_methods[] = {
241         { GDBUS_METHOD("GetProperties",
242                                 NULL, GDBUS_ARGS({"properties", "a{sv}"}),
243                                 get_properties) },
244         { GDBUS_METHOD("SetProperty",
245                                 GDBUS_ARGS({"name", "s"}, {"value", "v"}),
246                                 NULL, set_property) },
247         { GDBUS_METHOD("RegisterHandoverAgent",
248                         GDBUS_ARGS({ "path", "o" }), NULL,
249                         register_handover_agent) },
250         { GDBUS_METHOD("UnregisterHandoverAgent",
251                         GDBUS_ARGS({ "path", "o" }), NULL,
252                         unregister_handover_agent) },
253         { GDBUS_METHOD("RegisterNDEFAgent",
254                         GDBUS_ARGS({"path", "o"}, {"type", "s"}),
255                         NULL, register_ndef_agent) },
256         { GDBUS_METHOD("UnregisterNDEFAgent",
257                         GDBUS_ARGS({"path", "o"}, {"type", "s"}),
258                         NULL, unregister_ndef_agent) },
259         { },
260 };
261
262 static const GDBusSignalTable manager_signals[] = {
263         { GDBUS_SIGNAL("PropertyChanged",
264                                 GDBUS_ARGS({"name", "s"}, {"value", "v"})) },
265         { GDBUS_SIGNAL("AdapterAdded", GDBUS_ARGS({"adapter", "o" })) },
266         { GDBUS_SIGNAL("AdapterRemoved", GDBUS_ARGS({"adapter", "o" })) },
267         { }
268 };
269
270 int __near_manager_init(DBusConnection *conn)
271 {
272         DBG("");
273
274         connection = dbus_connection_ref(conn);
275
276         DBG("connection %p", connection);
277
278         g_dbus_register_interface(connection, NFC_MANAGER_PATH,
279                                                 NFC_MANAGER_INTERFACE,
280                                                 manager_methods,
281                                                 manager_signals, NULL, NULL, NULL);
282
283         return __near_netlink_get_adapters();
284 }
285
286 void __near_manager_cleanup(void)
287 {
288         DBG("");
289
290         g_dbus_unregister_interface(connection, NFC_MANAGER_PATH,
291                                                 NFC_MANAGER_INTERFACE);
292
293         dbus_connection_unref(connection);
294 }