#pragma once #include #include #include #include #include namespace mmth { class EndpointClient { public: EndpointClient() = delete; EndpointClient(const EndpointClient&) = delete; EndpointClient& operator=(const EndpointClient&) = delete; static glcr::UniquePtr AdoptEndpoint(z_cap_t cap); template glcr::ErrorOr> CallEndpointGetCap(const Req& req); template glcr::ErrorOr CallEndpoint(const Req& req); z_cap_t GetCap() const { return cap_; } private: EndpointClient(uint64_t cap) : cap_(cap) {} z_cap_t cap_; }; template glcr::ErrorOr> EndpointClient::CallEndpointGetCap( const Req& req) { uint64_t reply_port_cap; RET_ERR(ZEndpointSend(cap_, sizeof(Req), &req, 0, nullptr, &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}; } template glcr::ErrorOr EndpointClient::CallEndpoint(const Req& req) { uint64_t reply_port_cap; RET_ERR(ZEndpointSend(cap_, sizeof(Req), &req, 0, nullptr, &reply_port_cap)); Resp resp; uint64_t num_bytes = sizeof(Resp); uint64_t num_caps = 0; RET_ERR( ZReplyPortRecv(reply_port_cap, &num_bytes, &resp, &num_caps, nullptr)); if (num_bytes != sizeof(resp)) { return glcr::FAILED_PRECONDITION; } return resp; } } // namespace mmth