b23c230e833b75ab247ec6cbb391473b8a6173f1
[profile/ivi/neard.git] / plugins / nfctype3.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 #define CMD_POLL                0x00
43 #define RESP_POLL               0x01
44
45 #define CMD_REQUEST_SERVICE     0x02
46 #define RESP_REQUEST_SERVICE    0x03
47
48 #define CMD_REQUEST_RESPONSE    0x04
49 #define RESP_REQUEST_RESPONSE   0x05
50
51 #define CMD_READ_WO_ENCRYPT     0x06
52 #define RESP_READ_WO_ENCRYPT    0x07
53
54 #define CMD_WRITE_WO_ENCRYPT    0x08
55 #define RESP_WRITE_WO_ENCRYPT   0x09
56
57 #define CMD_REQUEST_SYS_CODE    0x0C
58 #define RESP_REQUEST_SYS_CODE   0x0D
59
60 #define CMD_AUTHENTICATION_1    0x10
61 #define RESP_AUTHENTICATION_1   0x11
62
63 #define CMD_AUTHENTICATION_2    0x12
64 #define RESP_AUTHENTICATION_2   0x13
65
66 #define CMD_READ                0x14
67 #define RESP_READ               0x15
68
69 #define CMD_WRITE               0x16
70 #define RESP_WRITE              0x17
71
72 #define NFC_SERVICE_CODE        0x000B
73 #define BLOCK_SIZE              16
74 #define META_BLOCK_START        0
75 #define DATA_BLOCK_START        1
76
77 #define LEN_ID                  0x08
78 #define LEN_CMD                 0x01
79 #define LEN_REPLY_CMD           0x02
80 #define LEN_CMD_LEN             0x01
81
82 /* offsets */
83 #define OFS_NFC_STATUS  0
84 #define OFS_NFC_LEN     1
85 #define OFS_CMD_RESP    2
86 #define OFS_IDM         3
87 #define OFS_CMD_DATA    (LEN_CMD_LEN + LEN_CMD + LEN_ID)
88 #define OFS_READ_FLAG   12
89 #define OFS_READ_DATA   14
90 #define BLOCK_SIZE      16
91 #define CHECKSUM_LEN    2
92
93 #define MAX_DATA_SIZE   254
94
95 #define NDEF_MAPPING_VERSION    0x10
96 #define MAX_READ_BLOCKS_PER_CHECK       0x04
97 #define MAX_WRITE_BLOCKS_PER_UPDATE     0x01
98 #define MAX_BLOCKS_FOR_NDEF_DATA        0x000D
99 #define ATTR_BLOCK_WRITE_FLAG   0x00
100 #define ATTR_BLOCK_RW_FLAG      0x01
101
102 #define IC_TYPE_OFFSET  12
103 #define SYSTEM_OPTION_OFFSET    17
104 #define FELICA_LITE_MC_BLOCK    0x88
105 #define FELICA_LITE_IC_TYPE     0xF0
106 #define FELICA_LITE_S_IC_TYPE   0xF1
107 #define FELICA_PLUG_IC_TYPE     0xE0
108
109 #define FELICA_LITE_AND_LITE_S_SYS_CODE 0x88B4
110
111 struct type3_cmd {
112         uint8_t len;
113         uint8_t cmd;
114         uint8_t data[MAX_DATA_SIZE];
115 } __attribute__((packed));
116
117 struct type3_tag {
118         uint32_t adapter_idx;
119         uint16_t current_block;
120         uint8_t IDm[LEN_ID];
121
122         near_tag_io_cb cb;
123         struct near_tag *tag;
124 };
125
126 struct t3_cookie {
127         uint32_t adapter_idx;
128         uint32_t target_idx;
129         near_tag_io_cb cb;
130         uint8_t IDm[LEN_ID];
131         uint8_t current_block;
132         uint8_t attr[BLOCK_SIZE];
133         struct near_ndef_message *ndef;
134         uint8_t ic_type;
135         uint8_t mc_block[BLOCK_SIZE];
136 };
137
138 static void t3_cookie_release(struct t3_cookie *cookie)
139 {
140         if (cookie == NULL)
141                 return;
142
143         if (cookie->ndef != NULL)
144                 g_free(cookie->ndef->data);
145
146         g_free(cookie->ndef);
147         g_free(cookie);
148         cookie = NULL;
149 }
150
151 /* common: Initialize structure to write block */
152 static void prepare_write_block(uint8_t *UID, struct type3_cmd *cmd,
153                                         uint8_t block, uint8_t *data)
154 {
155         cmd->cmd = CMD_WRITE_WO_ENCRYPT;        /* command */
156         memcpy(cmd->data, UID, LEN_ID);         /* IDm */
157
158         cmd->data[LEN_ID] = 1;                  /* number of services */
159         cmd->data[LEN_ID + 1] = 0x09;           /* service 0x0009 */
160         cmd->data[LEN_ID + 2] = 0x00;
161
162         cmd->data[LEN_ID + 3] = 0x01;           /* number of blocks */
163         cmd->data[LEN_ID + 4] = 0x80;           /* 2 byte block number format */
164         cmd->data[LEN_ID + 5] = block;          /* block number */
165         memcpy(cmd->data + LEN_ID + 6, data, BLOCK_SIZE); /* data to write */
166
167         cmd->len = LEN_ID + LEN_CMD + LEN_CMD_LEN + 6 + BLOCK_SIZE;
168 }
169
170 /* common: Initialize structure to read block */
171 static void prepare_read_block(uint8_t cur_block,
172                                 uint8_t *UID,
173                                 struct type3_cmd *cmd )
174 {
175         cmd->cmd         = CMD_READ_WO_ENCRYPT;         /* command */
176         memcpy(cmd->data, UID, LEN_ID);                 /* IDm */
177
178         cmd->data[LEN_ID] = 1;                          /* number of service */
179         cmd->data[LEN_ID + 1] = 0x0B;                   /* service x000B */
180         cmd->data[LEN_ID + 2] = 0x00;
181
182         cmd->data[LEN_ID + 3] = 0x01;                   /* number of block */
183         cmd->data[LEN_ID + 4] = 0x80;                   /* 2 bytes block id*/
184         cmd->data[LEN_ID + 5] = cur_block;              /* block number */
185
186         cmd->len = LEN_ID + LEN_CMD + LEN_CMD_LEN + 6;
187 }
188
189 /* common: Simple checks on received frame */
190 static int check_recv_frame(uint8_t *resp, uint8_t reply_code)
191 {
192         int err = 0;
193
194         if (resp[OFS_NFC_STATUS] != 0) {
195                 DBG("NFC Command failed: 0x%x",resp[OFS_NFC_STATUS]);
196                 err = -EIO;
197         }
198
199         if (resp[OFS_CMD_RESP] != reply_code ) {
200                 DBG("Felica cmd failed: 0x%x", resp[OFS_CMD_RESP]);
201                 err = -EIO;
202         }
203
204         return err;
205 }
206
207 static int nfctype3_data_recv(uint8_t *resp, int length, void *data)
208 {
209         struct type3_tag *tag = data;
210         struct type3_cmd cmd;
211         uint8_t *nfc_data;
212         size_t current_length, length_read, data_length;
213         uint32_t adapter_idx;
214         uint32_t target_idx;
215         int read_blocks;
216         int err;
217
218         DBG("%d", length);
219
220         adapter_idx = near_tag_get_adapter_idx(tag->tag);
221         target_idx = near_tag_get_target_idx(tag->tag);
222
223         if (length < 0) {
224                 err = -EIO;
225                 goto out;
226         }
227
228         nfc_data = near_tag_get_data(tag->tag, &data_length);
229         length_read = length - OFS_READ_DATA  ;
230         current_length = tag->current_block * BLOCK_SIZE;
231         if (current_length + (length - OFS_READ_DATA) > data_length)
232                 length_read = data_length - current_length;
233
234         memcpy(nfc_data + current_length, resp + OFS_READ_DATA, length_read);
235
236         if (current_length + length_read >= data_length) {
237                 GList *records;
238
239                 tag->current_block = 0;
240
241                 DBG("Done reading %zd bytes at %p", data_length, nfc_data);
242                 records = near_ndef_parse(nfc_data, data_length);
243                 near_tag_add_records(tag->tag, records, tag->cb, 0);
244
245                 g_free(tag);
246
247                 return 0;
248         }
249
250         /* Read the next block */
251         read_blocks = length / BLOCK_SIZE;
252         tag->current_block += read_blocks;
253
254         prepare_read_block(DATA_BLOCK_START + tag->current_block,
255                                 tag->IDm, &cmd );
256
257         err = near_adapter_send(adapter_idx, (uint8_t *)&cmd, cmd.len,
258                         nfctype3_data_recv, tag);
259         if (err < 0)
260                 goto out;
261
262         return 0;
263
264 out:
265         if (err < 0 && tag->cb)
266                 tag->cb(adapter_idx, target_idx, err);
267
268         g_free(tag);
269
270         return err;
271 }
272
273 static int nfctype3_data_read(struct type3_tag *tag)
274 {
275         struct type3_cmd cmd;
276         uint32_t adapter_idx;
277
278         DBG("");
279
280         tag->current_block = 0;
281
282         prepare_read_block(DATA_BLOCK_START + tag->current_block,
283                                                         tag->IDm, &cmd );
284
285         adapter_idx = near_tag_get_adapter_idx(tag->tag);
286
287         return near_adapter_send(adapter_idx,
288                                         (uint8_t *) &cmd, cmd.len,
289                                         nfctype3_data_recv, tag);
290 }
291
292 /* Read block 0 to retrieve the data length */
293 static int nfctype3_recv_block_0(uint8_t *resp, int length, void *data)
294 {
295         struct t3_cookie *cookie = data;
296         int err = 0;
297         struct near_tag *tag;
298         struct type3_tag *t3_tag = NULL;
299         uint32_t  ndef_data_length;
300
301         DBG("%d", length);
302
303         if (length < 0) {
304                 err = -EIO;
305                 goto out;
306         }
307
308         err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
309         if (err < 0)
310                 goto out;
311
312         if (resp[OFS_READ_FLAG] != 0) {
313                 DBG("Status 0x%x", resp[OFS_READ_FLAG]);
314                 err = -EIO;
315                 goto out;
316         }
317
318         /* Block 0:[11 - 13]: length is a 3 bytes value */
319         ndef_data_length =  resp[OFS_READ_DATA + 11] * 0x100;
320         ndef_data_length += resp[OFS_READ_DATA + 12];
321         ndef_data_length *= 0x100;
322         ndef_data_length += resp[OFS_READ_DATA + 13];
323
324         /* Add data to the tag */
325         err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx,
326                                         NULL, ndef_data_length);
327         if (err < 0)
328                 goto out;
329
330         tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
331         if (tag == NULL) {
332                 err = -ENOMEM;
333                 goto out;
334         }
335
336         /* Block 0:[10]: RW Flag. 1 for RW */
337         if (resp[OFS_READ_DATA + 10] == 0)
338                 near_tag_set_ro(tag, TRUE);
339         else
340                 near_tag_set_ro(tag, FALSE);
341
342         t3_tag = g_try_malloc0(sizeof(struct type3_tag));
343         if (t3_tag == NULL) {
344                 err = -ENOMEM;
345                 goto out;
346         }
347
348         memcpy(t3_tag->IDm, cookie->IDm , LEN_ID);
349
350         near_tag_set_idm(tag, cookie->IDm, LEN_ID);
351         near_tag_set_attr_block(tag, resp + OFS_READ_DATA, BLOCK_SIZE);
352         near_tag_set_blank(tag, FALSE);
353         near_tag_set_ic_type(tag, cookie->ic_type);
354
355         t3_tag->adapter_idx = cookie->adapter_idx;
356         t3_tag->cb = cookie->cb;
357         t3_tag->tag = tag;
358
359         err = nfctype3_data_read(t3_tag);
360
361 out:
362         if (err < 0) {
363                 if (cookie->cb)
364                         cookie->cb(cookie->adapter_idx, cookie->target_idx,
365                                                                         err);
366
367                 g_free(t3_tag);
368         }
369
370         t3_cookie_release(cookie);
371
372         return err;
373 }
374
375 static int poll_ndef_system_code(uint8_t *resp, int length, void *data)
376 {
377         struct t3_cookie *cookie = data;
378         int err = 0;
379         struct type3_cmd cmd;
380
381         DBG(" length: %d", length);
382
383         if (length < 0) {
384                 err = -EIO;
385                 goto out;
386         }
387
388         err = check_recv_frame(resp, RESP_POLL);
389         if (err < 0)
390                 goto out;
391
392         prepare_read_block(META_BLOCK_START, cookie->IDm, &cmd);
393
394         err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
395                                 cmd.len, nfctype3_recv_block_0, cookie);
396         if (err < 0)
397                 goto out;
398
399         return 0;
400
401 out:
402         if (err < 0 && cookie->cb)
403                 cookie->cb(cookie->adapter_idx,
404                                 cookie->target_idx, err);
405
406         t3_cookie_release(cookie);
407
408         return err;
409 }
410
411 static int check_sys_op_in_mc_block(uint8_t *resp, int length, void *data)
412 {
413         struct type3_cmd cmd;
414         struct near_tag *tag;
415         struct t3_cookie *cookie = data;
416         int err = 0;
417
418         DBG("length %d", length);
419
420         if (length < 0) {
421                 err = -EIO;
422                 goto out;
423         }
424
425         err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
426         if (err < 0)
427                 goto out;
428
429         if (resp[SYSTEM_OPTION_OFFSET] == 0x00) {
430                 DBG("Blank tag detected");
431
432                 err = near_tag_add_data(cookie->adapter_idx,
433                                         cookie->target_idx,
434                                         NULL, 1 /* dummy length */);
435                 if (err < 0)
436                         goto out;
437
438                 tag = near_tag_get_tag(cookie->adapter_idx,
439                                         cookie->target_idx);
440                 if (tag == NULL) {
441                         err = -ENOMEM;
442                         goto out;
443                 }
444
445                 near_tag_set_idm(tag, cookie->IDm, LEN_ID);
446                 near_tag_set_ic_type(tag, cookie->ic_type);
447                 near_tag_set_blank(tag, TRUE);
448
449                 if (cookie->cb)
450                         cookie->cb(cookie->adapter_idx,
451                                         cookie->target_idx, 0);
452
453                 t3_cookie_release(cookie);
454
455                 return 0;
456         } else {
457                 /* CMD POLL */
458                 cmd.cmd  = CMD_POLL;    /* POLL command */
459                 cmd.data[0] = 0x12;     /* System code (NFC SC) */
460                 cmd.data[1] = 0xFC;
461                 cmd.data[2] = 01;       /* request code */
462                 cmd.data[3] = 0x00;     /* time slot */
463                 /* data len + 2 bytes */
464                 cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
465
466                 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
467                         cmd.len , poll_ndef_system_code, cookie);
468         }
469
470         if (err < 0)
471                 goto out;
472
473         return 0;
474
475 out:
476         if (err < 0 && cookie->cb)
477                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
478
479         t3_cookie_release(cookie);
480
481         return err;
482 }
483
484 static int receive_system_code(uint8_t *resp, int length, void *data)
485 {
486         struct t3_cookie *cookie = data;
487         int err = 0;
488         struct type3_cmd cmd;
489         uint16_t system_code;
490
491         DBG(" length: %d", length);
492
493         if (length < 0) {
494                 err = -EIO;
495                 goto out;
496         }
497
498         err = check_recv_frame(resp, RESP_POLL);
499         if (err < 0)
500                 goto out;
501
502         cookie->ic_type = resp[IC_TYPE_OFFSET];
503         memcpy(cookie->IDm, resp + OFS_IDM, LEN_ID);
504         system_code = ((uint16_t)(resp[length - 2])) << 8;
505         system_code |= resp[length - 1];
506
507         switch (resp[IC_TYPE_OFFSET]) {
508         case FELICA_LITE_IC_TYPE:
509                 prepare_read_block(FELICA_LITE_MC_BLOCK, cookie->IDm, &cmd);
510                 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
511                                         cmd.len, check_sys_op_in_mc_block,
512                                         cookie);
513                 break;
514
515         case FELICA_LITE_S_IC_TYPE:
516         case FELICA_PLUG_IC_TYPE:
517                 /* CMD POLL */
518                 cmd.cmd  = CMD_POLL;    /* POLL command */
519                 cmd.data[0] = 0x12;     /* System code (NFC SC) */
520                 cmd.data[1] = 0xFC;
521                 cmd.data[2] = 01;       /* request code */
522                 cmd.data[3] = 0x00;     /* time slot */
523                 /* data len + 2 bytes */
524                 cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
525
526                 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
527                                         cmd.len, poll_ndef_system_code, cookie);
528         }
529
530         if (err < 0)
531                 goto out;
532
533         return 0;
534
535 out:
536         if (err < 0 && cookie->cb)
537                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
538
539         t3_cookie_release(cookie);
540
541         return err;
542 }
543
544 static int nfctype3_read(uint32_t adapter_idx,
545                                 uint32_t target_idx, near_tag_io_cb cb)
546 {
547         struct type3_cmd cmd;
548         struct t3_cookie *cookie;
549         int err;
550
551         DBG("");
552
553         /* CMD POLL */
554         cmd.cmd  = CMD_POLL;    /* POLL command */
555         cmd.data[0] = 0xFF;     /* System code */
556         cmd.data[1] = 0xFF;
557         cmd.data[2] = 01;       /* request code */
558         cmd.data[3] = 0x00;     /* time slot */
559
560         /* data len + 2 bytes */
561         cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
562
563         cookie = g_try_malloc0(sizeof(struct t3_cookie));
564         if (cookie == NULL)
565                 return -ENOMEM;
566
567         cookie->adapter_idx = adapter_idx;
568         cookie->target_idx = target_idx;
569         cookie->cb = cb;
570
571         err = near_adapter_send(adapter_idx, (uint8_t *)&cmd,
572                                 cmd.len , receive_system_code, cookie);
573         if (err < 0)
574                 g_free(cookie);
575
576         return err;
577 }
578
579 static int update_attr_block_cb(uint8_t *resp, int length, void *data)
580 {
581         struct t3_cookie *cookie = data;
582         int err;
583
584         DBG("");
585
586         if (length < 0) {
587                 err = -EIO;
588                 goto out;
589         }
590
591         err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
592         if (err < 0)
593                 goto out;
594
595         DBG("Done writing");
596
597 out:
598         if (cookie->cb)
599                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
600
601         t3_cookie_release(cookie);
602
603         return err;
604 }
605
606 static int update_attr_block(struct t3_cookie *cookie)
607 {
608         struct type3_cmd cmd;
609         uint16_t checksum;
610         uint8_t i;
611
612         DBG("");
613
614         cookie->attr[9] = 0x00; /* writing data completed */
615         cookie->attr[11] = (uint8_t) (cookie->ndef->length >> 16);
616         cookie->attr[12] = (uint8_t) (cookie->ndef->length >> 8);
617         cookie->attr[13] = (uint8_t) cookie->ndef->length;
618         checksum = 0;
619
620         for (i = 0; i < (BLOCK_SIZE - CHECKSUM_LEN); i++)
621                 checksum += cookie->attr[i];
622
623         cookie->attr[14] = (uint8_t) (checksum >> 8);
624         cookie->attr[15] = (uint8_t) checksum;
625
626         prepare_write_block(cookie->IDm, &cmd, 0, cookie->attr);
627
628         return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd, cmd.len,
629                                                 update_attr_block_cb, cookie);
630 }
631
632 static int data_write_resp(uint8_t *resp, int length, void *data)
633 {
634         struct t3_cookie *cookie = data;
635         struct type3_cmd cmd;
636         uint8_t padding[BLOCK_SIZE] = {0};
637         int err;
638
639         DBG("");
640
641         if (length < 0) {
642                 err = -EIO;
643                 goto out;
644         }
645
646         err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
647         if (err < 0)
648                 goto out;
649
650         if (cookie->ndef->offset >= cookie->ndef->length) {
651                 err = update_attr_block(cookie);
652                 if (err < 0)
653                         goto out;
654
655                 return 0;
656         }
657
658         if ((cookie->ndef->length - cookie->ndef->offset) <
659                         BLOCK_SIZE) {
660                 memcpy(padding, cookie->ndef->data + cookie->ndef->offset,
661                                 cookie->ndef->length - cookie->ndef->offset);
662                 prepare_write_block(cookie->IDm, &cmd,
663                                         cookie->current_block, padding);
664         } else {
665                 prepare_write_block(cookie->IDm, &cmd, cookie->current_block,
666                                 cookie->ndef->data + cookie->ndef->offset);
667         }
668
669         cookie->current_block++;
670         cookie->ndef->offset += BLOCK_SIZE;
671
672         err =  near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd, cmd.len,
673                                                 data_write_resp, cookie);
674         if (err < 0)
675                 goto out;
676
677         return 0;
678
679 out:
680         if (err < 0 && cookie->cb)
681                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
682
683         t3_cookie_release(cookie);
684
685         return err;
686 }
687
688 static int data_write(uint32_t adapter_idx, uint32_t target_idx,
689                                 struct near_ndef_message *ndef,
690                                 struct near_tag *tag,
691                                 near_tag_io_cb cb)
692 {
693         struct t3_cookie *cookie;
694         struct type3_cmd cmd;
695         uint16_t checksum, nmaxb;
696         uint8_t i, len = 0;
697         uint8_t *idm, *attr;
698         int err;
699
700         DBG("");
701
702         cookie = g_try_malloc0(sizeof(struct t3_cookie));
703         if (cookie == NULL) {
704                 err = -ENOMEM;
705                 goto out;
706         }
707
708         cookie->adapter_idx = adapter_idx;
709         cookie->target_idx = target_idx;
710         cookie->ndef = ndef;
711         cookie->cb = cb;
712         cookie->current_block = 0;
713
714         idm = near_tag_get_idm(tag, &len);
715         if (idm == NULL) {
716                 err = -EINVAL;
717                 goto out;
718         }
719
720         memcpy(cookie->IDm, idm, len);
721
722         attr = near_tag_get_attr_block(tag, &len);
723         if (attr == NULL) {
724                 err = -EINVAL;
725                 goto out;
726         }
727
728         memcpy(cookie->attr, attr, len);
729         nmaxb = (((uint16_t)(cookie->attr[3])) << 8) | cookie->attr[4];
730
731         if (cookie->ndef->length > (nmaxb * BLOCK_SIZE)) {
732                 near_error("not enough space on tag");
733                 err = -ENOSPC;
734                 goto out;
735         }
736
737         cookie->attr[9] = 0x0F; /* writing data in progress */
738         checksum = 0;
739
740         for (i = 0; i < 14; i++)
741                 checksum += cookie->attr[i];
742
743         cookie->attr[14] = (uint8_t)(checksum >> 8);
744         cookie->attr[15] = (uint8_t)(checksum);
745
746         prepare_write_block(cookie->IDm, &cmd, cookie->current_block,
747                                                         cookie->attr);
748         cookie->current_block++;
749
750         err = near_adapter_send(adapter_idx, (uint8_t *)&cmd, cmd.len,
751                                                 data_write_resp, cookie);
752         if (err < 0)
753                 goto out;
754
755         return 0;
756
757 out:
758         t3_cookie_release(cookie);
759
760         return err;
761 }
762
763 static int nfctype3_write(uint32_t adapter_idx, uint32_t target_idx,
764                                 struct near_ndef_message *ndef,
765                                 near_tag_io_cb cb)
766 {
767         struct near_tag *tag;
768
769         DBG("");
770
771         if (ndef == NULL || cb == NULL)
772                 return -EINVAL;
773
774         tag = near_tag_get_tag(adapter_idx, target_idx);
775         if (tag == NULL)
776                 return -EINVAL;
777
778         return data_write(adapter_idx, target_idx, ndef, tag, cb);
779 }
780
781 static int nfctype3_check_recv_UID(uint8_t *resp, int length, void *data)
782 {
783         struct t3_cookie *rcv_cookie = data;
784         int err = 0;
785
786         DBG("length %d", length);
787
788         if (length < 0)
789                 err = -EIO;
790
791         if (rcv_cookie->cb)
792                 rcv_cookie->cb(rcv_cookie->adapter_idx,
793                                 rcv_cookie->target_idx, err);
794
795         t3_cookie_release(rcv_cookie);
796
797         return err;
798 }
799
800 static int nfctype3_check_presence(uint32_t adapter_idx,
801                                 uint32_t target_idx, near_tag_io_cb cb)
802 {
803         struct type3_cmd cmd;
804         struct t3_cookie *cookie;
805         int err;
806
807         DBG("");
808
809         /* CMD POLL */
810         cmd.cmd  = CMD_POLL;    /* POLL command */
811         cmd.data[0] = 0xFF;     /* System code */
812         cmd.data[1] = 0xFF;
813         cmd.data[2] = 01;       /* request code */
814         cmd.data[3] = 0x00;     /* time slot */
815
816         /* data len + 2 bytes */
817         cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
818
819         cookie = g_try_malloc0(sizeof(struct t3_cookie));
820         if (cookie == NULL)
821                 return -ENOMEM;
822
823         cookie->adapter_idx = adapter_idx;
824         cookie->target_idx = target_idx;
825         cookie->cb = cb;
826
827         err = near_adapter_send(adapter_idx, (uint8_t *)&cmd,
828                         cmd.len , nfctype3_check_recv_UID, cookie);
829         if (err < 0)
830                 goto out;
831
832         return 0;
833
834 out:
835         t3_cookie_release(cookie);
836
837         return err;
838 }
839
840 static int format_resp(uint8_t *resp, int length, void *data)
841 {
842         struct near_tag *tag;
843         struct t3_cookie *cookie = data;
844         int err;
845
846         DBG("");
847
848         if (length < 0) {
849                 err = -EIO;
850                 goto out;
851         }
852
853         err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
854         if (err < 0)
855                 goto out;
856
857         tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
858         if (tag == NULL) {
859                 err = -ENOMEM;
860                 goto out;
861         }
862
863         near_tag_set_ro(tag, FALSE);
864         near_tag_set_idm(tag, cookie->IDm, LEN_ID);
865         near_tag_set_attr_block(tag, cookie->attr, BLOCK_SIZE);
866         near_tag_set_blank(tag, FALSE);
867
868         DBG("Formatting is done");
869
870 out:
871         if (cookie->cb)
872                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
873
874         t3_cookie_release(cookie);
875
876         return err;
877 }
878
879 static int write_attr_block(uint8_t *resp, int length , void *data)
880 {
881         struct type3_cmd cmd;
882         struct t3_cookie *cookie = data;
883         int err, i;
884         uint16_t checksum = 0;
885
886         DBG("length %d", length);
887
888         if (length < 0) {
889                 err = -EIO;
890                 goto out;
891         }
892
893         err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
894         if (err < 0)
895                 goto out;
896
897         cookie->attr[0] = NDEF_MAPPING_VERSION;
898         cookie->attr[1] = MAX_READ_BLOCKS_PER_CHECK;
899         cookie->attr[2] = MAX_WRITE_BLOCKS_PER_UPDATE;
900         cookie->attr[3] = (uint8_t) (MAX_BLOCKS_FOR_NDEF_DATA >> 8);
901         cookie->attr[4] = (uint8_t) (MAX_BLOCKS_FOR_NDEF_DATA);
902         cookie->attr[5] = 0;
903         cookie->attr[6] = 0;
904         cookie->attr[7] = 0;
905         cookie->attr[8] = 0;
906         cookie->attr[9] = ATTR_BLOCK_WRITE_FLAG;
907         cookie->attr[10] = ATTR_BLOCK_RW_FLAG;
908         cookie->attr[11] = 0;
909         cookie->attr[12] = 0;
910         cookie->attr[13] = 0;
911
912         for (i = 0; i < (BLOCK_SIZE - CHECKSUM_LEN); i++)
913                 checksum += cookie->attr[i];
914
915         cookie->attr[14] = (uint8_t) (checksum >> 8);
916         cookie->attr[15] = (uint8_t) checksum;
917
918         prepare_write_block(cookie->IDm, &cmd, META_BLOCK_START,
919                                                 cookie->attr);
920
921         err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
922                                 cmd.len, format_resp, cookie);
923         if (err < 0)
924                 goto out;
925
926         return 0;
927
928 out:
929         if (err < 0 && cookie->cb)
930                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
931
932         t3_cookie_release(cookie);
933
934         return err;
935 }
936
937 static int write_mc_block(uint8_t *resp, int length, void *data)
938 {
939         struct type3_cmd cmd;
940         struct t3_cookie *cookie = data;
941         int err;
942
943         DBG("length %d", length);
944
945         if (length < 0) {
946                 err = -EIO;
947                 goto out;
948         }
949
950         err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
951         if (err < 0)
952                 goto out;
953
954         if (resp[OFS_READ_FLAG] != 0) {
955                 DBG("Status 0x%x", resp[OFS_READ_FLAG]);
956                 err = -EIO;
957                 goto out;
958         }
959
960         memcpy(cookie->mc_block, resp + 14, BLOCK_SIZE);
961         /*
962          * By updating Byte3 to 01h means making Felica Lite
963          * compatible with NDEF.
964          */
965         cookie->mc_block[3] = 1;
966         prepare_write_block(cookie->IDm, &cmd, FELICA_LITE_MC_BLOCK,
967                                 cookie->mc_block);
968         err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
969                                 cmd.len, write_attr_block, cookie);
970         if (err < 0)
971                 goto out;
972
973         return 0;
974
975 out:
976         if (err < 0 && cookie->cb)
977                 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
978
979         t3_cookie_release(cookie);
980
981         return err;
982 }
983
984 static int nfctype3_format(uint32_t adapter_idx,
985                                 uint32_t target_idx, near_tag_io_cb cb)
986 {
987         struct type3_cmd cmd;
988         struct near_tag *tag;
989         struct t3_cookie *cookie;
990         uint8_t ic_type;
991         uint8_t *idm, len;
992         int err;
993
994         DBG("");
995
996         tag = near_tag_get_tag(adapter_idx, target_idx);
997         if (tag == NULL)
998                 return -ENOMEM;
999
1000         ic_type = near_tag_get_ic_type(tag);
1001         if (ic_type != FELICA_LITE_IC_TYPE)
1002                 return -EOPNOTSUPP;
1003
1004         cookie = g_try_malloc0(sizeof(struct t3_cookie));
1005         if (cookie == NULL)
1006                 return -ENOMEM;
1007
1008         cookie->adapter_idx = adapter_idx;
1009         cookie->target_idx = target_idx;
1010         cookie->cb = cb;
1011         cookie->ic_type = ic_type;
1012
1013         idm = near_tag_get_idm(tag, &len);
1014         if (idm == NULL) {
1015                 err = -EINVAL;
1016                 goto out;
1017         }
1018
1019         memcpy(cookie->IDm, idm, len);
1020
1021         prepare_read_block(FELICA_LITE_MC_BLOCK, cookie->IDm, &cmd);
1022         err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
1023                                 cmd.len, write_mc_block, cookie);
1024         if (err < 0)
1025                 goto out;
1026
1027         return 0;
1028
1029 out:
1030         t3_cookie_release(cookie);
1031
1032         return err;
1033 }
1034
1035 static struct near_tag_driver type1_driver = {
1036         .type           = NFC_PROTO_FELICA,
1037         .priority       = NEAR_TAG_PRIORITY_DEFAULT,
1038         .read           = nfctype3_read,
1039         .write          = nfctype3_write,
1040         .format         = nfctype3_format,
1041         .check_presence = nfctype3_check_presence,
1042 };
1043
1044 static int nfctype3_init(void)
1045 {
1046         DBG("");
1047
1048         return near_tag_driver_register(&type1_driver);
1049 }
1050
1051 static void nfctype3_exit(void)
1052 {
1053         DBG("");
1054
1055         near_tag_driver_unregister(&type1_driver);
1056 }
1057
1058 NEAR_PLUGIN_DEFINE(nfctype3, "NFC Forum Type 3 tags support", VERSION,
1059                         NEAR_PLUGIN_PRIORITY_HIGH, nfctype3_init, nfctype3_exit)