如何在 c 中处理 capn_data?
How to handle capn_data in c?
我使用 c-capnproto 序列化我的传感器数据。现在我需要给它添加一个 HMAC。它需要是一个 capn_data
blob,但这在 the example code.
中没有处理
当我尝试添加数据时,它不起作用。
这是我的 capnp
文件:
@0xe2d0214c41cb77af;
using C = import "c.capnp";
$C.fieldgetset;
struct Heartbeat @0x97002102216a8d67 {
temperature @0 :UInt32;
}
struct AuthenticatedHeartbeat @0xe2fa13efd2e3a9dc {
heartbeat @0 :Data;
hmac @1 :Data;
}
编译后,我使用它:
static uint8_t beat[1024];
static uint8_t hmac[32] = {0xc2, 0xf1, 0x53, 0x12, 0x4b, 0x0c, 0xa4, 0xd1,
0x22, 0xf1, 0x64, 0x22, 0x1b, 0xbc, 0xa5, 0xd2,
0xe2, 0xf2, 0x75, 0x32, 0x2b, 0x3c, 0xa6, 0xd3,
0x72, 0xf1, 0x86, 0x42, 0x6b, 0x7c, 0xa7, 0xd4};
static uint8_t auth[1024];
int main(void) {
int packed_size;
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
Heartbeat_ptr hb = new_Heartbeat(cs);
Heartbeat_set_temperature(hb, 0x25);
capn_setp(capn_root(&root), 0, hb.p);
packed_size = capn_write_mem(&root, beat, sizeof(beat), 1/*packed*/);
printf("BEAT: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
print_buffer(beat, packed_size);
//HMAC_calc(beat, packed_size, hmac);
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
AuthenticatedHeartbeat_ptr ahb = new_AuthenticatedHeartbeat(cs);
AuthenticatedHeartbeat_set_heartbeat(ahb, buf_to_data(beat, packed_size));
AuthenticatedHeartbeat_set_hmac(ahb, buf_to_data(hmac, 32));
capn_setp(capn_root(&root), 0, ahb.p);
packed_size = capn_write_mem(&root, auth, sizeof(auth), 1/*packed*/);
printf("AUTH: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
print_buffer(auth, packed_size);
}
我写了一个辅助函数,就像示例中提供的 chars_to_text
函数一样
static capn_data buf_to_data(char *buf, const int len) {
return (capn_data) {{
.type = CAPN_NULL,
.has_ptr_tag = 0,
.is_list_member = 0,
.is_composite_list = 0,
.datasz = 0,
.ptrs = 0,
.len = len,
.data = buf,
.seg = NULL,
}};
}
但我想我遗漏了一些部分。
结果数据
BEAT: max_unpacked_size=24, packed_size=6
[ 0] - 10021001 - ....
[ 1] - 01250000 - .%
AUTH: max_unpacked_size=32, packed_size=6
[ 0] - 10034002 - ..@.
[ 1] - 00010000 - ..
至少在认证数据中不再包含温度 (0x25
)。此外,HMAC 不存在,长度太短了。
能否请您提示我如何处理 capn_data
blob、如何填充它以及如何将其打包到根目录中。
终于在 this closed issue 中找到了一个提示,这在我一开始的研究中是不可见或被忽视的...
我使用此代码序列化 capn_data
(这替换了原始问题中的较低范围):
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
capn_list8 list8 = capn_new_list8(cs, packed_size);
capn_setv8(list8, 0, beat, packed_size);
capn_list8 list9 = capn_new_list8(cs, 32);
capn_setv8(list9, 0, hmac, 32);
struct AuthenticatedHeartbeat s_ahb;
s_ahb.heartbeat.p = list8.p;
s_ahb.hmac.p = list9.p;
AuthenticatedHeartbeat_ptr pahb = new_AuthenticatedHeartbeat(cs);
write_AuthenticatedHeartbeat(&s_ahb, pahb);
capn_setp(capn_root(&root), 0, pahb.p);
packed_size = capn_write_mem(&root, auth, sizeof(auth), 1/*packed*/);
printf("AUTH: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
因此,首先创建一个“列表”,稍后用作 capn_data
,因为这两个与 @eqvinox 所述基本相同。
不再需要 buf_to_data()
功能。
作为参考,这是反序列化数据的示例代码:
{
struct capn root;
capn_init_mem(&root, auth, packed_size, 1/*packed*/);
AuthenticatedHeartbeat_ptr ahbp;
ahbp.p = capn_getp(capn_root(&root), 0, 1);
capn_data dhb = AuthenticatedHeartbeat_get_heartbeat(ahbp);
capn_data dhmac = AuthenticatedHeartbeat_get_hmac(ahbp);
printf("dhb ptr=%p, len=%d\n", dhb.p.data, dhb.p.len);
printf("dhmac ptr=%p, len=%d\n", dhmac.p.data, dhmac.p.len);
unpacked_size = dhb.p.len;
hmac2_size = dhmac.p.len;
memcpy(beat2, dhb.p.data, unpacked_size);
memcpy(hmac2, dhmac.p.data, hmac2_size);
capn_free(&root);
}
{
struct capn root;
capn_init_mem(&root, beat2, unpacked_size, 1/*packed*/);
Heartbeat_ptr hbp;
hbp.p = capn_getp(capn_root(&root), 0, 1);
uint32_t temperature = Heartbeat_get_temperature(hbp);
printf("DESER: temperature=%x\n", temperature);
capn_free(&root);
}
我使用 c-capnproto 序列化我的传感器数据。现在我需要给它添加一个 HMAC。它需要是一个 capn_data
blob,但这在 the example code.
当我尝试添加数据时,它不起作用。
这是我的 capnp
文件:
@0xe2d0214c41cb77af;
using C = import "c.capnp";
$C.fieldgetset;
struct Heartbeat @0x97002102216a8d67 {
temperature @0 :UInt32;
}
struct AuthenticatedHeartbeat @0xe2fa13efd2e3a9dc {
heartbeat @0 :Data;
hmac @1 :Data;
}
编译后,我使用它:
static uint8_t beat[1024];
static uint8_t hmac[32] = {0xc2, 0xf1, 0x53, 0x12, 0x4b, 0x0c, 0xa4, 0xd1,
0x22, 0xf1, 0x64, 0x22, 0x1b, 0xbc, 0xa5, 0xd2,
0xe2, 0xf2, 0x75, 0x32, 0x2b, 0x3c, 0xa6, 0xd3,
0x72, 0xf1, 0x86, 0x42, 0x6b, 0x7c, 0xa7, 0xd4};
static uint8_t auth[1024];
int main(void) {
int packed_size;
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
Heartbeat_ptr hb = new_Heartbeat(cs);
Heartbeat_set_temperature(hb, 0x25);
capn_setp(capn_root(&root), 0, hb.p);
packed_size = capn_write_mem(&root, beat, sizeof(beat), 1/*packed*/);
printf("BEAT: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
print_buffer(beat, packed_size);
//HMAC_calc(beat, packed_size, hmac);
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
AuthenticatedHeartbeat_ptr ahb = new_AuthenticatedHeartbeat(cs);
AuthenticatedHeartbeat_set_heartbeat(ahb, buf_to_data(beat, packed_size));
AuthenticatedHeartbeat_set_hmac(ahb, buf_to_data(hmac, 32));
capn_setp(capn_root(&root), 0, ahb.p);
packed_size = capn_write_mem(&root, auth, sizeof(auth), 1/*packed*/);
printf("AUTH: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
print_buffer(auth, packed_size);
}
我写了一个辅助函数,就像示例中提供的 chars_to_text
函数一样
static capn_data buf_to_data(char *buf, const int len) {
return (capn_data) {{
.type = CAPN_NULL,
.has_ptr_tag = 0,
.is_list_member = 0,
.is_composite_list = 0,
.datasz = 0,
.ptrs = 0,
.len = len,
.data = buf,
.seg = NULL,
}};
}
但我想我遗漏了一些部分。 结果数据
BEAT: max_unpacked_size=24, packed_size=6
[ 0] - 10021001 - ....
[ 1] - 01250000 - .%
AUTH: max_unpacked_size=32, packed_size=6
[ 0] - 10034002 - ..@.
[ 1] - 00010000 - ..
至少在认证数据中不再包含温度 (0x25
)。此外,HMAC 不存在,长度太短了。
能否请您提示我如何处理 capn_data
blob、如何填充它以及如何将其打包到根目录中。
终于在 this closed issue 中找到了一个提示,这在我一开始的研究中是不可见或被忽视的...
我使用此代码序列化 capn_data
(这替换了原始问题中的较低范围):
{
struct capn root;
capn_init_malloc(&root);
capn_ptr cr = capn_root(&root);
struct capn_segment *cs = cr.seg;
capn_list8 list8 = capn_new_list8(cs, packed_size);
capn_setv8(list8, 0, beat, packed_size);
capn_list8 list9 = capn_new_list8(cs, 32);
capn_setv8(list9, 0, hmac, 32);
struct AuthenticatedHeartbeat s_ahb;
s_ahb.heartbeat.p = list8.p;
s_ahb.hmac.p = list9.p;
AuthenticatedHeartbeat_ptr pahb = new_AuthenticatedHeartbeat(cs);
write_AuthenticatedHeartbeat(&s_ahb, pahb);
capn_setp(capn_root(&root), 0, pahb.p);
packed_size = capn_write_mem(&root, auth, sizeof(auth), 1/*packed*/);
printf("AUTH: max_unpacked_size=%d, packed_size=%d\n", capn_size(&root), packed_size);
capn_free(&root);
}
因此,首先创建一个“列表”,稍后用作 capn_data
,因为这两个与 @eqvinox 所述基本相同。
不再需要 buf_to_data()
功能。
作为参考,这是反序列化数据的示例代码:
{
struct capn root;
capn_init_mem(&root, auth, packed_size, 1/*packed*/);
AuthenticatedHeartbeat_ptr ahbp;
ahbp.p = capn_getp(capn_root(&root), 0, 1);
capn_data dhb = AuthenticatedHeartbeat_get_heartbeat(ahbp);
capn_data dhmac = AuthenticatedHeartbeat_get_hmac(ahbp);
printf("dhb ptr=%p, len=%d\n", dhb.p.data, dhb.p.len);
printf("dhmac ptr=%p, len=%d\n", dhmac.p.data, dhmac.p.len);
unpacked_size = dhb.p.len;
hmac2_size = dhmac.p.len;
memcpy(beat2, dhb.p.data, unpacked_size);
memcpy(hmac2, dhmac.p.data, hmac2_size);
capn_free(&root);
}
{
struct capn root;
capn_init_mem(&root, beat2, unpacked_size, 1/*packed*/);
Heartbeat_ptr hbp;
hbp.p = capn_getp(capn_root(&root), 0, 1);
uint32_t temperature = Heartbeat_get_temperature(hbp);
printf("DESER: temperature=%x\n", temperature);
capn_free(&root);
}