1 |
''' |
2 |
''' Copyright (C) 2003 INRIA |
3 |
''' |
4 |
''' INRIA |
5 |
''' Domaine de Voluceau |
6 |
''' Rocquencourt - B.P. 105 |
7 |
''' 78153 Le Chesnay Cedex - France |
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 as published by |
11 |
''' the Free Software Foundation; either version 2 of the License, or |
12 |
''' (at your option) any later version. |
13 |
''' |
14 |
''' This program is distributed in the hope that it will be useful, |
15 |
''' but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
''' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
''' GNU General Public License for more details. |
18 |
''' |
19 |
''' You should have received a copy of the GNU General Public License |
20 |
''' along with this program; if not, write to the Free Software |
21 |
''' Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 |
''' |
23 |
''' Author: Loic Dachary <loic@gnu.org> |
24 |
''' |
25 |
.TH rfid 3 local |
26 |
.SH NAME |
27 |
rfid \- API to interact with RFID transponders (version @VERSION@) |
28 |
|
29 |
.SH SYNOPSIS |
30 |
.nf |
31 |
.ft CW |
32 |
#include <rfid.h> |
33 |
|
34 |
int rfid_init(rfid_t* rfid, const char* drivers); |
35 |
typedef int rfid_transponder_callback_t(rfid_t* rfid, |
36 |
int event, |
37 |
const rfid_transponder_t* transponder, |
38 |
void* data); |
39 |
typedef int rfid_inventory_callback_t(rfid_t* rfid, |
40 |
rfid_transponder_t** transponders, |
41 |
int transponders_length, |
42 |
void* data) |
43 |
int rfid_event_loop(rfid_t* rfid, int events_mask, |
44 |
rfid_transponder_callback_t* transponder_callback, |
45 |
rfid_inventory_callback_t* inventory_callback, |
46 |
void* data); |
47 |
int rfid_write(rfid_t* rfid, rfid_transponder_t* transponder); |
48 |
void rfid_end(rfid_t* rfid); |
49 |
|
50 |
rfid_transponder_t* rfid_transponder_alloc(rfid_t* rfid); |
51 |
void rfid_transponder_free(rfid_t* rfid, rfid_transponder_t* transponder); |
52 |
char* rfid_transponder_describe(rfid_t* rfid, rfid_transponder_t* transponder); |
53 |
int rfid_transponder_id_get(rfid_t* rfid, |
54 |
const rfid_transponder_t* transponder, |
55 |
char** idp); |
56 |
int rfid_transponder_id_set(rfid_t* rfid, |
57 |
rfid_transponder_t* transponder, |
58 |
char* id); |
59 |
|
60 |
char* rfid_strerror(rfid_t* rfid); |
61 |
int rfid_error(rfid_t* rfid); |
62 |
|
63 |
void rfid_options(rfid_t* rfid, int value); /* Macro */ |
64 |
const char* rfid_version(void); |
65 |
.ft R |
66 |
.fi |
67 |
|
68 |
.SH HELP MAKE RFID USELESS TO BIG BROTHER |
69 |
|
70 |
The RFID technology is an essential component to implement a world of |
71 |
total control. Unless citizens and scientists require safeguards, it |
72 |
can be used by corporations or governments to track and record about |
73 |
everything. At present (May 2003), this issue is not addressed at all: |
74 |
corporations are allowed to include RFID tags in any objects they like |
75 |
and citizens have no way to get rid of them. The standard used to |
76 |
dialog with a RFID tag (ISO-15693) does not even provide a way to |
77 |
permanently shut it down. |
78 |
|
79 |
We strongly encourage every citizen, company or government to require |
80 |
that industry standards are modified to implement safeguards designed |
81 |
to protect the privacy of citizens. Statements should be sent to the |
82 |
standardization group (http://www.wg8.de/) but there is no open |
83 |
mailing list for this group. The editor of ISO-15693-3 is Alain |
84 |
Berthon (a-berthon@ti.com). The webmaster of wg8.de and the editor of |
85 |
ISO-14443-2 is Michael Hegenbarth (michael@hegenbarth.com). The |
86 |
statements sent should be friendly : the editors of the standards are |
87 |
our allies, not our enemies. The editors could use well written |
88 |
statements to push for functionalities protecting privacy but |
89 |
aggressive letters would be useless to them. Please cc: every |
90 |
statement to the rfid-privacy@nongnu.org public mailing list for |
91 |
archive (http://mail.nongnu.org/archive/html/rfid-privacy/) |
92 |
|
93 |
The "RFID tags: Big Brother in small packages" article by Declan |
94 |
McCullagh (http://news.com.com/2010-1069-980325.html) is good |
95 |
introduction to the problem. The conclusion is as follows: "First, |
96 |
consumers should be notified--a notice on a checkout receipt would |
97 |
work--when RFID tags are present in what they're buying. Second, RFID |
98 |
tags should be disabled by default at the checkout counter. Third, |
99 |
RFID tags should be placed on the product's packaging instead of on |
100 |
the product when possible. Fourth, RFID tags should be readily visible |
101 |
and easily removable." |
102 |
|
103 |
.SH DESCRIPTION |
104 |
|
105 |
.I rfid |
106 |
implements an API to interact with RFID transponders thru a RFID |
107 |
reader. The caller can monitor the state of the RFID reader and |
108 |
ask for callback functions to be called whenever an event occur (RFID |
109 |
transponder entering the range of the RFID reader etc.). The caller |
110 |
can also write or read the memory area of a RFID transponder. |
111 |
|
112 |
.I rfid |
113 |
relies on a driver to talk to the RFID reader. The set of |
114 |
drivers to be used is defined by a string such as |
115 |
.B "s6350" |
116 |
or |
117 |
.B "iso15693/s6350" |
118 |
that will be interpreted by the |
119 |
.I rfid_init |
120 |
function to dynamically load the appropriate modules. |
121 |
|
122 |
Each driver implements |
123 |
an abstract interface ( |
124 |
.I rfid_reader(3) |
125 |
) and |
126 |
.I rfid |
127 |
will use this interface to talk to it. The purpose of the |
128 |
.I rfid_reader(3) |
129 |
interface is to isolate |
130 |
.I rfid |
131 |
from driver changes. In the following scheme we see that |
132 |
.I rfid |
133 |
talks to the |
134 |
.I iso15693(3) |
135 |
RFID reader driver or the |
136 |
.I s6350(3) |
137 |
RFID reader driver using the same |
138 |
.I rfid_reader(3) |
139 |
interface. The scheme also shows that |
140 |
.I iso15693(3) |
141 |
is based on the |
142 |
.I s6350(3) |
143 |
but this is transparent to |
144 |
.I rfid. |
145 |
An application can use |
146 |
the |
147 |
.I rfid_reader(3) |
148 |
API instead of the higher level |
149 |
.I rfid |
150 |
API. It can also use the driver API (such as |
151 |
.I s6350(3)) |
152 |
but doing so |
153 |
means it will be bound to that specific driver which |
154 |
may be a drawback for maintainance. |
155 |
|
156 |
.nf |
157 |
.ft CW |
158 |
+----------------+ |
159 |
| Application | |
160 |
+-------+--------+ |
161 |
+-------+--------+ |
162 |
| rfid(3) | |
163 |
+-------+--------+ |
164 |
+-------+--------+ |
165 |
+---------| rfid_reader(3) +---+ |
166 |
| +--------+-------+ | |
167 |
| | | |
168 |
| | | |
169 |
+-----+-------+ +---+----+ +----+----+ |
170 |
| iso15693(3) | |m2xxh(3)| | s6350(3)| |
171 |
+-v--------v--+ +---+----+ +----+----+ |
172 |
| | | | |
173 |
+-----+---+ +--+------+ | | |
174 |
| s6350(3)| | m2xxh(3)| | | |
175 |
+-----v---+ +--v------+ | | |
176 |
| | | | |
177 |
| | | | |
178 |
+-->v<---+ | | |
179 |
| +--------+----+ | |
180 |
+---------+ RFID reader +------+ |
181 |
+-------------+ |
182 |
.ft R |
183 |
.fi |
184 |
|
185 |
.I rfid |
186 |
is thread safe, except for the |
187 |
.I rfid_init |
188 |
function and blocks signals (INT, QUIT, TERM) while |
189 |
communicating with the RFID reader to ensure that an interrupt will |
190 |
not leave the RFID reader in an undefined state. |
191 |
|
192 |
.SH FUNCTIONS |
193 |
|
194 |
.TP |
195 |
.B int rfid_init(rfid_t* rfid, const char* drivers) |
196 |
|
197 |
Load the drivers specified by the |
198 |
.B drivers |
199 |
argument. It can have one of the following values: "s6350", "m2xxh", |
200 |
"iso15693/s6350", "iso15693/m2xxh". In addition, if a driver is |
201 |
provided by a third party, specifying "otherdriver" will look for |
202 |
.I /usr/lib/rfid/libotherdriver.la |
203 |
or any similar file in the path defined by the |
204 |
.I LTDL_LIBRARY_PATH |
205 |
environment variable. |
206 |
|
207 |
The initialization function of the driver is then called. |
208 |
|
209 |
The |
210 |
.I rfid->io.device |
211 |
string must be set to a valid URL describing the device used |
212 |
to access the RFID reader. It must be a TTY device and values |
213 |
such as |
214 |
.I /dev/ttyS0 |
215 |
or |
216 |
.I /dev/ttyUSB0 |
217 |
are valid examples. |
218 |
|
219 |
Error codes: |
220 |
|
221 |
.B EINVAL |
222 |
rfid->io.device is NULL. |
223 |
|
224 |
.B ENOTTY |
225 |
rfid->io.device is not a tty. |
226 |
|
227 |
.B ENOEXEC |
228 |
RFID reader firmware is not loaded (s6350 only). |
229 |
|
230 |
.TP |
231 |
.B int rfid_event_loop(rfid_t* rfid, int events_mask, rfid_transponder_callback_t* transponder_callback, rfid_inventory_callback_t* inventory_callback, void* data) |
232 |
|
233 |
Infinite loop polling the RFID reader. The |
234 |
.I events_mask |
235 |
argument controls |
236 |
the calls to the |
237 |
.I transponder_callback |
238 |
and |
239 |
.I inventory_callback |
240 |
functions. |
241 |
If the |
242 |
.I RFID_EVENT_NEW |
243 |
or |
244 |
.I RFID_EVENT_DELETE |
245 |
or |
246 |
.I RFID_EVENT_AGAIN |
247 |
bits are |
248 |
set, the |
249 |
.I transponder_callback |
250 |
function will be called. If the |
251 |
.I RFID_EVENT_INVENTORY |
252 |
bit is set, the |
253 |
.I inventory_callback |
254 |
function will be |
255 |
called at the end of each iteration. |
256 |
|
257 |
An iteration starts with a full inventory of the RFID transponders |
258 |
currently in the range of the RFID reader. This inventory is compared |
259 |
to the previous inventory in order to figure out which RFID |
260 |
transponders just entered the range of the RFID reader |
261 |
(RFID_EVENT_NEW), which RFID transponders just left the range of the |
262 |
RFID reader (RFID_EVENT_DELETE) and which RFID transponders are still |
263 |
in the range of the RFID reader (RFID_EVENT_AGAIN). When this |
264 |
comparison is finished and all callbacks have been called, the |
265 |
iteration is over. |
266 |
|
267 |
The |
268 |
.I data |
269 |
argument is an opaque pointer that is passed to the callback functions. |
270 |
|
271 |
The complete list of macros that can be used to set the |
272 |
.I event_mask |
273 |
argument follows: |
274 |
|
275 |
.nf |
276 |
.ft CW |
277 |
#define RFID_EVENT_NEW 0x01 |
278 |
#define RFID_EVENT_DELETE 0x02 |
279 |
#define RFID_EVENT_AGAIN 0x04 |
280 |
#define RFID_EVENT_INVENTORY 0x08 |
281 |
#define RFID_EVENT_ALL 0xFF |
282 |
#define RFID_EVENT_NONE 0x00 |
283 |
.ft R |
284 |
.fi |
285 |
|
286 |
The |
287 |
.I transponder_callback |
288 |
function has the following prototype: |
289 |
|
290 |
.nf |
291 |
.ft CW |
292 |
typedef int rfid_transponder_callback_t(rfid_t* rfid, |
293 |
int event, |
294 |
const rfid_transponder_t* transponder, |
295 |
void* data); |
296 |
.ft R |
297 |
.fi |
298 |
|
299 |
The |
300 |
.I event |
301 |
argument is set to |
302 |
.I RFID_EVENT_NEW |
303 |
or |
304 |
.I RFID_EVENT_DELETE |
305 |
or |
306 |
.I RFID_EVENT_AGAIN |
307 |
depending on the event that triggered the call. The |
308 |
.I transponder |
309 |
argument has the following structure: |
310 |
|
311 |
.nf |
312 |
.ft CW |
313 |
typedef struct { |
314 |
u_int8_t data[RFID_TRANSPONDER_DATA_SIZE + 1]; /* + 1 for trailing NULL */ |
315 |
int data_length; /* Length of data in the |
316 |
data field. */ |
317 |
} rfid_transponder_t; |
318 |
.ft R |
319 |
.fi |
320 |
|
321 |
The |
322 |
.I data |
323 |
argument is an opaque pointer equal to the |
324 |
.I data |
325 |
argument of the |
326 |
.I rfid_event_loop |
327 |
function. |
328 |
|
329 |
The |
330 |
.I inventory_callback |
331 |
function has the following prototype: |
332 |
|
333 |
.nf |
334 |
.ft CW |
335 |
typedef int rfid_inventory_callback_t(rfid_t* rfid, |
336 |
rfid_transponder_t** transponders, |
337 |
int transponders_length, |
338 |
void* data) |
339 |
.ft R |
340 |
.fi |
341 |
|
342 |
The |
343 |
.I transponders |
344 |
argument is an array of pointers to |
345 |
.I rfid_transponder_t |
346 |
objects and the |
347 |
.I transponders_length |
348 |
is the number of pointers in the array. |
349 |
|
350 |
The |
351 |
.I data |
352 |
argument is an opaque pointer equal to the |
353 |
.I data |
354 |
argument of the |
355 |
.I rfid_event_loop |
356 |
function. |
357 |
|
358 |
The callback functions (either |
359 |
.I transponder_callback |
360 |
or |
361 |
.I inventory_callback |
362 |
functions) must return one of the following: |
363 |
|
364 |
.B RFID_CALLBACK_OK |
365 |
The callback succeeded and |
366 |
.I rfid_event_loop |
367 |
must continue to poll the RFID reader. |
368 |
|
369 |
.B RFID_CALLBACK_END |
370 |
The callback succeeded and |
371 |
.I rfid_event_loop |
372 |
must stop polling the RFID reader and return success. |
373 |
|
374 |
.B RFID_CALLBACK_ERROR |
375 |
The callback failed and |
376 |
.I rfid_event_loop |
377 |
must stop polling the RFID reader and return failure. |
378 |
|
379 |
.TP |
380 |
.B int rfid_write(rfid_t* rfid, rfid_transponder_t* transponder) |
381 |
|
382 |
Write |
383 |
.B transponder->data_length |
384 |
bytes from |
385 |
.B transponder->data |
386 |
to a RFID transponder. If no RFID transponder is available, the |
387 |
.I rfid_write |
388 |
function will wait for a RFID transponder to become available. |
389 |
|
390 |
If the |
391 |
.I transponder |
392 |
unique identifier is set |
393 |
(presumably because the |
394 |
.I transponder |
395 |
was obtained by |
396 |
.I rfid_event_loop |
397 |
or because the caller used |
398 |
.I rfid_transponder_id_set) |
399 |
the |
400 |
.I rfid_write |
401 |
function will fail if the RFID transponder presented to the |
402 |
RFID reader does not match. If the |
403 |
.I transponder |
404 |
unique identifier is not set, the data is written to whatever |
405 |
RFID transponder is in the range of the RFID reader. |
406 |
|
407 |
.nf |
408 |
.ft CW |
409 |
typedef struct { |
410 |
u_int8_t data[RFID_TRANSPONDER_DATA_SIZE + 1]; /* + 1 for trailing |
411 |
NULL */ |
412 |
int data_length; /* Length of data in the |
413 |
data field. */ |
414 |
} rfid_transponder_t; |
415 |
.ft R |
416 |
.fi |
417 |
|
418 |
Error codes: |
419 |
|
420 |
.B EXDEV |
421 |
RFID transponder presented to the RFID reader does not match the |
422 |
identity specified in |
423 |
.I transponder->info. |
424 |
|
425 |
.TP |
426 |
.B rfid_transponder_t* rfid_transponder_alloc(rfid_t* rfid) |
427 |
|
428 |
Return a new |
429 |
.I rfid_transponder_t |
430 |
object. |
431 |
|
432 |
It is the responsibility of the caller to free the |
433 |
object using |
434 |
.I rfid_transponder_free. |
435 |
|
436 |
.TP |
437 |
.B void rfid_transponder_free(rfid_t* rfid, rfid_transponder_t* transponder) |
438 |
|
439 |
Free |
440 |
.I transponder |
441 |
previously allocated by |
442 |
.I rfid_transponder_alloc. |
443 |
|
444 |
.TP |
445 |
.B char* rfid_transponder_describe(rfid_t* rfid, rfid_transponder_t* transponder) |
446 |
|
447 |
Return a malloc'ed string containing a null terminated human readable |
448 |
description of the |
449 |
.I transponder |
450 |
argument. |
451 |
|
452 |
It is the responsibility of the caller to |
453 |
.I free(3) |
454 |
the returned string. |
455 |
|
456 |
.TP |
457 |
.B int rfid_transponder_id_get(rfid_t* rfid, const rfid_transponder_t* transponder, char** idp) |
458 |
Return a null terminated string containing an ascii representation of the |
459 |
unique identifier of the |
460 |
.I transponder |
461 |
argument. |
462 |
|
463 |
The string is malloc'ed and returned in the |
464 |
.I *idp |
465 |
argument. |
466 |
|
467 |
It is the responsibility of the caller to |
468 |
.I free(3) |
469 |
the returned string. |
470 |
|
471 |
.TP |
472 |
.B int rfid_transponder_id_set(rfid_t* rfid, rfid_transponder_t* transponder, char* id) |
473 |
|
474 |
Set the unique identifier of the |
475 |
.I tranponder |
476 |
from the ascii representation provided in the null terminated string |
477 |
.I id. |
478 |
|
479 |
.TP |
480 |
.B char* rfid_strerror(rfid_t* rfid) |
481 |
|
482 |
Return a string describing the last error. It is the responsibility |
483 |
of the caller to |
484 |
.I free(3) |
485 |
the returned string. |
486 |
|
487 |
.TP |
488 |
.B int rfid_error(rfid_t* rfid) |
489 |
|
490 |
Return the latest error number. All error numbers are |
491 |
.I errno(3) |
492 |
error numbers whose semantic is described in the corresponding |
493 |
function description. |
494 |
|
495 |
.TP |
496 |
.B void rfid_options(rfid_t* rfid, int value) |
497 |
|
498 |
Set the options of the |
499 |
.I rfid |
500 |
library to |
501 |
.B value. |
502 |
|
503 |
Options are bits that can be or'ed together and that modify |
504 |
the behaviour of some functions as shown below: |
505 |
|
506 |
.B RFID_OPTION_DUMP_FRAMES: |
507 |
print each RFID reader command and response to |
508 |
stderr. |
509 |
|
510 |
.TP |
511 |
.B const char* rfid_version(void) |
512 |
|
513 |
Return the version number of the library, as a string. For |
514 |
instance "1.0.0". |
515 |
|
516 |
.SH SIGNALS |
517 |
|
518 |
SIGTERM, SIGQUIT and SIGINT are blocked while talking to the RFID |
519 |
reader. Signals are only blocked during a limited amount of time, |
520 |
to ensure that the RFID reader will not receive a truncated |
521 |
frame and that responses are read in full. Signals are blocked, not |
522 |
ignored. They will be delivered as soon as the |
523 |
.I rfid |
524 |
library function is finished. |
525 |
|
526 |
.SH DEBUG |
527 |
|
528 |
If the |
529 |
.B rfid->verbose |
530 |
is set to 1, |
531 |
.I rfid |
532 |
functions will print debugging information on the error output (stderr). |
533 |
The meaning of the debug characters is as follows: |
534 |
|
535 |
.B . (dot) |
536 |
Waiting for a specific RFID transponder to |
537 |
enter the range of the RFID reader. |
538 |
|
539 |
.B N |
540 |
A RFID transponder entered the range of the RFID reader. |
541 |
|
542 |
.B W |
543 |
A RFID transponder was successfully written. |
544 |
|
545 |
.B ! (bang) |
546 |
A recoverable communication error occurred with the RFID reader. |
547 |
|
548 |
.B A |
549 |
A RFID transponder that was previously reported to enter |
550 |
the range of the RFID reader is still present. |
551 |
|
552 |
.B D |
553 |
A RFID transponder left the range of the RFID transponder. |
554 |
|
555 |
.B / (slash) |
556 |
End of a |
557 |
.I rfid_event_loop |
558 |
iteration loop. |
559 |
|
560 |
.SH RETURN VALUES |
561 |
|
562 |
All functions returning an |
563 |
.I int |
564 |
will return 0 on success and -1 on |
565 |
error. If an error occurs, the error number is avaible thru the |
566 |
.I rfid_error |
567 |
function. The |
568 |
.I rfid_strerror |
569 |
function translates the error number into a human readable string. |
570 |
|
571 |
.SH SEE ALSO |
572 |
rfid_commander(1), rfid_reader(3), iso15693(3), s6350(3), m2xxh(3), errno(2) |
573 |
.nf |
574 |
.ft CW |
575 |
http://www.rfidwizards.com/ |
576 |
.ft R |
577 |
.fi |
578 |
|
579 |
.SH AUTHOR |
580 |
Copyright holder: INRIA, Domaine de Voluceau, Rocquencourt - B.P. 105, 78153 Le Chesnay Cedex - France |
581 |
|
582 |
Loic Dachary loic@gnu.org |
583 |
.nf |
584 |
.ft CW |
585 |
http://nongnu.org/projects/rfid/ |
586 |
.ft R |
587 |
.fi |