XBee DigiMesh strange bit in frame and wrong checksum - c++

I am using XBee DigiMesh 2.4 API-2 and Raspberry Pi. I broadcast a frame from one node to another.
Frame to transmit:
7e 0 12 10 1 0 0 0 0 0 0 ff ff ff fe 0 0 41 6c 65 78 69
Frame received in the other node:
7e 0 10 90 0 7d 33 a2 0 40 91 57 26 ff fe c2 41 6c 65 78 1e
Byte which is bothering me, is c2. It should be 02. Why it appears in this way?
What is more, checksum is not correct (I read how the checksum should be calculated in API 2 mode).
With byte 0x02 it should be 0xe3 or with byte c2 it should be 0x23. I was trying to obtain the result 0x1e in many ways but I never got this value.
When I broadcast the packet in opposite direction (from second node to the first one) the same problems appear.
Both XBee´s are configurated with 9600 baudrate, no parity. Raspberry Pi UART as well.
----- Edit: I found the answer regarding to C2 byte. C2 is a bit field. C2 = 1100 0010.
Bits 7 and 6 are 11, it means here that it is Digimesh. Bit 1 is set so it is a broadcast packet.
https://dl.dropboxusercontent.com/u/318853/XBee%20900.PNG
Still looking for the reason of this checksum.

You can simplify your code by using API mode 1 and eliminating the need to escape and unescape values as you send and receive them. It really isn't that difficult to have your code figure out framing and ignore 0x7E in the middle of a frame: If you see a 0x7E followed by an invalid length, keep looking. If your frame has a bad checksum, skip the 0x7E and look for the next one.
If you absolutely must use escaping, ensure that the length value and checksum in your frame don't include the escaping bytes, and that you're properly escaping the necessary bytes as you send them.
On the receiving end, unescape the bytes and then calculate the checksum.

Related

How to decode modbus frame to float value using Arduino code?

Hello please I need your help, I am currently working on an emodbus project with arduino, I want to read the data from energy meter to the serial monitor on the arduino board,
I send for example the following frame of the arduino towards the meter to recover the value of the tension:
01 03 00 12 00 02 64 0E
in response from the counter to the arduino card I receive the following frame:
01 03 04 43 54 19 9A 25 9C
which must have the value: 212.1
my problem is that i could not display on the serial monitor
how can i decode this frame with arduino code to get the true value
Read here about the modbus library
Frame formats (This answers my question from the comment - you should have known that)
A Modbus "frame" consists of an Application Data Unit (ADU), which
encapsulates a Protocol Data Unit (PDU):[10]
ADU = Address + PDU + Error check,
PDU = Function code + Data.
The byte order for values in Modbus data frames is most significant
byte of a multi-byte value is sent before the others. All Modbus
variants use one of the following frame formats.[1] Modbus RTU frame
format (primarily used on asynchronous serial data lines like
RS-485/EIA-485) Name Length (bits) Function Start 28 At least 3½
character times of silence (mark condition) Address 8 Station
address Function 8 Indicates the function code; e.g., read
coils/holding registers Data n × 8 Data + length will be filled
depending on the message type CRC 16 Cyclic redundancy check End 28
At least 3½ character times of silence between frames
Before using the library or building blocks from it read the issues first.
For the application to emodbus go here: Look into the files emodbus.h and emodbus.cpp and etools.h and etools.cpp

How to read a QTcpSocket from R

I'm trying to send data from Qt to R. I am new to the QtNetwork module and relatively new to Qt overall. As such I am also trying to figure out how QIODevice encodes data for the purposes of reading and writing.
If I run the Fortune Server Example and connect to it with the following code in R:
connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10)
readBin(connection, what="raw", n = 1000)
the following raw hexadecimal vector is returned
00 00 00 56 00 59 00 6f 00 75 00 20 00 77 00 69 00 6c 00 6c 00 20 00 66 00 65 00 65 00 6c 00 20 00 68 00 75 00 6e 00 67 00 72 00 79 00 20 00 61 00 67 00 61 00 69 00 6e 00 20 00 69 00 6e 00 20 00 61 00 6e 00 6f 00 74 00 68 00 65 00 72 00 20 00 68 00 6f 00 75 00 72 00 2e
Removing the first five bytes and all the remaining null characters and converting to char I get:
"You will feel hungry again in another hour."
So what I want to know is where do all the characters that are not part of the fortune come from? The fourth byte seems to be the byte length of the message from the sixth byte to the end, the rest of the "non-fortune" characters are all null.
I read that QByteArray terminates each byte with a null character and QByteArray is converted to a QBuffer before being written by QTcpSocket, is that what is happening here? QBuffer adds the length of the message (but what of the other four bytes) and every second byte of a QByteArray is the null character? Also, the last byte is not null (did the readBin operation consume it/ how did readBin know where the message ended)?
Is this the only way to write data to the socket? If I wanted to transmit values of type double would I have to convert them to QByteArray to transmit them in this fashion? Is there not some non-text way of transmitting data through a socket?
Any enlightenment would be much appreciated!
EDIT:
Thanks for the answer! For completeness sake here is how you might decode the string in R
connection <- socketConnection(host="localhost", port=50743, open="rb", timeout=10)
# Read first 32 bits, which contains the size of the string in bytes
len.raw <- readBin(connection, what="raw", n = 4)
# convert to integer
len <- strtoi(paste(c("0x",len.raw),collapse=""))
# Read raw message
msg.raw <- readBin(connection, what="raw", n = len)
# convert to char using UTF-16BE
msg <- iconv(list(msg.raw),from="UTF-16BE")
close(connection)
cat(msg)
If you take a look at how the Fortune Server Example is implemented, you can see that it uses QDataStream to serialize fortunes (QStrings) over the socket:
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << fortunes.at(qrand() % fortunes.size());
So, the question is reduced to "How does QDataStream serialize QStrings?", and this is answered extensively in the documentation page about serializing Qt data types. You can see that a QString's serialization looks like this:
If the string is null: 0xFFFFFFFF (quint32)
Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
And this is exactly what you are seeing in your question. The first four bytes are the string length in bytes, and the "nulls" you are seeing later appear because of using UTF-16 encoding.
Is this the only way to write data to the socket? If I wanted to transmit values of type double would I have to convert them to QByteArray to transmit them in this fashion? Is there not some non-text way of transmitting data through a socket?
You can use any serialization format you like. QDataStream is widely used in Qt since it supports most Qt data types out of the box. This has nothing to do with using QByteArray, you can let QDataStream write to the socket directly. QDataStream is, actually, a binary format (non-text) as you can see. If want textual human-readable formats, you can use JSON.
But if you are aiming to send data from Qt to R using QDataStream, you'll have to write your QDataStream deserializer for R. I would recommend using some common data serialization that has implementations in C++ and R (in lieu of re-inventing the wheel). I believe JSON meets this criterion, and if you want to use a binary format, msgpack might be interesting for you, since it supports a lot of programming languages (including R and C++).

How to calculate checksum of UDP packet embedded inside IP packet

I have a UDP packet which is embedded inside IP packet and not able to calculate the checksum of UDP properly but I can correctly find the CHecksum of IP. Can someone help how the UDP checksum is found.
[45 00 00 53 00 80 00 00 40 11 66 16 0A 00 00 03 0A 00 00 02] CA B1 CA B1 00 3F DF A5
The bits enclosed in bracket is IP packet and the checksum is given in bold.
**UDP Packet**
CA B1 Source port
CA B1 Destination port
00 3F Length
DF A5 Checksum
Here how the checksum "DF A5" came. I did 16 bit addition and took the 1s complement but still not getting the value. Whether I need to consider IP header also to calculate the Checksum of UDP

Implementation of ISATAP Protocol

Can anybody help me figure out how to implement ISATAP packet?
I'm creating packets in C++ (Winpcap). I can't imagine how it should be.
Specification: http://www.networksorcery.com/enp/protocol/isatap.htm
Is that an example of ISATAP packet?
0000 5EFE C0A8 0110
(IP Address - 192.168.1.16)
4548 9559 (Some data)
According to specification the packet for 192.168.1.16 which is not globally uniqe (U bit set to 0) should look like in hexadecimal
00 00 5E FE
C0 A8 01 10
Some data
So it's correct

zlib decompression failing

I'm writing an application that needs to uncompress data compressed by another application (which is outside my control - I cannot make changes to it's source code). The producer application uses zlib to compress data using the z_stream mechanism. It uses the Z_FULL_FLUSH frequently (probably too frequently, in my opinion, but that's another matter). This third party application is also able to uncompress it's own data, so I'm pretty confident that the data itself is correct.
In my test, I'm using this third party app to compress the following simple text file (in hex):
48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a
The compressed bytes I receive from the app look like this (again, in hex):
78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff
If I try and compress the same data, I get very similar results:
78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55
There are two differences that I can see:
First, the fourth byte is F2, rather than F3, so the deflate "final block" bit has not been set. I assume this is because the stream interface never knows when the end of the incoming data will be, so never sets that bit?
Finally, the last four bytes in the external data is 00 00 FF FF, whereas in my test data it is 24 E9 04 55. Searching around I found on this page
http://www.bolet.org/~pornin/deflate-flush.html
...that this is a signature of a sync or full flush.
When I try and decompress my own data using the decompress() function, everything works perfectly. However, when I try and decompress the external data the decompress() function call fails with a return code of Z_DATA_ERROR, indicating corrupt data.
I have a few questions:
Should I be able to use the zlib "uncompress" function to uncompress data that has been compressed with the z_stream method?
In the example above, what is the significance of the last four bytes? Given that both the externally compressed data stream and my own test data stream are the same length, what do my last four bytes represent?
Cheers
Thanks to the zlib authors, I have found the answer. The third party app is generating zlib streams that are not finished correctly:
78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff
That is a partial zlib stream,
consisting of a zlib header and a
partial deflate stream. There are two
blocks, neither of which is a last
block. The second block is an empty
stored block, used as a marker when
flushing. A zlib decoder would
correctly decode what's there, and
then continue to look for data after
those bytes.
78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55
That is a complete zlib stream,
consisting of a zlib header, a single
block marked as the last block, and a
zlib trailer. The trailer is the
Adler-32 checksum of the uncompressed
data.
So My decompression is failing - probably because the CRC is missing, or the decompression code keeps looking for more data that does not exist.
solution is here:
http://technology.amis.nl/2010/03/13/utl_compress-gzip-and-zlib/
this is decompression and compression functions for start with 78 9C signature
compressed database blob (or stream).