48 #include "asterisk/stasis_channels.h"
49 #include "asterisk/stasis_bridges.h"
54 #define TEST_CATEGORY "/main/cel/"
56 #define CHANNEL_TECH_NAME "CELTestChannel"
58 #define TEST_BACKEND_NAME "CEL Test Logging"
80 .type = CHANNEL_TECH_NAME,
81 .description =
"Mock channel technology for CEL tests",
87 static void do_sleep(
void)
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; \
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; \
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; \
111 #define APPEND_DUMMY_EVENT() do { \
112 if (append_dummy_event()) { \
113 return AST_TEST_FAIL; \
117 #define BRIDGE_EXIT(channel, bridge) do { \
118 ast_test_validate(test, !ast_bridge_depart(channel)); \
119 BRIDGE_EXIT_EVENT(channel, bridge); \
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)); \
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); \
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)); \
147 #define BRIDGE_ENTER(channel, bridge) do { \
148 ast_test_validate(test, !ast_bridge_impart(bridge, channel, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE)); \
150 BRIDGE_ENTER_EVENT(channel, bridge); \
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)); \
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); \
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); \
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); \
196 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
199 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
202 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
205 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
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);\
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)); \
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)); \
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)); \
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)); \
253 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
254 if ((priority) > 0) { \
255 ast_channel_priority_set((channel), (priority)); \
257 ast_channel_appl_set((channel), (application)); \
258 ast_channel_data_set((channel), (data)); \
259 ast_channel_publish_snapshot((channel)); \
262 #define ANSWER_CHANNEL(chan) do { \
263 EMULATE_APP_DATA(chan, 1, "Answer", ""); \
264 ANSWER_NO_APP(chan); \
267 #define ANSWER_NO_APP(chan) do { \
268 ast_setstate(chan, AST_STATE_UP); \
269 APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
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); \
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); \
294 static void mid_test_sync(
void);
296 static int append_expected_event(
299 const char *userdefevname,
303 static int append_expected_event_snapshot(
306 const char *userdefevname,
311 static int append_dummy_event(
void);
318 char *current_chan = NULL;
325 (current_chan = ao2_iterator_next(&i));
326 ao2_cleanup(current_chan)) {
337 if (!current_snapshot) {
341 ast_str_append(&peer_str, 0,
"%s,", current_snapshot->base->name);
361 return __test_cel_generate_peer_str(chan, snapshot);
374 return test_cel_generate_peer_str_snapshot(snapshot, bridge);
377 static void safe_channel_release(
struct ast_channel *chan)
385 static void safe_bridge_destroy(
struct ast_bridge *bridge)
400 info->name = __func__;
401 info->category = TEST_CATEGORY;
402 info->summary =
"Test the CEL records created when a channel is created";
404 "Test the CEL records created when a channel is created";
405 return AST_TEST_NOT_RUN;
414 return AST_TEST_PASS;
424 info->name = __func__;
425 info->category = TEST_CATEGORY;
426 info->summary =
"Test inbound unanswered calls";
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;
442 return AST_TEST_PASS;
452 .id.number.valid = 1, };
456 info->name = __func__;
457 info->category = TEST_CATEGORY;
458 info->summary =
"Test outbound unanswered calls";
460 "Test CEL records for a call that is\n"
461 "outbound to Asterisk but is never answered.";
462 return AST_TEST_NOT_RUN;
469 ast_channel_exten_set(chan,
"s");
470 ast_channel_context_set(chan,
"default");
475 return AST_TEST_PASS;
485 info->name = __func__;
486 info->category = TEST_CATEGORY;
487 info->summary =
"Test CEL for a single party";
489 "Test CEL records for a call that is\n"
490 "answered, but only involves a single channel";
491 return AST_TEST_NOT_RUN;
497 ANSWER_CHANNEL(chan);
502 return AST_TEST_PASS;
514 info->name = __func__;
515 info->category = TEST_CATEGORY;
516 info->summary =
"Test CEL for a single party entering/leaving a bridge";
518 "Test CEL records for a call that is\n"
519 "answered, enters a bridge, and leaves it.";
520 return AST_TEST_NOT_RUN;
525 ast_test_validate(
test, bridge != NULL);
529 ANSWER_CHANNEL(chan);
533 BRIDGE_ENTER(chan, bridge);
537 BRIDGE_EXIT(chan, bridge);
541 return AST_TEST_PASS;
552 info->name = __func__;
553 info->category = TEST_CATEGORY;
554 info->summary =
"Test CEL for a single party entering/leaving a bridge";
556 "Test CEL records for a call that is\n"
557 "answered, enters a bridge, and leaves it.";
558 return AST_TEST_NOT_RUN;
563 ast_test_validate(
test, bridge != NULL);
567 ANSWER_CHANNEL(chan);
571 BRIDGE_ENTER(chan, bridge);
575 BRIDGE_EXIT(chan, bridge);
582 return AST_TEST_PASS;
595 info->name = __func__;
596 info->category = TEST_CATEGORY;
597 info->summary =
"Test CEL for a single party entering/leaving a bridge";
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;
607 ast_test_validate(
test, bridge != NULL);
613 ANSWER_CHANNEL(chan_alice);
616 BRIDGE_ENTER(chan_alice, bridge);
619 ANSWER_CHANNEL(chan_bob);
622 BRIDGE_ENTER(chan_bob, bridge);
624 BRIDGE_EXIT(chan_alice, bridge);
625 BRIDGE_EXIT(chan_bob, bridge);
630 return AST_TEST_PASS;
643 info->name = __func__;
644 info->category = TEST_CATEGORY;
645 info->summary =
"Test CEL for a single party entering/leaving a bridge";
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;
655 ast_test_validate(
test, bridge != NULL);
661 ANSWER_CHANNEL(chan_alice);
664 ANSWER_CHANNEL(chan_bob);
668 BRIDGE_ENTER(chan_bob, bridge);
670 BRIDGE_ENTER(chan_alice, bridge);
672 BRIDGE_EXIT(chan_alice, bridge);
673 BRIDGE_EXIT(chan_bob, bridge);
678 return AST_TEST_PASS;
697 info->name = __func__;
698 info->category = TEST_CATEGORY;
699 info->summary =
"Test CEL for a single party entering/leaving a multi-party bridge";
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;
709 ast_test_validate(
test, bridge != NULL);
715 ANSWER_CHANNEL(chan_alice);
720 BRIDGE_ENTER(chan_alice, bridge);
722 ANSWER_CHANNEL(chan_bob);
726 BRIDGE_ENTER(chan_bob, bridge);
728 ANSWER_CHANNEL(chan_charlie);
731 BRIDGE_ENTER(chan_charlie, bridge);
733 BRIDGE_EXIT(chan_alice, bridge);
734 BRIDGE_EXIT(chan_bob, bridge);
735 BRIDGE_EXIT(chan_charlie, bridge);
741 return AST_TEST_PASS;
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; \
752 #define START_DIALED(caller, callee) \
753 START_DIALED_FULL(caller, callee, "200", "Bob")
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; \
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); \
775 info->name = __func__;
776 info->category = TEST_CATEGORY;
777 info->summary =
"Test CEL for a dial that isn't answered";
779 "Test CEL records for a channel that\n"
780 "performs a dial operation that isn't answered";
781 return AST_TEST_NOT_RUN;
788 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
790 START_DIALED(chan_caller, chan_callee);
798 return AST_TEST_PASS;
809 info->name = __func__;
810 info->category = TEST_CATEGORY;
811 info->summary =
"Test CEL for a dial that isn't answered";
813 "Test CEL records for a channel that\n"
814 "performs a dial operation that isn't answered";
815 return AST_TEST_NOT_RUN;
822 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
824 START_DIALED(chan_caller, chan_callee);
833 return AST_TEST_PASS;
844 info->name = __func__;
845 info->category = TEST_CATEGORY;
846 info->summary =
"Test CEL for a dial that results in a busy";
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;
857 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
859 START_DIALED(chan_caller, chan_callee);
867 return AST_TEST_PASS;
878 info->name = __func__;
879 info->category = TEST_CATEGORY;
880 info->summary =
"Test CEL for a dial that results in congestion";
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;
891 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
893 START_DIALED(chan_caller, chan_callee);
901 return AST_TEST_PASS;
912 info->name = __func__;
913 info->category = TEST_CATEGORY;
914 info->summary =
"Test CEL for a dial that results in unavailable";
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;
925 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
927 START_DIALED(chan_caller, chan_callee);
932 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION,
"CHANUNAVAIL");
935 return AST_TEST_PASS;
946 info->name = __func__;
947 info->category = TEST_CATEGORY;
948 info->summary =
"Test CEL for a dial where the caller cancels";
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;
960 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
962 START_DIALED(chan_caller, chan_callee);
970 return AST_TEST_PASS;
983 info->name = __func__;
984 info->category = TEST_CATEGORY;
985 info->summary =
"Test a parallel dial where all channels fail to answer";
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;
998 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob&" CHANNEL_TECH_NAME
"/Charlie&" CHANNEL_TECH_NAME
"/David");
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");
1023 return AST_TEST_PASS;
1034 info->name = __func__;
1035 info->category = TEST_CATEGORY;
1036 info->summary =
"Test dialing, answering, and not going into a bridge.";
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;
1050 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
1052 START_DIALED(chan_caller, chan_callee);
1057 ANSWER_NO_APP(chan_caller);
1059 ANSWER_NO_APP(chan_callee);
1067 return AST_TEST_PASS;
1079 info->name = __func__;
1080 info->category = TEST_CATEGORY;
1081 info->summary =
"Test dialing, answering, and going into a 2-party bridge";
1083 "The most 'basic' of scenarios";
1084 return AST_TEST_NOT_RUN;
1089 ast_test_validate(
test, bridge != NULL);
1093 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
1095 START_DIALED(chan_caller, chan_callee);
1100 ANSWER_NO_APP(chan_caller);
1101 ANSWER_NO_APP(chan_callee);
1105 BRIDGE_ENTER(chan_caller, bridge);
1106 BRIDGE_ENTER(chan_callee, bridge);
1108 BRIDGE_EXIT(chan_caller, bridge);
1109 BRIDGE_EXIT(chan_callee, bridge);
1114 return AST_TEST_PASS;
1126 info->name = __func__;
1127 info->category = TEST_CATEGORY;
1128 info->summary =
"Test dialing, answering, and going into a 2-party bridge";
1130 "The most 'basic' of scenarios";
1131 return AST_TEST_NOT_RUN;
1136 ast_test_validate(
test, bridge != NULL);
1140 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
1142 START_DIALED(chan_caller, chan_callee);
1147 ANSWER_NO_APP(chan_caller);
1148 ANSWER_NO_APP(chan_callee);
1151 BRIDGE_ENTER(chan_callee, bridge);
1152 BRIDGE_ENTER(chan_caller, bridge);
1154 BRIDGE_EXIT(chan_caller, bridge);
1155 BRIDGE_EXIT(chan_callee, bridge);
1160 return AST_TEST_PASS;
1176 info->name = __func__;
1177 info->category = TEST_CATEGORY;
1178 info->summary =
"Test dialing, answering, and going into a multi-party bridge";
1180 "A little tricky to get to do, but possible with some redirects.";
1181 return AST_TEST_NOT_RUN;
1186 ast_test_validate(
test, bridge != NULL);
1190 EMULATE_DIAL(chan_alice, CHANNEL_TECH_NAME
"/Bob");
1192 START_DIALED(chan_alice, chan_bob);
1197 EMULATE_DIAL(chan_charlie, CHANNEL_TECH_NAME
"/Bob");
1200 START_DIALED_FULL(chan_charlie, chan_david,
"400",
"David");
1211 ANSWER_NO_APP(chan_alice);
1213 ANSWER_NO_APP(chan_bob);
1215 ANSWER_NO_APP(chan_charlie);
1217 ANSWER_NO_APP(chan_david);
1221 BRIDGE_ENTER(chan_charlie, bridge);
1222 BRIDGE_ENTER(chan_david, bridge);
1223 BRIDGE_ENTER(chan_bob, bridge);
1224 BRIDGE_ENTER(chan_alice, bridge);
1226 BRIDGE_EXIT(chan_alice, bridge);
1227 BRIDGE_EXIT(chan_bob, bridge);
1228 BRIDGE_EXIT(chan_charlie, bridge);
1229 BRIDGE_EXIT(chan_david, bridge);
1236 return AST_TEST_PASS;
1251 info->name = __func__;
1252 info->category = TEST_CATEGORY;
1253 info->summary =
"Test blind transfers to an extension";
1255 "This test creates two channels, bridges them, and then"
1256 " blind transfers the bridge to an extension.";
1257 return AST_TEST_NOT_RUN;
1262 ast_test_validate(
test, bridge != NULL);
1267 ANSWER_NO_APP(chan_alice);
1268 ANSWER_NO_APP(chan_bob);
1270 BRIDGE_ENTER(chan_bob, bridge);
1271 BRIDGE_ENTER(chan_alice, bridge);
1275 "transfer_extension",
"transfer_context");
1276 if (!transfer_msg) {
1278 ast_test_status_update(
test,
"Failed to create transfer Stasis message\n");
1279 return AST_TEST_FAIL;
1282 if (!transfer_msg->bridge) {
1284 ast_test_status_update(
test,
"Failed to create bridge snapshot\n");
1285 return AST_TEST_FAIL;
1290 BLINDTRANSFER_EVENT(chan_alice, bridge,
"transfer_extension",
"transfer_context");
1292 BRIDGE_EXIT(chan_alice, bridge);
1293 BRIDGE_EXIT(chan_bob, bridge);
1299 return AST_TEST_PASS;
1321 info->name = __func__;
1322 info->category = TEST_CATEGORY;
1323 info->summary =
"Test attended transfers between two pairs of bridged parties";
1325 "This test creates four channels, places each pair in"
1326 " a bridge, and then attended transfers the bridges"
1328 return AST_TEST_NOT_RUN;
1334 ast_test_validate(
test, bridge1 != NULL);
1338 ANSWER_NO_APP(chan_alice);
1339 ANSWER_NO_APP(chan_bob);
1341 BRIDGE_ENTER(chan_bob, bridge1);
1342 BRIDGE_ENTER(chan_alice, bridge1);
1346 ast_test_validate(
test, bridge2 != NULL);
1350 ANSWER_NO_APP(chan_david);
1351 ANSWER_NO_APP(chan_charlie);
1353 BRIDGE_ENTER(chan_charlie, bridge2);
1355 BRIDGE_ENTER(chan_david, bridge2);
1356 BRIDGE_EXIT_EVENT(chan_bob, bridge1);
1361 ast_test_status_update(
test,
"Attended transfer failed!\n");
1362 return AST_TEST_FAIL;
1365 BRIDGE_ENTER_EVENT_PEER(chan_bob, bridge2,
"CELTestChannel/David,CELTestChannel/Charlie");
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);
1372 BRIDGE_EXIT(chan_bob, bridge2);
1373 BRIDGE_EXIT(chan_charlie, bridge2);
1383 return AST_TEST_PASS;
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";
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;
1417 "test_cel",
"test_cel_atxfer_bridges_merge_1", NULL);
1418 ast_test_validate(
test, bridge1 != NULL);
1422 ANSWER_NO_APP(chan_alice);
1423 ANSWER_NO_APP(chan_bob);
1425 BRIDGE_ENTER(chan_bob, bridge1);
1426 BRIDGE_ENTER(chan_alice, bridge1);
1431 "test_cel",
"test_cel_atxfer_bridges_merge_2", NULL);
1432 ast_test_validate(
test, bridge2 != NULL);
1436 ANSWER_NO_APP(chan_david);
1437 ANSWER_NO_APP(chan_charlie);
1439 BRIDGE_ENTER(chan_charlie, bridge2);
1441 BRIDGE_ENTER(chan_david, bridge2);
1445 ast_test_status_update(
test,
"Attended transfer failed!\n");
1446 return AST_TEST_FAIL;
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);
1454 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1457 BRIDGE_EXIT(chan_bob, bridge1);
1458 BRIDGE_EXIT(chan_charlie, bridge1);
1468 return AST_TEST_PASS;
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";
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;
1507 "test_cel",
"test_cel_atxfer_bridges_link_1", NULL);
1508 ast_test_validate(
test, bridge1 != NULL);
1512 ANSWER_NO_APP(chan_alice);
1513 ANSWER_NO_APP(chan_bob);
1515 BRIDGE_ENTER(chan_bob, bridge1);
1516 BRIDGE_ENTER(chan_alice, bridge1);
1523 "test_cel",
"test_cel_atxfer_bridges_link_2", NULL);
1524 ast_test_validate(
test, bridge2 != NULL);
1528 ANSWER_NO_APP(chan_david);
1529 ANSWER_NO_APP(chan_charlie);
1531 BRIDGE_ENTER(chan_charlie, bridge2);
1532 BRIDGE_ENTER(chan_david, bridge2);
1535 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1541 APPEND_DUMMY_EVENT();
1542 APPEND_DUMMY_EVENT();
1545 BRIDGE_EXIT(chan_bob, bridge1);
1546 BRIDGE_EXIT(chan_charlie, bridge2);
1557 return AST_TEST_PASS;
1571 info->name = __func__;
1572 info->category = TEST_CATEGORY;
1573 info->summary =
"Test call pickup";
1575 "Test CEL records for a call that is\n"
1576 "inbound to Asterisk, executes some dialplan, and\n"
1578 return AST_TEST_NOT_RUN;
1585 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME
"/Bob");
1587 START_DIALED(chan_caller, chan_callee);
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);
1613 return AST_TEST_PASS;
1631 info->name = __func__;
1632 info->category = TEST_CATEGORY;
1633 info->summary =
"Test local channel optimization record generation";
1635 "Test CEL records for two local channels being optimized\n"
1636 "out by sending a messages indicating local optimization\n"
1638 return AST_TEST_NOT_RUN;
1644 ast_test_validate(
test, mc_blob != NULL);
1649 ast_channel_lock(chan_alice);
1651 ast_channel_unlock(chan_alice);
1652 ast_test_validate(
test, alice_snapshot != NULL);
1654 ast_channel_lock(chan_bob);
1656 ast_channel_unlock(chan_bob);
1657 ast_test_validate(
test, bob_snapshot != NULL);
1663 ast_test_validate(
test, local_opt_begin != NULL);
1666 ast_test_validate(
test, local_opt_end != NULL);
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);
1680 return AST_TEST_PASS;
1696 event_dup = ao2_alloc(event_len, NULL);
1701 memcpy(event_dup, event, event_len);
1706 static void mid_test_sync(
void)
1708 ast_mutex_lock(&mid_test_sync_lock);
1710 ast_mutex_unlock(&mid_test_sync_lock);
1715 ast_mutex_unlock(&mid_test_sync_lock);
1719 struct timespec end = {
1720 .tv_sec = start.tv_sec + 15,
1721 .tv_nsec = start.tv_usec * 1000
1725 ast_cond_timedwait(&
sync_out, &sync_lock, &end);
1732 ao2_ev = ao2_dup_event(ev);
1737 ao2_link(cel_expected_events, ao2_ev);
1742 static int append_dummy_event(
void)
1756 static int append_expected_event_snapshot(
1759 const char *userdefevname,
1772 static int append_expected_event(
1775 const char *userdefevname,
1780 ast_channel_lock(chan);
1782 ast_channel_unlock(chan);
1787 return append_expected_event_snapshot(snapshot, type, userdefevname, extra, peer);
1793 const char *chan_name;
1801 if (chan_name && strncmp(chan_name, CHANNEL_TECH_NAME, 14)) {
1806 ao2_link(cel_received_events, event_dup);
1811 if (expected <= received) {
1827 ast_assert(cel_received_events == NULL);
1828 ast_assert(cel_expected_events == NULL);
1830 ast_mutex_init(&mid_test_sync_lock);
1831 ast_mutex_init(&sync_lock);
1862 if (!intersection) {
1866 while ((chan = strsep(&str1_dup,
","))) {
1870 while ((chan = strsep(&str2_dup,
","))) {
1923 if (!str1 && !str2) {
1936 return !strcmp(str1, str2);
1948 static int events_are_equal(
struct ast_test *test,
struct ast_event *received,
struct ast_event *expected)
1969 static int dump_event(
struct ast_test *test,
struct ast_event *event)
1974 ast_test_status_update(test,
"Failed to initialize event iterator. :-(\n");
1978 ast_test_status_update(test,
"Event: %s\n",
1984 const char *ie_type_name;
1990 switch (ie_pltype) {
1991 case AST_EVENT_IE_PLTYPE_UNKNOWN:
1993 ast_test_status_update(test,
"%.30s: %s\n", ie_type_name,
1997 ast_test_status_update(test,
"%.30s: %u\n", ie_type_name,
2005 ast_test_status_update(test,
"\n");
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",
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)) {
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);
2041 ast_test_status_update(test,
"Compared events successfully%s\n",
2043 ?
" (wildcard match)" :
"");
2044 dump_event(test, rx_event);
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);
2055 ast_test_status_update(test,
"Received event:\n");
2056 dump_event(test, rx_event);
2060 ast_test_status_update(test,
"Expected event:\n");
2061 dump_event(test, ex_event);
2076 static int cel_verify_and_cleanup_cb(
struct ast_test_info *info,
struct ast_test *test)
2080 ast_assert(cel_received_events != NULL);
2081 ast_assert(cel_expected_events != NULL);
2089 cel_expected_events = NULL;
2090 cel_received_events = NULL;
2093 ast_test_validate(test, !check_events(test, local_expected, local_received));
2097 ao2_cleanup(saved_config);
2098 saved_config = NULL;
2101 ast_mutex_destroy(&sync_lock);
2102 ast_mutex_destroy(&mid_test_sync_lock);
2107 static int unload_module(
void)
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);
2118 AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge);
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);
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);
2137 AST_TEST_UNREGISTER(test_cel_blind_transfer);
2138 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_merge);
2140 AST_TEST_UNREGISTER(test_cel_dial_pickup);
2142 AST_TEST_UNREGISTER(test_cel_local_optimize);
2146 ao2_cleanup(cel_expected_events);
2147 cel_expected_events = NULL;
2148 ao2_cleanup(cel_received_events);
2149 cel_received_events = NULL;
2150 ao2_cleanup(cel_test_config);
2151 cel_test_config = NULL;
2156 static int load_module(
void)
2160 if (!cel_test_config) {
2163 cel_test_config->
enable = 1;
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);
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);
2197 AST_TEST_REGISTER(test_cel_single_multiparty_bridge);
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);
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);
2216 AST_TEST_REGISTER(test_cel_blind_transfer);
2217 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_merge);
2219 AST_TEST_REGISTER(test_cel_dial_pickup);
2221 AST_TEST_REGISTER(test_cel_local_optimize);
2225 ast_test_register_init(TEST_CATEGORY, test_cel_init_cb);
2226 ast_test_register_cleanup(TEST_CATEGORY, cel_verify_and_cleanup_cb);
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.
Contains all the initialization information required to store a new test definition.
struct ao2_container * channels
Main Channel structure associated with a channel.
Local proxy channel special access.
struct ast_channel_snapshot_base * base
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
ast_event_ie_pltype
Payload types for event information elements.
The arg parameter is a search key, but is not an object.
Message published during a blind transfer.
Time-related functions and macros.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
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...
static int test_cel_peer_strings_match(const char *str1, const char *str2)
Check two peer strings for equality.
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
static int debug
Global debug status.
Structure that contains a snapshot of information about a bridge.
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
int do_mid_test_sync
Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock.
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
A local channel optimization occurred, this marks the end.
Structure representing a snapshot of channel state.
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
char * str
Subscriber name (Malloced)
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
static struct ast_cel_general_config * cel_test_config
The CEL config used for CEL unit tests.
static struct ast_cel_general_config * saved_config
A placeholder for Asterisk's 'real' CEL configuration.
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.
const ast_string_field uniqueid
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
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.
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 ...
#define ast_strdup(str)
A wrapper for strdup()
supposed to be an opaque type
static int append_event(const char *str, int category)
events are appended to a queue from where they can be dispatched to clients.
static struct timespec to_sleep
A 1 second sleep.
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
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...
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
ast_mutex_t sync_lock
Lock used with sync_out for checking the end of test execution.
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
static struct ast_channel_tech test_cel_chan_tech
A channel technology used for the unit tests.
struct ast_json * ast_json_null(void)
Get the JSON null value.
struct ast_party_id id
Caller party ID.
void ast_cel_set_config(struct ast_cel_general_config *config)
Set the current CEL configuration.
ast_event_ie_type
Event Information Element types.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
General Asterisk PBX channel definitions.
static struct ao2_container * cel_received_events
Asterisk JSON abstraction layer.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
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.
Caller Party information.
ast_mutex_t mid_test_sync_lock
Lock used for synchronizing test execution stages with received events.
#define ALICE_CALLERID
Alice's Caller ID.
A set of macros to manage forward-linked lists.
#define CREATE_ALICE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Alice.
hangup terminates connection
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.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
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.
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
Structure that contains information about a bridge.
Support for dynamic strings.
#define CHARLIE_CALLERID
Charlie's Caller ID.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
struct ao2_container * apps
#define ast_bridge_unlock(bridge)
Unlock the bridge.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
struct ast_cel_general_config * ast_cel_get_config(void)
Obtain the current CEL configuration.
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...
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Payl...
#define HANGUP_CHANNEL(channel, cause, dialstatus)
Hang up a test channel safely.
Basic bridge subclass API.
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.
#define ast_bridge_lock(bridge)
Lock the bridge.
ast_cond_t sync_out
Condition used for checking the end of test execution.
A structure to hold CEL global configuration options.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
Initialize an event iterator instance.
#define BOB_CALLERID
Bob's Caller ID.
int ast_event_iterator_next(struct ast_event_iterator *iterator)
Move iterator instance to next IE.
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...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
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.
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
A ringing phone is answered.
A multi channel blob data structure for multi_channel_blob stasis messages.
const char * ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
Get the string representation of an information element type.
Internal Asterisk hangup causes.
#define AST_TEST_DEFINE(hdr)
Abstract JSON element (object, array, string, int, ...).
#define CREATE_DAVID_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for David.
#define CREATE_BOB_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Bob.
ast_cel_event_type
CEL event types.
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.
size_t ast_event_get_size(const struct ast_event *event)
Get the size of an event.
static struct ao2_container * cel_expected_events
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
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.
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.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
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.
a directed pickup was performed on this channel
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Charlie.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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.
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.
Structure for mutex and tracking information.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ao2_link(container, obj)
Add an object to a container.