3 * neard - Near Field Communication manager
5 * Copyright (C) 2011 Intel Corporation. All rights reserved.
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.
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.
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
29 #include <sys/socket.h>
31 #include <linux/socket.h>
32 #include <linux/nfc.h>
34 #include <near/plugin.h>
36 #include <near/types.h>
37 #include <near/adapter.h>
39 #include <near/ndef.h>
43 #define RESP_POLL 0x01
45 #define CMD_REQUEST_SERVICE 0x02
46 #define RESP_REQUEST_SERVICE 0x03
48 #define CMD_REQUEST_RESPONSE 0x04
49 #define RESP_REQUEST_RESPONSE 0x05
51 #define CMD_READ_WO_ENCRYPT 0x06
52 #define RESP_READ_WO_ENCRYPT 0x07
54 #define CMD_WRITE_WO_ENCRYPT 0x08
55 #define RESP_WRITE_WO_ENCRYPT 0x09
57 #define CMD_REQUEST_SYS_CODE 0x0C
58 #define RESP_REQUEST_SYS_CODE 0x0D
60 #define CMD_AUTHENTICATION_1 0x10
61 #define RESP_AUTHENTICATION_1 0x11
63 #define CMD_AUTHENTICATION_2 0x12
64 #define RESP_AUTHENTICATION_2 0x13
67 #define RESP_READ 0x15
69 #define CMD_WRITE 0x16
70 #define RESP_WRITE 0x17
72 #define NFC_SERVICE_CODE 0x000B
74 #define META_BLOCK_START 0
75 #define DATA_BLOCK_START 1
79 #define LEN_REPLY_CMD 0x02
80 #define LEN_CMD_LEN 0x01
83 #define OFS_NFC_STATUS 0
85 #define OFS_CMD_RESP 2
87 #define OFS_CMD_DATA (LEN_CMD_LEN + LEN_CMD + LEN_ID)
88 #define OFS_READ_FLAG 12
89 #define OFS_READ_DATA 14
91 #define CHECKSUM_LEN 2
93 #define MAX_DATA_SIZE 254
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
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
109 #define FELICA_LITE_AND_LITE_S_SYS_CODE 0x88B4
114 uint8_t data[MAX_DATA_SIZE];
115 } __attribute__((packed));
118 uint32_t adapter_idx;
119 uint16_t current_block;
123 struct near_tag *tag;
127 uint32_t adapter_idx;
131 uint8_t current_block;
132 uint8_t attr[BLOCK_SIZE];
133 struct near_ndef_message *ndef;
135 uint8_t mc_block[BLOCK_SIZE];
138 static void t3_cookie_release(struct t3_cookie *cookie)
143 if (cookie->ndef != NULL)
144 g_free(cookie->ndef->data);
146 g_free(cookie->ndef);
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)
155 cmd->cmd = CMD_WRITE_WO_ENCRYPT; /* command */
156 memcpy(cmd->data, UID, LEN_ID); /* IDm */
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;
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 */
167 cmd->len = LEN_ID + LEN_CMD + LEN_CMD_LEN + 6 + BLOCK_SIZE;
170 /* common: Initialize structure to read block */
171 static void prepare_read_block(uint8_t cur_block,
173 struct type3_cmd *cmd )
175 cmd->cmd = CMD_READ_WO_ENCRYPT; /* command */
176 memcpy(cmd->data, UID, LEN_ID); /* IDm */
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;
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 */
186 cmd->len = LEN_ID + LEN_CMD + LEN_CMD_LEN + 6;
189 /* common: Simple checks on received frame */
190 static int check_recv_frame(uint8_t *resp, uint8_t reply_code)
194 if (resp[OFS_NFC_STATUS] != 0) {
195 DBG("NFC Command failed: 0x%x",resp[OFS_NFC_STATUS]);
199 if (resp[OFS_CMD_RESP] != reply_code ) {
200 DBG("Felica cmd failed: 0x%x", resp[OFS_CMD_RESP]);
207 static int nfctype3_data_recv(uint8_t *resp, int length, void *data)
209 struct type3_tag *tag = data;
210 struct type3_cmd cmd;
212 size_t current_length, length_read, data_length;
213 uint32_t adapter_idx;
220 adapter_idx = near_tag_get_adapter_idx(tag->tag);
221 target_idx = near_tag_get_target_idx(tag->tag);
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;
234 memcpy(nfc_data + current_length, resp + OFS_READ_DATA, length_read);
236 if (current_length + length_read >= data_length) {
239 tag->current_block = 0;
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);
250 /* Read the next block */
251 read_blocks = length / BLOCK_SIZE;
252 tag->current_block += read_blocks;
254 prepare_read_block(DATA_BLOCK_START + tag->current_block,
257 err = near_adapter_send(adapter_idx, (uint8_t *)&cmd, cmd.len,
258 nfctype3_data_recv, tag);
265 if (err < 0 && tag->cb)
266 tag->cb(adapter_idx, target_idx, err);
273 static int nfctype3_data_read(struct type3_tag *tag)
275 struct type3_cmd cmd;
276 uint32_t adapter_idx;
280 tag->current_block = 0;
282 prepare_read_block(DATA_BLOCK_START + tag->current_block,
285 adapter_idx = near_tag_get_adapter_idx(tag->tag);
287 return near_adapter_send(adapter_idx,
288 (uint8_t *) &cmd, cmd.len,
289 nfctype3_data_recv, tag);
292 /* Read block 0 to retrieve the data length */
293 static int nfctype3_recv_block_0(uint8_t *resp, int length, void *data)
295 struct t3_cookie *cookie = data;
297 struct near_tag *tag;
298 struct type3_tag *t3_tag = NULL;
299 uint32_t ndef_data_length;
308 err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
312 if (resp[OFS_READ_FLAG] != 0) {
313 DBG("Status 0x%x", resp[OFS_READ_FLAG]);
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];
324 /* Add data to the tag */
325 err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx,
326 NULL, ndef_data_length);
330 tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
336 /* Block 0:[10]: RW Flag. 1 for RW */
337 if (resp[OFS_READ_DATA + 10] == 0)
338 near_tag_set_ro(tag, TRUE);
340 near_tag_set_ro(tag, FALSE);
342 t3_tag = g_try_malloc0(sizeof(struct type3_tag));
343 if (t3_tag == NULL) {
348 memcpy(t3_tag->IDm, cookie->IDm , LEN_ID);
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);
355 t3_tag->adapter_idx = cookie->adapter_idx;
356 t3_tag->cb = cookie->cb;
359 err = nfctype3_data_read(t3_tag);
364 cookie->cb(cookie->adapter_idx, cookie->target_idx,
370 t3_cookie_release(cookie);
375 static int poll_ndef_system_code(uint8_t *resp, int length, void *data)
377 struct t3_cookie *cookie = data;
379 struct type3_cmd cmd;
381 DBG(" length: %d", length);
388 err = check_recv_frame(resp, RESP_POLL);
392 prepare_read_block(META_BLOCK_START, cookie->IDm, &cmd);
394 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
395 cmd.len, nfctype3_recv_block_0, cookie);
402 if (err < 0 && cookie->cb)
403 cookie->cb(cookie->adapter_idx,
404 cookie->target_idx, err);
406 t3_cookie_release(cookie);
411 static int check_sys_op_in_mc_block(uint8_t *resp, int length, void *data)
413 struct type3_cmd cmd;
414 struct near_tag *tag;
415 struct t3_cookie *cookie = data;
418 DBG("length %d", length);
425 err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
429 if (resp[SYSTEM_OPTION_OFFSET] == 0x00) {
430 DBG("Blank tag detected");
432 err = near_tag_add_data(cookie->adapter_idx,
434 NULL, 1 /* dummy length */);
438 tag = near_tag_get_tag(cookie->adapter_idx,
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);
450 cookie->cb(cookie->adapter_idx,
451 cookie->target_idx, 0);
453 t3_cookie_release(cookie);
458 cmd.cmd = CMD_POLL; /* POLL command */
459 cmd.data[0] = 0x12; /* System code (NFC SC) */
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 ;
466 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
467 cmd.len , poll_ndef_system_code, cookie);
476 if (err < 0 && cookie->cb)
477 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
479 t3_cookie_release(cookie);
484 static int receive_system_code(uint8_t *resp, int length, void *data)
486 struct t3_cookie *cookie = data;
488 struct type3_cmd cmd;
489 uint16_t system_code;
491 DBG(" length: %d", length);
498 err = check_recv_frame(resp, RESP_POLL);
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];
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,
515 case FELICA_LITE_S_IC_TYPE:
516 case FELICA_PLUG_IC_TYPE:
518 cmd.cmd = CMD_POLL; /* POLL command */
519 cmd.data[0] = 0x12; /* System code (NFC SC) */
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 ;
526 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
527 cmd.len, poll_ndef_system_code, cookie);
536 if (err < 0 && cookie->cb)
537 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
539 t3_cookie_release(cookie);
544 static int nfctype3_read(uint32_t adapter_idx,
545 uint32_t target_idx, near_tag_io_cb cb)
547 struct type3_cmd cmd;
548 struct t3_cookie *cookie;
554 cmd.cmd = CMD_POLL; /* POLL command */
555 cmd.data[0] = 0xFF; /* System code */
557 cmd.data[2] = 01; /* request code */
558 cmd.data[3] = 0x00; /* time slot */
560 /* data len + 2 bytes */
561 cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
563 cookie = g_try_malloc0(sizeof(struct t3_cookie));
567 cookie->adapter_idx = adapter_idx;
568 cookie->target_idx = target_idx;
571 err = near_adapter_send(adapter_idx, (uint8_t *)&cmd,
572 cmd.len , receive_system_code, cookie);
579 static int update_attr_block_cb(uint8_t *resp, int length, void *data)
581 struct t3_cookie *cookie = data;
591 err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
599 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
601 t3_cookie_release(cookie);
606 static int update_attr_block(struct t3_cookie *cookie)
608 struct type3_cmd cmd;
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;
620 for (i = 0; i < (BLOCK_SIZE - CHECKSUM_LEN); i++)
621 checksum += cookie->attr[i];
623 cookie->attr[14] = (uint8_t) (checksum >> 8);
624 cookie->attr[15] = (uint8_t) checksum;
626 prepare_write_block(cookie->IDm, &cmd, 0, cookie->attr);
628 return near_adapter_send(cookie->adapter_idx, (uint8_t *) &cmd, cmd.len,
629 update_attr_block_cb, cookie);
632 static int data_write_resp(uint8_t *resp, int length, void *data)
634 struct t3_cookie *cookie = data;
635 struct type3_cmd cmd;
636 uint8_t padding[BLOCK_SIZE] = {0};
646 err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
650 if (cookie->ndef->offset >= cookie->ndef->length) {
651 err = update_attr_block(cookie);
658 if ((cookie->ndef->length - cookie->ndef->offset) <
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);
665 prepare_write_block(cookie->IDm, &cmd, cookie->current_block,
666 cookie->ndef->data + cookie->ndef->offset);
669 cookie->current_block++;
670 cookie->ndef->offset += BLOCK_SIZE;
672 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd, cmd.len,
673 data_write_resp, cookie);
680 if (err < 0 && cookie->cb)
681 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
683 t3_cookie_release(cookie);
688 static int data_write(uint32_t adapter_idx, uint32_t target_idx,
689 struct near_ndef_message *ndef,
690 struct near_tag *tag,
693 struct t3_cookie *cookie;
694 struct type3_cmd cmd;
695 uint16_t checksum, nmaxb;
702 cookie = g_try_malloc0(sizeof(struct t3_cookie));
703 if (cookie == NULL) {
708 cookie->adapter_idx = adapter_idx;
709 cookie->target_idx = target_idx;
712 cookie->current_block = 0;
714 idm = near_tag_get_idm(tag, &len);
720 memcpy(cookie->IDm, idm, len);
722 attr = near_tag_get_attr_block(tag, &len);
728 memcpy(cookie->attr, attr, len);
729 nmaxb = (((uint16_t)(cookie->attr[3])) << 8) | cookie->attr[4];
731 if (cookie->ndef->length > (nmaxb * BLOCK_SIZE)) {
732 near_error("not enough space on tag");
737 cookie->attr[9] = 0x0F; /* writing data in progress */
740 for (i = 0; i < 14; i++)
741 checksum += cookie->attr[i];
743 cookie->attr[14] = (uint8_t)(checksum >> 8);
744 cookie->attr[15] = (uint8_t)(checksum);
746 prepare_write_block(cookie->IDm, &cmd, cookie->current_block,
748 cookie->current_block++;
750 err = near_adapter_send(adapter_idx, (uint8_t *)&cmd, cmd.len,
751 data_write_resp, cookie);
758 t3_cookie_release(cookie);
763 static int nfctype3_write(uint32_t adapter_idx, uint32_t target_idx,
764 struct near_ndef_message *ndef,
767 struct near_tag *tag;
771 if (ndef == NULL || cb == NULL)
774 tag = near_tag_get_tag(adapter_idx, target_idx);
778 return data_write(adapter_idx, target_idx, ndef, tag, cb);
781 static int nfctype3_check_recv_UID(uint8_t *resp, int length, void *data)
783 struct t3_cookie *rcv_cookie = data;
786 DBG("length %d", length);
792 rcv_cookie->cb(rcv_cookie->adapter_idx,
793 rcv_cookie->target_idx, err);
795 t3_cookie_release(rcv_cookie);
800 static int nfctype3_check_presence(uint32_t adapter_idx,
801 uint32_t target_idx, near_tag_io_cb cb)
803 struct type3_cmd cmd;
804 struct t3_cookie *cookie;
810 cmd.cmd = CMD_POLL; /* POLL command */
811 cmd.data[0] = 0xFF; /* System code */
813 cmd.data[2] = 01; /* request code */
814 cmd.data[3] = 0x00; /* time slot */
816 /* data len + 2 bytes */
817 cmd.len = LEN_CMD + LEN_CMD_LEN + 4 ;
819 cookie = g_try_malloc0(sizeof(struct t3_cookie));
823 cookie->adapter_idx = adapter_idx;
824 cookie->target_idx = target_idx;
827 err = near_adapter_send(adapter_idx, (uint8_t *)&cmd,
828 cmd.len , nfctype3_check_recv_UID, cookie);
835 t3_cookie_release(cookie);
840 static int format_resp(uint8_t *resp, int length, void *data)
842 struct near_tag *tag;
843 struct t3_cookie *cookie = data;
853 err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
857 tag = near_tag_get_tag(cookie->adapter_idx, cookie->target_idx);
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);
868 DBG("Formatting is done");
872 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
874 t3_cookie_release(cookie);
879 static int write_attr_block(uint8_t *resp, int length , void *data)
881 struct type3_cmd cmd;
882 struct t3_cookie *cookie = data;
884 uint16_t checksum = 0;
886 DBG("length %d", length);
893 err = check_recv_frame(resp, RESP_WRITE_WO_ENCRYPT);
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);
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;
912 for (i = 0; i < (BLOCK_SIZE - CHECKSUM_LEN); i++)
913 checksum += cookie->attr[i];
915 cookie->attr[14] = (uint8_t) (checksum >> 8);
916 cookie->attr[15] = (uint8_t) checksum;
918 prepare_write_block(cookie->IDm, &cmd, META_BLOCK_START,
921 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
922 cmd.len, format_resp, cookie);
929 if (err < 0 && cookie->cb)
930 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
932 t3_cookie_release(cookie);
937 static int write_mc_block(uint8_t *resp, int length, void *data)
939 struct type3_cmd cmd;
940 struct t3_cookie *cookie = data;
943 DBG("length %d", length);
950 err = check_recv_frame(resp, RESP_READ_WO_ENCRYPT);
954 if (resp[OFS_READ_FLAG] != 0) {
955 DBG("Status 0x%x", resp[OFS_READ_FLAG]);
960 memcpy(cookie->mc_block, resp + 14, BLOCK_SIZE);
962 * By updating Byte3 to 01h means making Felica Lite
963 * compatible with NDEF.
965 cookie->mc_block[3] = 1;
966 prepare_write_block(cookie->IDm, &cmd, FELICA_LITE_MC_BLOCK,
968 err = near_adapter_send(cookie->adapter_idx, (uint8_t *)&cmd,
969 cmd.len, write_attr_block, cookie);
976 if (err < 0 && cookie->cb)
977 cookie->cb(cookie->adapter_idx, cookie->target_idx, err);
979 t3_cookie_release(cookie);
984 static int nfctype3_format(uint32_t adapter_idx,
985 uint32_t target_idx, near_tag_io_cb cb)
987 struct type3_cmd cmd;
988 struct near_tag *tag;
989 struct t3_cookie *cookie;
996 tag = near_tag_get_tag(adapter_idx, target_idx);
1000 ic_type = near_tag_get_ic_type(tag);
1001 if (ic_type != FELICA_LITE_IC_TYPE)
1004 cookie = g_try_malloc0(sizeof(struct t3_cookie));
1008 cookie->adapter_idx = adapter_idx;
1009 cookie->target_idx = target_idx;
1011 cookie->ic_type = ic_type;
1013 idm = near_tag_get_idm(tag, &len);
1019 memcpy(cookie->IDm, idm, len);
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);
1030 t3_cookie_release(cookie);
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,
1044 static int nfctype3_init(void)
1048 return near_tag_driver_register(&type1_driver);
1051 static void nfctype3_exit(void)
1055 near_tag_driver_unregister(&type1_driver);
1058 NEAR_PLUGIN_DEFINE(nfctype3, "NFC Forum Type 3 tags support", VERSION,
1059 NEAR_PLUGIN_PRIORITY_HIGH, nfctype3_init, nfctype3_exit)