skip to content
==> tests/wire.c <==
1/* place.rs frames_round_trip. */
2#include "mesh/abi/peer_frames.h"
3#include "mesh/abi/peer_sizes.h"
4#include "mesh/abi/place_ops.h"
5#include "mesh/check.h"
6#include "mesh/place_wire.h"
7
8#include <stdlib.h>
9
10static mpw_place place_msg(const mpw_bytes *b) {
11    CHECK(b->b[0] == MESH_F_PLACE);
12    size_t n;
13    char *err = NULL;
14    CHECK(mpw_place_rest_len(b->b + 1, &n, &err));
15    CHECK(b->n == 1 + MPW_PLACE_HEAD + n);
16    mpw_place m;
17    CHECK(mpw_place_decode(b->b + 1, b->b + 1 + MPW_PLACE_HEAD, n, &m, &err));
18    return m;
19}
20
21static bool place_eq(const mpw_place *a, const mpw_place *b) {
22    return a->op == b->op && a->id == b->id && !strcmp(a->name, b->name) && mpm_mode_eq(&a->mode, &b->mode) && a->aux == b->aux && a->nbytes == b->nbytes &&
23           (!a->nbytes || !memcmp(a->bytes, b->bytes, a->nbytes));
24}
25
26int main(void) {
27    uint8_t three[] = {1, 2, 3};
28    mpw_place p = {.op = MESH_PL_SET, .id = 7, .name = "doom", .mode = mpm_split(mpm_assign_new((uint32_t[]){2, 0, 1, 1}, 4)), .aux = 77, .bytes = three, .nbytes = 3};
29    mpw_bytes e = mpw_place_encode(&p);
30    mpw_place d = place_msg(&e);
31    CHECK(place_eq(&d, &p));
32    mpw_place_free(&d);
33    mpw_place q = {.op = MESH_PL_REQ, .id = 8, .name = "doom", .mode = mpm_pin(5), .aux = MPW_AUX_AUTO | 7};
34    mpw_bytes eq = mpw_place_encode(&q);
35    d = place_msg(&eq);
36    CHECK(place_eq(&d, &q));
37    mpw_place_free(&d);
38    mpw_bytes_free(&eq);
39    uint8_t st[12], data[64];
40    memset(st, 9, sizeof st), memset(data, 5, sizeof data);
41    mpw_frame f = {.name = "doom", .frame = 99, .parts = 3, .sys = 2, .state = st, .nstate = 12, .data = data, .ndata = 64};
42    mpw_bytes fe = mpw_frame_encode(&f);
43    CHECK(fe.b[0] == MESH_F_FRAME);
44    size_t n;
45    char *err = NULL;
46    CHECK(mpw_frame_rest_len(fe.b + 1, &n, &err) && fe.n == 1 + MPW_FRAME_HEAD + n);
47    mpw_frame g;
48    CHECK(mpw_frame_decode(fe.b + 1, fe.b + 1 + MPW_FRAME_HEAD, n, &g, &err));
49    CHECK(!strcmp(g.name, "doom") && g.frame == 99 && g.parts == 3 && g.sys == 2 && g.nstate == 12 && g.ndata == 64 && !memcmp(g.state, st, 12) && !memcmp(g.data, data, 64));
50    mpw_frame_free(&g);
51    mpw_bytes_free(&fe);
52    mpw_bytes in = mpw_input_encode("doom", (const uint8_t *)"wasd", 4);
53    CHECK(in.b[0] == MESH_F_INPUT && mpw_input_len(in.b + 1, &n, &err) && n == 4 && !memcmp(in.b + 1 + MPW_INPUT_HEAD, "wasd", 4));
54    mpw_bytes_free(&in);
55    /* Bounds: a hostile length is refused before anything is read. */
56    mpw_bytes big = mpw_place_encode(&p);
57    uint32_t over = MESH_F_PLACE_MAX + 1;
58    memcpy(big.b + 1 + MPW_PLACE_HEAD - 4, &over, 4);
59    CHECK(!mpw_place_rest_len(big.b + 1, &n, &err));
60    free(err);
61    mpw_bytes_free(&big);
62    mpw_bytes bad = mpw_place_encode(&p);
63    uint32_t op = 99;
64    memcpy(bad.b + 1, &op, 4);
65    CHECK(!mpw_place_decode(bad.b + 1, NULL, 0, &d, &err));
66    CHECK_S(err, "F_PLACE: bad op 99");
67    free(err);
68    mpw_bytes_free(&bad);
69    uint8_t huge[MESH_F_INPUT_MAX + 1] = {0};
70    mpw_bytes hi = mpw_input_encode("doom", huge, sizeof huge);
71    CHECK(!mpw_input_len(hi.b + 1, &n, &err));
72    free(err);
73    mpw_bytes_free(&hi);
74    uint8_t nm[MESH_NAME_BYTES];
75    mpw_name16("Doom", nm);
76    char out[MESH_NAME_BYTES + 1];
77    CHECK(!mpw_name_of(nm, MESH_NAME_BYTES, out, &err));
78    CHECK_S(err, "bad program name \"Doom\"");
79    free(err);
80    mpw_name16("a-1", nm);
81    CHECK(mpw_name_of(nm, MESH_NAME_BYTES, out, &err) && !strcmp(out, "a-1") && nm[3] == 0);
82    mpw_bytes_free(&e);
83    return mesh_check_done();
84}