zoap

A WiP CoAP implementation for bare-metal constrained devices in Zig

git clone https://git.8pit.net/zoap.git

 1const std = @import("std");
 2const pkt = @import("packet.zig");
 3const opts = @import("opts.zig");
 4const codes = @import("codes.zig");
 5
 6pub const ResourceHandler = fn (resp: *pkt.Response, req: *pkt.Request) codes.Code;
 7
 8// Size for reply buffer
 9const REPLY_BUFSIZ = 256;
10
11pub const Resource = struct {
12    path: []const u8,
13    handler: ResourceHandler,
14
15    pub fn matchPath(self: Resource, path: []const u8) bool {
16        return std.mem.eql(u8, self.path, path);
17    }
18};
19
20pub const Dispatcher = struct {
21    resources: []const Resource,
22    rbuf: [REPLY_BUFSIZ]u8 = undefined,
23
24    pub fn reply(self: *Dispatcher, req: *const pkt.Request, mt: pkt.Msg, code: codes.Code) !pkt.Response {
25        return pkt.Response.reply(&self.rbuf, req, mt, code);
26    }
27
28    pub fn dispatch(self: *Dispatcher, req: *pkt.Request) !pkt.Response {
29        const hdr = req.header;
30        if (hdr.type == pkt.Msg.con) {
31            // We are not able to process confirmable message presently
32            // thus *always* answer those with a reset with NOT_IMPL.
33            return self.reply(req, pkt.Msg.rst, codes.NOT_IMPL);
34        }
35
36        const path_opt = try req.findOption(opts.URIPath);
37        const path = path_opt.value;
38
39        for (self.resources) |res| {
40            if (!res.matchPath(path))
41                continue;
42
43            var resp = try self.reply(req, pkt.Msg.non, .{ .class = 0, .detail = 0 });
44            resp.setCode(res.handler(&resp, req));
45
46            return resp;
47        }
48
49        return self.reply(req, pkt.Msg.non, codes.NOT_FOUND);
50    }
51};