Correction additional about "Removed system controller."
[profile/ivi/ico-uxf-homescreen.git] / tests / apps-framework / tst_server.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   test server
11  *
12  * @date    Aug-19-2013
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 #include <glib.h>
21 #include <ico_uws.h>
22
23 #include "ico_syc_msg_cmd_def.h"
24 #include "ico_syc_msg.h"
25 #include "ico_syc_private.h"
26
27 #include "tst_common.h"
28
29 /* ----------------------------------------------- */
30 /* Define of static variable                       */
31 /* ----------------------------------------------- */
32 #define ZONE_EXIST      0
33 #define ZONE_NO_EXIST   1
34
35 static int num_close    = 0;
36
37 /* ----------------------------------------------- */
38 /* Define of static function                       */
39 /* ----------------------------------------------- */
40 static int _get_command(const void *data, size_t len);
41 static int _check_zone(const void *data, size_t len);
42 static msg_t _create_winctl_msg(int cmd);
43 static msg_t _create_winctl_attr_msg(int cmd, const char *type);
44 static msg_t _create_winctl_move_msg(const void *data, size_t len);
45 static msg_t _create_winctl_layer_msg(int cmd);
46 static msg_t _create_userctl_msg(int cmd);
47 static msg_t _create_resctl_msg(int cmd);
48 static msg_t _create_resctl_region_msg(int cmd);
49 static msg_t _create_msg(const void *data, size_t len);
50 static void tst_uws_callback(const struct ico_uws_context *context,
51                              const ico_uws_evt_e event,
52                              const void *id,
53                              const ico_uws_detail *detail,
54                              void *user_data);
55 static int test_server(void);
56
57 /* ----------------------------------------------- */
58 /* Static function                                 */
59 /* ----------------------------------------------- */
60 static int
61 _get_command(const void *data, size_t len)
62 {
63     /* get command from receive data */
64     JsonParser *parser  = NULL;
65     GError *error       = NULL;
66     gboolean gbool      = FALSE;
67     JsonNode *r_root    = NULL;
68     JsonObject *r_obj   = NULL;
69     int cmd             = -1;
70
71     /* get command */
72     parser = json_parser_new();
73     gbool = json_parser_load_from_data(parser, data, len, &error);
74     if (gbool == FALSE) {
75         g_object_unref(parser);
76         return -1;
77     }
78     r_root = json_parser_get_root(parser);
79     if (r_root == NULL) {
80         g_object_unref(parser);
81         return -1;
82     }
83     r_obj = json_node_get_object(r_root);
84     cmd = json_object_get_int_member(r_obj, MSG_PRMKEY_CMD);
85     g_object_unref(parser); 
86
87     return cmd;
88 }
89
90 static int
91 _check_zone(const void *data, size_t len)
92 {
93     /* get command from receive data */
94     JsonParser *parser  = NULL;
95     GError *error       = NULL;
96     gboolean gbool      = FALSE;
97     JsonNode *r_root    = NULL;
98     JsonObject *r_obj   = NULL;
99     JsonObject *arg_obj = NULL;
100     int ret             = -1;
101
102     /* get command */
103     parser = json_parser_new();
104     gbool = json_parser_load_from_data(parser, data, len, &error);
105     if (gbool == FALSE) {
106         g_object_unref(parser);
107         return -1;
108     }
109     r_root = json_parser_get_root(parser);
110     if (r_root == NULL) {
111         g_object_unref(parser);
112         return -1;
113     }
114
115     r_obj = json_node_get_object(r_root);
116     arg_obj = json_object_get_object_member(r_obj, MSG_PRMKEY_ARG);
117     if (json_object_has_member(arg_obj, MSG_PRMKEY_ZONE) == TRUE) {
118         ret = ZONE_EXIST;
119     }
120     else {
121         ret = ZONE_NO_EXIST;
122     }
123     g_object_unref(parser); 
124
125     return ret;
126 }
127
128 static msg_t
129 _create_winctl_msg(int cmd)
130 {
131     JsonObject *obj     = NULL;
132     JsonObject *argobj  = NULL;
133     JsonGenerator *gen  = NULL;
134     JsonNode *root      = NULL;
135
136     /* create json object and array */
137     obj = json_object_new();
138     argobj = json_object_new();
139     if (obj == NULL || argobj == NULL) {
140         return NULL;
141     }
142
143     /* set message */
144     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
145     json_object_set_int_member(obj, MSG_PRMKEY_CMD, cmd);
146     json_object_set_string_member(argobj, MSG_PRMKEY_WINNAME, TST_WIN_NAME);
147     json_object_set_int_member(argobj, MSG_PRMKEY_SURFACE, TST_SURFACE);
148     json_object_set_int_member(argobj, MSG_PRMKEY_NODE, TST_NODE);
149     json_object_set_int_member(argobj, MSG_PRMKEY_LAYER, TST_LAYER);
150     json_object_set_int_member(argobj, MSG_PRMKEY_POS_X, TST_POS_X);
151     json_object_set_int_member(argobj, MSG_PRMKEY_POS_Y, TST_POS_Y);
152     json_object_set_int_member(argobj, MSG_PRMKEY_WIDTH, TST_WIDTH);
153     json_object_set_int_member(argobj, MSG_PRMKEY_HEIGHT, TST_HEIGHT);
154     json_object_set_int_member(argobj, MSG_PRMKEY_RAISE, TST_RAISE);
155     json_object_set_int_member(argobj, MSG_PRMKEY_VISIBLE, TST_VISIBLE);
156     json_object_set_int_member(argobj, MSG_PRMKEY_ACTIVE, TST_ACTIVE);
157     json_object_set_int_member(argobj, MSG_PRMKEY_STRIDE, TST_STRIDE);
158     json_object_set_int_member(argobj, MSG_PRMKEY_FORMAT, TST_FORMAT);
159
160     json_object_set_object_member(obj, MSG_PRMKEY_ARG, argobj);
161
162     /* create root object */
163     root = json_node_new(JSON_NODE_OBJECT);
164     json_node_take_object(root, obj);
165
166     /* create generator object */
167     gen = json_generator_new();
168     json_generator_set_root(gen, root);
169
170     return gen;
171 }
172
173 static msg_t
174 _create_winctl_attr_msg(int cmd, const char *type)
175 {
176     JsonObject *obj     = NULL;
177     JsonObject *argobj  = NULL;
178     JsonGenerator *gen  = NULL;
179     JsonNode *root      = NULL;
180
181     /* create json object and array */
182     obj = json_object_new();
183     argobj = json_object_new();
184     if (obj == NULL || argobj == NULL) {
185         return NULL;
186     }
187
188     /* set message */
189     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
190     json_object_set_int_member(obj, MSG_PRMKEY_CMD, cmd);
191     json_object_set_string_member(argobj, MSG_PRMKEY_WINNAME, type);
192     json_object_set_int_member(argobj, MSG_PRMKEY_SURFACE, TST_SURFACE);
193     json_object_set_int_member(argobj, MSG_PRMKEY_NODE, TST_NODE);
194     json_object_set_int_member(argobj, MSG_PRMKEY_LAYER, TST_LAYER);
195     json_object_set_int_member(argobj, MSG_PRMKEY_POS_X, TST_POS_X);
196     json_object_set_int_member(argobj, MSG_PRMKEY_POS_Y, TST_POS_Y);
197     json_object_set_int_member(argobj, MSG_PRMKEY_WIDTH, TST_WIDTH);
198     json_object_set_int_member(argobj, MSG_PRMKEY_HEIGHT, TST_HEIGHT);
199     json_object_set_int_member(argobj, MSG_PRMKEY_RAISE, TST_RAISE);
200     json_object_set_int_member(argobj, MSG_PRMKEY_VISIBLE, TST_VISIBLE);
201     json_object_set_int_member(argobj, MSG_PRMKEY_ACTIVE, TST_ACTIVE);
202     json_object_set_int_member(argobj, MSG_PRMKEY_STRIDE, TST_STRIDE);
203     json_object_set_int_member(argobj, MSG_PRMKEY_FORMAT, TST_FORMAT);
204
205     json_object_set_object_member(obj, MSG_PRMKEY_ARG, argobj);
206
207     /* create root object */
208     root = json_node_new(JSON_NODE_OBJECT);
209     json_node_take_object(root, obj);
210
211     /* create generator object */
212     gen = json_generator_new();
213     json_generator_set_root(gen, root);
214
215     return gen;
216 }
217
218 static msg_t
219 _create_winctl_move_msg(const void *data, size_t len)
220 {
221     JsonObject *obj     = NULL;
222     JsonObject *argobj  = NULL;
223     JsonGenerator *gen  = NULL;
224     JsonNode *root      = NULL;
225
226     /* create json object and array */
227     obj = json_object_new();
228     argobj = json_object_new();
229     if (obj == NULL || argobj == NULL) {
230         return NULL;
231     }
232
233     /* set message */
234     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
235     json_object_set_int_member(obj, MSG_PRMKEY_CMD, MSG_CMD_CHANGE_ATTR);
236     json_object_set_string_member(argobj, MSG_PRMKEY_WINNAME, "move");
237     json_object_set_int_member(argobj, MSG_PRMKEY_SURFACE, TST_SURFACE);
238     json_object_set_int_member(argobj, MSG_PRMKEY_NODE, TST_NODE);
239     json_object_set_int_member(argobj, MSG_PRMKEY_LAYER, TST_LAYER);
240     if (_check_zone(data, len) == ZONE_EXIST) {
241         json_object_set_int_member(argobj, MSG_PRMKEY_POS_X, 0);
242         json_object_set_int_member(argobj, MSG_PRMKEY_POS_Y, 0);
243     }
244     else {
245         json_object_set_int_member(argobj, MSG_PRMKEY_POS_X, 10);
246         json_object_set_int_member(argobj, MSG_PRMKEY_POS_Y, 10);
247     }
248     json_object_set_int_member(argobj, MSG_PRMKEY_WIDTH, TST_WIDTH);
249     json_object_set_int_member(argobj, MSG_PRMKEY_HEIGHT, TST_HEIGHT);
250     json_object_set_int_member(argobj, MSG_PRMKEY_RAISE, TST_RAISE);
251     json_object_set_int_member(argobj, MSG_PRMKEY_VISIBLE, TST_VISIBLE);
252     json_object_set_int_member(argobj, MSG_PRMKEY_ACTIVE, TST_ACTIVE);
253     json_object_set_int_member(argobj, MSG_PRMKEY_STRIDE, TST_STRIDE);
254     json_object_set_int_member(argobj, MSG_PRMKEY_FORMAT, TST_FORMAT);
255
256     json_object_set_object_member(obj, MSG_PRMKEY_ARG, argobj);
257
258     /* create root object */
259     root = json_node_new(JSON_NODE_OBJECT);
260     json_node_take_object(root, obj);
261
262     /* create generator object */
263     gen = json_generator_new();
264     json_generator_set_root(gen, root);
265
266     return gen;
267 }
268
269 static msg_t
270 _create_winctl_layer_msg(int cmd)
271 {
272     JsonObject *obj     = NULL;
273     JsonObject *argobj  = NULL;
274     JsonGenerator *gen  = NULL;
275     JsonNode *root      = NULL;
276
277     /* create json object and array */
278     obj = json_object_new();
279     argobj = json_object_new();
280     if (obj == NULL || argobj == NULL) {
281         return NULL;
282     }
283
284     /* set message */
285     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
286     json_object_set_int_member(obj, MSG_PRMKEY_CMD, MSG_CMD_CHANGE_LAYER_ATTR);
287     json_object_set_int_member(argobj, MSG_PRMKEY_LAYER, TST_LAYER);
288     if (cmd == MSG_CMD_SHOW_LAYER) {
289         json_object_set_int_member(argobj, MSG_PRMKEY_VISIBLE, TST_VISIBLE);
290     }
291     else {
292         json_object_set_int_member(argobj, MSG_PRMKEY_VISIBLE, TST_INVISIBLE);
293     }
294
295     json_object_set_object_member(obj, MSG_PRMKEY_ARG, argobj);
296
297     /* create root object */
298     root = json_node_new(JSON_NODE_OBJECT);
299     json_node_take_object(root, obj);
300
301     /* create generator object */
302     gen = json_generator_new();
303     json_generator_set_root(gen, root);
304
305     return gen;
306 }
307
308
309 static msg_t
310 _create_userctl_msg(int cmd)
311 {
312     JsonObject *obj     = NULL;
313     JsonObject *argobj  = NULL;
314     JsonGenerator *gen  = NULL;
315     JsonNode *root      = NULL;
316     JsonArray *array    = NULL;
317
318     /* create json object and array */
319     obj = json_object_new();
320     argobj = json_object_new();
321     array = json_array_new();
322     if (obj == NULL || argobj == NULL || array == NULL) {
323         return NULL;
324     }
325
326     /* set message */
327     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
328     json_object_set_int_member(obj, MSG_PRMKEY_CMD, cmd);
329     json_object_set_int_member(argobj, MSG_PRMKEY_USER_NUM, 3);
330
331     json_array_add_string_element(array, TST_USER_A);
332     json_array_add_string_element(array, TST_USER_B);
333     json_array_add_string_element(array, TST_USER_C);
334     json_object_set_array_member(argobj, MSG_PRMKEY_USER_LIST, array);
335
336     json_object_set_string_member(argobj, MSG_PRMKEY_USER_LOGIN, TST_USER_A);
337     json_object_set_string_member(argobj, MSG_PRMKEY_LASTINFO, TST_LASTINFO);
338
339     json_object_set_object_member(obj, MSG_PRMKEY_ARG, argobj);
340
341     /* create root object */
342     root = json_node_new(JSON_NODE_OBJECT);
343     json_node_take_object(root, obj);
344
345     /* create generator object */
346     gen = json_generator_new();
347     json_generator_set_root(gen, root);
348
349     return gen;
350 }
351
352 static msg_t
353 _create_resctl_msg(int cmd)
354 {
355     JsonObject *obj     = NULL;
356     JsonObject *resobj  = NULL;
357     JsonObject *window_obj  = NULL;
358     JsonObject *sound_obj  = NULL;
359     JsonObject *input_obj  = NULL;
360     JsonGenerator *gen  = NULL;
361     JsonNode *root      = NULL;
362
363     /* create json object and array */
364     obj = json_object_new();
365     resobj = json_object_new();
366     window_obj = json_object_new();
367     sound_obj = json_object_new();
368     input_obj = json_object_new();
369     if (obj == NULL || resobj == NULL || window_obj == NULL
370         || sound_obj == NULL || input_obj == NULL) {
371         return NULL;
372     }
373
374     /* set message */
375     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
376     json_object_set_int_member(obj, MSG_PRMKEY_CMD, cmd);
377
378     /* window */
379     json_object_set_string_member(window_obj, MSG_PRMKEY_RES_ZONE, TST_ZONE_A);
380     json_object_set_string_member(window_obj, MSG_PRMKEY_RES_NAME, TST_NAME_A);
381     json_object_set_string_member(window_obj, MSG_PRMKEY_RES_ID, TST_ID_A);
382     /* sound */
383     json_object_set_string_member(sound_obj, MSG_PRMKEY_RES_ZONE, TST_ZONE_B);
384     json_object_set_string_member(sound_obj, MSG_PRMKEY_RES_NAME, TST_NAME_B);
385     json_object_set_string_member(sound_obj, MSG_PRMKEY_RES_ID, TST_ID_B);
386     json_object_set_int_member(sound_obj, MSG_PRMKEY_RES_ADJUST, TST_ADJUST);
387     /* input */
388     json_object_set_string_member(input_obj, MSG_PRMKEY_RES_NAME, TST_NAME_C);
389     json_object_set_int_member(input_obj, MSG_PRMKEY_RES_EV, TST_INPUT_EV);
390     /* type */
391     json_object_set_int_member(resobj, MSG_PRMKEY_RES_TYPE, TST_RES_TYPE);
392
393     /* set object */
394     json_object_set_object_member(resobj, MSG_PRMKEY_RES_WINDOW, window_obj);
395     json_object_set_object_member(resobj, MSG_PRMKEY_RES_SOUND, sound_obj);
396     json_object_set_object_member(resobj, MSG_PRMKEY_RES_INPUT, input_obj);
397     json_object_set_object_member(obj, MSG_PRMKEY_RES, resobj);
398
399     /* create root object */
400     root = json_node_new(JSON_NODE_OBJECT);
401     json_node_take_object(root, obj);
402
403     /* create generator object */
404     gen = json_generator_new();
405     json_generator_set_root(gen, root);
406
407     return gen;
408 }
409
410 static msg_t
411 _create_resctl_region_msg(int cmd)
412 {
413     JsonObject *obj     = NULL;
414     JsonObject *resobj  = NULL;
415     JsonGenerator *gen  = NULL;
416     JsonNode *root      = NULL;
417
418     /* create json object and array */
419     obj = json_object_new();
420     resobj = json_object_new();
421     if (obj == NULL || resobj == NULL) {
422         return NULL;
423     }
424
425     /* set message */
426     json_object_set_string_member(obj, MSG_PRMKEY_APPID, TST_APPID);
427     json_object_set_int_member(obj, MSG_PRMKEY_CMD, cmd);
428
429     /* region */
430     json_object_set_int_member(resobj, MSG_PRMKEY_RES_SURFACE, TST_SURFACE);
431     json_object_set_int_member(resobj, MSG_PRMKEY_RES_POS_X, TST_POS_X);
432     json_object_set_int_member(resobj, MSG_PRMKEY_RES_POS_Y, TST_POS_Y);
433     json_object_set_int_member(resobj, MSG_PRMKEY_RES_WIDTH, TST_REG_WIDTH);
434     json_object_set_int_member(resobj, MSG_PRMKEY_RES_HEIGHT, TST_REG_HEIGHT);
435     json_object_set_int_member(resobj, MSG_PRMKEY_RES_HOT_X, TST_REG_HOT_X);
436     json_object_set_int_member(resobj, MSG_PRMKEY_RES_HOT_Y, TST_REG_HOT_Y);
437     json_object_set_int_member(resobj, MSG_PRMKEY_RES_CUR_X, TST_REG_CUR_X);
438     json_object_set_int_member(resobj, MSG_PRMKEY_RES_CUR_Y, TST_REG_CUR_Y);
439     json_object_set_int_member(resobj, MSG_PRMKEY_RES_CUR_WIDTH, TST_REG_CUR_WIDTH);
440     json_object_set_int_member(resobj, MSG_PRMKEY_RES_CUR_HEIGHT, TST_REG_CUR_HEIGHT);
441     json_object_set_int_member(resobj, MSG_PRMKEY_RES_ATTR, TST_REG_ATTR);
442
443     /* set object */
444     json_object_set_object_member(obj, MSG_PRMKEY_REGION, resobj);
445
446     /* create root object */
447     root = json_node_new(JSON_NODE_OBJECT);
448     json_node_take_object(root, obj);
449
450     /* create generator object */
451     gen = json_generator_new();
452     json_generator_set_root(gen, root);
453
454     return gen;
455 }
456
457 static msg_t
458 _create_msg(const void *data, size_t len)
459 {
460     int cmd             = -1;
461     JsonGenerator *gen  = NULL;
462
463     /* get command */
464     cmd = _get_command(data, len);
465     if (cmd < 0) {
466         return NULL;
467     }
468
469     switch (cmd) {
470     case MSG_CMD_CREATE:
471     case MSG_CMD_DESTROY:
472     case MSG_CMD_CHANGE_ACTIVE:
473         gen = _create_winctl_msg(cmd);
474         break;
475     case MSG_CMD_SHOW:
476         gen = _create_winctl_attr_msg(MSG_CMD_CHANGE_ATTR, "show");
477         break;
478     case MSG_CMD_HIDE:
479         gen = _create_winctl_attr_msg(MSG_CMD_CHANGE_ATTR, "hide");
480         break;
481     case MSG_CMD_MOVE:
482         gen = _create_winctl_move_msg(data, len);
483         break;
484     case MSG_CMD_CHANGE_LAYER:
485         gen = _create_winctl_attr_msg(MSG_CMD_CHANGE_ATTR, "change layer");
486         break;
487     case MSG_CMD_MAP_THUMB:
488     case MSG_CMD_UNMAP_THUMB:
489         gen = _create_winctl_msg(cmd);
490         break;
491     case MSG_CMD_SHOW_LAYER:
492     case MSG_CMD_HIDE_LAYER:
493         gen = _create_winctl_layer_msg(cmd);
494         break;
495     case MSG_CMD_ADD_INPUT:
496     case MSG_CMD_DEL_INPUT:
497 #if 0           /* SystemController 0.9.21(with GENIVI ivi-shell) not support send_input */
498     case MSG_CMD_SEND_INPUT:
499 #endif
500         gen = NULL;
501         break;
502     case MSG_CMD_CHANGE_USER:
503     case MSG_CMD_GET_USERLIST:
504         gen = _create_userctl_msg(cmd);
505         break;
506     case MSG_CMD_ACQUIRE_RES:
507     case MSG_CMD_RELEASE_RES:
508     case MSG_CMD_DEPRIVE_RES:
509     case MSG_CMD_WAITING_RES:
510     case MSG_CMD_REVERT_RES:
511         gen = _create_resctl_msg(cmd);
512         break;
513     case MSG_CMD_SET_REGION:
514     case MSG_CMD_UNSET_REGION:
515         gen = _create_resctl_region_msg(cmd);
516         break;
517     default:
518         gen = NULL;
519         break;
520     }
521
522     return gen;
523 }
524
525 /* event callback */
526 static void
527 tst_uws_callback(const struct ico_uws_context *context,
528                  const ico_uws_evt_e event,
529                  const void *id,
530                  const ico_uws_detail *detail,
531                  void *user_data)
532 {
533     JsonNode *node  = NULL;
534     msg_t msg       = NULL;
535     msg_str_t data  = NULL;
536     size_t  len     = 0;
537
538     switch (event) {
539     case ICO_UWS_EVT_RECEIVE:
540         msg = _create_msg((const void *)detail->_ico_uws_message.recv_data,
541                           detail->_ico_uws_message.recv_len);
542         if (msg == NULL) break;
543         data = json_generator_to_data(msg, &len);
544         if (data == NULL) break;
545
546         /* send return message */
547         ico_uws_send((struct ico_uws_context *)context,
548                      (void *)id,
549                      (unsigned char *)data, len);
550         printf("send: %s\n", (char *)data);
551         /* free */
552         g_free(data);
553         node = json_generator_get_root(msg);
554         json_object_unref(json_node_get_object(node));
555         json_node_free(node);
556         usleep(50);
557         break;
558     case ICO_UWS_EVT_CLOSE:
559         num_close++;
560         break;
561     case ICO_UWS_EVT_OPEN:
562     case ICO_UWS_EVT_ERROR:
563     case ICO_UWS_EVT_ADD_FD:
564     case ICO_UWS_EVT_DEL_FD:
565     default:
566         /* other event is not test */
567         break;
568     }
569
570     return;
571 }
572
573 /* test main (server) */
574 static int
575 test_server(void)
576 {
577     struct ico_uws_context *context;
578
579     /* create context */
580     context = ico_uws_create_context(SRV_URI, ICO_SYC_PROTOCOL);
581
582     if (context) {
583         (void)ico_uws_set_event_cb(context, tst_uws_callback, NULL);
584
585         /* service (loop) */
586         while (num_close < 5) {
587             ico_uws_service(context);
588             usleep(50);
589         }
590
591         /* close */
592         ico_uws_close(context);
593     }
594
595     return 1;
596 }
597
598 /* ----------------------------------------------- */
599 /* Main                                            */
600 /* ----------------------------------------------- */
601 static GMainLoop *g_mainloop = NULL;
602
603 static gboolean
604 exit_program(gpointer data)
605 {
606     g_main_loop_quit(g_mainloop);
607
608     return FALSE;
609 }
610
611 /* main */
612 int
613 main(int argc, char **argv)
614 {
615     g_setenv("PKG_NAME", "org.test.ico.tst_server", 1);
616     g_mainloop = g_main_loop_new(NULL, 0);
617
618     test_server();
619
620     g_timeout_add_seconds(2, exit_program, NULL);
621     g_main_loop_run(g_mainloop);
622
623     return 0;
624 }
625 /* vim: set expandtab ts=4 sw=4: */