Decoding the string callback

99 views
Skip to first unread message

Altaf Hussain

unread,
Feb 24, 2023, 1:40:05 AM2/24/23
to nanopb
Hi,

I have an issue related to string callback decoding. Over Bluetooth Low Energy(BLE)  I am sending the encoded string callback data , but I am unable to decode the string properly in other device. 

The encoded string length is 244 bytes, but I am unable to receive whole encoded string as well.

Please help me to fix this issue.

Thanks,
Altaf


Petteri Aimonen

unread,
Feb 24, 2023, 2:18:01 AM2/24/23
to nan...@googlegroups.com
Hi,

Based on that it is impossible to guess what could be going from.

But the generic way to debug is to:

1. In the transmitting end, take a hex dump of the data you are going to send.
Decode with e.g. https://protobuf-decoder.netlify.app/ to check that it is correct.

2. In the receiving end, take a hex dump of the data before passing it to pb_decode().
Decode again to check.

3. If the output from pb_decode() is wrong even though the input is correct, post
the hex dump, the message struct as printed by debugger, the code you use for decoding
and the .proto file.

--
Petteri

Sudhir Bijanki

unread,
Feb 25, 2023, 10:35:33 PM2/25/23
to nan...@googlegroups.com
Thank you
 I will do it more methodically to make sure all the elements are consistently created. Regards

--
You received this message because you are subscribed to the Google Groups "nanopb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nanopb+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nanopb/20230224071756.kqzjandevllywqgw%40lakka.kapsi.fi.

Altaf Hussain

unread,
Feb 26, 2023, 4:47:14 AM2/26/23
to nanopb
How to encode and decode callbacks or other members of nested structure?
typedef struct  _struct {
    N_struct a;
    uint64_t ep;
    pb_callback_t  t;
    pb_callback_t  d;
} N;

Altaf Hussain

unread,
Feb 27, 2023, 4:35:11 AM2/27/23
to nanopb
// I have this kind of .proto file how to encode and decode this proto file?
message Data {
  uint32 kind = 1;
  uint64 startTime = 2;
  uint64 endTime = 3;
}

message  Status {
  uint64 startTime = 1;
  uint64 endTime = 2;
  repeated Data items = 3;
}

message history {
  repeated Status items = 1;
  uint32 total = 2;
  uint32 current = 3;

Petteri Aimonen

unread,
Feb 27, 2023, 7:11:30 AM2/27/23
to nan...@googlegroups.com
Hi,

Easiest way is to specify maximum counts for the fields.
https://jpa.kapsi.fi/nanopb/docs/reference.html#defining-the-options-in-a-.options-file

Only use callbacks if you need to handle large amounts of data
with limited memory, they add a lot of complexity to code.

--
Petteri

Altaf Hussain

unread,
Mar 1, 2023, 5:38:36 AM3/1/23
to nanopb
Decoding failed = parent stream too short
This error is coming.
Why it is coming and what is the solution for this error?

Altaf Hussain

unread,
Mar 7, 2023, 1:36:44 PM3/7/23
to nanopb
How to encode and decode :-
1. bool tpye
2. pb_callback_t
3. pb_size_t
4. union type
5. message GProto {
  SProto kind = 1;
  }
I have this kind of poroto how to encode and decode

message BProto {
  enum Alignment {
    C_START = 0;
    CENTER = 1;
    C_END = 2;
    T_START = 3;
    T_CENTER = 4;
    T_END = 5;
    B_START = 6;
    B_CENTER = 7;
    B_END = 8;
  }
  uint32 top = 1;
  uint32 left = 2;
  uint32 width = 3;
  uint32 height = 4;
  Alignment alignment = 5;
}

message CProto {
  BProto box = 1;
  uint32 imageId = 2;
}

Altaf Hussain

unread,
Mar 9, 2023, 8:01:47 AM3/9/23
to nanopb

syntax = "proto2";

 message stringCallback{

    required string name = 1;
    required string surname = 2;
    required int32 age = 3;
    repeated int32 values = 4;
}

/* Struct definitions */
typedef struct _stringCallback {
    pb_callback_t name;
    pb_callback_t surname;
    int32_t age;
    pb_callback_t values;
} stringCallback;


How to assign data in encoding time 
I did like that is this correct way to assign

stringCallback  message;
strcpy(message.name,"altaf");
strcpy(message.surname,"hussain");
message.age = 25;
message.values = 23; 

after assigning how to encode and decode

Petteri Aimonen

unread,
Mar 9, 2023, 8:09:26 AM3/9/23
to nan...@googlegroups.com
Hi,

I don't have the time to provide guidance at this level, but I suggest
you check out the examples "simple" and "network_server" for the basics.

--
Petteri

Teresa Muñoz Sesma

unread,
Jul 7, 2023, 2:22:47 AM7/7/23
to nanopb
Hi,
I have this .proto message: 
syntax = "proto3";

message Downlink {
  int32 id = 1;
  string method = 2;
  string version = 3;
  Params params = 4;
}

message Params {
  repeated string sensors = 1;
  int32 send_interval = 2;
  string gprs_apn = 3;
  string gprs_user = 4;
  string gprs_pass = 5;
  string sim_pin = 6;
  AFE no2 = 7;
  AFE o3 = 8;
  AFE no = 9;
  AFE so2 = 10;
  AFE h2s = 11;
  AFE co = 12;
}

message AFE {
  string equation = 1;
  int32 ref = 2;
  float wee = 3;
  float we0 = 4;
  float aee = 5;
  float ae0 = 6;
  float ssa = 7;
  float offset = 8;
  float slope = 9;
  int32 weu_adc_ch = 10;
  int32 aeu_adc_ch = 11;
  float no2_ssa = 12;
  int32 conversion_factor = 13;
}
And I can easily obtain the ID when I send a downlink message, but when trying to decode the string, it seems as if it was empty, though it isn't. I am using protobuf decoder online to see if there is something, and I get a result. This is the code I am working with: 
bool Serializer::get_rpc_method_lora(const byte *payload, size_t payloadLength, char *method, uint8_t method_size) {
  Serial.println("Estoy buscando el método");

  Downlink downlink = Downlink_init_default;
  pb_istream_t pb_stream = pb_istream_from_buffer(payload, payloadLength);

  // Deserializar los datos
  bool status = pb_decode(&pb_stream, Downlink_fields, &downlink);
  Serial.println(status);

  if (status) {
    if (downlink.method.arg != nullptr) {
      const pb_byte_t *method_buffer = reinterpret_cast<const pb_byte_t*>(downlink.method.arg);
      size_t method_length = pb_stream.bytes_left;
     
      // Verificar que la longitud de la cadena de caracteres sea adecuada
      if (method_length < method_size) {
        // Copiar la cadena de caracteres en el búfer proporcionado
        memcpy(method, method_buffer, method_length);
        method[method_length] = '\0';
        Serial.println(method);
        return true;
      } else {
        Serial.println("Error al leer la cadena de caracteres: tamaño del búfer insuficiente");
        return false;
      }
    } else {
      Serial.println("El método no está presente en el mensaje");
      return false;
    }
  } else {
    // Error al deserializar
    return false;
  }
}

Thanks to everyone in advance!!

Petteri Aimonen

unread,
Jul 7, 2023, 2:36:06 AM7/7/23
to nan...@googlegroups.com
Hi,

I don't quite understand how this should work:

> bool status = pb_decode(&pb_stream, Downlink_fields, &downlink);
> size_t method_length = pb_stream.bytes_left;

Normally pb_decode reads the whole stream, so bytes_left is expected to be zero.

I think you may want to specify the max_size option on method in .proto file (or separate .options file):

import 'nanopb.proto';
...
string method = 2 [(nanopb).max_size = 16];

This way the string will be available as simple char array, and you can use strlen() to get its length.

--
Petteri
Reply all
Reply to author
Forward
0 new messages