1
#include <droute/droute.h>
2
#include <glib.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6

            
7
#include "atspi/atspi.h"
8

            
9
#define TEST_OBJECT_PATH "/test/object"
10
#define TEST_INTERFACE_ONE "test.interface.One"
11
#define TEST_INTERFACE_TWO "test.interface.Two"
12

            
13
#define OBJECT_ONE "ObjectOne";
14
#define OBJECT_TWO "ObjectTwo";
15

            
16
#define STRING_ONE "StringOne"
17
#define STRING_TWO "StringTwo"
18

            
19
#define INT_ONE 0
20
#define INT_TWO 456
21

            
22
#define NONE_REPLY_STRING "NoneMethod"
23

            
24
const gchar *test_interface_One =
25
    "<interface name=\"test.interface.One\">"
26
    "  <method name=\"null\"/>"
27
    "  <method name=\"getInt\">"
28
    "    <arg direction=\"out\" type=\"o\"/>"
29
    "  </method>"
30
    "  <method name=\"setInt\">"
31
    "    <arg direction=\"in\" type=\"o\"/>"
32
    "  </method>"
33
    "  <method name=\"getString\">"
34
    "    <arg direction=\"out\" type=\"s\"/>"
35
    "  </method>"
36
    "  <method name=\"setString\">"
37
    "    <arg direction=\"in\" type=\"s\"/>"
38
    "  </method>"
39
    "</interface>";
40

            
41
const gchar *test_interface_Two =
42
    "<interface name=\"test.interface.One\">"
43
    "  <method name=\"null\"/>"
44
    "  <method name=\"getInt\">"
45
    "    <arg direction=\"out\" type=\"o\"/>"
46
    "  </method>"
47
    "  <method name=\"setInt\">"
48
    "    <arg direction=\"in\" type=\"o\"/>"
49
    "  </method>"
50
    "  <method name=\"getString\">"
51
    "    <arg direction=\"out\" type=\"s\"/>"
52
    "  </method>"
53
    "  <method name=\"setString\">"
54
    "    <arg direction=\"in\" type=\"s\"/>"
55
    "  </method>"
56
    "</interface>";
57

            
58
typedef struct _AnObject
59
{
60
  gchar *astring;
61
  guint *anint;
62
} AnObject;
63

            
64
static DBusConnection *bus;
65
static GMainLoop *main_loop;
66
static gboolean success = TRUE;
67

            
68
static DBusMessage *
69
1
impl_null (DBusConnection *bus, DBusMessage *message, void *user_data)
70
{
71
  DBusMessage *reply;
72

            
73
1
  reply = dbus_message_new_method_return (message);
74
1
  return reply;
75
}
76

            
77
static DBusMessage *
78
impl_getInt (DBusConnection *bus, DBusMessage *message, void *user_data)
79
{
80
  AnObject *object = (AnObject *) user_data;
81
  DBusMessage *reply;
82
  DBusError error;
83

            
84
  dbus_error_init (&error);
85

            
86
  reply = dbus_message_new_method_return (message);
87
  dbus_message_append_args (reply, DBUS_TYPE_INT32, &(object->anint), DBUS_TYPE_INVALID);
88
  return reply;
89
}
90

            
91
static DBusMessage *
92
impl_setInt (DBusConnection *bus, DBusMessage *message, void *user_data)
93
{
94
  AnObject *object = (AnObject *) user_data;
95
  DBusMessage *reply;
96
  DBusError error;
97

            
98
  dbus_error_init (&error);
99

            
100
  dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &(object->anint), DBUS_TYPE_INVALID);
101

            
102
  reply = dbus_message_new_method_return (message);
103
  return reply;
104
}
105

            
106
static DBusMessage *
107
impl_getString (DBusConnection *bus, DBusMessage *message, void *user_data)
108
{
109
  AnObject *object = (AnObject *) user_data;
110
  DBusMessage *reply;
111
  DBusError error;
112

            
113
  dbus_error_init (&error);
114

            
115
  reply = dbus_message_new_method_return (message);
116
  dbus_message_append_args (reply, DBUS_TYPE_STRING, &(object->astring), DBUS_TYPE_INVALID);
117
  return reply;
118
}
119

            
120
static DBusMessage *
121
impl_setString (DBusConnection *bus, DBusMessage *message, void *user_data)
122
{
123
  AnObject *object = (AnObject *) user_data;
124
  DBusMessage *reply;
125
  DBusError error;
126

            
127
  dbus_error_init (&error);
128

            
129
  g_free (object->astring);
130
  dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &(object->astring), DBUS_TYPE_INVALID);
131

            
132
  reply = dbus_message_new_method_return (message);
133
  return reply;
134
}
135

            
136
static DBusMessage *
137
1
impl_getInterfaceOne (DBusConnection *bus, DBusMessage *message, void *user_data)
138
{
139
  DBusMessage *reply;
140
  DBusError error;
141
1
  gchar *itf = TEST_INTERFACE_ONE;
142

            
143
1
  dbus_error_init (&error);
144

            
145
1
  reply = dbus_message_new_method_return (message);
146
1
  dbus_message_append_args (reply, DBUS_TYPE_STRING, &itf, DBUS_TYPE_INVALID);
147
1
  return reply;
148
}
149

            
150
static DBusMessage *
151
impl_getInterfaceTwo (DBusConnection *bus, DBusMessage *message, void *user_data)
152
{
153
  DBusMessage *reply;
154
  DBusError error;
155
  gchar *itf = TEST_INTERFACE_TWO;
156

            
157
  dbus_error_init (&error);
158

            
159
  reply = dbus_message_new_method_return (message);
160
  dbus_message_append_args (reply, DBUS_TYPE_STRING, &itf, DBUS_TYPE_INVALID);
161
  return reply;
162
}
163

            
164
static DRouteMethod test_methods_one[] = {
165
  { impl_null, "null" },
166
  { impl_getInt, "getInt" },
167
  { impl_setInt, "setInt" },
168
  { impl_getString, "getString" },
169
  { impl_setString, "setString" },
170
  { impl_getInterfaceOne, "getInterfaceOne" },
171
  { NULL, NULL }
172
};
173

            
174
static DRouteMethod test_methods_two[] = {
175
  { impl_null, "null" },
176
  { impl_getInt, "getInt" },
177
  { impl_setInt, "setInt" },
178
  { impl_getString, "getString" },
179
  { impl_setString, "setString" },
180
  { impl_getInterfaceTwo, "getInterfaceTwo" },
181
  { NULL, NULL }
182
};
183

            
184
static DRouteProperty test_properties[] = {
185
  { NULL, NULL, NULL }
186
};
187

            
188
static void
189
2
set_reply (DBusPendingCall *pending, void *user_data)
190
{
191
2
  void **replyptr = (void **) user_data;
192

            
193
2
  *replyptr = dbus_pending_call_steal_reply (pending);
194
2
  dbus_pending_call_unref (pending);
195
2
}
196

            
197
static DBusMessage *
198
2
send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error)
199
{
200
  DBusPendingCall *pending;
201
2
  DBusMessage *reply = NULL;
202

            
203
2
  if (!dbus_connection_send_with_reply (bus, message, &pending, -1))
204
    {
205
      return NULL;
206
    }
207
2
  dbus_pending_call_set_notify (pending, set_reply, (void *) &reply, NULL);
208
10
  while (!reply)
209
    {
210
8
      if (!dbus_connection_read_write_dispatch (bus, -1))
211
        return NULL;
212
    }
213
2
  return reply;
214
}
215

            
216
gboolean
217
1
do_tests_func (gpointer data)
218
{
219
  DBusError error;
220
  const gchar *bus_name;
221
  DBusMessage *message, *reply;
222

            
223
  gchar *expected_string;
224
  gchar *result_string;
225

            
226
1
  dbus_error_init (&error);
227
1
  bus_name = dbus_bus_get_unique_name (bus);
228

            
229
  /* --------------------------------------------------------*/
230

            
231
1
  message = dbus_message_new_method_call (bus_name,
232
                                          TEST_OBJECT_PATH,
233
                                          TEST_INTERFACE_ONE,
234
                                          "null");
235
1
  reply = send_and_allow_reentry (bus, message, NULL);
236
1
  dbus_message_unref (message);
237
1
  if (reply)
238
1
    dbus_message_unref (reply);
239

            
240
  /* --------------------------------------------------------*/
241

            
242
1
  expected_string = TEST_INTERFACE_ONE;
243
1
  result_string = NULL;
244
1
  message = dbus_message_new_method_call (bus_name,
245
                                          TEST_OBJECT_PATH,
246
                                          TEST_INTERFACE_ONE,
247
                                          "getInterfaceOne");
248
1
  reply = send_and_allow_reentry (bus, message, NULL);
249
1
  dbus_message_unref (message);
250
1
  dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &result_string,
251
                         DBUS_TYPE_INVALID);
252
1
  dbus_message_unref (reply);
253
1
  if (g_strcmp0 (expected_string, result_string))
254
    {
255
      g_print ("Failed: reply to getInterfaceOne was %s; expected %s\n",
256
               result_string, expected_string);
257
      exit (1);
258
    }
259

            
260
  /* --------------------------------------------------------*/
261

            
262
1
  g_main_loop_quit (main_loop);
263
1
  return FALSE;
264
}
265

            
266
int
267
1
main (int argc, char **argv)
268
{
269
  DRouteContext *cnx;
270
  DRoutePath *path;
271
  AnObject *object;
272
  DBusError error;
273

            
274
  /* Setup some server object */
275

            
276
1
  object = g_new0 (AnObject, 1);
277
1
  object->astring = g_strdup (STRING_ONE);
278
1
  object->anint = INT_ONE;
279

            
280
1
  dbus_error_init (&error);
281
1
  main_loop = g_main_loop_new (NULL, FALSE);
282
1
  bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
283
1
  atspi_dbus_connection_setup_with_g_main (bus, g_main_context_default ());
284

            
285
1
  cnx = droute_new ();
286
1
  path = droute_add_one (cnx, TEST_OBJECT_PATH, object);
287

            
288
1
  droute_path_add_interface (path,
289
                             TEST_INTERFACE_ONE,
290
                             test_interface_One,
291
                             test_methods_one,
292
                             test_properties);
293

            
294
1
  droute_path_add_interface (path,
295
                             TEST_INTERFACE_TWO,
296
                             test_interface_Two,
297
                             test_methods_two,
298
                             test_properties);
299

            
300
1
  droute_path_register (path, bus);
301

            
302
1
  g_idle_add (do_tests_func, NULL);
303
1
  g_main_loop_run (main_loop);
304

            
305
1
  droute_free (cnx);
306
1
  g_free (object->astring);
307
1
  g_free (object);
308

            
309
1
  if (success)
310
1
    return 0;
311
  else
312
    return 1;
313
}