'Отговор от устройството
Sub PrinterTX_NewData (Buffer() As Byte)
Dim s As String
s = BytesToString(Buffer, 0, Buffer.Length, PrinterCodePage)
If s.Length > 5 Then Log("In <- " & s)
GetAnswer(s)
End Sub
'Анализиране на получения отговор
Sub GetAnswer(RawAnswer As String) As String
Dim s As String
Dim Conv As ByteConverter
Dim i As Int
Dim j As Int
s = RawAnswer
If (s.Length = 1) And (s.SubString2(0, 1) = Chr(SYN)) Then
Log("SYN")
Return "" 'Printer sends WAIT command, wait for next block
End If
For j = 0 To 7 'Reset Status Bytes of the printer
StatusBytes(j) = 0
Next
Dim MyBytes(s.Length) As Byte
MyBytes = Conv.StringToBytes(s, PrinterCodePage)
If s.Length >= 25 Then
If True Then 'Here will be package CRC checks, now always TRUE
'Тук трябва да има проверка за валидност на пакета!
For i = 0 To (s.Length - 9) 'At least 8 status bytes
If MyBytes(i) = Splitter Then 'Data spliter found, next are the status bytes
ECRLastCommand = HexReverse(s.SubString2(6, 10)) 'BCD to Long conversion
ECRAnswer = s.SubString2(10, i-1)
ECRParams = Regex.Split(Sep, ECRAnswer)
ECRError = ECRParams(0)
For j = 0 To 7 'Copy Status Bytes
StatusBytes(j) = MyBytes(i + j + 1)
Next
Log("Status Bytes: " & HexSplit(Conv.HexFromBytes(StatusBytes))) 'Debug informaton
Exit 'Status bytes found, exiting loop
End If
Next
If ECRError <> "0" Then ErrorHandling
Log("Answer: " & ECRAnswer)
ExecuteTask 'Execute next task after getting the answer
Return ECRAnswer
Else
'Answer not valid, check sum failed! Here should be "Resend the command"
Return ""
End If
Else
'Answer not valid, too short! Here should be "Resend the command"
Return ""
End If
End Sub
Protocol description
Low level protocol
A) Protocol type - Master (Host) / Slave
The fiscal printer performs the commands sent by the Host and returns messages, which depend on the result. The fiscal printer cannot instigate asynchronous communications itself. Only responses to commands from the Host are sent to the Host. These messages are either wrapped or single byte control codes. The fiscal printer maintains the communication via the RS232 serial connection at baud rates of 1200, 2400, 4800, 9600, 19200, 38400, 57600 and 115200 b/s, 8N1.
B) Sequence of the messages
Host sends a wrapped message, containing a command for the fiscal printer. ECR executes the requested operation and response with a wrapped message. Host has to wait for a response from the fiscal printer before to send another message. The protocol uses non-wrapped messages with a length one byte for processing of the necessary pauses and error conditions.
C) Non-wrapped messages – time-out
When the transmitting of messages from the Host is normal, Slave answers not later than 60 ms either with a wrapped message or with a 1 byte code. Host must have 500 ms of time-out for receiving a message from Slave. If there is no message during this period of time the Host will transmit the message again with the same sequence number and the same command. After several unsuccessful attempts Host must indicate that there is either no connection to the fiscal printer or there is a hardware fault.
Non-wrapped messages consist of one byte and they are:
A) NAK 15H
This code is sent by Slave when an error in the control sum or the form of the received message is found. When Host receives a NAK it must again send a message with the same sequence number.
B) SYN 16H
This code is sent by Slave upon receiving a command which needs longer processing time. SYN is sent every 60 ms until the wrapped message is not ready for transmitting.
D) Wrapped messages
a) Host to fiscal printer (Send)
<01><LEN><SEQ><CMD><DATA><05><BCC><03>
b) Fiscal printer to Host (Receive)
<01><LEN><SEQ><CMD><DATA><04><STATUS><05><BCC><03>
Where:
<01> Preamble. - 1 byte long. Value: 01H.
<LEN> Number of bytes from <01> preamble (excluded) to <05> (included) plus the fixed offset of 20H.
Length: 4 bytes. Each digit from the two bytes is sent after 30H is added to it. For example the sum 1AE3H is presented as 31H, 3AH, 3EH, 33H.
<SEQ> Sequence number of the frame.
Length : 1 byte. Value: 20H – FFH. The fiscal printer saves the same <SEQ> in the return message. If the ECR gets a message with the same <SEQ> as the last message received it will not perform any operation, but will repeat the last sent message.
<CMD> The code of the command.
Length: 4 byte. The fiscal printer saves the same <CMD> in the return message. If the fiscal printer receives a non-existing code it returns a wrapped message with zero length in the data field and sets the respective status bit. Each digit from the two bytes is sent after 30H is added to it. For example the sum 1AE3H is presented as 31H, 3AH, 3EH, 33H.
<DATA> Data.
Length: 0-213 bytes for Host to fiscal printer, 0-218 bytes for Fiscal printer to Host. Value: 20H – FFH. The format and length of the field for storing data depends on the command. If the command has no data the length of this field is zero. If there is a syntax error the respective status bit is established in the data and a wrapped message is returned with zero field length.
<04> Separator (only for fiscal printer-to-Host massages),
Length: 1 byte. Value: 04H.
<STATUS> The field with the current status of the fiscal device.
Length: 8 bytes. Value: 80H-FFH.
<05> Postamble
Length: 1 byte. Value:05H.
<BCC> Control sum (0000H-FFFFH),
Length: 4 bytes. Value of each byte: 30H-3FH. The sum includes between <01> preamble (excluded) to <05>. Each digit from the two bytes is sent after 30H is added to it. For example the sum 1AE3H is presented as 31H, 3AH, 3EH, 33H.
<03> Terminator, Length: 1 byte. Value: 03H.
Message composition, syntax and meanings
a) The data field depends on the command.
b) The parameters sent to the fiscal printer may be separated with a [\t] and/or may have a fixed length.
c) The separator( [\t] ) between the parameters shows that it is mandatory.
d) Some of the parameters are mandatory and others are optional. Optional parameters can be left empty, but after them must have separator ( [\t] ).
The symbols with ASCII codes under 32 (20H) have special meanings and their use is explained whenever necessary. If such a symbol has to be sent for some reason (for example in an ESCAPE-command to the display) it must be preceded by 16 (10H) with an added offset 40H.
Here is some communication through COM port (PC)
Write COM1: 01 52 3C 2A 20 20 31 20 53 74 65 72 6C 69 6E 67 .R<* 1 Sterling
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 31 2E 1.
39 39 05 30 39 32 37 03 99.0927.
Read COM1: 01 2B 3C 2A 04 80 80 A0 80 86 98 05 30 33 3D 38 .+<*.ЂЂ Ђ†.03=8
Port flushed COM1 (31.08.2017 16:58:31)
Write COM1: 01 52 3D 2A 20 20 31 20 53 74 61 72 6F 62 72 6E .R=* 1 Starobrn
6F 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 o
20 20 20 20 20 20 20 20 20 20 20 20 20 20 31 2E 1.
35 39 05 30 39 37 36 03 59.0976.
Read COM1: 01 2B 3D 2A 04 80 80 A0 80 86 98 05 30 33 3D 39 .+=*.ЂЂ Ђ†.03=9
Port flushed COM1 (31.08.2017 16:58:31)
Write COM1: 01 25 3E 2A 20 05 30 30 3B 32 03 .%>* .00;2.
Read COM1: 01 2B 3E 2A 04 80 80 A0 80 86 98 05 30 33 3D 3A .+>*.ЂЂ Ђ†.03=:
Port flushed COM1 (31.08.2017 16:58:31)
Write COM1: 01 24 3F 27 05 30 30 38 3F 03 .$?'.008?.
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 .
Read COM1: 16 01 2F 3F 27 30 30 30 37 04 80 80 80 80 86 98 ../?'0007.ЂЂЂЂ†
05 30 34 38 33 03 .0483.
Port flushed COM1 (31.08.2017 16:58:32)
Write COM1: 01 24 40 3E 05 30 30 3A 37 03 .$@>.00:7.
Read COM1: 01 3C 40 3E 33 31 2D 30 38 2D 31 37 20 31 36 3A .<@>31-08-17 16:
35 38 3A 32 38 04 80 80 80 80 86 98 05 30 37 34 58:28.ЂЂЂЂ†.074
31 03 1.
Port flushed COM1 (31.08.2017 16:58:32)
Write COM1: 01 24 41 71 05 30 30 3D 3B 03 .$Aq.00=;.
Read COM1: 01 32 41 71 30 30 30 30 31 37 30 04 80 80 80 80 .2Aq0000170.ЂЂЂЂ
86 98 05 30 35 36 33 03 †.0563.
Port flushed COM1 (31.08.2017 16:58:32)
Write COM1: 01 25 42 4A 57 05 30 31 30 3D 03 .%BJW.010=.
Read COM1: 01 31 42 4A 80 80 80 80 86 98 04 80 80 80 80 86 .1BJЂЂЂЂ†.ЂЂЂЂ†
98 05 30 37 30 32 03 .0702.
Port closed COM1 (31.08.2017 16:58:32)