3 * neard - Near Field Communication manager
5 * Copyright (C) 2012 Intel Corporation. All rights reserved.
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.
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.
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
37 static DBusConnection *connection = NULL;
38 static GHashTable *ndef_app_hash;
40 struct near_ndef_agent {
47 static void ndef_agent_free(gpointer data)
50 struct near_ndef_agent *agent = data;
57 DBG("%s %s %s", agent->sender, agent->path, NFC_NDEF_AGENT_INTERFACE);
59 message = dbus_message_new_method_call(agent->sender, agent->path,
60 NFC_NDEF_AGENT_INTERFACE, "Release");
64 dbus_message_set_no_reply(message, TRUE);
66 g_dbus_send_message(connection, message);
68 g_dbus_remove_watch(connection, agent->watch);
70 g_free(agent->sender);
74 static void ndef_agent_disconnect(DBusConnection *conn, void *user_data)
76 struct near_ndef_agent *agent = user_data;
78 DBG("agent %s disconnected", agent->path);
80 g_hash_table_remove(ndef_app_hash, agent->record_type);
83 static void append_record_path(DBusMessageIter *iter, void *user_data)
85 GList *records = user_data, *list;
86 struct near_ndef_record *record;
89 for (list = records; list; list = list->next) {
92 path = __near_ndef_record_get_path(record);
96 dbus_message_iter_append_basic(iter,
97 DBUS_TYPE_STRING, &path);
101 static void append_ndef(DBusMessageIter *iter, void *user_data)
103 GList *records = user_data;
105 __near_ndef_append_records(iter, records);
108 static void ndef_agent_push_records(struct near_ndef_agent *agent,
111 DBusMessageIter iter, dict;
112 DBusMessage *message;
116 if (agent->sender == NULL || agent->path == NULL)
119 DBG("Sending NDEF to %s %s", agent->path, agent->sender);
121 message = dbus_message_new_method_call(agent->sender, agent->path,
122 NFC_NDEF_AGENT_INTERFACE,
127 dbus_message_iter_init_append(message, &iter);
129 near_dbus_dict_open(&iter, &dict);
130 near_dbus_dict_append_array(&dict, "Records",
131 DBUS_TYPE_STRING, append_record_path, records);
132 near_dbus_dict_append_array(&dict, "NDEF",
133 DBUS_TYPE_BYTE, append_ndef, records);
134 near_dbus_dict_close(&iter, &dict);
138 dbus_message_set_no_reply(message, TRUE);
140 g_dbus_send_message(connection, message);
143 void __near_agent_ndef_parse_records(GList *records)
146 struct near_ndef_record *record;
147 struct near_ndef_agent *agent;
152 for (list = records, agent = NULL; list; list = list->next) {
154 type = __near_ndef_record_get_type(record);
159 DBG("Looking for type %s", type);
161 agent = g_hash_table_lookup(ndef_app_hash, type);
169 ndef_agent_push_records(agent, records);
174 int __near_agent_ndef_register(const char *sender, const char *path,
175 const char *record_type)
177 struct near_ndef_agent *agent;
179 DBG("%s registers path %s for %s", sender, path, record_type);
181 if (g_hash_table_lookup(ndef_app_hash, record_type) != NULL)
184 agent = g_try_malloc0(sizeof(struct near_ndef_agent));
188 agent->sender = g_strdup(sender);
189 agent->path = g_strdup(path);
190 agent->record_type = g_strdup(record_type);
192 if (agent->sender == NULL || agent->path == NULL ||
193 agent->record_type == NULL) {
198 agent->watch = g_dbus_add_disconnect_watch(connection, sender,
199 ndef_agent_disconnect, agent, NULL);
200 g_hash_table_insert(ndef_app_hash, agent->record_type, agent);
205 int __near_agent_ndef_unregister(const char *sender, const char *path,
206 const char *record_type)
208 struct near_ndef_agent *agent;
210 DBG("sender %s path %s type %s", sender, path, record_type);
212 agent = g_hash_table_lookup(ndef_app_hash, record_type);
216 if (strcmp(agent->path, path) != 0 || strcmp(agent->sender, sender) != 0)
219 g_hash_table_remove(ndef_app_hash, record_type);
224 static guint handover_agent_watch = 0;
225 static gchar *handover_agent_path = NULL;
226 static gchar *handover_agent_sender = NULL;
228 static void handover_agent_free(void)
230 if (handover_agent_watch > 0) {
231 g_dbus_remove_watch(connection, handover_agent_watch);
232 handover_agent_watch = 0;
235 g_free(handover_agent_sender);
236 handover_agent_sender = NULL;
238 g_free(handover_agent_path);
239 handover_agent_path = NULL;
242 static void handover_agent_disconnect(DBusConnection *conn, void *data)
244 DBG("data %p", data);
246 handover_agent_watch = 0;
248 handover_agent_free();
251 static void handover_agent_release(void)
253 DBusMessage *message;
255 if (handover_agent_watch == 0)
258 message = dbus_message_new_method_call(handover_agent_sender,
260 "org.neard.HandoverAgent",
263 g_dbus_send_message(connection, message);
265 handover_agent_free();
268 int __near_agent_handover_register(const char *sender, const char *path)
270 DBG("sender %s path %s", sender, path);
272 if (handover_agent_path != NULL)
275 handover_agent_watch = g_dbus_add_disconnect_watch(connection, sender,
276 handover_agent_disconnect, NULL, NULL);
277 if (handover_agent_watch == 0)
280 handover_agent_sender = g_strdup(sender);
281 handover_agent_path = g_strdup(path);
286 int __near_agent_handover_unregister(const char *sender, const char *path)
288 DBG("sender %s path %s", sender, path);
290 if (handover_agent_path == NULL)
293 handover_agent_free();
298 int __near_agent_init(void)
302 connection = near_dbus_get_connection();
303 if (connection == NULL)
306 ndef_app_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
307 g_free, ndef_agent_free);
312 void __near_agent_cleanup(void)
316 g_hash_table_destroy(ndef_app_hash);
317 ndef_app_hash = NULL;
319 handover_agent_release();
321 dbus_connection_unref(connection);