Integrate neard post 0.6 changes - handover code
[profile/ivi/neard.git] / plugins / nfctype2.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 <stdint.h>
27 #include <errno.h>
28 #include <string.h>
29 #include <sys/socket.h>
30
31 #include <linux/socket.h>
32 #include <linux/nfc.h>
33
34 #include <near/plugin.h>
35 #include <near/log.h>
36 #include <near/types.h>
37 #include <near/adapter.h>
38 #include <near/tag.h>
39 #include <near/ndef.h>
40 #include <near/tlv.h>
41
42 extern int mifare_read(uint32_t adapter_idx, uint32_t target_idx,
43                 near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);
44
45 extern int mifare_check_presence(uint32_t adapter_idx, uint32_t target_idx,
46                         near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);
47
48 extern int mifare_write(uint32_t adapter_idx, uint32_t target_idx,
49                         struct near_ndef_message *ndef,
50                         near_tag_io_cb cb, enum near_tag_sub_type tgt_subtype);
51
52 #define CMD_READ         0x30
53 #define CMD_READ_SIZE    0x02
54
55 #define CMD_WRITE        0xA2
56
57 #define READ_SIZE  16
58 #define BLOCK_SIZE 4
59
60 #define META_BLOCK_START 0
61 #define DATA_BLOCK_START 4
62 #define TYPE2_MAGIC 0xe1
63
64 #define TAG_DATA_CC(data) ((data) + 12)
65 #define TAG_DATA_LENGTH(cc) ((cc)[2] * 8)
66 #define TAG_DATA_NFC(cc) ((cc)[0] & TYPE2_MAGIC)
67
68 #define TYPE2_NOWRITE_ACCESS    0x0F
69 #define TYPE2_READWRITE_ACCESS  0x00
70 #define TAG_T2_WRITE_FLAG(cc) ((cc)[3] & TYPE2_NOWRITE_ACCESS)
71
72 #define NDEF_MAX_SIZE   0x30
73
74 #define CC_BLOCK_START 3
75 #define TYPE2_TAG_VER_1_0  0x10
76 #define TYPE2_DATA_SIZE_48 0x6
77
78 struct type2_cmd {
79         uint8_t cmd;
80         uint8_t block;
81         uint8_t data[BLOCK_SIZE];
82 } __attribute__((packed));
83
84 struct type2_tag {
85         uint32_t adapter_idx;
86         uint16_t current_block;
87
88         near_tag_io_cb cb;
89         struct near_tag *tag;
90 };
91
92 struct t2_cookie {
93         uint32_t adapter_idx;
94         uint32_t target_idx;
95         uint8_t current_block;
96         struct near_ndef_message *ndef;
97         near_tag_io_cb cb;
98 };
99
100 struct type2_cc {
101         uint8_t magic;
102         uint8_t version;
103         uint8_t mem_size;
104         uint8_t read_write;
105 };
106
107 static int t2_cookie_release(int err, void *data)
108 {
109         struct t2_cookie *cookie = data;
110
111         DBG("%p", cookie);
112
113         if (cookie == NULL)
114                 return err;
115
116         if (cookie->ndef)
117                 g_free(cookie->ndef->data);
118
119         g_free(cookie->ndef);
120         g_free(cookie);
121         cookie = NULL;
122
123         return err;
124 }
125
126 static int data_recv(uint8_t *resp, int length, void *data)
127 {
128         struct type2_tag *tag = data;
129         struct type2_cmd cmd;
130         uint8_t *nfc_data;
131         size_t current_length, length_read, data_length;
132         uint32_t adapter_idx;
133         int read_blocks;
134
135         DBG("%d", length);
136
137         if (length < 0) {
138                 g_free(tag);
139
140                 return  length;
141         }
142
143         nfc_data = near_tag_get_data(tag->tag, &data_length);
144         adapter_idx = near_tag_get_adapter_idx(tag->tag);
145
146         length_read = length - NFC_HEADER_SIZE;
147         current_length = tag->current_block * BLOCK_SIZE;
148         if (current_length + length - NFC_HEADER_SIZE > data_length)
149                 length_read = data_length - current_length;
150
151         memcpy(nfc_data + current_length, resp + NFC_HEADER_SIZE, length_read);
152
153         if (current_length + length_read == data_length) {
154                 GList *records;
155
156                 /* TODO parse tag->data for NDEFS, and notify target.c */
157                 tag->current_block = 0;
158
159                 DBG("Done reading");
160
161                 records = near_tlv_parse(nfc_data, data_length);
162                 near_tag_add_records(tag->tag, records, tag->cb, 0);
163
164                 g_free(tag);
165
166                 return 0;
167         }
168
169         read_blocks = length / BLOCK_SIZE;
170         tag->current_block += read_blocks;
171
172         cmd.cmd = CMD_READ;
173         cmd.block = DATA_BLOCK_START + tag->current_block;
174
175         DBG("adapter %d", adapter_idx);
176
177         return near_adapter_send(adapter_idx,
178                                 (uint8_t *) &cmd, CMD_READ_SIZE,
179                                         data_recv, tag);
180 }
181
182 static int data_read(struct type2_tag *tag)
183 {
184         struct type2_cmd cmd;
185         uint32_t adapter_idx;
186
187         DBG("");
188
189         tag->current_block = 0;
190
191         cmd.cmd = CMD_READ;
192         cmd.block = DATA_BLOCK_START;
193
194         adapter_idx = near_tag_get_adapter_idx(tag->tag);
195
196         return near_adapter_send(adapter_idx,
197                                 (uint8_t *) &cmd, CMD_READ_SIZE,
198                                         data_recv, tag);
199 }
200
201 static int meta_recv(uint8_t *resp, int length, void *data)
202 {
203         struct t2_cookie *cookie = data;
204         struct near_tag *tag;
205         struct type2_tag *t2_tag;
206         uint8_t *cc;
207         int err;
208
209         DBG("%d", length);
210
211         if (length < 0) {
212                 err = length;
213                 goto out_err;
214         }
215
216         if (resp[0] != 0) {
217                 err = -EIO;
218                 goto out_err;
219         }
220
221         cc = TAG_DATA_CC(resp + NFC_HEADER_SIZE);
222
223         /* Default to 48 bytes data size in case of blank tag */
224         err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx,
225                         NULL, (TAG_DATA_LENGTH(cc) ? TAG_DATA_LENGTH(cc) :
226                         TYPE2_DATA_SIZE_48 << 3));
227
228         if (err < 0)
229                 goto out_err;
230
231         tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
232         if (tag == NULL) {
233                 err = -ENOMEM;
234                 goto out_err;
235         }
236
237         t2_tag = g_try_malloc0(sizeof(struct type2_tag));
238         if (t2_tag == NULL) {
239                 err = -ENOMEM;
240                 goto out_err;
241         }
242
243         t2_tag->adapter_idx = cookie->adapter_idx;
244         t2_tag->cb = cookie->cb;
245         t2_tag->tag = tag;
246
247         /* Set the ReadWrite flag */
248         if (TAG_T2_WRITE_FLAG(cc) == TYPE2_NOWRITE_ACCESS)
249                 near_tag_set_ro(tag, TRUE);
250         else
251                 near_tag_set_ro(tag, FALSE);
252
253         near_tag_set_memory_layout(tag, NEAR_TAG_MEMORY_STATIC);
254
255         if (TAG_DATA_NFC(cc) == 0) {
256                 DBG("Mark as blank tag");
257                 near_tag_set_blank(tag, TRUE);
258         } else {
259                 near_tag_set_blank(tag, FALSE);
260         }
261
262         err = data_read(t2_tag);
263         if (err < 0)
264                 goto out_tag;
265
266         return t2_cookie_release(err, cookie);
267
268 out_tag:
269         g_free(t2_tag);
270
271 out_err:
272         if (err < 0 && cookie->cb)
273                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
274
275         return t2_cookie_release(err, cookie);
276 }
277
278 static int nfctype2_read_meta(uint32_t adapter_idx, uint32_t target_idx,
279                                                         near_tag_io_cb cb)
280 {
281         struct type2_cmd cmd;
282         struct t2_cookie *cookie;
283         int err;
284
285         DBG("");
286
287         cmd.cmd = CMD_READ;
288         cmd.block = META_BLOCK_START;
289
290         cookie = g_try_malloc0(sizeof(struct t2_cookie));
291         if (cookie == NULL)
292                 return -ENOMEM;
293
294         cookie->adapter_idx = adapter_idx;
295         cookie->target_idx = target_idx;
296         cookie->cb = cb;
297
298         err = near_adapter_send(adapter_idx, (uint8_t *) &cmd, CMD_READ_SIZE,
299                                                         meta_recv, cookie);
300         if (err < 0)
301                 g_free(cookie);
302
303         return err;
304 }
305
306 static int nfctype2_read(uint32_t adapter_idx,
307                                 uint32_t target_idx, near_tag_io_cb cb)
308 {
309         int err;
310         enum near_tag_sub_type tgt_subtype;
311
312         DBG("");
313
314         tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);
315
316         switch (tgt_subtype) {
317         case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
318                 err = nfctype2_read_meta(adapter_idx, target_idx, cb);
319                 break;
320
321         /* Specific Mifare read access */
322         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
323         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
324                 err = mifare_read(adapter_idx, target_idx,
325                         cb, tgt_subtype);
326                 break;
327
328         default:
329                 DBG("Unknown Tag Type 2 subtype %d", tgt_subtype);
330                 err = -1;
331                 break;
332         }
333
334         return err;
335 }
336
337 static int data_write_resp(uint8_t *resp, int length, void *data)
338 {
339         int err;
340         struct t2_cookie *cookie = data;
341         struct type2_cmd cmd;
342
343         DBG("");
344
345         if (length < 0 || resp[0] != 0) {
346                 err = -EIO;
347                 goto out_err;
348         }
349
350         if (cookie->ndef->offset > cookie->ndef->length) {
351                 DBG("Done writing");
352
353                 if (cookie->cb)
354                         cookie->cb(cookie->adapter_idx, cookie->target_idx, 0);
355
356                 return t2_cookie_release(0, cookie);
357         }
358
359         cmd.cmd = CMD_WRITE;
360         cmd.block = cookie->current_block;
361         cookie->current_block++;
362
363         if ((cookie->ndef->offset + BLOCK_SIZE) <
364                         cookie->ndef->length) {
365                 memcpy(cmd.data, cookie->ndef->data +
366                                         cookie->ndef->offset, BLOCK_SIZE);
367                 cookie->ndef->offset += BLOCK_SIZE;
368         } else {
369                 memcpy(cmd.data, cookie->ndef->data + cookie->ndef->offset,
370                                 cookie->ndef->length - cookie->ndef->offset);
371                 cookie->ndef->offset = cookie->ndef->length + 1;
372         }
373
374         err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
375                                         sizeof(cmd), data_write_resp, cookie);
376
377         if (err < 0)
378                 goto out_err;
379
380         return 0;
381
382 out_err:
383         if (err < 0 && cookie->cb)
384                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
385
386         return t2_cookie_release(err, cookie);
387 }
388
389 static int data_write(uint32_t adapter_idx, uint32_t target_idx,
390                                 struct near_ndef_message *ndef,
391                                 near_tag_io_cb cb)
392 {
393         struct type2_cmd cmd;
394         struct t2_cookie *cookie;
395         int err;
396
397         DBG("");
398
399         cookie = g_try_malloc0(sizeof(struct t2_cookie));
400         if (cookie == NULL)
401                 return -ENOMEM;
402
403         cookie->adapter_idx = adapter_idx;
404         cookie->target_idx = target_idx;
405         cookie->current_block = DATA_BLOCK_START;
406         cookie->ndef = ndef;
407         cookie->cb = cb;
408
409         cmd.cmd = CMD_WRITE;
410         cmd.block = cookie->current_block;
411         memcpy(cmd.data, cookie->ndef->data, BLOCK_SIZE);
412         cookie->ndef->offset += BLOCK_SIZE;
413         cookie->current_block++;
414
415         err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
416                                         sizeof(cmd), data_write_resp, cookie);
417
418         if (err < 0)
419                 goto out_err;
420
421         return 0;
422
423 out_err:
424         return t2_cookie_release(err, cookie);
425 }
426
427 static int nfctype2_write(uint32_t adapter_idx, uint32_t target_idx,
428                                 struct near_ndef_message *ndef,
429                                 near_tag_io_cb cb)
430 {
431         struct near_tag *tag;
432         enum near_tag_sub_type tgt_subtype;
433         int err;
434
435         DBG("");
436
437         if (ndef == NULL || cb == NULL)
438                 return -EINVAL;
439
440         tag = near_tag_get_tag(adapter_idx, target_idx);
441         if (tag == NULL)
442                 return -EINVAL;
443
444         tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);
445
446         switch (tgt_subtype) {
447         case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
448                 /*
449                  * This check is valid for only static tags.
450                  * Max data length on Type 2 Tag
451                  * including TLV's is NDEF_MAX_SIZE
452                  */
453                 if (near_tag_get_memory_layout(tag) == NEAR_TAG_MEMORY_STATIC) {
454                         if ((ndef->length + 3) > NDEF_MAX_SIZE) {
455                                 near_error("not enough space on tag");
456                                 return -ENOSPC;
457                         }
458                 }
459
460                 err = data_write(adapter_idx, target_idx, ndef, cb);
461                 break;
462                 /* Specific Mifare write access */
463         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
464         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
465                 err = mifare_write(adapter_idx, target_idx, ndef,
466                                 cb, tgt_subtype);
467                 break;
468         default:
469                 DBG("Unknown TAG Type 2 subtype %d", tgt_subtype);
470                 err = -EINVAL;
471                 break;
472         }
473
474         return err;
475 }
476
477 static int check_presence(uint8_t *resp, int length, void *data)
478 {
479         struct t2_cookie *cookie = data;
480         int err = 0;
481
482         DBG("%d", length);
483
484         if (length < 0)
485                 err = -EIO;
486
487         if (cookie->cb)
488                 cookie->cb(cookie->adapter_idx,
489                                 cookie->target_idx, err);
490
491         return t2_cookie_release(err, cookie);
492 }
493
494 static int nfctype2_check_presence(uint32_t adapter_idx, uint32_t target_idx,
495                                                         near_tag_io_cb cb)
496 {
497         struct type2_cmd cmd;
498         struct t2_cookie *cookie;
499         enum near_tag_sub_type tgt_subtype;
500         int err;
501
502         DBG("");
503
504         tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);
505
506         switch (tgt_subtype) {
507         case NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT:
508                 cmd.cmd = CMD_READ;
509                 cmd.block = META_BLOCK_START;
510
511                 cookie = g_try_malloc0(sizeof(struct t2_cookie));
512                 if (cookie == NULL)
513                         return -ENOMEM;
514
515                 cookie->adapter_idx = adapter_idx;
516                 cookie->target_idx = target_idx;
517                 cookie->cb = cb;
518
519                 err = near_adapter_send(adapter_idx, (uint8_t *) &cmd,
520                                 CMD_READ_SIZE, check_presence, cookie);
521                 if (err < 0)
522                         goto out_err;
523
524                 break;
525         /* Specific Mifare check presence */
526         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_1K:
527         case NEAR_TAG_NFC_T2_MIFARE_CLASSIC_4K:
528                 err = mifare_check_presence(adapter_idx, target_idx,
529                                                         cb, tgt_subtype);
530                 break;
531
532         default:
533                 DBG("Unknown TAG Type 2 subtype %d", tgt_subtype);
534                 err = -1;
535                 break;
536         }
537
538         return err;
539
540 out_err:
541         return t2_cookie_release(err, cookie);
542 }
543
544 static int format_resp(uint8_t *resp, int length, void *data)
545 {
546         int err = 0;
547         struct t2_cookie *cookie = data;
548         struct near_tag *tag;
549
550         DBG("");
551
552         if (length < 0 || resp[0] != 0) {
553                 err = -EIO;
554                 goto out_err;
555         }
556
557         tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
558         if (tag == NULL) {
559                 err = -EINVAL;
560                 goto out_err;
561         }
562
563         DBG("Done formatting");
564         near_tag_set_blank(tag, FALSE);
565
566 out_err:
567         if (cookie->cb)
568                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
569
570         return t2_cookie_release(err, cookie);
571 }
572
573 static int nfctype2_format(uint32_t adapter_idx, uint32_t target_idx,
574                                 near_tag_io_cb cb)
575 {
576         struct type2_cmd cmd;
577         struct t2_cookie *cookie;
578         struct near_ndef_message *cc_ndef;
579         struct type2_cc *t2_cc;
580         struct near_tag *tag;
581         enum near_tag_sub_type tgt_subtype;
582         int err;
583
584         DBG("");
585
586         tag = near_tag_get_tag(adapter_idx, target_idx);
587         if (tag == NULL)
588                 return -EINVAL;
589
590
591         tgt_subtype = near_tag_get_subtype(adapter_idx, target_idx);
592
593         if (tgt_subtype != NEAR_TAG_NFC_T2_MIFARE_ULTRALIGHT) {
594                 DBG("Unknown Tag Type 2 subtype %d", tgt_subtype);
595                 return -1;
596         }
597
598         t2_cc = g_try_malloc0(sizeof(struct type2_cc));
599         cc_ndef = g_try_malloc0(sizeof(struct near_ndef_message));
600         cookie = g_try_malloc0(sizeof(struct t2_cookie));
601
602         if (t2_cc == NULL || cc_ndef == NULL || cookie == NULL) {
603                 err = -ENOMEM;
604                 goto out_err;
605         }
606
607         t2_cc->magic = TYPE2_MAGIC;
608         t2_cc->version = TYPE2_TAG_VER_1_0;
609         t2_cc->mem_size = TYPE2_DATA_SIZE_48;
610         t2_cc->read_write = TYPE2_READWRITE_ACCESS;
611
612         cookie->adapter_idx = adapter_idx;
613         cookie->target_idx = target_idx;
614         cookie->current_block = CC_BLOCK_START;
615         cookie->ndef = cc_ndef;
616         cookie->ndef->data = (uint8_t *) t2_cc;
617         cookie->cb = cb;
618
619         cmd.cmd = CMD_WRITE;
620         cmd.block = CC_BLOCK_START;
621         memcpy(cmd.data, (uint8_t *) t2_cc, BLOCK_SIZE);
622
623         err = near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd,
624                                         sizeof(cmd), format_resp, cookie);
625
626 out_err:
627         if (err < 0) {
628                 g_free(t2_cc);
629                 g_free(cc_ndef);
630                 g_free(cookie);
631         }
632
633         return err;
634 }
635
636 static struct near_tag_driver type2_driver = {
637         .type           = NFC_PROTO_MIFARE,
638         .priority       = NEAR_TAG_PRIORITY_DEFAULT,
639         .read           = nfctype2_read,
640         .write          = nfctype2_write,
641         .check_presence = nfctype2_check_presence,
642         .format         = nfctype2_format,
643 };
644
645 static int nfctype2_init(void)
646 {
647         DBG("");
648
649         return near_tag_driver_register(&type2_driver);
650 }
651
652 static void nfctype2_exit(void)
653 {
654         DBG("");
655
656         near_tag_driver_unregister(&type2_driver);
657 }
658
659 NEAR_PLUGIN_DEFINE(nfctype2, "NFC Forum Type 2 tags support", VERSION,
660                         NEAR_PLUGIN_PRIORITY_HIGH, nfctype2_init, nfctype2_exit)