00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00028 #ifdef HAVE_CONFIG_H
00029 # include "config.h"
00030 #endif // HAVE_CONFIG_H
00031
00032 #include "../drivers.h"
00033
00034 #include <stdio.h>
00035 #include <string.h>
00036 #ifdef HAVE_STRINGS_H
00037 # include <strings.h>
00038 #endif
00039
00040 #include "arygon.h"
00041
00042 #include <nfc/nfc-messages.h>
00043
00044
00045 #include "uart.h"
00046
00047 #include <sys/param.h>
00048
00052 #define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0'
00053
00056 #define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1'
00057
00060 #define DEV_ARYGON_PROTOCOL_TAMA '2'
00061
00064 #define DEV_ARYGON_PROTOCOL_TAMA_WAB '3'
00065
00066 #define SERIAL_DEFAULT_PORT_SPEED 9600
00067
00068
00069 static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
00070
00071
00072
00073 static const byte_t arygon_error_none[] = "FF000000\x0d\x0a";
00074 static const byte_t arygon_error_incomplete_command[] = "FF0C0000\x0d\x0a";
00075 static const byte_t arygon_error_unknown_mode[] = "FF060000\x0d\x0a";
00076
00077
00078 bool arygon_reset_tama (const nfc_device_spec_t nds);
00079 void arygon_firmware (const nfc_device_spec_t nds, char * str);
00080
00081 bool arygon_check_communication (const nfc_device_spec_t nds);
00082
00083 nfc_device_desc_t *
00084 arygon_pick_device (void)
00085 {
00086 nfc_device_desc_t *pndd;
00087
00088 if ((pndd = malloc (sizeof (*pndd)))) {
00089 size_t szN;
00090
00091 if (!arygon_list_devices (pndd, 1, &szN)) {
00092 DBG ("%s", "arygon_list_devices failed");
00093 free (pndd);
00094 return NULL;
00095 }
00096
00097 if (szN == 0) {
00098 DBG ("%s", "No device found");
00099 free (pndd);
00100 return NULL;
00101 }
00102 }
00103 return pndd;
00104 }
00105
00106 bool
00107 arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
00108 {
00112 #ifndef SERIAL_AUTOPROBE_ENABLED
00113 (void) pnddDevices;
00114 (void) szDevices;
00115 *pszDeviceFound = 0;
00116 DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
00117 return false;
00118 #else
00119 *pszDeviceFound = 0;
00120
00121 serial_port sp;
00122 const char *pcPorts[] = DEFAULT_SERIAL_PORTS;
00123 const char *pcPort;
00124 int iDevice = 0;
00125
00126 while ((pcPort = pcPorts[iDevice++])) {
00127 sp = uart_open (pcPort);
00128 DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
00129
00130 if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
00131 uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
00132
00133 if (!arygon_reset_tama((nfc_device_spec_t) sp))
00134 continue;
00135 uart_close (sp);
00136
00137
00138 strncpy (pnddDevices[*pszDeviceFound].acDevice, "ARYGON", DEVICE_NAME_LENGTH - 1);
00139 pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
00140 pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME;
00141 pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort);
00142 pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
00143 DBG ("Device found: %s (%s)", pnddDevices[*pszDeviceFound].acDevice, pcPort);
00144 (*pszDeviceFound)++;
00145
00146
00147 if ((*pszDeviceFound) >= szDevices)
00148 break;
00149 }
00150 # ifdef DEBUG
00151 if (sp == INVALID_SERIAL_PORT)
00152 DBG ("Invalid serial port: %s", pcPort);
00153 if (sp == CLAIMED_SERIAL_PORT)
00154 DBG ("Serial port already claimed: %s", pcPort);
00155 # endif
00156
00157 }
00158 #endif
00159 return true;
00160 }
00161
00162 nfc_device_t *
00163 arygon_connect (const nfc_device_desc_t * pndd)
00164 {
00165 serial_port sp;
00166 nfc_device_t *pnd = NULL;
00167
00168 DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
00169 sp = uart_open (pndd->pcPort);
00170
00171 if (sp == INVALID_SERIAL_PORT)
00172 ERR ("Invalid serial port: %s", pndd->pcPort);
00173 if (sp == CLAIMED_SERIAL_PORT)
00174 ERR ("Serial port already claimed: %s", pndd->pcPort);
00175 if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
00176 return NULL;
00177
00178 uart_set_speed (sp, pndd->uiSpeed);
00179 if (!arygon_reset_tama((nfc_device_spec_t) sp)) {
00180 return NULL;
00181 }
00182
00183 DBG ("Successfully connected to: %s", pndd->pcPort);
00184
00185
00186 pnd = malloc (sizeof (nfc_device_t));
00187 char acFirmware[10];
00188 arygon_firmware((nfc_device_spec_t) sp, acFirmware);
00189 snprintf (pnd->acName, DEVICE_NAME_LENGTH - 1, "%s %s (%s)", pndd->acDevice, acFirmware, pndd->pcPort);
00190 pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
00191 pnd->nc = NC_PN532;
00192 pnd->nds = (nfc_device_spec_t) sp;
00193 pnd->bActive = true;
00194
00195 return pnd;
00196 }
00197
00198 void
00199 arygon_disconnect (nfc_device_t * pnd)
00200 {
00201 uart_close ((serial_port) pnd->nds);
00202 free (pnd);
00203 }
00204
00205 #define TX_BUFFER_LENGTH (300)
00206 #define RX_BUFFER_LENGTH (PN53x_EXTENDED_FRAME_MAX_LEN + PN53x_EXTENDED_FRAME_OVERHEAD + sizeof(pn53x_ack_frame))
00207 bool
00208 arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx)
00209 {
00210 byte_t abtTxBuf[TX_BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff };
00211 byte_t abtRxBuf[RX_BUFFER_LENGTH];
00212 size_t szRxBufLen;
00213 size_t szReplyMaxLen = MIN(RX_BUFFER_LENGTH, *pszRx);
00214 size_t szPos;
00215 int res;
00216
00217
00218 abtTxBuf[4] = szTx;
00219
00220 abtTxBuf[5] = 256 - abtTxBuf[4];
00221
00222 memmove (abtTxBuf + 6, pbtTx, szTx);
00223
00224
00225 abtTxBuf[szTx + 6] = 0;
00226 for (szPos = 0; szPos < szTx; szPos++) {
00227 abtTxBuf[szTx + 6] -= abtTxBuf[szPos + 6];
00228 }
00229
00230
00231 abtTxBuf[szTx + 7] = 0;
00232
00233 #ifdef DEBUG
00234 PRINT_HEX ("TX", abtTxBuf, szTx + 8);
00235 #endif
00236 res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTx + 8);
00237 if (res != 0) {
00238 ERR ("%s", "Unable to transmit data. (TX)");
00239 pnd->iLastError = res;
00240 return false;
00241 }
00242 #ifdef DEBUG
00243 memset (abtRxBuf, 0x00, sizeof (abtRxBuf));
00244 #endif
00245 szRxBufLen = szReplyMaxLen;
00246 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
00247 if (res != 0) {
00248 ERR ("%s", "Unable to receive data. (RX)");
00249 pnd->iLastError = res;
00250 return false;
00251 }
00252 #ifdef DEBUG
00253 PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
00254 #endif
00255
00256
00257 if (!pn53x_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
00258 return false;
00259
00260 szRxBufLen -= sizeof (pn53x_ack_frame);
00261 memmove (abtRxBuf, abtRxBuf + sizeof (pn53x_ack_frame), szRxBufLen);
00262 szReplyMaxLen -= sizeof (pn53x_ack_frame);
00263
00264 if (szRxBufLen == 0) {
00265 do {
00266 delay_ms (10);
00267 szRxBufLen = szReplyMaxLen;
00268 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
00269 } while (res != 0);
00270 #ifdef DEBUG
00271 PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
00272 #endif
00273 }
00274
00275 if (!pn53x_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen))
00276 return false;
00277
00278
00279 if (pbtRx == NULL || pszRx == NULL)
00280 return true;
00281
00282
00283 if (szRxBufLen < 9)
00284 return false;
00285
00286
00287 *pszRx = szRxBufLen - 9;
00288 memcpy (pbtRx, abtRxBuf + 7, *pszRx);
00289
00290 return true;
00291 }
00292
00293 void
00294 arygon_firmware (const nfc_device_spec_t nds, char * str)
00295 {
00296 const byte_t arygon_firmware_version_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'v' };
00297 byte_t abtRx[RX_BUFFER_LENGTH];
00298 size_t szRx = 16;
00299 int res;
00300
00301 #ifdef DEBUG
00302 PRINT_HEX ("TX", arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
00303 #endif
00304 uart_send ((serial_port) nds, arygon_firmware_version_cmd, sizeof (arygon_firmware_version_cmd));
00305
00306 res = uart_receive ((serial_port) nds, abtRx, &szRx);
00307 if (res != 0) {
00308 DBG ("Unable to retrieve ARYGON firmware version.");
00309 return;
00310 }
00311 #ifdef DEBUG
00312 PRINT_HEX ("RX", abtRx, szRx);
00313 #endif
00314 if ( 0 == memcmp (abtRx, arygon_error_none, 6)) {
00315 byte_t * p = abtRx + 6;
00316 unsigned int szData;
00317 sscanf ((const char*)p, "%02x%s", &szData, p);
00318 memcpy (str, p, szData);
00319 *(str + szData) = '\0';
00320 }
00321 }
00322
00323 bool
00324 arygon_reset_tama (const nfc_device_spec_t nds)
00325 {
00326 const byte_t arygon_reset_tama_cmd[] = { DEV_ARYGON_PROTOCOL_ARYGON_ASCII, 'a', 'r' };
00327 byte_t abtRx[RX_BUFFER_LENGTH];
00328 size_t szRx = 10;
00329 int res;
00330
00331
00332 #ifdef DEBUG
00333 PRINT_HEX ("TX", arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
00334 #endif
00335 uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
00336
00337
00338
00339 res = uart_receive ((serial_port) nds, abtRx, &szRx);
00340 if (res != 0) {
00341 DBG ("No reply to 'reset TAMA' command.");
00342 return false;
00343 }
00344 #ifdef DEBUG
00345 PRINT_HEX ("RX", abtRx, szRx);
00346 #endif
00347 if ( 0 == memcmp (abtRx, arygon_error_unknown_mode, sizeof (arygon_error_unknown_mode) - 1)) {
00348
00349 #ifdef DEBUG
00350 PRINT_HEX ("TX", arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
00351 #endif
00352 uart_send ((serial_port) nds, arygon_reset_tama_cmd, sizeof (arygon_reset_tama_cmd));
00353 res = uart_receive ((serial_port) nds, abtRx, &szRx);
00354 if (res != 0) {
00355 return false;
00356 }
00357 #ifdef DEBUG
00358 PRINT_HEX ("RX", abtRx, szRx);
00359 #endif
00360 }
00361 if (0 != memcmp (abtRx, arygon_error_none, sizeof (arygon_error_none) - 1)) {
00362 return false;
00363 }
00364
00365 return true;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 bool
00391 arygon_check_communication (const nfc_device_spec_t nds)
00392 {
00393 byte_t abtRx[RX_BUFFER_LENGTH];
00394 size_t szRx;
00395 const byte_t attempted_result[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
00396 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 };
00397 int res;
00398
00400 const byte_t pncmd_communication_test[] =
00401 { DEV_ARYGON_PROTOCOL_TAMA,
00402 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 0x00 };
00403
00404 #ifdef DEBUG
00405 PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
00406 #endif
00407 res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test));
00408 if (res != 0) {
00409 ERR ("%s", "Unable to transmit data. (TX)");
00410 return false;
00411 }
00412
00413 res = uart_receive ((serial_port) nds, abtRx, &szRx);
00414 if (res != 0) {
00415 ERR ("%s", "Unable to receive data. (RX)");
00416 return false;
00417 }
00418 #ifdef DEBUG
00419 PRINT_HEX ("RX", abtRx, szRx);
00420 #endif
00421
00422 if (0 != memcmp (abtRx, attempted_result, sizeof (attempted_result))) {
00423 DBG ("%s", "Communication test failed, result doesn't match to attempted one.");
00424 return false;
00425 }
00426 return true;
00427 }