1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 Joël Krähemann
3  *
4  * This file is part of GSequencer.
5  *
6  * GSequencer is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSequencer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <glib.h>
21 #include <glib-object.h>
22 
23 #include <CUnit/CUnit.h>
24 #include <CUnit/Basic.h>
25 
26 #include <ags/libags.h>
27 #include <ags/libags-audio.h>
28 
29 #ifdef __APPLE__
30 #include <mach/clock.h>
31 #include <mach/mach.h>
32 #endif
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <math.h>
38 #include <time.h>
39 
40 gpointer ags_functional_osc_xmlrpc_server_test_add_thread(gpointer data);
41 
42 int ags_functional_osc_xmlrpc_server_test_init_suite();
43 int ags_functional_osc_xmlrpc_server_test_clean_suite();
44 
45 void ags_functional_osc_xmlrpc_server_test_action_controller();
46 void ags_functional_osc_xmlrpc_server_test_config_controller();
47 void ags_functional_osc_xmlrpc_server_test_info_controller();
48 void ags_functional_osc_xmlrpc_server_test_meter_controller();
49 void ags_functional_osc_xmlrpc_server_test_node_controller();
50 void ags_functional_osc_xmlrpc_server_test_renew_controller();
51 void ags_functional_osc_xmlrpc_server_test_status_controller();
52 
53 void ags_functional_osc_xmlrpc_server_test_authenticate_authenticate_callback(SoupSession *session,
54 									      SoupMessage *msg,
55 									      SoupAuth *auth,
56 									      gboolean retrying,
57 									      gpointer user_data);
58 
59 void ags_functional_osc_xmlrpc_server_test_websocket_callback(GObject *source_object,
60 							      GAsyncResult *res,
61 							      gpointer user_data);
62 void ags_functional_osc_xmlrpc_server_test_websocket_message_callback(SoupWebsocketConnection *websocket_connection,
63 								      gint type,
64 								      GBytes *message,
65 								      gpointer user_data);
66 void ags_functional_osc_xmlrpc_server_test_websocket_error_callback(SoupWebsocketConnection *websocket_connection,
67 								    GError *error,
68 								    gpointer user_data);
69 
70 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_CONFIG "[generic]\n"	\
71   "autosave-thread=false\n"					\
72   "simple-file=false\n"						\
73   "disable-feature=experimental\n"				\
74   "segmentation=4/4\n"						\
75   "\n"								\
76   "[server]\n"							\
77   "realm=ags-test-realm\n"					\
78   "auto-start=true\n"						\
79   "any-address=false\n"						\
80   "enable-ip4=true\n"						\
81   "ip4-address=127.0.0.1\n"					\
82   "enable-ip6=false\n"						\
83   "ip6-address=::1\n"						\
84   "server-port=8080\n"						\
85   "\n"								\
86   "[thread]\n"							\
87   "model=super-threaded\n"					\
88   "super-threaded-scope=channel\n"				\
89   "lock-global=ags-thread\n"					\
90   "lock-parent=ags-recycling-thread\n"				\
91   "thread-pool-max-unused-threads=8\n"				\
92   "max-precision=125\n"						\
93   "\n"								\
94   "[soundcard-0]\n"						\
95   "backend=alsa\n"						\
96   "device=default\n"						\
97   "samplerate=44100\n"						\
98   "buffer-size=1024\n"						\
99   "pcm-channels=2\n"						\
100   "dsp-channels=2\n"						\
101   "format=16\n"							\
102   "\n"								\
103   "[sequencer-0]\n"						\
104   "backend=alsa\n"						\
105   "device=default\n"						\
106   "\n"								\
107   "[recall]\n"							\
108   "auto-sense=true\n"						\
109   "\n"
110 
111 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_APPLY_CONFIG_ARGUMENT "[generic]\n" \
112   "autosave-thread=false\n"						\
113   "simple-file=false\n"							\
114   "disable-feature=experimental\n"					\
115   "segmentation=4/4\n"							\
116   "\n"									\
117   "[thread]\n"								\
118   "model=super-threaded\n"						\
119   "super-threaded-scope=channel\n"					\
120   "lock-global=ags-thread\n"						\
121   "lock-parent=ags-recycling-thread\n"					\
122   "thread-pool-max-unused-threads=8\n"					\
123   "max-precision=125\n"							\
124   "\n"									\
125   "[soundcard-0]\n"							\
126   "backend=alsa\n"							\
127   "device=default\n"							\
128   "samplerate=44100\n"							\
129   "buffer-size=256\n"							\
130   "pcm-channels=2\n"							\
131   "dsp-channels=2\n"							\
132   "format=16\n"								\
133   "\n"									\
134   "[recall]\n"								\
135   "auto-sense=true\n"							\
136   "\n"
137 
138 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_METER_PACKET_COUNT (16 * 30)
139 
140 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_AUTHENTICATION_FILENAME SRCDIR "/" "ags_functional_osc_xmlrpc_server_test_authentication.xml"
141 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_PASSWORD_STORE_FILENAME SRCDIR "/" "ags_functional_osc_xmlrpc_server_test_password_store.xml"
142 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_COOKIE_FILENAME SRCDIR "/" "ags_functional_osc_xmlrpc_server_test_cookie"
143 
144 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_AUTHENTICATE_LOGIN "ags-test-login"
145 #define AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_AUTHENTICATE_PASSWORD "ags-test-password"
146 
147 GThread *add_thread = NULL;
148 
149 GMainLoop *test_main_loop;
150 GMainContext *test_main_context;
151 
152 AgsApplicationContext *application_context;
153 
154 AgsAudio *drum;
155 
156 AgsOscXmlrpcServer *osc_xmlrpc_server;
157 
158 SoupSession *soup_session;
159 SoupCookieJar *jar;
160 
161 SoupWebsocketConnection *websocket_connection;
162 
163 GObject *default_soundcard;
164 
165 struct TestDataMeter{
166   gchar *login;
167   gchar *security_token;
168   gchar *resource_id;
169 
170   volatile gint *meter_packet_count;
171 }meter_data;
172 
173 gpointer
ags_functional_osc_xmlrpc_server_test_add_thread(gpointer data)174 ags_functional_osc_xmlrpc_server_test_add_thread(gpointer data)
175 {
176   CU_pSuite pSuite = NULL;
177 
178   putenv("LC_ALL=C");
179   putenv("LANG=C");
180 
181   putenv("LADSPA_PATH=\"\"");
182   putenv("DSSI_PATH=\"\"");
183   putenv("LV2_PATH=\"\"");
184 
185   test_main_context = g_main_context_new();
186   test_main_loop = g_main_loop_new(test_main_context, FALSE);
187 
188   /* initialize the CUnit test registry */
189   if(CUE_SUCCESS != CU_initialize_registry()){
190     exit(CU_get_error());
191   }
192 
193   /* add a suite to the registry */
194   pSuite = CU_add_suite("AgsFunctionalOscXmlrpcServerTest", ags_functional_osc_xmlrpc_server_test_init_suite, ags_functional_osc_xmlrpc_server_test_clean_suite);
195 
196   if(pSuite == NULL){
197     CU_cleanup_registry();
198 
199     exit(CU_get_error());
200   }
201 
202   /* add the tests to the suite */
203   if((CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing action controller", ags_functional_osc_xmlrpc_server_test_action_controller) == NULL) ||
204      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing config controller", ags_functional_osc_xmlrpc_server_test_config_controller) == NULL) ||
205      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing info controller", ags_functional_osc_xmlrpc_server_test_info_controller) == NULL) ||
206      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing meter controller", ags_functional_osc_xmlrpc_server_test_meter_controller) == NULL) ||
207      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing node controller", ags_functional_osc_xmlrpc_server_test_node_controller) == NULL) ||
208      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing renew controller", ags_functional_osc_xmlrpc_server_test_renew_controller) == NULL) ||
209      (CU_add_test(pSuite, "test of AgsOscXmlrpcServer providing status controller", ags_functional_osc_xmlrpc_server_test_status_controller) == NULL)){
210     CU_cleanup_registry();
211 
212     exit(CU_get_error());
213   }
214 
215   /* Run all tests using the CUnit Basic interface */
216   CU_basic_set_mode(CU_BRM_VERBOSE);
217   CU_basic_run_tests();
218 
219   CU_cleanup_registry();
220 
221   exit(CU_get_error());
222 }
223 
224 /* The suite initialization function.
225  * Opens the temporary file used by the tests.
226  * Returns zero on success, non-zero otherwise.
227  */
228 int
ags_functional_osc_xmlrpc_server_test_init_suite()229 ags_functional_osc_xmlrpc_server_test_init_suite()
230 {
231   AgsAuthenticationManager *authentication_manager;
232   AgsPasswordStoreManager *password_store_manager;
233   AgsXmlAuthentication *xml_authentication;
234   AgsXmlPasswordStore *xml_password_store;
235 
236   AgsConfig *config;
237 
238   GList *server;
239   GList *start_audio;
240 
241   ags_priority_load_defaults(ags_priority_get_instance());
242 
243   config = ags_config_get_instance();
244   ags_config_load_from_data(config,
245 			    AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_CONFIG,
246 			    strlen(AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_CONFIG));
247 
248   authentication_manager = ags_authentication_manager_get_instance();
249   password_store_manager = ags_password_store_manager_get_instance();
250 
251   xml_authentication = ags_xml_authentication_new();
252   ags_xml_authentication_open_filename(xml_authentication,
253 				       AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_AUTHENTICATION_FILENAME);
254   ags_authentication_manager_add_authentication(authentication_manager,
255 						xml_authentication);
256 
257   xml_password_store = ags_xml_password_store_new();
258   ags_xml_password_store_open_filename(xml_password_store,
259 				       AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_PASSWORD_STORE_FILENAME);
260   ags_password_store_manager_add_password_store(password_store_manager,
261 						xml_password_store);
262 
263   application_context = ags_audio_application_context_new();
264   g_object_ref(application_context);
265 
266   ags_application_context_prepare(application_context);
267   ags_application_context_setup(application_context);
268 
269   default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
270 
271   /* drum */
272   drum = ags_audio_new(default_soundcard);
273   g_object_ref(drum);
274 
275   g_object_set(drum,
276 	       "audio-name", "test-drum",
277 	       NULL);
278 
279   ags_audio_set_flags(drum,
280 		      (AGS_AUDIO_OUTPUT_HAS_RECYCLING |
281 		       AGS_AUDIO_INPUT_HAS_RECYCLING |
282 		       AGS_AUDIO_SYNC |
283 		       AGS_AUDIO_ASYNC));
284 
285   ags_audio_set_ability_flags(drum, (AGS_SOUND_ABILITY_PLAYBACK |
286 				     AGS_SOUND_ABILITY_SEQUENCER |
287 				     AGS_SOUND_ABILITY_NOTATION));
288 
289   ags_audio_set_audio_channels(drum,
290 			       2, 0);
291 
292   ags_audio_set_pads(drum,
293 		     AGS_TYPE_OUTPUT,
294 		     1, 0);
295   ags_audio_set_pads(drum,
296 		     AGS_TYPE_INPUT,
297 		     8, 0);
298 
299   start_audio = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
300   ags_sound_provider_set_audio(AGS_SOUND_PROVIDER(application_context),
301 			       g_list_prepend(start_audio,
302 					      drum));
303 
304   /* ags-volume */
305   ags_recall_factory_create(drum,
306 			    NULL, NULL,
307 			    "ags-volume",
308 			    0, 2,
309 			    0, 8,
310 			    (AGS_RECALL_FACTORY_INPUT |
311 			     AGS_RECALL_FACTORY_PLAY |
312 			     AGS_RECALL_FACTORY_RECALL |
313 			     AGS_RECALL_FACTORY_ADD),
314 			    0);
315 
316   /* ags-mute */
317   ags_recall_factory_create(drum,
318 			    NULL, NULL,
319 			    "ags-mute",
320 			    0, 2,
321 			    0, 8,
322 			    (AGS_RECALL_FACTORY_INPUT,
323 			     AGS_RECALL_FACTORY_PLAY |
324 			     AGS_RECALL_FACTORY_RECALL |
325 			     AGS_RECALL_FACTORY_ADD),
326 			    0);
327 
328   /* ags-peak */
329   ags_recall_factory_create(drum,
330 			    NULL, NULL,
331 			    "ags-peak",
332 			    0, 2,
333 			    0, 8,
334 			    (AGS_RECALL_FACTORY_INPUT |
335 			     AGS_RECALL_FACTORY_PLAY |
336 			     AGS_RECALL_FACTORY_RECALL |
337 			     AGS_RECALL_FACTORY_ADD),
338 			    0);
339 
340   ags_connectable_connect(AGS_CONNECTABLE(drum));
341 
342   /* OSC XMLRPC server */
343   signal(SIGPIPE, SIG_IGN);
344 
345   server = ags_service_provider_get_server(AGS_SERVICE_PROVIDER(application_context));
346 
347   osc_xmlrpc_server = ags_osc_xmlrpc_server_new();
348   g_object_set(osc_xmlrpc_server,
349 	       "xmlrpc-server", server->data,
350 	       NULL);
351 
352   while(!ags_server_test_flags(server->data, AGS_SERVER_RUNNING)){
353     sleep(1);
354   }
355 
356   ags_osc_xmlrpc_server_add_default_controller(osc_xmlrpc_server);
357 
358   ags_osc_server_start(osc_xmlrpc_server);
359 
360   sleep(5);
361 
362   /* soup session */
363   soup_session = soup_session_new_with_options(SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_AUTH_BASIC,
364 					       SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_AUTH_DIGEST,
365 					       SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_LOGGER,
366 					       NULL);
367 
368   jar = soup_cookie_jar_text_new(AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_XML_COOKIE_FILENAME,
369 				 FALSE);
370   soup_session_add_feature(soup_session, jar);
371 
372   g_object_set(G_OBJECT(soup_session),
373 	       SOUP_SESSION_SSL_STRICT, FALSE,
374 	       NULL);
375 
376   g_signal_connect(soup_session, "authenticate",
377 		   G_CALLBACK(ags_functional_osc_xmlrpc_server_test_authenticate_authenticate_callback), NULL);
378 
379   sleep(5);
380 
381   return(0);
382 }
383 
384 /* The suite cleanup function.
385  * Closes the temporary file used by the tests.
386  * Returns zero on success, non-zero otherwise.
387  */
388 int
ags_functional_osc_xmlrpc_server_test_clean_suite()389 ags_functional_osc_xmlrpc_server_test_clean_suite()
390 {
391   ags_osc_server_stop(osc_xmlrpc_server);
392 
393   return(0);
394 }
395 
396 void
ags_functional_osc_xmlrpc_server_test_authenticate_authenticate_callback(SoupSession * session,SoupMessage * msg,SoupAuth * auth,gboolean retrying,gpointer user_data)397 ags_functional_osc_xmlrpc_server_test_authenticate_authenticate_callback(SoupSession *session,
398 									 SoupMessage *msg,
399 									 SoupAuth *auth,
400 									 gboolean retrying,
401 									 gpointer user_data)
402 {
403   g_message("authenticate: ****");
404 
405   soup_auth_authenticate(auth,
406 			 AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_AUTHENTICATE_LOGIN,
407 			 AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_AUTHENTICATE_PASSWORD);
408 }
409 
410 void
ags_functional_osc_xmlrpc_server_test_websocket_callback(GObject * source_object,GAsyncResult * res,gpointer user_data)411 ags_functional_osc_xmlrpc_server_test_websocket_callback(GObject *source_object,
412 							 GAsyncResult *res,
413 							 gpointer user_data)
414 {
415   xmlDoc *doc;
416   xmlNode *root_node;
417   xmlNode *login_node;
418   xmlNode *security_token_node;
419   xmlNode *redirect_node;
420 
421   xmlChar *buffer;
422 
423   int buffer_length;
424 
425   GError *error;
426 
427   error = NULL;
428   websocket_connection = soup_session_websocket_connect_finish(SOUP_SESSION(source_object),
429 							       res,
430 							       &error);
431   g_object_ref(websocket_connection);
432 
433   if(error != NULL){
434     g_critical("%s", error->message);
435 
436     g_error_free(error);
437   }
438 
439   g_message("websocket ...");
440 
441   g_signal_connect(websocket_connection, "message",
442 		   G_CALLBACK(ags_functional_osc_xmlrpc_server_test_websocket_message_callback), NULL);
443 
444   g_signal_connect(websocket_connection, "error",
445 		   G_CALLBACK(ags_functional_osc_xmlrpc_server_test_websocket_error_callback), NULL);
446 
447 
448   /* websocket */
449   doc = xmlNewDoc("1.0");
450 
451   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
452   xmlDocSetRootElement(doc, root_node);
453 
454   login_node = xmlNewNode(NULL,
455 			  BAD_CAST "ags-srv-login");
456 
457   xmlNodeSetContent(login_node,
458 		    meter_data.login);
459 
460   xmlAddChild(root_node,
461 	      login_node);
462 
463   security_token_node = xmlNewNode(NULL,
464 				   BAD_CAST "ags-srv-security-token");
465 
466   xmlNodeSetContent(security_token_node,
467 		    meter_data.security_token);
468 
469   xmlAddChild(root_node,
470 	      security_token_node);
471 
472   redirect_node = xmlNewNode(NULL,
473 			     BAD_CAST "ags-srv-redirect");
474 
475   xmlNewProp(redirect_node,
476 	     "resource-id",
477 	     meter_data.resource_id);
478 
479   xmlAddChild(root_node,
480 	      redirect_node);
481 
482   buffer = NULL;
483   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
484 
485   sleep(5);
486 
487   soup_websocket_connection_send_text(websocket_connection,
488 				      buffer);
489 }
490 
491 void
ags_functional_osc_xmlrpc_server_test_websocket_message_callback(SoupWebsocketConnection * websocket_connection,gint type,GBytes * message,gpointer user_data)492 ags_functional_osc_xmlrpc_server_test_websocket_message_callback(SoupWebsocketConnection *websocket_connection,
493 								 gint type,
494 								 GBytes *message,
495 								 gpointer user_data)
496 {
497   xmlDoc *response_doc;
498   xmlNode *response_root_node;
499 
500   volatile gint *meter_packet_count;
501   guchar *data;
502 
503   gsize data_length;
504 
505   GError *error;
506 
507   data = g_bytes_get_data(message,
508 			  &data_length);
509 
510 
511   meter_packet_count = meter_data.meter_packet_count;
512 
513   response_doc = xmlParseDoc(data);
514   response_root_node = NULL;
515 
516   if(response_doc != NULL){
517     response_root_node = xmlDocGetRootElement(response_doc);
518 
519     if(response_root_node != NULL &&
520        !g_ascii_strncasecmp(response_root_node->name,
521 			    "ags-osc-over-xmlrpc",
522 			    20)){
523       g_atomic_int_inc(meter_packet_count);
524     }
525 
526     xmlFreeDoc(response_doc);
527   }
528 }
529 
530 void
ags_functional_osc_xmlrpc_server_test_websocket_error_callback(SoupWebsocketConnection * websocket_connection,GError * error,gpointer user_data)531 ags_functional_osc_xmlrpc_server_test_websocket_error_callback(SoupWebsocketConnection *websocket_connection,
532 							       GError *error,
533 							       gpointer user_data)
534 {
535   g_message("%s", error->message);
536 }
537 
538 void
ags_functional_osc_xmlrpc_server_test_action_controller()539 ags_functional_osc_xmlrpc_server_test_action_controller()
540 {
541   SoupMessage *msg;
542   SoupMessageHeaders *response_headers;
543   SoupMessageBody *response_body;
544 
545   SoupMessageHeadersIter iter;
546   GSList *cookie;
547 
548   xmlDoc *doc;
549   xmlNode *root_node;
550   xmlNode *osc_packet_node_list;
551   xmlNode *osc_packet_node;
552 
553   gchar *data;
554   guchar *packet;
555   xmlChar *buffer;
556 
557   int buffer_length;
558   guint status;
559 
560   static const guchar *start_soundcard_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSoundcard\x00\x00start\x00\x00\x00";
561   static const guchar *start_sequencer_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSequencer\x00\x00start\x00\x00\x00";
562   static const guchar *start_audio_message =     "/action\x00,ss\x00/AgsSoundProvider/AgsAudio[0]\x00\x00\x00start\x00\x00\x00";
563   static const guchar *stop_soundcard_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSoundcard\x00\x00stop\x00\x00\x00\x00";
564   static const guchar *stop_sequencer_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSequencer\x00\x00stop\x00\x00\x00\x00";
565   static const guchar *stop_audio_message =     "/action\x00,ss\x00/AgsSoundProvider/AgsAudio[0]\x00\x00\x00stop\x00\x00\x00\x00";
566 
567   static const guint start_soundcard_message_size = 52;
568   static const guint start_sequencer_message_size = 52;
569   static const guint start_audio_message_size = 52;
570   static const guint stop_soundcard_message_size = 52;
571   static const guint stop_sequencer_message_size = 52;
572   static const guint stop_audio_message_size = 52;
573 
574   /* start soundcard */
575   doc = xmlNewDoc("1.0");
576 
577   root_node = xmlNewNode(NULL,
578 			 BAD_CAST "ags-osc-over-xmlrpc");
579   xmlDocSetRootElement(doc,
580 		       root_node);
581 
582   osc_packet_node_list = xmlNewNode(NULL,
583 				    BAD_CAST "ags-osc-packet-list");
584 
585   xmlAddChild(root_node,
586 	      osc_packet_node_list);
587 
588   osc_packet_node = xmlNewNode(NULL,
589 				BAD_CAST "ags-osc-packet");
590 
591   xmlAddChild(osc_packet_node_list,
592 	      osc_packet_node);
593 
594   /* OSC message */
595   packet = (guchar *) g_malloc((4 + start_soundcard_message_size) * sizeof(guchar));
596 
597   ags_osc_buffer_util_put_int32(packet,
598 				start_soundcard_message_size);
599   memcpy(packet + 4, start_soundcard_message, (start_soundcard_message_size) * sizeof(guchar));
600 
601   data = g_base64_encode(packet,
602 			 4 + start_soundcard_message_size);
603 
604   xmlNodeSetContent(osc_packet_node,
605 		    data);
606 
607   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
608 
609   /* send message */
610   msg = soup_form_request_new("POST",
611 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
612 			      NULL);
613   soup_message_set_request(msg,
614 			   "text/xml; charset=UTF-8",
615 			   SOUP_MEMORY_COPY,
616 			   buffer,
617 			   buffer_length);
618 
619   status = soup_session_send_message(soup_session,
620 				     msg);
621 
622   g_object_get(msg,
623 	       "response-headers", &response_headers,
624 	       "response-body", &response_body,
625 	       NULL);
626 
627   g_message("status %d", status);
628 
629   CU_ASSERT(status == 200);
630 
631   xmlFree(buffer);
632 
633   sleep(5);
634 
635   /* start sequencer */
636   doc = xmlNewDoc("1.0");
637 
638   root_node = xmlNewNode(NULL,
639 			 BAD_CAST "ags-osc-over-xmlrpc");
640   xmlDocSetRootElement(doc, root_node);
641 
642   osc_packet_node_list = xmlNewNode(NULL,
643 				    BAD_CAST "ags-osc-packet-list");
644 
645   xmlAddChild(root_node,
646 	      osc_packet_node_list);
647 
648   osc_packet_node = xmlNewNode(NULL,
649 				BAD_CAST "ags-osc-packet");
650 
651   xmlAddChild(osc_packet_node_list,
652 	      osc_packet_node);
653 
654   /* OSC message */
655   packet = (guchar *) malloc((4 + start_sequencer_message_size) * sizeof(guchar));
656 
657   ags_osc_buffer_util_put_int32(packet,
658 				start_sequencer_message_size);
659   memcpy(packet + 4, start_sequencer_message, (start_sequencer_message_size) * sizeof(guchar));
660 
661   data = g_base64_encode(packet,
662 			 4 + start_sequencer_message_size);
663 
664   xmlNodeSetContent(osc_packet_node,
665 		    data);
666 
667   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
668 
669   /* send message */
670   msg = soup_form_request_new("POST",
671 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
672 			      NULL);
673   soup_message_set_request(msg,
674 			   "text/xml; charset=UTF-8",
675 			   SOUP_MEMORY_COPY,
676 			   buffer,
677 			   buffer_length);
678 
679   status = soup_session_send_message(soup_session,
680 				     msg);
681 
682   g_object_get(msg,
683 	       "response-headers", &response_headers,
684 	       "response-body", &response_body,
685 	       NULL);
686 
687   g_message("status %d", status);
688 
689   xmlFree(buffer);
690 
691   CU_ASSERT(status == 200);
692 
693   sleep(5);
694 
695   /* start audio */
696   doc = xmlNewDoc("1.0");
697 
698   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
699   xmlDocSetRootElement(doc, root_node);
700 
701   osc_packet_node_list = xmlNewNode(NULL,
702 				    BAD_CAST "ags-osc-packet-list");
703 
704   xmlAddChild(root_node,
705 	      osc_packet_node_list);
706 
707   osc_packet_node = xmlNewNode(NULL,
708 				BAD_CAST "ags-osc-packet");
709 
710   xmlAddChild(osc_packet_node_list,
711 	      osc_packet_node);
712 
713   /* OSC message */
714   packet = (guchar *) malloc((4 + start_audio_message_size) * sizeof(guchar));
715 
716   ags_osc_buffer_util_put_int32(packet,
717 				start_audio_message_size);
718   memcpy(packet + 4, start_audio_message, (start_audio_message_size) * sizeof(guchar));
719 
720   data = g_base64_encode(packet,
721 			 4 + start_audio_message_size);
722 
723   xmlNodeSetContent(osc_packet_node,
724 		    data);
725 
726   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
727 
728   /* send message */
729   msg = soup_form_request_new("POST",
730 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
731 			      NULL);
732   soup_message_set_request(msg,
733 			   "text/xml; charset=UTF-8",
734 			   SOUP_MEMORY_COPY,
735 			   buffer,
736 			   buffer_length);
737 
738   xmlFree(buffer);
739 
740   status = soup_session_send_message(soup_session,
741 				     msg);
742 
743   g_object_get(msg,
744 	       "response-headers", &response_headers,
745 	       "response-body", &response_body,
746 	       NULL);
747 
748   g_message("status %d", status);
749 
750   CU_ASSERT(status == 200);
751 
752   sleep(5);
753 
754   /* stop soundcard */
755   doc = xmlNewDoc("1.0");
756 
757   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
758   xmlDocSetRootElement(doc, root_node);
759 
760   osc_packet_node_list = xmlNewNode(NULL,
761 				    BAD_CAST "ags-osc-packet-list");
762 
763   xmlAddChild(root_node,
764 	      osc_packet_node_list);
765 
766   osc_packet_node = xmlNewNode(NULL,
767 				BAD_CAST "ags-osc-packet");
768 
769   xmlAddChild(osc_packet_node_list,
770 	      osc_packet_node);
771 
772   /* OSC message */
773   packet = (guchar *) g_malloc((4 + stop_soundcard_message_size) * sizeof(guchar));
774 
775   ags_osc_buffer_util_put_int32(packet,
776 				stop_soundcard_message_size);
777   memcpy(packet + 4, stop_soundcard_message, (stop_soundcard_message_size) * sizeof(guchar));
778 
779   data = g_base64_encode(packet,
780 			 4 + stop_soundcard_message_size);
781 
782   xmlNodeSetContent(osc_packet_node,
783 		    data);
784 
785   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
786 
787   /* send message */
788   msg = soup_form_request_new("POST",
789 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
790 			      NULL);
791   soup_message_set_request(msg,
792 			   "text/xml; charset=UTF-8",
793 			   SOUP_MEMORY_COPY,
794 			   buffer,
795 			   buffer_length);
796 
797   xmlFree(buffer);
798 
799   status = soup_session_send_message(soup_session,
800 				     msg);
801 
802   g_object_get(msg,
803 	       "response-headers", &response_headers,
804 	       "response-body", &response_body,
805 	       NULL);
806 
807   g_message("status %d", status);
808 
809   CU_ASSERT(status == 200);
810 
811   sleep(5);
812 
813   /* stop sequencer */
814   doc = xmlNewDoc("1.0");
815 
816   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
817   xmlDocSetRootElement(doc, root_node);
818 
819   osc_packet_node_list = xmlNewNode(NULL,
820 				    BAD_CAST "ags-osc-packet-list");
821 
822   xmlAddChild(root_node,
823 	      osc_packet_node_list);
824 
825   osc_packet_node = xmlNewNode(NULL,
826 				BAD_CAST "ags-osc-packet");
827 
828   xmlAddChild(osc_packet_node_list,
829 	      osc_packet_node);
830 
831   /* OSC message */
832   packet = (guchar *) malloc((4 + stop_sequencer_message_size) * sizeof(guchar));
833 
834   ags_osc_buffer_util_put_int32(packet,
835 				stop_sequencer_message_size);
836   memcpy(packet + 4, stop_sequencer_message, (stop_sequencer_message_size) * sizeof(guchar));
837 
838   data = g_base64_encode(packet,
839 			 4 + stop_sequencer_message_size);
840 
841   xmlNodeSetContent(osc_packet_node,
842 		    data);
843 
844   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
845 
846   /* send message */
847   msg = soup_form_request_new("POST",
848 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
849 			      NULL);
850   soup_message_set_request(msg,
851 			   "text/xml; charset=UTF-8",
852 			   SOUP_MEMORY_COPY,
853 			   buffer,
854 			   buffer_length);
855 
856   xmlFree(buffer);
857 
858   status = soup_session_send_message(soup_session,
859 				     msg);
860 
861   g_object_get(msg,
862 	       "response-headers", &response_headers,
863 	       "response-body", &response_body,
864 	       NULL);
865 
866   g_message("status %d", status);
867 
868   CU_ASSERT(status == 200);
869 
870   sleep(5);
871 
872   /* stop audio */
873   doc = xmlNewDoc("1.0");
874 
875   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
876   xmlDocSetRootElement(doc, root_node);
877 
878   osc_packet_node_list = xmlNewNode(NULL,
879 				    BAD_CAST "ags-osc-packet-list");
880 
881   xmlAddChild(root_node,
882 	      osc_packet_node_list);
883 
884   osc_packet_node = xmlNewNode(NULL,
885 				BAD_CAST "ags-osc-packet");
886 
887   xmlAddChild(osc_packet_node_list,
888 	      osc_packet_node);
889 
890   /* OSC message */
891   packet = (guchar *) malloc((4 + stop_audio_message_size) * sizeof(guchar));
892 
893   ags_osc_buffer_util_put_int32(packet,
894 				stop_audio_message_size);
895   memcpy(packet + 4, stop_audio_message, (stop_audio_message_size) * sizeof(guchar));
896 
897   data = g_base64_encode(packet,
898 			 4 + stop_audio_message_size);
899 
900   xmlNodeSetContent(osc_packet_node,
901 		    data);
902 
903   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
904 
905   /* send message */
906   msg = soup_form_request_new("POST",
907 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
908 			      NULL);
909   soup_message_set_request(msg,
910 			   "text/xml; charset=UTF-8",
911 			   SOUP_MEMORY_COPY,
912 			   buffer,
913 			   buffer_length);
914 
915   xmlFree(buffer);
916 
917   status = soup_session_send_message(soup_session,
918 				     msg);
919 
920   g_object_get(msg,
921 	       "response-headers", &response_headers,
922 	       "response-body", &response_body,
923 	       NULL);
924 
925   g_message("status %d", status);
926 
927   CU_ASSERT(status == 200);
928 
929   sleep(5);
930 }
931 
932 void
ags_functional_osc_xmlrpc_server_test_config_controller()933 ags_functional_osc_xmlrpc_server_test_config_controller()
934 {
935   SoupMessage *msg;
936   SoupMessageHeaders *response_headers;
937   SoupMessageBody *response_body;
938 
939   SoupMessageHeadersIter iter;
940   GSList *cookie;
941 
942   xmlDoc *doc;
943   xmlNode *root_node;
944   xmlNode *osc_packet_node_list;
945   xmlNode *osc_packet_node;
946 
947   guchar *message;
948   gchar *data;
949   guchar *packet;
950   xmlChar *buffer;
951 
952   guint config_length;
953   guint length;
954   int buffer_length;
955   guint status;
956 
957   static const guchar *config_message = "/config\x00,s\x00\x00";
958 
959   static const guint config_message_size = 12;
960 
961   /* apply config */
962   doc = xmlNewDoc("1.0");
963 
964   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
965   xmlDocSetRootElement(doc, root_node);
966 
967   osc_packet_node_list = xmlNewNode(NULL,
968 				    BAD_CAST "ags-osc-packet-list");
969 
970   xmlAddChild(root_node,
971 	      osc_packet_node_list);
972 
973   osc_packet_node = xmlNewNode(NULL,
974 				BAD_CAST "ags-osc-packet");
975 
976   xmlAddChild(osc_packet_node_list,
977 	      osc_packet_node);
978 
979   /* OSC message */
980   config_length = strlen(AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_APPLY_CONFIG_ARGUMENT);
981 
982   length = config_message_size + (4 * ceil((double) (config_length + 1) / 4.0));
983 
984   message = (guchar *) malloc(length * sizeof(guchar));
985   memset(message, 0, length * sizeof(guchar));
986 
987   memcpy(message, config_message, config_message_size * sizeof(guchar));
988   memcpy(message + config_message_size, AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_APPLY_CONFIG_ARGUMENT, config_length * sizeof(guchar));
989 
990   packet = (guchar *) g_malloc((4 + length) * sizeof(guchar));
991 
992   ags_osc_buffer_util_put_int32(packet,
993 				length);
994   memcpy(packet + 4, message, (length) * sizeof(guchar));
995 
996   data = g_base64_encode(packet,
997 			 4 + length);
998 
999   xmlNodeSetContent(osc_packet_node,
1000 		    data);
1001 
1002   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
1003 
1004   /* send message */
1005   msg = soup_form_request_new("POST",
1006 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
1007 			      NULL);
1008   soup_message_set_request(msg,
1009 			   "text/xml; charset=UTF-8",
1010 			   SOUP_MEMORY_COPY,
1011 			   buffer,
1012 			   buffer_length);
1013 
1014   xmlFree(buffer);
1015 
1016   status = soup_session_send_message(soup_session,
1017 				     msg);
1018 
1019   g_object_get(msg,
1020 	       "response-headers", &response_headers,
1021 	       "response-body", &response_body,
1022 	       NULL);
1023 
1024   g_message("status %d", status);
1025 
1026   CU_ASSERT(status == 200);
1027 
1028   sleep(5);
1029 }
1030 
1031 void
ags_functional_osc_xmlrpc_server_test_info_controller()1032 ags_functional_osc_xmlrpc_server_test_info_controller()
1033 {
1034   SoupMessage *msg;
1035   SoupMessageHeaders *response_headers;
1036   SoupMessageBody *response_body;
1037 
1038   SoupMessageHeadersIter iter;
1039   GSList *cookie;
1040 
1041   xmlDoc *doc;
1042   xmlNode *root_node;
1043   xmlNode *osc_packet_node_list;
1044   xmlNode *osc_packet_node;
1045 
1046   gchar *data;
1047   guchar *packet;
1048   xmlChar *buffer;
1049 
1050   int buffer_length;
1051   guint status;
1052 
1053   static const guchar *info_message = "/info\x00\x00\x00";
1054 
1055   static const guint info_message_size = 8;
1056 
1057   /* info */
1058   doc = xmlNewDoc("1.0");
1059 
1060   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
1061   xmlDocSetRootElement(doc, root_node);
1062 
1063   osc_packet_node_list = xmlNewNode(NULL,
1064 				    BAD_CAST "ags-osc-packet-list");
1065 
1066   xmlAddChild(root_node,
1067 	      osc_packet_node_list);
1068 
1069   osc_packet_node = xmlNewNode(NULL,
1070 				BAD_CAST "ags-osc-packet");
1071 
1072   xmlAddChild(osc_packet_node_list,
1073 	      osc_packet_node);
1074 
1075   /* OSC message */
1076   packet = (guchar *) g_malloc((4 + info_message_size) * sizeof(guchar));
1077 
1078   ags_osc_buffer_util_put_int32(packet,
1079 				info_message_size);
1080   memcpy(packet + 4, info_message, (info_message_size) * sizeof(guchar));
1081 
1082   data = g_base64_encode(packet,
1083 			 4 + info_message_size);
1084 
1085   xmlNodeSetContent(osc_packet_node,
1086 		    data);
1087 
1088   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
1089 
1090   /* send message */
1091   msg = soup_form_request_new("POST",
1092 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
1093 			      NULL);
1094   soup_message_set_request(msg,
1095 			   "text/xml; charset=UTF-8",
1096 			   SOUP_MEMORY_COPY,
1097 			   buffer,
1098 			   buffer_length);
1099 
1100   xmlFree(buffer);
1101 
1102   status = soup_session_send_message(soup_session,
1103 				     msg);
1104 
1105   g_object_get(msg,
1106 	       "response-headers", &response_headers,
1107 	       "response-body", &response_body,
1108 	       NULL);
1109 
1110   g_message("status %d", status);
1111 
1112   CU_ASSERT(status == 200);
1113 
1114   sleep(5);
1115 }
1116 
1117 void
ags_functional_osc_xmlrpc_server_test_meter_controller()1118 ags_functional_osc_xmlrpc_server_test_meter_controller()
1119 {
1120   SoupMessage *msg;
1121   SoupMessageHeaders *response_headers;
1122   SoupMessageBody *response_body;
1123 
1124   SoupMessageHeadersIter iter;
1125   GSList *cookie;
1126 
1127   xmlDoc *doc;
1128   xmlNode *root_node;
1129   xmlNode *child;
1130   xmlNode *osc_packet_node_list;
1131   xmlNode *osc_packet_node;
1132   xmlNode *login_node;
1133   xmlNode *security_token_node;
1134   xmlNode *redirect_node;
1135 
1136   struct timespec start_time;
1137   struct timespec timeout_delay;
1138   struct timespec idle_delay;
1139 
1140   gchar *login;
1141   gchar *security_token;
1142   gchar *resource_id;
1143   gchar *data;
1144   guchar *packet;
1145   xmlChar *buffer;
1146 
1147   int buffer_length;
1148   volatile gint meter_packet_count;
1149   guint i;
1150   gboolean retval;
1151   guint status;
1152 
1153   static const guchar *enable_peak_message = "/meter\x00\x00,sT\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-15]/AgsPeakChannel[0]/AgsPort[\"./peak[0]\"]:value\x00";
1154   static const guchar *disable_peak_message = "/meter\x00\x00,sF\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-15]/AgsPeakChannel[0]/AgsPort[\"./peak[0]\"]:value\x00";
1155 
1156   static const guint enable_peak_message_size = 112;
1157   static const guint disable_peak_message_size = 112;
1158 
1159   /* meter */
1160   doc = xmlNewDoc("1.0");
1161 
1162   root_node = xmlNewNode(NULL, "ags-osc-over-xmlrpc");
1163   xmlDocSetRootElement(doc, root_node);
1164 
1165   osc_packet_node_list = xmlNewNode(NULL,
1166 				    BAD_CAST "ags-osc-packet-list");
1167 
1168   xmlAddChild(root_node,
1169 	      osc_packet_node_list);
1170 
1171   osc_packet_node = xmlNewNode(NULL,
1172 				BAD_CAST "ags-osc-packet");
1173 
1174   xmlAddChild(osc_packet_node_list,
1175 	      osc_packet_node);
1176 
1177   /* OSC message */
1178   packet = (guchar *) g_malloc((4 + enable_peak_message_size) * sizeof(guchar));
1179 
1180   ags_osc_buffer_util_put_int32(packet,
1181 				enable_peak_message_size);
1182   memcpy(packet + 4, enable_peak_message, (enable_peak_message_size) * sizeof(guchar));
1183 
1184   data = g_base64_encode(packet,
1185 			 4 + enable_peak_message_size);
1186 
1187   xmlNodeSetContent(osc_packet_node,
1188 		    data);
1189 
1190   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
1191 
1192   /* send message */
1193   msg = soup_form_request_new("POST",
1194 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
1195 			      NULL);
1196   soup_message_set_request(msg,
1197 			   "text/xml; charset=UTF-8",
1198 			   SOUP_MEMORY_COPY,
1199 			   buffer,
1200 			   buffer_length);
1201 
1202   xmlFree(buffer);
1203 
1204   status = soup_session_send_message(soup_session,
1205 				     msg);
1206 
1207   sleep(5);
1208 
1209   response_headers = NULL;
1210   response_body = NULL;
1211 
1212   g_object_get(msg,
1213 	       "response-headers", &response_headers,
1214 	       "response-body", &response_body,
1215 	       NULL);
1216 
1217   g_message("status %d", status);
1218 
1219   CU_ASSERT(status == 200);
1220 
1221   /* parse cookies */
1222   cookie = soup_cookies_from_response(msg);
1223 
1224   login = NULL;
1225   security_token = NULL;
1226 
1227   while(cookie != NULL){
1228     char *cookie_name;
1229 
1230     cookie_name = soup_cookie_get_name(cookie->data);
1231 
1232     if(!g_ascii_strncasecmp(cookie_name,
1233 			    "ags-srv-login",
1234 			    14)){
1235       login =
1236 	meter_data.login = soup_cookie_get_value(cookie->data);
1237     }else if(!g_ascii_strncasecmp(cookie_name,
1238 				  "ags-srv-security-token",
1239 				  23)){
1240       security_token =
1241 	meter_data.security_token = soup_cookie_get_value(cookie->data);
1242     }
1243 
1244     if(login != NULL &&
1245        security_token != NULL){
1246       break;
1247     }
1248 
1249     cookie = cookie->next;
1250   }
1251 
1252   /* parse response */
1253   g_message("%s", response_body->data);
1254 
1255   doc = xmlParseDoc(response_body->data);
1256 
1257   CU_ASSERT(doc != NULL);
1258 
1259   root_node = xmlDocGetRootElement(doc);
1260 
1261   CU_ASSERT(root_node != NULL);
1262 
1263   child = NULL;
1264 
1265   if(root_node != NULL){
1266     child = root_node->children;
1267   }
1268 
1269   resource_id = NULL;
1270 
1271   while(child != NULL){
1272     if(child->type == XML_ELEMENT_NODE){
1273       if(!xmlStrncmp(child->name,
1274 		     "ags-srv-redirect",
1275 		     17)){
1276 	xmlChar *tmp_resource_id;
1277 
1278 	tmp_resource_id = xmlGetProp(child,
1279 				     "resource-id");
1280 
1281 	resource_id =
1282 	  meter_data.resource_id =  g_strdup(tmp_resource_id);
1283 
1284 	xmlFree(tmp_resource_id);
1285 
1286 	break;
1287       }
1288     }
1289 
1290     child = child->next;
1291   }
1292 
1293   CU_ASSERT(resource_id != NULL);
1294 
1295   /* read packets */
1296 #ifdef __APPLE__
1297   host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
1298 
1299   clock_get_time(cclock, &mts);
1300   mach_port_deallocate(mach_task_self(), cclock);
1301 
1302   start_time.tv_sec = mts.tv_sec;
1303   start_time.tv_nsec = mts.tv_nsec;
1304 #else
1305   clock_gettime(CLOCK_MONOTONIC, &start_time);
1306 #endif
1307 
1308   timeout_delay.tv_sec = 180;
1309   timeout_delay.tv_nsec = 0;
1310 
1311   idle_delay.tv_sec = 0;
1312   idle_delay.tv_nsec = AGS_NSEC_PER_SEC / 30;
1313 
1314   g_atomic_int_set(&(meter_packet_count),
1315 		   0);
1316   i = 0;
1317 
1318   /* follow redirect */
1319   msg = soup_message_new("GET",
1320 			 "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc/response");
1321 
1322   meter_data.meter_packet_count = &meter_packet_count;
1323   soup_session_websocket_connect_async(soup_session,
1324 				       msg,
1325 				       NULL,
1326 				       NULL,
1327 				       NULL,
1328 				       ags_functional_osc_xmlrpc_server_test_websocket_callback,
1329 				       NULL);
1330 
1331   g_message("wait for websocket");
1332 
1333   while(!ags_time_timeout_expired(&start_time,
1334 				  &timeout_delay)){
1335     g_main_context_iteration(test_main_context,
1336 			     FALSE);
1337     //empty
1338 
1339     nanosleep(&idle_delay,
1340 	      NULL);
1341   }
1342 
1343   g_message("Total received packets: %d", g_atomic_int_get(&meter_packet_count));
1344 
1345   CU_ASSERT(g_atomic_int_get(&(meter_packet_count)) >= AGS_FUNCTIONAL_OSC_XMLRPC_SERVER_TEST_METER_PACKET_COUNT);
1346 
1347   /* disable meter */
1348   packet = (guchar *) malloc((4 + disable_peak_message_size) * sizeof(guchar));
1349 
1350   ags_osc_buffer_util_put_int32(packet,
1351 				disable_peak_message_size);
1352   memcpy(packet + 4, disable_peak_message, (disable_peak_message_size) * sizeof(guchar));
1353 
1354   data = g_base64_encode(packet,
1355 			 4 + disable_peak_message_size);
1356 
1357   xmlNodeSetContent(osc_packet_node,
1358 		    data);
1359 
1360   xmlDocDumpFormatMemoryEnc(doc, &buffer, &buffer_length, "UTF-8", TRUE);
1361 
1362   /* send message */
1363   msg = soup_form_request_new("POST",
1364 			      "http://127.0.0.1:8080/ags-xmlrpc/ags-osc-over-xmlrpc",
1365 			      NULL);
1366   soup_message_set_request(msg,
1367 			   "text/xml; charset=UTF-8",
1368 			   SOUP_MEMORY_COPY,
1369 			   buffer,
1370 			   buffer_length);
1371 
1372   xmlFree(buffer);
1373 
1374   status = soup_session_send_message(soup_session,
1375 				     msg);
1376 
1377   response_headers = NULL;
1378   response_body = NULL;
1379 
1380   g_object_get(msg,
1381 	       "response-headers", &response_headers,
1382 	       "response-body", &response_body,
1383 	       NULL);
1384 
1385   g_message("status %d", status);
1386 
1387   CU_ASSERT(status == 200);
1388 
1389   //TODO:JK: implement me
1390 }
1391 
1392 void
ags_functional_osc_xmlrpc_server_test_node_controller()1393 ags_functional_osc_xmlrpc_server_test_node_controller()
1394 {
1395   SoupMessage *msg;
1396   SoupMessageHeaders *response_headers;
1397   SoupMessageBody *response_body;
1398 
1399   SoupMessageHeadersIter iter;
1400   GSList *cookie;
1401 
1402   xmlDoc *doc;
1403   xmlNode *root_node;
1404   xmlNode *osc_packet_node_list;
1405   xmlNode *osc_packet_node;
1406 
1407   gchar *data;
1408   guchar *packet;
1409   xmlChar *buffer;
1410 
1411   int buffer_length;
1412   guint status;
1413 
1414   static const guchar *volume_message = "/node\x00\x00\x00,s\x00\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-1]/AgsVolumeChannel[0]/AgsPort[\"./volume[0]\"]:value\x00\x00";
1415 
1416   static const guint volume_message_size = 116;
1417 
1418   //TODO:JK: implement me
1419 }
1420 
1421 void
ags_functional_osc_xmlrpc_server_test_renew_controller()1422 ags_functional_osc_xmlrpc_server_test_renew_controller()
1423 {
1424   SoupMessage *msg;
1425   SoupMessageHeaders *response_headers;
1426   SoupMessageBody *response_body;
1427 
1428   SoupMessageHeadersIter iter;
1429   GSList *cookie;
1430 
1431   xmlDoc *doc;
1432   xmlNode *root_node;
1433   xmlNode *osc_packet_node_list;
1434   xmlNode *osc_packet_node;
1435 
1436   gchar *data;
1437   guchar *packet;
1438   xmlChar *buffer;
1439 
1440   int buffer_length;
1441   guint status;
1442 
1443   static const guchar *mute_message = "/renew\x00\x00,sf\x00/AgsSoundProvider/AgsAudio[\"test-panel\"]/AgsInput[0-1]/AgsMuteChannel[0]/AgsPort[\"./muted[0]\"]:value\x00\x00\x00\x00\x00\x00";
1444 
1445   static const guint mute_message_size = 120;
1446 
1447   //TODO:JK: implement me
1448 }
1449 
1450 void
ags_functional_osc_xmlrpc_server_test_status_controller()1451 ags_functional_osc_xmlrpc_server_test_status_controller()
1452 {
1453   SoupMessage *msg;
1454   SoupMessageHeaders *response_headers;
1455   SoupMessageBody *response_body;
1456 
1457   SoupMessageHeadersIter iter;
1458   GSList *cookie;
1459 
1460   xmlDoc *doc;
1461   xmlNode *root_node;
1462   xmlNode *osc_packet_node_list;
1463   xmlNode *osc_packet_node;
1464 
1465   gchar *data;
1466   guchar *packet;
1467   xmlChar *buffer;
1468 
1469   int buffer_length;
1470   guint status;
1471 
1472   static const guchar *status_message = "/status\x00,\x00\x00\x00";
1473 
1474   static const guint status_message_size = 12;
1475 
1476   //TODO:JK: implement me
1477 }
1478 
1479 int
main(int argc,char ** argv)1480 main(int argc, char **argv)
1481 {
1482   add_thread = g_thread_new("libags_audio.so - functional OSC XMLRPC server test",
1483 			    ags_functional_osc_xmlrpc_server_test_add_thread,
1484 			    NULL);
1485 
1486   g_main_loop_run(g_main_loop_new(g_main_context_default(),
1487 				  FALSE));
1488 
1489   g_thread_join(add_thread);
1490 
1491   return(-1);
1492 }
1493