aboutsummaryrefslogtreecommitdiffstats
path: root/cphidgetrfid.c
diff options
context:
space:
mode:
Diffstat (limited to 'cphidgetrfid.c')
-rw-r--r--cphidgetrfid.c2904
1 files changed, 1263 insertions, 1641 deletions
diff --git a/cphidgetrfid.c b/cphidgetrfid.c
index 718653d..3d177ba 100644
--- a/cphidgetrfid.c
+++ b/cphidgetrfid.c
@@ -7,72 +7,12 @@
// === Internal Functions === //
CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr);
-
static int analyze_data(CPhidgetRFIDHandle phid);
+static int tagEvent_fromEM4100Data(CPhidgetRFIDHandle phid, unsigned char *data);
+#ifdef RFID_HITAGS_SUPPORT
static int analyze_data_AC(CPhidgetRFIDHandle phid);
-static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength);
-static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char *data);
-
-//Hitag S Commands
static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid);
-static int HitagS_AC_SEQUENCE(CPhidgetRFIDHandle phid, CPhidgetRFID_HitagACHandle ac);
-
-#define ABS(x) ((x) < 0 ? -(x) : (x))
-#define pdiff(a, b) ( ABS((a) - (b)) / (double)( ((a) + (b)) / 2.0 ) )
-
-int CPhidgetRFID_Tag_areEqual(void *arg1, void *arg2)
-{
- CPhidgetRFID_TagHandle tag1 = (CPhidgetRFID_TagHandle)arg1;
- CPhidgetRFID_TagHandle tag2 = (CPhidgetRFID_TagHandle)arg2;
-
- if(!tag1 || !tag2)
- return PFALSE;
-
- if(!strcmp(tag1->tagString, tag2->tagString)
- && tag1->tagInfo.tagType == tag2->tagInfo.tagType
- && tag1->tagInfo.bitRate == tag2->tagInfo.bitRate
- && tag1->tagInfo.encoding == tag2->tagInfo.encoding)
- return PTRUE;
- else
- return PFALSE;
-}
-
-void CPhidgetRFID_Tag_free(void *arg)
-{
- CPhidgetRFID_TagHandle tag = (CPhidgetRFID_TagHandle)arg;
-
- if(!tag)
- return;
-
- free(tag); tag = NULL;
- return;
-}
-
-int CPhidgetRFID_HitagAC_areEqual(void *arg1, void *arg2)
-{
- CPhidgetRFID_HitagACHandle ac1 = (CPhidgetRFID_HitagACHandle)arg1;
- CPhidgetRFID_HitagACHandle ac2 = (CPhidgetRFID_HitagACHandle)arg2;
-
- if(!ac1 || !ac2)
- return PFALSE;
-
- if(!memcmp(ac1->uid, ac2->uid, 4)
- && ac1->colPos == ac2->colPos)
- return PTRUE;
- else
- return PFALSE;
-}
-
-void CPhidgetRFID_HitagAC_free(void *arg)
-{
- CPhidgetRFID_HitagACHandle ac = (CPhidgetRFID_HitagACHandle)arg;
-
- if(!ac)
- return;
-
- free(ac); ac = NULL;
- return;
-}
+#endif
//clearVars - sets all device variables to unknown state
CPHIDGETCLEARVARS(RFID)
@@ -81,11 +21,7 @@ CPHIDGETCLEARVARS(RFID)
phid->antennaEchoState = PUNI_BOOL;
phid->ledEchoState = PUNI_BOOL;
phid->tagPresent = PUNI_BOOL;
- phid->fullStateEcho = PUNK_BOOL;
- phid->ledState = PUNK_BOOL;
- phid->antennaState = PUNK_BOOL;
phid->lastTagValid = PUNI_BOOL;
-
for (i = 0; i<RFID_MAXOUTPUTS; i++)
{
phid->outputEchoState[i] = PUNI_BOOL;
@@ -98,47 +34,36 @@ CPHIDGETCLEARVARS(RFID)
// used during attach initialization - on every attach
CPHIDGETINIT(RFID)
int i = 0;
- unsigned char buffer[8] = { 0 };
int result;
TESTPTR(phid);
+ //make sure the tagTimerThread isn't running
+ if (phid->tagTimerThread.thread_status == PTRUE)
+ {
+ phid->tagTimerThread.thread_status = PFALSE;
+ CThread_join(&phid->tagTimerThread);
+ }
+ phid->tagTimerThread.thread_status = PFALSE;
+
//Make sure no old writes are still pending
phid->outputPacketLen = 0;
//setup anything device specific
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID:
- if (phid->phid.deviceVersion < 200)
- {
- phid->fullStateEcho = PFALSE;
- phid->antennaEchoState = PTRUE;
- }
- else
- return EPHIDGET_BADVERSION;
+ case PHIDUID_RFID_OLD:
+ case PHIDUID_RFID:
+ phid->fullStateEcho = PFALSE;
+ phid->antennaEchoState = PTRUE;
break;
- case PHIDID_RFID_2OUTPUT: //2-output RFID
- if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 201))
- {
- phid->antennaEchoState = PUNK_BOOL;
- phid->fullStateEcho = PFALSE;
- }
- else if ((phid->phid.deviceVersion >= 201) && (phid->phid.deviceVersion < 300))
- {
- phid->antennaEchoState = PUNK_BOOL;
- phid->fullStateEcho = PTRUE;
- }
- else
- return EPHIDGET_BADVERSION;
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ phid->fullStateEcho = PFALSE;
+ phid->antennaEchoState = PUNK_BOOL;
break;
- case PHIDID_RFID_2OUTPUT_ADVANCED: //2-output RFID (Advanced)
- if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
- {
- phid->antennaEchoState = PUNK_BOOL;
- phid->fullStateEcho = PTRUE;
- }
- else
- return EPHIDGET_BADVERSION;
+ case PHIDUID_RFID_2OUTPUT:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ phid->fullStateEcho = PTRUE;
+ phid->antennaEchoState = PUNK_BOOL;
break;
default:
return EPHIDGET_UNEXPECTED;
@@ -149,68 +74,66 @@ CPHIDGETINIT(RFID)
{
phid->outputEchoState[i] = PUNK_BOOL;
}
+
phid->ledEchoState = PUNK_BOOL;
phid->tagPresent = PUNK_BOOL;
- ZEROMEM(phid->lastTag, 10);
+ ZEROMEM(&phid->lastTag, sizeof(CPhidgetRFID_Tag));
+ ZEROMEM(&phid->pendingTag, sizeof(CPhidgetRFID_Tag));
phid->tagEventPending = PFALSE;
+ phid->lastTagValid = PFALSE;
- phid->frequencyEcho = PUNK_INT;
phid->pregapClocksEcho = PUNK_INT;
- phid->postgapClocksEcho = PUNK_INT;
+ phid->prepulseClocksEcho = PUNK_INT;
phid->zeroClocksEcho = PUNK_INT;
phid->oneClocksEcho = PUNK_INT;
phid->spaceClocksEcho = PUNK_INT;
+ phid->postgapClocksEcho = PUNK_INT;
+ phid->eofpulseClocksEcho = PUNK_INT;
+ phid->listenDuringEOFEcho = PUNK_BOOL;
+
phid->_4097ConfEcho = PUNK_INT;
phid->dataReadPtr = 0;
phid->dataWritePtr = 0;
- phid->dataReadACPtr = 0;
- phid->userReadPtr = 0;
phid->manReadPtr = 0;
- phid->manEventReadPtr = 0;
phid->manWritePtr = 0;
phid->biphaseReadPtr = 0;
phid->biphaseWritePtr = 0;
-
- phid->ACCodingOK = PFALSE;
-
- phid->tagAdvancedCount = PUNK_INT;
- phid->polling = PTRUE;
+ phid->shortClocks = phid->longClocks = 0;
- CThread_mutex_lock(&phid->tagthreadlock);
- if(phid->tagAdvancedList)
- CList_emptyList((CListHandle *)&phid->tagAdvancedList, PTRUE, CPhidgetRFID_Tag_free);
- phid->tagAdvancedList = NULL;
- CThread_mutex_unlock(&phid->tagthreadlock);
- phid->lastTagAdvanced.tagString[0] = '\0';
-
- phid->one = phid->two = phid->oneCount = phid->twoCount = 0;
+ phid->manLockedIn = PFALSE;
+ phid->biphaseLockedIn = PFALSE;
+ phid->manShortChange = PFALSE;
+ phid->biphaseShortChange = PFALSE;
- phid->manLockedIn = 0;
- phid->biphaseLockedIn = 0;
- phid->manShortChange = 0;
- phid->biphaseShortChange = 0;
+ CThread_reset_event(&phid->tagAvailableEvent);
- //This needs to always have a valid time
-#ifdef _WINDOWS
- GetSystemTime(&phid->lastDataTime);
-#else
- gettimeofday(&phid->lastDataTime,NULL);
+#ifdef RFID_HITAGS_SUPPORT
+ phid->dataReadACPtr = 0;
+ phid->ACCodingOK = PFALSE;
+ phid->polling = PFALSE;
+ setTimeNow(&phid->lastDataTime);
+ setTimeNow(&phid->hitagReqTime);
+#endif
+
+#ifdef RFID_RAWDATA_API_SUPPORT
+ phid->userReadPtr = 0;
+ phid->manEventReadPtr = 0;
+ phid->lastManEventLong = PFALSE;
#endif
//send out any initial pre-read packets
- switch(phid->phid.deviceIDSpec) {
- case PHIDID_RFID:
- if (phid->phid.deviceVersion <= 103)
- {
- ZEROMEM(buffer,8);
- LOG(PHIDGET_LOG_INFO,"Sending workaround startup packet");
- if ((result = CUSBSendPacket((CPhidgetHandle)phid, buffer)) != EPHIDGET_OK)
- return result;
- }
+ switch(phid->phid.deviceUID) {
+ case PHIDUID_RFID_OLD:
+ {
+ unsigned char buffer[8] = { 0 };
+ ZEROMEM(buffer,8);
+ LOG(PHIDGET_LOG_INFO,"Sending workaround startup packet");
+ if ((result = CUSBSendPacket((CPhidgetHandle)phid, buffer)) != EPHIDGET_OK)
+ return result;
break;
- case PHIDID_RFID_2OUTPUT:
+ }
default:
break;
}
@@ -229,13 +152,35 @@ CPHIDGETINIT(RFID)
CPhidget_read((CPhidgetHandle)phid);
}
+ switch(phid->phid.deviceUID)
+ {
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ //Did we get some data? Wait for a tag
+ if(phid->dataWritePtr != 0)
+ {
+ int readtries = 30; //This should be enough data to guarantee detection of a tag.
+ while(readtries-- > 0)
+ {
+ CPhidget_read((CPhidgetHandle)phid);
+ if(phid->tagPresent != PUNK_BOOL)
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
//if the antenna is on, and tagPresent is unknown, then it is false
if(phid->antennaEchoState == PTRUE && phid->tagPresent == PUNK_BOOL)
phid->tagPresent = PFALSE;
- //if the antenna is on, and tagCount is unknown, then it is false
- if(phid->antennaEchoState == PTRUE && phid->tagAdvancedCount == PUNK_INT)
- phid->tagAdvancedCount = 0;
+ //So that we can get the tag in the attach handler
+ if(phid->tagPresent == PTRUE)
+ {
+ phid->lastTag = phid->pendingTag;
+ phid->lastTagValid = PTRUE;
+ }
//recover what we can - if anything isn't filled out, it's PUNK anyways
for (i = 0; i<phid->phid.attr.rfid.numOutputs; i++)
@@ -250,263 +195,216 @@ CPHIDGETINIT(RFID)
phid->zeroClocks = phid->zeroClocksEcho;
phid->oneClocks = phid->oneClocksEcho;
phid->spaceClocks = phid->spaceClocksEcho;
+ phid->eofpulseClocks = phid->eofpulseClocksEcho;
+ phid->prepulseClocks = phid->prepulseClocksEcho;
+ phid->listenDuringEOF = phid->listenDuringEOFEcho;
phid->_4097Conf = phid->_4097ConfEcho;
- //make sure the tagTimerThread isn't running
- if (phid->tagTimerThread.thread_status == PTRUE)
- {
- phid->tagTimerThread.thread_status = PFALSE;
- CThread_join(&phid->tagTimerThread);
- }
-
return EPHIDGET_OK;
}
//dataInput - parses device packets
CPHIDGETDATA(RFID)
int i = 0, j = 0;
- unsigned char newTag = PFALSE, newOutputs = PFALSE;
- unsigned char tagData[5];
+ unsigned char newStateData = PFALSE;
unsigned char outputs[RFID_MAXOUTPUTS];
- unsigned char lastOutputs[RFID_MAXOUTPUTS];
- unsigned char antennaState = 0, ledState = 0;
- unsigned char gotData = PFALSE;
+ unsigned char antennaState, ledState;
if (length<0) return EPHIDGET_INVALIDARG;
TESTPTR(phid);
TESTPTR(buffer);
- ZEROMEM(tagData, sizeof(tagData));
- ZEROMEM(outputs, sizeof(outputs));
- ZEROMEM(lastOutputs, sizeof(lastOutputs));
-
//Parse device packets - store data locally
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID:
- if (phid->phid.deviceVersion < 200)
- {
- gotData = PTRUE;
- CThread_mutex_lock(&phid->tagthreadlock);
- setTimeNow(&phid->lastTagTime);
- advancedTagEventForOldReaders(phid, buffer+1);
- if(!memcmp(phid->lastTag, buffer+1, 5) && phid->tagPresent == PTRUE)
- newTag = PFALSE;
- else if(!memcmp("\0\0\0\0\0", buffer+1, 5))
- newTag = PFALSE;
- else
- {
- memcpy(tagData, buffer+1, 5);
- newTag = PTRUE;
- }
- CThread_mutex_unlock(&phid->tagthreadlock);
- }
- else
- return EPHIDGET_UNEXPECTED;
+ case PHIDUID_RFID_OLD:
+ case PHIDUID_RFID:
+ // Enything other then all 0's means a tag is detected
+ if(memcmp("\0\0\0\0\0", buffer+1, 5))
+ tagEvent_fromEM4100Data(phid, buffer+1);
break;
- case PHIDID_RFID_2OUTPUT:
- if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 300))
- {
- switch(buffer[0])
- {
- case RFID_PACKET_TAG:
- gotData = PTRUE;
- CThread_mutex_lock(&phid->tagthreadlock);
- setTimeNow(&phid->lastTagTime);
- advancedTagEventForOldReaders(phid, buffer+1);
- if(!memcmp(phid->lastTag, buffer+1, 5) && phid->tagPresent == PTRUE)
- newTag = PFALSE;
- else if(!memcmp("\0\0\0\0\0", buffer+1, 5))
- newTag = PFALSE;
- else
- {
- memcpy(tagData, buffer+1, 5);
- newTag = PTRUE;
- }
- CThread_mutex_unlock(&phid->tagthreadlock);
- break;
- case RFID_PACKET_OUTPUT_ECHO:
- if(phid->fullStateEcho)
- {
- newOutputs = PTRUE;
-
- for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
- {
- if (buffer[1] & j)
- outputs[i] = PTRUE;
- else
- outputs[i] = PFALSE;
- }
-
- if(buffer[1] & RFID_LED_FLAG)
- ledState = PTRUE;
- else
- ledState = PFALSE;
-
- if(buffer[1] & RFID_ANTENNA_FLAG)
- antennaState = PTRUE;
- else
- antennaState = PFALSE;
- }
- break;
- default:
- return EPHIDGET_UNEXPECTED;
- }
- }
- else
- return EPHIDGET_UNEXPECTED;
- break;
- // RFID with decoding in software and write support
- case PHIDID_RFID_2OUTPUT_ADVANCED:
- if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ case PHIDUID_RFID_2OUTPUT:
+ switch(buffer[0])
{
- int dataLength = 0;
- int data[RFID_MAX_DATA_PER_PACKET];
- switch(buffer[0] & 0x40)
- {
- case RFID_READ_DATA_IN_PACKET:
- gotData = PTRUE;
- phid->frequencyEcho = buffer[1] * 1000;
-
- //move RFID data into local storage
- dataLength = buffer[0];
- for(i = 0; i < dataLength; i++)
- {
- data[i] = buffer[i+2];
- phid->dataBuffer[phid->dataWritePtr] = buffer[i+2];
-
- phid->dataWritePtr++;
- phid->dataWritePtr &= RFID_DATA_ARRAY_MASK;
-
- //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer
- if(phid->dataWritePtr == phid->dataReadPtr)
- {
- phid->dataReadPtr++;
- phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
- }
- if(phid->dataWritePtr == phid->dataReadACPtr)
- {
- phid->dataReadACPtr++;
- phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK;
- }
- }
-
- break;
- case RFID_ECHO_IN_PACKET:
- newOutputs = PTRUE;
- phid->frequencyEcho = buffer[1] * 1000;
-
- //LOG(PHIDGET_LOG_DEBUG, "Frequency: %d", phid->frequencyEcho);
-
- phid->pregapClocksEcho = buffer[2];
- phid->postgapClocksEcho = buffer[3];
- phid->zeroClocksEcho = buffer[4];
- phid->oneClocksEcho = buffer[5];
- phid->spaceClocksEcho = buffer[6];
+ case RFID_PACKET_TAG:
+ // Enything other then all 0's means a tag is detected
+ if(memcmp("\0\0\0\0\0", buffer+1, 5))
+ tagEvent_fromEM4100Data(phid, buffer+1);
+ break;
+ case RFID_PACKET_OUTPUT_ECHO:
+ if(phid->fullStateEcho)
+ {
+ newStateData = PTRUE;
for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
{
- if (buffer[7] & j)
+ if (buffer[1] & j)
outputs[i] = PTRUE;
else
outputs[i] = PFALSE;
}
- if(buffer[7] & RFID_LED_FLAG)
+ if(buffer[1] & RFID_LED_FLAG)
ledState = PTRUE;
else
ledState = PFALSE;
- if(buffer[7] & RFID_ANTENNA_FLAG)
+ if(buffer[1] & RFID_ANTENNA_FLAG)
antennaState = PTRUE;
else
antennaState = PFALSE;
+ }
+ break;
+ default:
+ return EPHIDGET_UNEXPECTED;
+ }
+ break;
+
+ // RFID with decoding in software and write support
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ {
+ int dataLength = 0;
+ int dataOffset = 1;
+ int data[RFID_MAX_DATA_PER_PACKET];
+ switch(buffer[0] & 0x40)
+ {
+ case RFID_ECHO_IN_PACKET:
+ dataOffset = 11;
+ newStateData = PTRUE;
+
+ //Don't bother - we don't use it.
+ //phid->frequencyEcho = buffer[1] * 1000;
+
+ phid->pregapClocksEcho = buffer[2];
+ phid->prepulseClocksEcho = buffer[7];
+ phid->zeroClocksEcho = buffer[4];
+ phid->oneClocksEcho = buffer[5];
+ phid->spaceClocksEcho = buffer[6];
+ phid->postgapClocksEcho = buffer[3];
+ phid->eofpulseClocksEcho = buffer[8];
+
+ for (i = 0, j = 0x01; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
+ {
+ if (buffer[9] & j)
+ outputs[i] = PTRUE;
+ else
+ outputs[i] = PFALSE;
+ }
- phid->_4097ConfEcho = buffer[8];
+ if(buffer[9] & RFID_LED_FLAG)
+ ledState = PTRUE;
+ else
+ ledState = PFALSE;
- //space in data
- if(buffer[9])
- {
- //Manchester event with space
- unsigned char manEventData[1];
- manEventData[0] = PUNK_BOOL;
+ if(buffer[9] & RFID_ANTENNA_FLAG)
+ antennaState = PTRUE;
+ else
+ antennaState = PFALSE;
+
+ if(buffer[9] & RFID_LISTEN_DURING_EOF_FLAG)
+ phid->listenDuringEOFEcho = PTRUE;
+ else
+ phid->listenDuringEOFEcho = PFALSE;
- FIRE(ManchesterData, manEventData, 1);
+ phid->_4097ConfEcho = buffer[10];
- //Add a space in the buffer - only if it's not already a space
+ //NOTE: Fall Through
+ case RFID_READ_DATA_IN_PACKET:
+
+ //move RFID data into local storage
+ dataLength = buffer[0] & 0x3F;
+ for(i = 0; i < dataLength; i++)
+ {
+ data[i] = buffer[i+dataOffset] << 1;
+ if((data[i] & 0xFE) == 0xFE)
+ {
+ data[i] = PUNK_INT;
phid->dataBuffer[phid->dataWritePtr] = PUNK_INT;
- phid->dataWritePtr++;
- phid->dataWritePtr &= RFID_DATA_ARRAY_MASK;
-
- //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer
- if(phid->dataWritePtr == phid->dataReadPtr)
- {
- phid->dataReadPtr++;
- phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
- }
- if(phid->dataWritePtr == phid->dataReadACPtr)
- {
- phid->dataReadACPtr++;
- phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK;
- }
- dataLength = 1;
- data[0] = PUNK_INT;
}
else
- gotData = PTRUE;
+ {
+ // convert to data lengths that we expect to deal with internally
+ int polarity = data[i] & 0x100;
+ int clocks = data[i] & 0xff;
+
+ if(clocks >= 10 && clocks <= 22)
+ phid->dataBuffer[phid->dataWritePtr] = polarity | 16;
+ else if(clocks >= 26 && clocks <= 40)
+ phid->dataBuffer[phid->dataWritePtr] = polarity | 32;
+ else if(clocks >= 42 && clocks <= 54)
+ phid->dataBuffer[phid->dataWritePtr] = polarity | 48;
+ else if(clocks >= 56 && clocks <= 72)
+ phid->dataBuffer[phid->dataWritePtr] = polarity | 64;
+ else if(clocks >= 120 && clocks <= 136)
+ phid->dataBuffer[phid->dataWritePtr] = polarity | 128;
+ else
+ phid->dataBuffer[phid->dataWritePtr] = PUNK_INT;
+ }
- break;
- default:
- return EPHIDGET_UNEXPECTED;
- }
+ phid->dataWritePtr++;
+ phid->dataWritePtr &= RFID_DATA_ARRAY_MASK;
- if(dataLength)
- {
- //send out raw data event
- FIRE(RawData, data, dataLength);
+ //if we run into data that hasn't been read... too bad, we overwrite it and adjust the read pointer
+ if(phid->dataWritePtr == phid->dataReadPtr)
+ {
+ phid->dataReadPtr++;
+ phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
+ }
+#ifdef RFID_HITAGS_SUPPORT
+ if(phid->dataWritePtr == phid->dataReadACPtr)
+ {
+ phid->dataReadACPtr++;
+ phid->dataReadACPtr &= RFID_DATA_ARRAY_MASK;
+ }
+#endif
+ }
- //analyze data
- analyze_data(phid);
- if(phid->ACCodingOK)
- analyze_data_AC(phid);
- else
- phid->dataReadACPtr = phid->dataWritePtr;
- }
+ break;
+ default:
+ return EPHIDGET_UNEXPECTED;
+ }
+
+ if(dataLength)
+ {
+
+#ifdef RFID_RAWDATA_API_SUPPORT
+ FIRE(RawData, data, dataLength);
+#endif
+
+ //analyze data
+ analyze_data(phid);
+
+#ifdef RFID_HITAGS_SUPPORT
+ setTimeNow(&phid->lastDataTime);
+ if(phid->ACCodingOK)
+ analyze_data_AC(phid);
+ else
+ phid->dataReadACPtr = phid->dataWritePtr;
+#endif
}
- else
- return EPHIDGET_UNEXPECTED;
break;
+ }
default:
return EPHIDGET_UNEXPECTED;
}
- if(gotData)
- setTimeNow(&phid->lastDataTime);
-
//Make sure values are within defined range, and store to structure
- if(newOutputs)
+ if(newStateData)
{
+ unsigned char lastOutputs[RFID_MAXOUTPUTS];
+
for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
{
lastOutputs[i] = phid->outputEchoState[i];
phid->outputEchoState[i] = outputs[i];
}
+
phid->ledEchoState = ledState;
phid->antennaEchoState = antennaState;
- }
- CThread_mutex_lock(&phid->tagthreadlock);
- if(newTag && !phid->tagEventPending)
- {
- memcpy(phid->pendingTag, tagData, 5);
- phid->tagEventPending = PTRUE;
- CThread_set_event(&phid->tagAvailableEvent);
- }
- CThread_mutex_unlock(&phid->tagthreadlock);
- //Events
- if(newOutputs)
- {
+ //Events
for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
{
if(lastOutputs[i] != phid->outputEchoState[i])
@@ -529,13 +427,24 @@ CPHIDGETINITEVENTS(RFID)
}
}
- //Initial tag events are sent from the tagTimerThread
+ //Initial non-remote tag events are sent from the tagTimerThread
//Don't start the tag thread if this is a networked Phidget
CThread_mutex_lock(&phid->phid.lock);
if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG))
{
- if(!CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ //For remote - if there is a tag present, send the tag event here
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ {
+ CThread_mutex_unlock(&phid->phid.lock);
+ if(phid->tagPresent == PTRUE && phid->lastTagValid == PTRUE)
+ {
+ if(phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100)
+ FIRE(Tag, phid->lastTag.tagData);
+ FIRE(Tag2, phid->lastTag.tagString, phid->lastTag.protocol);
+ }
+ }
+ else
{
CThread_mutex_unlock(&phid->phid.lock);
//Start the tagTimerThread - do it here because we are about to start the read thread, and that will keep it active
@@ -546,13 +455,6 @@ CPHIDGETINITEVENTS(RFID)
return EPHIDGET_UNEXPECTED;
}
}
- //For remote - if there is a tag present, send the tag event here
- else
- {
- CThread_mutex_unlock(&phid->phid.lock);
- if(phid->tagPresent == PTRUE)
- FIRE(Tag, phid->lastTag);
- }
}
else
{
@@ -584,8 +486,6 @@ int CPhidgetRFID_free(CPhidgetHandle phidG)
CPhidgetRFIDHandle phid = (CPhidgetRFIDHandle)phidG;
CThread_mutex_destroy(&phid->tagthreadlock);
CThread_destroy_event(&phid->tagAvailableEvent);
- CThread_destroy_event(&phid->respEvent);
- CThread_destroy_event(&phid->respEvent2);
return EPHIDGET_OK;
}
@@ -601,75 +501,91 @@ CMAKEPACKET(RFID)
TESTPTRS(phid, buffer);
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT: //4-output RFID
- if ((phid->phid.deviceVersion >= 200) && (phid->phid.deviceVersion < 300))
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ case PHIDUID_RFID_2OUTPUT:
+ //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value
+ for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
{
- //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value
- for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
- {
- if (phid->outputState[i] == PUNK_BOOL)
- phid->outputState[i] = PFALSE;
- }
- if(phid->antennaState == PUNK_BOOL)
- phid->antennaState = PFALSE;
- if(phid->ledState == PUNK_BOOL)
- phid->ledState = PFALSE;
+ if (phid->outputState[i] == PUNK_BOOL)
+ phid->outputState[i] = PFALSE;
+ }
+ if(phid->antennaState == PUNK_BOOL)
+ phid->antennaState = PFALSE;
+ if(phid->ledState == PUNK_BOOL)
+ phid->ledState = PFALSE;
- //construct the packet
- for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
- {
- if (phid->outputState[i])
- buffer[0] |= j;
- }
- if(phid->ledState == PTRUE)
- buffer[0] |= RFID_LED_FLAG;
- if(phid->antennaState == PTRUE)
- buffer[0] |= RFID_ANTENNA_FLAG;
+ //construct the packet
+ for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
+ {
+ if (phid->outputState[i])
+ buffer[0] |= j;
}
- else
- return EPHIDGET_UNEXPECTED;
+ if(phid->ledState == PTRUE)
+ buffer[0] |= RFID_LED_FLAG;
+ if(phid->antennaState == PTRUE)
+ buffer[0] |= RFID_ANTENNA_FLAG;
break;
- case PHIDID_RFID_2OUTPUT_ADVANCED: //4-output RFID Advanced
- if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value
+ for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
{
- //have to make sure that everything to be sent has some sort of default value if the user hasn't set a value
- for (i = 0; i < phid->phid.attr.rfid.numOutputs; i++)
- {
- if (phid->outputState[i] == PUNK_BOOL)
- phid->outputState[i] = PFALSE;
- }
- if(phid->antennaState == PUNK_BOOL)
- phid->antennaState = PFALSE;
- if(phid->ledState == PUNK_BOOL)
- phid->ledState = PFALSE;
-
- //construct the packet
- for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
- {
- if (phid->outputState[i])
- buffer[7] |= j;
- }
- if(phid->ledState == PTRUE)
- buffer[7] |= RFID_LED_FLAG;
- if(phid->antennaState == PTRUE)
- buffer[7] |= RFID_ANTENNA_FLAG;
-
- //TODO: make sure these are actually all valid
- buffer[0] = RFID_CONTROL_OUT_PACKET;
- buffer[1] = phid->pregapClocks;
- buffer[2] = phid->postgapClocks;
- buffer[3] = phid->zeroClocks;
- buffer[4] = phid->oneClocks;
- buffer[5] = phid->spaceClocks;
- buffer[6] = phid->_4097Conf;
+ if (phid->outputState[i] == PUNK_BOOL)
+ phid->outputState[i] = PFALSE;
}
+ if(phid->antennaState == PUNK_BOOL)
+ phid->antennaState = PFALSE;
+ if(phid->ledState == PUNK_BOOL)
+ phid->ledState = PFALSE;
+
+ // Default write timing to T5577
+ if(phid->pregapClocks == PUNK_INT)
+ phid->pregapClocks = RFID_T5577_StartGap;
+ if(phid->prepulseClocks == PUNK_INT)
+ phid->prepulseClocks = RFID_T5577_PrePulse;
+ if(phid->zeroClocks == PUNK_INT)
+ phid->zeroClocks = RFID_T5577_Zero;
+ if(phid->oneClocks == PUNK_INT)
+ phid->oneClocks = RFID_T5577_One;
+ if(phid->spaceClocks == PUNK_INT)
+ phid->spaceClocks = RFID_T5577_WriteGap;
+ if(phid->postgapClocks == PUNK_INT)
+ phid->postgapClocks = RFID_T5577_EndGap;
+ if(phid->eofpulseClocks == PUNK_INT)
+ phid->eofpulseClocks = RFID_T5577_EOF;
+ if(phid->listenDuringEOF == PUNK_BOOL)
+ phid->listenDuringEOF = PFALSE;
+
+ //construct the packet
+ for (i = 0, j = 1; i < phid->phid.attr.rfid.numOutputs; i++, j<<=1)
+ {
+ if (phid->outputState[i])
+ buffer[0] |= j;
+ }
+ if(phid->ledState == PTRUE)
+ buffer[0] |= RFID_LED_FLAG;
+ if(phid->antennaState == PTRUE)
+ buffer[0] |= RFID_ANTENNA_FLAG;
+
+ if(phid->antennaState == PTRUE)
+ phid->_4097Conf = RFID_4097_DefaultON;
else
- return EPHIDGET_UNEXPECTED;
+ phid->_4097Conf = RFID_4097_PowerDown;
+
+ buffer[0] |= RFID_CONTROL_OUT_PACKET;
+ buffer[1] = (phid->pregapClocks-1) & 0x3F;
+ buffer[1] |= ((phid->postgapClocks-1) << 2) & 0xC0;
+ buffer[2] = (phid->postgapClocks-1) & 0x0F;
+ buffer[2] |= ((phid->spaceClocks-1) << 2) & 0xF0;
+ buffer[3] = (phid->spaceClocks-1) & 0x03;
+ buffer[3] |= ((phid->zeroClocks-1) << 1) & 0xFC;
+ buffer[4] = (phid->zeroClocks-1) & 0x01;
+ buffer[4] |= ((phid->oneClocks-1) << 1) & 0xFE;
+ buffer[5] = phid->prepulseClocks;
+ buffer[6] = phid->eofpulseClocks;
+ buffer[7] = phid->_4097Conf;
break;
- case PHIDID_RFID:
- return EPHIDGET_UNSUPPORTED; //this version does not have outputs
default:
return EPHIDGET_UNEXPECTED;
}
@@ -681,15 +597,11 @@ CMAKEPACKET(RFID)
CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr)
{
CPhidgetRFIDHandle phid = (CPhidgetRFIDHandle)userPtr;
- CPhidgetRFID_TagList *trav = 0, *tagLostList = 0, *tagFoundList = 0;
if(!phid) return (CThread_func_return_t)EPHIDGET_INVALIDARG;
LOG(PHIDGET_LOG_INFO,"tagTimerThread running");
- //Set this before creation
- //phid->tagTimerThread.thread_status = PTRUE;
-
while (CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_ATTACHED_FLAG) && phid->tagTimerThread.thread_status == PTRUE)
{
//sleeps for up to 50ms, but can be signalled externally to return immediately
@@ -697,120 +609,71 @@ CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr)
CThread_reset_event(&phid->tagAvailableEvent);
//Tag events
- //Old-style
+ CThread_mutex_lock(&phid->tagthreadlock);
if(phid->tagEventPending)
{
- phid->tagPresent = PTRUE;
- FIRE(Tag, phid->pendingTag);
- CThread_mutex_lock(&phid->tagthreadlock);
- setTimeNow(&phid->lastTagTime);
-
- //so they can access the last tag from this tag event
- memcpy(phid->lastTag, phid->pendingTag, 5);
- phid->tagEventPending = PFALSE;
CThread_mutex_unlock(&phid->tagthreadlock);
- }
- //New-style
- CThread_mutex_lock(&phid->tagthreadlock);
- for (trav=phid->tagAdvancedList; trav; trav = trav->next)
- {
- if(trav->tag->tagEventPending == PTRUE)
- CList_addToList((CListHandle *)&tagFoundList, trav->tag, CPhidgetRFID_Tag_areEqual);
- }
- for (trav=tagFoundList; trav; trav = trav->next)
- {
- if(phid->tagAdvancedCount == PUNK_INT)
- phid->tagAdvancedCount = 0;
- phid->tagAdvancedCount++;
+ if(phid->pendingTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100)
+ FIRE(Tag, phid->pendingTag.tagData);
+ FIRE(Tag2, phid->pendingTag.tagString, phid->pendingTag.protocol);
- CThread_mutex_unlock(&phid->tagthreadlock);
- FIRE(TagAdvanced, trav->tag->tagString, &trav->tag->tagInfo);
+ //Fill in lastTag after the event so that LAST tag (not current tag) is avialable in the event
CThread_mutex_lock(&phid->tagthreadlock);
- setTimeNow(&trav->tag->lastTagTime);
-
- //so they can access the last tag from this tag event
- memcpy(&phid->lastTagAdvanced, trav->tag, sizeof(CPhidgetRFID_Tag));
- trav->tag->tagEventPending = PFALSE;
+ phid->lastTag = phid->pendingTag;
+ phid->lastTagValid = PTRUE;
+ phid->tagEventPending = PFALSE;
}
- CList_emptyList((CListHandle *)&tagFoundList, PFALSE, NULL);
CThread_mutex_unlock(&phid->tagthreadlock);
//TAG Lost events
- //Old-style
+ CThread_mutex_lock(&phid->tagthreadlock);
if(phid->tagPresent != PFALSE)
{
/* check for tag lost */
-
- CThread_mutex_lock(&phid->tagthreadlock);
+#ifdef RFID_HITAGS_SUPPORT
+ if((timeSince(&phid->lastTagTime) > 0.2 && phid->lastTag.protocol != PHIDGET_RFID_PROTOCOL_HITAGS_UID)
+ || (timeSince(&phid->lastTagTime) > 0.5 && phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_HITAGS_UID))
+#else
if(timeSince(&phid->lastTagTime) > 0.2)
+#endif
{
if (phid->tagPresent == PTRUE) {
phid->tagPresent = PFALSE;
CThread_mutex_unlock(&phid->tagthreadlock);
- FIRE(TagLost, phid->lastTag);
+
+ if(phid->pendingTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100)
+ FIRE(TagLost, phid->lastTag.tagData);
+ FIRE(TagLost2, phid->lastTag.tagString, phid->lastTag.protocol);
+
CThread_mutex_lock(&phid->tagthreadlock);
}
else if(phid->antennaEchoState == PTRUE) //could be PUNK_BOOL - don't send event, just set to PFALSE (but only if the antenna is on)
phid->tagPresent = PFALSE;
}
- CThread_mutex_unlock(&phid->tagthreadlock);
- }
- //New-style
- if(phid->tagAdvancedCount != 0)
- {
- if(phid->tagAdvancedCount != PUNK_INT)
- {
- CThread_mutex_lock(&phid->tagthreadlock);
- for (trav=phid->tagAdvancedList; trav; trav = trav->next)
- {
- if((timeSince(&trav->tag->lastTagTime) > 0.2 && trav->tag->tagInfo.tagType != PHIDGET_RFID_TAG_HITAGS)
- || (timeSince(&trav->tag->lastTagTime) > 0.5 && trav->tag->tagInfo.tagType == PHIDGET_RFID_TAG_HITAGS))
- CList_addToList((CListHandle *)&tagLostList, trav->tag, CPhidgetRFID_Tag_areEqual);
- }
- for (trav=tagLostList; trav; trav = trav->next)
- {
- CList_removeFromList((CListHandle *)&phid->tagAdvancedList, trav->tag, CPhidgetRFID_Tag_areEqual, PFALSE, NULL);
- phid->tagAdvancedCount--;
- CThread_mutex_unlock(&phid->tagthreadlock);
- FIRE(TagLostAdvanced, trav->tag->tagString, &trav->tag->tagInfo);
- CThread_mutex_lock(&phid->tagthreadlock);
- }
- CList_emptyList((CListHandle *)&tagLostList, PTRUE, CPhidgetRFID_Tag_free);
- CThread_mutex_unlock(&phid->tagthreadlock);
- }
- else if(phid->antennaEchoState == PTRUE)
- phid->tagAdvancedCount = 0;
}
+ CThread_mutex_unlock(&phid->tagthreadlock);
+#ifdef RFID_HITAGS_SUPPORT
//Actively look for tags if we haven't gotten data for a while (Hitag)
+ CThread_mutex_lock(&phid->tagthreadlock);
if(phid->antennaEchoState == PTRUE && phid->polling == PTRUE)
{
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT_ADVANCED: //2-output RFID Advanced
- if ((phid->phid.deviceVersion >= 100) && (phid->phid.deviceVersion < 200))
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ if(timeSince(&phid->hitagReqTime) > 0.1 && timeSince(&phid->lastDataTime) > 0.1) //100ms
{
- CThread_mutex_lock(&phid->tagthreadlock);
- if(timeSince(&phid->hitagReqTime) > 0.1) //100ms
- {
- if(timeSince(&phid->lastDataTime) > 0.1) //100ms
- {
- HitagS_UID_REQUEST(phid);
- }
- }
- CThread_mutex_unlock(&phid->tagthreadlock);
+ HitagS_UID_REQUEST(phid);
}
- else
- return (CThread_func_return_t)EPHIDGET_UNEXPECTED;
break;
+
//Cannot send data
- case PHIDID_RFID_2OUTPUT:
- case PHIDID_RFID:
- break;
default:
- return (CThread_func_return_t)EPHIDGET_UNEXPECTED;
+ break;
}
}
+ CThread_mutex_unlock(&phid->tagthreadlock);
+#endif
}
LOG(PHIDGET_LOG_INFO,"tagTimerThread exiting normally");
@@ -818,6 +681,67 @@ CThread_func_return_t tagTimerThreadFunction(CThread_func_arg_t userPtr)
return (CThread_func_return_t)EPHIDGET_OK;
}
+static int tagEvent(CPhidgetRFIDHandle phid, CPhidgetRFID_TagHandle tagPtr)
+{
+again:
+ CThread_mutex_lock(&phid->tagthreadlock);
+
+ //update time
+ setTimeNow(&phid->lastTagTime);
+
+ //See if there is a current tag, and if it matches this tag
+ if(phid->tagPresent != PTRUE ||
+ (phid->lastTagValid && strcmp(phid->lastTag.tagString, tagPtr->tagString) && phid->lastTag.protocol == tagPtr->protocol))
+ {
+ //Wait for tagEventPending to be false if it's true
+ if(phid->tagEventPending == PTRUE)
+ {
+ CThread_mutex_unlock(&phid->tagthreadlock);
+ SLEEP(10);
+ goto again;
+ }
+
+ phid->pendingTag = *tagPtr;
+ phid->tagEventPending = PTRUE;
+ CThread_set_event(&phid->tagAvailableEvent);
+ }
+
+ phid->tagPresent = PTRUE;
+
+ CThread_mutex_unlock(&phid->tagthreadlock);
+
+ return EPHIDGET_OK;
+}
+
+static int tagEvent_fromEM4100Data(CPhidgetRFIDHandle phid, unsigned char *data)
+{
+ CPhidgetRFID_Tag tag;
+ ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag));
+ snprintf(tag.tagString, RFID_MAX_TAG_STRING_LEN, "%02x%02x%02x%02x%02x",data[0],data[1],data[2],data[3],data[4]);
+ tag.protocol = PHIDGET_RFID_PROTOCOL_EM4100;
+ memcpy(tag.tagData, data, 5);
+ return tagEvent(phid, &tag);
+}
+
+static int waitForTag(CPhidgetRFIDHandle phid, char *tagString, int timeout)
+{
+ //Wait for this tag to show up
+ while(timeout > 0)
+ {
+ CThread_mutex_lock(&phid->tagthreadlock);
+ if(!strncmp(phid->pendingTag.tagString, tagString, RFID_MAX_TAG_STRING_LEN))
+ {
+ CThread_mutex_unlock(&phid->tagthreadlock);
+ return EPHIDGET_OK;
+ }
+ CThread_mutex_unlock(&phid->tagthreadlock);
+ SLEEP(50);
+ timeout-=50;
+ }
+
+ return EPHIDGET_TIMEOUT;
+}
+
static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength)
{
unsigned char buffer[10];
@@ -857,229 +781,210 @@ static int sendRAWData(CPhidgetRFIDHandle phid, unsigned char *data, int bitleng
return EPHIDGET_OK;
}
-static void resetHitagACBuffer(CPhidgetRFIDHandle phid)
+static void resetValuesFromSpace(CPhidgetRFIDHandle phid)
{
- phid->dataReadACPtr = phid->dataWritePtr;
- phid->ACCodingOK = PTRUE;
-}
+ phid->shortClocks = phid->longClocks = 0;
+ phid->manLockedIn = 0;
+ phid->manReadPtr = 0;
+ phid->manWritePtr = 0;
+ phid->biphaseReadPtr = 0;
+ phid->biphaseWritePtr = 0;
+ phid->manShortChange = 0;
+ phid->biphaseShortChange = 0;
+ phid->biphaseLockedIn = 0;
-//Hitag CRC
-#define CRC_PRESET 0xFF
-#define CRC_POLYNOM 0x1D
-static void calc_crc_hitag(unsigned char * crc,
- unsigned char data,
- unsigned char Bitcount)
-{
- *crc ^= data; //crc = crc (exor) data
- do
- {
- if( *crc & 0x80 ) // if (MSB-CRC == 1)
- {
- *crc<<=1; // CRC = CRC Bit-shift left
- *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM
- }
- else
- *crc<<=1; // CRC = CRC Bit-shift left
- } while(--Bitcount);
-}
-static unsigned char hitagCRC8(unsigned char *data, int dataBits)
-{
- unsigned char crc;
- int i;
- int dataLength = dataBits / 8;
- if(dataBits%8 != 0)
- dataLength++;
- crc = CRC_PRESET; /* initialize crc algorithm */
+#ifdef RFID_RAWDATA_API_SUPPORT
+ phid->manEventReadPtr = 0;
- for(i=0; i<dataLength; i++)
+ //Manchester event with space
+ if(phid->lastManEventLong == PFALSE)
{
- calc_crc_hitag(&crc, data[i], ((dataBits > 8) ? 8 : dataBits));
- dataBits -= 8;
+ unsigned char manEventData[1];
+ phid->lastManEventLong = PTRUE;
+ manEventData[0] = PUNK_BOOL;
+ FIRE(ManchesterData, manEventData, 1);
}
-
- return crc;
+#endif
}
-static int HitagS_WRITE(CPhidgetRFIDHandle phid, int page, unsigned char *data, unsigned char blockWrite)
+//ISO11785 CRC
+static void CRC_16_CCITT_update(unsigned short *crc, unsigned char x)
{
- int res;
- unsigned char buf[] = {0,0,0};
- unsigned char crc;
-
- buf[0] = (blockWrite ? 0x90 : 0x80) | page >> 4;
- buf[1] = page << 4;
- crc = hitagCRC8(buf, 12);
- buf[1] |= crc >> 4;
- buf[2] = crc << 4;
-
- //make sure it's been at least 50ms since last hitag request
- CThread_mutex_lock(&phid->tagthreadlock);
- while(timeSince(&phid->hitagReqTime) < 0.01) //50ms
- SLEEP(10);
-
- phid->hitagState = RFID_HITAG_STATE_WRITE;
- phid->hitagOffset = page;
-
- phid->manShortChange=0;
- phid->manLockedIn = 1;
- phid->manReadPtr = phid->manWritePtr;
-
- //Send a Hitag S Command
- res = CPhidgetRFID_writeRaw(phid, buf, 20, 7, 7, 7, 13, 21);
-
- //Don't send it again for at least 100ms
- setTimeNow(&phid->hitagReqTime);
- CThread_mutex_unlock(&phid->tagthreadlock);
-
- //Wait for ACK
-
- //Send page data
-
- return res;
+ unsigned short crc_new = (unsigned char)((*crc) >> 8) | ((*crc) << 8);
+ crc_new ^= x;
+ crc_new ^= (unsigned char)(crc_new & 0xff) >> 4;
+ crc_new ^= crc_new << 12;
+ crc_new ^= (crc_new & 0xff) << 5;
+ (*crc) = crc_new;
}
-static int HitagS_READ(CPhidgetRFIDHandle phid, int page, unsigned char blockRead)
+//Reverse all bits
+static __uint64
+reverse(__uint64 x)
{
- int res;
- unsigned char buf[] = {0,0,0};
- unsigned char crc;
-
- buf[0] = (blockRead ? 0xD0 : 0xC0) | page >> 4;
- buf[1] = page << 4;
- crc = hitagCRC8(buf, 12);
- buf[1] |= crc >> 4;
- buf[2] = crc << 4;
-
- //make sure it's been at least 50ms since last hitag request
- CThread_mutex_lock(&phid->tagthreadlock);
- while(timeSince(&phid->hitagReqTime) < 0.01) //50ms
- SLEEP(10);
-
- phid->hitagState = RFID_HITAG_STATE_READ;
- phid->hitagOffset = page;
-
- phid->manShortChange=0;
- phid->manLockedIn = 1;
- phid->manReadPtr = phid->manWritePtr;
-
- //Send a Hitag S Command
- res = CPhidgetRFID_writeRaw(phid, buf, 20, 7, 7, 7, 13, 21);
-
- //Don't send it again for at least 100ms
- setTimeNow(&phid->hitagReqTime);
- CThread_mutex_unlock(&phid->tagthreadlock);
-
- return res;
+ x = (((x & 0xaaaaaaaaaaaaaaaaLL) >> 1) | ((x & 0x5555555555555555LL) << 1));
+ x = (((x & 0xccccccccccccccccLL) >> 2) | ((x & 0x3333333333333333LL) << 2));
+ x = (((x & 0xf0f0f0f0f0f0f0f0LL) >> 4) | ((x & 0x0f0f0f0f0f0f0f0fLL) << 4));
+ x = (((x & 0xff00ff00ff00ff00LL) >> 8) | ((x & 0x00ff00ff00ff00ffLL) << 8));
+ x = (((x & 0xffff0000ffff0000LL) >> 16) | ((x & 0x0000ffff0000ffffLL) << 16));
+ return((x >> 32) | (x << 32));
}
-static int HitagS_SELECT(CPhidgetRFIDHandle phid, unsigned char *UID)
+/* Takes the tagString in 10-digit hex, and produces data for programming.
+ * blockData are 32-bit blocks.
+ * blockDataLen will be 2 when we return, as EM4100 takes 64-bits.
+ */
+static int encodeEM4100(char *tagString, unsigned int *blockData, int *blockDataLen)
{
- int res;
- unsigned char buf[] = {0,0,0,0,0,0};
- unsigned char crc;
- int k,i;
-
- if(!UID)
- return EPHIDGET_INVALIDARG;
- if(strlen((char *)UID)!=8)
+ __int64 tagData, mask;
+ __uint64 encodedTagData = 0;
+ int i,j,row,col;
+ TESTPTRS(tagString, blockData)
+ TESTPTR(blockDataLen)
+ if(*blockDataLen < 2)
return EPHIDGET_INVALIDARG;
+ if(strlen(tagString) != 10 )
+ if(!(strlen(tagString) == 12 && tagString[0] == '0' && tagString[1] == 'x'))
+ return EPHIDGET_INVALIDARG;
- for(i=0,k=5;i<32;i++,k++)
+ tagData = strtoll(tagString, NULL, 16);
+
+ //9 leading 1's
+ encodedTagData = 0xFF80000000000000LL;
+ //Data
+ for(i=0, mask=0x0078000000000000LL, j=15; i<10; i++, j--, mask>>=5)
{
- buf[k/8] |= ((hexval(UID[i/4]) >> (3-(i%4))) & 0x01) << (7-(k%8));
+ encodedTagData |= ((tagData << j) & mask);
}
- crc = hitagCRC8(buf, 37);
- for(i=0;i<8;i++,k++)
+ //Parity
+ for(i=0, row=1, col=1; i<40; i++, col++)
{
- buf[k/8] |= (crc >> (7-(i%8))) << (7-(k%8));
+ if(col>4) { col=1; row++; }
+
+ //column parity
+ encodedTagData ^= ((tagData & 0x1) << col);
+ //row parity
+ encodedTagData ^= ((tagData & 0x1) << (row*5));
+
+ tagData>>=1;
}
- //make sure it's been at least 50ms since last hitag request
- CThread_mutex_lock(&phid->tagthreadlock);
- while(timeSince(&phid->hitagReqTime) < 0.05) //50ms
- SLEEP(10);
-
- phid->hitagState = RFID_HITAG_STATE_SELECT;
-
- phid->manShortChange=0;
- phid->manLockedIn = 1;
- phid->manReadPtr = phid->manWritePtr;
-
- //Send a Hitag S AC Sequence Command
- res = CPhidgetRFID_writeRaw(phid, buf, k, 7, 7, 7, 13, 21);
-
- //Don't send it again for at least 100ms
- setTimeNow(&phid->hitagReqTime);
- CThread_mutex_unlock(&phid->tagthreadlock);
+ blockData[0] = (int)(encodedTagData >> 32);
+ blockData[1] = (int)encodedTagData;
+ *blockDataLen = 2;
- return res;
+ return EPHIDGET_OK;
}
-static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid)
+
+/* Takes the tagString in 15-digit decimal, and produces data for programming.
+ * blockData are 32-bit blocks.
+ * blockDataLen will be 4 when we return, as FDX-B takes 128-bits.
+ */
+static int encodeISO11785_FDX_B(char *tagString, unsigned int *blockData, int *blockDataLen)
{
- int res;
- //Send a Hitag S UID Request Command
- unsigned char buf[] = { 0xC0 };
+ __uint64 tagData, encodedTagData[2] = {0,0}, mask, uniqueID;
+ unsigned short crc = 0x0000;
+ unsigned long countryCode;
+ char countryCodeStr[4];
+ int i,j;
+ TESTPTRS(tagString, blockData)
+ TESTPTR(blockDataLen)
+ if(*blockDataLen < 4)
+ return EPHIDGET_INVALIDARG;
+ if(strlen(tagString) != 15 )
+ return EPHIDGET_INVALIDARG;
- //make sure it's been at least 50ms since last hitag request
- CThread_mutex_lock(&phid->tagthreadlock);
- while(timeSince(&phid->hitagReqTime) < 0.05) //50ms
- SLEEP(10);
+ //Get uniqueID
+ uniqueID = (__uint64)strtoll(tagString+3, NULL, 10);
+ //must be 38-bit or less
+ if(uniqueID > 0x3FFFFFFFFFLL)
+ return EPHIDGET_INVALIDARG;
- phid->hitagState = RFID_HITAG_STATE_UID_REQUEST;
+ //Get Country Code
+ memcpy(countryCodeStr, tagString, 3);
+ countryCodeStr[3] = '\0';
+ countryCode = strtoul(countryCodeStr, NULL, 10);
+
+ //Create ISO11784 64-bit data
+ tagData = (((__uint64)countryCode) << 38) | uniqueID;
+ //Add the animal bit
+ tagData |= 0x8000000000000000LL;
+ //Reverse because order is LSB 1st.
+ tagData = reverse(tagData);
+ //Calculate CRC
+ for(i=0,j=7*8;i<8;i++,j-=8)
+ CRC_16_CCITT_update(&crc, (unsigned char)((tagData>>j) & 0xFF));
+
+ //Put it into the FDX-B Format
+
+ //Header and control bits
+ encodedTagData[0] = 0x0020100804020100LL;
+ encodedTagData[1] = 0x8040201008040201LL;
+ //Data
+ for(i=0, mask = 0x001FE00000000000LL, j=11; i<6; i++, mask >>= 9, j++)
+ encodedTagData[0] |= ((tagData >> j) & mask);
+ for(i=0, mask = 0x7F80000000000000LL, j=47; i<2; i++, mask >>= 9, j--)
+ encodedTagData[1] |= ((tagData << j) & mask);
+ //CRC
+ encodedTagData[1] |= ((((__uint64)crc) << 29) & 0x00001FE000000000LL);
+ encodedTagData[1] |= ((((__uint64)crc) << 28) & 0x0000000FF0000000LL);
+
+ blockData[0] = (int)(encodedTagData[0] >> 32);
+ blockData[1] = (int)encodedTagData[0];
+ blockData[2] = (int)(encodedTagData[1] >> 32);
+ blockData[3] = (int)encodedTagData[1];
+ *blockDataLen = 4;
- //Empty AC List
- if(phid->hitagACList)
- CList_emptyList((CListHandle *)&phid->hitagACList, PTRUE, CPhidgetRFID_HitagAC_free);
- phid->hitagACList = NULL;
+ return EPHIDGET_OK;
+}
- resetHitagACBuffer(phid);
- res = CPhidgetRFID_writeRaw(phid, buf, 5, 7, 7, 7, 13, 21);
+/* Takes the tagString in ASCII up to 24 characters, and produces data for programming.
+ * blockData are 32-bit blocks.
+ * blockDataLen will be 7 when we return, as PHIDGETS_TAG takes 224-bits.
+ */
+static int encodePHIDGETS_TAG(char *tagString, unsigned int *blockData, int *blockDataLen)
+{
+ char tagData[24];
+ int len, i, j;
+ unsigned short crc;
+ TESTPTRS(tagString, blockData)
+ TESTPTR(blockDataLen)
+ if(*blockDataLen < 7)
+ return EPHIDGET_INVALIDARG;
+ if(strlen(tagString) > 24 )
+ return EPHIDGET_INVALIDARG;
- //Don't send it again for at least 100ms
- setTimeNow(&phid->hitagReqTime);
- CThread_mutex_unlock(&phid->tagthreadlock);
+ //copy of string.
+ len = strlen(tagString);
+ ZEROMEM(tagData, 24);
+ memcpy(tagData, tagString, len);
- return res;
-}
-static int HitagS_AC_SEQUENCE(CPhidgetRFIDHandle phid, CPhidgetRFID_HitagACHandle ac)
-{
- int res;
- unsigned char buf[] = {0,0,0,0,0,0};
- unsigned char crc;
- int k,i;
+ //Calculate CRC
+ crc=0;
+ for(i=0;i<24;i++)
+ CRC_16_CCITT_update(&crc, (unsigned char)tagData[i]);
- buf[0] = (ac->colPos) << 3;
- for(i=0,k=5;i<ac->colPos;i++,k++)
+ //Header, control bits and CRC
+ blockData[0] = 0x00040201;
+ blockData[0] |= (((unsigned int)crc) << 2 & 0x0003FC00);
+ blockData[0] |= (((unsigned int)crc) << 1 & 0x000001FE);
+ //Control bits
+ for(i=1;i<7;i++)
+ blockData[i] = 0x01010101;
+ //Data
+ for(i=0,j=184;i<24;i++,j-=8)
{
- buf[k/8] |= (ac->uid[i/8] >> (7-(i%8))) << (7-(k%8));
+ int block = i/4+1;
+ int shift = (j%32)+1;
+ blockData[block] |= (tagData[i] << shift);
}
- crc = hitagCRC8(buf, ac->colPos+5);
- for(i=0;i<8;i++,k++)
- {
- buf[k/8] |= (crc >> (7-(i%8))) << (7-(k%8));
- }
-
- //make sure it's been at least 50ms since last hitag request
- CThread_mutex_lock(&phid->tagthreadlock);
- while(timeSince(&phid->hitagReqTime) < 0.05) //50ms
- SLEEP(10);
-
- memcpy(&phid->lastHitagAC, ac, sizeof(CPhidgetRFID_HitagAC));
- //Send a Hitag S AC Sequence Command
- phid->hitagState = RFID_HITAG_STATE_AC_SEQUENCE;
-
- resetHitagACBuffer(phid);
- res = CPhidgetRFID_writeRaw(phid, buf, k, 7, 7, 7, 13, 21);
-
- //Don't send it again for at least 100ms
- setTimeNow(&phid->hitagReqTime);
- CThread_mutex_unlock(&phid->tagthreadlock);
+ *blockDataLen = 7;
- return res;
+ return EPHIDGET_OK;
}
-static int decodeEM4102(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag)
+static int decodeEM4100(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag)
{
int i, foundStart, k, j;
int myReadPtr = *startPtr;
@@ -1116,7 +1021,7 @@ start:
}
//Got here? - We found the start pattern
- //Now decode the EM4102 data
+ //Now decode the EM4100 data
for(i=0;i<64;i++)
{
em4103data[i] = data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK];
@@ -1157,22 +1062,11 @@ start:
j++; //skip row parity bit
}
- //Old style Tag event for EM4102
- CThread_mutex_lock(&phid->tagthreadlock);
- setTimeNow(&phid->lastTagTime);
- if((memcmp(phid->lastTag, decodedData, 5) || phid->tagPresent == PFALSE)
- && memcmp("\0\0\0\0\0", decodedData, 5)
- && !phid->tagEventPending)
- {
- memcpy(phid->pendingTag, decodedData, 5);
- phid->tagEventPending = PTRUE;
- CThread_set_event(&phid->tagAvailableEvent);
- }
- CThread_mutex_unlock(&phid->tagthreadlock);
- //Update the tag struct for the advanced tag event
- snprintf(tag->tagString, 255, "%02x%02x%02x%02x%02x",decodedData[0],decodedData[1],decodedData[2],decodedData[3],decodedData[4]);
- tag->tagInfo.tagType = PHIDGET_RFID_TAG_EM4102;
+ //Update the tag struct for the tag2 event
+ snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%02x%02x%02x%02x%02x",decodedData[0],decodedData[1],decodedData[2],decodedData[3],decodedData[4]);
+ tag->protocol = PHIDGET_RFID_PROTOCOL_EM4100;
+ memcpy(tag->tagData, decodedData, 5);
//update master read pointer
(*startPtr)+=64;
@@ -1185,19 +1079,7 @@ tryagain:
goto start;
}
-//ISO11785 CRC
-void
-CRC_16_CCITT_update(unsigned short *crc, unsigned char x)
-{
- unsigned short crc_new = (unsigned char)((*crc) >> 8) | ((*crc) << 8);
- crc_new ^= x;
- crc_new ^= (unsigned char)(crc_new & 0xff) >> 4;
- crc_new ^= crc_new << 12;
- crc_new ^= (crc_new & 0xff) << 5;
- (*crc) = crc_new;
-}
-
-static int decodeISO11785(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag)
+static int decodeISO11785_FDX_B(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag)
{
int i, foundStart, k;
int myReadPtr = *startPtr;
@@ -1305,8 +1187,8 @@ start:
(((__uint64)iso11785dataReversed[6]) << 8) +
((__uint64)iso11785dataReversed[7])) & 0x3FFFFFFFFFll;// 38 bit - bits 27-63
- snprintf(tag->tagString, 255, "%03d%012lld",countryCode, UID);
- tag->tagInfo.tagType = PHIDGET_RFID_TAG_ISO11784;
+ snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%03d%012lld",countryCode, UID);
+ tag->protocol = PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B;
}
//update master read pointer
@@ -1320,271 +1202,119 @@ tryagain:
goto start;
}
-static int decodeHitagUID(CPhidgetRFIDHandle phid, unsigned char *data, int bytesInQueue, CPhidgetRFID_TagHandle tag, int *collisionPos)
-{
- int i, k;
- int myReadPtr = 0;
- unsigned int HitagUID;
- int sofBits = 3;
- int expectedBytes = 0;
-
- if(phid->hitagState == RFID_HITAG_STATE_UID_REQUEST)
- expectedBytes = 35;
- else if(phid->hitagState == RFID_HITAG_STATE_AC_SEQUENCE)
- expectedBytes = 35 - phid->lastHitagAC.colPos;
-
- *collisionPos = -1;
-
- //UID is 32 bits, plus SOF == '111'
- if(bytesInQueue != expectedBytes)
- return EPHIDGET_NOTFOUND;
-
- //verify SOF
- for(i=0;i<sofBits;i++)
- {
- if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1)
- return EPHIDGET_NOTFOUND;
- }
-
- //advance past SOF
- myReadPtr += sofBits;
- myReadPtr &= RFID_DATA_ARRAY_MASK;
-
- HitagUID = 0;
-
- //if AC Sequence, read in bits from last AC
- for(k=0;k<(32-(expectedBytes-sofBits));k++)
- {
- HitagUID |= (phid->lastHitagAC.uid[k/8] >> (7-(k%8))) << (31-k);
- }
-
- for(i=0;i<(expectedBytes-sofBits);k++,i++)
- {
- //check for a collision
- if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] == PUNK_BOOL)
- {
- *collisionPos = k;
- return EPHIDGET_NOTFOUND;
- }
- HitagUID |= data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] << (31-k);
- }
-
- //We're good!
- snprintf(tag->tagString, 255, "%08x",HitagUID);
- tag->tagInfo.tagType = PHIDGET_RFID_TAG_HITAGS;
-
- return EPHIDGET_OK;
-}
-
-static int decodeHitagACKResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr)
+static int decodePHIDGETS_TAG(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr, CPhidgetRFID_TagHandle tag)
{
+ int i, foundStart, k;
int myReadPtr = *startPtr;
+ char tagData[24];
int bytesInQueue;
- int i;
- int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit
- int expectedBytes = 7;
-
+ unsigned short crcCalc = 0x0000, crcRead = 0x0000;
+ //Look for the starting pattern of 13 zeroes and 1 one
+start:
bytesInQueue = *endPtr - myReadPtr;
if(myReadPtr > *endPtr)
bytesInQueue += RFID_DATA_ARRAY_SIZE;
- //printf("maybe(read).. %d\n", bytesInQueue);
- //print_buffer(data, *startPtr, *endPtr);
-
- if(bytesInQueue != expectedBytes)
- return EPHIDGET_NOTFOUND;
-
- //verify SOF
- for(i=0;i<sofBits;i++)
+ while(myReadPtr != *endPtr)
{
- if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1)
+ //full sequence is 224 bits
+ if(bytesInQueue < 224)
+ return EPHIDGET_NOTFOUND;
+ foundStart = 1;
+
+ for(i=0;i<13;i++)
{
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
+ if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 0)
+ {
+ foundStart = 0;
+ break;
+ }
}
- }
-
- //Data should be '01'
- if(data[(myReadPtr + 5) & RFID_DATA_ARRAY_MASK] != 0
- || data[(myReadPtr + 6) & RFID_DATA_ARRAY_MASK] != 1)
- {
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
- }
-
- phid->respStatus = EPHIDGET_OK;
-done:
- CThread_set_event(&phid->respEvent);
- return phid->respStatus;
-}
-
-static int decodeHitagReadResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr)
-{
- int myReadPtr = *startPtr;
- int bytesInQueue;
- unsigned char buf[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- int i,k;
- int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit
- int expectedBytes = 141;
- unsigned char crcExpected = 0, crcFound = 0;
- CPhidgetRFID_TagHandle tag = phid->respData;
-
- bytesInQueue = *endPtr - myReadPtr;
- if(myReadPtr > *endPtr)
- bytesInQueue += RFID_DATA_ARRAY_SIZE;
-
- //printf("maybe(read).. %d\n", bytesInQueue);
- //print_buffer(data, *startPtr, *endPtr);
-
- if(bytesInQueue != expectedBytes)
- return EPHIDGET_NOTFOUND;
-
- //verify SOF
- for(i=0;i<sofBits;i++)
- {
- if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1)
+ if(data[(myReadPtr + 13) & RFID_DATA_ARRAY_MASK] != 1)
{
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
+ foundStart = 0;
}
- }
-
- //advance past SOF
- myReadPtr += sofBits;
- myReadPtr &= RFID_DATA_ARRAY_MASK;
+ if(foundStart)
+ break;
- for(k=0;k<128;k++)
- {
- buf[k/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-(k%8));
- }
- for(i=0;i<8;k++,i++)
- {
- crcFound |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-i);
- }
- crcExpected = hitagCRC8(buf, 128);
+ myReadPtr++;
+ myReadPtr &= RFID_DATA_ARRAY_MASK;
- if(crcFound != crcExpected)
- {
- LOG(PHIDGET_LOG_WARNING, "Hitag Read response has bad CRC (%02x, %02x)",crcFound, crcExpected);
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
+ bytesInQueue--;
}
- //We're good! transfer Read data
- memcpy(tag->tagData + phid->hitagOffset * 4, buf, 16);
- tag->tagDataValid = PTRUE;
-
- //update timer
- setTimeNow(&tag->lastTagTime);
-
- phid->respStatus = EPHIDGET_OK;
-done:
- CThread_set_event(&phid->respEvent);
- return phid->respStatus;
-}
-
-static int decodeHitagSelectResponse(CPhidgetRFIDHandle phid, unsigned char *data, int *startPtr, int *endPtr)
-{
- int myReadPtr = *startPtr;
- int bytesInQueue;
- unsigned char buf[] = {0,0,0,0};
- int i,k;
- int sofBits = 5; //SOF is really 6-bit but we only see it as 5-bit
- int expectedBytes = 45;
- unsigned char crcExpected = 0, crcFound = 0;
- CPhidgetRFID_TagHandle tag = phid->respData;
-
- bytesInQueue = *endPtr - myReadPtr;
- if(myReadPtr > *endPtr)
- bytesInQueue += RFID_DATA_ARRAY_SIZE;
-
- //printf("maybe.. %d\n", bytesInQueue);
- //print_buffer(data, *startPtr, *endPtr);
+ //advance past header
+ myReadPtr += 14;
+ myReadPtr &= RFID_DATA_ARRAY_MASK;
- if(bytesInQueue != expectedBytes)
- return EPHIDGET_NOTFOUND;
+ //Got here? - We found the start pattern
- //verify SOF
- for(i=0;i<sofBits;i++)
+ //Pull out the CRC
+ for(k=0,i=0;i<16;i++,k++)
{
- if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1)
+ if(i>0 && i%8 == 0)
{
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
+ if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1) goto tryagain;
+ k++;
}
- }
-
- //advance past SOF
- myReadPtr += sofBits;
- myReadPtr &= RFID_DATA_ARRAY_MASK;
+ crcRead |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (15-i);
+ }
+ if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1) goto tryagain;
+ k++;
- for(k=0;k<32;k++)
- {
- buf[k/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-(k%8));
- }
- for(i=0;i<8;k++,i++)
+ //Now decode the PHIDGETS_TAG data
+ //every block of 7 is followed by a '1'
+ memset(tagData, 0, 24);
+ for(i=0;i<192;i++,k++)
{
- crcFound |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (7-i);
+ //Check for control bit
+ if((i+1)%8 == 0)
+ {
+ if(data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] != 1)
+ goto tryagain;
+ }
+ //pull out data
+ else
+ {
+ tagData[i/8] |= data[(myReadPtr + k) & RFID_DATA_ARRAY_MASK] << (6-(i%8));
+ }
}
- crcExpected = hitagCRC8(buf, 32);
- if(crcFound != crcExpected)
- {
- LOG(PHIDGET_LOG_WARNING, "Hitag Select response has bad CRC (%02x, %02x)",crcFound, crcExpected);
- phid->respStatus = EPHIDGET_NOTFOUND;
- goto done;
- }
+ //Calculate CRC
+ crcCalc = 0;
+ for(i=0;i<24;i++)
+ CRC_16_CCITT_update(&crcCalc, (unsigned char)tagData[i]);
- //We're good! fill in structure
- //Memory size
- switch(buf[0] & 0x03)
+ if(crcCalc != crcRead)
{
- case 0x00:
- tag->tagOptions.memSize = 32;
- break;
- case 0x01:
- tag->tagOptions.memSize = 256;
- break;
- case 0x02:
- tag->tagOptions.memSize = 2048;
- break;
- case 0x03:
- default:
- phid->respStatus = EPHIDGET_UNEXPECTED;
- goto done;
+ //FAIL
+ goto tryagain;
}
- //AUT bit
- if(buf[1] & 0x80)
- tag->tagOptions.encrypted = PTRUE;
- else
- tag->tagOptions.encrypted = PFALSE;
- //LCON bit
- if(buf[1] & 0x02)
- tag->tagOptions.writable = PFALSE;
- else
- tag->tagOptions.writable = PTRUE;
- tag->tagOptionsValid = PTRUE;
+ //We're good!
+ memcpy(tag->tagString, tagData, 24);
+ tag->tagString[24] = '\0';
+ tag->protocol = PHIDGET_RFID_PROTOCOL_PHIDGETS;
- //update timer
- setTimeNow(&tag->lastTagTime);
+ //update master read pointer
+ (*startPtr) += 224;
+ (*startPtr) &= RFID_DATA_ARRAY_MASK;
+ return EPHIDGET_OK;
- phid->respStatus = EPHIDGET_OK;
-done:
- CThread_set_event(&phid->respEvent);
- return phid->respStatus;
+tryagain:
+ myReadPtr++;
+ myReadPtr &= RFID_DATA_ARRAY_MASK;
+ goto start;
}
-static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClocks, int longClocks)
+static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr)
{
int myReadPtr = phid->dataReadPtr;
while(myReadPtr != readToPtr)
{
- int clocks = phid->dataBuffer[myReadPtr] & 0x7F;
- //int polarity = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0;
+ int clocks = phid->dataBuffer[myReadPtr] & 0xFF;
- //1
- if (pdiff(clocks, longClocks) < 0.3) {
+ if (clocks == phid->longClocks) {
phid->biphaseBuffer[phid->biphaseWritePtr] = 1;
@@ -1600,7 +1330,7 @@ static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClo
phid->biphaseLockedIn = 1;
phid->biphaseShortChange = 0;
}
- else if (pdiff(clocks, shortClocks) < 0.3) {
+ else if (clocks == phid->shortClocks) {
if (phid->biphaseLockedIn && phid->biphaseShortChange) {
phid->biphaseBuffer[phid->biphaseWritePtr] = 0;
@@ -1632,15 +1362,26 @@ static int add_biphase_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClo
return EPHIDGET_OK;
}
-static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr, int shortClocks, int longClocks)
+static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr)
{
int myReadPtr = phid->dataReadPtr;
while(myReadPtr != readToPtr)
{
- int clocks = phid->dataBuffer[myReadPtr] & 0x7F;
- int polarity = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0;
+ int clocks = phid->dataBuffer[myReadPtr] & 0xFF;
+ int polarity = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0;
- if (pdiff(clocks, longClocks) < 0.3) {
+ if (clocks == phid->longClocks)
+ {
+ //We're out of sync - re-sync
+ if(phid->manShortChange)
+ {
+ phid->manReadPtr = phid->manWritePtr;
+ phid->manReadPtr &= RFID_DATA_ARRAY_MASK;
+#ifdef RFID_RAWDATA_API_SUPPORT
+ phid->manEventReadPtr = phid->manWritePtr;
+ phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK;
+#endif
+ }
if (polarity)
phid->manBuffer[phid->manWritePtr] = 1;
@@ -1650,59 +1391,427 @@ static int add_manchester_data(CPhidgetRFIDHandle phid, int readToPtr, int short
phid->manWritePtr++;
phid->manWritePtr &= RFID_DATA_ARRAY_MASK;
+ //TODO: is there a danger of these actually happening??
if(phid->manWritePtr == phid->manReadPtr)
{
phid->manReadPtr++;
phid->manReadPtr &= RFID_DATA_ARRAY_MASK;
}
+#ifdef RFID_RAWDATA_API_SUPPORT
if(phid->manWritePtr == phid->manEventReadPtr)
{
phid->manEventReadPtr++;
phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK;
}
+#endif
phid->manLockedIn = 1;
phid->manShortChange = 0;
- }
- else if (pdiff(clocks, shortClocks) < 0.3) {
- if (phid->manLockedIn && phid->manShortChange) {
- if (polarity)
- phid->manBuffer[phid->manWritePtr] = 1;
- else
- phid->manBuffer[phid->manWritePtr] = 0;
-
- phid->manWritePtr++;
- phid->manWritePtr &= RFID_DATA_ARRAY_MASK;
-
- if(phid->manWritePtr == phid->manReadPtr)
+ }
+ // Short clocks
+ else
+ {
+ if(!phid->manLockedIn)
+ {
+ if(polarity)
{
- phid->manReadPtr++;
- phid->manReadPtr &= RFID_DATA_ARRAY_MASK;
+ phid->manShortChange=1;
+ phid->manLockedIn = 1;
}
-
- if(phid->manWritePtr == phid->manEventReadPtr)
+ }
+ else
+ {
+ if(phid->manShortChange)
{
- phid->manEventReadPtr++;
- phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK;
- }
+ if (polarity)
+ phid->manBuffer[phid->manWritePtr] = 1;
+ else
+ phid->manBuffer[phid->manWritePtr] = 0;
+
+ phid->manWritePtr++;
+ phid->manWritePtr &= RFID_DATA_ARRAY_MASK;
+
+ if(phid->manWritePtr == phid->manReadPtr)
+ {
+ phid->manReadPtr++;
+ phid->manReadPtr &= RFID_DATA_ARRAY_MASK;
+ }
+
+#ifdef RFID_RAWDATA_API_SUPPORT
+ if(phid->manWritePtr == phid->manEventReadPtr)
+ {
+ phid->manEventReadPtr++;
+ phid->manEventReadPtr &= RFID_DATA_ARRAY_MASK;
+ }
+#endif
- phid->manShortChange=0;
+ phid->manShortChange=0;
+ }
+ else
+ phid->manShortChange=1;
}
- else
- phid->manShortChange=1;
}
- else {
- phid->manLockedIn = 0;
- //invalid
- phid->manReadPtr = phid->manEventReadPtr = phid->manWritePtr;
- //This is not Manchester encoded data
- return EPHIDGET_NOTFOUND;
+
+ myReadPtr++;
+ myReadPtr &= RFID_DATA_ARRAY_MASK;
+ }
+ return EPHIDGET_OK;
+}
+
+//Analyses streaming data in Manchester or Biphase coding
+static int analyze_data(CPhidgetRFIDHandle phid)
+{
+ int bytesToRead = 0, bytesRead = 0;
+ int temp, clocks;
+ int myReadPtr;
+ CPhidgetRFID_Tag tag;
+
+ //read till we have real data
+start:
+ while(phid->dataReadPtr != phid->dataWritePtr)
+ {
+ if(phid->dataBuffer[phid->dataReadPtr] == PUNK_INT)
+ {
+ //LOG(PHIDGET_LOG_DEBUG, "LONG");
+ phid->dataReadPtr++;
+ phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
+ resetValuesFromSpace(phid);
+ }
+ else
+ break;
+ }
+
+ //Make sure we have enough data to do something useful with..
+ bytesToRead = phid->dataWritePtr - phid->dataReadPtr;
+ if(phid->dataReadPtr > phid->dataWritePtr)
+ bytesToRead += RFID_DATA_ARRAY_SIZE;
+
+ //then read till we have a space or run out of data - figure out data rate
+ bytesRead = 0;
+ myReadPtr = phid->dataReadPtr;
+ while(myReadPtr != phid->dataWritePtr)
+ {
+ if(phid->dataBuffer[myReadPtr] == PUNK_INT)
+ break;
+
+ clocks = (phid->dataBuffer[myReadPtr] & 0xFF);
+
+ if(!phid->shortClocks)
+ {
+ phid->shortClocks = clocks;
+ }
+ else if(clocks != phid->shortClocks)
+ {
+ if(!phid->longClocks)
+ {
+ if(phid->shortClocks * 2 == clocks || phid->shortClocks / 2 == clocks)
+ phid->longClocks = clocks;
+ else
+ //found a values that doesn't work - error
+ goto update_readPtr_restart;
+ }
+ else if(clocks != phid->longClocks)
+ //found a values that doesn't work - error
+ goto update_readPtr_restart;
}
myReadPtr++;
myReadPtr &= RFID_DATA_ARRAY_MASK;
+ bytesRead++;
+ }
+
+ //We haven't seen a one and a two!!
+ if(phid->shortClocks == 0 || phid->longClocks == 0)
+ {
+ //got a gap? move on to more data
+ if(bytesRead != bytesToRead)
+ goto check_done;
+
+ //otherwise, wait for more data
+ return EPHIDGET_OK;
+ }
+
+ //Order them by size
+ if(phid->longClocks < phid->shortClocks)
+ {
+ temp = phid->longClocks;
+ phid->longClocks = phid->shortClocks;
+ phid->shortClocks = temp;
+ }
+
+ ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag));
+
+ //Shift data into Manchester and Biphase decoders, update read ptr
+ if(!add_manchester_data(phid, myReadPtr))
+ {
+#ifdef RFID_RAWDATA_API_SUPPORT
+ unsigned char manEventData[RFID_DATA_ARRAY_SIZE];
+ int manEventDataWritePtr = 0;
+#endif
+
+ if(!decodeEM4100(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag))
+ tagEvent(phid, &tag);
+
+#ifdef RFID_RAWDATA_API_SUPPORT
+ //Manchester data event
+ while(phid->manEventReadPtr != phid->manWritePtr)
+ {
+ manEventData[manEventDataWritePtr++] = phid->manBuffer[phid->manEventReadPtr];
+ phid->manEventReadPtr++;
+ phid->manEventReadPtr&=RFID_DATA_ARRAY_MASK;
+ }
+ if(manEventDataWritePtr)
+ {
+ phid->lastManEventLong = PFALSE;
+ FIRE(ManchesterData, manEventData, manEventDataWritePtr);
+ }
+ }
+ //Manchester event with space
+ else if(phid->lastManEventLong == PFALSE)
+ {
+ unsigned char manEventData[1];
+ phid->lastManEventLong = PTRUE;
+ manEventData[0] = PUNK_BOOL;
+ FIRE(ManchesterData, manEventData, 1);
+#endif
+ }
+
+ if(!add_biphase_data(phid, myReadPtr))
+ {
+ if(!decodePHIDGETS_TAG(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag))
+ tagEvent(phid, &tag);
+ if(!decodeISO11785_FDX_B(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag))
+ tagEvent(phid, &tag);
+ }
+
+check_done:
+ //update read pointer
+ phid->dataReadPtr = myReadPtr;
+
+ //If there is more data, loop around
+ if(phid->dataReadPtr != phid->dataWritePtr)
+ goto start;
+
+ return EPHIDGET_OK;
+
+ //ran into a bad pulse length or a gap - reset stuff
+update_readPtr_restart:
+ phid->dataReadPtr++;
+ phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
+ resetValuesFromSpace(phid);
+
+ goto start;
+}
+
+static int T5577_WriteBlock(CPhidgetRFIDHandle phid, int page, int block, unsigned int data, int lockpage)
+{
+ int res = EPHIDGET_OK;
+ unsigned char byteData[5];
+
+ byteData[0] = ((0x02 | (page & 0x01)) << 6); //OpCode
+ byteData[0] |= ((lockpage ? 0x01 : 0x00) << 5); //Lock
+ byteData[0] |= ((data >> 27) & 0x1F); //Data 31:27
+ byteData[1] = ((data >> 19) & 0xFF); //Data 26:19
+ byteData[2] = ((data >> 11) & 0xFF); //Data 18:11
+ byteData[3] = ((data >> 3) & 0xFF); //Data 10:3
+ byteData[4] = ((data << 5) & 0xE0); //Data 2:0
+ byteData[4] |= ((block & 0x07) << 2); //Block (0-7)
+
+ res = CPhidgetRFID_writeRaw(phid, byteData, 38,
+ RFID_T5577_StartGap,
+ RFID_T5577_WriteGap,
+ RFID_T5577_EndGap,
+ RFID_T5577_Zero,
+ RFID_T5577_One,
+ RFID_T5577_PrePulse,
+ RFID_T5577_EOF,
+ PFALSE);
+
+ return res;
+}
+
+static int T5577_Reset(CPhidgetRFIDHandle phid)
+{
+ int res = EPHIDGET_OK;
+ unsigned char byteData[1];
+
+ byteData[0] = 0x00; //OpCode
+
+ res = CPhidgetRFID_writeRaw(phid, byteData, 2,
+ RFID_T5577_StartGap,
+ RFID_T5577_WriteGap,
+ RFID_T5577_EndGap,
+ RFID_T5577_Zero,
+ RFID_T5577_One,
+ RFID_T5577_PrePulse,
+ RFID_T5577_EOF,
+ PFALSE);
+
+ return res;
+}
+
+/* Programs a T5577 using the specified protocol and data
+ * data: Tag string.
+ * lock: lock the T5577 so it cannot be reprogrammed.
+ */
+static int T5577_WriteTag(CPhidgetRFIDHandle phid, CPhidgetRFID_Protocol protocol, char *tagString, int lock)
+{
+ int ret = EPHIDGET_OK, i;
+ unsigned int data[7];
+ int dataLen = 7;
+ unsigned int configBlock;
+
+ switch(protocol)
+ {
+ case PHIDGET_RFID_PROTOCOL_EM4100:
+ if((ret = encodeEM4100(tagString, data, &dataLen)) != EPHIDGET_OK)
+ return ret;
+ configBlock = 0x00148040; // RF/63, manchester, Maxblock = 2
+ break;
+ case PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B:
+ if((ret = encodeISO11785_FDX_B(tagString, data, &dataLen)) != EPHIDGET_OK)
+ return ret;
+ configBlock = 0x603F8080; // RF/32, differential bi-phase, Maxblock = 4
+ break;
+ case PHIDGET_RFID_PROTOCOL_PHIDGETS:
+ if((ret = encodePHIDGETS_TAG(tagString, data, &dataLen)) != EPHIDGET_OK)
+ return ret;
+ configBlock = 0x603F80E0; // RF/32, differential bi-phase, Maxblock = 7
+ break;
+ default:
+ return EPHIDGET_INVALIDARG;
+ }
+
+ //Write Data
+ for(i=0;i<dataLen;i++)
+ {
+ if((ret = T5577_WriteBlock(phid, 0, i+1, data[i], lock)) != EPHIDGET_OK)
+ return ret;
+ SLEEP(50); //some time beetween writes!
+ }
+ //Write config
+ if((ret = T5577_WriteBlock(phid, 0, 0, configBlock, lock)) != EPHIDGET_OK)
+ return ret;
+
+ SLEEP(50); //some time beetween writes!
+ //Reset Chip
+ if((ret = T5577_Reset(phid)) != EPHIDGET_OK)
+ return ret;
+
+ return ret;
+}
+
+#ifdef RFID_HITAGS_SUPPORT
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#define pdiff(a, b) ( ABS((a) - (b)) / (double)( ((a) + (b)) / 2.0 ) )
+
+static void resetHitagACBuffer(CPhidgetRFIDHandle phid)
+{
+ phid->dataReadACPtr = phid->dataWritePtr;
+ phid->ACCodingOK = PTRUE;
+}
+
+//Hitag CRC
+#define CRC_PRESET 0xFF
+#define CRC_POLYNOM 0x1D
+static void calc_crc_hitag(unsigned char * crc,
+ unsigned char data,
+ unsigned char Bitcount)
+{
+ *crc ^= data; //crc = crc (exor) data
+ do
+ {
+ if( *crc & 0x80 ) // if (MSB-CRC == 1)
+ {
+ *crc<<=1; // CRC = CRC Bit-shift left
+ *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM
+ }
+ else
+ *crc<<=1; // CRC = CRC Bit-shift left
+ } while(--Bitcount);
+}
+static unsigned char hitagCRC8(unsigned char *data, int dataBits)
+{
+ unsigned char crc;
+ int i;
+ int dataLength = dataBits / 8;
+ if(dataBits%8 != 0)
+ dataLength++;
+ crc = CRC_PRESET; /* initialize crc algorithm */
+
+ for(i=0; i<dataLength; i++)
+ {
+ calc_crc_hitag(&crc, data[i], ((dataBits > 8) ? 8 : dataBits));
+ dataBits -= 8;
+ }
+
+ return crc;
+}
+
+static int HitagS_UID_REQUEST(CPhidgetRFIDHandle phid)
+{
+ int res;
+ //Send a Hitag S UID Request Command
+ unsigned char buf[] = { 0xC0 };
+
+ //make sure it's been at least 50ms since last hitag request
+ while(timeSince(&phid->hitagReqTime) < 0.05) //50ms
+ SLEEP(10);
+
+ resetHitagACBuffer(phid);
+ res = CPhidgetRFID_writeRaw(phid, buf, 5, 7, 7, 7, 13, 21, 0, 64, PTRUE);
+
+ //Don't send it again for at least 100ms
+ setTimeNow(&phid->hitagReqTime);
+
+ return res;
+}
+
+static int decodeHitagUID(CPhidgetRFIDHandle phid, unsigned char *data, int bytesInQueue, CPhidgetRFID_TagHandle tag, int *collisionPos)
+{
+ int i, k;
+ int myReadPtr = 0;
+ unsigned int HitagUID;
+ int sofBits = 3;
+ int expectedBytes = 0;
+
+ expectedBytes = 35;
+
+ *collisionPos = -1;
+
+ //UID is 32 bits, plus SOF == '111'
+ if(bytesInQueue != expectedBytes)
+ return EPHIDGET_NOTFOUND;
+
+ //verify SOF
+ for(i=0;i<sofBits;i++)
+ {
+ if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] != 1)
+ return EPHIDGET_NOTFOUND;
+ }
+
+ //advance past SOF
+ myReadPtr += sofBits;
+ myReadPtr &= RFID_DATA_ARRAY_MASK;
+
+ HitagUID = 0;
+
+ for(i=0,k=0;i<(expectedBytes-sofBits);k++,i++)
+ {
+ //check for a collision
+ if(data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] == PUNK_BOOL)
+ {
+ *collisionPos = k;
+ return EPHIDGET_NOTFOUND;
+ }
+ HitagUID |= data[(myReadPtr + i) & RFID_DATA_ARRAY_MASK] << (31-k);
}
+
+ //We're good!
+ snprintf(tag->tagString, RFID_MAX_TAG_STRING_LEN, "%08x",HitagUID);
+ tag->protocol = PHIDGET_RFID_PROTOCOL_HITAGS_UID;
+
return EPHIDGET_OK;
}
@@ -1721,20 +1830,17 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
int acWritePtr = 0;
unsigned char acBitLocation = 0;
- if(phid->hitagState == RFID_HITAG_STATE_UID_REQUEST)
- lastIndex = 34;
- else if(phid->hitagState == RFID_HITAG_STATE_AC_SEQUENCE)
- lastIndex = 34 - phid->lastHitagAC.colPos;
+ lastIndex = 34;
if(*acBufferSize < lastIndex+1)
goto fail;
//if the first pulse is low, we need to add a high pulse before it
- if(!(phid->dataBuffer[phid->dataReadACPtr] & 0x80))
+ if(!(phid->dataBuffer[phid->dataReadACPtr] & 0x100))
{
myReadPtr--;
myReadPtr &= RFID_DATA_ARRAY_MASK;
- phid->dataBuffer[myReadPtr] = (shortClocks/2) | 0x80;
+ phid->dataBuffer[myReadPtr] = (shortClocks/2) | 0x100;
}
bytesToRead = readToPtr - myReadPtr;
@@ -1748,10 +1854,10 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
for(i=0;i<bytesToRead;i+=2)
{
- clocks1 = phid->dataBuffer[myReadPtr] & 0x7F;
- polarity1 = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0;
- clocks2 = phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x7F;
- polarity2 = (phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x80) ? 1 : 0;
+ clocks1 = phid->dataBuffer[myReadPtr] & 0xFF;
+ polarity1 = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0;
+ clocks2 = phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0xFF;
+ polarity2 = (phid->dataBuffer[(myReadPtr+1) & RFID_DATA_ARRAY_MASK] & 0x100) ? 1 : 0;
clocks = clocks1 + clocks2;
@@ -1759,7 +1865,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
goto fail;
//the first pulse can be long
- if (pdiff(clocks, shortClocks) < 0.2 || acWritePtr == 0)
+ if (clocks == shortClocks || acWritePtr == 0)
{
if(acBitLocation == 1)
{
@@ -1769,7 +1875,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
}
acBitLocation ^= 1;
}
- else if(pdiff(clocks, longClocks) < 0.2)
+ else if(clocks == longClocks)
{
if(acBitLocation == 1)
{
@@ -1807,13 +1913,13 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
//last low pulse won't be seen because we idle low
if(acWritePtr == lastIndex && myReadPtr == ((readToPtr-1) & RFID_DATA_ARRAY_MASK))
{
- clocks = phid->dataBuffer[myReadPtr] & 0x7F;
- polarity1 = (phid->dataBuffer[myReadPtr] & 0x80) ? 1 : 0;
+ clocks = phid->dataBuffer[myReadPtr] & 0xFF;
+ polarity1 = (phid->dataBuffer[myReadPtr] & 0x100) ? 1 : 0;
if(polarity1 != 1)
goto fail;
- if(pdiff(clocks, shortClocks/2) < 0.4)
+ if(clocks == shortClocks/2)
{
if(acBitLocation==1)
{
@@ -1824,7 +1930,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
else
acBitLocation ^= 1;
}
- else if(pdiff(clocks, longClocks/2) < 0.3)
+ else if(clocks == shortClocks)
{
if(acBitLocation==1)
goto fail;
@@ -1832,7 +1938,7 @@ static int decodeACdata(CPhidgetRFIDHandle phid, unsigned char *acBuffer, int *a
acBuffer[acWritePtr] = PFALSE;
acWritePtr++;
}
- else if(pdiff(clocks, (longClocks/4)*3) < 0.25)
+ else if(clocks, shortClocks * 1.5)
{
if(acBitLocation==1)
goto fail;
@@ -1858,257 +1964,6 @@ fail:
return EPHIDGET_NOTFOUND;
}
-//NOTE: tag is a local variable, we need to make a copy of it before adding it to lists, etc.
-static int advanced_tag_event(CPhidgetRFIDHandle phid, CPhidgetRFID_TagHandle tagPtr, int lock)
-{
- CPhidgetRFID_TagHandle tag;
- //Add to the tag list here, remove from the tag list in the tagTimerThreadFunction
- if(lock)
- CThread_mutex_lock(&phid->tagthreadlock);
- if(CList_findInList((CListHandle)phid->tagAdvancedList, tagPtr, CPhidgetRFID_Tag_areEqual, (void**)&tag) == EPHIDGET_NOTFOUND)
- {
- //make a copy
- tag = (CPhidgetRFID_TagHandle)malloc(sizeof(*tag));
- memcpy(tag, tagPtr, sizeof(*tag));
- tag->tagEventPending = PTRUE;
- CThread_set_event(&phid->tagAvailableEvent);
- CList_addToList((CListHandle *)&phid->tagAdvancedList, tag, CPhidgetRFID_Tag_areEqual);
- }
-
- setTimeNow(&tag->lastTagTime);
- if(lock)
- CThread_mutex_unlock(&phid->tagthreadlock);
-
- return EPHIDGET_OK;
-}
-
-//Analyses streaming data in Manchester or Biphase coding
-static int analyze_data(CPhidgetRFIDHandle phid)
-{
- int bytesToRead = 0, bytesRead = 0;
- int temp, one, two;
- int myReadPtr;
- CPhidgetRFID_Tag tag;
-
- //read till we have real data
-start:
- while(phid->dataReadPtr != phid->dataWritePtr)
- {
- if(phid->dataBuffer[phid->dataReadPtr] == PUNK_INT)
- {
- phid->dataReadPtr++;
- phid->dataReadPtr &= RFID_DATA_ARRAY_MASK;
- phid->atGap = PTRUE;
-
- phid->one = phid->two = phid->oneCount = phid->twoCount = 0;
- }
- else
- break;
- }
- myReadPtr = phid->dataReadPtr;
-
- //Make sure we have enough data to do something useful with..
- bytesToRead = phid->dataWritePtr - phid->dataReadPtr;
- if(phid->dataReadPtr > phid->dataWritePtr)
- bytesToRead += RFID_DATA_ARRAY_SIZE;
-
- if(bytesToRead < 32 && phid->atGap)
- return EPHIDGET_OK;
-
- //then read till we have a space or run out of data - figure out data rate
- one = two = 0;
- bytesRead = 0;
- while(myReadPtr != phid->dataWritePtr)
- {
- if(phid->dataBuffer[myReadPtr] == PUNK_INT)
- break;
-
- if(phid->one == 0)
- {
- phid->one = phid->dataBuffer[myReadPtr] & 0x7F;
- phid->oneCount++;
- }
- else
- {
- temp = round((double)((double)phid->one / (double)phid->oneCount));
- if(pdiff(temp, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3)
- {
- phid->one += phid->dataBuffer[myReadPtr] & 0x7F;
- phid->oneCount++;
- }
- else
- {
- if(phid->two == 0)
- {
- temp = round((double)((double)phid->one / (double)phid->oneCount));
- if(pdiff(temp * 2, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3
- || pdiff(temp / 2, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3)
- {
- phid->two = phid->dataBuffer[myReadPtr] & 0x7F;
- phid->twoCount++;
- }
- else
- {
- goto update_readPtr_restart;
- }
- }
- else
- {
- temp = round((double)((double)phid->two / (double)phid->twoCount));
- if(pdiff(temp, phid->dataBuffer[myReadPtr] & 0x7F) < 0.3)
- {
- phid->two += phid->dataBuffer[myReadPtr] & 0x7F;
- phid->twoCount++;
- }
- else
- {
- goto update_readPtr_restart;
- }
- }
- }
- }
-
- myReadPtr++;
- myReadPtr &= RFID_DATA_ARRAY_MASK;
- bytesRead++;
- }
-
- if(bytesRead < bytesToRead)
- {
- goto update_readPtr_restart;
- }
-
- //don't let the one and two counters get too big
- if(phid->oneCount >= RFID_DATA_ARRAY_SIZE)
- {
- phid->one = round((double)((double)phid->one / 2.0));
- phid->oneCount = phid->oneCount / 2;
- }
- if(phid->twoCount >= RFID_DATA_ARRAY_SIZE)
- {
- phid->two = round((double)((double)phid->two / 2.0));
- phid->twoCount = phid->twoCount / 2;
- }
-
- if(phid->one)
- one = round((double)((double)phid->one / (double)phid->oneCount));
- if(phid->two)
- two = round((double)((double)phid->two / (double)phid->twoCount));
-
- //Order them by size
- if(two < one)
- {
- temp = two;
- two = one;
- one = temp;
- }
-
- //printf("One: %3d Two: %3d Bytes: %4d\n",one, two, bytesToRead);
-
- ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag));
- //Normalize the data rate we supply to the user to be a power of 2
- //TODO: are there any tags which use a bitrate that's not a power of two?
- //Yes - Q5 can have an arbitrary data rate
- temp=1;
- tag.tagInfo.bitRate = two;
- while(temp<two)
- {
- temp*=2;
- if(pdiff(temp, two) < 0.3)
- {
- tag.tagInfo.bitRate = temp;
- break;
- }
- }
- if(tag.tagInfo.bitRate == 128)
- printf("hmm\n"); //TODO: are we actually going to do something about this?
-
- //Shift data into Manchester and Biphase decoders, update read ptr
- if(phid->hitagState == RFID_HITAG_STATE_SELECT
- || phid->hitagState == RFID_HITAG_STATE_READ
- || phid->hitagState == RFID_HITAG_STATE_WRITE)
- {
- if(phid->manReadPtr == phid->manWritePtr)
- {
- //may have to advance one to make things work
- if(phid->dataBuffer[phid->dataReadPtr] & 0x80 && pdiff(phid->dataBuffer[phid->dataReadPtr] & 0x7F, 16) < 0.3)
- phid->dataReadPtr = ((phid->dataReadPtr + 1) & RFID_DATA_ARRAY_MASK);
- }
- }
- if(!add_manchester_data(phid, myReadPtr, one, two))
- {
- unsigned char manEventData[RFID_DATA_ARRAY_SIZE];
- int manEventDataWritePtr = 0;
-
- tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_MANCHESTER;
-
- //Manchester data event
- while(phid->manEventReadPtr != phid->manWritePtr)
- {
- manEventData[manEventDataWritePtr++] = phid->manBuffer[phid->manEventReadPtr];
- phid->manEventReadPtr++;
- phid->manEventReadPtr&=RFID_DATA_ARRAY_MASK;
- }
- if(manEventDataWritePtr)
- FIRE(ManchesterData, manEventData, manEventDataWritePtr);
-
- if(phid->hitagState == RFID_HITAG_STATE_SELECT)
- {
- //try to decode a Hitag SELECT response
- decodeHitagSelectResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr);
- }
- if(phid->hitagState == RFID_HITAG_STATE_READ)
- {
- //try to decode a Hitag READ response
- decodeHitagReadResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr);
- }
- if(phid->hitagState == RFID_HITAG_STATE_WRITE)
- {
- //try to decode a Hitag WRITE response
- decodeHitagACKResponse(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr);
- }
- if(!decodeEM4102(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag))
- advanced_tag_event(phid, &tag, PTRUE);
- if(!decodeISO11785(phid, phid->manBuffer, &phid->manReadPtr, &phid->manWritePtr, &tag))
- advanced_tag_event(phid, &tag, PTRUE);
- }
- else
- {
- //Manchester event with space
- unsigned char manEventData[1];
- manEventData[0] = PUNK_BOOL;
- phid->manEventReadPtr = phid->manWritePtr;
-
- FIRE(ManchesterData, manEventData, 1);
- }
- if(!add_biphase_data(phid, myReadPtr, one, two))
- {
- tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_BIPHASE;
- if(!decodeEM4102(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag))
- advanced_tag_event(phid, &tag, PTRUE);
- if(!decodeISO11785(phid, phid->biphaseBuffer, &phid->biphaseReadPtr, &phid->biphaseWritePtr, &tag))
- advanced_tag_event(phid, &tag, PTRUE);
- }
-
- //update read pointer
- phid->dataReadPtr = myReadPtr;
- phid->atGap = PFALSE;
-
- return EPHIDGET_OK;
-
- //ran into a bad pulse length or a gap - reset stuff
-update_readPtr_restart:
- phid->one = phid->two = phid->oneCount = phid->twoCount = 0;
- phid->dataReadPtr = myReadPtr;
- phid->atGap = PTRUE;
- phid->manReadPtr = 0;
- phid->manEventReadPtr = 0;
- phid->manWritePtr = 0;
- phid->biphaseReadPtr = 0;
- phid->biphaseWritePtr = 0;
- goto start;
-}
-
//Analyses data for Hitag AC coding
static int analyze_data_AC(CPhidgetRFIDHandle phid)
{
@@ -2164,44 +2019,9 @@ static int analyze_data_AC(CPhidgetRFIDHandle phid)
phid->ACCodingOK = PFALSE;
- //printf("%d ",phid->acWritePtr);
- tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_AC;
- tag.tagInfo.bitRate = 64;
if(!decodeHitagUID(phid, acBuffer, acBufferSize, &tag, &collision))
{
- advanced_tag_event(phid, &tag, PTRUE);
- //TODO: select tag?
- //printf("Got Hitag Tag: %s\n",tag.tagString);
-
- //Any pending AC commands?
- if(phid->hitagACList)
- {
- CPhidgetRFID_HitagACHandle ac = phid->hitagACList[0].hitagAC;
- HitagS_AC_SEQUENCE(phid, ac);
- CList_removeFromList((CListHandle *)&phid->hitagACList, ac, CPhidgetRFID_HitagAC_areEqual, PTRUE, CPhidgetRFID_HitagAC_free);
- }
- }
- else if(collision != -1)
- {
- int k;
- CPhidgetRFID_HitagACHandle ac = (CPhidgetRFID_HitagACHandle)malloc(sizeof(CPhidgetRFID_HitagAC));
- ZEROMEM(ac, sizeof(CPhidgetRFID_HitagAC));
- //printf("Got Hitag Collision: %d\n",collision);
-
- for(k=0;k<collision;k++)
- {
- ac->uid[k/8] |= acBuffer[k+3] << (7-(k%8));
- }
- //choose 1 for the collision position
- ac->uid[k/8] |= 1 << (7-(k%8));
-
- ac->colPos = collision+1;
-
- HitagS_AC_SEQUENCE(phid, ac);
-
- //add AC with 0 to queue
- ac->uid[k/8] &= ~(1 << (7-(k%8)));
- CList_addToList((CListHandle *)&phid->hitagACList, ac, CPhidgetRFID_HitagAC_areEqual);
+ tagEvent(phid, &tag);
}
}
@@ -2210,18 +2030,7 @@ static int analyze_data_AC(CPhidgetRFIDHandle phid)
return EPHIDGET_OK;
}
-
-static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char *data)
-{
- CPhidgetRFID_Tag tag;
- ZEROMEM(&tag, sizeof(CPhidgetRFID_Tag));
- tag.tagInfo.bitRate = 64;
- tag.tagInfo.encoding = PHIDGET_RFID_ENCODING_MANCHESTER;
- snprintf(tag.tagString, 255, "%02x%02x%02x%02x%02x",data[0],data[1],data[2],data[3],data[4]);
- tag.tagInfo.tagType = PHIDGET_RFID_TAG_EM4102;
- return advanced_tag_event(phid, &tag, PFALSE);
-}
-
+#endif
// === Exported Functions === //
@@ -2229,8 +2038,6 @@ static int advancedTagEventForOldReaders(CPhidgetRFIDHandle phid, unsigned char
CCREATE_EXTRA(RFID, PHIDCLASS_RFID)
CThread_mutex_init(&phid->tagthreadlock);
CThread_create_event(&phid->tagAvailableEvent);
- CThread_create_event(&phid->respEvent);
- CThread_create_event(&phid->respEvent2);
phid->phid.fptrClose = CPhidgetRFID_close;
phid->phid.fptrFree = CPhidgetRFID_free;
return EPHIDGET_OK;
@@ -2238,12 +2045,17 @@ CCREATE_EXTRA(RFID, PHIDCLASS_RFID)
//event setup functions
CFHANDLE(RFID, OutputChange, int, int)
-CFHANDLE(RFID, Tag, unsigned char *)
-CFHANDLE(RFID, TagLost, unsigned char *)
+CFHANDLE(RFID, Tag2, char *tagString, CPhidgetRFID_Protocol protocol)
+CFHANDLE(RFID, TagLost2, char *tagString, CPhidgetRFID_Protocol protocol)
+#ifdef RFID_RAWDATA_API_SUPPORT
CFHANDLE(RFID, ManchesterData, unsigned char *data, int dataLength)
CFHANDLE(RFID, RawData, int *data, int dataLength)
-CFHANDLE(RFID, TagAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo)
-CFHANDLE(RFID, TagLostAdvanced, char *tagString, CPhidgetRFID_TagInfoHandle tagInfo)
+#else
+PHIDGET21_API int CCONV CPhidgetRFID_set_OnManchesterData_Handler(CPhidgetRFIDHandle phidA, int (CCONV *fptr)(CPhidgetRFIDHandle, void *userPtr, unsigned char *data, int dataLength), void *userPtr)
+{return EPHIDGET_UNSUPPORTED;}
+PHIDGET21_API int CCONV CPhidgetRFID_set_OnRawData_Handler(CPhidgetRFIDHandle phidA, int (CCONV *fptr)(CPhidgetRFIDHandle, void *userPtr, int *data, int dataLength), void *userPtr)
+{return EPHIDGET_UNSUPPORTED;}
+#endif
CGET(RFID,OutputCount,int)
TESTPTRS(phid,pVal)
@@ -2258,9 +2070,9 @@ CGETINDEX(RFID,OutputState,int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
TESTINDEX(phid.attr.rfid.numOutputs)
- TESTMASGN(outputState[Index], PUNK_BOOL)
+ TESTMASGN(outputEchoState[Index], PUNK_BOOL)
- MASGN(outputState[Index])
+ MASGN(outputEchoState[Index])
}
CSETINDEX(RFID,OutputState,int)
TESTPTR(phid)
@@ -2302,9 +2114,11 @@ CSET(RFID,AntennaOn,int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT:
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ case PHIDUID_RFID_2OUTPUT:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
TESTRANGE(PFALSE, PTRUE)
if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
@@ -2313,41 +2127,11 @@ CSET(RFID,AntennaOn,int)
{
SENDPACKET(RFID, antennaState);
//echo back state if the device doesn't
- if (!(phid->fullStateEcho))
+ if (phid->fullStateEcho == PFALSE)
phid->antennaEchoState = newVal;
}
return EPHIDGET_OK;
- case PHIDID_RFID_2OUTPUT_ADVANCED:
- if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
- ADDNETWORKKEY(AntennaOn, "%d", antennaState);
- else
- {
- unsigned char *buffer;
- int ret = 0;
- if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY;
- ZEROMEM(buffer, phid->phid.outputReportByteLength);
- CThread_mutex_lock(&phid->phid.writelock);
-
- phid->antennaState = newVal;
- if(newVal)
- {
- //phid->_4097Conf = RFID_4097_AmpDemod | RFID_4097_Active | RFID_4097_DataOut | RFID_4097_IntPLL | RFID_4097_FastStart | RFID_4097_Gain960;
- phid->_4097Conf = RFID_4097_AmpDemod | RFID_4097_Active | RFID_4097_DataOut | RFID_4097_IntPLL | RFID_4097_FastStart | RFID_4097_Gain120;
- }
- else
- {
- phid->_4097Conf = RFID_4097_PowerDown;
- }
- if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2;
- if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2;
- done2:
- CThread_mutex_unlock(&phid->phid.writelock);
- free(buffer);
- if(ret) return ret;
- }
- return EPHIDGET_OK;
- case PHIDID_RFID:
default:
return EPHIDGET_UNSUPPORTED;
}
@@ -2358,13 +2142,13 @@ CGET(RFID,LEDOn,int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT:
- case PHIDID_RFID_2OUTPUT_ADVANCED:
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ case PHIDUID_RFID_2OUTPUT:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
TESTMASGN(ledEchoState, PUNK_BOOL)
MASGN(ledEchoState)
- case PHIDID_RFID:
default:
return EPHIDGET_UNSUPPORTED;
}
@@ -2374,10 +2158,11 @@ CSET(RFID,LEDOn,int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- switch(phid->phid.deviceIDSpec)
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT:
- case PHIDID_RFID_2OUTPUT_ADVANCED:
+ case PHIDUID_RFID_2OUTPUT_NO_ECHO:
+ case PHIDUID_RFID_2OUTPUT:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
TESTRANGE(PFALSE, PTRUE)
if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
@@ -2390,7 +2175,6 @@ CSET(RFID,LEDOn,int)
phid->ledEchoState = newVal;
}
return EPHIDGET_OK;
- case PHIDID_RFID:
default:
return EPHIDGET_UNSUPPORTED;
}
@@ -2401,29 +2185,42 @@ CSET(RFID,PollingOn,int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- switch(phid->phid.deviceIDSpec)
+#ifdef RFID_HITAGS_SUPPORT
+ switch(phid->phid.deviceUID)
{
- case PHIDID_RFID_2OUTPUT_ADVANCED:
- phid->polling = newVal;
- return EPHIDGET_OK;
- case PHIDID_RFID_2OUTPUT:
- case PHIDID_RFID:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ return EPHIDGET_UNSUPPORTED; //TODO? maybe just don't enable over webservice.
+ else
+ {
+ phid->polling = newVal;
+ return EPHIDGET_OK;
+ }
default:
return EPHIDGET_UNSUPPORTED;
}
+#else
+ return EPHIDGET_UNSUPPORTED;
+#endif
}
-CGET(RFID, LastTag, unsigned char)
- TESTPTRS(phid,pVal)
+
+PHIDGET21_API int CCONV CPhidgetRFID_getLastTag2(CPhidgetRFIDHandle phid, char **tagString, CPhidgetRFID_Protocol *protocol)
+{
+ TESTPTRS(phid,tagString)
+ TESTPTR(protocol)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- //if it's all 0's - it's not yet available
- if(!memcmp("\0\0\0\0\0", phid->lastTag, 5))
- return EPHIDGET_UNKNOWNVAL;
-
- memcpy(pVal, phid->lastTag, 5);
-
- return EPHIDGET_OK;
+ CThread_mutex_lock(&phid->tagthreadlock);
+ if(phid->lastTagValid == PTRUE)
+ {
+ *tagString = phid->lastTag.tagString;
+ *protocol = phid->lastTag.protocol;
+ CThread_mutex_unlock(&phid->tagthreadlock);
+ return EPHIDGET_OK;
+ }
+ CThread_mutex_unlock(&phid->tagthreadlock);
+ return EPHIDGET_UNKNOWNVAL;
}
CGET(RFID, TagStatus, int)
@@ -2431,361 +2228,186 @@ CGET(RFID, TagStatus, int)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- if(phid->tagPresent == PUNK_BOOL && phid->tagAdvancedCount == PUNK_INT)
- {
- *pVal = PUNK_BOOL;
- return EPHIDGET_UNKNOWNVAL;
- }
+ *pVal = phid->tagPresent;
- if(phid->tagPresent == PTRUE || (phid->tagAdvancedCount > 0 && phid->tagAdvancedCount != PUNK_INT))
- *pVal = PTRUE;
- else
- *pVal = PFALSE;
+ if(*pVal == PUNK_BOOL)
+ return EPHIDGET_UNKNOWNVAL;
return EPHIDGET_OK;
}
-PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength, int pregap, int space, int postgap, int zero, int one)
+PHIDGET21_API int CCONV CPhidgetRFID_writeRaw(CPhidgetRFIDHandle phid, unsigned char *data, int bitlength,
+ int pregap, int space, int postgap, int zero, int one, int prepulse, int eof, int listenDuringEOF)
{
int retval;
TESTPTR(phid)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- if(pregap < (2) || pregap > (255)) return EPHIDGET_INVALIDARG;
- if(space < (2) || space > (255)) return EPHIDGET_INVALIDARG;
- if(postgap < (2) || postgap > (255)) return EPHIDGET_INVALIDARG;
- if(zero < (5) || zero > (255)) return EPHIDGET_INVALIDARG;
- if(one < (5) || one > (255)) return EPHIDGET_INVALIDARG;
- if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
- ;//ADDNETWORKKEYINDEXED(Acceleration, "%lE", motorAcceleration); //TODO
- else
+ switch(phid->phid.deviceUID)
{
- unsigned char *buffer;
- int ret = 0;
- if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY;
- ZEROMEM(buffer, phid->phid.outputReportByteLength);
- CThread_mutex_lock(&phid->phid.writelock);
-
- phid->pregapClocks = pregap;
- phid->postgapClocks = postgap;
- phid->spaceClocks = space;
- phid->zeroClocks = zero;
- phid->oneClocks = one;
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ //limit spaces to 64 clocks
+ if(pregap < (2) || pregap > (64)) return EPHIDGET_INVALIDARG;
+ if(space < (2) || space > (64)) return EPHIDGET_INVALIDARG;
+ if(postgap < (2) || postgap > (64)) return EPHIDGET_INVALIDARG;
+ //pulses can be up to 256 clocks
+ if(zero < (4) || zero > (128)) return EPHIDGET_INVALIDARG;
+ if(one < (4) || one > (128)) return EPHIDGET_INVALIDARG;
+ if(prepulse < (0) || prepulse > (255)) return EPHIDGET_INVALIDARG;
+ if(eof < (0) || eof > (255)) return EPHIDGET_INVALIDARG;
+ if(listenDuringEOF < (PFALSE) || listenDuringEOF > (PTRUE)) return EPHIDGET_INVALIDARG;
- //Send timing
- if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2;
- if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2;
-
- //send data
- if((retval = sendRAWData(phid, data, bitlength))) goto done2;
-
- done2:
- CThread_mutex_unlock(&phid->phid.writelock);
- free(buffer);
- if(ret) return ret;
- }
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
+ return EPHIDGET_UNSUPPORTED;//TODO
+ else
+ {
+ unsigned char *buffer;
+ int ret = 0;
+ if(!(buffer = malloc(phid->phid.outputReportByteLength))) return EPHIDGET_NOMEMORY;
+ ZEROMEM(buffer, phid->phid.outputReportByteLength);
+ CThread_mutex_lock(&phid->phid.writelock);
- return EPHIDGET_OK;
-}
+ phid->pregapClocks = pregap;
+ phid->postgapClocks = postgap;
+ phid->spaceClocks = space;
+ phid->zeroClocks = zero;
+ phid->oneClocks = one;
+ phid->prepulseClocks = prepulse;
+ phid->eofpulseClocks = eof;
+ phid->listenDuringEOF = listenDuringEOF;
-PHIDGET21_API int CCONV CPhidgetRFID_getRawData(CPhidgetRFIDHandle phid, int *data, int *dataLength)
-{
- int i;
- TESTPTR(phid)
- TESTDEVICETYPE(PHIDCLASS_RFID)
- TESTATTACHED
+ //Send timing
+ if((ret = CPhidgetRFID_makePacket(phid, buffer))) goto done2;
+ if((ret = CPhidgetRFID_sendpacket(phid, buffer))) goto done2;
- //make sure length is even so we only send out data with starting space and ending pulse
- if((*dataLength % 2) == 1)
- (*dataLength)--;
+ //send data
+ if((retval = sendRAWData(phid, data, bitlength))) goto done2;
- for(i=0;i<*dataLength;i++)
- {
- if(phid->userReadPtr == phid->dataWritePtr)
- break;
+ done2:
+ CThread_mutex_unlock(&phid->phid.writelock);
+ free(buffer);
+ if(ret) return ret;
+ }
- data[i] = phid->dataBuffer[phid->userReadPtr];
- phid->userReadPtr = (phid->userReadPtr + 1) & RFID_DATA_ARRAY_MASK;
- }
+ return EPHIDGET_OK;
- //make sure i is even so that we don't end with a pulse
- if((i % 2) == 1)
- {
- //negate the pulse if we added it
- i--;
- phid->userReadPtr = (phid->userReadPtr - 1) & RFID_DATA_ARRAY_MASK;
+ default:
+ return EPHIDGET_UNSUPPORTED;
}
-
- *dataLength = i;
-
- return EPHIDGET_OK;
}
-PHIDGET21_API int CCONV CPhidgetRFID_getTagOptions(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_TagOptionsHandle options)
+PHIDGET21_API int CCONV CPhidgetRFID_getRawData(CPhidgetRFIDHandle phid, int *data, int *dataLength)
{
- int ret = EPHIDGET_OK, wait_return = 0;
- CPhidgetRFID_TagList *trav = 0;
- CPhidgetRFID_TagHandle tag = 0;
- TESTPTRS(phid,tagString)
- TESTPTR(options)
+ TESTPTR(phid)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- //1st find it in the list - not there? can't get options.
- CThread_mutex_lock(&phid->tagthreadlock);
- for (trav=phid->tagAdvancedList; trav; trav = trav->next)
- {
- if(!strcmp(trav->tag->tagString, tagString))
- tag = trav->tag;
- }
- if(!tag)
- {
- CThread_mutex_unlock(&phid->tagthreadlock);
- return EPHIDGET_NOTFOUND;
- }
-
- //Do we need to poll for the options? yes for Hitag
- if(!tag->tagOptionsValid)
+#ifdef RFID_RAWDATA_API_SUPPORT
+ switch(phid->phid.deviceUID)
{
- switch(tag->tagInfo.tagType)
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
{
- case PHIDGET_RFID_TAG_HITAGS:
- CThread_mutex_unlock(&phid->tagthreadlock);
-
- phid->respData = tag;
- CThread_reset_event(&phid->respEvent);
- HitagS_SELECT(phid, (unsigned char *)tagString);
-
- wait_return = CThread_wait_on_event(&phid->respEvent, 500);
- switch (wait_return) {
- case WAIT_TIMEOUT:
- ret = EPHIDGET_TIMEOUT;
- break;
- case WAIT_OBJECT_0:
- ret = phid->respStatus;
- break;
- default:
- ret = EPHIDGET_UNEXPECTED;
- break;
- }
-
- CThread_reset_event(&phid->respEvent);
-
- CThread_mutex_lock(&phid->tagthreadlock);
- break;
- case PHIDGET_RFID_TAG_ISO11784:
- break;
- case PHIDGET_RFID_TAG_EM4102:
- break;
- default:
- CThread_mutex_unlock(&phid->tagthreadlock);
- return EPHIDGET_UNEXPECTED;
- }
- }
- //copy over options
- memcpy(options, &tag->tagOptions, sizeof(CPhidgetRFID_TagOptions));
-
- CThread_mutex_unlock(&phid->tagthreadlock);
- return ret;
-}
-
-PHIDGET21_API int CCONV CPhidgetRFID_read(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int *dataLength, char *password)
-{
- int ret = EPHIDGET_OK, wait_return = 0, i;
- CPhidgetRFID_TagList *trav = 0;
- CPhidgetRFID_TagHandle tag = 0;
- CPhidgetRFID_TagOptions options;
- TESTPTRS(phid,tagString)
- TESTPTR(data)
- TESTDEVICETYPE(PHIDCLASS_RFID)
- TESTATTACHED
-
- //1st find it in the list - not there? can't get options.
- CThread_mutex_lock(&phid->tagthreadlock);
- for (trav=phid->tagAdvancedList; trav; trav = trav->next)
- {
- if(!strcmp(trav->tag->tagString, tagString))
- tag = trav->tag;
- }
- if(!tag)
- {
- CThread_mutex_unlock(&phid->tagthreadlock);
- return EPHIDGET_NOTFOUND;
- }
+ int i;
+ //make sure length is even so we only send out data with starting space and ending pulse
+ if((*dataLength % 2) == 1)
+ (*dataLength)--;
- switch(tag->tagInfo.tagType)
- {
- case PHIDGET_RFID_TAG_HITAGS:
- if(tag->tagOptions.memSize == 32)
+ for(i=0;i<*dataLength;i++)
{
- ret = EPHIDGET_UNSUPPORTED;
- break;
- }
- //Do we need to select the tag first?
- if(!tag->tagOptionsValid)
- {
- CThread_mutex_unlock(&phid->tagthreadlock);
- if((ret = CPhidgetRFID_getTagOptions(phid, tagString, &options)))
- return ret;
- CThread_mutex_lock(&phid->tagthreadlock);
+ if(phid->userReadPtr == phid->dataWritePtr)
+ break;
+
+ data[i] = phid->dataBuffer[phid->userReadPtr];
+ phid->userReadPtr = (phid->userReadPtr + 1) & RFID_DATA_ARRAY_MASK;
}
- //Now do the reads
- if(!tag->tagDataValid)
+ //make sure i is even so that we don't end with a pulse
+ if((i % 2) == 1)
{
- CThread_mutex_unlock(&phid->tagthreadlock);
- phid->respData = tag;
- CThread_reset_event(&phid->respEvent);
- //reading blocks - 4 pages/block, 32 bits/page
- for(i=0;i<tag->tagOptions.memSize/32;i+=4)
- {
- HitagS_READ(phid, i, PTRUE);
-
- wait_return = CThread_wait_on_event(&phid->respEvent, 1000);
- switch (wait_return) {
- case WAIT_TIMEOUT:
- return EPHIDGET_TIMEOUT;
- case WAIT_OBJECT_0:
- if((ret = phid->respStatus))
- return ret;
- break;
- default:
- return EPHIDGET_UNEXPECTED;
- }
+ //negate the pulse if we added it
+ i--;
+ phid->userReadPtr = (phid->userReadPtr - 1) & RFID_DATA_ARRAY_MASK;
+ }
- CThread_reset_event(&phid->respEvent);
- }
+ *dataLength = i;
- CThread_mutex_lock(&phid->tagthreadlock);
- }
- //copy over data - ignore 1st 8 bytes, it's UID and configuration
- //TODO: if Authentication is turned on, we lose even more space
- if(*dataLength > tag->tagOptions.memSize/8 - 8)
- *dataLength = tag->tagOptions.memSize/8 - 8;
- memcpy(data, tag->tagData + 8, *dataLength);
+ return EPHIDGET_OK;
+ }
- break;
- case PHIDGET_RFID_TAG_ISO11784:
- ret = EPHIDGET_UNSUPPORTED;
- break;
- case PHIDGET_RFID_TAG_EM4102:
- ret = EPHIDGET_UNSUPPORTED;
- break;
default:
- ret = EPHIDGET_UNEXPECTED;
- break;
+ return EPHIDGET_UNSUPPORTED;
}
-
- CThread_mutex_unlock(&phid->tagthreadlock);
- return ret;
+#else
+ return EPHIDGET_UNSUPPORTED;
+#endif
}
-PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, unsigned char *data, int dataLength, int offset, char *password)
+PHIDGET21_API int CCONV CPhidgetRFID_write(CPhidgetRFIDHandle phid, char *tagString, CPhidgetRFID_Protocol protocol, int lock)
{
- int ret = EPHIDGET_OK, wait_return = 0, i, writePage, writeSize;
- CPhidgetRFID_TagList *trav = 0;
- CPhidgetRFID_TagHandle tag = 0;
- CPhidgetRFID_TagOptions options;
- unsigned char readData[256];
- int readDataSize = 256;
- TESTPTRS(phid,tagString)
- TESTPTR(data)
+ int ret = EPHIDGET_OK;
+ char newVal[50];
+ TESTPTRS(phid,tagString)
TESTDEVICETYPE(PHIDCLASS_RFID)
TESTATTACHED
- //1st find it in the list - not there? can't get options.
- CThread_mutex_lock(&phid->tagthreadlock);
- for (trav=phid->tagAdvancedList; trav; trav = trav->next)
- {
- if(!strcmp(trav->tag->tagString, tagString))
- tag = trav->tag;
- }
- if(!tag)
- {
- CThread_mutex_unlock(&phid->tagthreadlock);
- return EPHIDGET_NOTFOUND;
- }
-
- switch(tag->tagInfo.tagType)
+ switch(phid->phid.deviceUID)
{
- case PHIDGET_RFID_TAG_HITAGS:
+ case PHIDUID_RFID_2OUTPUT_READ_WRITE:
+ if(protocol < (PHIDGET_RFID_PROTOCOL_EM4100) || protocol > (PHIDGET_RFID_PROTOCOL_PHIDGETS))
+ return EPHIDGET_INVALIDARG;
+ if(lock < (PFALSE) || lock > (PTRUE))
+ return EPHIDGET_INVALIDARG;
- if(tag->tagOptions.memSize == 32)
+ if(CPhidget_statusFlagIsSet(phid->phid.status, PHIDGET_REMOTE_FLAG))
{
- ret = EPHIDGET_UNSUPPORTED;
- break;
+ sprintf(newVal, "%d/%d/%s", protocol, lock, tagString);
+ ADDNETWORKKEY(WriteTag, "%s", remoteWrite);
}
- //Do we need to select the tag first?
- if(!tag->tagOptionsValid)
+ else
{
+ CThread_mutex_lock(&phid->tagthreadlock);
+ ret = T5577_WriteTag(phid, protocol, tagString, lock);
CThread_mutex_unlock(&phid->tagthreadlock);
- if((ret = CPhidgetRFID_getTagOptions(phid, tagString, &options)))
+ if(ret != EPHIDGET_OK)
return ret;
- CThread_mutex_lock(&phid->tagthreadlock);
- }
-
- if(offset+dataLength > (tag->tagOptions.memSize/8)-8)
- return EPHIDGET_INVALIDARG;
-
- //Need to read in the tag first
- CThread_mutex_unlock(&phid->tagthreadlock);
- if((ret = CPhidgetRFID_read(phid, tagString, readData, &readDataSize, password)))
- return ret;
- CThread_mutex_lock(&phid->tagthreadlock);
-
- //Now do the writes
- CThread_mutex_unlock(&phid->tagthreadlock);
- phid->respData = tag;
- CThread_reset_event(&phid->respEvent);
-
- //need to start the write on a page border
- //these are in pages (4 bytes)
- writePage = offset/4;
- writeSize = dataLength/4 + (dataLength%4 ? 1 : 0) + offset%4;
-
- //replace what the user wants to write
- memcpy(readData+offset, data, dataLength);
-
- for(i=writePage;i<writePage+writeSize;i+=(i%4 ? i%4 : 4))
- {
- HitagS_WRITE(phid, i, readData+i, PTRUE);
-
- wait_return = CThread_wait_on_event(&phid->respEvent, 500);
- switch (wait_return) {
- case WAIT_TIMEOUT:
- return EPHIDGET_TIMEOUT;
- case WAIT_OBJECT_0:
- if((ret = phid->respStatus))
- return ret;
- break;
- default:
- return EPHIDGET_UNEXPECTED;
- }
-
- CThread_reset_event(&phid->respEvent);
+ return waitForTag(phid, tagString, 500);
}
- CThread_mutex_lock(&phid->tagthreadlock);
-
- break;
- case PHIDGET_RFID_TAG_ISO11784:
- ret = EPHIDGET_UNSUPPORTED;
- break;
- case PHIDGET_RFID_TAG_EM4102:
- ret = EPHIDGET_UNSUPPORTED;
break;
+
default:
- ret = EPHIDGET_UNEXPECTED;
- break;
+ return EPHIDGET_UNSUPPORTED;
}
- CThread_mutex_unlock(&phid->tagthreadlock);
- return ret;
+ return EPHIDGET_OK;
}
// === Deprecated Functions === //
+CFHANDLE(RFID, Tag, unsigned char *)
+CFHANDLE(RFID, TagLost, unsigned char *)
CGET(RFID,NumOutputs,int)
return CPhidgetRFID_getOutputCount(phid, pVal);
}
+CGET(RFID, LastTag, unsigned char)
+ int ret = EPHIDGET_OK;
+ TESTPTRS(phid,pVal)
+ TESTDEVICETYPE(PHIDCLASS_RFID)
+ TESTATTACHED
+
+ //This function only work if the last tag was EM4100
+ CThread_mutex_lock(&phid->tagthreadlock);
+ if(phid->lastTagValid)
+ {
+ if(phid->lastTag.protocol == PHIDGET_RFID_PROTOCOL_EM4100)
+ memcpy(pVal, phid->lastTag.tagData, 5);
+ else
+ ret = EPHIDGET_UNSUPPORTED; //unsupported for the protocol of the last tag
+ }
+ else
+ ret = EPHIDGET_UNKNOWNVAL;
+ CThread_mutex_unlock(&phid->tagthreadlock);
+
+ return ret;
+}