CRO_Tomislav 0 Posted March 20, 2019 Dear all. I have a small experminet of reading of RFID tags information's using a RFID reader and attached .dll. Function is: Function Inventory(var ComAdr : byte; var State : byte; var AFI : byte; DSFIDAndUID : pchar; var CardNum : byte; frmComPortindex : integer): LongInt; stdcall; external 'RR3036.dll'; I can call successfully function which is reading some data from RFID tags in a range ( I get positive result of this function and number of tag’s): Get_UID_RFID_Tag_Data_Status:=Inventory(fComAdr, State, AFI, DSFIDAndUID, CardNum,frmcomportindex); With this function I read set of data called DSFIDAndUID which are declared: var DSFIDAndUID: array[0..8000] of Char; In a reader manual description of: DSFIDAndUID is --> Output. Pointed to array storing the function result. The unit of the array is 9 bytes including a 1 byte DSFID and 8 bytes of UID. The volume of the results is CardNum*9 bytes with least significant byte first for UID. CardNum is --> Output. Point to a number of tags detected. The maximum number of tags one time collected is 16 Problem is in DSFIDAndUID – I do not understand how to decode data from that array to get ASCII values of DSFID and UID. With my function’s I all way's get a wrong data and I do not have any more idea… I am reading only one RFID tag at a time… Thx in advance Tomislav Share this post Link to post
ertank 27 Posted March 21, 2019 (edited) Hello, Are you building for Windows? If yes, most of the readers today are PCSC capable. If that is the case with your reader, you are better using APDU commands to communicate with reader and cards. Check out http://www.infintuary.org/stpcsc.php Edited March 21, 2019 by ertank Share this post Link to post
PeterBelow 238 Posted March 21, 2019 13 hours ago, CRO_Tomislav said: Dear all. I have a small experminet of reading of RFID tags information's using a RFID reader and attached .dll. Function is: Function Inventory(var ComAdr : byte; var State : byte; var AFI : byte; DSFIDAndUID : pchar; var CardNum : byte; frmComPortindex : integer): LongInt; stdcall; external 'RR3036.dll'; I can call successfully function which is reading some data from RFID tags in a range ( I get positive result of this function and number of tag’s): Get_UID_RFID_Tag_Data_Status:=Inventory(fComAdr, State, AFI, DSFIDAndUID, CardNum,frmcomportindex); With this function I read set of data called DSFIDAndUID which are declared: var DSFIDAndUID: array[0..8000] of Char; In a reader manual description of: DSFIDAndUID is --> Output. Pointed to array storing the function result. The unit of the array is 9 bytes including a 1 byte DSFID and 8 bytes of UID. The volume of the results is CardNum*9 bytes with least significant byte first for UID. CardNum is --> Output. Point to a number of tags detected. The maximum number of tags one time collected is 16 Problem is in DSFIDAndUID – I do not understand how to decode data from that array to get ASCII values of DSFID and UID. With my function’s I all way's get a wrong data and I do not have any more idea… I am reading only one RFID tag at a time… Thx in advance Tomislav From your description the data you get back are not characters, so do not use an array of char, use an array of byte. In fact you should be able to use something like this: type TTagResult = packed record DFSID: byte; case boolean of false: (UIDasBytes: array [0..7] of byte); true: (UID: Uint64); end; TagBuffer = packed array [0..15] of TTagResult; type the DSFIDAndUID parameter of the Inventory function as var DSFIDAndUID : TTagBuffer and you should be able to just pass a variable of type TTagBuffer and get the result back in a digested format. 1 Share this post Link to post
Remy Lebeau 1393 Posted March 21, 2019 (edited) 18 hours ago, CRO_Tomislav said: Function is: Function Inventory(var ComAdr : byte; var State : byte; var AFI : byte; DSFIDAndUID : pchar; var CardNum : byte; frmComPortindex : integer): LongInt; stdcall; external 'RR3036.dll'; Remember that PChar is PWideChar in Delphi 2009+, but the DSFIDAndUID data is returning an array of bytes, not characters, so the function should be declared as using PByte, not PChar, for that parameter: Function Inventory(var ComAdr : Byte; var State : Byte; var AFI : Byte; DSFIDAndUID : PByte; var CardNum : Byte; frmComPortindex : Integer): LongInt; stdcall; external 'RR3036.dll'; 5 hours ago, PeterBelow said: From your description the data you get back are not characters, so do not use an array of char, use an array of byte. In fact you should be able to use something like this: I would recommend this approach as well. However, do note that the function declaration would have to be changed to accommodate this, eg: Function Inventory(var ComAdr : Byte; var State : Byte; var AFI : Byte; var DSFIDAndUID : TTagBuffer; var CardNum : Byte; frmComPortindex : Integer): LongInt; stdcall; external 'RR3036.dll'; Otherwise, you would have to type-cast the DSFIDAndUID variable when passing it: var DSFIDAndUID : TTagBuffer; Get_UID_RFID_Tag_Data_Status := Inventory(fComAdr, State, AFI, PChar(@DSFIDAndUID), CardNum, frmcomportindex); Edited March 21, 2019 by Remy Lebeau 1 Share this post Link to post
CRO_Tomislav 0 Posted March 27, 2019 Hello. First of all, my apology for late replay. I was a few days out of office with a very limited access to internet (mountains)... I go with a suggested approach and „only unknown” part is: how do I get DSFID and UID values form DSFIDAndUID : TTagBuffer; ? With best regards Tom Share this post Link to post
Remy Lebeau 1393 Posted March 27, 2019 (edited) 1 hour ago, CRO_Tomislav said: I go with a suggested approach and „only unknown” part is: how do I get DSFID and UID values form DSFIDAndUID : TTagBuffer; ? Like this: var DSFIDAndUID : TTagBuffer; CardNum: Byte; ... DFSID: Byte; UID: Uint64; i: Integer; begin ... // populate DSFIDAndUID and CardNum as needed, then ... for i := 0 to CardNum-1 do begin DFSID := DSFIDAndUID[i].DFSID; UID := DSFIDAndUID[i].UID; // use DFSID and UID as needed... end; ... end; Edited March 27, 2019 by Remy Lebeau Share this post Link to post
CRO_Tomislav 0 Posted March 28, 2019 (edited) Hello. It's working, but it seams that I get a UID value in reversed order... For "fast test" I use IntToHEX(DSFID,2) + ' - ' + IntToHEX(UID,2); result is reversed by two HEXs: Example: I get as result. E004020056486E86 It should be: 866E4856000204E00 Manage to solve this... Thx again Tom Edited March 28, 2019 by CRO_Tomislav Progress Share this post Link to post
CRO_Tomislav 0 Posted March 28, 2019 23 hours ago, Remy Lebeau said: var DSFIDAndUID : TTagBuffer; CardNum: Byte; ... DFSID: Byte; UID: Uint64; i: Integer; begin ... // populate DSFIDAndUID and CardNum as needed, then ... for i := 0 to CardNum-1 do Hmm... From a code above: I get UID in Uint64 and this is OK for a rest of my code but: I need to pass this UID to a function as a byte (8 bytes) or Pchar but I get function error It seams that I am making some mistake in conversions. Is there some function or similar for make this conversion correctly? Tom Share this post Link to post
Remy Lebeau 1393 Posted March 28, 2019 6 hours ago, CRO_Tomislav said: It's working, but it seams that I get a UID value in reversed order... For "fast test" I use IntToHEX(DSFID,2) + ' - ' + IntToHEX(UID,2); result is reversed by two HEXs: Example: I get as result. E004020056486E86 It should be: 866E4856000204E00 Manage to solve this... Little Endian vs Big Endian. Simply swap the bytes around. 42 minutes ago, CRO_Tomislav said: I need to pass this UID to a function as a byte (8 bytes) or Pchar but I get function error It seams that I am making some mistake in conversions. Is there some function or similar for make this conversion correctly? You don't need to convert anything. TTagResult has a UIDasBytes field to access the raw 8 bytes of the UID. Simply pass that field as-is to the function that wants the bytes. 1 Share this post Link to post
CRO_Tomislav 0 Posted March 30, 2019 Hello. Still doesn't solved... It's killing me... I have a function form .dll (from manual): Function GetSystemInformation(var ComAdr : byte; var State : byte; UIDI : PChar; var InformationFlag : byte; UIDO : pchar; var DSFID : byte; var AFI : byte; MemorySize : pchar; var ICReference : Byte; var ErrorCode : byte; frmComPortindex : integer): LongInt; stdcall;external 'RR3036.dll'; Description of UIDI: Input, Pointed to 8 bytes of tag's UID value with least segnificant byte first I change in function UIDI: Byte So I need to call the function with: Get_Designated_tag_info_status:= GetSystemInformation(fComAdr, State, DSFIDAndUID[0].UIDasBytes, InformationFlag, UIDO, DSFID, AFI, MemorySize, ICReference, errorCode,frmcomportindex); This is obviously that this will not work because DSFIDAndUID[0].UIDasBytes is array of bytes (0..7), but what ever I try it doesn’t work... Share this post Link to post
Remy Lebeau 1393 Posted March 31, 2019 (edited) Get_Designated_tag_info_status := GetSystemInformation(fComAdr, State, PChar(@DSFIDAndUID[0].UIDasBytes), InformationFlag, UIDO, DSFID, AFI, MemorySize, ICReference, errorCode, frmcomportindex); You need to type cast the array when passing it as a PChar. Edited March 31, 2019 by Remy Lebeau Share this post Link to post
CRO_Tomislav 0 Posted April 2, 2019 Hi. Thx for answers... I still get this error so the problem is not in conversion... You help me a lot. Big THX once more Best regards Tom Share this post Link to post
Remy Lebeau 1393 Posted April 2, 2019 (edited) 9 hours ago, CRO_Tomislav said: I still get this error so the problem is not in conversion... Sorry, I missed the part where you had changed the function declaration to make the UIDI parameter be a single Byte, which is of course wrong. I thought you were still passing that parameter by PChar instead. So, you need to EITHER do this: Function GetSystemInformation(...; UIDI : PByte; ...): LongInt; stdcall;external 'RR3036.dll'; ... Get_Designated_tag_info_status := GetSystemInformation(..., PByte(@(DSFIDAndUID[0].UIDasBytes)), ...); alternatively Get_Designated_tag_info_status := GetSystemInformation(..., @(DSFIDAndUID[0].UIDasBytes[0]), ...); Or this: Function GetSystemInformation(...; var UIDI : Byte; ...): LongInt; stdcall;external 'RR3036.dll'; ... Get_Designated_tag_info_status := GetSystemInformation(..., DSFIDAndUID[0].UIDasBytes[0], ...); Edited April 3, 2019 by Remy Lebeau Share this post Link to post
Attila Kovacs 629 Posted April 2, 2019 On 3/30/2019 at 11:04 AM, CRO_Tomislav said: I change in function UIDI: Byte Don't do that. Share this post Link to post