3 * neard - Near Field Communication manager
5 * Copyright (C) 2011 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
43 uint8_t nfcid[NFC_MAX_NFCID1_LEN];
52 DBusMessage *push_msg; /* Push pending message */
55 static DBusConnection *connection = NULL;
57 static GHashTable *device_hash;
59 static GSList *driver_list = NULL;
61 static void free_device(gpointer data)
63 struct near_device *device = data;
65 DBG("device %p", device);
67 near_ndef_records_free(device->records);
69 g_dbus_unregister_interface(connection, device->path,
70 NFC_DEVICE_INTERFACE);
77 struct near_device *near_device_get_device(uint32_t adapter_idx,
80 struct near_device *device;
85 path = g_strdup_printf("%s/nfc%d/device%d", NFC_PATH,
86 adapter_idx, target_idx);
90 device = g_hash_table_lookup(device_hash, path);
97 const char *__near_device_get_path(struct near_device *device)
102 uint32_t __neard_device_get_idx(struct near_device *device)
104 return device->target_idx;
107 static void push_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
109 struct near_device *device;
110 DBusConnection *conn;
113 DBG("Push status %d", status);
115 conn = near_dbus_get_connection();
116 device = near_device_get_device(adapter_idx, target_idx);
118 if (!conn || !device)
122 reply = __near_error_failed(device->push_msg, -status);
124 g_dbus_send_message(conn, reply);
126 g_dbus_send_reply(conn, device->push_msg, DBUS_TYPE_INVALID);
129 dbus_message_unref(device->push_msg);
130 device->push_msg = NULL;
133 static char *sn_from_message(DBusMessage *msg)
135 DBusMessageIter iter;
136 DBusMessageIter arr_iter;
140 dbus_message_iter_init(msg, &iter);
141 dbus_message_iter_recurse(&iter, &arr_iter);
143 while (dbus_message_iter_get_arg_type(&arr_iter) !=
145 const char *key, *value;
146 DBusMessageIter ent_iter;
147 DBusMessageIter var_iter;
149 dbus_message_iter_recurse(&arr_iter, &ent_iter);
150 dbus_message_iter_get_basic(&ent_iter, &key);
152 if (g_strcmp0(key, "Type") != 0) {
153 dbus_message_iter_next(&arr_iter);
157 dbus_message_iter_next(&ent_iter);
158 dbus_message_iter_recurse(&ent_iter, &var_iter);
160 switch (dbus_message_iter_get_arg_type(&var_iter)) {
161 case DBUS_TYPE_STRING:
162 dbus_message_iter_get_basic(&var_iter, &value);
164 if (g_strcmp0(value, "Text") == 0)
165 return NEAR_DEVICE_SN_SNEP;
166 else if (g_strcmp0(value, "URI") == 0)
167 return NEAR_DEVICE_SN_SNEP;
168 else if (g_strcmp0(value, "SmartPoster") == 0)
169 return NEAR_DEVICE_SN_SNEP;
170 else if (g_strcmp0(value, "Handover") == 0)
171 return NEAR_DEVICE_SN_HANDOVER;
172 else if (g_strcmp0(value, "StaticHandover") == 0)
173 return NEAR_DEVICE_SN_HANDOVER;
174 else if (g_strcmp0(value, "MIME") == 0)
175 return NEAR_DEVICE_SN_SNEP;
176 else if (g_strcmp0(value, "Raw") == 0)
177 return NEAR_DEVICE_SN_SNEP;
184 dbus_message_iter_next(&arr_iter);
190 static DBusMessage *push_ndef(DBusConnection *conn,
191 DBusMessage *msg, void *data)
193 struct near_device *device = data;
194 struct near_ndef_message *ndef;
198 DBG("conn %p", conn);
200 if (device->push_msg)
201 return __near_error_in_progress(msg);
203 device->push_msg = dbus_message_ref(msg);
205 service_name = sn_from_message(msg);
211 ndef = __ndef_build_from_message(msg);
217 err = __near_device_push(device, ndef, service_name, push_cb);
224 dbus_message_unref(device->push_msg);
225 device->push_msg = NULL;
227 return __near_error_failed(msg, -err);
230 static gboolean property_get_adapter(const GDBusPropertyTable *property,
231 DBusMessageIter *iter, void *user_data)
233 struct near_device *device = user_data;
234 struct near_adapter *adapter;
237 adapter = __near_adapter_get(device->adapter_idx);
241 path = __near_adapter_get_path(adapter);
245 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
251 static DBusMessage *dump_raw_ndef(DBusConnection *conn,
252 DBusMessage *msg, void *data)
254 struct near_device *device = data;
256 DBusMessageIter iter, array;
260 reply = dbus_message_new_method_return(msg);
264 dbus_message_iter_init_append(reply, &iter);
266 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
267 DBUS_TYPE_BYTE_AS_STRING,
270 __near_ndef_append_records(&array, device->records);
272 dbus_message_iter_close_container(&iter, &array);
277 static const GDBusMethodTable device_methods[] = {
278 { GDBUS_ASYNC_METHOD("Push", GDBUS_ARGS({"attributes", "a{sv}"}),
280 { GDBUS_METHOD("DumpRawNDEF",
281 NULL, GDBUS_ARGS({"NDEF", "ay"}),
286 static const GDBusPropertyTable device_properties[] = {
287 { "Adapter", "o", property_get_adapter },
292 void __near_device_remove(struct near_device *device)
294 char *path = device->path;
296 DBG("path %s", device->path);
298 if (device->push_msg)
299 push_cb(device->adapter_idx, device->target_idx, EIO);
301 g_hash_table_remove(device_hash, path);
304 int near_device_add_data(uint32_t adapter_idx, uint32_t target_idx,
305 uint8_t *data, size_t data_length)
307 struct near_device *device;
309 device = near_device_get_device(adapter_idx, target_idx);
313 device->data_length = data_length;
314 device->data = g_try_malloc0(data_length);
319 memcpy(device->data, data, data_length);
324 int near_device_add_records(struct near_device *device, GList *records,
325 near_device_io_cb cb, int status)
328 struct near_ndef_record *record;
331 DBG("records %p", records);
333 near_ndef_records_free(device->records);
334 device->records = NULL;
336 for (list = records; list; list = list->next) {
339 path = g_strdup_printf("%s/nfc%d/device%d/record%d",
340 NFC_PATH, device->adapter_idx,
341 device->target_idx, device->n_records);
346 __near_ndef_record_register(record, path);
349 device->records = g_list_append(device->records, record);
352 __near_agent_ndef_parse_records(device->records);
355 cb(device->adapter_idx, device->target_idx, status);
357 g_list_free(records);
362 struct near_device *__near_device_add(uint32_t adapter_idx, uint32_t target_idx,
363 uint8_t *nfcid, uint8_t nfcid_len)
365 struct near_device *device;
368 device = near_device_get_device(adapter_idx, target_idx);
372 device = g_try_malloc0(sizeof(struct near_device));
376 device->path = g_strdup_printf("%s/nfc%d/device%d", NFC_PATH,
377 adapter_idx, target_idx);
382 device->adapter_idx = adapter_idx;
383 device->target_idx = target_idx;
384 device->n_records = 0;
386 if (nfcid_len <= NFC_MAX_NFCID1_LEN && nfcid_len > 0) {
387 device->nfcid_len = nfcid_len;
388 memcpy(device->nfcid, nfcid, nfcid_len);
391 path = g_strdup(device->path);
397 g_hash_table_insert(device_hash, path, device);
402 bool __near_device_register_interface(struct near_device *device)
404 DBG("connection %p", connection);
406 return g_dbus_register_interface(connection, device->path,
407 NFC_DEVICE_INTERFACE,
408 device_methods, NULL,
409 device_properties, device, NULL);
412 int __near_device_listen(struct near_device *device, near_device_io_cb cb)
418 for (list = driver_list; list; list = list->next) {
419 struct near_device_driver *driver = list->data;
421 return driver->listen(device->adapter_idx, cb);
427 int __near_device_push(struct near_device *device,
428 struct near_ndef_message *ndef, char *service_name,
429 near_device_io_cb cb)
435 if (!__near_adapter_get_dep_state(device->adapter_idx)) {
436 near_error("DEP link is not established");
440 for (list = driver_list; list; list = list->next) {
441 struct near_device_driver *driver = list->data;
443 return driver->push(device->adapter_idx, device->target_idx,
444 ndef, service_name, cb);
450 static gint cmp_prio(gconstpointer a, gconstpointer b)
452 const struct near_tag_driver *driver1 = a;
453 const struct near_tag_driver *driver2 = b;
455 return driver2->priority - driver1->priority;
458 int near_device_driver_register(struct near_device_driver *driver)
465 driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
467 __near_adapter_listen(driver);
472 void near_device_driver_unregister(struct near_device_driver *driver)
476 driver_list = g_slist_remove(driver_list, driver);
479 int __near_device_init(void)
483 connection = near_dbus_get_connection();
485 device_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
486 g_free, free_device);
491 void __near_device_cleanup(void)
495 g_hash_table_destroy(device_hash);