Integrate neard post 0.6 changes - handover code
[profile/ivi/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         near_bool_t 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         near_bool_t 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 == NULL)
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 == NULL)
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 DBusMessage *get_properties(DBusConnection *conn,
185                                         DBusMessage *msg, void *data)
186 {
187         struct near_tag *tag = data;
188         const char *protocol, *type;
189         DBusMessage *reply;
190         DBusMessageIter array, dict;
191
192         DBG("conn %p", conn);
193
194         reply = dbus_message_new_method_return(msg);
195         if (reply == NULL)
196                 return NULL;
197
198         dbus_message_iter_init_append(reply, &array);
199
200         near_dbus_dict_open(&array, &dict);
201
202         type = type_string(tag);
203         if (type != NULL)
204                 near_dbus_dict_append_basic(&dict, "Type",
205                                         DBUS_TYPE_STRING, &type);
206
207         protocol = protocol_string(tag);
208         if (protocol != NULL)
209                 near_dbus_dict_append_basic(&dict, "Protocol",
210                                         DBUS_TYPE_STRING, &protocol);
211
212         near_dbus_dict_append_basic(&dict, "ReadOnly",
213                                         DBUS_TYPE_BOOLEAN, &tag->readonly);
214
215         near_dbus_dict_append_array(&dict, "Records",
216                                 DBUS_TYPE_OBJECT_PATH, append_records, tag);
217
218         near_dbus_dict_close(&array, &dict);
219
220         return reply;
221 }
222
223 static DBusMessage *set_property(DBusConnection *conn,
224                                         DBusMessage *msg, void *data)
225 {
226         DBG("conn %p", conn);
227
228         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
229 }
230
231 static void tag_read_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
232 {
233         __near_adapter_tags_changed(adapter_idx);
234 }
235
236 static void write_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
237 {
238         struct near_tag *tag;
239         DBusConnection *conn;
240         DBusMessage *reply;
241
242         DBG("Write status %d", status);
243
244         conn = near_dbus_get_connection();
245         tag = near_tag_get_tag(adapter_idx, target_idx);
246
247         if (conn == NULL || tag == NULL)
248                 return;
249
250         if (status != 0) {
251                 reply = __near_error_failed(tag->write_msg, EINVAL);
252                 if (reply != NULL)
253                         g_dbus_send_message(conn, reply);
254         } else {
255                 g_dbus_send_reply(conn, tag->write_msg, DBUS_TYPE_INVALID);
256         }
257
258         dbus_message_unref(tag->write_msg);
259         tag->write_msg = NULL;
260
261         near_ndef_records_free(tag->records);
262         tag->n_records = 0;
263         tag->records = NULL;
264         g_free(tag->data);
265
266         if (status == 0)
267                 __near_tag_read(tag, tag_read_cb);
268 }
269
270 static void format_cb(uint32_t adapter_idx, uint32_t target_idx, int status)
271 {
272         struct near_tag *tag;
273         int err;
274
275         DBG("format status %d", status);
276
277         tag = near_tag_get_tag(adapter_idx, target_idx);
278         if (tag == NULL)
279                 return;
280
281         if (tag->write_msg == NULL)
282                 return;
283
284         if (status == 0) {
285                 err = __near_tag_write(tag, tag->write_ndef,
286                                                 write_cb);
287                 if (err < 0)
288                         goto error;
289         } else {
290                 err = status;
291                 goto error;
292         }
293
294         return;
295
296 error:
297         write_cb(tag->adapter_idx, tag->target_idx, err);
298 }
299
300 static DBusMessage *write_ndef(DBusConnection *conn,
301                                 DBusMessage *msg, void *data)
302 {
303         struct near_tag *tag = data;
304         struct near_ndef_message *ndef, *ndef_with_header = NULL;
305         int err;
306
307         DBG("conn %p", conn);
308
309         if (tag->readonly == TRUE) {
310                 DBG("Read only tag");
311                 return __near_error_permission_denied(msg);
312         }
313
314         if (tag->write_msg)
315                 return __near_error_in_progress(msg);
316
317         ndef = __ndef_build_from_message(msg);
318         if (ndef == NULL)
319                 return __near_error_failed(msg, EINVAL);
320
321         tag->write_msg = dbus_message_ref(msg);
322
323         /* Add NDEF header information depends upon tag type */
324         switch (tag->type) {
325         case NFC_PROTO_JEWEL:
326         case NFC_PROTO_MIFARE:
327                 ndef_with_header = g_try_malloc0(sizeof(
328                                         struct near_ndef_message));
329                 if (ndef_with_header == NULL)
330                         goto fail;
331
332                 ndef_with_header->offset = 0;
333                 ndef_with_header->length = ndef->length + 3;
334                 ndef_with_header->data = g_try_malloc0(ndef->length + 3);
335                 if (ndef_with_header->data == NULL)
336                         goto fail;
337
338                 ndef_with_header->data[0] = TLV_NDEF;
339                 ndef_with_header->data[1] = ndef->length;
340                 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
341                 ndef_with_header->data[ndef->length + 2] = TLV_END;
342
343                 break;
344
345         case NFC_PROTO_FELICA:
346                 ndef_with_header = g_try_malloc0(sizeof(
347                                         struct near_ndef_message));
348                 if (ndef_with_header == NULL)
349                         goto fail;
350
351                 ndef_with_header->offset = 0;
352                 ndef_with_header->length = ndef->length;
353                 ndef_with_header->data = g_try_malloc0(
354                                                 ndef_with_header->length);
355                 if (ndef_with_header->data == NULL)
356                         goto fail;
357
358                 memcpy(ndef_with_header->data, ndef->data, ndef->length);
359
360                 break;
361
362         case NFC_PROTO_ISO14443:
363                 ndef_with_header = g_try_malloc0(sizeof(
364                                         struct near_ndef_message));
365                 if (ndef_with_header == NULL)
366                         goto fail;
367
368                 ndef_with_header->offset = 0;
369                 ndef_with_header->length = ndef->length + 2;
370                 ndef_with_header->data = g_try_malloc0(ndef->length + 2);
371                 if (ndef_with_header->data == NULL)
372                         goto fail;
373
374                 ndef_with_header->data[0] = (uint8_t)(ndef->length >> 8);
375                 ndef_with_header->data[1] = (uint8_t)(ndef->length);
376                 memcpy(ndef_with_header->data + 2, ndef->data, ndef->length);
377
378                 break;
379
380         default:
381                 g_free(ndef->data);
382                 g_free(ndef);
383
384                 return __near_error_failed(msg, EOPNOTSUPP);
385         }
386
387         g_free(ndef->data);
388         g_free(ndef);
389
390         tag->write_ndef = ndef_with_header;
391         err = __near_tag_write(tag, ndef_with_header, write_cb);
392         if (err < 0) {
393                 g_free(ndef_with_header->data);
394                 g_free(ndef_with_header);
395
396                 return __near_error_failed(msg, -err);
397         }
398
399         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
400
401 fail:
402         dbus_message_unref(tag->write_msg);
403         tag->write_msg = NULL;
404
405         return __near_error_failed(msg, ENOMEM);
406 }
407
408 static const GDBusMethodTable tag_methods[] = {
409         { GDBUS_METHOD("GetProperties",
410                                 NULL, GDBUS_ARGS({"properties", "a{sv}"}),
411                                 get_properties) },
412         { GDBUS_METHOD("SetProperty",
413                                 GDBUS_ARGS({"name", "s"}, {"value", "v"}),
414                                 NULL, set_property) },
415         { GDBUS_ASYNC_METHOD("Write", GDBUS_ARGS({"attributes", "a{sv}"}),
416                                                         NULL, write_ndef) },
417         { },
418 };
419
420 static const GDBusSignalTable tag_signals[] = {
421         { GDBUS_SIGNAL("PropertyChanged",
422                                 GDBUS_ARGS({"name", "s"}, {"value", "v"})) },
423         { }
424 };
425
426
427 void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter)
428 {
429         GList *list;
430
431         for (list = tag->records; list; list = list->next) {
432                 struct near_ndef_record *record = list->data;
433                 char *path;
434
435                 path = __near_ndef_record_get_path(record);
436                 if (path == NULL)
437                         continue;
438
439                 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
440                                                         &path);
441         }
442 }
443
444 #define NFC_TAG_A (NFC_PROTO_ISO14443_MASK | NFC_PROTO_NFC_DEP_MASK | \
445                                 NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
446 #define NFC_TAG_A_TYPE2      0x00
447 #define NFC_TAG_A_TYPE4      0x01
448 #define NFC_TAG_A_NFC_DEP    0x02
449 #define NFC_TAG_A_TYPE4_DEP  0x03
450
451 #define NFC_TAG_A_SENS_RES_SSD_JEWEL      0x00
452 #define NFC_TAG_A_SENS_RES_PLATCONF_JEWEL 0x0c
453
454 #define NFC_TAG_A_SEL_PROT(sel_res) (((sel_res) & 0x60) >> 5)
455 #define NFC_TAG_A_SEL_CASCADE(sel_res) (((sel_res) & 0x04) >> 2)
456 #define NFC_TAG_A_SENS_RES_SSD(sens_res) ((sens_res) & 0x001f)
457 #define NFC_TAG_A_SENS_RES_PLATCONF(sens_res) (((sens_res) & 0x0f00) >> 8)
458
459 static enum near_tag_sub_type get_tag_type2_sub_type(uint8_t sel_res)
460 {
461         switch(sel_res) {
462         case 0x00 :
463                 return NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT;
464         case 0x08:
465                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K;
466         case 0x09:
467                 return NEAR_TAG_NFC_T2_MIFARE_MINI;
468         case 0x18:
469                 return NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K;
470         case 0x20:
471                 return NEAR_TAG_NFC_T2_MIFARE_DESFIRE;
472         case 0x28 :
473                 return NEAR_TAG_NFC_T2_JCOP30;
474         case 0x38:
475                 return NEAR_TAG_NFC_T2_MIFARE_4K_EMUL;
476         case 0x88:
477                 return NEAR_TAG_NFC_T2_MIFARE_1K_INFINEON;
478         case 0x98:
479                 return NEAR_TAG_NFC_T2_MPCOS;
480         }
481
482         return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
483 }
484
485 static void set_tag_type(struct near_tag *tag,
486                                 uint16_t sens_res, uint8_t sel_res)
487 {
488         uint8_t platconf, ssd, proto;
489
490         DBG("protocol 0x%x sens_res 0x%x sel_res 0x%x", tag->protocol,
491                                                         sens_res, sel_res);
492
493         switch (tag->protocol) {
494         case NFC_PROTO_JEWEL_MASK:
495                 platconf = NFC_TAG_A_SENS_RES_PLATCONF(sens_res);
496                 ssd = NFC_TAG_A_SENS_RES_SSD(sens_res);
497
498                 DBG("Jewel");
499
500                 if ((ssd == NFC_TAG_A_SENS_RES_SSD_JEWEL) &&
501                                 (platconf == NFC_TAG_A_SENS_RES_PLATCONF_JEWEL))
502                         tag->type = NFC_PROTO_JEWEL;
503                 break;
504
505         case NFC_PROTO_MIFARE_MASK:
506         case NFC_PROTO_ISO14443_MASK:
507                 proto = NFC_TAG_A_SEL_PROT(sel_res);
508
509                 DBG("proto 0x%x", proto);
510
511                 switch(proto) {
512                 case NFC_TAG_A_TYPE2:
513                         tag->type = NFC_PROTO_MIFARE;
514                         tag->sub_type = get_tag_type2_sub_type(sel_res);
515                         break;
516                 case NFC_TAG_A_TYPE4:
517                         tag->type = NFC_PROTO_ISO14443;
518                         break;
519                 case NFC_TAG_A_TYPE4_DEP:
520                         tag->type = NFC_PROTO_NFC_DEP;
521                         break;
522                 }
523                 break;
524
525         case NFC_PROTO_FELICA_MASK:
526                 tag->type = NFC_PROTO_FELICA;
527                 break;
528
529         default:
530                 tag->type = NFC_PROTO_MAX;
531                 break;
532         }
533
534         DBG("tag type 0x%x", tag->type);
535 }
536
537 static int tag_initialize(struct near_tag *tag,
538                         uint32_t adapter_idx, uint32_t target_idx,
539                         uint32_t protocols,
540                         uint16_t sens_res, uint8_t sel_res,
541                         uint8_t *nfcid, uint8_t nfcid_len)
542 {
543         DBG("");
544
545         tag->path = g_strdup_printf("%s/nfc%d/tag%d", NFC_PATH,
546                                         adapter_idx, target_idx);
547         if (tag->path == NULL)
548                 return -ENOMEM;
549         tag->adapter_idx = adapter_idx;
550         tag->target_idx = target_idx;
551         tag->protocol = protocols;
552         tag->n_records = 0;
553         tag->readonly = FALSE;
554
555         if (nfcid_len <= NFC_MAX_NFCID1_LEN) {
556                 tag->nfcid_len = nfcid_len;
557                 memcpy(tag->nfcid, nfcid, nfcid_len);
558         }
559
560         set_tag_type(tag, sens_res, sel_res);
561
562         return 0;
563 }
564
565 struct near_tag *__near_tag_add(uint32_t adapter_idx, uint32_t target_idx,
566                                 uint32_t protocols,
567                                 uint16_t sens_res, uint8_t sel_res,
568                                 uint8_t *nfcid, uint8_t nfcid_len)
569 {
570         struct near_tag *tag;
571         char *path;
572
573         tag = near_tag_get_tag(adapter_idx, target_idx);
574         if (tag != NULL)
575                 return NULL;
576
577         tag = g_try_malloc0(sizeof(struct near_tag));
578         if (tag == NULL)
579                 return NULL;
580
581         if (tag_initialize(tag, adapter_idx, target_idx,
582                                 protocols,
583                                 sens_res, sel_res,
584                                 nfcid, nfcid_len) < 0) {
585                 g_free(tag);
586                 return NULL;
587         }
588
589         path = g_strdup(tag->path);
590         if (path == NULL) {
591                 g_free(tag);
592                 return NULL;
593         }
594
595         g_hash_table_insert(tag_hash, path, tag);
596
597         DBG("connection %p", connection);
598
599         g_dbus_register_interface(connection, tag->path,
600                                         NFC_TAG_INTERFACE,
601                                         tag_methods, tag_signals,
602                                                         NULL, tag, NULL);
603
604         return tag;
605 }
606
607 void __near_tag_remove(struct near_tag *tag)
608 {
609         char *path = tag->path;
610
611         DBG("path %s", tag->path);
612
613         if (g_hash_table_lookup(tag_hash, tag->path) == NULL)
614                 return;
615
616         g_dbus_unregister_interface(connection, tag->path,
617                                                 NFC_TAG_INTERFACE);
618
619         g_hash_table_remove(tag_hash, path);
620 }
621
622 const char *__near_tag_get_path(struct near_tag *tag)
623 {
624         return tag->path;
625 }
626
627 uint32_t __near_tag_get_type(struct near_tag *tag)
628 {
629         return tag->type;
630 }
631
632 enum near_tag_sub_type near_tag_get_subtype(uint32_t adapter_idx,
633                                 uint32_t target_idx)
634
635 {
636         struct near_tag *tag;
637
638         tag = near_tag_get_tag(adapter_idx, target_idx);
639         if (tag == NULL)
640                 return NEAR_TAG_NFC_SUBTYPE_UNKNOWN;
641
642         return tag->sub_type;
643 }
644
645 uint8_t *near_tag_get_nfcid(uint32_t adapter_idx, uint32_t target_idx,
646                                 uint8_t *nfcid_len)
647 {
648         struct near_tag *tag;
649         uint8_t *nfcid;
650
651         tag = near_tag_get_tag(adapter_idx, target_idx);
652         if (tag == NULL)
653                 goto fail;
654
655         nfcid = g_try_malloc0(tag->nfcid_len);
656         if (nfcid == NULL)
657                 goto fail;
658
659         memcpy(nfcid, tag->nfcid, tag->nfcid_len);
660         *nfcid_len = tag->nfcid_len;
661
662         return nfcid;
663
664 fail:
665         *nfcid_len = 0;
666         return NULL;
667 }
668
669 int near_tag_set_nfcid(uint32_t adapter_idx, uint32_t target_idx,
670                                         uint8_t *nfcid, size_t nfcid_len)
671 {
672         struct near_tag *tag;
673
674         DBG("NFCID len %zd", nfcid_len);
675
676         tag = near_tag_get_tag(adapter_idx, target_idx);
677         if (tag == NULL)
678                 return -ENODEV;
679
680         if (tag->nfcid_len > 0)
681                 return -EALREADY;
682
683         if (nfcid_len > NFC_MAX_NFCID1_LEN)
684                 return -EINVAL;
685
686         memcpy(tag->nfcid, nfcid, nfcid_len);
687         tag->nfcid_len = nfcid_len;
688
689         return 0;
690 }
691
692 int near_tag_add_data(uint32_t adapter_idx, uint32_t target_idx,
693                         uint8_t *data, size_t data_length)
694 {
695         struct near_tag *tag;
696
697         tag = near_tag_get_tag(adapter_idx, target_idx);
698         if (tag == NULL)
699                 return -ENODEV;
700
701         tag->data_length = data_length;
702         tag->data = g_try_malloc0(data_length);
703         if (tag->data == NULL)
704                 return -ENOMEM;
705
706         if (data != NULL)
707                 memcpy(tag->data, data, data_length);
708
709         return 0;
710 }
711
712 int near_tag_add_records(struct near_tag *tag, GList *records,
713                                 near_tag_io_cb cb, int status)
714 {
715         GList *list;
716         struct near_ndef_record *record;
717         char *path;
718
719         DBG("records %p", records);
720
721         for (list = records; list; list = list->next) {
722                 record = list->data;
723
724                 path = g_strdup_printf("%s/nfc%d/tag%d/record%d",
725                                         NFC_PATH, tag->adapter_idx,
726                                         tag->target_idx, tag->n_records);
727
728                 if (path == NULL)
729                         continue;
730
731                 __near_ndef_record_register(record, path);
732
733                 tag->n_records++;
734                 tag->records = g_list_append(tag->records, record);
735         }
736
737         __near_agent_ndef_parse_records(tag->records);
738
739         if (cb != NULL)
740                 cb(tag->adapter_idx, tag->target_idx, status);
741
742         g_list_free(records);
743
744         return 0;
745 }
746
747 void near_tag_set_ro(struct near_tag *tag, near_bool_t readonly)
748 {
749         tag->readonly = readonly;
750 }
751
752 void near_tag_set_blank(struct near_tag *tag, near_bool_t blank)
753 {
754         tag->blank = blank;
755 }
756
757 uint8_t *near_tag_get_data(struct near_tag *tag, size_t *data_length)
758 {
759         if (data_length == NULL)
760                 return NULL;
761
762         *data_length = tag->data_length;
763
764         return tag->data;
765 }
766
767 uint32_t near_tag_get_adapter_idx(struct near_tag *tag)
768 {
769         return tag->adapter_idx;
770 }
771
772 uint32_t near_tag_get_target_idx(struct near_tag *tag)
773 {
774         return tag->target_idx;
775 }
776
777 enum near_tag_memory_layout near_tag_get_memory_layout(struct near_tag *tag)
778 {
779         if (tag == NULL)
780                 return NEAR_TAG_MEMORY_UNKNOWN;
781
782         return tag->layout;
783 }
784
785 void near_tag_set_memory_layout(struct near_tag *tag,
786                                         enum near_tag_memory_layout layout)
787 {
788         if (tag == NULL)
789                 return;
790
791         tag->layout = layout;
792 }
793
794 void near_tag_set_max_ndef_size(struct near_tag *tag, uint16_t size)
795 {
796         if (tag == NULL)
797                 return;
798
799         tag->t4.max_ndef_size = size;
800 }
801
802 uint16_t near_tag_get_max_ndef_size(struct near_tag *tag)
803 {
804         if (tag == NULL)
805                 return 0;
806
807         return tag->t4.max_ndef_size;
808 }
809
810 void near_tag_set_c_apdu_max_size(struct near_tag *tag, uint16_t size)
811 {
812         if (tag == NULL)
813                 return;
814
815         tag->t4.c_apdu_max_size = size;
816 }
817
818 uint16_t near_tag_get_c_apdu_max_size(struct near_tag *tag)
819 {
820         if (tag == NULL)
821                 return 0;
822
823         return tag->t4.c_apdu_max_size;
824 }
825
826 void near_tag_set_idm(struct near_tag *tag, uint8_t *idm, uint8_t len)
827 {
828         if (tag == NULL || len > TYPE3_IDM_LEN)
829                 return;
830
831         memset(tag->t3.IDm, 0, TYPE3_IDM_LEN);
832         memcpy(tag->t3.IDm, idm, len);
833 }
834
835 uint8_t *near_tag_get_idm(struct near_tag *tag, uint8_t *len)
836 {
837         if (tag == NULL || len == NULL)
838                 return NULL;
839
840         *len = TYPE3_IDM_LEN;
841         return tag->t3.IDm;
842 }
843
844 void near_tag_set_attr_block(struct near_tag *tag, uint8_t *attr, uint8_t len)
845 {
846         if (tag == NULL || len > TYPE3_ATTR_BLOCK_SIZE)
847                 return;
848
849         memset(tag->t3.attr, 0, TYPE3_ATTR_BLOCK_SIZE);
850         memcpy(tag->t3.attr, attr, len);
851 }
852
853 uint8_t *near_tag_get_attr_block(struct near_tag *tag, uint8_t *len)
854 {
855         if (tag == NULL || len == NULL)
856                 return NULL;
857
858         *len = TYPE3_ATTR_BLOCK_SIZE;
859         return tag->t3.attr;
860 }
861
862 void near_tag_set_ic_type(struct near_tag *tag, uint8_t ic_type)
863 {
864         if (tag == NULL)
865                 return;
866
867         tag->t3.ic_type = ic_type;
868 }
869
870 uint8_t near_tag_get_ic_type(struct near_tag *tag)
871 {
872         if (tag == NULL)
873                 return 0;
874
875         return tag->t3.ic_type;
876 }
877
878 static gint cmp_prio(gconstpointer a, gconstpointer b)
879 {
880         const struct near_tag_driver *driver1 = a;
881         const struct near_tag_driver *driver2 = b;
882
883         return driver2->priority - driver1->priority;
884 }
885
886 int near_tag_driver_register(struct near_tag_driver *driver)
887 {
888         DBG("");
889
890         if (driver->read == NULL)
891                 return -EINVAL;
892
893         driver_list = g_slist_insert_sorted(driver_list, driver, cmp_prio);
894
895         return 0;
896 }
897
898 void near_tag_driver_unregister(struct near_tag_driver *driver)
899 {
900         DBG("");
901
902         driver_list = g_slist_remove(driver_list, driver);
903 }
904
905 int __near_tag_read(struct near_tag *tag, near_tag_io_cb cb)
906 {
907         GSList *list;
908
909         DBG("type 0x%x", tag->type);
910
911         for (list = driver_list; list; list = list->next) {
912                 struct near_tag_driver *driver = list->data;
913
914                 DBG("driver type 0x%x", driver->type);
915
916                 if (driver->type == tag->type)
917                         return driver->read(tag->adapter_idx, tag->target_idx,
918                                                                         cb);
919         }
920
921         return 0;
922 }
923
924 int __near_tag_write(struct near_tag *tag,
925                                 struct near_ndef_message *ndef,
926                                 near_tag_io_cb cb)
927 {
928         GSList *list;
929         int err;
930
931         DBG("type 0x%x", tag->type);
932
933         for (list = driver_list; list; list = list->next) {
934                 struct near_tag_driver *driver = list->data;
935
936                 DBG("driver type 0x%x", driver->type);
937
938                 if (driver->type == tag->type) {
939                         if (tag->blank == TRUE && driver->format != NULL) {
940                                 DBG("Blank tag detected, formatting");
941                                 err = driver->format(tag->adapter_idx,
942                                                 tag->target_idx, format_cb);
943                                 if (err < 0)
944                                         return err;
945                         } else {
946                                 return driver->write(tag->adapter_idx,
947                                                 tag->target_idx, ndef,
948                                                 cb);
949                         }
950                 }
951         }
952
953         return 0;
954 }
955
956 int __near_tag_check_presence(struct near_tag *tag, near_tag_io_cb cb)
957 {
958         GSList *list;
959
960         DBG("type 0x%x", tag->type);
961
962         for (list = driver_list; list; list = list->next) {
963                 struct near_tag_driver *driver = list->data;
964
965                 DBG("driver type 0x%x", driver->type);
966
967                 if (driver->type == tag->type) {
968                         if (driver->check_presence == NULL)
969                                 continue;
970
971                         return driver->check_presence(tag->adapter_idx, tag->target_idx, cb);
972                 }
973         }
974
975         return -EOPNOTSUPP;
976 }
977
978 static void free_tag(gpointer data)
979 {
980         struct near_tag *tag = data;
981
982         DBG("tag %p", tag);
983
984         near_ndef_records_free(tag->records);
985
986         g_free(tag->path);
987         g_free(tag->data);
988         g_free(tag);
989 }
990
991 int __near_tag_init(void)
992 {
993         DBG("");
994
995         connection = near_dbus_get_connection();
996
997         tag_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
998                                                 g_free, free_tag);
999
1000         return 0;
1001 }
1002
1003 void __near_tag_cleanup(void)
1004 {
1005         DBG("");
1006
1007         g_hash_table_destroy(tag_hash);
1008         tag_hash = NULL;
1009 }