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
00030
00031
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <usb.h>
00036 #include <string.h>
00037
00038 #include "../drivers.h"
00039 #include "../bitutils.h"
00040
00041 #include <nfc/nfc-messages.h>
00042
00043 #define BUFFER_LENGTH 256
00044 #define USB_TIMEOUT 30000
00045
00046
00047 void get_end_points(struct usb_device *dev, usb_spec_t* pus)
00048 {
00049 uint32_t uiIndex;
00050 uint32_t uiEndPoint;
00051 struct usb_interface_descriptor* puid = dev->config->interface->altsetting;
00052
00053
00054 for(uiIndex = 0; uiIndex < puid->bNumEndpoints; uiIndex++)
00055 {
00056
00057 if(puid->endpoint[uiIndex].bmAttributes != USB_ENDPOINT_TYPE_BULK) continue;
00058
00059
00060 uiEndPoint = puid->endpoint[uiIndex].bEndpointAddress;
00061
00062
00063 if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
00064 {
00065 DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
00066 pus->uiEndPointIn = uiEndPoint;
00067 }
00068
00069
00070 if((uiEndPoint & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
00071 {
00072 DBG("Bulk endpoint in : 0x%02X", uiEndPoint);
00073 pus->uiEndPointOut = uiEndPoint;
00074 }
00075 }
00076 }
00077
00078 bool pn53x_usb_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t *pszDeviceFound,usb_candidate_t candidates[], int num_candidates, char * target_name)
00079 {
00080 int ret, i;
00081
00082 struct usb_bus *bus;
00083 struct usb_device *dev;
00084 usb_dev_handle *udev;
00085 uint32_t uiBusIndex = 0;
00086 char string[256];
00087
00088 string[0]= '\0';
00089 usb_init();
00090
00091 if ((ret= usb_find_busses() < 0)) return NULL;
00092 DBG("%d busses",ret);
00093 if ((ret= usb_find_devices() < 0)) return NULL;
00094 DBG("%d devices",ret);
00095
00096 *pszDeviceFound= 0;
00097
00098 for (bus = usb_get_busses(); bus; bus = bus->next)
00099 {
00100 for (dev = bus->devices; dev; dev = dev->next, uiBusIndex++)
00101 {
00102 for(i = 0; i < num_candidates; ++i)
00103 {
00104 DBG("Checking device %04x:%04x (%04x:%04x)",dev->descriptor.idVendor,dev->descriptor.idProduct,candidates[i].idVendor,candidates[i].idProduct);
00105 if (candidates[i].idVendor==dev->descriptor.idVendor && candidates[i].idProduct==dev->descriptor.idProduct)
00106 {
00107
00108
00109 if (dev->config == NULL || dev->config->interface == NULL || dev->config->interface->altsetting == NULL)
00110 {
00111
00112 continue;
00113 }
00114 if (dev->config->interface->altsetting->bNumEndpoints < 2)
00115 {
00116
00117 continue;
00118 }
00119 if (dev->descriptor.iManufacturer || dev->descriptor.iProduct)
00120 {
00121 udev = usb_open(dev);
00122 if(udev)
00123 {
00124 usb_get_string_simple(udev, dev->descriptor.iManufacturer, string, sizeof(string));
00125 if(strlen(string) > 0)
00126 strcpy(string + strlen(string)," / ");
00127 usb_get_string_simple(udev, dev->descriptor.iProduct, string + strlen(string), sizeof(string) - strlen(string));
00128 }
00129 usb_close(udev);
00130 }
00131 if(strlen(string) == 0)
00132 strcpy(pnddDevices[*pszDeviceFound].acDevice, target_name);
00133 else
00134 strcpy(pnddDevices[*pszDeviceFound].acDevice, string);
00135 pnddDevices[*pszDeviceFound].pcDriver = target_name;
00136 pnddDevices[*pszDeviceFound].uiBusIndex = uiBusIndex;
00137 (*pszDeviceFound)++;
00138 DBG("%s","Match!");
00139
00140 if((*pszDeviceFound) == szDevices)
00141 {
00142 DBG("Found %d devices",*pszDeviceFound);
00143 return true;
00144 }
00145 }
00146 }
00147 }
00148 }
00149 DBG("Found %d devices",*pszDeviceFound);
00150 if(*pszDeviceFound)
00151 return true;
00152 return false;
00153 }
00154
00155 nfc_device_t* pn53x_usb_connect(const nfc_device_desc_t* pndd,const char * target_name, int target_chip)
00156 {
00157 nfc_device_t* pnd = NULL;
00158 usb_spec_t* pus;
00159 usb_spec_t us;
00160 struct usb_bus *bus;
00161 struct usb_device *dev;
00162 uint32_t uiBusIndex;
00163
00164 us.uiEndPointIn = 0;
00165 us.uiEndPointOut = 0;
00166 us.pudh = NULL;
00167
00168
00169
00170 if(pndd == NULL) return NULL;
00171
00172 DBG("Connecting %s device",target_name);
00173 usb_init();
00174
00175 uiBusIndex= pndd->uiBusIndex;
00176
00177 DBG("Skipping to device no. %d",uiBusIndex);
00178 for (bus = usb_get_busses(); bus; bus = bus->next)
00179 {
00180 for (dev = bus->devices; dev; dev = dev->next, uiBusIndex--)
00181 {
00182 DBG("Checking device %04x:%04x",dev->descriptor.idVendor,dev->descriptor.idProduct);
00183 if(uiBusIndex == 0)
00184 {
00185 DBG("Found device index %d", pndd->uiBusIndex);
00186
00187
00188 us.pudh = usb_open(dev);
00189
00190 get_end_points(dev,&us);
00191 if(usb_set_configuration(us.pudh,1) < 0)
00192 {
00193 DBG("%s", "Setting config failed");
00194 usb_close(us.pudh);
00195
00196 return NULL;
00197 }
00198
00199 if(usb_claim_interface(us.pudh,0) < 0)
00200 {
00201 DBG("%s", "Can't claim interface");
00202 usb_close(us.pudh);
00203
00204 return NULL;
00205 }
00206
00207 pus = malloc(sizeof(usb_spec_t));
00208 *pus = us;
00209 pnd = malloc(sizeof(nfc_device_t));
00210 strcpy(pnd->acName,target_name);
00211 pnd->nc = target_chip;
00212 pnd->nds = (nfc_device_spec_t)pus;
00213 pnd->bActive = true;
00214 pnd->bCrc = true;
00215 pnd->bPar = true;
00216 pnd->ui8TxBits = 0;
00217 return pnd;
00218 }
00219 }
00220 }
00221
00222 DBG("%s","Device index not found!");
00223 return NULL;
00224 }
00225
00226 void pn53x_usb_disconnect(nfc_device_t* pnd)
00227 {
00228 usb_spec_t* pus = (usb_spec_t*)pnd->nds;
00229 int ret;
00230
00231 DBG("%s","resetting USB");
00232 usb_reset(pus->pudh);
00233 if((ret= usb_release_interface(pus->pudh,0)) < 0)
00234 DBG("usb_release failed %i",ret);
00235 if((ret= usb_close(pus->pudh)) < 0)
00236 DBG("usb_close failed %i",ret);
00237 free(pnd->nds);
00238 free(pnd);
00239 DBG("%s","done!");
00240 }
00241
00242 bool pn53x_usb_transceive(const nfc_device_spec_t nds, const byte_t* pbtTx, const size_t szTxLen, byte_t* pbtRx, size_t* pszRxLen)
00243 {
00244 size_t uiPos = 0;
00245 int ret = 0;
00246 byte_t abtTx[BUFFER_LENGTH] = { 0x00, 0x00, 0xff };
00247 byte_t abtRx[BUFFER_LENGTH];
00248 usb_spec_t* pus = (usb_spec_t*)nds;
00249
00250
00251 abtTx[3] = szTxLen;
00252
00253 abtTx[4] = BUFFER_LENGTH - abtTx[3];
00254
00255 memmove(abtTx+5,pbtTx,szTxLen);
00256
00257
00258 abtTx[szTxLen+5] = 0;
00259 for(uiPos=0; uiPos < szTxLen; uiPos++)
00260 {
00261 abtTx[szTxLen+5] -= abtTx[uiPos+5];
00262 }
00263
00264
00265 abtTx[szTxLen+6] = 0;
00266
00267 DBG("%s","pn53x_usb_transceive");
00268 #ifdef DEBUG
00269 printf(" TX: ");
00270 print_hex(abtTx,szTxLen+7);
00271 #endif
00272
00273 ret = usb_bulk_write(pus->pudh, pus->uiEndPointOut, (char*)abtTx, szTxLen+7, USB_TIMEOUT);
00274 if( ret < 0 )
00275 {
00276 DBG("usb_bulk_write failed with error %d", ret);
00277 return false;
00278 }
00279
00280 ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
00281 if( ret < 0 )
00282 {
00283 DBG( "usb_bulk_read failed with error %d", ret);
00284 return false;
00285 }
00286
00287 #ifdef DEBUG
00288 printf(" RX: ");
00289 print_hex(abtRx,ret);
00290 #endif
00291
00292 if( ret == 6 )
00293 {
00294 ret = usb_bulk_read(pus->pudh, pus->uiEndPointIn, (char*)abtRx, BUFFER_LENGTH, USB_TIMEOUT);
00295 if( ret < 0 )
00296 {
00297 DBG("usb_bulk_read failed with error %d", ret);
00298 return false;
00299 }
00300
00301 #ifdef DEBUG
00302 printf(" RX: ");
00303 print_hex(abtRx,ret);
00304 #endif
00305 }
00306
00307
00308 if(pbtRx == NULL || pszRxLen == NULL) return true;
00309
00310
00311 if(ret < 9)
00312 {
00313 DBG("%s","No data");
00314 return false;
00315 }
00316
00317
00318 *pszRxLen = ret - 7 - 2;
00319
00320
00321 if ((abtRx[5]==0xd5) && (abtRx[6]==0x07) && (*pszRxLen==2)) {
00322
00323 *pszRxLen = (*pszRxLen) - 1;
00324 memcpy( pbtRx, abtRx + 8, *pszRxLen);
00325 return true;
00326 }
00327
00328 memcpy( pbtRx, abtRx + 7, *pszRxLen);
00329
00330 return true;
00331 }