00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #ifdef HAVE_CONFIG_H
00026 # include "config.h"
00027 #endif // HAVE_CONFIG_H
00028
00029 #include "../drivers.h"
00030
00031 #include <stdio.h>
00032 #include <string.h>
00033
00034 #include "pn532_uart.h"
00035
00036 #include <nfc/nfc.h>
00037 #include <nfc/nfc-messages.h>
00038
00039
00040 #include "uart.h"
00041
00042 #define BUFFER_LENGTH 256
00043
00044 #define SERIAL_DEFAULT_PORT_SPEED 115200
00045
00046 void pn532_uart_wakeup (const nfc_device_spec_t nds);
00047 bool pn532_uart_check_communication (const nfc_device_spec_t nds, bool * success);
00048
00049 nfc_device_desc_t *
00050 pn532_uart_pick_device (void)
00051 {
00052 nfc_device_desc_t *pndd;
00053
00054 if ((pndd = malloc (sizeof (*pndd)))) {
00055 size_t szN;
00056
00057 if (!pn532_uart_list_devices (pndd, 1, &szN)) {
00058 DBG ("%s", "pn532_uart_list_devices failed");
00059 return NULL;
00060 }
00061
00062 if (szN == 0) {
00063 DBG ("%s", "No device found");
00064 return NULL;
00065 }
00066 }
00067
00068 return pndd;
00069 }
00070
00071 bool
00072 pn532_uart_list_devices (nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound)
00073 {
00077 #ifndef SERIAL_AUTOPROBE_ENABLED
00078 (void) pnddDevices;
00079 (void) szDevices;
00080 *pszDeviceFound = 0;
00081 DBG ("%s", "Serial auto-probing have been disabled at compile time. Skipping autoprobe.");
00082 return false;
00083 #else
00084 *pszDeviceFound = 0;
00085
00086 serial_port sp;
00087 const char *pcPorts[] = DEFAULT_SERIAL_PORTS;
00088 const char *pcPort;
00089 int iDevice = 0;
00090
00091 while ((pcPort = pcPorts[iDevice++])) {
00092 sp = uart_open (pcPort);
00093 DBG ("Trying to find PN532 device on serial port: %s at %d bauds.", pcPort, SERIAL_DEFAULT_PORT_SPEED);
00094
00095 if ((sp != INVALID_SERIAL_PORT) && (sp != CLAIMED_SERIAL_PORT)) {
00096 bool bComOk;
00097
00098 uart_set_speed (sp, SERIAL_DEFAULT_PORT_SPEED);
00099
00100 pn532_uart_wakeup ((nfc_device_spec_t) sp);
00101
00102 if (!pn532_uart_check_communication ((nfc_device_spec_t) sp, &bComOk))
00103 return false;
00104 if (!bComOk)
00105 continue;
00106 uart_close (sp);
00107
00108 snprintf (pnddDevices[*pszDeviceFound].acDevice, DEVICE_NAME_LENGTH - 1, "%s (%s)", "PN532", pcPort);
00109 pnddDevices[*pszDeviceFound].acDevice[DEVICE_NAME_LENGTH - 1] = '\0';
00110 pnddDevices[*pszDeviceFound].pcDriver = PN532_UART_DRIVER_NAME;
00111 pnddDevices[*pszDeviceFound].pcPort = strdup (pcPort);
00112 pnddDevices[*pszDeviceFound].uiSpeed = SERIAL_DEFAULT_PORT_SPEED;
00113 DBG ("Device found: %s.", pnddDevices[*pszDeviceFound].acDevice);
00114 (*pszDeviceFound)++;
00115
00116
00117 if ((*pszDeviceFound) >= szDevices)
00118 break;
00119 }
00120 # ifdef DEBUG
00121 if (sp == INVALID_SERIAL_PORT)
00122 DBG ("Invalid serial port: %s", pcPort);
00123 if (sp == CLAIMED_SERIAL_PORT)
00124 DBG ("Serial port already claimed: %s", pcPort);
00125 # endif
00126
00127 }
00128 #endif
00129 return true;
00130 }
00131
00132 nfc_device_t *
00133 pn532_uart_connect (const nfc_device_desc_t * pndd)
00134 {
00135 serial_port sp;
00136 nfc_device_t *pnd = NULL;
00137 bool bComOk;
00138
00139 DBG ("Attempt to connect to: %s at %d bauds.", pndd->pcPort, pndd->uiSpeed);
00140 sp = uart_open (pndd->pcPort);
00141
00142 if (sp == INVALID_SERIAL_PORT)
00143 ERR ("Invalid serial port: %s", pndd->pcPort);
00144 if (sp == CLAIMED_SERIAL_PORT)
00145 ERR ("Serial port already claimed: %s", pndd->pcPort);
00146 if ((sp == CLAIMED_SERIAL_PORT) || (sp == INVALID_SERIAL_PORT))
00147 return NULL;
00148
00149 uart_set_speed (sp, pndd->uiSpeed);
00150
00151
00152 pn532_uart_wakeup ((nfc_device_spec_t) sp);
00153
00154 if (!pn532_uart_check_communication ((nfc_device_spec_t) sp, &bComOk))
00155 return NULL;
00156 if (!bComOk)
00157 return NULL;
00158
00159 DBG ("Successfully connected to: %s", pndd->pcPort);
00160
00161
00162 pnd = malloc (sizeof (nfc_device_t));
00163 strncpy (pnd->acName, pndd->acDevice, DEVICE_NAME_LENGTH - 1);
00164 pnd->acName[DEVICE_NAME_LENGTH - 1] = '\0';
00165
00166 pnd->nc = NC_PN532;
00167 pnd->nds = (nfc_device_spec_t) sp;
00168 pnd->bActive = true;
00169 pnd->bCrc = true;
00170 pnd->bPar = true;
00171 pnd->ui8TxBits = 0;
00172 return pnd;
00173 }
00174
00175 void
00176 pn532_uart_disconnect (nfc_device_t * pnd)
00177 {
00178 uart_close ((serial_port) pnd->nds);
00179 free (pnd);
00180 }
00181
00182 bool
00183 pn532_uart_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxLen, byte_t * pbtRx,
00184 size_t * pszRxLen)
00185 {
00186 byte_t abtTxBuf[BUFFER_LENGTH] = { 0x00, 0x00, 0xff };
00187 byte_t abtRxBuf[BUFFER_LENGTH];
00188 size_t szRxBufLen = BUFFER_LENGTH;
00189 size_t szPos;
00190 int res;
00191
00192 uint8_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
00193
00194
00195 abtTxBuf[3] = szTxLen;
00196
00197 abtTxBuf[4] = BUFFER_LENGTH - abtTxBuf[3];
00198
00199 memmove (abtTxBuf + 5, pbtTx, szTxLen);
00200
00201
00202 abtTxBuf[szTxLen + 5] = 0;
00203 for (szPos = 0; szPos < szTxLen; szPos++) {
00204 abtTxBuf[szTxLen + 5] -= abtTxBuf[szPos + 5];
00205 }
00206
00207
00208 abtTxBuf[szTxLen + 6] = 0;
00209
00210 #ifdef DEBUG
00211 PRINT_HEX ("TX", abtTxBuf, szTxLen + 7);
00212 #endif
00213 res = uart_send ((serial_port) pnd->nds, abtTxBuf, szTxLen + 7);
00214 if (res != 0) {
00215 ERR ("%s", "Unable to transmit data. (TX)");
00216 pnd->iLastError = res;
00217 return false;
00218 }
00219
00220 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
00221 if (res != 0) {
00222 ERR ("%s", "Unable to receive data. (RX)");
00223 pnd->iLastError = res;
00224 return false;
00225 }
00226 #ifdef DEBUG
00227 PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
00228 #endif
00229
00230
00231 if (!pn53x_transceive_check_ack_frame_callback (pnd, abtRxBuf, szRxBufLen))
00232 return false;
00233 szRxBufLen -= sizeof (ack_frame);
00234 memmove (abtRxBuf, abtRxBuf + sizeof (ack_frame), szRxBufLen);
00235
00236 if (szRxBufLen == 0) {
00237 szRxBufLen = BUFFER_LENGTH;
00238 do {
00239 delay_ms (10);
00240 res = uart_receive ((serial_port) pnd->nds, abtRxBuf, &szRxBufLen);
00241 } while (res != 0);
00242 #ifdef DEBUG
00243 PRINT_HEX ("RX", abtRxBuf, szRxBufLen);
00244 #endif
00245 }
00246
00247 #ifdef DEBUG
00248 PRINT_HEX ("TX", ack_frame, 6);
00249 #endif
00250 res = uart_send ((serial_port) pnd->nds, ack_frame, 6);
00251 if (res != 0) {
00252 ERR ("%s", "Unable to transmit data. (TX)");
00253 pnd->iLastError = res;
00254 return false;
00255 }
00256
00257 if (!pn53x_transceive_check_error_frame_callback (pnd, abtRxBuf, szRxBufLen))
00258 return false;
00259
00260
00261 if (pbtRx == NULL || pszRxLen == NULL)
00262 return true;
00263
00264
00265 if (szRxBufLen < 9) {
00266 pnd->iLastError = DEINVAL;
00267 return false;
00268 }
00269
00270 *pszRxLen = szRxBufLen - 9;
00271 memcpy (pbtRx, abtRxBuf + 7, *pszRxLen);
00272
00273 return true;
00274 }
00275
00276 void
00277 pn532_uart_wakeup (const nfc_device_spec_t nds)
00278 {
00279 byte_t abtRx[BUFFER_LENGTH];
00280 size_t szRxLen;
00284 const byte_t pncmd_pn532c106_wakeup_preamble[] =
00285 { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00, 0x00, 0xff, 0x03, 0xfd,
00286 0xd4, 0x14, 0x01, 0x17, 0x00 };
00287 #ifdef DEBUG
00288 PRINT_HEX ("TX", pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble));
00289 #endif
00290 uart_send ((serial_port) nds, pncmd_pn532c106_wakeup_preamble, sizeof (pncmd_pn532c106_wakeup_preamble));
00291 if (0 == uart_receive ((serial_port) nds, abtRx, &szRxLen)) {
00292 #ifdef DEBUG
00293 PRINT_HEX ("RX", abtRx, szRxLen);
00294 #endif
00295 }
00296 }
00297
00298 bool
00299 pn532_uart_check_communication (const nfc_device_spec_t nds, bool * success)
00300 {
00301 byte_t abtRx[BUFFER_LENGTH];
00302 size_t szRxLen;
00303 const byte_t attempted_result[] =
00304 { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x09, 0xf7, 0xD5, 0x01, 0x00, 'l', 'i', 'b', 'n', 'f', 'c',
00305 0xbc, 0x00 };
00306 int res;
00307
00309 const byte_t pncmd_communication_test[] =
00310 { 0x00, 0x00, 0xff, 0x09, 0xf7, 0xd4, 0x00, 0x00, 'l', 'i', 'b', 'n', 'f', 'c', 0xbe, 0x00 };
00311
00312 *success = false;
00313
00314 #ifdef DEBUG
00315 PRINT_HEX ("TX", pncmd_communication_test, sizeof (pncmd_communication_test));
00316 #endif
00317 res = uart_send ((serial_port) nds, pncmd_communication_test, sizeof (pncmd_communication_test));
00318 if (res != 0) {
00319 ERR ("%s", "Unable to transmit data. (TX)");
00320 return false;
00321 }
00322
00323 res = uart_receive ((serial_port) nds, abtRx, &szRxLen);
00324 if (res != 0) {
00325 ERR ("%s", "Unable to receive data. (RX)");
00326 return false;
00327 }
00328 #ifdef DEBUG
00329 PRINT_HEX ("RX", abtRx, szRxLen);
00330 #endif
00331
00332 if (0 == memcmp (abtRx, attempted_result, sizeof (attempted_result)))
00333 *success = true;
00334
00335 return true;
00336 }