libnfc
1.4.2
|
00001 /*- 00002 * Public platform independent Near Field Communication (NFC) library 00003 * 00004 * Copyright (C) 2009, Roel Verdult 00005 * 00006 * This program is free software: you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published by the 00008 * Free Software Foundation, either version 3 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but WITHOUT 00012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00014 * more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 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 // Bus 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 // TODO Move this one level up for libnfc-1.6 00069 static const byte_t pn53x_ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; 00070 // XXX It seems that sending arygon_ack_frame to cancel current command is not allowed by ARYGON µC (see arygon_ack()) 00071 // static const byte_t arygon_ack_frame[] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; 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 // void arygon_ack (const nfc_device_spec_t nds); 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 /* SERIAL_AUTOPROBE_ENABLED */ 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 // ARYGON reader is found 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 // Test if we reach the maximum "wanted" devices 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 /* DEBUG */ 00157 } 00158 #endif /* SERIAL_AUTOPROBE_ENABLED */ 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 // We have a connection 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 }; // Every packet must start with "0x32 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 // Packet length = data length (len) + checksum (1) + end of stream marker (1) 00218 abtTxBuf[4] = szTx; 00219 // Packet length checksum 00220 abtTxBuf[5] = 256 - abtTxBuf[4]; 00221 // Copy the PN53X command into the packet buffer 00222 memmove (abtTxBuf + 6, pbtTx, szTx); 00223 00224 // Calculate data payload checksum 00225 abtTxBuf[szTx + 6] = 0; 00226 for (szPos = 0; szPos < szTx; szPos++) { 00227 abtTxBuf[szTx + 6] -= abtTxBuf[szPos + 6]; 00228 } 00229 00230 // End of stream marker 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 // WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time 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 // When the answer should be ignored, just return a successful result 00279 if (pbtRx == NULL || pszRx == NULL) 00280 return true; 00281 00282 // Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable) 00283 if (szRxBufLen < 9) 00284 return false; 00285 00286 // Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable) 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; // Attempted response is 10 bytes long 00329 int res; 00330 00331 // 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) 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 // Two reply are possible from ARYGON device: arygon_error_none (ie. in case the byte is well-sent) 00338 // or arygon_error_unknown_mode (ie. in case of the first byte was bad-transmitted) 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 // HACK Here we are... the first byte wasn't sent as expected, so we resend the same command 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 void 00370 arygon_ack (const nfc_device_spec_t nds) 00371 { 00372 byte_t abtRx[BUFFER_LENGTH]; 00373 size_t szRx; 00374 #ifdef DEBUG 00375 PRINT_HEX ("TX", arygon_ack_frame, sizeof (arygon_ack_frame)); 00376 #endif 00377 uart_send ((serial_port) nds, arygon_ack_frame, sizeof (arygon_ack_frame)); 00378 uart_receive ((serial_port) nds, abtRx, &szRx); 00379 #ifdef DEBUG 00380 PRINT_HEX ("RX", abtRx, szRx); 00381 #endif 00382 // ARYGON device will send an arygon_error_incomplete_command when sending an 00383 // ACK frame, and I (Romuald) don't know if the command is sent to PN or not 00384 if (0 != memcmp (abtRx, arygon_error_incomplete_command, sizeof (arygon_error_incomplete_command) - 1)) { 00385 return false; 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, // ACK 00396 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbc, 0x00 }; // Reply 00397 int res; 00398 00400 const byte_t pncmd_communication_test[] = 00401 { DEV_ARYGON_PROTOCOL_TAMA, // Header to passthrough front ARYGON µC (== directly talk to PN53x) 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 }