I am facing a problem while building an integration between ECR (electronic cash register) and an android POS. I'm working on the android POS and i want to calculate the message size and add it in "2 bytes, binary".
I have this block of code to calculate and generate the complete message
fun generateMessage(message: String): String {
return buildString {
append(Constants.DIRECTION)
append(AppData.getProtocolVariant())
append(AppData.getProtocolVersion())
append(message)
val buffer = ByteBuffer.allocate(2)
buffer.putShort(message.length.toShort())
insert(0, buffer.array().decodeToString())
}
}
But this code only works for really small messages, because in the logs i can see that for larger messages this code adds 3 digits and communication fails. The complete message is in the form of <MSG SIZE(2 bytes, binary)><DIRECTION INDICATOR(3 bytes, ascii)><PROTOCOL VARIANT(2 bytes, ascii)><PROTOCOL VERSION(2 bytes, ascii)><Actual messsage (MSG SIZE-7)>
When I send a simple message "E/000" (hex dump 45 2f 30 30 30) the code works and the ECR accepts it and in the logs i see "��POS0110E/000" when i have a bigger message i see something like this "���POS0110R/S852484/RDLF****16/T93/M0/C00/DMastercard:00:0000***1234:200:200:0:0:0:1:803:2:133030119089:193439:497853:20230926115814:0"
which has 3 digits for the message size and it fails.
So how can i create this message and follow the protocol <MSG SIZE(2 bytes, binary)>?
override fun sendMessage(message: String) {
val finalMessage = Utils.generateMessage(message)
server.sendMessage(finalMessage.encodeToByteArray()) }
`
changed the code to
fun sendMessage(bytes: ByteArray) {
coroutineScope.launch(Dispatchers.IO) {
val outputStream = socket?.getOutputStream()
outputStream?.write(bytes)
outputStream?.flush()
}
}`
and still is not accepted
You need to write bytes to the OutputStream
, not a String
. You should change your generateMessage()
method to return a ByteArray
instead of a String
, like this:
fun generateMessage(message: String): ByteArray {
val x = buildString {
append(Constants.DIRECTION)
append(AppData.getProtocolVariant())
append(AppData.getProtocolVersion())
append(message)
}
// Create byte array containing 2-byte message length (binary) followed
// by the actual message
val buffer = ByteBuffer.allocate(2 + x.length)
buffer.putShort(x.length.toShort())
buffer.put(x.getBytes())
return buffer
}
Also, please note that the message length (according to the example from the guide you pasted) is the length of the entire message (including the header: direction, protocol version, etc.). In your code you only used the length of the actual message (not including the header data).