skip to content
==> src/frame.c <==
1/* blobd.rs's blob frames: the bytes it writes (ack, push, get, answer) and how it reads them. */
2#include "mesh/blobs/frame.h"
3#include "mesh/abi/peer_frames.h"
4
5#include <string.h>
6
7static void u32le(msb *o, uint32_t v) {
8    uint8_t b[4];
9    for (int i = 0; i < 4; i++) b[i] = (uint8_t)(v >> 8 * i);
10    msb_put(o, b, 4);
11}
12
13static void u64le(msb *o, uint64_t v) {
14    uint8_t b[8];
15    for (int i = 0; i < 8; i++) b[i] = (uint8_t)(v >> 8 * i);
16    msb_put(o, b, 8);
17}
18
19void mbf_put(msb *o, const mj_hash *h, mj_job_id job, const void *bytes, uint32_t n) {
20    msb_putc(o, (char)MESH_F_BLOB_PUT);
21    u32le(o, 44 + n);
22    msb_put(o, h->b, 32);
23    u64le(o, job);
24    u32le(o, n);
25    msb_put(o, bytes, n);
26}
27
28void mbf_ack(msb *o, const mj_hash *h, bool ok, mj_job_id job) {
29    msb_putc(o, (char)MESH_F_BLOB_ACK);
30    u32le(o, 44);
31    msb_put(o, h->b, 32);
32    u32le(o, ok ? 1 : 0);
33    u64le(o, job);
34}
35
36void mbf_get(msb *o, const mj_hash *h, mj_job_id job) {
37    msb_putc(o, (char)MESH_F_BLOB_GET);
38    u32le(o, 40);
39    msb_put(o, h->b, 32);
40    u64le(o, job);
41}
42
43void mbf_blob(msb *o, const mj_hash *h, const void *bytes, size_t n, bool found) {
44    msb_putc(o, (char)MESH_F_BLOB);
45    u32le(o, (uint32_t)(36 + (found ? n : 0)));
46    msb_put(o, h->b, 32);
47    u32le(o, found ? 1 : 0);
48    if (found) msb_put(o, bytes, n);
49}
50
51static bool u32_at(const uint8_t *b, size_t n, size_t o, uint32_t *v) {
52    if (n < o + 4) return false;
53    *v = (uint32_t)b[o] | (uint32_t)b[o + 1] << 8 | (uint32_t)b[o + 2] << 16 | (uint32_t)b[o + 3] << 24;
54    return true;
55}
56
57static bool u64_at(const uint8_t *b, size_t n, size_t o, uint64_t *v) {
58    if (n < o + 8) return false;
59    uint64_t x = 0;
60    for (int i = 7; i >= 0; i--) x = x << 8 | b[o + (size_t)i];
61    *v = x;
62    return true;
63}
64
65bool mbf_decode(uint8_t ty, const uint8_t *b, size_t n, mbf_body *out) {
66    memset(out, 0, sizeof *out);
67    if (n < 32) return false;
68    memcpy(out->hash.b, b, 32);
69    uint32_t v;
70    switch (ty) {
71    case MESH_F_BLOB_PUT:
72        if (!u64_at(b, n, 32, &out->job) || !u32_at(b, n, 40, &out->len)) return false;
73        out->bytes = b + 44;
74        out->nbytes = n - 44;
75        return true;
76    case MESH_F_BLOB_ACK:
77        if (!u32_at(b, n, 32, &v) || !u64_at(b, n, 36, &out->job)) return false;
78        out->ok = v != 0;
79        return true;
80    case MESH_F_BLOB_GET: return true;
81    case MESH_F_BLOB:
82        out->ok = u32_at(b, n, 32, &v) && v != 0;
83        if (out->ok) {
84            out->bytes = b + 36;
85            out->nbytes = n - 36;
86        }
87        return true;
88    default: return false;
89    }
90}