diff --git a/projects/miragesdk/src/Dockerfile b/projects/miragesdk/src/Dockerfile index bca509aef..5ec0ab67e 100644 --- a/projects/miragesdk/src/Dockerfile +++ b/projects/miragesdk/src/Dockerfile @@ -18,7 +18,7 @@ RUN which capnp ### SDK #FROM ocaml/opam@sha256:b42566186327141d715c212da3057942bd4cfa5503a87733d366835fa2ddf98d -FROM ocaml/opam:alpine-3.5_ocaml-4.04.0 as sdk +FROM ocaml/opam:alpine-3.5_ocaml-4.05.0 as sdk COPY --from=capnp /usr/local/bin/capnp /usr/local/bin/ COPY --from=capnp /usr/local/bin/capnpc /usr/local/bin/ @@ -31,22 +31,17 @@ RUN sudo mkdir -p /src USER opam WORKDIR /src -RUN git -C /home/opam/opam-repository fetch origin && \ - git -C /home/opam/opam-repository reset 092a9a66 --hard && \ - opam update -u - -# capnp -RUN opam pin add -n mirage-flow.dev --dev -RUN opam pin add -n capnp.dev 'https://github.com/talex5/capnp-ocaml.git#interfaces2' -RUN opam pin add -n capnp-rpc.dev 'https://github.com/mirage/capnp-rpc.git' -RUN opam pin add -n capnp-rpc-lwt.dev 'https://github.com/mirage/capnp-rpc.git' +RUN git -C /home/opam/opam-repository fetch && \ + git -C /home/opam/opam-repository reset ac26509c --hard && \ + opam update COPY sdk.opam /src RUN sudo chown opam -R /src RUN opam pin add sdk.local /src -n RUN opam depext -y alcotest sdk -RUN opam install alcotest && opam install --deps sdk -t +RUN opam install alcotest mtime +RUN opam install --deps sdk RUN opam list @@ -60,9 +55,6 @@ RUN opam update sdk && opam install sdk -t FROM sdk as dhcp-client # charrua -RUN opam pin add -n charrua-client.dev https://github.com/mirage/charrua-core.git -RUN opam pin add -n charrua-client-lwt.dev https://github.com/samoht/charrua-core.git#fix-build-and-tests -RUN opam pin add -n charrua-client-mirage.dev https://github.com/samoht/charrua-core.git#fix-build-and-tests COPY dhcp-client.opam /src RUN sudo chown opam -R /src diff --git a/projects/miragesdk/src/sdk/api.ml b/projects/miragesdk/src/sdk/api.ml index ab4116aac..99d1a509b 100644 --- a/projects/miragesdk/src/sdk/api.ml +++ b/projects/miragesdk/src/sdk/api.ml @@ -1 +1 @@ -include Proto.MakeRPC(Capnp.BytesMessage)(Capnp_rpc_lwt) +include Proto.MakeRPC(Capnp_rpc_lwt) diff --git a/projects/miragesdk/src/sdk/conf.ml b/projects/miragesdk/src/sdk/conf.ml index 0a1e672df..5569b7660 100644 --- a/projects/miragesdk/src/sdk/conf.ml +++ b/projects/miragesdk/src/sdk/conf.ml @@ -17,19 +17,15 @@ exception Undefined_field of int let err_not_found fmt = Fmt.kstrf (fun x -> Lwt.fail_invalid_arg x) fmt let failf fmt = Fmt.kstrf (fun x -> Lwt.fail_with x) fmt - -module R = Api.Reader.Conf -module B = Api.Builder.Conf - module Callback = struct let service f = - B.Callback.local @@ object (_: B.Callback.service) - inherit B.Callback.service - method f_impl req = - let module P = R.Callback.F_params in - let params = P.of_payload req in - let change = P.change_get params in + let open Api.Service.Conf.Callback in + local @@ object (_: service) + inherit service + method f_impl req release_param_caps = + let change = F.Params.change_get req in + release_param_caps (); Service.return_lwt (fun () -> f change >|= fun () -> Ok (Service.Response.create_empty ()) @@ -37,21 +33,20 @@ module Callback = struct end let client t change = - let module P = B.Callback.F_params in - let req, p = Capability.Request.create P.init_pointer in - P.change_set p change; - Capability.call_for_value t R.Callback.f_method req >>= function - | Ok _ -> Lwt.return () - | Error e -> failf "error: f(%s) -> %a" change Capnp_rpc.Error.pp e + let open Api.Client.Conf.Callback in + let req, p = Capability.Request.create F.Params.init_pointer in + F.Params.change_set p change; + Capability.call_for_value_exn t F.method_id req >|= + ignore end module Client (F: Flow.S) = struct - type t = R.t Capability.t + module Conf = Api.Client.Conf - let pp_error = Capnp_rpc.Error.pp + type t = Conf.t Capability.t let connect ~switch ?tags f = let ep = Capnp_rpc_lwt.Endpoint.of_flow ~switch (module F) f in @@ -59,18 +54,14 @@ module Client (F: Flow.S) = struct Capnp_rpc_lwt.CapTP.bootstrap client |> Lwt.return let find t path = - let module P = B.Read_params in - let req, p = Capability.Request.create P.init_pointer in - P.path_set_list p path |> ignore; - Capability.call_for_value t R.read_method req >>= function - | Error e -> failf "error read(%a): %a" pp_path path pp_error e - | Ok r -> - let module R = R.Response in - let r = R.of_payload r in - match R.get r with - | R.Ok data -> Lwt.return (Some data) - | R.NotFound -> Lwt.return None - | R.Undefined _ -> failf "invalid return" + let open Conf.Read in + let req, p = Capability.Request.create Params.init_pointer in + Params.path_set_list p path |> ignore; + Capability.call_for_value_exn t method_id req >>= fun r -> + match Results.get r with + | Ok data -> Lwt.return (Some data) + | NotFound -> Lwt.return None + | Undefined _ -> failf "invalid return" let get t path = find t path >>= function @@ -78,31 +69,24 @@ module Client (F: Flow.S) = struct | None -> err_not_found "get %a" pp_path path let set t path data = - let module P = B.Write_params in - let req, p = Capability.Request.create P.init_pointer in - P.path_set_list p path |> ignore; - P.data_set p data; - Capability.call_for_value t R.write_method req >>= function - | Ok _ -> Lwt.return () - | Error e -> failf "error write(%a): %a" pp_path path pp_error e + let open Conf.Write in + let req, p = Capability.Request.create Params.init_pointer in + Params.path_set_list p path |> ignore; + Params.data_set p data; + Capability.call_for_value_exn t method_id req >|= ignore let delete t path = - let module P = B.Delete_params in - let req, p = Capability.Request.create P.init_pointer in - P.path_set_list p path |> ignore; - Capability.call_for_value t R.delete_method req >>= function - | Ok _ -> Lwt.return () - | Error e -> failf "error delete(%a): %a" pp_path path pp_error e + let open Conf.Delete in + let req, p = Capability.Request.create Params.init_pointer in + Params.path_set_list p path |> ignore; + Capability.call_for_value_exn t method_id req >|= ignore let watch t path f = - let module P = B.Watch_params in - let req, p = Capability.Request.create P.init_pointer in - P.path_set_list p path |> ignore; - let callback = Capability.Request.export req (Callback.service f) in - P.callback_set p (Some callback); - Capability.call_for_value t R.watch_method req >>= function - | Ok _ -> Lwt.return () - | Error e -> failf "error watch(%a): %a" pp_path path pp_error e + let open Conf.Watch in + let req, p = Capability.Request.create Params.init_pointer in + Params.path_set_list p path |> ignore; + Params.callback_set p (Some (Callback.service f)); + Capability.call_for_value_exn t method_id req >|= ignore end @@ -123,7 +107,8 @@ module Server (F: Flow.S) = struct type op = [ `Read | `Write | `Delete ] - type t = R.t Capability.t + module Conf = Api.Service.Conf + type t = Conf.t Capability.t let infof fmt = Fmt.kstrf (fun msg () -> @@ -164,55 +149,54 @@ module Server (F: Flow.S) = struct | exception Not_found -> Service.fail "%s" (not_allowed key) let service ~switch ~routes db = - B.local @@ object (_ : B.service) - inherit B.service - method read_impl req = - let module P = R.Read_params in - let params = P.of_payload req in - let key = P.path_get_list params in + Conf.local @@ object (_ : Conf.service) + inherit Conf.service + method read_impl req release_param_caps = + let open Conf.Read in + let key = Params.path_get_list req in + release_param_caps (); with_permission_check ~routes `Read key @@ fun () -> Service.return_lwt (fun () -> - let module R = B.Response in - let resp, r = Service.Response.create R.init_pointer in + let resp, r = Service.Response.create Results.init_pointer in (KV.find db key >|= function - | None -> R.not_found_set r - | Some x -> R.ok_set r x + | None -> Results.not_found_set r + | Some x -> Results.ok_set r x ) >|= fun () -> Ok resp ) - method write_impl req = - let module P = R.Write_params in - let params = P.of_payload req in - let key = P.path_get_list params in - let value = P.data_get params in + method write_impl req release_param_caps = + let open Conf.Write in + let key = Params.path_get_list req in + let value = Params.data_get req in + release_param_caps (); with_permission_check ~routes `Write key @@ fun () -> Service.return_lwt (fun () -> write db key value >|= fun () -> Ok (Service.Response.create_empty ()) ) - method delete_impl req = - let module P = R.Delete_params in - let params = P.of_payload req in - let key = P.path_get_list params in + method delete_impl req release_param_caps = + let open Conf.Delete in + let key = Params.path_get_list req in + release_param_caps (); with_permission_check ~routes `Delete key @@ fun () -> Service.return_lwt (fun () -> delete db key >|= fun () -> Ok (Service.Response.create_empty ()) ) - method watch_impl req = - let module P = R.Watch_params in - let params = P.of_payload req in - let key = P.path_get_list params in - match P.callback_get params with - | None -> failwith "No watcher callback given" + method watch_impl req release_param_caps = + let open Conf.Watch in + let key = Params.path_get_list req in + let callback = Params.callback_get req in + release_param_caps (); + match callback with + | None -> Service.fail "No watcher callback given" | Some i -> - let callback = Payload.import req i in with_permission_check ~routes `Read key @@ fun () -> Service.return_lwt (fun () -> - watch ~switch db key (Callback.client callback) >|= fun () -> + watch ~switch db key (Callback.client i) >|= fun () -> Ok (Service.Response.create_empty ()) ) end diff --git a/projects/miragesdk/src/sdk/flow.ml b/projects/miragesdk/src/sdk/flow.ml index e1a2cea28..a047b6345 100644 --- a/projects/miragesdk/src/sdk/flow.ml +++ b/projects/miragesdk/src/sdk/flow.ml @@ -8,12 +8,10 @@ end module Client (F: S) = struct + module Flow = Api.Client.Flow + type 'a io = 'a Lwt.t - - module R = Api.Reader.Flow - module B = Api.Builder.Flow - - type t = R.t Capability.t + type t = Flow.t Capability.t type flow = t type buffer = Cstruct.t @@ -44,59 +42,57 @@ module Client (F: S) = struct Capnp_rpc_lwt.CapTP.bootstrap client |> Lwt.return let read_result r = - let module R = R.ReadResult in - match R.get (R.of_payload r) with + let module R = Flow.Read.Results in + match R.get r with | R.Data data -> Ok (`Data (Cstruct.of_string data)) | R.Eof -> Ok `Eof | R.Error s -> Error (`Msg s) | R.Undefined i -> Error (`Undefined i) - let read t = - let module P = B.Read_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value t R.read_method req >|= function - | Error e -> Error (`Capnp e) - | Ok r -> read_result r - let write_result r = - let module R = R.WriteResult in - match R.get (R.of_payload r) with + let module R = Flow.Write.Results in + match R.get r with | R.Ok -> Ok () | R.Closed -> Error `Closed | R.Error s -> Error (`Msg s) | R.Undefined i -> Error (`Undefined i) + let read t = + let open Flow.Read in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value t method_id req >|= function + | Error e -> Error (`Capnp e) + | Ok r -> read_result r + let write t buf = - let module P = B.Write_params in - let req, p = Capability.Request.create P.init_pointer in - P.buffer_set p (Cstruct.to_string buf); - Capability.call_for_value t R.write_method req >|= function + let open Flow.Write in + let req, p = Capability.Request.create Params.init_pointer in + Params.buffer_set p (Cstruct.to_string buf); + Capability.call_for_value t method_id req >|= function | Error e -> Error (`Capnp e) | Ok r -> write_result r let writev t bufs = - let module P = B.Writev_params in - let req, p = Capability.Request.create P.init_pointer in - ignore @@ P.buffers_set_list p (List.map Cstruct.to_string bufs); - Capability.call_for_value t R.writev_method req >|= function + let open Flow.Writev in + let req, p = Capability.Request.create Params.init_pointer in + Params.buffers_set_list p (List.map Cstruct.to_string bufs) |> ignore; + Capability.call_for_value t method_id req >|= function | Error e -> Error (`Capnp e) | Ok r -> write_result r let close t = - let module P = B.Close_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value t R.close_method req >|= fun _ -> - () + let open Flow.Close in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn t method_id req >|= ignore end module Server (F: S) (Local: S) = struct - module R = Api.Reader.Flow - module B = Api.Builder.Flow + module Flow = Api.Service.Flow let read_result result = - let module R = B.ReadResult in + let module R = Flow.Read.Results in let resp, r = Service.Response.create R.init_pointer in let () = match result with | Ok (`Data buf) -> R.data_set r (Cstruct.to_string buf) @@ -106,7 +102,7 @@ module Server (F: S) (Local: S) = struct Ok resp let write_result result = - let module R = B.WriteResult in + let module R = Flow.Write.Results in let resp, r = Service.Response.create R.init_pointer in let () = match result with | Ok () -> R.ok_set r @@ -116,36 +112,37 @@ module Server (F: S) (Local: S) = struct Ok resp let close_result () = - let module R = B.Close_results in + let module R = Flow.Close.Results in let resp, _ = Service.Response.create R.init_pointer in Ok resp let service t = - B.local @@ - object (_ : B.service) - inherit B.service + Flow.local @@ object (_ : Flow.service) + inherit Flow.service - method read_impl _req = + method read_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> Local.read t >|= read_result) - method write_impl req = - let module P = R.Write_params in - let params = P.of_payload req in - let buf = P.buffer_get params |> Cstruct.of_string in + method write_impl req release_param_caps = + let open Flow.Write in + let buf = Params.buffer_get req |> Cstruct.of_string in + release_param_caps (); Service.return_lwt (fun () -> Local.write t buf >|= write_result) - method writev_impl req = - let module P = R.Writev_params in - let params = P.of_payload req in - let bufs = P.buffers_get_list params |> List.map Cstruct.of_string in + method writev_impl req release_param_caps = + let open Flow.Writev in + let bufs = Params.buffers_get_list req |> List.map Cstruct.of_string in + release_param_caps (); Service.return_lwt (fun () -> Local.writev t bufs >|= write_result) - method close_impl _req = + method close_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> Local.close t >|= close_result) end - type t = R.t Capability.t + type t = Flow.t Capability.t let listen ~switch ?tags service fd = let endpoint = Capnp_rpc_lwt.Endpoint.of_flow ~switch (module F) fd in diff --git a/projects/miragesdk/src/sdk/host.ml b/projects/miragesdk/src/sdk/host.ml index d1652a3a4..21f4f4b39 100644 --- a/projects/miragesdk/src/sdk/host.ml +++ b/projects/miragesdk/src/sdk/host.ml @@ -68,138 +68,117 @@ end open Lwt.Infix open Capnp_rpc_lwt -module R = Api.Reader.Host -module B = Api.Builder.Host - module Client (F: Flow.S) = struct - let pp_error = Capnp_rpc.Error.pp + module Host = Api.Client.Host - type t = R.t Capability.t - - let error e = Fmt.kstrf Lwt.fail_with "%a" pp_error e + type t = Host.t Capability.t let connect ~switch ?tags f = let ep = Capnp_rpc_lwt.Endpoint.of_flow ~switch (module F) f in let client = Capnp_rpc_lwt.CapTP.connect ~switch ?tags ep in Capnp_rpc_lwt.CapTP.bootstrap client |> Lwt.return - let intf_result r = - let module R = R.Intf_results in - R.intf_get (R.of_payload r) - let interface t = - let module P = B.Intf_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value t R.intf_method req >>= function - | Error e -> error e - | Ok r -> Lwt.return (intf_result r) - - let mac_result r = - let module R = R.Mac_results in - let mac = R.mac_get (R.of_payload r) in - Macaddr.of_string_exn mac + let open Host.Intf in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn t method_id req >|= + Host.Intf.Results.intf_get let mac t = - let module P = B.Mac_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value t R.mac_method req >>= function - | Error e -> error e - | Ok r -> Lwt.return (mac_result r) + let open Host.Mac in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn t method_id req >|= fun r -> + Macaddr.of_string_exn (Results.mac_get r) - let dhcp_options_result r = - let module R = R.DhcpOptions_results in - let options = R.options_get_list (R.of_payload r) in + let dhcp_options t = + let open Host.DhcpOptions in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn t method_id req >|= fun r -> + let options = Results.options_get_list r in List.fold_left (fun acc o -> match Dhcp_wire.string_to_option_code o with | None -> acc | Some o -> o :: acc ) [] options - let dhcp_options t = - let module P = B.DhcpOptions_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value t R.dhcp_options_method req >>= function - | Error e -> error e - | Ok r -> Lwt.return (dhcp_options_result r) - let set_ip t ip = - let module P = B.SetIp_params in - let req, p = Capability.Request.create P.init_pointer in - P.ip_set p (Ipaddr.V4.to_string ip); - Capability.call_for_value t R.set_ip_method req >>= function - | Error e -> error e - | Ok _ -> Lwt.return () + let open Host.SetIp in + let req, p = Capability.Request.create Params.init_pointer in + Params.ip_set p (Ipaddr.V4.to_string ip); + Capability.call_for_value_exn t method_id req >|= + ignore let set_gateway t ip = - let module P = B.SetGateway_params in - let req, p = Capability.Request.create P.init_pointer in - P.ip_set p (Ipaddr.V4.to_string ip); - Capability.call_for_value t R.set_gateway_method req >>= function - | Error e -> error e - | Ok _r -> Lwt.return () + let open Host.SetGateway in + let req, p = Capability.Request.create Params.init_pointer in + Params.ip_set p (Ipaddr.V4.to_string ip); + Capability.call_for_value_exn t method_id req >|= + ignore end module Server (F: Flow.S) (N: S) = struct - type t = B.t Capability.t + module Host = Api.Service.Host + + type t = Host.t Capability.t let mac_result result = - let module R = B.Mac_results in + let module R = Host.Mac.Results in let resp, r = Service.Response.create R.init_pointer in R.mac_set r (Macaddr.to_string result); Ok resp let intf_result result = - let module R = B.Intf_results in + let module R = Host.Intf.Results in let resp, r = Service.Response.create R.init_pointer in R.intf_set r result; Ok resp let dhcp_options_result result = - let module R = B.DhcpOptions_results in + let module R = Host.DhcpOptions.Results in let resp, r = Service.Response.create R.init_pointer in let result = List.map Dhcp_wire.option_code_to_string result in let _ = R.options_set_list r result in Ok resp let service t = - B.local @@ - object (_ : B.service) - inherit B.service + Host.local @@ object (_ : Host.service) + inherit Host.service - method intf_impl _req = + method intf_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> N.interface t >|= intf_result) - method mac_impl _req = + method mac_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> N.mac t >|= mac_result) - method dhcp_options_impl _req = + method dhcp_options_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> N.dhcp_options t >|= dhcp_options_result) - method set_ip_impl req = - let module P = R.SetIp_params in - let params = P.of_payload req in - let ip = P.ip_get params in + method set_ip_impl req release_param_caps = + let open Host.SetIp in + let ip = Params.ip_get req in + release_param_caps (); Service.return_lwt (fun () -> - let module R = B.SetIp_results in - let resp, _ = Service.Response.create R.init_pointer in + let resp, _ = Service.Response.create Results.init_pointer in match Ipaddr.V4.of_string ip with - | None ->Lwt.fail_invalid_arg "invalid ip" + | None -> Lwt.fail_with "invalid ip" | Some ip -> N.set_ip t ip >|= fun () -> Ok resp ) - method set_gateway_impl req = - let module P = R.SetGateway_params in - let params = P.of_payload req in - let ip = P.ip_get params in + method set_gateway_impl req release_param_caps = + let open Host.SetGateway in + let ip = Params.ip_get req in + release_param_caps (); Service.return_lwt (fun () -> - let module R = B.SetGateway_results in - let resp, _ = Service.Response.create R.init_pointer in + let resp, _ = Service.Response.create Results.init_pointer in match Ipaddr.V4.of_string ip with - | None ->Lwt.fail_invalid_arg "invalid ip" - | Some ip -> N.set_ip t ip >|= fun () -> Ok resp + | None -> Lwt.fail_invalid_arg "invalid ip" + | Some ip -> N.set_gateway t ip >|= fun () -> Ok resp ) end diff --git a/projects/miragesdk/src/sdk/jbuild b/projects/miragesdk/src/sdk/jbuild index c2b9febb9..4888193ff 100644 --- a/projects/miragesdk/src/sdk/jbuild +++ b/projects/miragesdk/src/sdk/jbuild @@ -5,7 +5,7 @@ (public_name sdk) (flags (:standard -w -53-55)) (libraries (irmin irmin-mem lwt.unix rawlink charrua-core.wire - tuntap astring mirage-flow-lwt mirage-net-flow + tuntap astring mirage-flow-lwt mirage-flow-unix mirage-net-flow mirage-time-lwt mirage-flow-rawlink capnp capnp-rpc-lwt)))) (rule diff --git a/projects/miragesdk/src/sdk/net.ml b/projects/miragesdk/src/sdk/net.ml index 0fe380322..e7f05759a 100644 --- a/projects/miragesdk/src/sdk/net.ml +++ b/projects/miragesdk/src/sdk/net.ml @@ -1,46 +1,40 @@ open Lwt.Infix open Capnp_rpc_lwt -module B = Api.Builder.Net -module R = Api.Reader.Net - module type S = Mirage_net_lwt.S module Callback = struct let service f = - B.Callback.local @@ object (_: B.Callback.service) - inherit B.Callback.service - method f_impl req = - let module P = R.Callback.F_params in - let params = P.of_payload req in - let change = P.buffer_get params in + let open Api.Service.Net.Callback in + local @@ object (_: service) + inherit service + method f_impl req release_param_caps = + let change = F.Params.buffer_get req in + release_param_caps (); Service.return_lwt (fun () -> f (Cstruct.of_string change) >|= fun () -> Ok (Service.Response.create_empty ()) ) end - module F = Api.Reader.Conf.Callback - let client t change = - let module P = B.Callback.F_params in - let req, p = Capability.Request.create P.init_pointer in + let open Api.Client.Net.Callback in + let req, p = Capability.Request.create F.Params.init_pointer in let change = Cstruct.to_string change in - P.buffer_set p change; - Capability.call_for_value t R.Callback.f_method req >>= function - | Ok _ -> Lwt.return () - | Error e -> - Fmt.kstrf Lwt.fail_with "error: f(%s) -> %a" change Capnp_rpc.Error.pp e + F.Params.buffer_set p change; + Capability.call_for_value_exn t F.method_id req >|= ignore end module Client (F: Flow.S) = struct + module Net = Api.Client.Net + type 'a io = 'a Lwt.t type t = { - cap : R.t Capability.t; + cap : Net.t Capability.t; mac : Macaddr.t; stats: Mirage_net.stats; } @@ -62,49 +56,48 @@ module Client (F: Flow.S) = struct | `Capnp e -> Fmt.pf ppf "capnp: %a" Capnp_rpc.Error.pp e | #Mirage_device.error as e -> Mirage_device.pp_error ppf e - let result r = - let module R = R.Result in - match R.get (R.of_payload r) with - | R.Ok -> Ok () + let result r: (unit, error) result = + let module R = Net.Write.Results in + match R.get r with + | R.Ok -> Ok () | R.Unimplemented -> Error `Unimplemented | R.Disconnected -> Error `Disconnected | R.Error s -> Error (`Msg s) | R.Undefined i -> Error (`Undefined i) let write t buf = - let module P = B.Write_params in - let req, p = Capability.Request.create P.init_pointer in - P.buffer_set p (Cstruct.to_string buf); - Capability.call_for_value t.cap R.write_method req >|= function + let open Net.Write in + let req, p = Capability.Request.create Params.init_pointer in + Params.buffer_set p (Cstruct.to_string buf); + Capability.call_for_value t.cap method_id req >|= function | Error e -> Error (`Capnp e) | Ok r -> Mirage_net.Stats.tx t.stats (Int64.of_int @@ Cstruct.len buf); result r let writev t bufs = - let module P = B.Writev_params in - let req, p = Capability.Request.create P.init_pointer in - ignore @@ P.buffers_set_list p (List.map Cstruct.to_string bufs); - Capability.call_for_value t.cap R.writev_method req >|= function + let open Net.Writev in + let req, p = Capability.Request.create Params.init_pointer in + Params.buffers_set_list p (List.map Cstruct.to_string bufs) |> ignore; + Capability.call_for_value t.cap method_id req >|= function | Error e -> Error (`Capnp e) | Ok r -> Mirage_net.Stats.tx t.stats (Int64.of_int @@ Cstruct.lenv bufs); result r let listen t f = - let module P = B.Listen_params in - let req, p = Capability.Request.create P.init_pointer in - let callback = Capability.Request.export req (Callback.service f) in - P.callback_set p (Some callback); - Capability.call_for_value t.cap R.listen_method req >|= function + let open Net.Listen in + let req, p = Capability.Request.create Params.init_pointer in + Params.callback_set p (Some (Callback.service f)); + Capability.call_for_value t.cap method_id req >|= function | Ok _ -> Ok () | Error e -> Error (`Capnp e) let disconnect { cap; _ } = - let module P = B.Disconnect_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value cap R.disconnect_method req >|= fun _ -> - () + let open Net.Disconnect in + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn cap method_id req >|= + ignore let mac t = t.mac @@ -114,16 +107,13 @@ module Client (F: Flow.S) = struct Capnp_rpc_lwt.CapTP.bootstrap client |> Lwt.return let connect ~switch ?tags f = + let open Net.Mac in capability ~switch ?tags f >>= fun cap -> - let module P = B.Mac_params in - let req, _ = Capability.Request.create P.init_pointer in - Capability.call_for_value cap R.mac_method req >>= function - | Error e -> Fmt.kstrf Lwt.fail_with "%a" Capnp_rpc.Error.pp e - | Ok r -> - let module R = R.Mac_results in - let mac = R.mac_get (R.of_payload r) |> Macaddr.of_string_exn in - let stats = Mirage_net.Stats.create () in - Lwt.return { cap; mac; stats } + let req, _ = Capability.Request.create Params.init_pointer in + Capability.call_for_value_exn cap method_id req >|= fun r -> + let mac = Results.mac_get r |> Macaddr.of_string_exn in + let stats = Mirage_net.Stats.create () in + { cap; mac; stats } let reset_stats_counters t = Mirage_net.Stats.reset t.stats let get_stats_counters t = t.stats @@ -131,8 +121,10 @@ end module Server (F: Flow.S) (Local: Mirage_net_lwt.S) = struct + module Net = Api.Service.Net + let result x = - let module R = B.Result in + let module R = Net.Write.Results in let resp, r = Service.Response.create R.init_pointer in let () = match x with | Ok () -> R.ok_set r @@ -143,55 +135,54 @@ module Server (F: Flow.S) (Local: Mirage_net_lwt.S) = struct Ok resp let mac_result x = - let module R = B.Mac_results in + let module R = Net.Mac.Results in let resp, r = Service.Response.create R.init_pointer in R.mac_set r (Macaddr.to_string x); - Ok resp + resp let disconnect_result () = - let module R = B.Disconnect_results in + let module R = Net.Disconnect.Results in let resp, _ = Service.Response.create R.init_pointer in Ok resp let service t = - B.local @@ - object (_ : B.service) - inherit B.service + Net.local @@ object (_ : Net.service) + inherit Net.service - method disconnect_impl _req = + method disconnect_impl _req release_param_caps = + release_param_caps (); Service.return_lwt (fun () -> Local.disconnect t >|= disconnect_result) - method write_impl req = - let module P = R.Write_params in - let params = P.of_payload req in - let buf = P.buffer_get params |> Cstruct.of_string in + method write_impl req release_param_caps = + let open Net.Write in + let buf = Params.buffer_get req |> Cstruct.of_string in + release_param_caps (); Service.return_lwt (fun () -> Local.write t buf >|= result) - method writev_impl req = - let module P = R.Writev_params in - let params = P.of_payload req in - let bufs = P.buffers_get_list params |> List.map Cstruct.of_string in + method writev_impl req release_param_caps = + let open Net.Writev in + let bufs = Params.buffers_get_list req |> List.map Cstruct.of_string in + release_param_caps (); Service.return_lwt (fun () -> Local.writev t bufs >|= result) - method listen_impl req = - let module P = R.Listen_params in - let params = P.of_payload req in - match P.callback_get params with - | None -> failwith "No watcher callback given" + method listen_impl req release_param_caps = + let open Net.Listen in + let callback = Params.callback_get req in + release_param_caps (); + match callback with + | None -> Service.fail "No watcher callback given" | Some i -> - let callback = Payload.import req i in Service.return_lwt (fun () -> - Local.listen t (Callback.client callback) >|= result + Local.listen t (Callback.client i) >|= result ) - method mac_impl req = - let module P = R.Mac_params in - let _params = P.of_payload req in - Service.return_lwt (fun () -> Lwt.return (mac_result (Local.mac t))) + method mac_impl _req release_param_caps = + release_param_caps (); + Service.return (mac_result (Local.mac t)) end - type t = R.t Capability.t + type t = Net.t Capability.t let listen ~switch ?tags service fd = let endpoint = Capnp_rpc_lwt.Endpoint.of_flow ~switch (module F) fd in