libnfc 1.3.9
|
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 #ifdef _WIN32 00041 # define bzero(a, b) memset(a, 0x00, b) 00042 #endif 00043 00044 #include "arygon.h" 00045 00046 #include <nfc/nfc-messages.h> 00047 00048 // Bus 00049 #include "uart.h" 00050 00051 #define BUFFER_LENGTH 256 00052 00056 #define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0' 00057 00060 #define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1' 00061 00064 #define DEV_ARYGON_PROTOCOL_TAMA '2' 00065 00068 #define DEV_ARYGON_PROTOCOL_TAMA_WAB '3' 00069 00070 #define SERIAL_DEFAULT_PORT_SPEED 9600 00071 00072 bool arygon_check_communication (const nfc_device_spec_t nds); 00073 00081 nfc_device_desc_t * 00082 arygon_pick_device (void) 00083 { 00084 nfc_device_desc_t *pndd; 00085 00086 if ((pndd = malloc (sizeof (*pndd)))) { 00087 size_t szN; 00088 00089 if (!arygon_list_devices (pndd, 1, &szN)) { 00090 DBG ("%s", "arygon_list_devices failed"); 00091 return NULL; 00092 } 00093 00094 if (szN == 0) { 00095 DBG ("%s", "No device found"); 00096 return NULL; 00097 } 00098 } 00099 00100 return pndd; 00101 } 00102 00103 bool 00104 arygon_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound) 00105 { 00109 #ifndef SERIAL_AUTOPROBE_ENABLED 00110 (void) pnddDevices; 00111 (void) szDevices; 00112 *pszDeviceFound = 0; 00113 DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe."); 00114 return false; 00115 #else /* SERIAL_AUTOPROBE_ENABLED */ 00116 *pszDeviceFound = 0; 00117 00118 serial_port sp; 00119 const char *pcPorts[] = DEFAULT_SERIAL_PORTS; 00120 const char *pcPort; 00121 int iDevice = 0; 00122 00123 while ((pcPort = pcPorts[iDevice++])) { 00124 sp = uart_open (pcPort); 00125 DBG ("Trying to find ARYGON device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED); 00126 00127 if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) { 00128 uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED); 00129 if (!arygon_check_communication ((nfc_device_spec_t) sp)) 00130 continue; 00131 uart_close (sp); 00132 00133 // ARYGON reader is found 00134 snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "ARYGON", pcPort); 00135 pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0'; 00136 pnddDevices[*pszDeviceFound].pcDriver = ARYGON_DRIVER_NAME; 00137 pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort); 00138 pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED; 00139 DBG ("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice); 00140 (*pszDeviceFound)++; 00141 00142 // Test if we reach the maximum "wanted" devices 00143 if ((*pszDeviceFound) >= szDevices) 00144 break; 00145 } 00146 # ifdef DEBUG 00147 if (sp == INVALID_SERIAL_PORT) 00148 DBG ("Invalid serial port: %s", pcPort); 00149 if (sp == CLAIMED_SERIAL_PORT) 00150 DBG ("Serial port already claimed: %s", pcPort); 00151 # endif 00152 /* DEBUG */ 00153 } 00154 #endif /* SERIAL_AUTOPROBE_ENABLED */ 00155 return true; 00156 } 00157 00158 nfc_device_t * 00159 arygon_connect (const nfc_device_desc_t * pndd) 00160 { 00161 serial_port sp; 00162 nfc_device_t *pnd = NULL; 00163 00164 DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed); 00165 sp = uart_open (pndd->pcPort); 00166 00167 if (sp == INVALID_SERIAL_PORT) 00168 ERR ("Invalid serial port: %s", pndd->pcPort); 00169 if (sp == CLAIMED_SERIAL_PORT) 00170 ERR ("Serial port already claimed: %s", pndd->pcPort); 00171 if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT)) 00172 return NULL; 00173 00174 uart_set_speed (sp, pndd->uiSpeed); 00175 00176 DBG ("Successfully connected to: %s", pndd->pcPort); 00177 00178 // We have a connection 00179 pnd = malloc (sizeof (nfc_device_t)); 00180 strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1); 00181 pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0'; 00182 00183 pnd->nc = NC_PN532; 00184 pnd->nds = (nfc_device_spec_t) sp; 00185 pnd->bActive = true; 00186 pnd->bCrc = true; 00187 pnd->bPar = true; 00188 pnd->ui8TxBits = 0; 00189 return pnd; 00190 } 00191 00192 void 00193 arygon_disconnect (nfc_device_t * pnd) 00194 { 00195 uart_close ((serial_port) pnd->nds); 00196 free (pnd); 00197 } 00198 00199 bool 00200 arygon_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx, size_t * pszRxLen) 00201 { 00202 byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" 00203 byte_t abtRxBuf[BUFFER_LENGTH]; 00204 size_t szRxBufLen = BUFFER_LENGTH; 00205 size_t szPos; 00206 int res; 00207 // TODO: Move this one level up for libnfc-1.6 00208 uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 }; 00209 00210 // Packet length = data length (len) + checksum (1) + end of stream marker (1) 00211 abtTxBuf[4] = szTxLen; 00212 // Packet length checksum 00213 abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4]; 00214 // Copy the PN53X command into the packet buffer 00215 memmove (abtTxBuf + 6, pbtTx, szTxLen); 00216 00217 // Calculate data payload checksum 00218 abtTxBuf[szTxLen + 6] = 0; 00219 for (szPos = 0; szPos < szTxLen; szPos++) { 00220 abtTxBuf[szTxLen + 6] -= abtTxBuf[szPos + 6]; 00221 } 00222 00223 // End of stream marker 00224 abtTxBuf[szTxLen + 7] = 0; 00225 00226 #ifdef DEBUG 00227 PRINT_HEX ("TX", abtTxBuf, szTxLen + 8); 00228 #endif 00229 res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTxLen + 8); 00230 if (res != 0) { 00231 ERR ("%s", "Unable to transmit data. (TX)"); 00232 pnd->iLastError = res; 00233 return false; 00234 } 00235 #ifdef DEBUG 00236 bzero (abtRxBuf, sizeof (abtRxBuf)); 00237 #endif 00238 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen); 00239 if (res != 0) { 00240 ERR ("%s", "Unable to receive data. (RX)"); 00241 pnd->iLastError = res; 00242 return false; 00243 } 00244 #ifdef DEBUG 00245 PRINT_HEX ("RX", abtRxBuf, szRxBufLen); 00246 #endif 00247 00248 // WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time 00249 if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen)) 00250 return false; 00251 00252 szRxBufLen -= sizeof (ack_frame); 00253 memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen); 00254 00255 if (szRxBufLen == 0) { 00256 szRxBufLen = BUFFER_LENGTH; 00257 do { 00258 delay_ms (10); 00259 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen); 00260 } while (res != 0); 00261 #ifdef DEBUG 00262 PRINT_HEX ("RX", abtRxBuf, szRxBufLen); 00263 #endif 00264 } 00265 00266 /* 00267 #ifdef DEBUG 00268 PRINT_HEX("TX", ack_frame, sizeof(ack_frame)); 00269 #endif 00270 res = uart_send((serial_port)pnd->nds, ack_frame, sizeof(ack_frame)); 00271 if (res != 0) { 00272 ERR("%s", "Unable to transmit data. (TX)"); 00273 pnd->iLastError = res; 00274 return false; 00275 } 00276 */ 00277 if (!pn53x_transceive_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen)) 00278 return false; 00279 00280 // When the answer should be ignored, just return a successful result 00281 if (pbtRx == NULL || pszRxLen == NULL) 00282 return true; 00283 00284 // Only succeed when the result is at least 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable) 00285 if (szRxBufLen < 9) 00286 return false; 00287 00288 // Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable) 00289 *pszRxLen = szRxBufLen - 9; 00290 memcpy (pbtRx, abtRxBuf + 7, *pszRxLen); 00291 00292 return true; 00293 } 00294 00295 //TODO Use tranceive function instead of raw uart send/receive for communication check. 00296 bool 00297 arygon_check_communication (const nfc_device_spec_t nds) 00298 { 00299 byte_t abtRx[BUFFER_LENGTH]; 00300 size_t szRxLen; 00301 const byte_t attempted_result[] = 00302 { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xD5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 00303 0xbc, 0x00 }; 00304 int res; 00305 00307 const byte_t pncmd_communication_test[] = 00308 { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 00309 0x00 }; 00310 00311 #ifdef DEBUG 00312 PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test)); 00313 #endif 00314 res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test)); 00315 if (res != 0) { 00316 ERR ("%s", "Unable to transmit data. (TX)"); 00317 return false; 00318 } 00319 00320 res = uart_receive ((serial_port) nds, abtRx, &szRxLen); 00321 if (res != 0) { 00322 ERR ("%s", "Unable to receive data. (RX)"); 00323 return false; 00324 } 00325 #ifdef DEBUG 00326 PRINT_HEX ("RX", abtRx, szRxLen); 00327 #endif 00328 00329 if (0 != memcmp (abtRx, attempted_result, sizeof (attempted_result))) { 00330 DBG ("%s", "Communication test failed, result doesn't match to attempted one."); 00331 return false; 00332 } 00333 return true; 00334 }