fbc71c3d749fababb440126b4e7f2a1197fa697d
[platform/upstream/neard.git] / src / tag.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 #include <string.h>
30
31 #include <glib.h>
32
33 #include <gdbus.h>
34
35 #include "near.h"
36
37 #define TYPE3_IDM_LEN 8
38 #define TYPE3_ATTR_BLOCK_SIZE 16
39
40 struct near_tag {
41         char *path;
42
43         uint32_t adapter_idx;
44         uint32_t target_idx;
45
46         uint32_t protocol;
47         uint32_t type;
48         enum near_tag_sub_type sub_type;
49         enum near_tag_memory_layout layout;
50         bool readonly;
51
52         uint8_t nfcid[NFC_MAX_NFCID1_LEN];
53         uint8_t nfcid_len;
54
55         size_t data_length;
56         uint8_t *data;
57
58         uint32_t n_records;
59         GList *records;
60         bool blank;
61
62         /* Tag specific structures */
63         struct {
64                 uint8_t IDm[TYPE3_IDM_LEN];
65                 uint8_t attr[TYPE3_ATTR_BLOCK_SIZE];
66                 uint8_t ic_type;
67         } t3;
68
69         struct {
70                 uint16_t max_ndef_size;
71                 uint16_t c_apdu_max_size;
72         } t4;
73
74         DBusMessage *write_msg; /* Pending write message */
75         struct near_ndef_message *write_ndef;
76 };
77
78 static DBusConnection *connection = NULL;
79
80 static GHashTable *tag_hash;
81
82 static GSList *driver_list = NULL;
83
84 struct near_tag *near_tag_get_tag(uint32_t adapter_idx, uint32_t target_idx)
85 {
86         struct near_tag *tag;
87         char *path;
88
89         path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
90                                         adapter_idx, target_idx);
91         if (!path)
92                 return NULL;
93
94         tag = g_hash_table_lookup(tag_hash, path);
95         g_free(path);
96
97         /* TODO refcount */
98         return tag;
99 }
100
101 static void append_records(DBusMessageIter *iter, void *user_data)
102 {
103         struct near_tag *tag = user_data;
104         GList *list;
105
106         DBG("");
107
108         for (list = tag->records; list; list = list->next) {
109                 struct near_ndef_record *record = list->data;
110                 char *path;
111
112                 path = __near_ndef_record_get_path(record);
113                 if (!path)
114                         continue;
115
116                 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
117                                                         &path);
118         }
119 }
120
121 static const char *type_string(struct near_tag *tag)
122 {
123         const char *type;
124
125         DBG("type 0x%x", tag->type);
126
127         switch (tag->type) {
128         case NFC_PROTO_JEWEL:
129                 type = "Type 1";
130                 break;
131
132         case NFC_PROTO_MIFARE:
133                 type = "Type 2";
134                 break;
135
136         case NFC_PROTO_FELICA:
137                 type = "Type 3";
138                 break;
139
140         case NFC_PROTO_ISO14443:
141                 type = "Type 4";
142                 break;
143
144         default:
145                 type = NULL;
146                 near_error("Unknown tag type 0x%x", tag->type);
147                 break;
148         }
149
150         return type;
151 }
152
153 static const char *protocol_string(struct near_tag *tag)
154 {
155         const char *protocol;
156
157         DBG("protocol 0x%x", tag->protocol);
158
159         switch (tag->protocol) {
160         case NFC_PROTO_FELICA_MASK:
161                 protocol = "Felica";
162                 break;
163
164         case NFC_PROTO_MIFARE_MASK:
165                 protocol = "MIFARE";
166                 break;
167
168         case NFC_PROTO_JEWEL_MASK:
169                 protocol = "Jewel";
170                 break;
171
172         case NFC_PROTO_ISO14443_MASK:
173                 protocol = "ISO-DEP";
174                 break;
175
176         default:
177                 near_error("Unknown tag protocol 0x%x", tag->protocol);
178                 protocol = NULL;
179         }
180
181         return protocol;
182 }
183
184 static void append_properties(DBusMessageIter *iter, struct near_tag *tag)
185 {
186         DBusMessageIter dict;
187         dbus_bool_t readonly;
188         const char *protocol, *type;
189
190         near_dbus_dict_open(iter, &dict);
191
192         type = type_string(tag);
193         if (type)
194                 near_dbus_dict_append_basic(&dict, "Type",
195                                         DBUS_TYPE_STRING, &type);
196
197         protocol = protocol_string(tag);
198         if (protocol)
199                 near_dbus_dict_append_basic(&dict, "Protocol",
200                                         DBUS_TYPE_STRING, &protocol);
201
202         readonly = tag->readonly;
203         near_dbus_dict_append_basic(&dict, "ReadOnly",
204                                         DBUS_TYPE_BOOLEAN, &readonly);
205
206         near_dbus_dict_append_array(&dict, "Records",
207                                 DBUS_TYPE_OBJECT_PATH, append_records, tag);
208
209         near_dbus_dict_close(iter, &dict);
210 }
211
212 static DBusMessage *get_properties(DBusConnection *conn,
213                                         DBusMessage *msg, void *data)
214 {
215         struct near_tag *tag = data;
216         DBusMessage *reply;
217         DBusMessageIter array;
218
219         DBG("conn %p", conn);
220
221         reply = dbus_message_new_method_return(msg);
222         if (!reply)
223                 return NULL;
224
225         dbus_message_iter_init_append(reply, &array);
226
227         append_properties(&array, tag);
228
229         return reply;
230 }
231
232 static DBusMessage *set_property(DBusConnection *conn,
233                                         DBusMessage *msg, void *data)
234 {
235         DBG("conn %p", conn);
236
237         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
238 }
239
240 void __near_tag_found_signal(struct near_adapter *adapter,
241                                                 struct near_tag *tag)
242 {
243         const char *path;
244         DBusMessage *signal;
245         DBusMessageIter iter;
246
247         path = __near_adapter_get_path(adapter);
248         if (!path)
249                 return;
250
251         signal = dbus_message_new_signal(path, NFC_ADAPTER_INTERFACE,
252                                                                 "TagFound");
253         if (!signal)
254                 return;
255
256         dbus_message_iter_init_append(signal, &iter);
257         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
258                                                                 &tag->path);
259         append_properties(&iter, tag);
260
261         dbus_connection_send(connection, signal, NULL);
262         dbus_message_unref(signal);
263 }
264
265 void __near_tag_lost_signal(struct near_adapter *adapter, struct near_tag *tag)
266 {
267         const char *path;
268
269         path = __near_adapter_get_path(adapter);
270         if (!path)
271                 return;
272
273         g_dbus_emit_signal(connection, path, NFC_ADAPTER_INTERFACE,
274                         "TagLost", DBUS_TYPE_OBJECT_PATH, &tag->path,
275                         DBUS_TYPE_INVALID);
276 }
277
278 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
279 {
280         struct near_tag *tag;
281
282         tag = near_tag_get_tag(adapter_idx, target_idx);
283
284         if (!tag)
285                 return;
286
287         dbus_message_unref(tag->write_msg);
288         tag->write_msg = NULL;
289
290         __near_adapter_start_check_presence(adapter_idx, target_idx);
291
292         __near_adapter_tags_changed(adapter_idx);
293 }
294
295 static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
296 {
297         struct near_tag *tag;
298         DBusConnection *conn;
299         DBusMessage *reply;
300
301         DBG("Write status %d", status);
302
303         tag = near_tag_get_tag(adapter_idx, target_idx);
304         if (!tag)
305                 return;
306
307         conn = near_dbus_get_connection();
308         if (!conn)
309                 goto out;
310
311         if (status != 0) {
312                 reply = __near_error_failed(tag->write_msg, EINVAL);
313                 if (reply)
314                         g_dbus_send_message(conn, reply);
315         } else {
316                 g_dbus_send_reply(conn, tag->write_msg, DBUS_TYPE_INVALID);
317         }
318
319         near_ndef_records_free(tag->records);
320         tag->n_records = 0;
321         tag->records = NULL;
322         g_free(tag->data);
323         tag->data = NULL;
324
325         if (status == 0) {
326                 /*
327                  * If writing succeeded,
328                  * check presence will be restored after reading
329                  */
330                 __near_tag_read(tag, tag_read_cb);
331                 return;
332         }
333
334 out:
335         dbus_message_unref(tag->write_msg);
336         tag->write_msg = NULL;
337
338         __near_adapter_start_check_presence(tag->adapter_idx, tag->target_idx);
339 }
340
341 static void format_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
342 {
343         struct near_tag *tag;
344         int err;
345
346         DBG("format status %d", status);
347
348         tag = near_tag_get_tag(adapter_idx, target_idx);
349         if (!tag)
350                 return;
351
352         if (!tag->write_msg)
353                 return;
354
355         if (status == 0) {
356                 err = __near_tag_write(tag, tag->write_ndef,
357                                                 write_cb);
358                 if (err < 0)
359                         goto error;
360         } else {
361                 err = status;
362                 goto error;
363         }
364
365         return;
366
367 error:
368         write_cb(tag->adapter_idx, tag->target_idx, err);
369 }
370
371 static DBusMessage *write_ndef(DBusConnection *conn,
372                                 DBusMessage *msg, void *data)
373 {
374         struct near_tag *tag = data;
375         struct near_ndef_message *ndef, *ndef_with_header = NULL;
376         int tlv_len_size, err;
377
378         DBG("conn %p", conn);
379
380         if (tag->readonly) {
381                 DBG("Read only tag");
382                 return __near_error_permission_denied(msg);
383         }
384
385         if (tag->write_msg)
386                 return __near_error_in_progress(msg);
387
388         ndef = __ndef_build_from_message(msg);
389         if (!ndef)
390                 return __near_error_failed(msg, EINVAL);
391
392         tag->write_msg = dbus_message_ref(msg);
393
394         /* Add NDEF header information depends upon tag type */
395         switch (tag->type) {
396         case NFC_PROTO_JEWEL:
397         case NFC_PROTO_MIFARE:
398                 if (ndef->length < 0xff)
399                         tlv_len_size = 3;
400                 else
401                         tlv_len_size = 5;
402
403                 ndef_with_header = g_try_malloc0(sizeof(
404                                         struct near_ndef_message));
405                 if (!ndef_with_header)
406                         goto fail;
407
408                 ndef_with_header->offset = 0;
409                 ndef_with_header->length = ndef->length + tlv_len_size;
410                 ndef_with_header->data =
411                                 g_try_malloc0(ndef->length + tlv_len_size);
412                 if (!ndef_with_header->data)
413                         goto fail;
414
415                 ndef_with_header->data[0] = TLV_NDEF;
416
417                 if (ndef->length < 0xff) {
418                         ndef_with_header->data[1] = ndef->length;
419                 } else {
420                         ndef_with_header->data[1] = 0xff;
421                         ndef_with_header->data[2] =
422                                         (uint8_t)(ndef->length >> 8);
423                         ndef_with_header->data[3] = (uint8_t)(ndef->length);
424                 }
425
426                 memcpy(ndef_with_header->data + tlv_len_size - 1, ndef->data,
427                                 ndef->length);
428                 ndef_with_header->data[ndef->length + tlv_len_size - 1] =
429                                                                         TLV_END;
430                 break;
431
432         case NFC_PROTO_FELICA:
433                 ndef_with_header = g_try_malloc0(sizeof(
434                                         struct near_ndef_message));
435                 if (!ndef_with_header)
436                         goto fail;
437
438                 ndef_with_header->offset = 0;
439                 ndef_with_header->length = ndef->length;
440                 ndef_with_header->data = g_try_malloc0(
441                                                 ndef_with_header->length);
442                 if (!ndef_with_header->data)
443                         goto fail;
444
445                 memcpy(ndef_with_header->data, ndef->data, ndef->length);
446
447                 break;
448
449         case NFC_PROTO_ISO14443:
450                 ndef_with_header = g_try_malloc0(sizeof(
451                                         struct near_ndef_message));
452                 if (!ndef_with_header)
453                         goto fail;
454
455                 ndef_with_header->offset = 0;
456                 ndef_with_header->length = ndef->length + 2;
457                 ndef_with_header->data = g_try_malloc0(ndef->length + 2);
458                 if (!ndef_with_header->data)
459                         goto fail;
460
461                 ndef_with_header->data[0] = (uint8_t)(ndef->length >> 8);
462                 ndef_with_header->data[1] = (uint8_t)(ndef->length);
463                 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
464
465                 break;
466
467         default:
468                 g_free(ndef->data);
469                 g_free(ndef);
470
471                 return __near_error_failed(msg, EOPNOTSUPP);
472         }
473
474         g_free(ndef->data);
475         g_free(ndef);
476
477         tag->write_ndef = ndef_with_header;
478         err = __near_tag_write(tag, ndef_with_header, write_cb);
479         if (err < 0) {
480                 g_free(ndef_with_header->data);
481                 g_free(ndef_with_header);
482
483                 return __near_error_failed(msg, -err);
484         }
485
486         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
487
488 fail:
489         dbus_message_unref(tag->write_msg);
490         tag->write_msg = NULL;
491
492         return __near_error_failed(msg, ENOMEM);
493 }
494
495 static const GDBusMethodTable tag_methods[] = {
496         { GDBUS_METHOD("GetProperties",
497                                 NULL, GDBUS_ARGS({"properties", "a{sv}"}),
498                                 get_properties) },
499         { GDBUS_METHOD("SetProperty",
500                                 GDBUS_ARGS({"name", "s"}, {"value", "v"}),
501                                 NULL, set_property) },
502         { GDBUS_ASYNC_METHOD("Write", GDBUS_ARGS({"attributes", "a{sv}"}),
503                                                         NULL, write_ndef) },
504         { },
505 };
506
507 static const GDBusSignalTable tag_signals[] = {
508         { GDBUS_SIGNAL("PropertyChanged",
509                                 GDBUS_ARGS({"name", "s"}, {"value", "v"})) },
510         { }
511 };
512
513
514 void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter)
515 {
516         GList *list;
517
518         for (list = tag->records; list; list = list->next) {
519                 struct near_ndef_record *record = list->data;
520                 char *path;
521
522                 path = __near_ndef_record_get_path(record);
523                 if (!path)
524                         continue;
525
526                 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
527                                                         &path);
528         }
529 }
530
531 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
532                                 NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
533 #define NFC_TAG_A_TYPE2      0x00
534 #define NFC_TAG_A_TYPE4      0x01
535 #define NFC_TAG_A_NFC_DEP    0x02
536 #define NFC_TAG_A_TYPE4_DEP  0x03
537
538 #define NFC_TAG_A_SENS_RES_SSD_JEWEL      0x00
539 #define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c
540
541 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
542 #define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2)
543 #define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f)
544 #define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8)
545
546 static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res)
547 {
548         switch (sel_res) {
549         case 0x00:
550                 return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT;
551         case 0x08:
552                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K;
553         case 0x09:
554                 return NEAR_TAG_NFC_T2_MIFARE_MINI;
555         case 0x18:
556                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K;
557         case 0x20:
558                 return NEAR_TAG_NFC_T2_MIFARE_DESFIRE;
559         case 0x28:
560                 return NEAR_TAG_NFC_T2_JCOP30;
561         case 0x38:
562                 return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL;
563         case 0x88:
564                 return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON;
565         case 0x98:
566                 return NEAR_TAG_NFC_T2_MPCOS;
567         }
568
569         return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
570 }
571
572 static void set_tag_type(struct near_tag *tag,
573                                 uint16_t sens_res, uint8_t sel_res)
574 {
575         uint8_t platconf, ssd, proto;
576
577         DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol,
578                                                         sens_res, sel_res);
579
580         switch (tag->protocol) {
581         case NFC_PROTO_JEWEL_MASK:
582                 platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res);
583                 ssd = NFC_TAG_A_SENS_RES_SSD(sens_res);
584
585                 DBG("Jewel");
586
587                 if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) &&
588                                 (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL))
589                         tag->type = NFC_PROTO_JEWEL;
590                 break;
591
592         case NFC_PROTO_MIFARE_MASK:
593         case NFC_PROTO_ISO14443_MASK:
594                 proto = NFC_TAG_A_SEL_PROT(sel_res);
595
596                 DBG("proto 0x%x", proto);
597
598                 switch (proto) {
599                 case NFC_TAG_A_TYPE2:
600                         tag->type = NFC_PROTO_MIFARE;
601                         tag->sub_type = get_tag_type2_sub_type(sel_res);
602                         break;
603                 case NFC_TAG_A_TYPE4:
604                         tag->type = NFC_PROTO_ISO14443;
605                         break;
606                 case NFC_TAG_A_TYPE4_DEP:
607                         tag->type = NFC_PROTO_NFC_DEP;
608                         break;
609                 }
610                 break;
611
612         case NFC_PROTO_FELICA_MASK:
613                 tag->type = NFC_PROTO_FELICA;
614                 break;
615
616         case NFC_PROTO_ISO14443_B_MASK:
617                 tag->type = NFC_PROTO_ISO14443_B;
618                 break;
619
620         default:
621                 tag->type = NFC_PROTO_MAX;
622                 break;
623         }
624
625         DBG("tag type 0x%x", tag->type);
626 }
627
628 static int tag_initialize(struct near_tag *tag,
629                         uint32_t adapter_idx, uint32_t target_idx,
630                         uint32_t protocols,
631                         uint16_t sens_res, uint8_t sel_res,
632                         uint8_t *nfcid, uint8_t nfcid_len)
633 {
634         DBG("");
635
636         tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
637                                         adapter_idx, target_idx);
638         if (!tag->path)
639                 return -ENOMEM;
640         tag->adapter_idx = adapter_idx;
641         tag->target_idx = target_idx;
642         tag->protocol = protocols;
643         tag->n_records = 0;
644         tag->readonly = false;
645
646         if (nfcid_len <= NFC_MAX_NFCID1_LEN) {
647                 tag->nfcid_len = nfcid_len;
648                 memcpy(tag->nfcid, nfcid, nfcid_len);
649         }
650
651         set_tag_type(tag, sens_res, sel_res);
652
653         return 0;
654 }
655
656 struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx,
657                                 uint32_t protocols,
658                                 uint16_t sens_res, uint8_t sel_res,
659                                 uint8_t *nfcid, uint8_t nfcid_len)
660 {
661         struct near_tag *tag;
662         char *path;
663
664         tag = near_tag_get_tag(adapter_idx, target_idx);
665         if (tag)
666                 return NULL;
667
668         tag = g_try_malloc0(sizeof(struct near_tag));
669         if (!tag)
670                 return NULL;
671
672         if (tag_initialize(tag, adapter_idx, target_idx,
673                                 protocols,
674                                 sens_res, sel_res,
675                                 nfcid, nfcid_len) < 0) {
676                 g_free(tag);
677                 return NULL;
678         }
679
680         path = g_strdup(tag->path);
681         if (!path) {
682                 g_free(tag);
683                 return NULL;
684         }
685
686         g_hash_table_insert(tag_hash, path, tag);
687
688         DBG("connection %p", connection);
689
690         g_dbus_register_interface(connection, tag->path,
691                                         NFC_TAG_INTERFACE,
692                                         tag_methods, tag_signals,
693                                                         NULL, tag, NULL);
694
695         return tag;
696 }
697
698 void __near_tag_remove(struct near_tag *tag)
699 {
700         char *path = tag->path;
701
702         DBG("path %s", tag->path);
703
704         if (!g_hash_table_lookup(tag_hash, tag->path))
705                 return;
706
707         g_dbus_unregister_interface(connection, tag->path,
708                                                 NFC_TAG_INTERFACE);
709
710         g_hash_table_remove(tag_hash, path);
711 }
712
713 const char *__near_tag_get_path(struct near_tag *tag)
714 {
715         return tag->path;
716 }
717
718 uint32_t __near_tag_get_type(struct near_tag *tag)
719 {
720         return tag->type;
721 }
722
723 enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx,
724                                 uint32_t target_idx)
725
726 {
727         struct near_tag *tag;
728
729         tag = near_tag_get_tag(adapter_idx, target_idx);
730         if (!tag)
731                 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
732
733         return tag->sub_type;
734 }
735
736 uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx,
737                                 uint8_t *nfcid_len)
738 {
739         struct near_tag *tag;
740         uint8_t *nfcid;
741
742         tag = near_tag_get_tag(adapter_idx, target_idx);
743         if (!tag)
744                 goto fail;
745
746         nfcid = g_try_malloc0(tag->nfcid_len);
747         if (!nfcid)
748                 goto fail;
749
750         memcpy(nfcid, tag->nfcid, tag->nfcid_len);
751         *nfcid_len = tag->nfcid_len;
752
753         return nfcid;
754
755 fail:
756         *nfcid_len = 0;
757         return NULL;
758 }
759
760 int near_tag_set_nfcid(uint32_t adapter_idx, uint32_t target_idx,
761                                         uint8_t *nfcid, size_t nfcid_len)
762 {
763         struct near_tag *tag;
764
765         DBG("NFCID len %zd", nfcid_len);
766
767         tag = near_tag_get_tag(adapter_idx, target_idx);
768         if (!tag)
769                 return -ENODEV;
770
771         if (tag->nfcid_len > 0)
772                 return -EALREADY;
773
774         if (nfcid_len > NFC_MAX_NFCID1_LEN)
775                 return -EINVAL;
776
777         memcpy(tag->nfcid, nfcid, nfcid_len);
778         tag->nfcid_len = nfcid_len;
779
780         return 0;
781 }
782
783 int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx,
784                         uint8_t *data, size_t data_length)
785 {
786         struct near_tag *tag;
787
788         tag = near_tag_get_tag(adapter_idx, target_idx);
789         if (!tag)
790                 return -ENODEV;
791
792         tag->data_length = data_length;
793         tag->data = g_try_malloc0(data_length);
794         if (!tag->data)
795                 return -ENOMEM;
796
797         if (data)
798                 memcpy(tag->data, data, data_length);
799
800         return 0;
801 }
802
803 int near_tag_add_records(struct near_tag *tag, GList *records,
804                                 near_tag_io_cb cb, int status)
805 {
806         GList *list;
807         struct near_ndef_record *record;
808         char *path;
809
810         DBG("records %p", records);
811
812         for (list = records; list; list = list->next) {
813                 record = list->data;
814
815                 path = g_strdup_printf("%s/nfc%d/tag%d/record%d",
816                                         NFC_PATH, tag->adapter_idx,
817                                         tag->target_idx, tag->n_records);
818
819                 if (!path)
820                         continue;
821
822                 __near_ndef_record_register(record, path);
823
824                 tag->n_records++;
825                 tag->records = g_list_append(tag->records, record);
826         }
827
828         __near_agent_ndef_parse_records(tag->records);
829
830         near_dbus_property_changed_array(tag->path,
831                                         NFC_TAG_INTERFACE, "Records",
832                                         DBUS_TYPE_OBJECT_PATH, append_records,
833                                         tag);
834
835         if (cb)
836                 cb(tag->adapter_idx, tag->target_idx, status);
837
838         g_list_free(records);
839
840         return 0;
841 }
842
843 void near_tag_set_ro(struct near_tag *tag, bool readonly)
844 {
845         tag->readonly = readonly;
846 }
847
848 void near_tag_set_blank(struct near_tag *tag, bool blank)
849 {
850         tag->blank = blank;
851 }
852
853 bool near_tag_get_blank(struct near_tag *tag)
854 {
855         return tag->blank;
856 }
857
858 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
859 {
860         if (!data_length)
861                 return NULL;
862
863         *data_length = tag->data_length;
864
865         return tag->data;
866 }
867
868 size_t near_tag_get_data_length(struct near_tag *tag)
869 {
870         return tag->data_length;
871 }
872
873 uint32_t near_tag_get_adapter_idx(struct near_tag *tag)
874 {
875         return tag->adapter_idx;
876 }
877
878 uint32_t near_tag_get_target_idx(struct near_tag *tag)
879 {
880         return tag->target_idx;
881 }
882
883 enum near_tag_memory_layout near_tag_get_memory_layout(struct near_tag *tag)
884 {
885         if (!tag)
886                 return NEAR_TAG_MEMORY_UNKNOWN;
887
888         return tag->layout;
889 }
890
891 void near_tag_set_memory_layout(struct near_tag *tag,
892                                         enum near_tag_memory_layout layout)
893 {
894         if (!tag)
895                 return;
896
897         tag->layout = layout;
898 }
899
900 void near_tag_set_max_ndef_size(struct near_tag *tag, uint16_t size)
901 {
902         if (!tag)
903                 return;
904
905         tag->t4.max_ndef_size = size;
906 }
907
908 uint16_t near_tag_get_max_ndef_size(struct near_tag *tag)
909 {
910         if (!tag)
911                 return 0;
912
913         return tag->t4.max_ndef_size;
914 }
915
916 void near_tag_set_c_apdu_max_size(struct near_tag *tag, uint16_t size)
917 {
918         if (!tag)
919                 return;
920
921         tag->t4.c_apdu_max_size = size;
922 }
923
924 uint16_t near_tag_get_c_apdu_max_size(struct near_tag *tag)
925 {
926         if (!tag)
927                 return 0;
928
929         return tag->t4.c_apdu_max_size;
930 }
931
932 void near_tag_set_idm(struct near_tag *tag, uint8_t *idm, uint8_t len)
933 {
934         if (!tag || len > TYPE3_IDM_LEN)
935                 return;
936
937         memset(tag->t3.IDm, 0, TYPE3_IDM_LEN);
938         memcpy(tag->t3.IDm, idm, len);
939 }
940
941 uint8_t *near_tag_get_idm(struct near_tag *tag, uint8_t *len)
942 {
943         if (!tag || !len)
944                 return NULL;
945
946         *len = TYPE3_IDM_LEN;
947         return tag->t3.IDm;
948 }
949
950 void near_tag_set_attr_block(struct near_tag *tag, uint8_t *attr, uint8_t len)
951 {
952         if (!tag || len > TYPE3_ATTR_BLOCK_SIZE)
953                 return;
954
955         memset(tag->t3.attr, 0, TYPE3_ATTR_BLOCK_SIZE);
956         memcpy(tag->t3.attr, attr, len);
957 }
958
959 uint8_t *near_tag_get_attr_block(struct near_tag *tag, uint8_t *len)
960 {
961         if (!tag || !len)
962                 return NULL;
963
964         *len = TYPE3_ATTR_BLOCK_SIZE;
965         return tag->t3.attr;
966 }
967
968 void near_tag_set_ic_type(struct near_tag *tag, uint8_t ic_type)
969 {
970         if (!tag)
971                 return;
972
973         tag->t3.ic_type = ic_type;
974 }
975
976 uint8_t near_tag_get_ic_type(struct near_tag *tag)
977 {
978         if (!tag)
979                 return 0;
980
981         return tag->t3.ic_type;
982 }
983
984 static gint cmp_prio(gconstpointer a, gconstpointer b)
985 {
986         const struct near_tag_driver *driver1 = a;
987         const struct near_tag_driver *driver2 = b;
988
989         return driver2->priority - driver1->priority;
990 }
991
992 int near_tag_driver_register(struct near_tag_driver *driver)
993 {
994         DBG("");
995
996         if (!driver->read)
997                 return -EINVAL;
998
999         driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
1000
1001         return 0;
1002 }
1003
1004 void near_tag_driver_unregister(struct near_tag_driver *driver)
1005 {
1006         DBG("");
1007
1008         driver_list = g_slist_remove(driver_list, driver);
1009 }
1010
1011 int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
1012 {
1013         GSList *list;
1014
1015         DBG("type 0x%x", tag->type);
1016
1017         /* Stop check presence while reading */
1018         __near_adapter_stop_check_presence(tag->adapter_idx, tag->target_idx);
1019
1020         for (list = driver_list; list; list = list->next) {
1021                 struct near_tag_driver *driver = list->data;
1022
1023                 DBG("driver type 0x%x", driver->type);
1024
1025                 if (driver->type == tag->type)
1026                         return driver->read(tag->adapter_idx, tag->target_idx,
1027                                                                         cb);
1028         }
1029
1030         return 0;
1031 }
1032
1033 int __near_tag_write(struct near_tag *tag,
1034                                 struct near_ndef_message *ndef,
1035                                 near_tag_io_cb cb)
1036 {
1037         GSList *list;
1038         int err;
1039
1040         DBG("type 0x%x", tag->type);
1041
1042         for (list = driver_list; list; list = list->next) {
1043                 struct near_tag_driver *driver = list->data;
1044
1045                 DBG("driver type 0x%x", driver->type);
1046
1047                 if (driver->type == tag->type) {
1048                         /* Stop check presence while writing */
1049                         __near_adapter_stop_check_presence(tag->adapter_idx,
1050                                                                 tag->target_idx);
1051
1052                         if (tag->blank && driver->format) {
1053                                 DBG("Blank tag detected, formatting");
1054                                 err = driver->format(tag->adapter_idx,
1055                                                 tag->target_idx, format_cb);
1056                         } else {
1057                                 err = driver->write(tag->adapter_idx,
1058                                                         tag->target_idx, ndef,
1059                                                         cb);
1060                         }
1061
1062                         break;
1063                 }
1064         }
1065
1066         if (!list)
1067                 err = -EOPNOTSUPP;
1068
1069         if (err < 0)
1070                 __near_adapter_start_check_presence(tag->adapter_idx,
1071                                                         tag->target_idx);
1072
1073         return err;
1074 }
1075
1076 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)
1077 {
1078         GSList *list;
1079
1080         DBG("type 0x%x", tag->type);
1081
1082         for (list = driver_list; list; list = list->next) {
1083                 struct near_tag_driver *driver = list->data;
1084
1085                 DBG("driver type 0x%x", driver->type);
1086
1087                 if (driver->type == tag->type) {
1088                         if (!driver->check_presence)
1089                                 continue;
1090
1091                         return driver->check_presence(tag->adapter_idx, tag->target_idx, cb);
1092                 }
1093         }
1094
1095         return -EOPNOTSUPP;
1096 }
1097
1098 static void free_tag(gpointer data)
1099 {
1100         struct near_tag *tag = data;
1101
1102         DBG("tag %p", tag);
1103
1104         near_ndef_records_free(tag->records);
1105
1106         g_free(tag->path);
1107         g_free(tag->data);
1108         g_free(tag);
1109 }
1110
1111 int __near_tag_init(void)
1112 {
1113         DBG("");
1114
1115         connection = near_dbus_get_connection();
1116
1117         tag_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1118                                                 g_free, free_tag);
1119
1120         return 0;
1121 }
1122
1123 void __near_tag_cleanup(void)
1124 {
1125         DBG("");
1126
1127         g_hash_table_destroy(tag_hash);
1128         tag_hash = NULL;
1129 }