PORTS Forum
Ports and Interfaces => Serial Ports => Topic started by: hiramlight on April 05, 2011, 06:18:25 am
-
Hello,
I developed an Hotel Room management system (VB>NET). Up to now I was using dllImports to integrate electronic key door system , but this time I would like to connect directly to encoder interface.
the encoder use a USB to UART driver ( I get the latest drivers from sil lab ) and it work good ( OS
is win 7) , Also this is my first time working on serialCom .
I build a test application to connect to the com port but I am not sure that I am even connecting to the encoder.
I use the Advanced serial Monitor port to comapre , what my test RS 232 code is sending (TX) and what my other test app ( using the manufacture dll through dllImport) is sending .
The dllImport test app is adding some charaters in the string who just dont make sens to me .
the doc coming with the encoder aspecify this data structure:
Data Format
Data format: 1 start bit, 1 end bit, 8 data bits, no verification; The communication rate is from 2400bps to 19200bps.
Control Character
STX (0x02): Tag the beginning of the data.
ETX (0x03): Tag the end of the data.
Information Format
Information format: <STX>ddssff[data]<ETX>cc
When the receiving end gets the information complying with the above format, it will respond with “ACK” if the calculated verification is same as the received verification. Otherwise, it will respond with “NAK”.
Information Field Description
dd Destination address, target (client) address
ss Source address which tags the information source
ff Command or answer code
[data] Data region (optional)
Check character: 2-byte;
Algorithm: Use 0x00 as the seed to do XOR with all the data after STX. The result of each XOR will be used as the new seed for the next XOR. The final 1-byte result will be transformed into a 2-byte hexadecimal ASCII code.
Example:
STX 0x30 0x39 0x52 ETX C1 C2
First calculation: 0x00 XOR 0x30 = 0x30
Second calculation: 0x30 XOR 0x39 = 0x09
Third calculation: 0x09 XOR 0x52 = 0x5B
Forth calculation: 0x5B XOR 0x03 = 0x58
Verification code of the first byte (C1): 0x5 ->ASCII 5 = 0x35
Verification code of the second byte (C2): 0x8 ->ASCII 8 = 0x38
and my test is : <STX>0103E<ETX>CC
//////
Card Verification/Guest Card Reading Command
Command code: (E).
This command is used to read the information in guest card and search the card’s information in the database. If the search is successful, relative information (R, N, D and O) will be fed back. Example as follows:
PMS: <STX>0103E<ETX>CC
AIS: <ACK>
AIS: <STX>03010<RS>R101<RS>NDuck<RS>D200212201200<RS>O200212302100<ETX>CC
PMS: <ACK>
/////////////
this is what the serial port monitore show:
<20110405141219.100 SYS>
COM port is opened
<20110405141219.100 SYS>
Purge the serial port: RXCLEAR, TXCLEAR
<20110405141219.100 SYS>
Baud rate 9600
<20110405141219.100 SYS>
RTS off
<20110405141219.100 SYS>
DTR off
<20110405141219.100 SYS>
Data bits=8, Stop bits=1, Parity=None
<20110405141219.100 SYS>
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
<20110405141219.100 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=2048, XoffLimit=512
<20110405141219.100 SYS>
In/out queue size 512/512
<20110405141219.100 SYS>
Set timeouts: ReadInterval=100, ReadTotalTimeoutMultiplier=2000, ReadTotalTimeoutConstant=2000, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20110405141219.100 SYS>
Purge the serial port: RXCLEAR, TXCLEAR
<20110405141219.100 TX>
<STX>103E<ETX>74
<20110405141231.163 SYS>
COM port is closed
and this is the dllimport test show , sending the same query:
IOCTL_SERIAL_SET_DTR: Set DTR
000031: I/O Request (UP), 29.03.2011 16:47:51.075 +0.0
IOCTL_SERIAL_SET_DTR: Set DTR
000032: I/O Request (DOWN), 29.03.2011 16:47:51.075 +0.0
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
WordLength=8
StopBits=1 stop bit
Parity=No parity
000033: I/O Request (UP), 29.03.2011 16:47:51.090 +0.015
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
000034: I/O Request (DOWN), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_CHARS: Set special characters
EofChar=0x0
ErrorChar=0x0
BreakChar=0x0
EventChar=0x0
XonChar=0x11
XoffChar=0x13
000035: I/O Request (UP), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_CHARS: Set special characters
000036: I/O Request (DOWN), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
ControlHandShake=1
FlowReplace=0
XonLimit=28672
XoffLimit=7168
000037: I/O Request (UP), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
000040: I/O Request (DOWN), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
ReadIntervalTimeout=4294967295 >>> when I try to put this value I get an error in my 232 class
ReadTotalTimeoutMultiplier=0
ReadTotalTimeoutConstant=0
WriteTotalTimeoutMultiplier=0
WriteTotalTimeoutConstant=5000
000041: I/O Request (UP), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
000042: I/O Request (DOWN), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_PURGE: Purge requests
Purge mask=TXABORT: Read requests, RXABORT: Receive buffer, TXCLEAR: Write requests, RXCLEAR: Write buffer
000043: I/O Request (UP), 29.03.2011 16:47:51.090 +0.0
IOCTL_SERIAL_PURGE: Purge requests
000044: Write Request (DOWN), 29.03.2011 16:47:51.090 +0.0
Buffer size: 0x16 bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 7E ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~
FF 00 DF 0B 17 7E ÿ.ß..~
000049: Read Request (UP), 29.03.2011 16:47:51.121 +0.0
Buffer size: 0x1 bytes
Status: 0x00000000
7E ~
000053: Read Request (UP), 29.03.2011 16:47:51.121 +0.0
Buffer size: 0x1 bytes
Status: 0x00000000
00 .
000057: Read Request (UP), 29.03.2011 16:47:51.121 +0.0
Buffer size: 0x1 bytes
Status: 0x00000000
00 .
etc.....
There is many additional characteres who dont make sens to me the why all the ""FF"" and also the translation show 7E ÿ.ß..~... what does that mean ...? when my rs232 code show this as hex value:
WriteTotalTimeoutConstant=100 103E74COM port is close
when compare with a serial monitor
( using dllimport and the encodoer dll)
00000129 24.03.2011 19:52:25.419 +0.0 IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_TIMEOUTS UP 0x00000000
00000130 24.03.2011 19:52:25.419 +0.0 IRP_MJ_WRITE DOWN 0x00000000 7e ff 03 80 31 85 02 00 63 5b e0 7e ~...1...c[.~
(using my ES232 test app)
00000049 24.03.2011 20:20:36.259 +0.006 IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE UP 0x00000000
00000050 24.03.2011 20:20:48.354 +12.094 IRP_MJ_WRITE DOWN 0x00000000 3c 45 54 58 3e 31 3c 45 4e 51 3e 3c 4e 55 4c 3e <ETX>1<ENQ><NUL>
with the mfct dll the bytes translate to those funny characters ""~...1...c[.~"" when I run the same command in my test app the bytes show in char that we can read ""<ETX>1<ENQ><NUL>"" so am I doing something wrong in the convert function
this is my first posting on this board so I hope that I didn't exceed the lenght and I will be happy to attached any piece of code or doc that I have and who are needed to resolve this .
Sincerely,
alan
-
Let me see if I understand.
In both cases, the RF encoder connects to a PC via a SiLabs USB/serial-port adapter?
The original system used a DLL and its API to access the encoder, and now you want to do so directly by reading and writing to the USB virtual serial port?
So you're trying to reverse engineer the protocols by monitoring the traffic?
"dllimport test" is a test application provided by the vendor?
The "serial port monitor" data shows the traffic when you run "dllimport test"?
The port is closed after the purge request?
Jan
-
Hello Jan ,
I am not trying to reverse engineering anything, encoder come usually with their own software ... limited in scope and sometime not so stable like orbita for exemple ... their software are memory leak and after a while just lock the system .
In The application that I built , rooms and floors are in graphical display, ledger and accounting areinclude as well as a trnsparent online booking system , but since hotels are using different key card encoder system ( like orbita, mifare 2 of the most used ) I was using the their api ( C++ build dll) . RMS being a .net app using dllimport was by the only way I could integret their API .
I got a document from Mifare showing the dta structutre if i wanted to use rs232 to directly talk to the encoder , I tought that if I could do that it would be more stable and since most encoder use the same format and only data that you are passing is different it would make for a better more stable app. also I could then work with any encoder ... with some company it is very difficult to get doc or API.
I attached the rs 232 doc and the Api from Orbita .
I monitore the traffic from my test app using dllImport because I build the test app ( using rs232 call) by following the doc from Mifare and dont get the result that I expect it .. so like I put in my first post .. I try to understand what did I do wrong .
====================
In both cases, the RF encoder connects to a PC via a SiLabs USB/serial-port adapter? > Correct
The original system used a DLL and its API to access the encoder, and now you want to do so directly by reading and writing to the USB virtual serial port? > correct
So you're trying to reverse engineer the protocols by monitoring the traffic? > not to sure what you meant by reverse eng .. but no I followed the doc that I got from the encoder cpy ( attached to this post)
"dllimport test" is a test application provided by the vendor? > nope I build it ib VB.NET using the dll and doc provider by vendor
for ex:
3. Read Card Number, if success, return 0
int (*GetCardNumber)(int ComNumber,int* CardNumber) ;
Explain:
ComNumber, the comport to connect the encoder.
CardNumber, Card number will be return from the parameter “CardNumber”.
become in my test app:
<DllImport("akey/HUNERF.DLL", EntryPoint:="GetCardNumber")> _
Public Shared Function GetCardNumber(ByVal comport As Integer, ByRef CardNumber As IntPtr) As IntPtr
End Function
The "serial port monitor" data shows the traffic when you run "dllimport test"? >> it show both , the first sample show traffic from my test app using the RS 232 test app and end:
<20110405141219.100 TX>
<STX>103E<ETX>74
<20110405141231.163 SYS>
COM port is closed
the second when using the second test app and dll import :
000044: Write Request (DOWN), 29.03.2011 16:47:51.090 +0.0
Buffer size: 0x16 bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 7E ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~
FF 00 DF 0B 17 7E ÿ.ß..~
and like I put in my post what really baffle me is the difference :
what those meant ...?? ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~
FF 00 DF 0B 17 7E ÿ.ß..~
I known thos are the byte values FF 00 DF 0B 17 7E, but this ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~ or ÿ.ß..~ , when following the rs232 doc my string look like this: 100 103E74COM
I got 2 encoder I can trest with a Mifare and an Orbita and got the same problem with both .. I can send you some traffic from the orbit a next if you like ... but look preety much the same .
I though that the function that I build to go from ASCII char to byte and XOR the dta was correct ...but maybe not
wha
Alan
[attachment deleted by admin]
-
In your Write Request, it looks like you're sending 16 bytes: 15 FFh followed by one 7Eh. Assuming that's not what you intended to send, I would start by looking at how you declare and store data in the buffer.
Jan
-
Hello Jan ,
I use an RS 232 class from a sample app that I found on the internet ( please find attached)
then I call a funcion to convert the ASCII command to byte :
I declare CMD as global variable forthe test
and idxsent as in integer
/*
Target : Points to a byte Array big enough to hold the command
CMD : Points to a character Array with the command NULL terminated
Return : length of the Target Command to send to the remote Device
*/
I wanted CMD to "point" to a string ie : Dim enComd As String = "0103E"
Note: My call is expecting a pointer to the string, not the actual string.
In the case of the CMD, this could just be the string as its not changed.
In the case of Target it needs to point to the target as it gets updated.
Dim comhold As New rs232 'class that handles the com port connections
Dim hexconv As hexconv = New hexconv ' class that handle convertion to bytes and XON
Dim myTestByte(X) As Byte
CMD = "103E"
idxsent = hexconv.FormatCommand_MifareByte(myTestByte, Encoder)
===============================
Public Function FormatCommand_Mifare(ByVal Target() As Byte, ByVal ENC As Integer) As Integer
' Encoder= 2
'Mifare string
'common char & byte
Dim STX As Byte = &H2
Dim ECT As Byte = &H3
Dim ENQ As Byte = &H5
Dim ACK As Byte = &H6
Dim NAK As Byte = &H15
Dim RS As Byte = &H1E
Dim Idx As Integer = 0
Dim [Loop] As Integer
Dim CC As New Byte()
' Move STX into array
Target(Idx) = STX
Idx += 1
' Move "user" command into array
For [Loop] = 0 To CMD.Length - 1
Target(Idx) = CByte(AscW(CMD([Loop])))
Idx += 1
Next [Loop]
' Move ECT into array
Target(Idx) = ECT
Idx += 1
' Calc CC : XOR all bytes (seed with 0) execpt the first byte
CC = 0
[Loop] = 1
Do While [Loop] < Idx
CC = CC Xor Target([Loop])
[Loop] += 1
Loop
' Get CC high nibble and convert to hex/ascii
If (CC >> 4) > 9 Then
Target(Idx) = CByte(AscW("A"c) + (CC >> 4))
Idx += 1
Else
Target(Idx) = CByte(AscW("0"c) + (CC >> 4))
Idx += 1
End If
' Get CC low nibble and convert to hex/ascii
If (CC And &HF) > 9 Then
Target(Idx) = CByte(AscW("A"c) + (CC And &HF))
Idx += 1
Else
Target(Idx) = CByte(AscW("0"c) + (CC And &HF))
Idx += 1
End If
Return Idx
End Function
==================================
then call the write command
comhold.Write(myTestByte)
txtRX.Text = comhold.Read(idxsent).ToString
////
but to come back to your question , this example :
000044: Write Request (DOWN), 29.03.2011 16:47:51.090 +0.0
Buffer size: 0x16 bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 7E ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ~
FF 00 DF 0B 17 7E ÿ.ß..~
000049: Read Request (UP), 29.03.2011 16:47:51.121 +0.0
Buffer size: 0x1 bytes
Status: 0x00000000
7E
is coming from the test app using dllimport and it is working well, this what I would like to achive using my RS232 class test app
Read Request (UP) meant we are reading a reply from the encoder, since we have a total of 6 request read.. correct ..?I didn't put them all for the sake of lenght ..
here I send a different string <ETX>1<ENQ><NUL> instead <STX>0103E<ETX> but it doesn't really matter what string that I send the formatting seem off.
From the DLL Import test
/////////
00000033 24.03.2011 19:52:19.471 +0.0 IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_TIMEOUTS UP 0x00000000
00000034 24.03.2011 19:52:19.471 +0.0 IRP_MJ_WRITE DOWN 0x00000000 7e ff 03 80 31 05 00 67 32 7e ~...1..g2~
00000037 24.03.2011 19:52:19.605 +0.133 IRP_MJ_READ UP 0x00000000 7e ~
00000039 24.03.2011 19:52:19.606 +0.001 IRP_MJ_READ UP 0x00000000 ff .
00000041 24.03.2011 19:52:19.607 +0.001 IRP_MJ_READ UP 0x00000000 03 .
00000043 24.03.2011 19:52:19.608 +0.001 IRP_MJ_READ UP 0x00000000 80
/////////////////////////////
from the rs232 class test app
/////////
00000048 24.03.2011 20:20:36.253 +57.433 IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE DOWN 0x00000000 0c 00 00 00 ....
00000049 24.03.2011 20:20:36.259 +0.006 IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE UP 0x00000000
00000050 24.03.2011 20:20:48.354 +12.094 IRP_MJ_WRITE DOWN 0x00000000 3c 45 54 58 3e 31 3c 45 4e 51 3e 3c 4e 55 4c 3e <ETX>1<ENQ><NUL>
then the port closed no IRP_MJ_READ UP so no reply from the encoder.
////////
Also I come accross "Any Serial Port". Did you ever use that application ..? can it be an option for me to look at ...?
Thank's for taking the time to help...
Alan
[attachment deleted by admin]
-
If you have working code in your dllimport example, why are you trying to do it in a different way? It's possible you've explained this already, but please refresh my memory.
Jan
-
Hello Jan,
I am working with 2 encoder an orbita and a Mifare, I only got the dll instruction for Orbita ( with the dll) so I was able to build a com module using dllImport... No such luck with the Mifare and I look around to other cpy who sale the same encoder type , but most are chinese and i didn't get any reply ... I think just interested in selling harware and in any cases the 2 cpy that I find selling the same type of encoder didn't even bother to reply to my emails as mention it above .... the only doc I got is RS232 spec that I load in my previous email.
I am not formating my command string correctly, when I resolve this .. I think it be light at the end of the tunnel ...
thank's
Alan
PS: Apology for the tardy reply, had to go On Site for a week and didn't see that you replied until I came back .... somehow I miss the email from LVR