2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
21 * @file conversation/test_conversation_api.c
22 * @brief testcase for conversation_api.c
24 * This test performs the operations of a call to a phone
25 * where the phone user picks up and then the call is
26 * terminated by the party that initiated the call. The
27 * actual transmission of voice data is not tested.
30 #include "gnunet_util_lib.h"
31 #include "gnunet_testing_lib.h"
32 #include "gnunet_gnsrecord_lib.h"
33 #include "gnunet_conversation_service.h"
34 #include "gnunet_identity_service.h"
35 #include "gnunet_namestore_service.h"
37 #define FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
41 static const struct GNUNET_CONFIGURATION_Handle *cfg;
43 static struct GNUNET_IDENTITY_Handle *id;
45 static struct GNUNET_IDENTITY_Operation *op;
47 static struct GNUNET_CONVERSATION_Phone *phone;
49 static struct GNUNET_NAMESTORE_Handle *ns;
51 static struct GNUNET_CONVERSATION_Call *call;
53 static struct GNUNET_NAMESTORE_QueueEntry *qe;
55 static struct GNUNET_CONVERSATION_Caller *active_caller;
57 static char *gns_name;
59 static char *gns_caller_id;
61 static GNUNET_MICROPHONE_RecordedDataCallback phone_rdc;
63 static void *phone_rdc_cls;
65 static GNUNET_MICROPHONE_RecordedDataCallback call_rdc;
67 static void *call_rdc_cls;
69 static GNUNET_SCHEDULER_TaskIdentifier phone_task;
71 static GNUNET_SCHEDULER_TaskIdentifier call_task;
75 phone_send (void *cls,
76 const struct GNUNET_SCHEDULER_TaskContext *tc)
78 static unsigned int i;
81 GNUNET_assert (NULL != phone_rdc);
82 GNUNET_snprintf (buf, sizeof (buf), "phone-%u", i++);
83 phone_rdc (phone_rdc_cls, strlen (buf) + 1, buf);
84 phone_task = GNUNET_SCHEDULER_add_delayed (FREQ,
91 const struct GNUNET_SCHEDULER_TaskContext *tc)
93 static unsigned int i;
96 GNUNET_assert (NULL != call_rdc);
97 GNUNET_snprintf (buf, sizeof (buf), "call-%u", i++);
98 call_rdc (call_rdc_cls, strlen (buf) + 1, buf);
99 call_task = GNUNET_SCHEDULER_add_delayed (FREQ,
105 enable_speaker (void *cls)
107 const char *origin = cls;
110 "Speaker %s enabled\n",
117 disable_speaker (void *cls)
119 const char *origin = cls;
122 "Speaker %s disabled\n",
132 const char *origin = cls;
133 static unsigned int phone_i;
134 static unsigned int call_i;
137 if (0 == strcmp (origin, "phone"))
138 GNUNET_snprintf (buf, sizeof (buf), "phone-%u", phone_i++);
140 GNUNET_snprintf (buf, sizeof (buf), "call-%u", call_i++);
141 if ( (data_size != strlen (buf) + 1) ||
142 (0 != strncmp (buf, data, data_size)) )
145 "Expected %s, received %.*s\n",
148 (const char *) data);
150 if ( (20 < call_i) &&
153 /* time to hang up ... */
154 GNUNET_CONVERSATION_call_stop (call);
161 destroy_speaker (void *cls)
163 const char *origin = cls;
165 fprintf (stderr, "Speaker %s destroyed\n", origin);
169 static struct GNUNET_SPEAKER_Handle caller_speaker = {
178 static struct GNUNET_SPEAKER_Handle phone_speaker = {
188 enable_mic (void *cls,
189 GNUNET_MICROPHONE_RecordedDataCallback rdc,
192 const char *origin = cls;
197 if (0 == strcmp (origin, "phone"))
200 phone_rdc_cls = rdc_cls;
201 phone_task = GNUNET_SCHEDULER_add_now (&phone_send, NULL);
206 call_rdc_cls = rdc_cls;
207 call_task = GNUNET_SCHEDULER_add_now (&call_send, NULL);
214 disable_mic (void *cls)
216 const char *origin = cls;
221 if (0 == strcmp (origin, "phone"))
224 phone_rdc_cls = NULL;
225 GNUNET_SCHEDULER_cancel (phone_task);
231 GNUNET_SCHEDULER_cancel (call_task);
238 destroy_mic (void *cls)
240 const char *origin = cls;
243 "Mic %s destroyed\n",
248 static struct GNUNET_MICROPHONE_Handle caller_mic = {
256 static struct GNUNET_MICROPHONE_Handle phone_mic = {
265 * Signature of the main function of a task.
268 * @param tc context information (why was this task triggered now)
271 end_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
273 GNUNET_SCHEDULER_shutdown ();
276 GNUNET_IDENTITY_cancel (op);
281 GNUNET_CONVERSATION_call_stop (call);
286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from PHONE service.\n");
287 GNUNET_CONVERSATION_phone_destroy (phone);
292 GNUNET_IDENTITY_disconnect (id);
297 GNUNET_NAMESTORE_cancel (qe);
302 GNUNET_NAMESTORE_disconnect (ns);
309 caller_event_handler (void *cls,
310 enum GNUNET_CONVERSATION_CallerEventCode code)
314 case GNUNET_CONVERSATION_EC_CALLER_SUSPEND:
315 case GNUNET_CONVERSATION_EC_CALLER_RESUME:
316 fprintf (stderr, "Unexpected caller code: %d\n", code);
323 phone_event_handler (void *cls,
324 enum GNUNET_CONVERSATION_PhoneEventCode code,
325 struct GNUNET_CONVERSATION_Caller *caller,
326 const char *caller_id)
328 static enum GNUNET_CONVERSATION_PhoneEventCode expect
329 = GNUNET_CONVERSATION_EC_PHONE_RING;
331 GNUNET_break (0 == strcmp (caller_id,
333 GNUNET_break (code == expect);
336 case GNUNET_CONVERSATION_EC_PHONE_RING:
337 active_caller = caller;
338 GNUNET_CONVERSATION_caller_pick_up (caller,
339 &caller_event_handler,
343 expect = GNUNET_CONVERSATION_EC_PHONE_HUNG_UP;
345 case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP:
346 GNUNET_break (caller == active_caller);
347 active_caller = NULL;
349 GNUNET_SCHEDULER_shutdown ();
352 fprintf (stderr, "Unexpected phone code: %d\n", code);
359 call_event_handler (void *cls,
360 enum GNUNET_CONVERSATION_CallEventCode code)
362 static enum GNUNET_CONVERSATION_CallEventCode expect
363 = GNUNET_CONVERSATION_EC_CALL_RINGING;
365 GNUNET_break (code == expect);
368 case GNUNET_CONVERSATION_EC_CALL_RINGING:
369 expect = GNUNET_CONVERSATION_EC_CALL_PICKED_UP;
371 case GNUNET_CONVERSATION_EC_CALL_PICKED_UP:
374 case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL:
375 case GNUNET_CONVERSATION_EC_CALL_HUNG_UP:
376 case GNUNET_CONVERSATION_EC_CALL_SUSPENDED:
377 case GNUNET_CONVERSATION_EC_CALL_RESUMED:
378 fprintf (stderr, "Unexpected call code: %d\n", code);
385 caller_ego_create_cont (void *cls,
389 GNUNET_assert (NULL == emsg);
394 namestore_put_cont (void *cls,
399 GNUNET_assert (GNUNET_YES == success);
400 GNUNET_assert (NULL == emsg);
401 GNUNET_assert (NULL == op);
402 op = GNUNET_IDENTITY_create (id, "caller-ego", &caller_ego_create_cont, NULL);
407 identity_cb (void *cls,
408 struct GNUNET_IDENTITY_Ego *ego,
412 struct GNUNET_GNSRECORD_Data rd;
413 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
419 if (0 == strcmp (name, "phone-ego"))
421 GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
422 GNUNET_asprintf (&gns_name,
424 GNUNET_GNSRECORD_pkey_to_zkey (&pub));
425 phone = GNUNET_CONVERSATION_phone_create (cfg,
427 &phone_event_handler,
429 GNUNET_assert (NULL != phone);
430 memset (&rd, 0, sizeof (rd));
431 GNUNET_CONVERSATION_phone_get_record (phone,
433 GNUNET_assert (rd.record_type == GNUNET_GNSRECORD_TYPE_PHONE);
434 rd.expiration_time = UINT64_MAX;
435 qe = GNUNET_NAMESTORE_records_store (ns,
436 GNUNET_IDENTITY_ego_get_private_key (ego),
437 "phone" /* GNS label */,
444 if (0 == strcmp (name, "caller-ego"))
446 GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
447 GNUNET_asprintf (&gns_caller_id,
449 GNUNET_GNSRECORD_pkey_to_zkey (&pub));
450 call = GNUNET_CONVERSATION_call_start (cfg,
463 phone_ego_create_cont (void *cls,
467 GNUNET_assert (NULL == emsg);
473 const struct GNUNET_CONFIGURATION_Handle *c,
474 struct GNUNET_TESTING_Peer *peer)
477 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
478 (GNUNET_TIME_UNIT_MINUTES, 1), &end_test,
480 id = GNUNET_IDENTITY_connect (cfg,
483 op = GNUNET_IDENTITY_create (id, "phone-ego", &phone_ego_create_cont, NULL);
484 ns = GNUNET_NAMESTORE_connect (cfg);
489 main (int argc, char *argv[])
491 if (0 != GNUNET_TESTING_peer_run ("test_conversation_api",
492 "test_conversation.conf",
498 /* end of test_conversation_api.c */