简体   繁体   English

从 nanopb 读取 Proto Buffer 消息时出现 DecodeError

[英]DecodeError when reading Proto Buffer message from nanopb

I implemented a small HttpClient for an IoT device and wanted to use Proto Buffer as a communication format.我为 IoT 设备实现了一个小型 HttpClient,并希望使用 Proto Buffer 作为一种通信格式。 Because of the constraints of the platform I am using nanopb.由于平台的限制,我使用的是 nanopb。 That's the relevant code in C:这是C中的相关代码:

#include <pb_encode.h>
#include "device_data.pb.h"
#include <ESP8266HTTPClient.h>

[...]
pb_MEvent m_event = pb_MEvent_init_zero;
uint8_t m_buffer[21];
pb_ostream_t stream = pb_ostream_from_buffer(m_buffer, 21);
pb_encode(&stream, pb_MEvent_fields, &m_event);

int httpCode = httpClient.POST(m_buffer, stream.bytes_written);
[...]

I created a small flask server which exposes an endpoint.我创建了一个小型 flask 服务器,它公开了一个端点。 When I try to decode the message, I get the following error: google.protobuf.message.DecodeError: Error parsing message with type 'pb.MEvent'当我尝试解码消息时,出现以下错误: google.protobuf.message.DecodeError: Error parsing message with type 'pb.MEvent'

That the code for it:它的代码:

from flask import Flask, request

from device_data_pb2 import MEvent

app = Flask(__name__)

@app.route("/", methods = ['POST', "GET"])
def hello_world():
    m_event = MEvent()

    m_event.ParseFromString(request.data)
    print(m_event)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port= 5000)

I tried to use io.ByteStream and read it then and I also tried to encode the bytes with ASCII and UTF-8 but neither of that approaches worked.我尝试使用 io.ByteStream 然后读取它,我还尝试使用 ASCII 和 UTF-8 对字节进行编码,但这些方法都不起作用。

Could you please help me find out, what is causing the problem?您能帮我找出问题所在吗? The error message is not that helpful.错误消息没有那么有用。

Update更新

This is the content fo the proto file:这是 proto 文件的内容:

syntax = "proto2";
package pb;

message MEvent {
    required float accelX = 1;
    required float accelY = 2;
    required float accelZ = 3;
    required float gyroX = 4;
    required float gyroY = 5;
    required float gyroZ = 6;
    required int64 msec = 7;
}

And here are some data points:以下是一些数据点:

DATA:
0.16 -0.08 9.96 0.00 -0.00 0.02 0
HEX:
0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d

DATA:
0.16 -0.09 9.96 0.00 -0.00 0.02 0
HEX:
0d:cd:7d:20:3e:15:56:ab:bc:bd:1d:5f:6b:1f:41:25:79:22:a0:3b:2d


DATA:
0.15 -0.10 9.96 0.00 -0.00 0.02 0
HEX:
0d:89:0a:1e:3e:15:21:05:c4:bd:1d:de:52:1f:41:25:b5:33:70:3b:2d

DATA: 0.16 -0.08 9.96 0.00 -0.00 0.02 0 HEX: 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d数据:0.16 -0.08 9.96 0.00 -0.00 0.02 0 十六进制:0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70 :3b:2d

I'm using the nanopb/tests/raw_decode to analyze this.我正在使用nanopb/tests/raw_decode来分析这个。 Marc Gravell's decode utility used to be great for this but for some reason it does not work very well for corrupted data anymore. Marc Gravell 的解码实用程序曾经非常适合此功能,但由于某种原因,它不再适用于损坏的数据。

user@host:~/nanopb/tests$ echo 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d \
| tr -d ':' | xxd -r -p | build/raw_decode/raw_decode

At 0: field tag 1, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3e27d798
At 5: field tag 2, wire type 5 (32BIT), fixed32 value (4 bytes): 0xbdadf7bf
At 10: field tag 3, wire type 5 (32BIT), fixed32 value (4 bytes): 0x411f7046
At 15: field tag 4, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3b7033b5
At 20: field tag 5, wire type 5 (32BIT)
ERROR: Failed to parse fixed32: io error
LATEST BYTES READ (21 to 21): 

It appears your message is cut short.看来您的消息被缩短了。 The amount of buffer space you reserve on this line is not large enough:您在此行保留的缓冲区空间量不够大:

uint8_t m_buffer[21]; uint8_t m_buffer[21];

If you check the return value of pb_encode() it is probably also returning false and stream.errmsg indicates that the buffer is full.如果您检查pb_encode()的返回值,它可能也返回false并且stream.errmsg表示缓冲区已满。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM