Asterisk - The Open Source Telephony Project GIT-master-7e7a603
test_cel.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Kinsey Moore <kmoore@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*!
20 * \file
21 * \brief CEL unit tests
22 *
23 * \author Kinsey Moore <kmoore@digium.com>
24 *
25 */
26
27/*** MODULEINFO
28 <depend>TEST_FRAMEWORK</depend>
29 <support_level>core</support_level>
30 ***/
31
32#include "asterisk.h"
33
34#include <math.h>
35#include "asterisk/module.h"
36#include "asterisk/test.h"
37#include "asterisk/cel.h"
38#include "asterisk/channel.h"
41#include "asterisk/chanvars.h"
42#include "asterisk/utils.h"
43#include "asterisk/causes.h"
44#include "asterisk/time.h"
45#include "asterisk/bridge.h"
47#include "asterisk/pickup.h"
50#include "asterisk/json.h"
51#include "asterisk/features.h"
52#include "asterisk/core_local.h"
53
54#define TEST_CATEGORY "/main/cel/"
55
56#define CHANNEL_TECH_NAME "CELTestChannel"
57
58#define TEST_BACKEND_NAME "CEL Test Logging"
59
60/*! \brief A placeholder for Asterisk's 'real' CEL configuration */
62
63/*! \brief The CEL config used for CEL unit tests */
65
66/*! \brief Lock used for synchronizing test execution stages with received events */
68
69/*! \brief Lock used with sync_out for checking the end of test execution */
71
72/*! \brief Condition used for checking the end of test execution */
74
75/*! \brief Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock */
77
78/*! \brief A channel technology used for the unit tests */
81 .description = "Mock channel technology for CEL tests",
82};
83
84/*! \brief A 1 second sleep */
85static struct timespec to_sleep = {1, 0};
86
87static void do_sleep(void)
88{
89 while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)) {
90 }
91}
92
93#define APPEND_EVENT(chan, ev_type, userevent, extra) do { \
94 if (append_expected_event(chan, ev_type, userevent, extra, NULL)) { \
95 return AST_TEST_FAIL; \
96 } \
97 } while (0)
98
99#define APPEND_EVENT_PEER(chan, ev_type, userevent, extra, peer) do { \
100 if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \
101 return AST_TEST_FAIL; \
102 } \
103 } while (0)
104
105#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer) do { \
106 if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \
107 return AST_TEST_FAIL; \
108 } \
109 } while (0)
110
111#define APPEND_DUMMY_EVENT() do { \
112 if (append_dummy_event()) { \
113 return AST_TEST_FAIL; \
114 } \
115 } while (0)
116
117#define BRIDGE_EXIT(channel, bridge) do { \
118 ast_test_validate(test, !ast_bridge_depart(channel)); \
119 BRIDGE_EXIT_EVENT(channel, bridge); \
120 mid_test_sync(); \
121 } while (0)
122
123#define BRIDGE_EXIT_EVENT(channel, bridge) do { \
124 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
125 peer_str = test_cel_generate_peer_str(channel, bridge); \
126 ast_test_validate(test, peer_str != NULL); \
127 BRIDGE_EXIT_EVENT_PEER(channel, bridge, ast_str_buffer(peer_str)); \
128 } while (0)
129
130#define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer) do { \
131 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
132 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
133 ast_test_validate(test, extra != NULL); \
134 APPEND_EVENT_PEER(channel, AST_CEL_BRIDGE_EXIT, NULL, extra, peer); \
135 } while (0)
136
137#define BRIDGE_EXIT_SNAPSHOT(channel, bridge) do { \
138 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
139 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
140 peer_str = test_cel_generate_peer_str_snapshot(channel, bridge); \
141 ast_test_validate(test, peer_str != NULL); \
142 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
143 ast_test_validate(test, extra != NULL); \
144 APPEND_EVENT_SNAPSHOT(channel, AST_CEL_BRIDGE_EXIT, NULL, extra, ast_str_buffer(peer_str)); \
145 } while (0)
146
147#define BRIDGE_ENTER(channel, bridge) do { \
148 ast_test_validate(test, !ast_bridge_impart(bridge, channel, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE)); \
149 do_sleep(); \
150 BRIDGE_ENTER_EVENT(channel, bridge); \
151 mid_test_sync(); \
152 } while (0)
153
154#define BRIDGE_ENTER_EVENT(channel, bridge) do { \
155 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
156 peer_str = test_cel_generate_peer_str(channel, bridge); \
157 ast_test_validate(test, peer_str != NULL); \
158 BRIDGE_ENTER_EVENT_PEER(channel, bridge, ast_str_buffer(peer_str)); \
159 } while (0)
160
161#define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer) do { \
162 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
163 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
164 ast_test_validate(test, extra != NULL); \
165 APPEND_EVENT_PEER(channel, AST_CEL_BRIDGE_ENTER, NULL, extra, peer); \
166 } while (0)
167
168#define BLINDTRANSFER_EVENT(channel, bridge, extension, context) do { \
169 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
170 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}", \
171 "extension", extension, \
172 "context", context, \
173 "bridge_id", bridge->uniqueid, \
174 "transferee_channel_name", "N/A", \
175 "transferee_channel_uniqueid", "N/A"); \
176 ast_test_validate(test, extra != NULL); \
177 APPEND_EVENT(channel, AST_CEL_BLINDTRANSFER, NULL, extra); \
178 } while (0)
179
180#define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4) do { \
181 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
182 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}", \
183 "bridge1_id", bridge1->uniqueid, \
184 "channel2_name", ast_channel_name(channel2), \
185 "channel2_uniqueid", ast_channel_uniqueid(channel2), \
186 "bridge2_id", bridge2->uniqueid, \
187 "transferee_channel_name", ast_channel_name(channel4), \
188 "transferee_channel_uniqueid", ast_channel_uniqueid(channel4), \
189 "transfer_target_channel_name", ast_channel_name(channel3), \
190 "transfer_target_channel_uniqueid", ast_channel_uniqueid(channel3)); \
191 ast_test_validate(test, extra != NULL); \
192 APPEND_EVENT(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra); \
193 } while (0)
194
195/*! \brief Alice's Caller ID */
196#define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
197
198/*! \brief Bob's Caller ID */
199#define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
200
201/*! \brief Charlie's Caller ID */
202#define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
203
204/*! \brief David's Caller ID */
205#define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
206
207/*! \brief Set ulaw format on channel */
208#define SET_FORMATS(chan) do {\
209 struct ast_format_cap *caps;\
210 caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);\
211 ast_format_cap_append(caps, ast_format_ulaw, 0);\
212 ast_channel_nativeformats_set((chan), caps);\
213 ast_channel_set_writeformat((chan), ast_format_ulaw);\
214 ast_channel_set_rawwriteformat((chan), ast_format_ulaw);\
215 ast_channel_set_readformat((chan), ast_format_ulaw);\
216 ast_channel_set_rawreadformat((chan), ast_format_ulaw);\
217 ao2_ref(caps, -1);\
218} while (0)
219
220/*! \brief Create a \ref test_cel_chan_tech for Alice. */
221#define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \
222 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
223 SET_FORMATS((channel_var));\
224 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
225 ast_channel_unlock((channel_var)); \
226 } while (0)
227
228/*! \brief Create a \ref test_cel_chan_tech for Bob. */
229#define CREATE_BOB_CHANNEL(channel_var, caller_id) do { \
230 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
231 SET_FORMATS((channel_var));\
232 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
233 ast_channel_unlock((channel_var)); \
234 } while (0)
235
236/*! \brief Create a \ref test_cel_chan_tech for Charlie. */
237#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id) do { \
238 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
239 SET_FORMATS((channel_var));\
240 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
241 ast_channel_unlock((channel_var)); \
242 } while (0)
243
244/*! \brief Create a \ref test_cel_chan_tech for David. */
245#define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \
246 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
247 SET_FORMATS((channel_var));\
248 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
249 ast_channel_unlock((channel_var)); \
250 } while (0)
251
252/*! \brief Emulate a channel entering into an application */
253#define EMULATE_APP_DATA(channel, priority, application, data) do { \
254 if ((priority) > 0) { \
255 ast_channel_priority_set((channel), (priority)); \
256 } \
257 ast_channel_appl_set((channel), (application)); \
258 ast_channel_data_set((channel), (data)); \
259 ast_channel_publish_snapshot((channel)); \
260 } while (0)
261
262#define ANSWER_CHANNEL(chan) do { \
263 EMULATE_APP_DATA(chan, 1, "Answer", ""); \
264 ANSWER_NO_APP(chan); \
265 } while (0)
266
267#define ANSWER_NO_APP(chan) do { \
268 ast_setstate(chan, AST_STATE_UP); \
269 APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
270 } while (0)
271
272/*! \brief Hang up a test channel safely */
273#define HANGUP_CHANNEL(channel, cause, dialstatus) do { \
274 ast_channel_hangupcause_set((channel), (cause)); \
275 ao2_ref(channel, +1); \
276 ast_hangup((channel)); \
277 HANGUP_EVENT(channel, cause, dialstatus); \
278 APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL); \
279 ao2_cleanup(ast_channel_snapshot_get_latest(ast_channel_uniqueid(channel))); \
280 ao2_cleanup(channel); \
281 channel = NULL; \
282 } while (0)
283
284#define HANGUP_EVENT(channel, cause, dialstatus) do { \
285 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
286 extra = ast_json_pack("{s: i, s: s, s: s}", \
287 "hangupcause", cause, \
288 "hangupsource", "", \
289 "dialstatus", dialstatus); \
290 ast_test_validate(test, extra != NULL); \
291 APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, extra); \
292 } while (0)
293
294static void mid_test_sync(void);
295
296static int append_expected_event(
297 struct ast_channel *chan,
299 const char *userdefevname,
300 struct ast_json *extra,
301 const char *peer);
302
304 struct ast_channel_snapshot *snapshot,
306 const char *userdefevname,
307 struct ast_json *extra,
308 const char *peer);
309
310#ifdef RACEY_TESTS
311static int append_dummy_event(void);
312#endif
313
315{
316 struct ast_str *peer_str = ast_str_create(32);
317 struct ao2_iterator i;
318 char *current_chan = NULL;
319
320 if (!peer_str) {
321 return NULL;
322 }
323
324 for (i = ao2_iterator_init(bridge->channels, 0);
325 (current_chan = ao2_iterator_next(&i));
326 ao2_cleanup(current_chan)) {
327 RAII_VAR(struct ast_channel_snapshot *, current_snapshot,
328 NULL,
330
331 /* Don't add the channel for which this message is being generated */
332 if (!strcmp(current_chan, chan->base->uniqueid)) {
333 continue;
334 }
335
336 current_snapshot = ast_channel_snapshot_get_latest(current_chan);
337 if (!current_snapshot) {
338 continue;
339 }
340
341 ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
342 }
344
345 /* Rip off the trailing comma */
346 ast_str_truncate(peer_str, -1);
347
348 return peer_str;
349}
350
352{
353 RAII_VAR(struct ast_bridge_snapshot *, snapshot,
356
357 if (!snapshot) {
358 return NULL;
359 }
360
361 return __test_cel_generate_peer_str(chan, snapshot);
362}
363
364static struct ast_str *test_cel_generate_peer_str(struct ast_channel *chan, struct ast_bridge *bridge)
365{
366 RAII_VAR(struct ast_channel_snapshot *, snapshot,
369
370 if (!snapshot) {
371 return NULL;
372 }
373
374 return test_cel_generate_peer_str_snapshot(snapshot, bridge);
375}
376
377static void safe_channel_release(struct ast_channel *chan)
378{
379 if (!chan) {
380 return;
381 }
383}
384
385static void safe_bridge_destroy(struct ast_bridge *bridge)
386{
387 if (!bridge) {
388 return;
389 }
390 ast_bridge_destroy(bridge, 0);
391}
392
393AST_TEST_DEFINE(test_cel_channel_creation)
394{
396 struct ast_party_caller caller = ALICE_CALLERID;
397
398 switch (cmd) {
399 case TEST_INIT:
400 info->name = __func__;
401 info->category = TEST_CATEGORY;
402 info->summary = "Test the CEL records created when a channel is created";
403 info->description =
404 "Test the CEL records created when a channel is created";
405 return AST_TEST_NOT_RUN;
406 case TEST_EXECUTE:
407 break;
408 }
409
410 CREATE_ALICE_CHANNEL(chan, (&caller));
411
413
414 return AST_TEST_PASS;
415}
416
417AST_TEST_DEFINE(test_cel_unanswered_inbound_call)
418{
420 struct ast_party_caller caller = ALICE_CALLERID;
421
422 switch (cmd) {
423 case TEST_INIT:
424 info->name = __func__;
425 info->category = TEST_CATEGORY;
426 info->summary = "Test inbound unanswered calls";
427 info->description =
428 "Test CEL records for a call that is\n"
429 "inbound to Asterisk, executes some dialplan, but\n"
430 "is never answered.";
431 return AST_TEST_NOT_RUN;
432 case TEST_EXECUTE:
433 break;
434 }
435
436 CREATE_ALICE_CHANNEL(chan, &caller);
437
438 EMULATE_APP_DATA(chan, 1, "Wait", "1");
439
441
442 return AST_TEST_PASS;
443}
444
445AST_TEST_DEFINE(test_cel_unanswered_outbound_call)
446{
448 struct ast_party_caller caller = {
449 .id.name.str = "",
450 .id.name.valid = 1,
451 .id.number.str = "",
452 .id.number.valid = 1, };
453
454 switch (cmd) {
455 case TEST_INIT:
456 info->name = __func__;
457 info->category = TEST_CATEGORY;
458 info->summary = "Test outbound unanswered calls";
459 info->description =
460 "Test CEL records for a call that is\n"
461 "outbound to Asterisk but is never answered.";
462 return AST_TEST_NOT_RUN;
463 case TEST_EXECUTE:
464 break;
465 }
466
467 CREATE_ALICE_CHANNEL(chan, &caller);
468
469 ast_channel_exten_set(chan, "s");
470 ast_channel_context_set(chan, "default");
472 EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
474
475 return AST_TEST_PASS;
476}
477
478AST_TEST_DEFINE(test_cel_single_party)
479{
481 struct ast_party_caller caller = ALICE_CALLERID;
482
483 switch (cmd) {
484 case TEST_INIT:
485 info->name = __func__;
486 info->category = TEST_CATEGORY;
487 info->summary = "Test CEL for a single party";
488 info->description =
489 "Test CEL records for a call that is\n"
490 "answered, but only involves a single channel";
491 return AST_TEST_NOT_RUN;
492 case TEST_EXECUTE:
493 break;
494 }
495 CREATE_ALICE_CHANNEL(chan, &caller);
496
497 ANSWER_CHANNEL(chan);
498 EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
499
501
502 return AST_TEST_PASS;
503}
504
505AST_TEST_DEFINE(test_cel_single_bridge)
506{
508 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
509
510 struct ast_party_caller caller = ALICE_CALLERID;
511
512 switch (cmd) {
513 case TEST_INIT:
514 info->name = __func__;
515 info->category = TEST_CATEGORY;
516 info->summary = "Test CEL for a single party entering/leaving a bridge";
517 info->description =
518 "Test CEL records for a call that is\n"
519 "answered, enters a bridge, and leaves it.";
520 return AST_TEST_NOT_RUN;
521 case TEST_EXECUTE:
522 break;
523 }
524 bridge = ast_bridge_basic_new();
525 ast_test_validate(test, bridge != NULL);
526
527 CREATE_ALICE_CHANNEL(chan, &caller);
528
529 ANSWER_CHANNEL(chan);
530 EMULATE_APP_DATA(chan, 2, "Bridge", "");
531
532 do_sleep();
533 BRIDGE_ENTER(chan, bridge);
534
535 do_sleep();
536
537 BRIDGE_EXIT(chan, bridge);
538
540
541 return AST_TEST_PASS;
542}
543
544AST_TEST_DEFINE(test_cel_single_bridge_continue)
545{
547 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
548 struct ast_party_caller caller = ALICE_CALLERID;
549
550 switch (cmd) {
551 case TEST_INIT:
552 info->name = __func__;
553 info->category = TEST_CATEGORY;
554 info->summary = "Test CEL for a single party entering/leaving a bridge";
555 info->description =
556 "Test CEL records for a call that is\n"
557 "answered, enters a bridge, and leaves it.";
558 return AST_TEST_NOT_RUN;
559 case TEST_EXECUTE:
560 break;
561 }
562 bridge = ast_bridge_basic_new();
563 ast_test_validate(test, bridge != NULL);
564
565 CREATE_ALICE_CHANNEL(chan, &caller);
566
567 ANSWER_CHANNEL(chan);
568 EMULATE_APP_DATA(chan, 2, "Bridge", "");
569
570 do_sleep();
571 BRIDGE_ENTER(chan, bridge);
572
573 do_sleep();
574
575 BRIDGE_EXIT(chan, bridge);
576
577 EMULATE_APP_DATA(chan, 3, "Wait", "");
578
579 /* And then it hangs up */
581
582 return AST_TEST_PASS;
583}
584
585AST_TEST_DEFINE(test_cel_single_twoparty_bridge_a)
586{
587 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
588 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
589 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
590 struct ast_party_caller caller_alice = ALICE_CALLERID;
591 struct ast_party_caller caller_bob = BOB_CALLERID;
592
593 switch (cmd) {
594 case TEST_INIT:
595 info->name = __func__;
596 info->category = TEST_CATEGORY;
597 info->summary = "Test CEL for a single party entering/leaving a bridge";
598 info->description =
599 "Test CEL records for a call that is\n"
600 "answered, enters a bridge, and leaves it. In this scenario, the\n"
601 "Party A should answer the bridge first.";
602 return AST_TEST_NOT_RUN;
603 case TEST_EXECUTE:
604 break;
605 }
606 bridge = ast_bridge_basic_new();
607 ast_test_validate(test, bridge != NULL);
608
609 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
610
611 CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
612
613 ANSWER_CHANNEL(chan_alice);
614 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
615
616 BRIDGE_ENTER(chan_alice, bridge);
617 do_sleep();
618
619 ANSWER_CHANNEL(chan_bob);
620 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
621
622 BRIDGE_ENTER(chan_bob, bridge);
623
624 BRIDGE_EXIT(chan_alice, bridge);
625 BRIDGE_EXIT(chan_bob, bridge);
626
627 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
628 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
629
630 return AST_TEST_PASS;
631}
632
633AST_TEST_DEFINE(test_cel_single_twoparty_bridge_b)
634{
635 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
636 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
637 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
638 struct ast_party_caller caller_alice = ALICE_CALLERID;
639 struct ast_party_caller caller_bob = BOB_CALLERID;
640
641 switch (cmd) {
642 case TEST_INIT:
643 info->name = __func__;
644 info->category = TEST_CATEGORY;
645 info->summary = "Test CEL for a single party entering/leaving a bridge";
646 info->description =
647 "Test CEL records for a call that is\n"
648 "answered, enters a bridge, and leaves it. In this scenario, the\n"
649 "Party B should answer the bridge first.";
650 return AST_TEST_NOT_RUN;
651 case TEST_EXECUTE:
652 break;
653 }
654 bridge = ast_bridge_basic_new();
655 ast_test_validate(test, bridge != NULL);
656
657 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
658
659 CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
660
661 ANSWER_CHANNEL(chan_alice);
662 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
663
664 ANSWER_CHANNEL(chan_bob);
665 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
666 do_sleep();
667
668 BRIDGE_ENTER(chan_bob, bridge);
669
670 BRIDGE_ENTER(chan_alice, bridge);
671
672 BRIDGE_EXIT(chan_alice, bridge);
673 BRIDGE_EXIT(chan_bob, bridge);
674
675 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
676 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
677
678 return AST_TEST_PASS;
679}
680
681/* XXX Validation needs to be reworked on a per-channel basis before
682 * test_cel_single_multiparty_bridge and test_cel_dial_answer_multiparty
683 * can operate properly. */
684#ifdef RACEY_TESTS
685AST_TEST_DEFINE(test_cel_single_multiparty_bridge)
686{
687 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
688 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
689 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
690 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
691 struct ast_party_caller caller_alice = ALICE_CALLERID;
692 struct ast_party_caller caller_bob = BOB_CALLERID;
693 struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
694
695 switch (cmd) {
696 case TEST_INIT:
697 info->name = __func__;
698 info->category = TEST_CATEGORY;
699 info->summary = "Test CEL for a single party entering/leaving a multi-party bridge";
700 info->description =
701 "Test CEL records for a call that is\n"
702 "answered, enters a bridge, and leaves it. A total of three\n"
703 "parties perform this action.";
704 return AST_TEST_NOT_RUN;
705 case TEST_EXECUTE:
706 break;
707 }
708 bridge = ast_bridge_basic_new();
709 ast_test_validate(test, bridge != NULL);
710
711 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
712 CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
713 CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie);
714
715 ANSWER_CHANNEL(chan_alice);
716 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
717
718 do_sleep();
719
720 BRIDGE_ENTER(chan_alice, bridge);
721
722 ANSWER_CHANNEL(chan_bob);
723 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
724 do_sleep();
725
726 BRIDGE_ENTER(chan_bob, bridge);
727
728 ANSWER_CHANNEL(chan_charlie);
729 EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
730 do_sleep();
731 BRIDGE_ENTER(chan_charlie, bridge);
732
733 BRIDGE_EXIT(chan_alice, bridge);
734 BRIDGE_EXIT(chan_bob, bridge);
735 BRIDGE_EXIT(chan_charlie, bridge);
736
737 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
738 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
739 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
740
741 return AST_TEST_PASS;
742}
743#endif
744
745#define EMULATE_DIAL(channel, dialstring) do { \
746 EMULATE_APP_DATA(channel, 1, "Dial", dialstring); \
747 if (append_expected_event(channel, AST_CEL_APP_START, NULL, NULL, NULL)) { \
748 return AST_TEST_FAIL; \
749 } \
750 } while (0)
751
752#define START_DIALED(caller, callee) \
753 START_DIALED_FULL(caller, callee, "200", "Bob")
754
755#define START_DIALED_FULL(caller, callee, number, name) do { \
756 callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, NULL, caller, 0, CHANNEL_TECH_NAME "/" name); \
757 SET_FORMATS(callee);\
758 ast_channel_unlock(callee); \
759 if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL, NULL)) { \
760 return AST_TEST_FAIL; \
761 } \
762 ast_set_flag(ast_channel_flags(callee), AST_FLAG_OUTGOING); \
763 EMULATE_APP_DATA(callee, 0, "AppDial", "(Outgoing Line)"); \
764 ast_channel_publish_dial(caller, callee, name, NULL); \
765 } while (0)
766
767AST_TEST_DEFINE(test_cel_dial_unanswered)
768{
769 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
770 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
771 struct ast_party_caller caller = ALICE_CALLERID;
772
773 switch (cmd) {
774 case TEST_INIT:
775 info->name = __func__;
776 info->category = TEST_CATEGORY;
777 info->summary = "Test CEL for a dial that isn't answered";
778 info->description =
779 "Test CEL records for a channel that\n"
780 "performs a dial operation that isn't answered";
781 return AST_TEST_NOT_RUN;
782 case TEST_EXECUTE:
783 break;
784 }
785
786 CREATE_ALICE_CHANNEL(chan_caller, &caller);
787
788 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
789
790 START_DIALED(chan_caller, chan_callee);
791
793 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
794
795 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "NOANSWER");
796 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "");
797
798 return AST_TEST_PASS;
799}
800
801AST_TEST_DEFINE(test_cel_dial_unanswered_filter)
802{
803 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
804 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
805 struct ast_party_caller caller = ALICE_CALLERID;
806
807 switch (cmd) {
808 case TEST_INIT:
809 info->name = __func__;
810 info->category = TEST_CATEGORY;
811 info->summary = "Test CEL for a dial that isn't answered";
812 info->description =
813 "Test CEL records for a channel that\n"
814 "performs a dial operation that isn't answered";
815 return AST_TEST_NOT_RUN;
816 case TEST_EXECUTE:
817 break;
818 }
819
820 CREATE_ALICE_CHANNEL(chan_caller, &caller);
821
822 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
823
824 START_DIALED(chan_caller, chan_callee);
825
827 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOT A VALID DIAL STATUS");
828 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
829
830 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "NOANSWER");
831 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "");
832
833 return AST_TEST_PASS;
834}
835
836AST_TEST_DEFINE(test_cel_dial_busy)
837{
838 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
839 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
840 struct ast_party_caller caller = ALICE_CALLERID;
841
842 switch (cmd) {
843 case TEST_INIT:
844 info->name = __func__;
845 info->category = TEST_CATEGORY;
846 info->summary = "Test CEL for a dial that results in a busy";
847 info->description =
848 "Test CEL records for a channel that\n"
849 "performs a dial operation to an endpoint that's busy";
850 return AST_TEST_NOT_RUN;
851 case TEST_EXECUTE:
852 break;
853 }
854
855 CREATE_ALICE_CHANNEL(chan_caller, &caller);
856
857 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
858
859 START_DIALED(chan_caller, chan_callee);
860
862 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
863
864 HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY, "BUSY");
865 HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY, "");
866
867 return AST_TEST_PASS;
868}
869
870AST_TEST_DEFINE(test_cel_dial_congestion)
871{
872 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
873 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
874 struct ast_party_caller caller = ALICE_CALLERID;
875
876 switch (cmd) {
877 case TEST_INIT:
878 info->name = __func__;
879 info->category = TEST_CATEGORY;
880 info->summary = "Test CEL for a dial that results in congestion";
881 info->description =
882 "Test CEL records for a channel that\n"
883 "performs a dial operation to an endpoint that's congested";
884 return AST_TEST_NOT_RUN;
885 case TEST_EXECUTE:
886 break;
887 }
888
889 CREATE_ALICE_CHANNEL(chan_caller, &caller);
890
891 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
892
893 START_DIALED(chan_caller, chan_callee);
894
896 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
897
898 HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION, "CONGESTION");
899 HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION, "");
900
901 return AST_TEST_PASS;
902}
903
904AST_TEST_DEFINE(test_cel_dial_unavailable)
905{
906 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
907 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
908 struct ast_party_caller caller = ALICE_CALLERID;
909
910 switch (cmd) {
911 case TEST_INIT:
912 info->name = __func__;
913 info->category = TEST_CATEGORY;
914 info->summary = "Test CEL for a dial that results in unavailable";
915 info->description =
916 "Test CEL records for a channel that\n"
917 "performs a dial operation to an endpoint that's unavailable";
918 return AST_TEST_NOT_RUN;
919 case TEST_EXECUTE:
920 break;
921 }
922
923 CREATE_ALICE_CHANNEL(chan_caller, &caller);
924
925 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
926
927 START_DIALED(chan_caller, chan_callee);
928
930 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
931
932 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION, "CHANUNAVAIL");
934
935 return AST_TEST_PASS;
936}
937
938AST_TEST_DEFINE(test_cel_dial_caller_cancel)
939{
940 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
941 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
942 struct ast_party_caller caller = ALICE_CALLERID;
943
944 switch (cmd) {
945 case TEST_INIT:
946 info->name = __func__;
947 info->category = TEST_CATEGORY;
948 info->summary = "Test CEL for a dial where the caller cancels";
949 info->description =
950 "Test CEL records for a channel that\n"
951 "performs a dial operation to an endpoint but then decides\n"
952 "to hang up, cancelling the dial";
953 return AST_TEST_NOT_RUN;
954 case TEST_EXECUTE:
955 break;
956 }
957
958 CREATE_ALICE_CHANNEL(chan_caller, &caller);
959
960 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
961
962 START_DIALED(chan_caller, chan_callee);
963
965 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
966
967 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
968 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "CANCEL");
969
970 return AST_TEST_PASS;
971}
972
973AST_TEST_DEFINE(test_cel_dial_parallel_failed)
974{
975 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
976 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
977 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
978 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
979 struct ast_party_caller caller = ALICE_CALLERID;
980
981 switch (cmd) {
982 case TEST_INIT:
983 info->name = __func__;
984 info->category = TEST_CATEGORY;
985 info->summary = "Test a parallel dial where all channels fail to answer";
986 info->description =
987 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
988 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
989 "Alice hangs up. Three records are created for Alice as a result.";
990 return AST_TEST_NOT_RUN;
991 case TEST_EXECUTE:
992 break;
993 }
994
995 CREATE_ALICE_CHANNEL(chan_caller, &caller);
996
997 /* Channel enters Dial app */
998 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
999
1000 /* Outbound channels are created */
1001 START_DIALED_FULL(chan_caller, chan_bob, "200", "Bob");
1002 START_DIALED_FULL(chan_caller, chan_charlie, "300", "Charlie");
1003 START_DIALED_FULL(chan_caller, chan_david, "400", "David");
1004
1005 /* Dial starts */
1007
1008 /* Charlie is busy */
1009 ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1010 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY, "");
1011
1012 /* David is congested */
1013 ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1014 HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION, "");
1015
1016 /* Bob is canceled */
1017 ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1018 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1019
1020 /* Alice hangs up */
1021 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "BUSY");
1022
1023 return AST_TEST_PASS;
1024}
1025
1026AST_TEST_DEFINE(test_cel_dial_answer_no_bridge)
1027{
1028 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1029 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1030 struct ast_party_caller caller = ALICE_CALLERID;
1031
1032 switch (cmd) {
1033 case TEST_INIT:
1034 info->name = __func__;
1035 info->category = TEST_CATEGORY;
1036 info->summary = "Test dialing, answering, and not going into a bridge.";
1037 info->description =
1038 "This is a weird one, but theoretically possible. You can perform\n"
1039 "a dial, then bounce both channels to different priorities and\n"
1040 "never have them enter a bridge together. Ew. This makes sure that\n"
1041 "when we answer, we get a CEL, it gets ended at that point, and\n"
1042 "that it gets finalized appropriately.";
1043 return AST_TEST_NOT_RUN;
1044 case TEST_EXECUTE:
1045 break;
1046 }
1047
1048 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1049
1050 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1051
1052 START_DIALED(chan_caller, chan_callee);
1053
1055 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1056
1057 ANSWER_NO_APP(chan_caller);
1059 ANSWER_NO_APP(chan_callee);
1060
1061 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1062 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1063
1064 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1065 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1066
1067 return AST_TEST_PASS;
1068}
1069
1070AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_a)
1071{
1072 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1073 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1074 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1075 struct ast_party_caller caller = ALICE_CALLERID;
1076
1077 switch (cmd) {
1078 case TEST_INIT:
1079 info->name = __func__;
1080 info->category = TEST_CATEGORY;
1081 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1082 info->description =
1083 "The most 'basic' of scenarios";
1084 return AST_TEST_NOT_RUN;
1085 case TEST_EXECUTE:
1086 break;
1087 }
1088 bridge = ast_bridge_basic_new();
1089 ast_test_validate(test, bridge != NULL);
1090
1091 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1092
1093 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1094
1095 START_DIALED(chan_caller, chan_callee);
1096
1098 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1099
1100 ANSWER_NO_APP(chan_caller);
1101 ANSWER_NO_APP(chan_callee);
1102
1103 do_sleep();
1104
1105 BRIDGE_ENTER(chan_caller, bridge);
1106 BRIDGE_ENTER(chan_callee, bridge);
1107
1108 BRIDGE_EXIT(chan_caller, bridge);
1109 BRIDGE_EXIT(chan_callee, bridge);
1110
1111 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1112 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1113
1114 return AST_TEST_PASS;
1115}
1116
1117AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_b)
1118{
1119 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1120 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1121 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1122 struct ast_party_caller caller = ALICE_CALLERID;
1123
1124 switch (cmd) {
1125 case TEST_INIT:
1126 info->name = __func__;
1127 info->category = TEST_CATEGORY;
1128 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1129 info->description =
1130 "The most 'basic' of scenarios";
1131 return AST_TEST_NOT_RUN;
1132 case TEST_EXECUTE:
1133 break;
1134 }
1135 bridge = ast_bridge_basic_new();
1136 ast_test_validate(test, bridge != NULL);
1137
1138 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1139
1140 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1141
1142 START_DIALED(chan_caller, chan_callee);
1143
1145 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1146
1147 ANSWER_NO_APP(chan_caller);
1148 ANSWER_NO_APP(chan_callee);
1149
1150 do_sleep();
1151 BRIDGE_ENTER(chan_callee, bridge);
1152 BRIDGE_ENTER(chan_caller, bridge);
1153
1154 BRIDGE_EXIT(chan_caller, bridge);
1155 BRIDGE_EXIT(chan_callee, bridge);
1156
1157 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1158 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1159
1160 return AST_TEST_PASS;
1161}
1162
1163#ifdef RACEY_TESTS
1164AST_TEST_DEFINE(test_cel_dial_answer_multiparty)
1165{
1166 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1167 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1168 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1169 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1170 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1171 struct ast_party_caller alice_caller = ALICE_CALLERID;
1172 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1173
1174 switch (cmd) {
1175 case TEST_INIT:
1176 info->name = __func__;
1177 info->category = TEST_CATEGORY;
1178 info->summary = "Test dialing, answering, and going into a multi-party bridge";
1179 info->description =
1180 "A little tricky to get to do, but possible with some redirects.";
1181 return AST_TEST_NOT_RUN;
1182 case TEST_EXECUTE:
1183 break;
1184 }
1185 bridge = ast_bridge_basic_new();
1186 ast_test_validate(test, bridge != NULL);
1187
1188 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1189
1190 EMULATE_DIAL(chan_alice, CHANNEL_TECH_NAME "/Bob");
1191
1192 START_DIALED(chan_alice, chan_bob);
1193 do_sleep();
1194
1195 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1196 do_sleep();
1197 EMULATE_DIAL(chan_charlie, CHANNEL_TECH_NAME "/Bob");
1198 do_sleep();
1199
1200 START_DIALED_FULL(chan_charlie, chan_david, "400", "David");
1201
1203 do_sleep();
1205 do_sleep();
1206 ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1207 do_sleep();
1208 ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1209 do_sleep();
1210
1211 ANSWER_NO_APP(chan_alice);
1212 do_sleep();
1213 ANSWER_NO_APP(chan_bob);
1214 do_sleep();
1215 ANSWER_NO_APP(chan_charlie);
1216 do_sleep();
1217 ANSWER_NO_APP(chan_david);
1218 do_sleep();
1219
1220 do_sleep();
1221 BRIDGE_ENTER(chan_charlie, bridge);
1222 BRIDGE_ENTER(chan_david, bridge);
1223 BRIDGE_ENTER(chan_bob, bridge);
1224 BRIDGE_ENTER(chan_alice, bridge);
1225
1226 BRIDGE_EXIT(chan_alice, bridge);
1227 BRIDGE_EXIT(chan_bob, bridge);
1228 BRIDGE_EXIT(chan_charlie, bridge);
1229 BRIDGE_EXIT(chan_david, bridge);
1230
1231 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "ANSWER");
1232 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1233 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "ANSWER");
1234 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1235
1236 return AST_TEST_PASS;
1237}
1238#endif
1239
1240AST_TEST_DEFINE(test_cel_blind_transfer)
1241{
1242 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1243 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1244 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1245 RAII_VAR(struct ast_blind_transfer_message *, transfer_msg, NULL, ao2_cleanup);
1246 struct ast_party_caller alice_caller = ALICE_CALLERID;
1247 struct ast_party_caller bob_caller = BOB_CALLERID;
1248
1249 switch (cmd) {
1250 case TEST_INIT:
1251 info->name = __func__;
1252 info->category = TEST_CATEGORY;
1253 info->summary = "Test blind transfers to an extension";
1254 info->description =
1255 "This test creates two channels, bridges them, and then"
1256 " blind transfers the bridge to an extension.";
1257 return AST_TEST_NOT_RUN;
1258 case TEST_EXECUTE:
1259 break;
1260 }
1261 bridge = ast_bridge_basic_new();
1262 ast_test_validate(test, bridge != NULL);
1263
1264 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1265 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1266
1267 ANSWER_NO_APP(chan_alice);
1268 ANSWER_NO_APP(chan_bob);
1269
1270 BRIDGE_ENTER(chan_bob, bridge);
1271 BRIDGE_ENTER(chan_alice, bridge);
1272
1273 ast_bridge_lock(bridge);
1274 transfer_msg = ast_blind_transfer_message_create(1, chan_alice,
1275 "transfer_extension", "transfer_context");
1276 if (!transfer_msg) {
1277 ast_bridge_unlock(bridge);
1278 ast_test_status_update(test, "Failed to create transfer Stasis message\n");
1279 return AST_TEST_FAIL;
1280 }
1281 transfer_msg->bridge = ast_bridge_snapshot_create(bridge);
1282 if (!transfer_msg->bridge) {
1283 ast_bridge_unlock(bridge);
1284 ast_test_status_update(test, "Failed to create bridge snapshot\n");
1285 return AST_TEST_FAIL;
1286 }
1287 ast_bridge_unlock(bridge);
1288 transfer_msg->result = AST_BRIDGE_TRANSFER_SUCCESS;
1290 BLINDTRANSFER_EVENT(chan_alice, bridge, "transfer_extension", "transfer_context");
1291
1292 BRIDGE_EXIT(chan_alice, bridge);
1293 BRIDGE_EXIT(chan_bob, bridge);
1294
1295 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1296 do_sleep();
1297 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1298
1299 return AST_TEST_PASS;
1300}
1301
1302/* XXX Validation needs to take into account the BRIDGE_EXIT for Alice and the
1303 * ATTENDEDTRANSFER message are not guaranteed to be ordered
1304 */
1305#ifdef RACEY_TESTS
1306AST_TEST_DEFINE(test_cel_attended_transfer_bridges_swap)
1307{
1308 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1309 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1310 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1311 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1312 RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1313 RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1314 struct ast_party_caller alice_caller = ALICE_CALLERID;
1315 struct ast_party_caller bob_caller = BOB_CALLERID;
1316 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1317 struct ast_party_caller david_caller = ALICE_CALLERID;
1318
1319 switch (cmd) {
1320 case TEST_INIT:
1321 info->name = __func__;
1322 info->category = TEST_CATEGORY;
1323 info->summary = "Test attended transfers between two pairs of bridged parties";
1324 info->description =
1325 "This test creates four channels, places each pair in"
1326 " a bridge, and then attended transfers the bridges"
1327 " together.";
1328 return AST_TEST_NOT_RUN;
1329 case TEST_EXECUTE:
1330 break;
1331 }
1332 /* Create first set of bridged parties */
1333 bridge1 = ast_bridge_basic_new();
1334 ast_test_validate(test, bridge1 != NULL);
1335
1336 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1337 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1338 ANSWER_NO_APP(chan_alice);
1339 ANSWER_NO_APP(chan_bob);
1340
1341 BRIDGE_ENTER(chan_bob, bridge1);
1342 BRIDGE_ENTER(chan_alice, bridge1);
1343
1344 /* Create second set of bridged parties */
1345 bridge2 = ast_bridge_basic_new();
1346 ast_test_validate(test, bridge2 != NULL);
1347
1348 CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1349 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1350 ANSWER_NO_APP(chan_david);
1351 ANSWER_NO_APP(chan_charlie);
1352
1353 BRIDGE_ENTER(chan_charlie, bridge2);
1354
1355 BRIDGE_ENTER(chan_david, bridge2);
1356 BRIDGE_EXIT_EVENT(chan_bob, bridge1);
1357 do_sleep();
1358
1359 /* Perform attended transfer */
1360 if (ast_bridge_transfer_attended(chan_alice, chan_david)) {
1361 ast_test_status_update(test, "Attended transfer failed!\n");
1362 return AST_TEST_FAIL;
1363 }
1364 do_sleep();
1365 BRIDGE_ENTER_EVENT_PEER(chan_bob, bridge2, "CELTestChannel/David,CELTestChannel/Charlie");
1366
1367 BRIDGE_EXIT_EVENT(chan_david, bridge2);
1368 BRIDGE_EXIT_EVENT(chan_alice, bridge1);
1369 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1370
1371 do_sleep();
1372 BRIDGE_EXIT(chan_bob, bridge2);
1373 BRIDGE_EXIT(chan_charlie, bridge2);
1374
1375 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1376 do_sleep();
1377 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1378 do_sleep();
1379 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1380 do_sleep();
1381 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1382
1383 return AST_TEST_PASS;
1384}
1385#endif
1386
1387AST_TEST_DEFINE(test_cel_attended_transfer_bridges_merge)
1388{
1389 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1390 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1391 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1392 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1393 RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1394 RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1395 struct ast_party_caller alice_caller = ALICE_CALLERID;
1396 struct ast_party_caller bob_caller = BOB_CALLERID;
1397 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1398 struct ast_party_caller david_caller = ALICE_CALLERID;
1399
1400 switch (cmd) {
1401 case TEST_INIT:
1402 info->name = __func__;
1403 info->category = TEST_CATEGORY;
1404 info->summary = "Test attended transfers between two pairs of"
1405 " bridged parties that results in a bridge merge";
1406 info->description =
1407 "This test creates four channels, places each pair"
1408 " in a bridge, and then attended transfers the bridges"
1409 " together causing a bridge merge.";
1410 return AST_TEST_NOT_RUN;
1411 case TEST_EXECUTE:
1412 break;
1413 }
1414 /* Create first set of bridged parties */
1417 "test_cel", "test_cel_atxfer_bridges_merge_1", NULL);
1418 ast_test_validate(test, bridge1 != NULL);
1419
1420 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1421 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1422 ANSWER_NO_APP(chan_alice);
1423 ANSWER_NO_APP(chan_bob);
1424
1425 BRIDGE_ENTER(chan_bob, bridge1);
1426 BRIDGE_ENTER(chan_alice, bridge1);
1427
1428 /* Create second set of bridged parties */
1431 "test_cel", "test_cel_atxfer_bridges_merge_2", NULL);
1432 ast_test_validate(test, bridge2 != NULL);
1433
1434 CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1435 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1436 ANSWER_NO_APP(chan_david);
1437 ANSWER_NO_APP(chan_charlie);
1438
1439 BRIDGE_ENTER(chan_charlie, bridge2);
1440
1441 BRIDGE_ENTER(chan_david, bridge2);
1442
1443 /* Perform attended transfer */
1444 if (ast_bridge_transfer_attended(chan_alice, chan_david)) {
1445 ast_test_status_update(test, "Attended transfer failed!\n");
1446 return AST_TEST_FAIL;
1447 }
1448 do_sleep();
1449 BRIDGE_EXIT_EVENT_PEER(chan_charlie, bridge2, "CELTestChannel/David");
1450 BRIDGE_ENTER_EVENT_PEER(chan_charlie, bridge1, "CELTestChannel/Bob,CELTestChannel/Alice");
1451 BRIDGE_EXIT_EVENT(chan_david, bridge2);
1452 BRIDGE_EXIT_EVENT(chan_alice, bridge1);
1453
1454 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1455
1456 do_sleep();
1457 BRIDGE_EXIT(chan_bob, bridge1);
1458 BRIDGE_EXIT(chan_charlie, bridge1);
1459
1460 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1461 do_sleep();
1462 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1463 do_sleep();
1464 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1465 do_sleep();
1466 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1467
1468 return AST_TEST_PASS;
1469}
1470
1471/* XXX Validation needs to take into account the BRIDGE_EXIT for David and the
1472 * ATTENDEDTRANSFER message are not guaranteed to be ordered
1473 */
1474#ifdef RACEY_TESTS
1475AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link)
1476{
1477 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1478 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1479 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1480 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1481 RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1482 RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1483 struct ast_party_caller alice_caller = ALICE_CALLERID;
1484 struct ast_party_caller bob_caller = BOB_CALLERID;
1485 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1486 struct ast_party_caller david_caller = ALICE_CALLERID;
1487
1488 switch (cmd) {
1489 case TEST_INIT:
1490 info->name = __func__;
1491 info->category = TEST_CATEGORY;
1492 info->summary = "Test attended transfers between two pairs of"
1493 " bridged parties that results in a bridge merge";
1494 info->description =
1495 "This test creates four channels, places each pair"
1496 " in a bridge, and then attended transfers the bridges"
1497 " together causing a bridge link.";
1498 return AST_TEST_NOT_RUN;
1499 case TEST_EXECUTE:
1500 break;
1501 }
1502 /* Create first set of bridged parties */
1507 "test_cel", "test_cel_atxfer_bridges_link_1", NULL);
1508 ast_test_validate(test, bridge1 != NULL);
1509
1510 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1511 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1512 ANSWER_NO_APP(chan_alice);
1513 ANSWER_NO_APP(chan_bob);
1514
1515 BRIDGE_ENTER(chan_bob, bridge1);
1516 BRIDGE_ENTER(chan_alice, bridge1);
1517
1518 /* Create second set of bridged parties */
1523 "test_cel", "test_cel_atxfer_bridges_link_2", NULL);
1524 ast_test_validate(test, bridge2 != NULL);
1525
1526 CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1527 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1528 ANSWER_NO_APP(chan_david);
1529 ANSWER_NO_APP(chan_charlie);
1530
1531 BRIDGE_ENTER(chan_charlie, bridge2);
1532 BRIDGE_ENTER(chan_david, bridge2);
1533
1534 /* Perform attended transfer */
1535 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1536
1537 ast_bridge_transfer_attended(chan_alice, chan_david);
1538 do_sleep();
1539
1540 /* BRIDGE_EXIT alice and david */
1543
1544 do_sleep();
1545 BRIDGE_EXIT(chan_bob, bridge1);
1546 BRIDGE_EXIT(chan_charlie, bridge2);
1547
1548 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1549 do_sleep();
1550 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1551 do_sleep();
1552 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1553 do_sleep();
1554 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1555 do_sleep();
1556
1557 return AST_TEST_PASS;
1558}
1559#endif
1560
1561AST_TEST_DEFINE(test_cel_dial_pickup)
1562{
1563 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1564 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1565 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1566 struct ast_party_caller caller = ALICE_CALLERID;
1567 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1568
1569 switch (cmd) {
1570 case TEST_INIT:
1571 info->name = __func__;
1572 info->category = TEST_CATEGORY;
1573 info->summary = "Test call pickup";
1574 info->description =
1575 "Test CEL records for a call that is\n"
1576 "inbound to Asterisk, executes some dialplan, and\n"
1577 "is picked up.";
1578 return AST_TEST_NOT_RUN;
1579 case TEST_EXECUTE:
1580 break;
1581 }
1582
1583 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1584
1585 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1586
1587 START_DIALED(chan_caller, chan_callee);
1588
1590
1591 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1592
1593 {
1594 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1595 SCOPED_CHANNELLOCK(lock, chan_callee);
1596
1597 extra = ast_json_pack("{s: s, s: s}", "pickup_channel", ast_channel_name(chan_charlie),
1598 "pickup_channel_uniqueid", ast_channel_uniqueid(chan_charlie));
1599 ast_test_validate(test, extra != NULL);
1600
1601 APPEND_EVENT(chan_callee, AST_CEL_PICKUP, NULL, extra);
1602 ast_test_validate(test, !ast_do_pickup(chan_charlie, chan_callee));
1603 }
1604
1605 /* Hang up the masqueraded zombie */
1606 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1607
1608 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1609
1610 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1611 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1612
1613 return AST_TEST_PASS;
1614}
1615
1616AST_TEST_DEFINE(test_cel_local_optimize)
1617{
1618 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1619 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1620 struct ast_party_caller alice_caller = ALICE_CALLERID;
1621 struct ast_party_caller bob_caller = BOB_CALLERID;
1622 RAII_VAR(struct ast_multi_channel_blob *, mc_blob, NULL, ao2_cleanup);
1623 RAII_VAR(struct ast_channel_snapshot *, alice_snapshot, NULL, ao2_cleanup);
1624 RAII_VAR(struct ast_channel_snapshot *, bob_snapshot, NULL, ao2_cleanup);
1625 RAII_VAR(struct stasis_message *, local_opt_begin, NULL, ao2_cleanup);
1626 RAII_VAR(struct stasis_message *, local_opt_end, NULL, ao2_cleanup);
1627 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1628
1629 switch (cmd) {
1630 case TEST_INIT:
1631 info->name = __func__;
1632 info->category = TEST_CATEGORY;
1633 info->summary = "Test local channel optimization record generation";
1634 info->description =
1635 "Test CEL records for two local channels being optimized\n"
1636 "out by sending a messages indicating local optimization\n"
1637 "begin and end";
1638 return AST_TEST_NOT_RUN;
1639 case TEST_EXECUTE:
1640 break;
1641 }
1642
1644 ast_test_validate(test, mc_blob != NULL);
1645
1646 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1647 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1648
1649 ast_channel_lock(chan_alice);
1650 alice_snapshot = ast_channel_snapshot_create(chan_alice);
1651 ast_channel_unlock(chan_alice);
1652 ast_test_validate(test, alice_snapshot != NULL);
1653
1654 ast_channel_lock(chan_bob);
1655 bob_snapshot = ast_channel_snapshot_create(chan_bob);
1656 ast_channel_unlock(chan_bob);
1657 ast_test_validate(test, bob_snapshot != NULL);
1658
1659 ast_multi_channel_blob_add_channel(mc_blob, "1", alice_snapshot);
1660 ast_multi_channel_blob_add_channel(mc_blob, "2", bob_snapshot);
1661
1662 local_opt_begin = stasis_message_create(ast_local_optimization_begin_type(), mc_blob);
1663 ast_test_validate(test, local_opt_begin != NULL);
1664
1665 local_opt_end = stasis_message_create(ast_local_optimization_end_type(), mc_blob);
1666 ast_test_validate(test, local_opt_end != NULL);
1667
1668 stasis_publish(ast_channel_topic(chan_alice), local_opt_begin);
1669 stasis_publish(ast_channel_topic(chan_alice), local_opt_end);
1670
1671 extra = ast_json_pack("{s: s, s: s}", "local_two", bob_snapshot->base->name,
1672 "local_two_uniqueid", bob_snapshot->base->uniqueid);
1673 ast_test_validate(test, extra != NULL);
1674
1675 APPEND_EVENT_SNAPSHOT(alice_snapshot, AST_CEL_LOCAL_OPTIMIZE, NULL, extra, NULL);
1676
1677 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1678 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1679
1680 return AST_TEST_PASS;
1681}
1682
1683/*! Container for astobj2 duplicated ast_events */
1685
1686/*! Container for expected CEL events */
1688
1689static struct ast_event *ao2_dup_event(const struct ast_event *event)
1690{
1691 struct ast_event *event_dup;
1692 uint16_t event_len;
1693
1695
1696 event_dup = ao2_alloc(event_len, NULL);
1697 if (!event_dup) {
1698 return NULL;
1699 }
1700
1701 memcpy(event_dup, event, event_len);
1702
1703 return event_dup;
1704}
1705
1706static void mid_test_sync(void)
1707{
1711 return;
1712 }
1713
1714 do_mid_test_sync = 1;
1716
1717 {
1718 struct timeval start = ast_tvnow();
1719 struct timespec end = {
1720 .tv_sec = start.tv_sec + 15,
1721 .tv_nsec = start.tv_usec * 1000
1722 };
1723
1726 }
1727}
1728
1729static int append_event(struct ast_event *ev)
1730{
1731 RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
1732 ao2_ev = ao2_dup_event(ev);
1733 if (!ao2_ev) {
1734 return -1;
1735 }
1736
1738 return 0;
1739}
1740
1741#ifdef RACEY_TESTS
1742static int append_dummy_event(void)
1743{
1744 RAII_VAR(struct ast_event *, ev, NULL, ast_free);
1745 RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
1746
1748 if (!ev) {
1749 return -1;
1750 }
1751
1752 return append_event(ev);
1753}
1754#endif
1755
1757 struct ast_channel_snapshot *snapshot,
1759 const char *userdefevname,
1760 struct ast_json *extra,
1761 const char *peer)
1762{
1763 RAII_VAR(struct ast_event *, ev, NULL, ast_free);
1764 ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer);
1765 if (!ev) {
1766 return -1;
1767 }
1768
1769 return append_event(ev);
1770}
1771
1773 struct ast_channel *chan,
1775 const char *userdefevname,
1776 struct ast_json *extra,
1777 const char *peer)
1778{
1779 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1780 ast_channel_lock(chan);
1781 snapshot = ast_channel_snapshot_create(chan);
1782 ast_channel_unlock(chan);
1783 if (!snapshot) {
1784 return -1;
1785 }
1786
1787 return append_expected_event_snapshot(snapshot, type, userdefevname, extra, peer);
1788}
1789
1790static void test_sub(struct ast_event *event)
1791{
1792 RAII_VAR(struct ast_event *, event_dup, ao2_dup_event(event), ao2_cleanup);
1793 const char *chan_name;
1794 SCOPED_MUTEX(mid_test_lock, &mid_test_sync_lock);
1795
1796 if (!event_dup) {
1797 return;
1798 }
1799
1800 chan_name = ast_event_get_ie_str(event_dup, AST_EVENT_IE_CEL_CHANNAME);
1801 if (chan_name && strncmp(chan_name, CHANNEL_TECH_NAME, 14)) {
1802 return;
1803 }
1804
1805 /* save the event for later processing */
1806 ao2_link(cel_received_events, event_dup);
1807
1808 if (do_mid_test_sync) {
1811 if (expected <= received) {
1812 {
1815 do_mid_test_sync = 0;
1816 }
1817 }
1818 }
1819}
1820
1821/*!
1822 * \internal
1823 * \brief Callback function called before each test executes
1824 */
1825static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
1826{
1829
1833
1834 /* Back up the real CEL config and insert the test's config */
1837
1838 /* init CEL event storage (degenerate hash table becomes a linked list) */
1841
1842 /* start the CEL event callback */
1844 return -1;
1845 }
1846 return 0;
1847}
1848
1849/*!
1850 * \brief Check two peer strings for equality
1851 *
1852 * \retval zero if the peer strings do not match
1853 * \retval non-zero if the peer strings match
1854 */
1855static int test_cel_peer_strings_match(const char *str1, const char *str2)
1856{
1857 RAII_VAR(struct ao2_container *, intersection, ast_str_container_alloc(11), ao2_cleanup);
1858 RAII_VAR(char *, str1_dup, ast_strdup(str1), ast_free);
1859 RAII_VAR(char *, str2_dup, ast_strdup(str2), ast_free);
1860 char *chan;
1861
1862 if (!intersection) {
1863 return 1;
1864 }
1865
1866 while ((chan = strsep(&str1_dup, ","))) {
1867 ast_str_container_add(intersection, chan);
1868 }
1869
1870 while ((chan = strsep(&str2_dup, ","))) {
1871 RAII_VAR(char *, ao2_chan, ao2_find(intersection, chan, OBJ_SEARCH_KEY), ao2_cleanup);
1872
1873 /* item in str2 not in str1 */
1874 if (!ao2_chan) {
1875 return 0;
1876 }
1877
1878 ast_str_container_remove(intersection, chan);
1879 }
1880
1881 /* item in str1 not in str2 */
1882 if (ao2_container_count(intersection)) {
1883 return 0;
1884 }
1885
1886 return 1;
1887}
1888
1889/*!
1890 * \brief Check an IE value from two events
1891 *
1892 * \retval zero if the IEs in the events of the specified type do not match
1893 * \retval non-zero if the IEs in the events of the specified type match
1894 */
1895static int match_ie_val(
1896 const struct ast_event *event1,
1897 const struct ast_event *event2,
1899{
1901
1902 /* XXX ignore sec/usec for now */
1904 return 1;
1905 }
1906
1908 return 1;
1909 }
1910
1911 switch (pltype) {
1913 {
1914 uint32_t val = ast_event_get_ie_uint(event2, type);
1915
1916 return (val == ast_event_get_ie_uint(event1, type)) ? 1 : 0;
1917 }
1919 {
1920 const char *str1 = ast_event_get_ie_str(event1, type);
1921 const char *str2 = ast_event_get_ie_str(event2, type);
1922
1923 if (!str1 && !str2) {
1924 return 1;
1925 } else if (!str1) {
1926 return 0;
1927 } else if (!str2) {
1928 return 0;
1929 }
1930
1931 /* use special matching for CEL PEER field */
1932 if (type == AST_EVENT_IE_CEL_PEER) {
1933 return test_cel_peer_strings_match(str1, str2);
1934 }
1935
1936 return !strcmp(str1, str2);
1937 }
1940 /* Fall through: just pass on these types */
1941 return 1;
1942 default:
1943 break;
1944 }
1945 return 0;
1946}
1947
1948static int events_are_equal(struct ast_test *test, struct ast_event *received, struct ast_event *expected)
1949{
1950 struct ast_event_iterator iterator;
1951 int res;
1952
1953 if (ast_event_get_type(expected) == AST_EVENT_CUSTOM) {
1954 /* this event is flagged as a wildcard match */
1955 return 1;
1956 }
1957
1958 for (res = ast_event_iterator_init(&iterator, received); !res; res = ast_event_iterator_next(&iterator)) {
1959 int ie_type = ast_event_iterator_get_ie_type(&iterator);
1960 if (!match_ie_val(received, expected, ie_type)) {
1961 ast_test_status_update(test, "Failed matching on field %s\n", ast_event_get_ie_type_name(ie_type));
1962 return 0;
1963 }
1964 }
1965
1966 return 1;
1967}
1968
1969static int dump_event(struct ast_test *test, struct ast_event *event)
1970{
1971 struct ast_event_iterator i;
1972
1973 if (ast_event_iterator_init(&i, event)) {
1974 ast_test_status_update(test, "Failed to initialize event iterator. :-(\n");
1975 return 0;
1976 }
1977
1978 ast_test_status_update(test, "Event: %s\n",
1980
1981 do {
1982 enum ast_event_ie_type ie_type;
1983 enum ast_event_ie_pltype ie_pltype;
1984 const char *ie_type_name;
1985
1986 ie_type = ast_event_iterator_get_ie_type(&i);
1987 ie_type_name = ast_event_get_ie_type_name(ie_type);
1988 ie_pltype = ast_event_get_ie_pltype(ie_type);
1989
1990 switch (ie_pltype) {
1993 ast_test_status_update(test, "%.30s: %s\n", ie_type_name,
1995 break;
1997 ast_test_status_update(test, "%.30s: %u\n", ie_type_name,
1999 break;
2000 default:
2001 break;
2002 }
2003 } while (!ast_event_iterator_next(&i));
2004
2006
2007 return 0;
2008}
2009
2010static int check_events(struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
2011{
2012 struct ao2_iterator received_it;
2013 struct ao2_iterator expected_it;
2014 RAII_VAR(struct ast_event *, rx_event, NULL, ao2_cleanup);
2015 RAII_VAR(struct ast_event *, ex_event, NULL, ao2_cleanup);
2016 int debug = 0;
2017
2018 if (ao2_container_count(local_expected) != ao2_container_count(local_received)) {
2019 ast_test_status_update(test, "Increasing verbosity since the number of expected events (%d)"
2020 " did not match number of received events (%d).\n",
2021 ao2_container_count(local_expected),
2022 ao2_container_count(local_received));
2023 debug = 1;
2024 }
2025
2026 received_it = ao2_iterator_init(local_received, 0);
2027 expected_it = ao2_iterator_init(local_expected, 0);
2028 rx_event = ao2_iterator_next(&received_it);
2029 ex_event = ao2_iterator_next(&expected_it);
2030 while (rx_event && ex_event) {
2031 if (!events_are_equal(test, rx_event, ex_event)) {
2032 ao2_iterator_destroy(&received_it);
2033 ao2_iterator_destroy(&expected_it);
2034 ast_test_status_update(test, "Received event:\n");
2035 dump_event(test, rx_event);
2036 ast_test_status_update(test, "Expected event:\n");
2037 dump_event(test, ex_event);
2038 return -1;
2039 }
2040 if (debug) {
2041 ast_test_status_update(test, "Compared events successfully%s\n",
2043 ? " (wildcard match)" : "");
2044 dump_event(test, rx_event);
2045 }
2046 ao2_cleanup(rx_event);
2047 ao2_cleanup(ex_event);
2048 rx_event = ao2_iterator_next(&received_it);
2049 ex_event = ao2_iterator_next(&expected_it);
2050 }
2051 ao2_iterator_destroy(&received_it);
2052 ao2_iterator_destroy(&expected_it);
2053
2054 if (rx_event) {
2055 ast_test_status_update(test, "Received event:\n");
2056 dump_event(test, rx_event);
2057 return -1;
2058 }
2059 if (ex_event) {
2060 ast_test_status_update(test, "Expected event:\n");
2061 dump_event(test, ex_event);
2062 return -1;
2063 }
2064 return 0;
2065}
2066
2067/*!
2068 * \internal
2069 * \brief Callback function called after each test executes.
2070 *
2071 * \details
2072 * In addition to cleanup, this function also performs verification
2073 * that the events received during a test match the events that were
2074 * expected to have been generated during the test.
2075 */
2076static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
2077{
2078 RAII_VAR(struct ao2_container *, local_expected, cel_expected_events, ao2_cleanup);
2079 RAII_VAR(struct ao2_container *, local_received, cel_received_events, ao2_cleanup);
2082
2083 do_sleep();
2084
2085 /* stop the CEL event callback and clean up storage structures*/
2087
2088 /* cleaned up by RAII_VAR's */
2091
2092 /* check events */
2093 ast_test_validate(test, !check_events(test, local_expected, local_received));
2094
2095 /* Restore the real CEL config */
2099
2100 /* clean up the locks */
2104 return 0;
2105}
2106
2107static int unload_module(void)
2108{
2109 AST_TEST_UNREGISTER(test_cel_channel_creation);
2110 AST_TEST_UNREGISTER(test_cel_unanswered_inbound_call);
2111 AST_TEST_UNREGISTER(test_cel_unanswered_outbound_call);
2112 AST_TEST_UNREGISTER(test_cel_single_party);
2113 AST_TEST_UNREGISTER(test_cel_single_bridge);
2114 AST_TEST_UNREGISTER(test_cel_single_bridge_continue);
2115 AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_a);
2116 AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_b);
2117#ifdef RACEY_TESTS
2118 AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge);
2119#endif
2120
2121 AST_TEST_UNREGISTER(test_cel_dial_unanswered);
2122 AST_TEST_UNREGISTER(test_cel_dial_unanswered_filter);
2123 AST_TEST_UNREGISTER(test_cel_dial_congestion);
2124 AST_TEST_UNREGISTER(test_cel_dial_busy);
2125 AST_TEST_UNREGISTER(test_cel_dial_unavailable);
2126 AST_TEST_UNREGISTER(test_cel_dial_caller_cancel);
2127 AST_TEST_UNREGISTER(test_cel_dial_parallel_failed);
2128 AST_TEST_UNREGISTER(test_cel_dial_answer_no_bridge);
2129 AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_a);
2130 AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_b);
2131#ifdef RACEY_TESTS
2132 AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty);
2133 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_swap);
2134 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_link);
2135#endif
2136
2137 AST_TEST_UNREGISTER(test_cel_blind_transfer);
2138 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_merge);
2139
2140 AST_TEST_UNREGISTER(test_cel_dial_pickup);
2141
2142 AST_TEST_UNREGISTER(test_cel_local_optimize);
2143
2145
2152
2153 return 0;
2154}
2155
2156static int load_module(void)
2157{
2158 /* build the test config */
2160 if (!cel_test_config) {
2161 return -1;
2162 }
2165 return -1;
2166 }
2168 return -1;
2169 }
2171 return -1;
2172 }
2184
2186
2187 AST_TEST_REGISTER(test_cel_channel_creation);
2188 AST_TEST_REGISTER(test_cel_unanswered_inbound_call);
2189 AST_TEST_REGISTER(test_cel_unanswered_outbound_call);
2190
2191 AST_TEST_REGISTER(test_cel_single_party);
2192 AST_TEST_REGISTER(test_cel_single_bridge);
2193 AST_TEST_REGISTER(test_cel_single_bridge_continue);
2194 AST_TEST_REGISTER(test_cel_single_twoparty_bridge_a);
2195 AST_TEST_REGISTER(test_cel_single_twoparty_bridge_b);
2196#ifdef RACEY_TESTS
2197 AST_TEST_REGISTER(test_cel_single_multiparty_bridge);
2198#endif
2199
2200 AST_TEST_REGISTER(test_cel_dial_unanswered);
2201 AST_TEST_REGISTER(test_cel_dial_unanswered_filter);
2202 AST_TEST_REGISTER(test_cel_dial_congestion);
2203 AST_TEST_REGISTER(test_cel_dial_busy);
2204 AST_TEST_REGISTER(test_cel_dial_unavailable);
2205 AST_TEST_REGISTER(test_cel_dial_caller_cancel);
2206 AST_TEST_REGISTER(test_cel_dial_parallel_failed);
2207 AST_TEST_REGISTER(test_cel_dial_answer_no_bridge);
2208 AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_a);
2209 AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_b);
2210#ifdef RACEY_TESTS
2211 AST_TEST_REGISTER(test_cel_dial_answer_multiparty);
2212 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_swap);
2213 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_link);
2214#endif
2215
2216 AST_TEST_REGISTER(test_cel_blind_transfer);
2217 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_merge);
2218
2219 AST_TEST_REGISTER(test_cel_dial_pickup);
2220
2221 AST_TEST_REGISTER(test_cel_local_optimize);
2222
2223 /* ast_test_register_* has to happen after AST_TEST_REGISTER */
2224 /* Verify received vs expected events and clean things up after every test */
2225 ast_test_register_init(TEST_CATEGORY, test_cel_init_cb);
2226 ast_test_register_cleanup(TEST_CATEGORY, cel_verify_and_cleanup_cb);
2227
2229}
2230
ast_mutex_t lock
Definition: app_sla.c:331
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
Bridging API.
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:934
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:94
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:90
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:92
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4677
Basic bridge subclass API.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_TO
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_SMART
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
Internal Asterisk hangup causes.
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_NORMAL
Definition: causes.h:151
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:109
Call Event Logging API.
void ast_cel_set_config(struct ast_cel_general_config *config)
Set the current CEL configuration.
Definition: cel.c:1743
struct ast_event * ast_cel_create_event(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const char *userdefevname, struct ast_json *extra, const char *peer_str)
Allocate and populate a CEL event structure.
Definition: cel.c:519
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1769
ast_cel_event_type
CEL event types.
Definition: cel.h:41
@ AST_CEL_CHANNEL_END
channel end
Definition: cel.h:47
@ AST_CEL_ANSWER
A ringing phone is answered.
Definition: cel.h:51
@ AST_CEL_BRIDGE_EXIT
channel exits a bridge
Definition: cel.h:59
@ AST_CEL_HANGUP
hangup terminates connection
Definition: cel.h:49
@ AST_CEL_PICKUP
a directed pickup was performed on this channel
Definition: cel.h:73
@ AST_CEL_APP_START
an app starts
Definition: cel.h:53
@ AST_CEL_CHANNEL_START
channel birth
Definition: cel.h:45
@ AST_CEL_ATTENDEDTRANSFER
a transfer occurs
Definition: cel.h:67
@ AST_CEL_BRIDGE_ENTER
channel enters a bridge
Definition: cel.h:57
@ AST_CEL_BLINDTRANSFER
a transfer occurs
Definition: cel.h:65
@ AST_CEL_LOCAL_OPTIMIZE
A local channel optimization occurred, this marks the end.
Definition: cel.h:77
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
Definition: cel.c:189
struct ast_cel_general_config * ast_cel_get_config(void)
Obtain the current CEL configuration.
Definition: cel.c:1731
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition: cel.c:1781
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:493
static const char type[]
Definition: chan_ooh323.c:109
General Asterisk PBX channel definitions.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
#define ast_channel_lock(chan)
Definition: channel.h:2922
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
@ AST_FLAG_OUTGOING
Definition: channel.h:999
@ AST_FLAG_ORIGINATED
Definition: channel.h:1039
#define ast_channel_unlock(chan)
Definition: channel.h:2923
@ AST_STATE_RINGING
Definition: channelstate.h:41
Channel Variables.
Local proxy channel special access.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
char * end
Definition: eagi_proxy.c:73
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:402
size_t ast_event_get_size(const struct ast_event *event)
Get the size of an event.
Definition: event.c:228
const char * ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
Get the string representation of an information element type.
Definition: event.c:208
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:293
enum ast_event_ie_pltype ast_event_get_ie_pltype(enum ast_event_ie_type ie_type)
Get the payload type for a given information element type.
Definition: event.c:218
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:302
enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator)
Get the type of the current IE in the iterator instance.
Definition: event.c:264
int ast_event_iterator_next(struct ast_event_iterator *iterator)
Move iterator instance to next IE.
Definition: event.c:258
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition: event.c:288
int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
Initialize an event iterator instance.
Definition: event.c:242
const char * ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
Get the value of the current IE in the iterator as a string payload.
Definition: event.c:274
uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator)
Get the value of the current IE in the iterator as an integer payload.
Definition: event.c:269
ast_event_ie_type
Event Information Element types.
Definition: event_defs.h:68
@ AST_EVENT_IE_END
Definition: event_defs.h:70
@ AST_EVENT_IE_CEL_EVENT_TIME
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
@ AST_EVENT_IE_CEL_CHANNAME
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
@ AST_EVENT_IE_CEL_EVENT_TIME_USEC
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
@ AST_EVENT_IE_CEL_EVENT_TYPE
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
@ AST_EVENT_IE_CEL_PEER
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Paylo...
Definition: event_defs.h:241
@ AST_EVENT_CUSTOM
Definition: event_defs.h:36
ast_event_ie_pltype
Payload types for event information elements.
Definition: event_defs.h:321
@ AST_EVENT_IE_PLTYPE_RAW
Definition: event_defs.h:330
@ AST_EVENT_IE_PLTYPE_UINT
Definition: event_defs.h:326
@ AST_EVENT_IE_PLTYPE_BITFLAGS
Definition: event_defs.h:332
@ AST_EVENT_IE_PLTYPE_STR
Definition: event_defs.h:328
@ AST_EVENT_IE_PLTYPE_UNKNOWN
Definition: event_defs.h:322
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
Media Format Cache API.
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate.
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
char * strsep(char **str, const char *delims)
Asterisk JSON abstraction layer.
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
A set of macros to manage forward-linked lists.
#define ast_cond_destroy(cond)
Definition: lock.h:202
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
pthread_cond_t ast_cond_t
Definition: lock.h:178
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:589
#define ast_mutex_destroy(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203
int errno
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
def info(msg)
Call Pickup API.
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
Definition: pickup.c:301
static int debug
Global debug status.
Definition: res_xmpp.c:441
#define NULL
Definition: resample.c:96
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct ast_blind_transfer_message * ast_blind_transfer_message_create(int is_external, struct ast_channel *transferer, const char *exten, const char *context)
Create a blind transfer message to be published.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:786
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition: strings.h:1365
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
void ast_str_container_remove(struct ao2_container *str_container, const char *remove)
Removes a string from a string container allocated by ast_str_container_alloc.
Definition: strings.c:221
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition: strings.c:205
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Message published during a blind transfer.
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
struct ao2_container * channels
Definition: bridge.h:331
Structure that contains information about a bridge.
Definition: bridge.h:349
A structure to hold CEL global configuration options.
Definition: cel.h:223
int64_t events
Definition: cel.h:228
struct ao2_container * apps
Definition: cel.h:232
const ast_string_field uniqueid
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition: channel.h:628
const char *const type
Definition: channel.h:629
Main Channel structure associated with a channel.
supposed to be an opaque type
Definition: event_defs.h:352
An event.
Definition: event.c:81
uint16_t event_len
Definition: event.c:85
Abstract JSON element (object, array, string, int, ...).
A multi channel blob data structure for multi_channel_blob stasis messages.
Structure for mutex and tracking information.
Definition: lock.h:135
Caller Party information.
Definition: channel.h:418
struct ast_party_id id
Caller party ID.
Definition: channel.h:420
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
char * str
Subscriber name (Malloced)
Definition: channel.h:264
Support for dynamic strings.
Definition: strings.h:623
Contains all the initialization information required to store a new test definition.
Definition: test.h:235
Definition: astman.c:222
Definition: ast_expr2.c:325
Test Framework API.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
#define APPEND_EVENT(chan, ev_type, userevent, extra)
Definition: test_cel.c:93
AST_TEST_DEFINE(test_cel_channel_creation)
Definition: test_cel.c:393
#define CREATE_ALICE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Alice.
Definition: test_cel.c:221
#define BRIDGE_EXIT_EVENT(channel, bridge)
Definition: test_cel.c:123
static int append_expected_event_snapshot(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
Definition: test_cel.c:1756
ast_cond_t sync_out
Condition used for checking the end of test execution.
Definition: test_cel.c:73
static int dump_event(struct ast_test *test, struct ast_event *event)
Definition: test_cel.c:1969
#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer)
Definition: test_cel.c:105
static struct ast_str * test_cel_generate_peer_str_snapshot(struct ast_channel_snapshot *chan, struct ast_bridge *bridge)
Definition: test_cel.c:351
#define CREATE_BOB_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Bob.
Definition: test_cel.c:229
static struct ao2_container * cel_received_events
Definition: test_cel.c:1684
static struct ast_event * ao2_dup_event(const struct ast_event *event)
Definition: test_cel.c:1689
static int match_ie_val(const struct ast_event *event1, const struct ast_event *event2, enum ast_event_ie_type type)
Check an IE value from two events.
Definition: test_cel.c:1895
static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cel.c:2076
static void test_sub(struct ast_event *event)
Definition: test_cel.c:1790
static void safe_bridge_destroy(struct ast_bridge *bridge)
Definition: test_cel.c:385
#define BOB_CALLERID
Bob's Caller ID.
Definition: test_cel.c:199
int do_mid_test_sync
Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock.
Definition: test_cel.c:76
static void do_sleep(void)
Definition: test_cel.c:87
static int events_are_equal(struct ast_test *test, struct ast_event *received, struct ast_event *expected)
Definition: test_cel.c:1948
ast_mutex_t mid_test_sync_lock
Lock used for synchronizing test execution stages with received events.
Definition: test_cel.c:67
#define BRIDGE_EXIT(channel, bridge)
Definition: test_cel.c:117
#define CHANNEL_TECH_NAME
Definition: test_cel.c:56
#define ALICE_CALLERID
Alice's Caller ID.
Definition: test_cel.c:196
#define EMULATE_DIAL(channel, dialstring)
Definition: test_cel.c:745
#define BRIDGE_ENTER(channel, bridge)
Definition: test_cel.c:147
#define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer)
Definition: test_cel.c:130
#define APPEND_DUMMY_EVENT()
Definition: test_cel.c:111
static void safe_channel_release(struct ast_channel *chan)
Definition: test_cel.c:377
#define CREATE_DAVID_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for David.
Definition: test_cel.c:245
#define TEST_BACKEND_NAME
Definition: test_cel.c:58
static struct ast_channel_tech test_cel_chan_tech
A channel technology used for the unit tests.
Definition: test_cel.c:79
#define START_DIALED(caller, callee)
Definition: test_cel.c:752
#define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer)
Definition: test_cel.c:161
static int append_event(struct ast_event *ev)
Definition: test_cel.c:1729
#define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4)
Definition: test_cel.c:180
#define START_DIALED_FULL(caller, callee, number, name)
Definition: test_cel.c:755
#define BLINDTRANSFER_EVENT(channel, bridge, extension, context)
Definition: test_cel.c:168
static int append_expected_event(struct ast_channel *chan, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
Definition: test_cel.c:1772
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Charlie.
Definition: test_cel.c:237
static int check_events(struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
Definition: test_cel.c:2010
static int test_cel_peer_strings_match(const char *str1, const char *str2)
Check two peer strings for equality.
Definition: test_cel.c:1855
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition: test_cel.c:253
#define ANSWER_NO_APP(chan)
Definition: test_cel.c:267
#define HANGUP_CHANNEL(channel, cause, dialstatus)
Hang up a test channel safely.
Definition: test_cel.c:273
static int load_module(void)
Definition: test_cel.c:2156
ast_mutex_t sync_lock
Lock used with sync_out for checking the end of test execution.
Definition: test_cel.c:70
static int unload_module(void)
Definition: test_cel.c:2107
static struct ast_cel_general_config * saved_config
A placeholder for Asterisk's 'real' CEL configuration.
Definition: test_cel.c:61
static struct ast_str * __test_cel_generate_peer_str(struct ast_channel_snapshot *chan, struct ast_bridge_snapshot *bridge)
Definition: test_cel.c:314
#define TEST_CATEGORY
Definition: test_cel.c:54
static struct ao2_container * cel_expected_events
Definition: test_cel.c:1687
static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cel.c:1825
static void mid_test_sync(void)
Definition: test_cel.c:1706
#define ANSWER_CHANNEL(chan)
Definition: test_cel.c:262
static struct ast_str * test_cel_generate_peer_str(struct ast_channel *chan, struct ast_bridge *bridge)
Definition: test_cel.c:364
static struct ast_cel_general_config * cel_test_config
The CEL config used for CEL unit tests.
Definition: test_cel.c:64
static struct timespec to_sleep
A 1 second sleep.
Definition: test_cel.c:85
#define CHARLIE_CALLERID
Charlie's Caller ID.
Definition: test_cel.c:202
Time-related functions and macros.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Utility functions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70