add some known vendor codes
[librfid] / rfid_proto_mifare_ul.c
1
2 /* Mifare Ultralight implementation, PCD side.
3  *
4  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
5  *
6  */
7
8 /*
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2 
11  *  as published by the Free Software Foundation
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include <rfid/rfid.h>
29 #include <rfid/rfid_protocol.h>
30 #include <rfid/rfid_layer2.h>
31 //#include <rfid/rfid_layer2_iso14443b.h>
32
33 //#include <rfid/rfid_asic.h>
34 //#include <rfid/rfid_reader.h>
35
36 #include "rfid_iso14443_common.h"
37
38
39 #define MIFARE_UL_CMD_WRITE     0xA2
40 #define MIFARE_UL_CMD_READ      0x30
41
42 /* FIXME */
43 #define MIFARE_UL_READ_FWT      100
44 #define MIFARE_UL_WRITE_FWT     100
45
46 static int
47 mful_read(struct rfid_protocol_handle *ph, unsigned int page,
48           unsigned char *rx_data, unsigned int *rx_len)
49 {
50         unsigned char rx_buf[16];
51         unsigned int real_rx_len = sizeof(rx_buf);
52         unsigned char tx[2];
53         int ret;
54
55         if (page > 7)
56                 return -EINVAL;
57
58         tx[0] = MIFARE_UL_CMD_READ;
59         tx[1] = page & 0xff;
60
61         ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx_buf,
62                                          &real_rx_len, MIFARE_UL_READ_FWT, 0);
63
64         if (ret < 0)
65                 return ret;
66
67         if (real_rx_len < *rx_len)
68                 *rx_len = real_rx_len;
69
70         memcpy(rx_data, rx_buf, *rx_len);
71
72         return ret;
73 }
74
75 static int
76 mful_write(struct rfid_protocol_handle *ph, unsigned int page,
77            unsigned char *tx_data, unsigned int tx_len)
78 {
79         unsigned int i;
80         unsigned char tx[6];
81         unsigned char rx[1];
82         unsigned int rx_len;
83         int ret;
84
85         if (tx_len != 4 || page > 7)
86                 return -EINVAL;
87
88         tx[0] = MIFARE_UL_CMD_WRITE;
89         tx[1] = page & 0xff;
90
91         for (i = 0; i < 4; i++)
92                 tx[2+i] = tx_data[i];
93
94         ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx,
95                                          &rx_len, MIFARE_UL_WRITE_FWT, 0);
96                                         
97         /* FIXME:look at RX, check for ACK/NAK */
98
99         return ret;
100 }
101
102 static int
103 mful_transcieve(struct rfid_protocol_handle *ph,
104                 const unsigned char *tx_data, unsigned int tx_len,
105                 unsigned char *rx_data, unsigned int *rx_len,
106                 unsigned int timeout, unsigned int flags)
107 {
108         return -EINVAL;
109 }
110
111 static struct rfid_protocol_handle *
112 mful_init(struct rfid_layer2_handle *l2h)
113 {
114         struct rfid_protocol_handle *ph;
115         ph = malloc(sizeof(struct rfid_protocol_handle));
116         return ph;
117 }
118
119 static int mful_fini(struct rfid_protocol_handle *ph)
120 {
121         free(ph);
122         return 0;
123 }
124
125 struct rfid_protocol rfid_protocol_mful = {
126         .id     = RFID_PROTOCOL_MIFARE_UL,
127         .name   = "Mifare Ultralight",
128         .fn     = {
129                 .init           = &mful_init,
130                 /* .transcieve  = &mful_transcieve,*/
131                 .read           = &mful_read,
132                 .write          = &mful_write,
133                 .fini           = &mful_fini,
134         },
135 };