Reputation: 1
I'm trying to setup a Siemens QNA2820D.EU lorawan sensor, and the measurements are sent encoded using protobuf and I think more precisely nanoPB. It's my first time using these technologies so I'm having a very hard time decoding the messages.
The company sent me their protobuf files (21 files) and I was able to compile them with protoc and nanopb output, and using the simple.c example in the nanopb files, I wrote a code to try to encode/decode a message:
#include <stdio.h>
#include <stdint.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include "SiemensLoRaIAQMessage.pb.h"
int main()
{
/* This is the buffer where we will store our message. */
uint8_t buffer[128];
//Example of a message I receive from the sensor
// char data[] = "0A06080210B79602100042220A06626F6F747570120D312E362E322E7369656D656E7328E7FFFFFFFFFFFFFFFF01";
size_t message_length;
bool status;
/* Encode our message */
{
/* Allocate space on the stack to store the message data.
*
* Nanopb generates simple struct definitions for all the messages.
* - check out the contents of simple.pb.h!
* It is a good idea to always initialize your structures
* so that you do not have garbage data from RAM in there.
*/
SiemensIAQLoraMessage message = SiemensIAQLoraMessage_init_zero;
SiemensIAQEventScoreMessage_Sensor val = {18, 50, 500, 0, 0, 0, 0, true, 0, true, 0};
message.event_score.sensor = val;
printf("Your temperature was %f!\n", message.event_score.sensor.temp);
/* Create a stream that will write to our buffer. */
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
/* Now we are ready to encode the message! */
status = pb_encode(&stream, &SiemensIAQLoraMessage_msg, &message);
message_length = stream.bytes_written;
printf("message length: %ld \n", message_length);
/* Then just check for any errors.. */
if (!status)
{
printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
return 1;
}
}
/* Now we could transmit the message over network, store it in a file or
* wrap it to a pigeon's leg.
*/
/* But because we are lazy, we will just decode it immediately. */
{
/* Allocate space for the decoded message. */
size_t size = 0;
for (size = sizeof(buffer); buffer[size] == 0x00; size--)
{}
size = size/6;
printf(" message lgt manually done : %ld \n", size);
SiemensIAQLoraMessage message = SiemensIAQLoraMessage_init_zero;
for (int i = 0; i<sizeof(buffer); i++){
printf("%d",buffer[i]);
}
printf("\n");
/* Create a stream that reads from the buffer. */
pb_istream_t stream = pb_istream_from_buffer(buffer, size);
/* Now we are ready to decode the message. */
status = pb_decode(&stream, &SiemensIAQLoraMessage_msg, &message);
/* Check for errors... */
if (!status)
{
printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
return 1;
}
/* Print the data contained in the message. */
printf("Your lucky number was %f!\n", message.event_score.sensor.temp);
}
return 0;
}
Now when I launch the code, I have no errors so I presume the message is encoded correctly but when I try to decode it, the value I get for the value I set up is 0. What am I doing wrong? And moreover how am I supposed to get the message length from the string I receive in Lorawan, finally is it possible to use nanoPB in a python code?
Thank you very much
Upvotes: 0
Views: 362
Reputation: 12176
You can decode the messages using any Protobuf implementation, for example python-protobuf if you are using Python.
for (size = sizeof(buffer); buffer[size] == 0x00; size--) {} size = size/6; printf(" message lgt manually done : %ld \n", size);
I'm not sure what this is supposed to do, but it seems very incorrect. The protobuf encoded message length should be passed separately to the decoding side, because protobuf messages do not contain any indication of their end. There can be zero bytes in middle of a message. Zero bytes can also occur at the end of the message.
Upvotes: 0