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
37 #define TYPE3_IDM_LEN 8
38 #define TYPE3_ATTR_BLOCK_SIZE 16
48 enum near_tag_sub_type sub_type;
49 enum near_tag_memory_layout layout;
52 uint8_t nfcid[NFC_MAX_NFCID1_LEN];
61 /* Tag specific structures */
63 uint8_t IDm[TYPE3_IDM_LEN];
64 uint8_t attr[TYPE3_ATTR_BLOCK_SIZE];
68 uint16_t max_ndef_size;
69 uint16_t c_apdu_max_size;
73 static DBusConnection *connection = NULL;
75 static GHashTable *tag_hash;
77 static GSList *driver_list = NULL;
79 struct near_tag *near_tag_get_tag(uint32_t adapter_idx, uint32_t target_idx)
84 path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
85 adapter_idx, target_idx);
89 tag = g_hash_table_lookup(tag_hash, path);
96 static void append_records(DBusMessageIter *iter, void *user_data)
98 struct near_tag *tag = user_data;
103 for (list = tag->records; list; list = list->next) {
104 struct near_ndef_record *record = list->data;
107 path = __near_ndef_record_get_path(record);
111 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
116 static const char *type_string(struct near_tag *tag)
120 DBG("type 0x%x", tag->type);
123 case NFC_PROTO_JEWEL:
127 case NFC_PROTO_MIFARE:
131 case NFC_PROTO_FELICA:
135 case NFC_PROTO_ISO14443:
141 near_error("Unknown tag type 0x%x", tag->type);
148 static const char *protocol_string(struct near_tag *tag)
150 const char *protocol;
152 DBG("protocol 0x%x", tag->protocol);
154 switch (tag->protocol) {
155 case NFC_PROTO_FELICA_MASK:
159 case NFC_PROTO_MIFARE_MASK:
163 case NFC_PROTO_JEWEL_MASK:
167 case NFC_PROTO_ISO14443_MASK:
168 protocol = "ISO-DEP";
172 near_error("Unknown tag protocol 0x%x", tag->protocol);
179 static DBusMessage *get_properties(DBusConnection *conn,
180 DBusMessage *msg, void *data)
182 struct near_tag *tag = data;
183 const char *protocol, *type;
185 DBusMessageIter array, dict;
187 DBG("conn %p", conn);
189 reply = dbus_message_new_method_return(msg);
193 dbus_message_iter_init_append(reply, &array);
195 near_dbus_dict_open(&array, &dict);
197 type = type_string(tag);
199 near_dbus_dict_append_basic(&dict, "Type",
200 DBUS_TYPE_STRING, &type);
202 protocol = protocol_string(tag);
203 if (protocol != NULL)
204 near_dbus_dict_append_basic(&dict, "Protocol",
205 DBUS_TYPE_STRING, &protocol);
207 near_dbus_dict_append_basic(&dict, "ReadOnly",
208 DBUS_TYPE_BOOLEAN, &tag->readonly);
210 near_dbus_dict_append_array(&dict, "Records",
211 DBUS_TYPE_OBJECT_PATH, append_records, tag);
213 near_dbus_dict_close(&array, &dict);
218 static DBusMessage *set_property(DBusConnection *conn,
219 DBusMessage *msg, void *data)
221 DBG("conn %p", conn);
223 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
226 static GDBusMethodTable tag_methods[] = {
227 { "GetProperties", "", "a{sv}", get_properties },
228 { "SetProperty", "sv", "", set_property },
232 static GDBusSignalTable tag_signals[] = {
233 { "PropertyChanged", "sv" },
238 void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter)
242 for (list = tag->records; list; list = list->next) {
243 struct near_ndef_record *record = list->data;
246 path = __near_ndef_record_get_path(record);
250 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
255 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
256 NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
257 #define NFC_TAG_A_TYPE2 0x00
258 #define NFC_TAG_A_TYPE4 0x01
259 #define NFC_TAG_A_NFC_DEP 0x02
260 #define NFC_TAG_A_TYPE4_DEP 0x03
262 #define NFC_TAG_A_SENS_RES_SSD_JEWEL 0x00
263 #define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c
265 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
266 #define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2)
267 #define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f)
268 #define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8)
270 static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res)
274 return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT;
276 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K;
278 return NEAR_TAG_NFC_T2_MIFARE_MINI;
280 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K;
282 return NEAR_TAG_NFC_T2_MIFARE_DESFIRE;
284 return NEAR_TAG_NFC_T2_JCOP30;
286 return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL;
288 return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON;
290 return NEAR_TAG_NFC_T2_MPCOS;
293 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
296 static void set_tag_type(struct near_tag *tag,
297 uint16_t sens_res, uint8_t sel_res)
299 uint8_t platconf, ssd, proto;
301 DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol,
304 switch (tag->protocol) {
305 case NFC_PROTO_JEWEL_MASK:
306 platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res);
307 ssd = NFC_TAG_A_SENS_RES_SSD(sens_res);
311 if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) &&
312 (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL))
313 tag->type = NFC_PROTO_JEWEL;
316 case NFC_PROTO_MIFARE_MASK:
317 case NFC_PROTO_ISO14443_MASK:
318 proto = NFC_TAG_A_SEL_PROT(sel_res);
320 DBG("proto 0x%x", proto);
323 case NFC_TAG_A_TYPE2:
324 tag->type = NFC_PROTO_MIFARE;
325 tag->sub_type = get_tag_type2_sub_type(sel_res);
327 case NFC_TAG_A_TYPE4:
328 tag->type = NFC_PROTO_ISO14443;
330 case NFC_TAG_A_TYPE4_DEP:
331 tag->type = NFC_PROTO_NFC_DEP;
336 case NFC_PROTO_FELICA_MASK:
337 tag->type = NFC_PROTO_FELICA;
341 tag->type = NFC_PROTO_MAX;
345 DBG("tag type 0x%x", tag->type);
348 static int tag_initialize(struct near_tag *tag,
349 uint32_t adapter_idx, uint32_t target_idx,
351 uint16_t sens_res, uint8_t sel_res,
352 uint8_t *nfcid, uint8_t nfcid_len)
356 tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
357 adapter_idx, target_idx);
358 if (tag->path == NULL)
360 tag->adapter_idx = adapter_idx;
361 tag->target_idx = target_idx;
362 tag->protocol = protocols;
366 if (nfcid_len <= NFC_MAX_NFCID1_LEN) {
367 tag->nfcid_len = nfcid_len;
368 memcpy(tag->nfcid, nfcid, nfcid_len);
371 set_tag_type(tag, sens_res, sel_res);
376 struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx,
378 uint16_t sens_res, uint8_t sel_res,
379 uint8_t *nfcid, uint8_t nfcid_len)
381 struct near_tag *tag;
384 tag = near_tag_get_tag(adapter_idx, target_idx);
388 tag = g_try_malloc0(sizeof(struct near_tag));
392 if (tag_initialize(tag, adapter_idx, target_idx,
395 nfcid, nfcid_len) < 0) {
400 path = g_strdup(tag->path);
406 g_hash_table_insert(tag_hash, path, tag);
408 DBG("connection %p", connection);
410 g_dbus_register_interface(connection, tag->path,
412 tag_methods, tag_signals,
418 void __near_tag_remove(struct near_tag *tag)
420 char *path = tag->path;
422 DBG("path %s", tag->path);
424 if (g_hash_table_lookup(tag_hash, tag->path) == NULL)
427 g_dbus_unregister_interface(connection, tag->path,
430 g_hash_table_remove(tag_hash, path);
433 const char *__near_tag_get_path(struct near_tag *tag)
439 uint32_t __near_tag_get_idx(struct near_tag *tag)
441 return tag->target_idx;
444 uint32_t __near_tag_get_type(struct near_tag *tag)
449 enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx,
453 struct near_tag *tag;
455 tag = near_tag_get_tag(adapter_idx, target_idx);
457 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
459 return tag->sub_type;
462 uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx,
465 struct near_tag *tag;
468 tag = near_tag_get_tag(adapter_idx, target_idx);
472 nfcid = g_try_malloc0(tag->nfcid_len);
476 memcpy(nfcid, tag->nfcid, tag->nfcid_len);
477 *nfcid_len = tag->nfcid_len;
486 int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx,
487 uint8_t *data, size_t data_length)
489 struct near_tag *tag;
491 tag = near_tag_get_tag(adapter_idx, target_idx);
495 tag->data_length = data_length;
496 tag->data = g_try_malloc0(data_length);
497 if (tag->data == NULL)
501 memcpy(tag->data, data, data_length);
506 struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx,
507 uint8_t *data, size_t data_length)
509 struct near_tag *tag;
512 path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
513 adapter_idx, target_idx);
518 if (g_hash_table_lookup(tag_hash, path) != NULL)
522 tag = g_try_malloc0(sizeof(struct near_tag));
526 g_hash_table_insert(tag_hash, path, tag);
528 DBG("connection %p", connection);
530 g_dbus_register_interface(connection, tag->path,
532 tag_methods, tag_signals,
538 void __near_tag_free(struct near_tag *tag)
544 for (list = tag->records; list; list = list->next) {
545 struct near_ndef_record *record = list->data;
547 __near_ndef_record_free(record);
550 g_list_free(tag->records);
556 uint32_t __near_tag_n_records(struct near_tag *tag)
558 return tag->n_records;
561 int __near_tag_add_record(struct near_tag *tag,
562 struct near_ndef_record *record)
567 tag->records = g_list_append(tag->records, record);
572 int near_tag_set_ro(struct near_tag *tag, near_bool_t readonly)
574 tag->readonly = readonly;
579 near_bool_t near_tag_get_ro(struct near_tag *tag)
581 return tag->readonly;
584 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
586 if (data_length == NULL)
589 *data_length = tag->data_length;
594 uint32_t near_tag_get_adapter_idx(struct near_tag *tag)
596 return tag->adapter_idx;
599 uint32_t near_tag_get_target_idx(struct near_tag *tag)
601 return tag->target_idx;
604 enum near_tag_memory_layout near_tag_get_memory_layout(struct near_tag *tag)
607 return NEAR_TAG_MEMORY_UNKNOWN;
612 void near_tag_set_memory_layout(struct near_tag *tag,
613 enum near_tag_memory_layout layout)
618 tag->layout = layout;
621 void near_tag_set_max_ndef_size(struct near_tag *tag, uint16_t size)
626 tag->t4.max_ndef_size = size;
629 uint16_t near_tag_get_max_ndef_size(struct near_tag *tag)
634 return tag->t4.max_ndef_size;
637 void near_tag_set_c_apdu_max_size(struct near_tag *tag, uint16_t size)
642 tag->t4.c_apdu_max_size = size;
645 uint16_t near_tag_get_c_apdu_max_size(struct near_tag *tag)
650 return tag->t4.c_apdu_max_size;
653 void near_tag_set_idm(struct near_tag *tag, uint8_t *idm, uint8_t len)
655 if (tag == NULL || len > TYPE3_IDM_LEN)
658 memset(tag->t3.IDm, 0, TYPE3_IDM_LEN);
659 memcpy(tag->t3.IDm, idm, len);
662 uint8_t *near_tag_get_idm(struct near_tag *tag, uint8_t *len)
664 if (tag == NULL || len == NULL)
667 *len = TYPE3_IDM_LEN;
671 void near_tag_set_attr_block(struct near_tag *tag, uint8_t *attr, uint8_t len)
673 if (tag == NULL || len > TYPE3_ATTR_BLOCK_SIZE)
676 memset(tag->t3.attr, 0, TYPE3_ATTR_BLOCK_SIZE);
677 memcpy(tag->t3.attr, attr, len);
680 uint8_t *near_tag_get_attr_block(struct near_tag *tag, uint8_t *len)
682 if (tag == NULL || len == NULL)
685 *len = TYPE3_ATTR_BLOCK_SIZE;
689 static gint cmp_prio(gconstpointer a, gconstpointer b)
691 const struct near_tag_driver *driver1 = a;
692 const struct near_tag_driver *driver2 = b;
694 return driver2->priority - driver1->priority;
697 int near_tag_driver_register(struct near_tag_driver *driver)
701 if (driver->read_tag == NULL)
704 driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
709 void near_tag_driver_unregister(struct near_tag_driver *driver)
713 driver_list = g_slist_remove(driver_list, driver);
716 int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
720 DBG("type 0x%x", tag->type);
722 for (list = driver_list; list; list = list->next) {
723 struct near_tag_driver *driver = list->data;
725 DBG("driver type 0x%x", driver->type);
727 if (driver->type == tag->type)
728 return driver->read_tag(tag->adapter_idx, tag->target_idx, cb);
734 int __near_tag_add_ndef(struct near_tag *tag,
735 struct near_ndef_message *ndef,
740 DBG("type 0x%x", tag->type);
742 for (list = driver_list; list; list = list->next) {
743 struct near_tag_driver *driver = list->data;
745 DBG("driver type 0x%x", driver->type);
747 if (driver->type == tag->type)
748 return driver->add_ndef(tag->adapter_idx, tag->target_idx,
755 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)
759 DBG("type 0x%x", tag->type);
761 for (list = driver_list; list; list = list->next) {
762 struct near_tag_driver *driver = list->data;
764 DBG("driver type 0x%x", driver->type);
766 if (driver->type == tag->type) {
767 if (driver->check_presence == NULL)
770 return driver->check_presence(tag->adapter_idx, tag->target_idx, cb);
777 static void free_tag(gpointer data)
779 struct near_tag *tag = data;
784 for (list = tag->records; list; list = list->next) {
785 struct near_ndef_record *record = list->data;
787 __near_ndef_record_free(record);
792 g_list_free(tag->records);
800 int __near_tag_init(void)
804 connection = near_dbus_get_connection();
806 tag_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
812 void __near_tag_cleanup(void)
816 g_hash_table_destroy(tag_hash);