Add MSRPC client and fix server code
authorSam Thursfield <samthursfield@codethink.co.uk>
Wed, 18 May 2011 14:25:07 +0000 (15:25 +0100)
committerSam Thursfield <samthursfield@codethink.co.uk>
Fri, 20 May 2011 13:59:22 +0000 (14:59 +0100)
Makefile.am
src/moonshot-msrpc-server.vala
src/moonshot-msrpc-vala.c [new file with mode: 0644]
src/moonshot-msrpc-vala.h [new file with mode: 0644]
src/moonshot-msrpc.idl
src/moonshot-msrpc.vapi
src/msrpc-client.vala [new file with mode: 0644]

index 82e7a3e..ca7e12f 100644 (file)
@@ -37,8 +37,20 @@ noinst_HEADERS = src/moonshot-msrpc.h
 src_moonshot_SOURCES += \
         src/moonshot-msrpc-server.vala \
         src/moonshot-msrpc_s.c \
+        src/moonshot-msrpc-vala.c \
         src/moonshot-msrpc.vapi
 
+bin_PROGRAMS += src/msrpc-client
+
+src_msrpc_client_SOURCES = \
+        src/msrpc-client.vala \
+        src/moonshot-msrpc_c.c \
+        src/moonshot-msrpc-vala.c \
+        src/moonshot-msrpc.vapi
+
+src_msrpc_client_LDADD = \
+        $(moonshot_LIBS)
+
 BUILT_SOURCES = src/moonshot-msrpc.h src/moonshot-msrpc_s.c src/moonshot-msrpc_c.c
 
 DISTCLEANFILES = ${BUILT_SOURCES}
index ff718d2..937f616 100644 (file)
@@ -8,25 +8,22 @@ using MoonshotRpcInterface;
 public class IdentityRequest : Object {
     private Rpc.AsyncCall call;
     private MainWindow main_window;
-    private char **p_identity;
-    private char **p_password;
-    private char **p_service;
+    private Identity **result;
 
     public IdentityRequest (Rpc.AsyncCall _call,
                             Gtk.Window window,
-                            char **_p_identity,
-                            char **_p_password,
-                            char **_p_service)
+                            Identity **_result)
     {
         call = _call;
-        p_identity = _p_identity;
-        p_password = _p_password;
-        p_service = _p_service;
+        main_window = (MainWindow)window;
+        result = _result;
     }
 
     public bool main_loop_cb ()
     {
-        main_window.set_callback (id_card_selected_cb);
+        // Execution is passed from the RPC get_identity() call to
+        // here, where we are inside the main loop thread.
+        main_window.set_callback (this.id_card_selected_cb);
         return false;
     }
 
@@ -34,9 +31,16 @@ public class IdentityRequest : Object {
     {
         var id_card = this.main_window.selected_id_card_widget.id_card;
 
-        *p_identity = "identity";
-        *p_password = id_card.password;
-        *p_service = "certificate";
+        *result = new Identity();
+
+        (*result)->identity = "identity";
+        (*result)->password = id_card.password;
+        (*result)->service = "certificate";
+
+        call.return (null);
+
+        //delete result;
+
         return false;
     }
 }
@@ -49,7 +53,6 @@ public class IdentityRequest : Object {
  * Shutdown is automatically done by the RPC runtime when the
  * process ends
  */
-
 public class MoonshotServer : Object {
     private static int counter;
     private static MainWindow main_window;
@@ -85,15 +88,9 @@ public class MoonshotServer : Object {
                                               string in_identity,
                                               string in_password,
                                               string in_service,
-                                              char **out_identity,
-                                              char **out_password,
-                                              char **out_service)
+                                              Identity **result)
     {
-        IdentityRequest request = new IdentityRequest (call,
-                                                       main_window,
-                                                       out_identity,
-                                                       out_password,
-                                                       out_service);
+        IdentityRequest request = new IdentityRequest (call, main_window, result);
 
         // Pass execution to the main loop thread
         Idle.add (request.main_loop_cb);
diff --git a/src/moonshot-msrpc-vala.c b/src/moonshot-msrpc-vala.c
new file mode 100644 (file)
index 0000000..2d29f82
--- /dev/null
@@ -0,0 +1,16 @@
+/* Allocation functions required to bind the MSRPC interface to
+ * Vala: these functions are required for all structs/classes that
+ * are accessed from inside Vala.
+ */
+
+#include "moonshot-msrpc.h"
+
+MoonshotRpcInterfaceIdentity *moonshot_rpc_interface_identity_new () {
+    MoonshotRpcInterfaceIdentity *data = MIDL_user_allocate (sizeof (MoonshotRpcInterfaceIdentity));
+    memset (data, 0, sizeof(MoonshotRpcInterfaceIdentity));
+    return data;
+}
+
+void moonshot_rpc_interface_identity_free (MoonshotRpcInterfaceIdentity *data) {
+    MIDL_user_free (data);
+}
diff --git a/src/moonshot-msrpc-vala.h b/src/moonshot-msrpc-vala.h
new file mode 100644 (file)
index 0000000..12b7b81
--- /dev/null
@@ -0,0 +1,6 @@
+/* Helper .h file for inclusion in Vala-generated C code */
+
+#include "moonshot-msrpc.h"
+
+MoonshotRpcInterfaceIdentity *moonshot_rpc_interface_identity_new ();
+void moonshot_rpc_interface_identity_free (MoonshotRpcInterfaceIdentity *data);
index 7174418..5c1f2bf 100644 (file)
@@ -6,15 +6,21 @@ interface moonshot
 {
     int moonshot_ping ([in, string] const char *message);
 
-    /* The DBus API returns the 3 output parameters as an array. MSRPC
-     * and Vala combine to make this very difficult; easier to use
-     * output parameters.
+    /* Returning arrays in MSRPC is difficult, because it's hard to
+     * get it to understand the size of the array and still have the
+     * C code bindable in Vala. A struct is more practical.
+     * Output parameters are also much more practical than function
+     * return values.
      */
-    void moonshot_get_identity ([in, string] const char *in_identity,
-                                [in, string] const char *in_password,
-                                [in, string] const char *in_service,
-                                [out, string] char **out_identity,
-                                [out, string] char **out_password,
-                                [out, string] char **out_service);
+    typedef struct {
+        [ref, string] char *identity;
+        [ref, string] char *password;
+        [ref, string] char *service;
+    } MoonshotRpcInterfaceIdentity;
+
+    void moonshot_get_identity ([in, string] const char *identity,
+                                [in, string] const char *password,
+                                [in, string] const char *service,
+                                [out] MoonshotRpcInterfaceIdentity **result);
 }
 
index a346883..a4999bb 100644 (file)
@@ -2,8 +2,7 @@
 
 using Rpc;
 
-[CCode (cheader_filename = "moonshot-msrpc.h")]
-
+[CCode (cheader_filename = "moonshot-msrpc-vala.h")]
 namespace MoonshotRpcInterface {
     [CCode (cname = "moonshot_v1_0_s_ifspec")]
     public const InterfaceHandle spec;
@@ -11,14 +10,22 @@ namespace MoonshotRpcInterface {
     [CCode (cname = "moonshot_binding_handle")]
     public BindingHandle binding_handle;
 
+    [CCode (cname = "MoonshotRpcInterfaceIdentity")]
+    [Compact]
+    public class Identity {
+        public Identity() {}
+        public string identity;
+        public string password;
+        public string service;
+    }
+
     [CCode (cname = "moonshot_ping")]
-    public int ping (string message);
+    public extern int ping (string message);
 
-    [CCode (cname = "moonshot_get_message")]
-    public void moonshot_get_identity (string in_identity,
-                                       string in_password,
-                                       string in_service,
-                                       char **out_identity,
-                                       char **out_password,
-                                       char **out_service);
+    [CCode (cname = "moonshot_get_identity")]
+    public extern void get_identity (Rpc.AsyncCall call,
+                                     string in_identity,
+                                     string in_password,
+                                     string in_service,
+                                     MoonshotRpcInterface.Identity **identity);
 }
diff --git a/src/msrpc-client.vala b/src/msrpc-client.vala
new file mode 100644 (file)
index 0000000..43a5081
--- /dev/null
@@ -0,0 +1,27 @@
+using Rpc;
+using MoonshotRpcInterface;
+
+void main () {
+    Rpc.client_bind (ref MoonshotRpcInterface.binding_handle, "/org/janet/Moonshot");
+
+    int pong = ping ("Hello from Vala");
+    stdout.printf ("%d\n", pong);
+
+    Identity *id = null;
+    Rpc.AsyncCall call = Rpc.AsyncCall();
+    get_identity (call, "identity", "username", "pass", &id);
+
+    call.complete ();
+
+    if (id == null)
+        /* FIXME: this is happening when moonshot crashes instead
+         * of returning a result - surely RpcAsyncCompleteCall should
+         * *tell* us that the call failed !
+         */
+        error ("Call failed but error was not raised\n");
+    else
+        stdout.printf ("%s %s %s\n", id->identity, id->password, id->service);
+
+    Rpc.client_unbind (ref MoonshotRpcInterface.binding_handle);
+}
+