Message variable length indicator (VLI) 2 bytes precede every message sent to/from BizSwitch. The 2 bytes are referred to as a variable length indicator. Bytes 1-2 indicate the number of bytes in the message (excluding the first 2 bytes). The 2 bytes represent a 16bit unsigned integer in network byte order. Note that if a compressed message is being sent, the message will have to first be compressed, in order to determine its length, before being sent. As an example, suppose that you were to look at just the text (excluding the 2 byte header) making up an XML message from a particular example and that you then counted the characters and they happened to add up to 299 characters. If you took a scientific calculator (the one in Windows for example) and you typed in 299 with "Dec" (for decimal) selected, then you select "Hex", the value that would be shown is "12B", which means the same as 01 2B, which is exactly what one would expect to see for the first two bytes of the message if the message had been dumped to a file and then opened with a hex editor. Example java code for calculating a VLI:
public byte[] wrap(byte[] msg) throws Exception {
int len = msg.length;
if (len > 65535) {
throw new IllegalArgumentException("Exceeds 65535 bytes.");
}
byte firstByte = (byte)(len >>> 8);
byte secondByte = (byte)len;
ByteArrayOutputStream baos = new ByteArrayOutputStream(len + 2);
baos.write(firstByte);
baos.write(secondByte);
baos.write(msg);
return baos.toByteArray();
}
public byte[] unWrap(InputStream inputStream) throws Exception {
int firstByte = inputStream.read();
if (firstByte == -1) {
throw new IOException("End of Stream while trying to read vli byte 1");
}
int firstByteValue = firstByte << 8;
int secondByteValue = inputStream.read();
if (secondByteValue == -1) {
throw new IOException("End of Stream reading vli byte 2." );
}
int len = firstByteValue + secondByteValue;
byte[] message = new byte[len];
int requestLen;
int readLen;
int currentIndex = 0;
while(true) {
requestLen = len - currentIndex;
readLen = inputStream.read(message, currentIndex, requestLen);
if (readLen == requestLen) {
break; // Message is complete.
}
// Either data was not yet available, or End of Stream.
currentIndex += readLen;
int nextByte = inputStream.read();
if (nextByte == -1) {
throw new IOException("End of Stream at " + currentIndex
);
}
message[currentIndex++] = (byte)nextByte;
}
return message;
}
and here is my python converted code
import io
def wrap(msg):
msg_len = len(msg)
if msg_len > 65535:
return "Message exceeds 65535 bytes."
first_byte = bytes(msg_len >> 8)
second_byte = bytes(msg_len)
# create an empty bytearray
data_frame = bytearray()
data_frame.extend(first_byte)
data_frame.extend(second_byte)
data_frame.extend(msg)
return data_frame
def un_wrap(data_frame):
data_frame = io.BytesIO(data_frame)
first_byte = data_frame.read()
try:
first_byte == -1
except:
raise "End of Stream while trying to read vli byte 1"
first_byte_value = first_byte << 8
second_byte_value = data_frame.read(1)
try:
second_byte_value == -1
except:
raise "End of Stream reading vli byte 2."
byt_len = first_byte_value + second_byte_value
message = bytes(byt_len)
request_len = 0
read_len = 0
current_index = 0
while True:
request_len = byt_len - current_index
read_len = data_frame.read(message, current_index, request_len)
if read_len == request_len:
return "Message is complete."
# Either data was not yet available, or End of Stream.
current_index += read_len
next_byte = data_frame
if next_byte == -1:
return "End of Stream at " + current_index
message.extend(bytes(next_byte))
return message
This is the error am getting
first_byte_value = first_byte << 8
TypeError: unsupported operand type(s) for <<: 'bytes' and 'int'
This is the is what am sending as the message but I require two bytes to precede the message
<ipayMsg client="PESATRANS" term="00001" seqNum="0" time="2019-10-09 10:13:20 +0300">
<elecMsg ver="2.44">
<vendReq>
<ref>749761497475</ref>
<amt cur="KES">500</amt>
<numTokens>1</numTokens>
<meter>01450344831</meter>
<payType>cash</payType>
</vendReq>
</elecMsg>
</ipayMsg>