diff --git a/src/dev_arygon.c b/src/dev_arygon.c index 997ac41..df25eee 100644 --- a/src/dev_arygon.c +++ b/src/dev_arygon.c @@ -34,7 +34,25 @@ along with this program. If not, see #define BUFFER_LENGTH 256 #define USB_TIMEOUT 30000 -static byte_t abtTxBuf[BUFFER_LENGTH] = { 0x32, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" + +/** @def DEV_ARYGON_PROTOCOL_ARYGON_ASCII + * @brief High level language in ASCII format. (Common µC commands and Mifare® commands) + */ +#define DEV_ARYGON_PROTOCOL_ARYGON_ASCII '0' +/** @def DEV_ARYGON_MODE_HL_ASCII + * @brief High level language in Binary format With AddressingByte for party line. (Common µC commands and Mifare® commands) + */ +#define DEV_ARYGON_PROTOCOL_ARYGON_BINARY_WAB '1' +/** @def DEV_ARYGON_PROTOCOL_TAMA + * @brief Philips protocol (TAMA language) in binary format. + */ +#define DEV_ARYGON_PROTOCOL_TAMA '2' +/** @def DEV_ARYGON_PROTOCOL_TAMA_WAB + * @brief Philips protocol (TAMA language) in binary With AddressingByte for party line. + */ +#define DEV_ARYGON_PROTOCOL_TAMA_WAB '3' + +static byte_t abtTxBuf[BUFFER_LENGTH] = { DEV_ARYGON_PROTOCOL_TAMA, 0x00, 0x00, 0xff }; // Every packet must start with "00 00 ff" dev_info* dev_arygon_connect(const uint32_t uiIndex) { @@ -42,11 +60,9 @@ dev_info* dev_arygon_connect(const uint32_t uiIndex) serial_port sp; char acConnect[BUFFER_LENGTH]; dev_info* pdi = INVALID_DEVICE_INFO; - -#ifdef DEBUG - printf("Trying to find ARYGON device on serial port: %s#\n",SERIAL_STRING); -#endif - + + DBG("Trying to find ARYGON device on serial port: %s#",SERIAL_STRING); + // I have no idea how MAC OS X deals with multiple devices, so a quick workaround for (uiDevNr=0; uiDevNracName,"ARYGON"); @@ -80,60 +94,65 @@ dev_info* dev_arygon_connect(const uint32_t uiIndex) pdi->bPar = true; pdi->ui8TxBits = 0; return pdi; -} +} void dev_arygon_disconnect(dev_info* pdi) { rs232_close((serial_port)pdi->ds); free(pdi); -} +} bool dev_arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_t uiTxLen, byte_t* pbtRx, uint32_t* puiRxLen) { byte_t abtRxBuf[BUFFER_LENGTH]; uint32_t uiRxBufLen = BUFFER_LENGTH; uint32_t uiPos; - + // Packet length = data length (len) + checksum (1) + end of stream marker (1) - abtTxBuf[4] = uiTxLen; - // Packet length checksum - abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4]; + abtTxBuf[4] = uiTxLen; + // Packet length checksum + abtTxBuf[5] = BUFFER_LENGTH - abtTxBuf[4]; // Copy the PN53X command into the packet buffer memmove(abtTxBuf+6,pbtTx,uiTxLen); - + // Calculate data payload checksum - abtTxBuf[uiTxLen+6] = 0; + abtTxBuf[uiTxLen+6] = 0; for(uiPos=0; uiPos < uiTxLen; uiPos++) { abtTxBuf[uiTxLen+6] -= abtTxBuf[uiPos+6]; } - + // End of stream marker - abtTxBuf[uiTxLen+7] = 0; - + abtTxBuf[uiTxLen+7] = 0; + #ifdef DEBUG - printf("Tx: "); + printf(" TX: "); print_hex(abtTxBuf,uiTxLen+8); #endif - if (!rs232_send((serial_port)ds,abtTxBuf,uiTxLen+8)) return false; + if (!rs232_send((serial_port)ds,abtTxBuf,uiTxLen+8)) { + ERR("Unable to transmit data. (TX)"); + return false; + } - if (!rs232_receive((serial_port)ds,abtRxBuf,&uiRxBufLen)) return false; - + if (!rs232_receive((serial_port)ds,abtRxBuf,&uiRxBufLen)) { + ERR("Unable to receive data. (RX)"); + return false; + } #ifdef DEBUG - printf("Rx: "); + printf(" RX: "); print_hex(abtRxBuf,uiRxBufLen); #endif - - // When the answer should be ignored, just return a succesful result + + // When the answer should be ignored, just return a successful result if(pbtRx == NULL || puiRxLen == NULL) return true; // Only succeed when the result is at least 00 00 ff 00 ff 00 00 00 FF xx Fx Dx xx .. .. .. xx 00 (x = variable) if(uiRxBufLen < 15) return false; - + // Remove the preceding and appending bytes 00 00 ff 00 ff 00 00 00 FF xx Fx .. .. .. xx 00 (x = variable) *puiRxLen = uiRxBufLen - 15; memcpy(pbtRx, abtRxBuf+13, *puiRxLen); - + return true; } diff --git a/src/libnfc.c b/src/libnfc.c index cdb8524..8fa477a 100644 --- a/src/libnfc.c +++ b/src/libnfc.c @@ -256,18 +256,18 @@ dev_info* nfc_connect() uint32_t uiDev; byte_t abtFw[4]; uint32_t uiFwLen = sizeof(abtFw); - + // Search through the device list for an available device for (uiDev=0; uiDevpdc = &(dev_callbacks_list[uiDev]); + pdi->pdc = &(dev_callbacks_list[uiDev]); pdi->pdc->transceive(pdi->ds,pncmd_get_register,4,NULL,NULL); // Try to retrieve PN53x chip revision diff --git a/src/list.c b/src/list.c index cb3dc71..ec94bc2 100644 --- a/src/list.c +++ b/src/list.c @@ -30,15 +30,15 @@ static dev_info* pdi; static byte_t abtFelica[5] = { 0x00, 0xff, 0xff, 0x00, 0x00 }; int main(int argc, const char* argv[]) -{ +{ tag_info ti; // Try to open the NFC reader pdi = nfc_connect(); - + if (pdi == INVALID_DEVICE_INFO) { - printf("Error connecting NFC reader\n"); + ERR("Unable to connect to NFC device."); return 1; } nfc_initiator_init(pdi); @@ -57,7 +57,7 @@ int main(int argc, const char* argv[]) nfc_configure(pdi,DCO_ACTIVATE_FIELD,true); printf("\nConnected to NFC reader: %s\n\n",pdi->acName); - + // Poll for a ISO14443A (MIFARE) tag if (nfc_initiator_select_tag(pdi,IM_ISO14443A_106,NULL,0,&ti)) { @@ -80,19 +80,19 @@ int main(int argc, const char* argv[]) printf("%18s","Parameter (PAD): "); print_hex(ti.tif.abtPad,8); } - // Poll for a ISO14443B tag - if (nfc_initiator_select_tag(pdi,IM_ISO14443B_106,"\x00",1,&ti)) - { - printf("The following (NFC) ISO14443-B tag was found:\n\n"); - printf(" ATQB: "); print_hex(ti.tib.abtAtqb,12); - printf(" ID: "); print_hex(ti.tib.abtId,4); - printf(" CID: %02x\n",ti.tib.btCid); - if (ti.tib.uiInfLen>0) - { - printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.uiInfLen); - } - printf("PARAMS: %02x %02x %02x %02x\n",ti.tib.btParam1,ti.tib.btParam2,ti.tib.btParam3,ti.tib.btParam4); - } + // Poll for a ISO14443B tag + if (nfc_initiator_select_tag(pdi,IM_ISO14443B_106,"\x00",1,&ti)) + { + printf("The following (NFC) ISO14443-B tag was found:\n\n"); + printf(" ATQB: "); print_hex(ti.tib.abtAtqb,12); + printf(" ID: "); print_hex(ti.tib.abtId,4); + printf(" CID: %02x\n",ti.tib.btCid); + if (ti.tib.uiInfLen>0) + { + printf(" INF: "); print_hex(ti.tib.abtInf,ti.tib.uiInfLen); + } + printf("PARAMS: %02x %02x %02x %02x\n",ti.tib.btParam1,ti.tib.btParam2,ti.tib.btParam3,ti.tib.btParam4); + } // Poll for a Jewel tag if (nfc_initiator_select_tag(pdi,IM_JEWEL_106,NULL,0,&ti)) diff --git a/src/rs232.c b/src/rs232.c index 6ea30a7..06bc30d 100644 --- a/src/rs232.c +++ b/src/rs232.c @@ -73,12 +73,24 @@ serial_port rs232_open(const char* pcPortName) // Copy the old terminal info struct sp->tiNew = sp->tiOld; + + /** @todo provide this settings dynamically using model provide in configuration file */ sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD; sp->tiNew.c_iflag = CCLAIMED | IGNPAR; sp->tiNew.c_oflag = 0; sp->tiNew.c_lflag = 0; - sp->tiNew.c_cc[VMIN] = 0; // block untill n bytes are received - sp->tiNew.c_cc[VTIME] = 0; // block untill a timer expires (n * 100 mSec.) + + /** + * @note ARYGON-ADRA (PN531): ???,n,8,1 + * @note ARYGON-ADRB (PN532): ???,n,8,1 + * @note ARYGON-APDA (PN531): 9600,n,8,1 + * @note ARYGON-APDB (PN532): 115200,n,8,1 + */ + cfsetispeed(&(sp->tiNew), B115200); + cfsetospeed(&(sp->tiNew), B115200); + + sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received + sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.) if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1) { rs232_close(sp); @@ -106,7 +118,7 @@ bool rs232_receive(const serial_port sp, byte_t* pbtRx, uint32_t* puiRxLen) int iResult; uint32_t uiCount = 0; fd_set rfds; - + while (true) { // Reset file descriptor @@ -115,18 +127,24 @@ bool rs232_receive(const serial_port sp, byte_t* pbtRx, uint32_t* puiRxLen) iResult = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv); // Read error - if (iResult < 0) return false; - + if (iResult < 0) { + DBG("RX error."); + return false; + } + // Read time-out if (iResult == 0) { // Test if we at least have received something if (uiCount == 0) return false; + + DBG("RX time-out."); + // Store the received byte count and return succesful *puiRxLen = uiCount; return true; } - + // There is something available, read the data uiCount += read(((serial_port_unix*)sp)->fd,pbtRx+uiCount,*puiRxLen-uiCount); } @@ -139,7 +157,7 @@ bool rs232_send(const serial_port sp, const byte_t* pbtTx, const uint32_t uiTxLe return (iResult >= 0); } -#else +#else // The windows serial port implementation typedef struct { @@ -186,7 +204,7 @@ serial_port rs232_open(const char* pcPortName) sp->ct.ReadTotalTimeoutConstant = 30; sp->ct.WriteTotalTimeoutMultiplier = 0; sp->ct.WriteTotalTimeoutConstant = 30; - + if(!SetCommTimeouts(sp->hPort,&sp->ct)) { rs232_close(sp);