tag: Do not unref a NULL write message
[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         if (tag->write_msg) {
288                 dbus_message_unref(tag->write_msg);
289                 tag->write_msg = NULL;
290         }
291
292         __near_adapter_start_check_presence(adapter_idx, target_idx);
293
294         __near_adapter_tags_changed(adapter_idx);
295 }
296
297 static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
298 {
299         struct near_tag *tag;
300         DBusConnection *conn;
301         DBusMessage *reply;
302
303         DBG("Write status %d", status);
304
305         tag = near_tag_get_tag(adapter_idx, target_idx);
306         if (!tag)
307                 return;
308
309         conn = near_dbus_get_connection();
310         if (!conn)
311                 goto out;
312
313         if (status != 0) {
314                 reply = __near_error_failed(tag->write_msg, EINVAL);
315                 if (reply)
316                         g_dbus_send_message(conn, reply);
317         } else {
318                 g_dbus_send_reply(conn, tag->write_msg, DBUS_TYPE_INVALID);
319         }
320
321         near_ndef_records_free(tag->records);
322         tag->n_records = 0;
323         tag->records = NULL;
324         g_free(tag->data);
325         tag->data = NULL;
326
327         if (status == 0) {
328                 /*
329                  * If writing succeeded,
330                  * check presence will be restored after reading
331                  */
332                 __near_tag_read(tag, tag_read_cb);
333                 return;
334         }
335
336 out:
337         dbus_message_unref(tag->write_msg);
338         tag->write_msg = NULL;
339
340         __near_adapter_start_check_presence(tag->adapter_idx, tag->target_idx);
341 }
342
343 static void format_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
344 {
345         struct near_tag *tag;
346         int err;
347
348         DBG("format status %d", status);
349
350         tag = near_tag_get_tag(adapter_idx, target_idx);
351         if (!tag)
352                 return;
353
354         if (!tag->write_msg)
355                 return;
356
357         if (status == 0) {
358                 err = __near_tag_write(tag, tag->write_ndef,
359                                                 write_cb);
360                 if (err < 0)
361                         goto error;
362         } else {
363                 err = status;
364                 goto error;
365         }
366
367         return;
368
369 error:
370         write_cb(tag->adapter_idx, tag->target_idx, err);
371 }
372
373 static DBusMessage *write_ndef(DBusConnection *conn,
374                                 DBusMessage *msg, void *data)
375 {
376         struct near_tag *tag = data;
377         struct near_ndef_message *ndef, *ndef_with_header = NULL;
378         int tlv_len_size, err;
379
380         DBG("conn %p", conn);
381
382         if (tag->readonly) {
383                 DBG("Read only tag");
384                 return __near_error_permission_denied(msg);
385         }
386
387         if (tag->write_msg)
388                 return __near_error_in_progress(msg);
389
390         ndef = __ndef_build_from_message(msg);
391         if (!ndef)
392                 return __near_error_failed(msg, EINVAL);
393
394         tag->write_msg = dbus_message_ref(msg);
395
396         /* Add NDEF header information depends upon tag type */
397         switch (tag->type) {
398         case NFC_PROTO_JEWEL:
399         case NFC_PROTO_MIFARE:
400                 if (ndef->length < 0xff)
401                         tlv_len_size = 3;
402                 else
403                         tlv_len_size = 5;
404
405                 ndef_with_header = g_try_malloc0(sizeof(
406                                         struct near_ndef_message));
407                 if (!ndef_with_header)
408                         goto fail;
409
410                 ndef_with_header->offset = 0;
411                 ndef_with_header->length = ndef->length + tlv_len_size;
412                 ndef_with_header->data =
413                                 g_try_malloc0(ndef->length + tlv_len_size);
414                 if (!ndef_with_header->data)
415                         goto fail;
416
417                 ndef_with_header->data[0] = TLV_NDEF;
418
419                 if (ndef->length < 0xff) {
420                         ndef_with_header->data[1] = ndef->length;
421                 } else {
422                         ndef_with_header->data[1] = 0xff;
423                         ndef_with_header->data[2] =
424                                         (uint8_t)(ndef->length >> 8);
425                         ndef_with_header->data[3] = (uint8_t)(ndef->length);
426                 }
427
428                 memcpy(ndef_with_header->data + tlv_len_size - 1, ndef->data,
429                                 ndef->length);
430                 ndef_with_header->data[ndef->length + tlv_len_size - 1] =
431                                                                         TLV_END;
432                 break;
433
434         case NFC_PROTO_FELICA:
435                 ndef_with_header = g_try_malloc0(sizeof(
436                                         struct near_ndef_message));
437                 if (!ndef_with_header)
438                         goto fail;
439
440                 ndef_with_header->offset = 0;
441                 ndef_with_header->length = ndef->length;
442                 ndef_with_header->data = g_try_malloc0(
443                                                 ndef_with_header->length);
444                 if (!ndef_with_header->data)
445                         goto fail;
446
447                 memcpy(ndef_with_header->data, ndef->data, ndef->length);
448
449                 break;
450
451         case NFC_PROTO_ISO14443:
452                 ndef_with_header = g_try_malloc0(sizeof(
453                                         struct near_ndef_message));
454                 if (!ndef_with_header)
455                         goto fail;
456
457                 ndef_with_header->offset = 0;
458                 ndef_with_header->length = ndef->length + 2;
459                 ndef_with_header->data = g_try_malloc0(ndef->length + 2);
460                 if (!ndef_with_header->data)
461                         goto fail;
462
463                 ndef_with_header->data[0] = (uint8_t)(ndef->length >> 8);
464                 ndef_with_header->data[1] = (uint8_t)(ndef->length);
465                 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
466
467                 break;
468
469         default:
470                 g_free(ndef->data);
471                 g_free(ndef);
472
473                 return __near_error_failed(msg, EOPNOTSUPP);
474         }
475
476         g_free(ndef->data);
477         g_free(ndef);
478
479         tag->write_ndef = ndef_with_header;
480         err = __near_tag_write(tag, ndef_with_header, write_cb);
481         if (err < 0) {
482                 g_free(ndef_with_header->data);
483                 g_free(ndef_with_header);
484
485                 return __near_error_failed(msg, -err);
486         }
487
488         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
489
490 fail:
491         dbus_message_unref(tag->write_msg);
492         tag->write_msg = NULL;
493
494         return __near_error_failed(msg, ENOMEM);
495 }
496
497 static const GDBusMethodTable tag_methods[] = {
498         { GDBUS_METHOD("GetProperties",
499                                 NULL, GDBUS_ARGS({"properties", "a{sv}"}),
500                                 get_properties) },
501         { GDBUS_METHOD("SetProperty",
502                                 GDBUS_ARGS({"name", "s"}, {"value", "v"}),
503                                 NULL, set_property) },
504         { GDBUS_ASYNC_METHOD("Write", GDBUS_ARGS({"attributes", "a{sv}"}),
505                                                         NULL, write_ndef) },
506         { },
507 };
508
509 static const GDBusSignalTable tag_signals[] = {
510         { GDBUS_SIGNAL("PropertyChanged",
511                                 GDBUS_ARGS({"name", "s"}, {"value", "v"})) },
512         { }
513 };
514
515
516 void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter)
517 {
518         GList *list;
519
520         for (list = tag->records; list; list = list->next) {
521                 struct near_ndef_record *record = list->data;
522                 char *path;
523
524                 path = __near_ndef_record_get_path(record);
525                 if (!path)
526                         continue;
527
528                 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
529                                                         &path);
530         }
531 }
532
533 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
534                                 NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
535 #define NFC_TAG_A_TYPE2      0x00
536 #define NFC_TAG_A_TYPE4      0x01
537 #define NFC_TAG_A_NFC_DEP    0x02
538 #define NFC_TAG_A_TYPE4_DEP  0x03
539
540 #define NFC_TAG_A_SENS_RES_SSD_JEWEL      0x00
541 #define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c
542
543 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
544 #define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2)
545 #define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f)
546 #define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8)
547
548 static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res)
549 {
550         switch (sel_res) {
551         case 0x00:
552                 return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT;
553         case 0x08:
554                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K;
555         case 0x09:
556                 return NEAR_TAG_NFC_T2_MIFARE_MINI;
557         case 0x18:
558                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K;
559         case 0x20:
560                 return NEAR_TAG_NFC_T2_MIFARE_DESFIRE;
561         case 0x28:
562                 return NEAR_TAG_NFC_T2_JCOP30;
563         case 0x38:
564                 return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL;
565         case 0x88:
566                 return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON;
567         case 0x98:
568                 return NEAR_TAG_NFC_T2_MPCOS;
569         }
570
571         return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
572 }
573
574 static void set_tag_type(struct near_tag *tag,
575                                 uint16_t sens_res, uint8_t sel_res)
576 {
577         uint8_t platconf, ssd, proto;
578
579         DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol,
580                                                         sens_res, sel_res);
581
582         switch (tag->protocol) {
583         case NFC_PROTO_JEWEL_MASK:
584                 platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res);
585                 ssd = NFC_TAG_A_SENS_RES_SSD(sens_res);
586
587                 DBG("Jewel");
588
589                 if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) &&
590                                 (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL))
591                         tag->type = NFC_PROTO_JEWEL;
592                 break;
593
594         case NFC_PROTO_MIFARE_MASK:
595         case NFC_PROTO_ISO14443_MASK:
596                 proto = NFC_TAG_A_SEL_PROT(sel_res);
597
598                 DBG("proto 0x%x", proto);
599
600                 switch (proto) {
601                 case NFC_TAG_A_TYPE2:
602                         tag->type = NFC_PROTO_MIFARE;
603                         tag->sub_type = get_tag_type2_sub_type(sel_res);
604                         break;
605                 case NFC_TAG_A_TYPE4:
606                         tag->type = NFC_PROTO_ISO14443;
607                         break;
608                 case NFC_TAG_A_TYPE4_DEP:
609                         tag->type = NFC_PROTO_NFC_DEP;
610                         break;
611                 }
612                 break;
613
614         case NFC_PROTO_FELICA_MASK:
615                 tag->type = NFC_PROTO_FELICA;
616                 break;
617
618         case NFC_PROTO_ISO14443_B_MASK:
619                 tag->type = NFC_PROTO_ISO14443_B;
620                 break;
621
622         default:
623                 tag->type = NFC_PROTO_MAX;
624                 break;
625         }
626
627         DBG("tag type 0x%x", tag->type);
628 }
629
630 static int tag_initialize(struct near_tag *tag,
631                         uint32_t adapter_idx, uint32_t target_idx,
632                         uint32_t protocols,
633                         uint16_t sens_res, uint8_t sel_res,
634                         uint8_t *nfcid, uint8_t nfcid_len)
635 {
636         DBG("");
637
638         tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
639                                         adapter_idx, target_idx);
640         if (!tag->path)
641                 return -ENOMEM;
642         tag->adapter_idx = adapter_idx;
643         tag->target_idx = target_idx;
644         tag->protocol = protocols;
645         tag->n_records = 0;
646         tag->readonly = false;
647
648         if (nfcid_len <= NFC_MAX_NFCID1_LEN) {
649                 tag->nfcid_len = nfcid_len;
650                 memcpy(tag->nfcid, nfcid, nfcid_len);
651         }
652
653         set_tag_type(tag, sens_res, sel_res);
654
655         return 0;
656 }
657
658 struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx,
659                                 uint32_t protocols,
660                                 uint16_t sens_res, uint8_t sel_res,
661                                 uint8_t *nfcid, uint8_t nfcid_len)
662 {
663         struct near_tag *tag;
664         char *path;
665
666         tag = near_tag_get_tag(adapter_idx, target_idx);
667         if (tag)
668                 return NULL;
669
670         tag = g_try_malloc0(sizeof(struct near_tag));
671         if (!tag)
672                 return NULL;
673
674         if (tag_initialize(tag, adapter_idx, target_idx,
675                                 protocols,
676                                 sens_res, sel_res,
677                                 nfcid, nfcid_len) < 0) {
678                 g_free(tag);
679                 return NULL;
680         }
681
682         path = g_strdup(tag->path);
683         if (!path) {
684                 g_free(tag);
685                 return NULL;
686         }
687
688         g_hash_table_insert(tag_hash, path, tag);
689
690         DBG("connection %p", connection);
691
692         g_dbus_register_interface(connection, tag->path,
693                                         NFC_TAG_INTERFACE,
694                                         tag_methods, tag_signals,
695                                                         NULL, tag, NULL);
696
697         return tag;
698 }
699
700 void __near_tag_remove(struct near_tag *tag)
701 {
702         char *path = tag->path;
703
704         DBG("path %s", tag->path);
705
706         if (!g_hash_table_lookup(tag_hash, tag->path))
707                 return;
708
709         g_dbus_unregister_interface(connection, tag->path,
710                                                 NFC_TAG_INTERFACE);
711
712         g_hash_table_remove(tag_hash, path);
713 }
714
715 const char *__near_tag_get_path(struct near_tag *tag)
716 {
717         return tag->path;
718 }
719
720 uint32_t __near_tag_get_type(struct near_tag *tag)
721 {
722         return tag->type;
723 }
724
725 enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx,
726                                 uint32_t target_idx)
727
728 {
729         struct near_tag *tag;
730
731         tag = near_tag_get_tag(adapter_idx, target_idx);
732         if (!tag)
733                 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
734
735         return tag->sub_type;
736 }
737
738 uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx,
739                                 uint8_t *nfcid_len)
740 {
741         struct near_tag *tag;
742         uint8_t *nfcid;
743
744         tag = near_tag_get_tag(adapter_idx, target_idx);
745         if (!tag)
746                 goto fail;
747
748         nfcid = g_try_malloc0(tag->nfcid_len);
749         if (!nfcid)
750                 goto fail;
751
752         memcpy(nfcid, tag->nfcid, tag->nfcid_len);
753         *nfcid_len = tag->nfcid_len;
754
755         return nfcid;
756
757 fail:
758         *nfcid_len = 0;
759         return NULL;
760 }
761
762 int near_tag_set_nfcid(uint32_t adapter_idx, uint32_t target_idx,
763                                         uint8_t *nfcid, size_t nfcid_len)
764 {
765         struct near_tag *tag;
766
767         DBG("NFCID len %zd", nfcid_len);
768
769         tag = near_tag_get_tag(adapter_idx, target_idx);
770         if (!tag)
771                 return -ENODEV;
772
773         if (tag->nfcid_len > 0)
774                 return -EALREADY;
775
776         if (nfcid_len > NFC_MAX_NFCID1_LEN)
777                 return -EINVAL;
778
779         memcpy(tag->nfcid, nfcid, nfcid_len);
780         tag->nfcid_len = nfcid_len;
781
782         return 0;
783 }
784
785 int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx,
786                         uint8_t *data, size_t data_length)
787 {
788         struct near_tag *tag;
789
790         tag = near_tag_get_tag(adapter_idx, target_idx);
791         if (!tag)
792                 return -ENODEV;
793
794         tag->data_length = data_length;
795         tag->data = g_try_malloc0(data_length);
796         if (!tag->data)
797                 return -ENOMEM;
798
799         if (data)
800                 memcpy(tag->data, data, data_length);
801
802         return 0;
803 }
804
805 int near_tag_add_records(struct near_tag *tag, GList *records,
806                                 near_tag_io_cb cb, int status)
807 {
808         GList *list;
809         struct near_ndef_record *record;
810         char *path;
811
812         DBG("records %p", records);
813
814         for (list = records; list; list = list->next) {
815                 record = list->data;
816
817                 path = g_strdup_printf("%s/nfc%d/tag%d/record%d",
818                                         NFC_PATH, tag->adapter_idx,
819                                         tag->target_idx, tag->n_records);
820
821                 if (!path)
822                         continue;
823
824                 __near_ndef_record_register(record, path);
825
826                 tag->n_records++;
827                 tag->records = g_list_append(tag->records, record);
828         }
829
830         __near_agent_ndef_parse_records(tag->records);
831
832         near_dbus_property_changed_array(tag->path,
833                                         NFC_TAG_INTERFACE, "Records",
834                                         DBUS_TYPE_OBJECT_PATH, append_records,
835                                         tag);
836
837         if (cb)
838                 cb(tag->adapter_idx, tag->target_idx, status);
839
840         g_list_free(records);
841
842         return 0;
843 }
844
845 void near_tag_set_ro(struct near_tag *tag, bool readonly)
846 {
847         tag->readonly = readonly;
848 }
849
850 void near_tag_set_blank(struct near_tag *tag, bool blank)
851 {
852         tag->blank = blank;
853 }
854
855 bool near_tag_get_blank(struct near_tag *tag)
856 {
857         return tag->blank;
858 }
859
860 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
861 {
862         if (!data_length)
863                 return NULL;
864
865         *data_length = tag->data_length;
866
867         return tag->data;
868 }
869
870 size_t near_tag_get_data_length(struct near_tag *tag)
871 {
872         return tag->data_length;
873 }
874
875 uint32_t near_tag_get_adapter_idx(struct near_tag *tag)
876 {
877         return tag->adapter_idx;
878 }
879
880 uint32_t near_tag_get_target_idx(struct near_tag *tag)
881 {
882         return tag->target_idx;
883 }
884
885 enum near_tag_memory_layout near_tag_get_memory_layout(struct near_tag *tag)
886 {
887         if (!tag)
888                 return NEAR_TAG_MEMORY_UNKNOWN;
889
890         return tag->layout;
891 }
892
893 void near_tag_set_memory_layout(struct near_tag *tag,
894                                         enum near_tag_memory_layout layout)
895 {
896         if (!tag)
897                 return;
898
899         tag->layout = layout;
900 }
901
902 void near_tag_set_max_ndef_size(struct near_tag *tag, uint16_t size)
903 {
904         if (!tag)
905                 return;
906
907         tag->t4.max_ndef_size = size;
908 }
909
910 uint16_t near_tag_get_max_ndef_size(struct near_tag *tag)
911 {
912         if (!tag)
913                 return 0;
914
915         return tag->t4.max_ndef_size;
916 }
917
918 void near_tag_set_c_apdu_max_size(struct near_tag *tag, uint16_t size)
919 {
920         if (!tag)
921                 return;
922
923         tag->t4.c_apdu_max_size = size;
924 }
925
926 uint16_t near_tag_get_c_apdu_max_size(struct near_tag *tag)
927 {
928         if (!tag)
929                 return 0;
930
931         return tag->t4.c_apdu_max_size;
932 }
933
934 void near_tag_set_idm(struct near_tag *tag, uint8_t *idm, uint8_t len)
935 {
936         if (!tag || len > TYPE3_IDM_LEN)
937                 return;
938
939         memset(tag->t3.IDm, 0, TYPE3_IDM_LEN);
940         memcpy(tag->t3.IDm, idm, len);
941 }
942
943 uint8_t *near_tag_get_idm(struct near_tag *tag, uint8_t *len)
944 {
945         if (!tag || !len)
946                 return NULL;
947
948         *len = TYPE3_IDM_LEN;
949         return tag->t3.IDm;
950 }
951
952 void near_tag_set_attr_block(struct near_tag *tag, uint8_t *attr, uint8_t len)
953 {
954         if (!tag || len > TYPE3_ATTR_BLOCK_SIZE)
955                 return;
956
957         memset(tag->t3.attr, 0, TYPE3_ATTR_BLOCK_SIZE);
958         memcpy(tag->t3.attr, attr, len);
959 }
960
961 uint8_t *near_tag_get_attr_block(struct near_tag *tag, uint8_t *len)
962 {
963         if (!tag || !len)
964                 return NULL;
965
966         *len = TYPE3_ATTR_BLOCK_SIZE;
967         return tag->t3.attr;
968 }
969
970 void near_tag_set_ic_type(struct near_tag *tag, uint8_t ic_type)
971 {
972         if (!tag)
973                 return;
974
975         tag->t3.ic_type = ic_type;
976 }
977
978 uint8_t near_tag_get_ic_type(struct near_tag *tag)
979 {
980         if (!tag)
981                 return 0;
982
983         return tag->t3.ic_type;
984 }
985
986 static gint cmp_prio(gconstpointer a, gconstpointer b)
987 {
988         const struct near_tag_driver *driver1 = a;
989         const struct near_tag_driver *driver2 = b;
990
991         return driver2->priority - driver1->priority;
992 }
993
994 int near_tag_driver_register(struct near_tag_driver *driver)
995 {
996         DBG("");
997
998         if (!driver->read)
999                 return -EINVAL;
1000
1001         driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
1002
1003         return 0;
1004 }
1005
1006 void near_tag_driver_unregister(struct near_tag_driver *driver)
1007 {
1008         DBG("");
1009
1010         driver_list = g_slist_remove(driver_list, driver);
1011 }
1012
1013 int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
1014 {
1015         GSList *list;
1016
1017         DBG("type 0x%x", tag->type);
1018
1019         /* Stop check presence while reading */
1020         __near_adapter_stop_check_presence(tag->adapter_idx, tag->target_idx);
1021
1022         for (list = driver_list; list; list = list->next) {
1023                 struct near_tag_driver *driver = list->data;
1024
1025                 DBG("driver type 0x%x", driver->type);
1026
1027                 if (driver->type == tag->type)
1028                         return driver->read(tag->adapter_idx, tag->target_idx,
1029                                                                         cb);
1030         }
1031
1032         return 0;
1033 }
1034
1035 int __near_tag_write(struct near_tag *tag,
1036                                 struct near_ndef_message *ndef,
1037                                 near_tag_io_cb cb)
1038 {
1039         GSList *list;
1040         int err;
1041
1042         DBG("type 0x%x", tag->type);
1043
1044         for (list = driver_list; list; list = list->next) {
1045                 struct near_tag_driver *driver = list->data;
1046
1047                 DBG("driver type 0x%x", driver->type);
1048
1049                 if (driver->type == tag->type) {
1050                         /* Stop check presence while writing */
1051                         __near_adapter_stop_check_presence(tag->adapter_idx,
1052                                                                 tag->target_idx);
1053
1054                         if (tag->blank && driver->format) {
1055                                 DBG("Blank tag detected, formatting");
1056                                 err = driver->format(tag->adapter_idx,
1057                                                 tag->target_idx, format_cb);
1058                         } else {
1059                                 err = driver->write(tag->adapter_idx,
1060                                                         tag->target_idx, ndef,
1061                                                         cb);
1062                         }
1063
1064                         break;
1065                 }
1066         }
1067
1068         if (!list)
1069                 err = -EOPNOTSUPP;
1070
1071         if (err < 0)
1072                 __near_adapter_start_check_presence(tag->adapter_idx,
1073                                                         tag->target_idx);
1074
1075         return err;
1076 }
1077
1078 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)
1079 {
1080         GSList *list;
1081
1082         DBG("type 0x%x", tag->type);
1083
1084         for (list = driver_list; list; list = list->next) {
1085                 struct near_tag_driver *driver = list->data;
1086
1087                 DBG("driver type 0x%x", driver->type);
1088
1089                 if (driver->type == tag->type) {
1090                         if (!driver->check_presence)
1091                                 continue;
1092
1093                         return driver->check_presence(tag->adapter_idx, tag->target_idx, cb);
1094                 }
1095         }
1096
1097         return -EOPNOTSUPP;
1098 }
1099
1100 static void free_tag(gpointer data)
1101 {
1102         struct near_tag *tag = data;
1103
1104         DBG("tag %p", tag);
1105
1106         near_ndef_records_free(tag->records);
1107
1108         g_free(tag->path);
1109         g_free(tag->data);
1110         g_free(tag);
1111 }
1112
1113 int __near_tag_init(void)
1114 {
1115         DBG("");
1116
1117         connection = near_dbus_get_connection();
1118
1119         tag_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1120                                                 g_free, free_tag);
1121
1122         return 0;
1123 }
1124
1125 void __near_tag_cleanup(void)
1126 {
1127         DBG("");
1128
1129         g_hash_table_destroy(tag_hash);
1130         tag_hash = NULL;
1131 }