aboutsummaryrefslogtreecommitdiff
path: root/src/conversation/test_conversation_api_twocalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conversation/test_conversation_api_twocalls.c')
-rw-r--r--src/conversation/test_conversation_api_twocalls.c643
1 files changed, 0 insertions, 643 deletions
diff --git a/src/conversation/test_conversation_api_twocalls.c b/src/conversation/test_conversation_api_twocalls.c
deleted file mode 100644
index 9abf91d0b..000000000
--- a/src/conversation/test_conversation_api_twocalls.c
+++ /dev/null
@@ -1,643 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2018x GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file conversation/test_conversation_api_twocalls.c
22 * @brief testcase for conversation_api.c
23 *
24 * This test performs the operations of TWO calls made to a phone
25 * where the phone user picks up one, suspends it, picks up the
26 * second one; eventually, the initiator hangs up, the callee
27 * resumes the first call, and then the initiator hangs up the
28 * second call.
29 */
30#include "platform.h"
31#include "gnunet_util_lib.h"
32#include "gnunet_testing_lib.h"
33#include "gnunet_gnsrecord_lib.h"
34#include "gnunet_conversation_service.h"
35#include "gnunet_identity_service.h"
36#include "gnunet_namestore_service.h"
37
38#define FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
39
40#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 25)
41
42#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
43
44#define LOG_DEBUG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
45
46static const struct GNUNET_CONFIGURATION_Handle *cfg;
47
48static struct GNUNET_IDENTITY_Handle *id;
49
50static struct GNUNET_IDENTITY_Operation *op;
51
52static struct GNUNET_CONVERSATION_Phone *phone;
53
54static struct GNUNET_NAMESTORE_Handle *ns;
55
56static struct GNUNET_CONVERSATION_Call *call1;
57
58static struct GNUNET_CONVERSATION_Call *call2;
59
60static struct GNUNET_NAMESTORE_QueueEntry *qe;
61
62static struct GNUNET_CONVERSATION_Caller *active_caller1;
63
64static struct GNUNET_CONVERSATION_Caller *active_caller2;
65
66static char *gns_name;
67
68static char *gns_caller_id;
69
70static GNUNET_MICROPHONE_RecordedDataCallback phone_rdc;
71
72static void *phone_rdc_cls;
73
74static struct GNUNET_SCHEDULER_Task *phone_task;
75
76static struct GNUNET_SCHEDULER_Task *timeout_task;
77
78/**
79 * Variable for recognizing caller1
80 */
81static const char *caller1 = "caller1";
82
83/**
84 * Variable for recognizing caller2
85 */
86static const char *caller2 = "caller2";
87
88/**
89 * Variable for recognizing callee
90 */
91static const char *phone0 = "phone";
92
93
94#define CALLER1 &caller1
95#define CALLER2 &caller2
96#define PHONE0 &phone0
97
98#define CLS_STR(caller) (*((char **) caller))
99
100
101/**
102 * Did caller1 call finish successfully
103 */
104static int call1_finished;
105
106/**
107 * Did caller2 call finish successfully
108 */
109static int call2_finished;
110
111struct MicContext
112{
113 GNUNET_MICROPHONE_RecordedDataCallback rdc;
114
115 void *rdc_cls;
116
117 struct GNUNET_SCHEDULER_Task *call_task;
118};
119
120static struct MicContext call1_mic_ctx;
121static struct MicContext call2_mic_ctx;
122// static struct MicContext phone_mic_ctx;
123
124
125static void
126phone_send (void *cls)
127{
128 char buf[32];
129
130 (void) cls;
131 GNUNET_assert (NULL != phone_rdc);
132 GNUNET_snprintf (buf, sizeof(buf), "phone");
133 phone_rdc (phone_rdc_cls, strlen (buf) + 1, buf);
134 phone_task = GNUNET_SCHEDULER_add_delayed (FREQ, &phone_send, NULL);
135}
136
137
138static void
139call_send (void *cls)
140{
141 struct MicContext *mc = cls;
142 char buf[32];
143
144 (void) cls;
145 GNUNET_assert (NULL != mc->rdc);
146 GNUNET_snprintf (buf, sizeof(buf), "call");
147 mc->rdc (mc->rdc_cls, strlen (buf) + 1, buf);
148 mc->call_task = GNUNET_SCHEDULER_add_delayed (FREQ, &call_send, mc);
149}
150
151
152static int
153enable_speaker (void *cls)
154{
155 const char *origin = CLS_STR (cls);
156
157 (void) cls;
158 LOG_DEBUG ("Speaker %s enabled\n", origin);
159 return GNUNET_OK;
160}
161
162
163static void
164disable_speaker (void *cls)
165{
166 const char *origin = CLS_STR (cls);
167
168 (void) cls;
169 LOG_DEBUG ("Speaker %s disabled\n", origin);
170}
171
172
173static void
174play (void *cls, size_t data_size, const void *data)
175{
176 static unsigned int phone_i;
177 static unsigned int call_i;
178
179 (void) cls;
180 if (0 == strncmp ("call", data, data_size))
181 call_i++;
182 else if (0 == strncmp ("phone", data, data_size))
183 phone_i++;
184 else
185 {
186 LOG_DEBUG ("Received %u bytes of unexpected data `%.*s'\n",
187 (unsigned int) data_size,
188 (int) data_size,
189 (const char *) data);
190 }
191
192 if ((20 < call_i) && (20 < phone_i) && (CALLER2 == cls))
193 {
194 /* time to hang up ... */
195 GNUNET_CONVERSATION_call_stop (call2);
196 call2 = NULL;
197 /* reset counters */
198 call_i = 0;
199 phone_i = 0;
200 call2_finished = GNUNET_YES;
201 }
202 if ((20 < call_i) && (20 < phone_i) && (CALLER1 == cls))
203 {
204 /* time to hang up ... */
205 GNUNET_CONVERSATION_call_stop (call1);
206 call1 = NULL;
207 call_i = 0;
208 phone_i = 0;
209 call1_finished = GNUNET_YES;
210 }
211}
212
213
214static void
215destroy_speaker (void *cls)
216{
217 const char *origin = CLS_STR (cls);
218
219 LOG_DEBUG ("Speaker %s destroyed\n", origin);
220}
221
222
223static struct GNUNET_SPEAKER_Handle call1_speaker = { &enable_speaker,
224 &play,
225 &disable_speaker,
226 &destroy_speaker,
227 CALLER1 };
228
229
230static struct GNUNET_SPEAKER_Handle call2_speaker = { &enable_speaker,
231 &play,
232 &disable_speaker,
233 &destroy_speaker,
234 CALLER2 };
235
236
237static struct GNUNET_SPEAKER_Handle phone_speaker = { &enable_speaker,
238 &play,
239 &disable_speaker,
240 &destroy_speaker,
241 PHONE0 };
242
243
244static int
245enable_mic (void *cls,
246 GNUNET_MICROPHONE_RecordedDataCallback rdc,
247 void *rdc_cls)
248{
249 const char *origin = CLS_STR (cls);
250 struct MicContext *mc;
251
252 LOG_DEBUG ("Mic %s enabled\n", origin);
253 if (PHONE0 == cls)
254 {
255 phone_rdc = rdc;
256 phone_rdc_cls = rdc_cls;
257 GNUNET_break (NULL == phone_task);
258 phone_task = GNUNET_SCHEDULER_add_now (&phone_send, NULL);
259 return GNUNET_OK;
260 }
261 mc = (CALLER1 == cls) ? &call1_mic_ctx : &call2_mic_ctx;
262 mc->rdc = rdc;
263 mc->rdc_cls = rdc_cls;
264 GNUNET_break (NULL == mc->call_task);
265 mc->call_task = GNUNET_SCHEDULER_add_now (&call_send, mc);
266 return GNUNET_OK;
267}
268
269
270static void
271disable_mic (void *cls)
272{
273 const char *origin = CLS_STR (cls);
274 struct MicContext *mc;
275
276 LOG_DEBUG ("Mic %s disabled\n", origin);
277 if (PHONE0 == cls)
278 {
279 phone_rdc = NULL;
280 phone_rdc_cls = NULL;
281 GNUNET_SCHEDULER_cancel (phone_task);
282 phone_task = NULL;
283 return;
284 }
285 mc = (CALLER1 == cls) ? &call1_mic_ctx : &call2_mic_ctx;
286 mc->rdc = NULL;
287 mc->rdc_cls = NULL;
288 GNUNET_SCHEDULER_cancel (mc->call_task);
289 mc->call_task = NULL;
290}
291
292
293static void
294destroy_mic (void *cls)
295{
296 const char *origin = CLS_STR (cls);
297
298 LOG_DEBUG ("Mic %s destroyed\n", origin);
299}
300
301
302static struct GNUNET_MICROPHONE_Handle call1_mic = { &enable_mic,
303 &disable_mic,
304 &destroy_mic,
305 CALLER1 };
306
307
308static struct GNUNET_MICROPHONE_Handle call2_mic = { &enable_mic,
309 &disable_mic,
310 &destroy_mic,
311 CALLER2 };
312
313
314static struct GNUNET_MICROPHONE_Handle phone_mic = { &enable_mic,
315 &disable_mic,
316 &destroy_mic,
317 PHONE0 };
318
319
320/**
321 * Function run on timeout.
322 *
323 * @param cls closure
324 */
325static void
326end_test (void *cls)
327{
328 (void) cls;
329 timeout_task = NULL;
330 fprintf (stderr, "Timeout!\n");
331 GNUNET_SCHEDULER_shutdown ();
332}
333
334
335/**
336 * Function run on shutdown.
337 *
338 * @param cls closure
339 */
340static void
341do_shutdown (void *cls)
342{
343 (void) cls;
344 if (NULL != timeout_task)
345 {
346 GNUNET_SCHEDULER_cancel (timeout_task);
347 timeout_task = NULL;
348 }
349 if (NULL != op)
350 {
351 GNUNET_IDENTITY_cancel (op);
352 op = NULL;
353 }
354 if (NULL != call1)
355 {
356 GNUNET_CONVERSATION_call_stop (call1);
357 call1 = NULL;
358 }
359 if (NULL != call2)
360 {
361 GNUNET_CONVERSATION_call_stop (call2);
362 call2 = NULL;
363 }
364 if (NULL != phone)
365 {
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from PHONE service.\n");
367 GNUNET_CONVERSATION_phone_destroy (phone);
368 phone = NULL;
369 }
370 if (NULL != id)
371 {
372 GNUNET_IDENTITY_disconnect (id);
373 id = NULL;
374 }
375 if (NULL != qe)
376 {
377 GNUNET_NAMESTORE_cancel (qe);
378 qe = NULL;
379 }
380 if (NULL != ns)
381 {
382 GNUNET_NAMESTORE_disconnect (ns);
383 ns = NULL;
384 }
385}
386
387
388static void
389caller_event_handler (void *cls, enum GNUNET_CONVERSATION_CallerEventCode code)
390{
391 (void) cls;
392 switch (code)
393 {
394 case GNUNET_CONVERSATION_EC_CALLER_SUSPEND:
395 case GNUNET_CONVERSATION_EC_CALLER_RESUME:
396 LOG (GNUNET_ERROR_TYPE_WARNING, "Unexpected caller code: %d\n", code);
397 break;
398 }
399}
400
401
402static void
403phone_event_handler (void *cls,
404 enum GNUNET_CONVERSATION_PhoneEventCode code,
405 struct GNUNET_CONVERSATION_Caller *caller,
406 const struct GNUNET_IDENTITY_PublicKey *caller_id)
407{
408 const char *cid;
409
410 (void) cls;
411 (void) caller_id;
412
413 switch (code)
414 {
415 case GNUNET_CONVERSATION_EC_PHONE_RING:
416 if (NULL == active_caller1)
417 {
418 active_caller1 = caller;
419 cid = "caller1";
420 GNUNET_CONVERSATION_caller_pick_up (caller,
421 &caller_event_handler,
422 (void *) cid,
423 &phone_speaker,
424 &phone_mic);
425 }
426 else
427 {
428 GNUNET_CONVERSATION_caller_suspend (active_caller1);
429 active_caller2 = caller;
430 cid = "caller2";
431 GNUNET_CONVERSATION_caller_pick_up (caller,
432 &caller_event_handler,
433 (void *) cid,
434 &phone_speaker,
435 &phone_mic);
436 }
437 break;
438
439 case GNUNET_CONVERSATION_EC_PHONE_HUNG_UP:
440 if (caller == active_caller2)
441 {
442 active_caller2 = NULL;
443 GNUNET_CONVERSATION_caller_resume (active_caller1,
444 &phone_speaker,
445 &phone_mic);
446 }
447 else if (caller == active_caller1)
448 {
449 active_caller1 = NULL;
450 GNUNET_break (NULL == active_caller2);
451 GNUNET_SCHEDULER_shutdown ();
452 }
453 break;
454
455 default:
456 LOG (GNUNET_ERROR_TYPE_WARNING, "Unexpected phone code: %d\n", code);
457 break;
458 }
459}
460
461
462static void
463call_event_handler (void *cls, enum GNUNET_CONVERSATION_CallEventCode code)
464{
465 const char *cid = cls;
466
467 switch (code)
468 {
469 case GNUNET_CONVERSATION_EC_CALL_RINGING:
470 break;
471
472 case GNUNET_CONVERSATION_EC_CALL_PICKED_UP:
473 LOG_DEBUG ("Call %s picked\n", cid);
474 break;
475
476 case GNUNET_CONVERSATION_EC_CALL_GNS_FAIL:
477 LOG_DEBUG ("Call %s GNS lookup failed \n", cid);
478 break;
479
480 case GNUNET_CONVERSATION_EC_CALL_HUNG_UP:
481 LOG_DEBUG ("Call %s hungup\n", cid);
482 if (0 == strcmp (cid, "call1"))
483 call1 = NULL;
484 else
485 call2 = NULL;
486 break;
487
488 case GNUNET_CONVERSATION_EC_CALL_SUSPENDED:
489 LOG_DEBUG ("Call %s suspended\n", cid);
490 break;
491
492 case GNUNET_CONVERSATION_EC_CALL_RESUMED:
493 LOG_DEBUG ("Call %s resumed\n", cid);
494 break;
495
496 case GNUNET_CONVERSATION_EC_CALL_ERROR:
497 GNUNET_break (0);
498 if (0 == strcmp (cid, "call1"))
499 call1 = NULL;
500 else
501 call2 = NULL;
502 GNUNET_SCHEDULER_shutdown ();
503 break;
504 }
505}
506
507
508static void
509caller_ego_create_cont (void *cls,
510 const struct GNUNET_IDENTITY_PrivateKey *pk,
511 const char *emsg)
512{
513 (void) cls;
514 op = NULL;
515 GNUNET_assert (NULL == emsg);
516}
517
518
519static void
520namestore_put_cont (void *cls, int32_t success, const char *emsg)
521{
522 (void) cls;
523 qe = NULL;
524 GNUNET_assert (GNUNET_YES == success);
525 GNUNET_assert (NULL == emsg);
526 GNUNET_assert (NULL == op);
527 op = GNUNET_IDENTITY_create (id, "caller-ego", NULL,
528 GNUNET_IDENTITY_TYPE_ECDSA,
529 &caller_ego_create_cont,
530 NULL);
531}
532
533
534static void
535identity_cb (void *cls,
536 struct GNUNET_IDENTITY_Ego *ego,
537 void **ctx,
538 const char *name)
539{
540 struct GNUNET_GNSRECORD_Data rd;
541 struct GNUNET_IDENTITY_PublicKey pub;
542
543 (void) cls;
544 (void) ctx;
545 if (NULL == name)
546 return;
547 if (NULL == ego)
548 return;
549 if (0 == strcmp (name, "phone-ego"))
550 {
551 GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
552 GNUNET_asprintf (&gns_name,
553 "phone.%s",
554 GNUNET_GNSRECORD_pkey_to_zkey (&pub));
555 phone =
556 GNUNET_CONVERSATION_phone_create (cfg, ego, &phone_event_handler, NULL);
557 GNUNET_assert (NULL != phone);
558 memset (&rd, 0, sizeof(rd));
559 GNUNET_CONVERSATION_phone_get_record (phone, &rd);
560 GNUNET_assert (rd.record_type == GNUNET_GNSRECORD_TYPE_PHONE);
561 rd.expiration_time = UINT64_MAX;
562 qe =
563 GNUNET_NAMESTORE_records_store (ns,
564 GNUNET_IDENTITY_ego_get_private_key (ego),
565 "phone" /* GNS label */,
566 1,
567 &rd,
568 &namestore_put_cont,
569 NULL);
570 return;
571 }
572 if (0 == strcmp (name, "caller-ego"))
573 {
574 GNUNET_IDENTITY_ego_get_public_key (ego, &pub);
575 GNUNET_asprintf (&gns_caller_id,
576 "%s",
577 GNUNET_GNSRECORD_pkey_to_zkey (&pub));
578 call1 = GNUNET_CONVERSATION_call_start (cfg,
579 ego,
580 gns_name,
581 &call1_speaker,
582 &call1_mic,
583 &call_event_handler,
584 (void *) "call1");
585 call2 = GNUNET_CONVERSATION_call_start (cfg,
586 ego,
587 gns_name,
588 &call2_speaker,
589 &call2_mic,
590 &call_event_handler,
591 (void *) "call2");
592 return;
593 }
594}
595
596
597static void
598phone_ego_create_cont (void *cls,
599 const struct GNUNET_IDENTITY_PrivateKey *pk,
600 const char *emsg)
601{
602 (void) cls;
603 op = NULL;
604 GNUNET_assert (NULL == emsg);
605}
606
607
608static void
609run (void *cls,
610 const struct GNUNET_CONFIGURATION_Handle *c,
611 struct GNUNET_TESTING_Peer *peer)
612{
613 (void) cls;
614 (void) peer;
615 cfg = c;
616 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_test, NULL);
617 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
618 id = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
619 op = GNUNET_IDENTITY_create (id, "phone-ego", NULL,
620 GNUNET_IDENTITY_TYPE_ECDSA,
621 &phone_ego_create_cont,
622 NULL);
623 ns = GNUNET_NAMESTORE_connect (cfg);
624}
625
626
627int
628main (int argc, char *argv[])
629{
630 (void) argc;
631 (void) argv;
632 if (0 != GNUNET_TESTING_peer_run ("test_conversation_api_twocalls",
633 "test_conversation.conf",
634 &run,
635 NULL))
636 return 1;
637 if (call1_finished && call2_finished)
638 return 0;
639 return 1;
640}
641
642
643/* end of test_conversation_api_twocalls.c */