==> 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}