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];
62 /* Tag specific structures */
64 uint8_t IDm[TYPE3_IDM_LEN];
65 uint8_t attr[TYPE3_ATTR_BLOCK_SIZE];
70 uint16_t max_ndef_size;
71 uint16_t c_apdu_max_size;
74 DBusMessage *write_msg; /* Pending write message */
75 struct near_ndef_message *write_ndef;
78 static DBusConnection *connection = NULL;
80 static GHashTable *tag_hash;
82 static GSList *driver_list = NULL;
84 struct near_tag *near_tag_get_tag(uint32_t adapter_idx, uint32_t target_idx)
89 path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
90 adapter_idx, target_idx);
94 tag = g_hash_table_lookup(tag_hash, path);
101 static void append_records(DBusMessageIter *iter, void *user_data)
103 struct near_tag *tag = user_data;
108 for (list = tag->records; list; list = list->next) {
109 struct near_ndef_record *record = list->data;
112 path = __near_ndef_record_get_path(record);
116 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
121 static const char *type_string(struct near_tag *tag)
125 DBG("type 0x%x", tag->type);
128 case NFC_PROTO_JEWEL:
132 case NFC_PROTO_MIFARE:
136 case NFC_PROTO_FELICA:
140 case NFC_PROTO_ISO14443:
146 near_error("Unknown tag type 0x%x", tag->type);
153 static const char *protocol_string(struct near_tag *tag)
155 const char *protocol;
157 DBG("protocol 0x%x", tag->protocol);
159 switch (tag->protocol) {
160 case NFC_PROTO_FELICA_MASK:
164 case NFC_PROTO_MIFARE_MASK:
168 case NFC_PROTO_JEWEL_MASK:
172 case NFC_PROTO_ISO14443_MASK:
173 protocol = "ISO-DEP";
177 near_error("Unknown tag protocol 0x%x", tag->protocol);
184 static DBusMessage *get_properties(DBusConnection *conn,
185 DBusMessage *msg, void *data)
187 struct near_tag *tag = data;
188 const char *protocol, *type;
190 DBusMessageIter array, dict;
192 DBG("conn %p", conn);
194 reply = dbus_message_new_method_return(msg);
198 dbus_message_iter_init_append(reply, &array);
200 near_dbus_dict_open(&array, &dict);
202 type = type_string(tag);
204 near_dbus_dict_append_basic(&dict, "Type",
205 DBUS_TYPE_STRING, &type);
207 protocol = protocol_string(tag);
208 if (protocol != NULL)
209 near_dbus_dict_append_basic(&dict, "Protocol",
210 DBUS_TYPE_STRING, &protocol);
212 near_dbus_dict_append_basic(&dict, "ReadOnly",
213 DBUS_TYPE_BOOLEAN, &tag->readonly);
215 near_dbus_dict_append_array(&dict, "Records",
216 DBUS_TYPE_OBJECT_PATH, append_records, tag);
218 near_dbus_dict_close(&array, &dict);
223 static DBusMessage *set_property(DBusConnection *conn,
224 DBusMessage *msg, void *data)
226 DBG("conn %p", conn);
228 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
231 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
233 struct near_tag *tag;
235 tag = near_tag_get_tag(adapter_idx, target_idx);
240 dbus_message_unref(tag->write_msg);
241 tag->write_msg = NULL;
243 __near_adapter_start_check_presence(adapter_idx, target_idx);
245 __near_adapter_tags_changed(adapter_idx);
248 static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
250 struct near_tag *tag;
251 DBusConnection *conn;
254 DBG("Write status %d", status);
256 tag = near_tag_get_tag(adapter_idx, target_idx);
260 conn = near_dbus_get_connection();
265 reply = __near_error_failed(tag->write_msg, EINVAL);
267 g_dbus_send_message(conn, reply);
269 g_dbus_send_reply(conn, tag->write_msg, DBUS_TYPE_INVALID);
272 near_ndef_records_free(tag->records);
280 * If writing succeeded,
281 * check presence will be restored after reading
283 __near_tag_read(tag, tag_read_cb);
288 dbus_message_unref(tag->write_msg);
289 tag->write_msg = NULL;
291 __near_adapter_start_check_presence(tag->adapter_idx, tag->target_idx);
294 static void format_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
296 struct near_tag *tag;
299 DBG("format status %d", status);
301 tag = near_tag_get_tag(adapter_idx, target_idx);
305 if (tag->write_msg == NULL)
309 err = __near_tag_write(tag, tag->write_ndef,
321 write_cb(tag->adapter_idx, tag->target_idx, err);
324 static DBusMessage *write_ndef(DBusConnection *conn,
325 DBusMessage *msg, void *data)
327 struct near_tag *tag = data;
328 struct near_ndef_message *ndef, *ndef_with_header = NULL;
331 DBG("conn %p", conn);
333 if (tag->readonly == TRUE) {
334 DBG("Read only tag");
335 return __near_error_permission_denied(msg);
339 return __near_error_in_progress(msg);
341 ndef = __ndef_build_from_message(msg);
343 return __near_error_failed(msg, EINVAL);
345 tag->write_msg = dbus_message_ref(msg);
347 /* Add NDEF header information depends upon tag type */
349 case NFC_PROTO_JEWEL:
350 case NFC_PROTO_MIFARE:
351 ndef_with_header = g_try_malloc0(sizeof(
352 struct near_ndef_message));
353 if (ndef_with_header == NULL)
356 ndef_with_header->offset = 0;
357 ndef_with_header->length = ndef->length + 3;
358 ndef_with_header->data = g_try_malloc0(ndef->length + 3);
359 if (ndef_with_header->data == NULL)
362 ndef_with_header->data[0] = TLV_NDEF;
363 ndef_with_header->data[1] = ndef->length;
364 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
365 ndef_with_header->data[ndef->length + 2] = TLV_END;
369 case NFC_PROTO_FELICA:
370 ndef_with_header = g_try_malloc0(sizeof(
371 struct near_ndef_message));
372 if (ndef_with_header == NULL)
375 ndef_with_header->offset = 0;
376 ndef_with_header->length = ndef->length;
377 ndef_with_header->data = g_try_malloc0(
378 ndef_with_header->length);
379 if (ndef_with_header->data == NULL)
382 memcpy(ndef_with_header->data, ndef->data, ndef->length);
386 case NFC_PROTO_ISO14443:
387 ndef_with_header = g_try_malloc0(sizeof(
388 struct near_ndef_message));
389 if (ndef_with_header == NULL)
392 ndef_with_header->offset = 0;
393 ndef_with_header->length = ndef->length + 2;
394 ndef_with_header->data = g_try_malloc0(ndef->length + 2);
395 if (ndef_with_header->data == NULL)
398 ndef_with_header->data[0] = (uint8_t)(ndef->length >> 8);
399 ndef_with_header->data[1] = (uint8_t)(ndef->length);
400 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
408 return __near_error_failed(msg, EOPNOTSUPP);
414 tag->write_ndef = ndef_with_header;
415 err = __near_tag_write(tag, ndef_with_header, write_cb);
417 g_free(ndef_with_header->data);
418 g_free(ndef_with_header);
420 return __near_error_failed(msg, -err);
423 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
426 dbus_message_unref(tag->write_msg);
427 tag->write_msg = NULL;
429 return __near_error_failed(msg, ENOMEM);
432 static const GDBusMethodTable tag_methods[] = {
433 { GDBUS_METHOD("GetProperties",
434 NULL, GDBUS_ARGS({"properties", "a{sv}"}),
436 { GDBUS_METHOD("SetProperty",
437 GDBUS_ARGS({"name", "s"}, {"value", "v"}),
438 NULL, set_property) },
439 { GDBUS_ASYNC_METHOD("Write", GDBUS_ARGS({"attributes", "a{sv}"}),
444 static const GDBusSignalTable tag_signals[] = {
445 { GDBUS_SIGNAL("PropertyChanged",
446 GDBUS_ARGS({"name", "s"}, {"value", "v"})) },
451 void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter)
455 for (list = tag->records; list; list = list->next) {
456 struct near_ndef_record *record = list->data;
459 path = __near_ndef_record_get_path(record);
463 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
468 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
469 NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
470 #define NFC_TAG_A_TYPE2 0x00
471 #define NFC_TAG_A_TYPE4 0x01
472 #define NFC_TAG_A_NFC_DEP 0x02
473 #define NFC_TAG_A_TYPE4_DEP 0x03
475 #define NFC_TAG_A_SENS_RES_SSD_JEWEL 0x00
476 #define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c
478 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
479 #define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2)
480 #define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f)
481 #define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8)
483 static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res)
487 return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT;
489 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K;
491 return NEAR_TAG_NFC_T2_MIFARE_MINI;
493 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K;
495 return NEAR_TAG_NFC_T2_MIFARE_DESFIRE;
497 return NEAR_TAG_NFC_T2_JCOP30;
499 return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL;
501 return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON;
503 return NEAR_TAG_NFC_T2_MPCOS;
506 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
509 static void set_tag_type(struct near_tag *tag,
510 uint16_t sens_res, uint8_t sel_res)
512 uint8_t platconf, ssd, proto;
514 DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol,
517 switch (tag->protocol) {
518 case NFC_PROTO_JEWEL_MASK:
519 platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res);
520 ssd = NFC_TAG_A_SENS_RES_SSD(sens_res);
524 if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) &&
525 (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL))
526 tag->type = NFC_PROTO_JEWEL;
529 case NFC_PROTO_MIFARE_MASK:
530 case NFC_PROTO_ISO14443_MASK:
531 proto = NFC_TAG_A_SEL_PROT(sel_res);
533 DBG("proto 0x%x", proto);
536 case NFC_TAG_A_TYPE2:
537 tag->type = NFC_PROTO_MIFARE;
538 tag->sub_type = get_tag_type2_sub_type(sel_res);
540 case NFC_TAG_A_TYPE4:
541 tag->type = NFC_PROTO_ISO14443;
543 case NFC_TAG_A_TYPE4_DEP:
544 tag->type = NFC_PROTO_NFC_DEP;
549 case NFC_PROTO_FELICA_MASK:
550 tag->type = NFC_PROTO_FELICA;
554 tag->type = NFC_PROTO_MAX;
558 DBG("tag type 0x%x", tag->type);
561 static int tag_initialize(struct near_tag *tag,
562 uint32_t adapter_idx, uint32_t target_idx,
564 uint16_t sens_res, uint8_t sel_res,
565 uint8_t *nfcid, uint8_t nfcid_len)
569 tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
570 adapter_idx, target_idx);
571 if (tag->path == NULL)
573 tag->adapter_idx = adapter_idx;
574 tag->target_idx = target_idx;
575 tag->protocol = protocols;
577 tag->readonly = FALSE;
579 if (nfcid_len <= NFC_MAX_NFCID1_LEN) {
580 tag->nfcid_len = nfcid_len;
581 memcpy(tag->nfcid, nfcid, nfcid_len);
584 set_tag_type(tag, sens_res, sel_res);
589 struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx,
591 uint16_t sens_res, uint8_t sel_res,
592 uint8_t *nfcid, uint8_t nfcid_len)
594 struct near_tag *tag;
597 tag = near_tag_get_tag(adapter_idx, target_idx);
601 tag = g_try_malloc0(sizeof(struct near_tag));
605 if (tag_initialize(tag, adapter_idx, target_idx,
608 nfcid, nfcid_len) < 0) {
613 path = g_strdup(tag->path);
619 g_hash_table_insert(tag_hash, path, tag);
621 DBG("connection %p", connection);
623 g_dbus_register_interface(connection, tag->path,
625 tag_methods, tag_signals,
631 void __near_tag_remove(struct near_tag *tag)
633 char *path = tag->path;
635 DBG("path %s", tag->path);
637 if (g_hash_table_lookup(tag_hash, tag->path) == NULL)
640 g_dbus_unregister_interface(connection, tag->path,
643 g_hash_table_remove(tag_hash, path);
646 const char *__near_tag_get_path(struct near_tag *tag)
651 uint32_t __near_tag_get_type(struct near_tag *tag)
656 enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx,
660 struct near_tag *tag;
662 tag = near_tag_get_tag(adapter_idx, target_idx);
664 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
666 return tag->sub_type;
669 uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx,
672 struct near_tag *tag;
675 tag = near_tag_get_tag(adapter_idx, target_idx);
679 nfcid = g_try_malloc0(tag->nfcid_len);
683 memcpy(nfcid, tag->nfcid, tag->nfcid_len);
684 *nfcid_len = tag->nfcid_len;
693 int near_tag_set_nfcid(uint32_t adapter_idx, uint32_t target_idx,
694 uint8_t *nfcid, size_t nfcid_len)
696 struct near_tag *tag;
698 DBG("NFCID len %zd", nfcid_len);
700 tag = near_tag_get_tag(adapter_idx, target_idx);
704 if (tag->nfcid_len > 0)
707 if (nfcid_len > NFC_MAX_NFCID1_LEN)
710 memcpy(tag->nfcid, nfcid, nfcid_len);
711 tag->nfcid_len = nfcid_len;
716 int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx,
717 uint8_t *data, size_t data_length)
719 struct near_tag *tag;
721 tag = near_tag_get_tag(adapter_idx, target_idx);
725 tag->data_length = data_length;
726 tag->data = g_try_malloc0(data_length);
727 if (tag->data == NULL)
731 memcpy(tag->data, data, data_length);
736 int near_tag_add_records(struct near_tag *tag, GList *records,
737 near_tag_io_cb cb, int status)
740 struct near_ndef_record *record;
743 DBG("records %p", records);
745 for (list = records; list; list = list->next) {
748 path = g_strdup_printf("%s/nfc%d/tag%d/record%d",
749 NFC_PATH, tag->adapter_idx,
750 tag->target_idx, tag->n_records);
755 __near_ndef_record_register(record, path);
758 tag->records = g_list_append(tag->records, record);
761 __near_agent_ndef_parse_records(tag->records);
764 cb(tag->adapter_idx, tag->target_idx, status);
766 g_list_free(records);
771 void near_tag_set_ro(struct near_tag *tag, near_bool_t readonly)
773 tag->readonly = readonly;
776 void near_tag_set_blank(struct near_tag *tag, near_bool_t blank)
781 near_bool_t near_tag_get_blank(struct near_tag *tag)
786 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
788 if (data_length == NULL)
791 *data_length = tag->data_length;
796 uint32_t near_tag_get_adapter_idx(struct near_tag *tag)
798 return tag->adapter_idx;
801 uint32_t near_tag_get_target_idx(struct near_tag *tag)
803 return tag->target_idx;
806 enum near_tag_memory_layout near_tag_get_memory_layout(struct near_tag *tag)
809 return NEAR_TAG_MEMORY_UNKNOWN;
814 void near_tag_set_memory_layout(struct near_tag *tag,
815 enum near_tag_memory_layout layout)
820 tag->layout = layout;
823 void near_tag_set_max_ndef_size(struct near_tag *tag, uint16_t size)
828 tag->t4.max_ndef_size = size;
831 uint16_t near_tag_get_max_ndef_size(struct near_tag *tag)
836 return tag->t4.max_ndef_size;
839 void near_tag_set_c_apdu_max_size(struct near_tag *tag, uint16_t size)
844 tag->t4.c_apdu_max_size = size;
847 uint16_t near_tag_get_c_apdu_max_size(struct near_tag *tag)
852 return tag->t4.c_apdu_max_size;
855 void near_tag_set_idm(struct near_tag *tag, uint8_t *idm, uint8_t len)
857 if (tag == NULL || len > TYPE3_IDM_LEN)
860 memset(tag->t3.IDm, 0, TYPE3_IDM_LEN);
861 memcpy(tag->t3.IDm, idm, len);
864 uint8_t *near_tag_get_idm(struct near_tag *tag, uint8_t *len)
866 if (tag == NULL || len == NULL)
869 *len = TYPE3_IDM_LEN;
873 void near_tag_set_attr_block(struct near_tag *tag, uint8_t *attr, uint8_t len)
875 if (tag == NULL || len > TYPE3_ATTR_BLOCK_SIZE)
878 memset(tag->t3.attr, 0, TYPE3_ATTR_BLOCK_SIZE);
879 memcpy(tag->t3.attr, attr, len);
882 uint8_t *near_tag_get_attr_block(struct near_tag *tag, uint8_t *len)
884 if (tag == NULL || len == NULL)
887 *len = TYPE3_ATTR_BLOCK_SIZE;
891 void near_tag_set_ic_type(struct near_tag *tag, uint8_t ic_type)
896 tag->t3.ic_type = ic_type;
899 uint8_t near_tag_get_ic_type(struct near_tag *tag)
904 return tag->t3.ic_type;
907 static gint cmp_prio(gconstpointer a, gconstpointer b)
909 const struct near_tag_driver *driver1 = a;
910 const struct near_tag_driver *driver2 = b;
912 return driver2->priority - driver1->priority;
915 int near_tag_driver_register(struct near_tag_driver *driver)
919 if (driver->read == NULL)
922 driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
927 void near_tag_driver_unregister(struct near_tag_driver *driver)
931 driver_list = g_slist_remove(driver_list, driver);
934 int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
938 DBG("type 0x%x", tag->type);
940 /* Stop check presence while reading */
941 __near_adapter_stop_check_presence(tag->adapter_idx, tag->target_idx);
943 for (list = driver_list; list; list = list->next) {
944 struct near_tag_driver *driver = list->data;
946 DBG("driver type 0x%x", driver->type);
948 if (driver->type == tag->type)
949 return driver->read(tag->adapter_idx, tag->target_idx,
956 int __near_tag_write(struct near_tag *tag,
957 struct near_ndef_message *ndef,
963 DBG("type 0x%x", tag->type);
965 for (list = driver_list; list; list = list->next) {
966 struct near_tag_driver *driver = list->data;
968 DBG("driver type 0x%x", driver->type);
970 if (driver->type == tag->type) {
971 /* Stop check presence while writing */
972 __near_adapter_stop_check_presence(tag->adapter_idx,
975 if (tag->blank == TRUE && driver->format != NULL) {
976 DBG("Blank tag detected, formatting");
977 err = driver->format(tag->adapter_idx,
978 tag->target_idx, format_cb);
980 err = driver->write(tag->adapter_idx,
981 tag->target_idx, ndef,
993 __near_adapter_start_check_presence(tag->adapter_idx,
999 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)
1003 DBG("type 0x%x", tag->type);
1005 for (list = driver_list; list; list = list->next) {
1006 struct near_tag_driver *driver = list->data;
1008 DBG("driver type 0x%x", driver->type);
1010 if (driver->type == tag->type) {
1011 if (driver->check_presence == NULL)
1014 return driver->check_presence(tag->adapter_idx, tag->target_idx, cb);
1021 static void free_tag(gpointer data)
1023 struct near_tag *tag = data;
1027 near_ndef_records_free(tag->records);
1034 int __near_tag_init(void)
1038 connection = near_dbus_get_connection();
1040 tag_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1046 void __near_tag_cleanup(void)
1050 g_hash_table_destroy(tag_hash);