Encoding NanoPB variable Strings

Viewed 67

I have a String that is determined at runtime by reading from EEPROM:

 pb_ostream_t config_params_apn = pb_ostream_from_buffer(buffer_arr, buffer_arr_size);

 read_or_load_defaults_buffer(APN_CONFIG_BASE,eeprom_buffer,&eeprom_buffer_length);

 apn_msg.domain.arg = &eeprom_buffer;
 apn_msg.domain.funcs.encode = &encode_string;
 read_or_load_defaults_buffer(APN_UNAME_BASE,eeprom_buffer,&eeprom_buffer_length);
 apn_msg.username.arg = "nuts";
 apn_msg.username.funcs.encode = &encode_string;

The problem is that "nuts" is being encoded but the variable value in eeprom_buffer is not. I need some advise on why this could be happening, please?

Here is my encode_string function:

bool encode_string(pb_ostream_t* stream, const pb_field_t* field, void* const* arg)

 char* str = (char*)(*arg);

if (!pb_encode_tag_for_field(stream, field))
    return false;

return pb_encode_string(stream, (uint8_t*)str, strlen(str));
1 Answers
 read_or_load_defaults_buffer(APN_CONFIG_BASE,eeprom_buffer,&eeprom_buffer_length);
 apn_msg.domain.arg = &eeprom_buffer;
 apn_msg.domain.funcs.encode = &encode_string;
 read_or_load_defaults_buffer(APN_UNAME_BASE,eeprom_buffer,&eeprom_buffer_length);

First problem is probably that the code is setting arg to &eeprom_buffer. Depending on what type it is declared as, the code should probably be passing eeprom_buffer like it does to the other function.

A second problem is that the eeprom_buffer seems to be reused for other data before pb_encode is called. Therefore when the callback eventually gets called, it will only see the latest data in eeprom_buffer.


I would suggest to instead do the EEPROM reading in the callback function itself:

bool encode_from_eeprom(pb_ostream_t* stream, const pb_field_t* field, void* const* arg)
{
 char eeprom_buffer[128];
 size_t eeprom_buffer_len;
 int address = (int)(*arg);

 read_or_load_defaults_buffer(address,eeprom_buffer,&eeprom_buffer_len);

 if (!pb_encode_tag_for_field(stream, field))
    return false;

 return pb_encode_string(stream, eeprom_buffer, eeprom_buffer_len);
}

...

apn_msg.domain.arg = (void*)APN_CONFIG_BASE;
apn_msg.domain.funcs.encode = &encode_from_eeprom;

That way there is no need to store the string in RAM any longer than necessary.

Related