2023-06-21 21:26:24 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <glacier/container/pair.h>
|
|
|
|
#include <glacier/status/error_or.h>
|
|
|
|
#include <zcall.h>
|
|
|
|
#include <ztypes.h>
|
|
|
|
|
|
|
|
class EndpointClient {
|
|
|
|
public:
|
|
|
|
static EndpointClient AdoptEndpoint(z_cap_t cap);
|
|
|
|
|
|
|
|
template <typename Req, typename Resp>
|
|
|
|
glcr::ErrorOr<glcr::Pair<Resp, z_cap_t>> CallEndpoint(const Req& req);
|
|
|
|
|
2023-06-22 02:19:16 -07:00
|
|
|
z_cap_t GetCap() { return cap_; }
|
|
|
|
|
2023-06-21 21:26:24 -07:00
|
|
|
private:
|
|
|
|
EndpointClient(uint64_t cap) : cap_(cap) {}
|
|
|
|
z_cap_t cap_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename Req, typename Resp>
|
|
|
|
glcr::ErrorOr<glcr::Pair<Resp, z_cap_t>> EndpointClient::CallEndpoint(
|
|
|
|
const Req& req) {
|
|
|
|
uint64_t reply_port_cap;
|
|
|
|
RET_ERR(ZEndpointSend(cap_, sizeof(Req), &req, &reply_port_cap));
|
|
|
|
|
|
|
|
Resp resp;
|
|
|
|
z_cap_t cap = 0;
|
|
|
|
uint64_t num_caps = 1;
|
|
|
|
uint64_t num_bytes = sizeof(Resp);
|
|
|
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &num_bytes, &resp, &num_caps, &cap));
|
|
|
|
|
|
|
|
if (num_bytes != sizeof(resp) || num_caps != 1) {
|
|
|
|
return glcr::FAILED_PRECONDITION;
|
|
|
|
}
|
|
|
|
|
|
|
|
return glcr::Pair{resp, cap};
|
|
|
|
}
|