libnfc  1.4.2
arygon.c
Go to the documentation of this file.
1 /*-
2  * Public platform independent Near Field Communication (NFC) library
3  *
4  * Copyright (C) 2009, Roel Verdult
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>
18  */
19 
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif // HAVE_CONFIG_H
31 
32 #include "../drivers.h"
33 
34 #include <stdio.h>
35 #include <string.h>
36 #ifdef HAVE_STRINGS_H
37 # include <strings.h>
38 #endif
39 
40 #include "arygon.h"
41 
42 #include <nfc/nfc-messages.h>
43 
44 // Bus
45 #include "uart.h"
46 
47 #include <sys/param.h>
48 
52 #define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0'
53 
56 #define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1'
57 
60 #define DEV_ARYGON_PROTOCOL_TAMA '2'
61 
64 #define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
65 
66 #define SERIAL_DEFAULT_PORT_SPEED 9600
67 
68 // TODO Move this one level up for libnfc-1.6
69 static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
70 // XXX It seems that sending arygon_ack_frame to cancel current command is not allowed by ARYGON µC (see arygon_ack())
71 // static const byte_t arygon_ack_frame[] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
72 
73 static const byte_t arygon_error_none[] = "FF000000\x0d\x0a";
74 static const byte_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
75 static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
76 
77 // void arygon_ack (const nfc_device_spec_t nds);
78 bool arygon_reset_tama (const nfc_device_spec_t nds);
79 void arygon_firmware (const nfc_device_spec_t nds, char * str);
80 
81 bool arygon_check_communication (const nfc_device_spec_t nds);
82 
84 arygon_pick_device (void)
85 {
86  nfc_device_desc_t *pndd;
87 
88  if ((pndd = malloc (sizeof (*pndd)))) {
89  size_t szN;
90 
91  if (!arygon_list_devices (pndd, 1, &szN)) {
92  DBG ("%s", "arygon_list_devices failed");
93  free (pndd);
94  return NULL;
95  }
96 
97  if (szN == 0) {
98  DBG ("%s", "No device found");
99  free (pndd);
100  return NULL;
101  }
102  }
103  return pndd;
104 }
105 
106 bool
107 arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
108 {
112 #ifndef SERIAL_AUTOPROBE_ENABLED
113  (void) pnddDevices;
114  (void) szDevices;
115  *pszDeviceFound = 0;
116  DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
117  return false;
118 #else /* SERIAL_AUTOPROBE_ENABLED */
119  *pszDeviceFound = 0;
120 
121  serial_port sp;
122  const char *pcPorts[] = DEFAULT_SERIAL_PORTS;
123  const char *pcPort;
124  int iDevice = 0;
125 
126  while ((pcPort = pcPorts[iDevice++])) {
127  sp = uart_open (pcPort);
128  DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
129 
130  if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
131  uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
132 
133  if (!arygon_reset_tama((nfc_device_spec_t) sp))
134  continue;
135  uart_close (sp);
136 
137  // ARYGON reader is found
138  strncpy (pnddDevices[*pszDeviceFound].acDevice, "ARYGON", DEVICE_NAME_LENGTH - 1);
139  pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
140  pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
141  pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort);
142  pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
143  DBG ("Device found: %s (%s)", pnddDevices[*pszDeviceFound].acDevice, pcPort);
144  (*pszDeviceFound)++;
145 
146  // Test if we reach the maximum "wanted" devices
147  if ((*pszDeviceFound) >= szDevices)
148  break;
149  }
150 # ifdef DEBUG
151  if (sp == INVALID_SERIAL_PORT)
152  DBG ("Invalid serial port: %s", pcPort);
153  if (sp == CLAIMED_SERIAL_PORT)
154  DBG ("Serial port already claimed: %s", pcPort);
155 # endif
156  /* DEBUG */
157  }
158 #endif /* SERIAL_AUTOPROBE_ENABLED */
159  return true;
160 }
161 
162 nfc_device_t *
163 arygon_connect (const nfc_device_desc_t * pndd)
164 {
165  serial_port sp;
166  nfc_device_t *pnd = NULL;
167 
168  DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
169  sp = uart_open (pndd->pcPort);
170 
171  if (sp == INVALID_SERIAL_PORT)
172  ERR ("Invalid serial port: %s", pndd->pcPort);
173  if (sp == CLAIMED_SERIAL_PORT)
174  ERR ("Serial port already claimed: %s", pndd->pcPort);
175  if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
176  return NULL;
177 
178  uart_set_speed (sp, pndd->uiSpeed);
179  if (!arygon_reset_tama((nfc_device_spec_t) sp)) {
180  return NULL;
181  }
182 
183  DBG ("Successfully connected to: %s", pndd->pcPort);
184 
185  // We have a connection
186  pnd = malloc (sizeof (nfc_device_t));
187  char acFirmware[10];
188  arygon_firmware((nfc_device_spec_t) sp, acFirmware);
189  snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s %s (%s)", pndd->acDevice, acFirmware, pndd->pcPort);
190  pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
191  pnd->nc = NC_PN532;
192  pnd->nds = (nfc_device_spec_t) sp;
193  pnd->bActive = true;
194 
195  return pnd;
196 }
197 
198 void
199 arygon_disconnect (nfc_device_t * pnd)
200 {
201  uart_close ((serial_port) pnd->nds);
202  free (pnd);
203 }
204 
205 #define TX_BUFFER_LENGTH (300)
206 #define RX_BUFFER_LENGTH (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD + sizeof(pn53x_ack_frame))
207 bool
208 arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx)
209 {
210  byte_t abtTxBuf[TX_BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "0x32 0x00 0x00 0xff"
211  byte_t abtRxBuf[RX_BUFFER_LENGTH];
212  size_t szRxBufLen;
213  size_t szReplyMaxLen = MIN(RX_BUFFER_LENGTH, *pszRx);
214  size_t szPos;
215  int res;
216 
217  // Packet length = data length (len) + checksum (1) + end of stream marker (1)
218  abtTxBuf[4] = szTx;
219  // Packet length checksum
220  abtTxBuf[5] = 256 - abtTxBuf[4];
221  // Copy the PN53X command into the packet buffer
222  memmove (abtTxBuf + 6, pbtTx, szTx);
223 
224  // Calculate data payload checksum
225  abtTxBuf[szTx + 6] = 0;
226  for (szPos = 0; szPos < szTx; szPos++) {
227  abtTxBuf[szTx + 6] -= abtTxBuf[szPos + 6];
228  }
229 
230  // End of stream marker
231  abtTxBuf[szTx + 7] = 0;
232 
233 #ifdef DEBUG
234  PRINT_HEX ("TX", abtTxBuf, szTx + 8);
235 #endif
236  res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTx + 8);
237  if (res != 0) {
238  ERR ("%s", "Unable to transmit data. (TX)");
239  pnd->iLastError = res;
240  return false;
241  }
242 #ifdef DEBUG
243  memset (abtRxBuf, 0x00, sizeof (abtRxBuf));
244 #endif
245  szRxBufLen = szReplyMaxLen;
246  res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
247  if (res != 0) {
248  ERR ("%s", "Unable to receive data. (RX)");
249  pnd->iLastError = res;
250  return false;
251  }
252 #ifdef DEBUG
253  PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
254 #endif
255 
256  // WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time
257  if (!pn53x_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
258  return false;
259 
260  szRxBufLen -= sizeof (pn53x_ack_frame);
261  memmove (abtRxBuf, abtRxBuf + sizeof (pn53x_ack_frame), szRxBufLen);
262  szReplyMaxLen -= sizeof (pn53x_ack_frame);
263 
264  if (szRxBufLen == 0) {
265  do {
266  delay_ms (10);
267  szRxBufLen = szReplyMaxLen;
268  res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
269  } while (res != 0);
270 #ifdef DEBUG
271  PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
272 #endif
273  }
274 
275  if (!pn53x_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen))
276  return false;
277 
278  // When the answer should be ignored, just return a successful result
279  if (pbtRx == NULL || pszRx == NULL)
280  return true;
281 
282  // Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable)
283  if (szRxBufLen < 9)
284  return false;
285 
286  // Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable)
287  *pszRx = szRxBufLen - 9;
288  memcpy (pbtRx, abtRxBuf + 7, *pszRx);
289 
290  return true;
291 }
292 
293 void
294 arygon_firmware (const nfc_device_spec_t nds, char * str)
295 {
296  const byte_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
297  byte_t abtRx[RX_BUFFER_LENGTH];
298  size_t szRx = 16;
299  int res;
300 
301 #ifdef DEBUG
302  PRINT_HEX ("TX", arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
303 #endif
304  uart_send ((serial_port) nds, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
305 
306  res = uart_receive ((serial_port) nds, abtRx, &szRx);
307  if (res != 0) {
308  DBG ("Unable to retrieve ARYGON firmware version.");
309  return;
310  }
311 #ifdef DEBUG
312  PRINT_HEX ("RX", abtRx, szRx);
313 #endif
314  if ( 0 == memcmp (abtRx, arygon_error_none, 6)) {
315  byte_t * p = abtRx + 6;
316  unsigned int szData;
317  sscanf ((const char*)p, "%02x%s", &szData, p);
318  memcpy (str, p, szData);
319  *(str + szData) = '\0';
320  }
321 }
322 
323 bool
324 arygon_reset_tama (const nfc_device_spec_t nds)
325 {
326  const byte_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
327  byte_t abtRx[RX_BUFFER_LENGTH];
328  size_t szRx = 10; // Attempted response is 10 bytes long
329  int res;
330 
331  // Sometimes the first byte we send is not well-transmited (ie. a previously sent data on a wrong baud rate can put some junk in buffer)
332 #ifdef DEBUG
333  PRINT_HEX ("TX", arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
334 #endif
335  uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
336 
337  // Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent)
338  // or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted)
339  res = uart_receive ((serial_port) nds, abtRx, &szRx);
340  if (res != 0) {
341  DBG ("No reply to 'reset TAMA' command.");
342  return false;
343  }
344 #ifdef DEBUG
345  PRINT_HEX ("RX", abtRx, szRx);
346 #endif
347  if ( 0 == memcmp (abtRx, arygon_error_unknown_mode, sizeof (arygon_error_unknown_mode) - 1)) {
348  // HACK Here we are... the first byte wasn't sent as expected, so we resend the same command
349 #ifdef DEBUG
350  PRINT_HEX ("TX", arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
351 #endif
352  uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
353  res = uart_receive ((serial_port) nds, abtRx, &szRx);
354  if (res != 0) {
355  return false;
356  }
357 #ifdef DEBUG
358  PRINT_HEX ("RX", abtRx, szRx);
359 #endif
360  }
361  if (0 != memcmp (abtRx, arygon_error_none, sizeof (arygon_error_none) - 1)) {
362  return false;
363  }
364 
365  return true;
366 }
367 
368 /*
369 void
370 arygon_ack (const nfc_device_spec_t nds)
371 {
372  byte_t abtRx[BUFFER_LENGTH];
373  size_t szRx;
374 #ifdef DEBUG
375  PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame));
376 #endif
377  uart_send ((serial_port) nds, arygon_ack_frame, sizeof (arygon_ack_frame));
378  uart_receive ((serial_port) nds, abtRx, &szRx);
379 #ifdef DEBUG
380  PRINT_HEX ("RX", abtRx, szRx);
381 #endif
382  // ARYGON device will send an arygon_error_incomplete_command when sending an
383  // ACK frame, and I (Romuald) don't know if the command is sent to PN or not
384  if (0 != memcmp (abtRx, arygon_error_incomplete_command, sizeof (arygon_error_incomplete_command) - 1)) {
385  return false;
386  }
387 }
388 */
389 
390 bool
391 arygon_check_communication (const nfc_device_spec_t nds)
392 {
393  byte_t abtRx[RX_BUFFER_LENGTH];
394  size_t szRx;
395  const byte_t attempted_result[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, // ACK
396  0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 }; // Reply
397  int res;
398 
400  const byte_t pncmd_communication_test[] =
401  { DEV_ARYGON_PROTOCOL_TAMA, // Header to passthrough front ARYGON µC (== directly talk to PN53x)
402  0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 0x00 };
403 
404 #ifdef DEBUG
405  PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
406 #endif
407  res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test));
408  if (res != 0) {
409  ERR ("%s", "Unable to transmit data. (TX)");
410  return false;
411  }
412 
413  res = uart_receive ((serial_port) nds, abtRx, &szRx);
414  if (res != 0) {
415  ERR ("%s", "Unable to receive data. (RX)");
416  return false;
417  }
418 #ifdef DEBUG
419  PRINT_HEX ("RX", abtRx, szRx);
420 #endif
421 
422  if (0 != memcmp (abtRx, attempted_result, sizeof (attempted_result))) {
423  DBG ("%s", "Communication test failed, result doesn't match to attempted one.");
424  return false;
425  }
426  return true;
427 }