diff --git a/include/asterisk/cel.h b/include/asterisk/cel.h index 62644d2fbefe14b3f501a654b22ebef37430673e..5850edc2188d79ac5498dba4d5600a2ce9151209 100644 --- a/include/asterisk/cel.h +++ b/include/asterisk/cel.h @@ -51,44 +51,28 @@ enum ast_cel_event_type { AST_CEL_APP_START = 5, /*! \brief an app ends */ AST_CEL_APP_END = 6, - /*! \brief a bridge is established */ - AST_CEL_BRIDGE_START = 7, - /*! \brief a bridge is torn down */ - AST_CEL_BRIDGE_END = 8, - /*! \brief a conference is started */ - AST_CEL_CONF_START = 9, - /*! \brief a conference is ended */ - AST_CEL_CONF_END = 10, + /*! \brief channel enters a bridge */ + AST_CEL_BRIDGE_ENTER = 7, + /*! \brief channel exits a bridge */ + AST_CEL_BRIDGE_EXIT = 8, /*! \brief a channel is parked */ - AST_CEL_PARK_START = 11, + AST_CEL_PARK_START = 9, /*! \brief channel out of the park */ - AST_CEL_PARK_END = 12, + AST_CEL_PARK_END = 10, /*! \brief a transfer occurs */ - AST_CEL_BLINDTRANSFER = 13, + AST_CEL_BLINDTRANSFER = 11, /*! \brief a transfer occurs */ - AST_CEL_ATTENDEDTRANSFER = 14, - /*! \brief a 3-way conference, usually part of a transfer */ - AST_CEL_HOOKFLASH = 16, - /*! \brief a 3-way conference, usually part of a transfer */ - AST_CEL_3WAY_START = 17, - /*! \brief a 3-way conference, usually part of a transfer */ - AST_CEL_3WAY_END = 18, - /*! \brief channel enters a conference */ - AST_CEL_CONF_ENTER = 19, - /*! \brief channel exits a conference */ - AST_CEL_CONF_EXIT = 20, + AST_CEL_ATTENDEDTRANSFER = 12, /*! \brief a user-defined event, the event name field should be set */ - AST_CEL_USER_DEFINED = 21, + AST_CEL_USER_DEFINED = 13, /*! \brief the last channel with the given linkedid is retired */ - AST_CEL_LINKEDID_END = 22, + AST_CEL_LINKEDID_END = 14, /*! \brief a directed pickup was performed on this channel */ - AST_CEL_PICKUP = 24, + AST_CEL_PICKUP = 15, /*! \brief this call was forwarded somewhere else */ - AST_CEL_FORWARD = 25, - /*! \brief a bridge turned into a conference and will be treated as such until it is torn down */ - AST_CEL_BRIDGE_TO_CONF = 26, + AST_CEL_FORWARD = 16, /*! \brief A local channel optimization occurred */ - AST_CEL_LOCAL_OPTIMIZE = 27, + AST_CEL_LOCAL_OPTIMIZE = 17, }; /*! @@ -289,7 +273,6 @@ struct ast_channel_snapshot; * \param userdefevname Custom name for the call event. (optional) * \param extra An event-specific opaque JSON blob to be rendered and placed * in the "CEL_EXTRA" information element of the call event. (optional) - * \param peer_name The peer name to be placed into the event. (optional) * * \since 12 * @@ -298,7 +281,7 @@ struct ast_channel_snapshot; */ 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_name); + struct ast_json *extra); /*! * \brief CEL backend callback diff --git a/main/cel.c b/main/cel.c index a613b7c2ea01609178220a673442e4e5335f2ad9..ca0496c0fef788d4b07cdda216807a54fbc17055 100644 --- a/main/cel.c +++ b/main/cel.c @@ -21,10 +21,6 @@ * * \author Steve Murphy <murf@digium.com> * \author Russell Bryant <russell@digium.com> - * - * \todo Do thorough testing of all transfer methods to ensure that BLINDTRANSFER, - * ATTENDEDTRANSFER, BRIDGE_START, and BRIDGE_END events are all reported - * as expected. */ /*! \li \ref cel.c uses the configuration file \ref cel.conf @@ -96,23 +92,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") <enum name="HANGUP"/> <enum name="APP_START"/> <enum name="APP_END"/> - <enum name="BRIDGE_START"/> - <enum name="BRIDGE_END"/> - <enum name="BRIDGE_TO_CONF"/> - <enum name="CONF_START"/> - <enum name="CONF_END"/> <enum name="PARK_START"/> <enum name="PARK_END"/> <enum name="USER_DEFINED"/> - <enum name="CONF_ENTER"/> - <enum name="CONF_EXIT"/> + <enum name="BRIDGE_ENTER"/> + <enum name="BRIDGE_EXIT"/> <enum name="BLINDTRANSFER"/> <enum name="ATTENDEDTRANSFER"/> <enum name="PICKUP"/> <enum name="FORWARD"/> - <enum name="3WAY_START"/> - <enum name="3WAY_END"/> - <enum name="HOOKFLASH"/> <enum name="LINKEDID_END"/> <enum name="LOCAL_OPTIMIZE"/> </enumlist> @@ -144,12 +132,6 @@ static struct stasis_subscription *cel_parking_forwarder; /*! Subscription for forwarding the CEL-specific topic */ static struct stasis_subscription *cel_cel_forwarder; -/*! Container for primary channel/bridge ID listing for 2 party bridges */ -static struct ao2_container *bridge_primaries; - -/*! The number of buckets into which bridge primary structs will be hashed */ -#define BRIDGE_PRIMARY_BUCKETS 251 - struct stasis_message_type *cel_generic_type(void); STASIS_MESSAGE_TYPE_DEFN(cel_generic_type); @@ -308,23 +290,15 @@ static const char * const cel_event_types[CEL_MAX_EVENT_IDS] = { [AST_CEL_HANGUP] = "HANGUP", [AST_CEL_APP_START] = "APP_START", [AST_CEL_APP_END] = "APP_END", - [AST_CEL_BRIDGE_START] = "BRIDGE_START", - [AST_CEL_BRIDGE_END] = "BRIDGE_END", - [AST_CEL_BRIDGE_TO_CONF] = "BRIDGE_TO_CONF", - [AST_CEL_CONF_START] = "CONF_START", - [AST_CEL_CONF_END] = "CONF_END", [AST_CEL_PARK_START] = "PARK_START", [AST_CEL_PARK_END] = "PARK_END", [AST_CEL_USER_DEFINED] = "USER_DEFINED", - [AST_CEL_CONF_ENTER] = "CONF_ENTER", - [AST_CEL_CONF_EXIT] = "CONF_EXIT", + [AST_CEL_BRIDGE_ENTER] = "BRIDGE_ENTER", + [AST_CEL_BRIDGE_EXIT] = "BRIDGE_EXIT", [AST_CEL_BLINDTRANSFER] = "BLINDTRANSFER", [AST_CEL_ATTENDEDTRANSFER] = "ATTENDEDTRANSFER", [AST_CEL_PICKUP] = "PICKUP", [AST_CEL_FORWARD] = "FORWARD", - [AST_CEL_3WAY_START] = "3WAY_START", - [AST_CEL_3WAY_END] = "3WAY_END", - [AST_CEL_HOOKFLASH] = "HOOKFLASH", [AST_CEL_LINKEDID_END] = "LINKEDID_END", [AST_CEL_LOCAL_OPTIMIZE] = "LOCAL_OPTIMIZE", }; @@ -380,80 +354,6 @@ static int cel_backend_cmp(void *obj, void *arg, int flags) return !strcmp(backend1_id, backend2_id) ? CMP_MATCH | CMP_STOP : 0; } -struct bridge_assoc { - AST_DECLARE_STRING_FIELDS( - AST_STRING_FIELD(bridge_id); /*!< UniqueID of the bridge */ - AST_STRING_FIELD(secondary_name); /*!< UniqueID of the secondary/dialed channel */ - ); - struct ast_channel_snapshot *primary_snapshot; /*!< The snapshot for the initiating channel in the bridge */ - int track_as_conf; /*!< Whether this bridge will be treated like a conference in CEL terms */ -}; - -static void bridge_assoc_dtor(void *obj) -{ - struct bridge_assoc *assoc = obj; - ast_string_field_free_memory(assoc); - ao2_cleanup(assoc->primary_snapshot); - assoc->primary_snapshot = NULL; -} - -static struct bridge_assoc *bridge_assoc_alloc(struct ast_channel_snapshot *primary, const char *bridge_id, const char *secondary_name) -{ - RAII_VAR(struct bridge_assoc *, assoc, ao2_alloc(sizeof(*assoc), bridge_assoc_dtor), ao2_cleanup); - if (!primary || !assoc || ast_string_field_init(assoc, 64)) { - return NULL; - } - - ast_string_field_set(assoc, bridge_id, bridge_id); - ast_string_field_set(assoc, secondary_name, secondary_name); - - assoc->primary_snapshot = primary; - ao2_ref(primary, +1); - - ao2_ref(assoc, +1); - return assoc; -} - -static int add_bridge_primary(struct ast_channel_snapshot *primary, const char *bridge_id, const char *secondary_name) -{ - RAII_VAR(struct bridge_assoc *, assoc, bridge_assoc_alloc(primary, bridge_id, secondary_name), ao2_cleanup); - if (!assoc) { - return -1; - } - - ao2_link(bridge_primaries, assoc); - return 0; -} - -static void remove_bridge_primary(const char *channel_id) -{ - ao2_find(bridge_primaries, channel_id, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK | OBJ_KEY); -} - -/*! \brief Hashing function for bridge_assoc */ -static int bridge_assoc_hash(const void *obj, int flags) -{ - const struct bridge_assoc *assoc = obj; - const char *uniqueid = obj; - if (!(flags & OBJ_KEY)) { - uniqueid = assoc->primary_snapshot->uniqueid; - } - - return ast_str_hash(uniqueid); -} - -/*! \brief Comparator function for bridge_assoc */ -static int bridge_assoc_cmp(void *obj, void *arg, int flags) -{ - struct bridge_assoc *assoc1 = obj, *assoc2 = arg; - const char *assoc2_id = arg, *assoc1_id = assoc1->primary_snapshot->uniqueid; - if (!(flags & OBJ_KEY)) { - assoc2_id = assoc2->primary_snapshot->uniqueid; - } - - return !strcmp(assoc1_id, assoc2_id) ? CMP_MATCH | CMP_STOP : 0; -} - static const char *get_caller_uniqueid(struct ast_multi_channel_blob *blob) { struct ast_channel_snapshot *caller = ast_multi_channel_blob_get_channel(blob, "caller"); @@ -685,7 +585,7 @@ static int cel_track_app(const char *const_app) static int cel_linkedid_ref(const char *linkedid); 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_name) + struct ast_json *extra) { struct timeval eventtime = ast_tvnow(); RAII_VAR(char *, extra_txt, NULL, ast_json_free); @@ -714,7 +614,7 @@ struct ast_event *ast_cel_create_event(struct ast_channel_snapshot *snapshot, AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, snapshot->linkedid, AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, snapshot->userfield, AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, S_OR(extra_txt, ""), - AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, S_OR(peer_name, ""), + AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, "", AST_EVENT_IE_END); } @@ -728,12 +628,10 @@ static int cel_backend_send_cb(void *obj, void *arg, int flags) static int cel_report_event(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const char *userdefevname, - struct ast_json *extra, const char *peer2_name) + struct ast_json *extra) { struct ast_event *ev; char *linkedid = ast_strdupa(snapshot->linkedid); - const char *peer_name = peer2_name; - RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup); RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup); if (!cfg || !cfg->general) { @@ -744,13 +642,6 @@ static int cel_report_event(struct ast_channel_snapshot *snapshot, return 0; } - if (ast_strlen_zero(peer_name)) { - assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY); - if (assoc) { - peer_name = assoc->secondary_name; - } - } - /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't * reporting on CHANNEL_START so we can track when to send LINKEDID_END */ if (ast_cel_track_event(AST_CEL_LINKEDID_END) && event_type == AST_CEL_CHANNEL_START && linkedid) { @@ -768,7 +659,7 @@ static int cel_report_event(struct ast_channel_snapshot *snapshot, return 0; } - ev = ast_cel_create_event(snapshot, event_type, userdefevname, extra, peer_name); + ev = ast_cel_create_event(snapshot, event_type, userdefevname, extra); if (!ev) { return -1; } @@ -801,7 +692,7 @@ static void check_retire_linkedid(struct ast_channel_snapshot *snapshot) * before unreffing the channel we have a refcount of 3, we're done. Unlink and report. */ if (ao2_ref(lid, -1) == 3) { ast_str_container_remove(linkedids, lid); - cel_report_event(snapshot, AST_CEL_LINKEDID_END, NULL, NULL, NULL); + cel_report_event(snapshot, AST_CEL_LINKEDID_END, NULL, NULL); } ao2_ref(lid, -1); } @@ -1037,13 +928,13 @@ static void cel_channel_state_change( int is_hungup, was_hungup; if (!new_snapshot) { - cel_report_event(old_snapshot, AST_CEL_CHANNEL_END, NULL, NULL, NULL); + cel_report_event(old_snapshot, AST_CEL_CHANNEL_END, NULL, NULL); check_retire_linkedid(old_snapshot); return; } if (!old_snapshot) { - cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, NULL, NULL, NULL); + cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, NULL, NULL); return; } @@ -1061,12 +952,12 @@ static void cel_channel_state_change( "hangupcause", new_snapshot->hangupcause, "hangupsource", new_snapshot->hangupsource, "dialstatus", dialstatus); - cel_report_event(new_snapshot, AST_CEL_HANGUP, NULL, extra, NULL); + cel_report_event(new_snapshot, AST_CEL_HANGUP, NULL, extra); return; } if (old_snapshot->state != new_snapshot->state && new_snapshot->state == AST_STATE_UP) { - cel_report_event(new_snapshot, AST_CEL_ANSWER, NULL, NULL, NULL); + cel_report_event(new_snapshot, AST_CEL_ANSWER, NULL, NULL); return; } } @@ -1099,12 +990,12 @@ static void cel_channel_app_change( /* old snapshot has an application, end it */ if (old_snapshot && !ast_strlen_zero(old_snapshot->appl)) { - cel_report_event(old_snapshot, AST_CEL_APP_END, NULL, NULL, NULL); + cel_report_event(old_snapshot, AST_CEL_APP_END, NULL, NULL); } /* new snapshot has an application, start it */ if (new_snapshot && !ast_strlen_zero(new_snapshot->appl)) { - cel_report_event(new_snapshot, AST_CEL_APP_START, NULL, NULL, NULL); + cel_report_event(new_snapshot, AST_CEL_APP_START, NULL, NULL); } } @@ -1119,46 +1010,6 @@ cel_channel_snapshot_monitor cel_channel_monitors[] = { cel_channel_linkedid_change, }; -static void update_bridge_primary(struct ast_channel_snapshot *snapshot) -{ - RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup); - - if (!snapshot) { - return; - } - - assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY); - if (!assoc) { - return; - } - - ao2_cleanup(assoc->primary_snapshot); - ao2_ref(snapshot, +1); - assoc->primary_snapshot = snapshot; -} - -static int bridge_match_cb(void *obj, void *arg, int flags) -{ - struct bridge_assoc *assoc = obj; - char *bridge_id = arg; - if (!strcmp(bridge_id, assoc->bridge_id)) { - return CMP_MATCH; - } - return 0; -} - -static struct bridge_assoc *find_bridge_primary_by_bridge_id(const char *bridge_id) -{ - char *dup_id = ast_strdupa(bridge_id); - return ao2_callback(bridge_primaries, 0, bridge_match_cb, dup_id); -} - -static void clear_bridge_primary(const char *bridge_id) -{ - char *dup_id = ast_strdupa(bridge_id); - ao2_callback(bridge_primaries, OBJ_KEY | OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, bridge_match_cb, dup_id); -} - static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot) { if (!snapshot) { @@ -1184,26 +1035,9 @@ static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub, return; } - update_bridge_primary(new_snapshot); - for (i = 0; i < ARRAY_LEN(cel_channel_monitors); ++i) { cel_channel_monitors[i](old_snapshot, new_snapshot); } - } else if (ast_bridge_snapshot_type() == update->type) { - struct ast_bridge_snapshot *old_snapshot; - struct ast_bridge_snapshot *new_snapshot; - - old_snapshot = stasis_message_data(update->old_snapshot); - new_snapshot = stasis_message_data(update->new_snapshot); - - if (!old_snapshot) { - return; - } - - if (!new_snapshot) { - clear_bridge_primary(old_snapshot->uniqueid); - return; - } } } @@ -1215,79 +1049,18 @@ static void cel_bridge_enter_cb( struct ast_bridge_blob *blob = stasis_message_data(message); struct ast_bridge_snapshot *snapshot = blob->bridge; struct ast_channel_snapshot *chan_snapshot = blob->channel; - RAII_VAR(struct bridge_assoc *, assoc, find_bridge_primary_by_bridge_id(snapshot->uniqueid), ao2_cleanup); + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); if (cel_filter_channel_snapshot(chan_snapshot)) { return; } - if (snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE)) { - if (assoc && assoc->track_as_conf) { - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); - if (extra) { - cel_report_event(chan_snapshot, AST_CEL_CONF_ENTER, NULL, extra, NULL); - } - return; - } - - if (ao2_container_count(snapshot->channels) == 2) { - struct ao2_iterator i; - RAII_VAR(char *, channel_id, NULL, ao2_cleanup); - RAII_VAR(struct ast_channel_snapshot *, latest_primary, NULL, ao2_cleanup); - - /* get the name of the channel in the container we don't already know the name of */ - i = ao2_iterator_init(snapshot->channels, 0); - while ((channel_id = ao2_iterator_next(&i))) { - if (strcmp(channel_id, chan_snapshot->uniqueid)) { - break; - } - ao2_cleanup(channel_id); - channel_id = NULL; - } - ao2_iterator_destroy(&i); - - latest_primary = ast_channel_snapshot_get_latest(channel_id); - if (!latest_primary) { - return; - } - - add_bridge_primary(latest_primary, snapshot->uniqueid, chan_snapshot->name); - cel_report_event(latest_primary, AST_CEL_BRIDGE_START, NULL, NULL, chan_snapshot->name); - } else if (ao2_container_count(snapshot->channels) > 2) { - if (!assoc) { - ast_log(LOG_ERROR, "No association found for bridge %s\n", snapshot->uniqueid); - return; - } - - /* this bridge will no longer be treated like a bridge, so mark the bridge_assoc as such */ - if (!assoc->track_as_conf) { - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - assoc->track_as_conf = 1; - - extra = ast_json_pack("{s: s, s: s}", - "channel_name", chan_snapshot->name, - "bridge_id", snapshot->uniqueid); - - if (extra) { - cel_report_event(assoc->primary_snapshot, AST_CEL_BRIDGE_TO_CONF, NULL, - extra, assoc->secondary_name); - } - - ast_string_field_set(assoc, secondary_name, ""); - } - } - } else if (snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) { - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - if (!assoc) { - add_bridge_primary(chan_snapshot, snapshot->uniqueid, ""); - return; - } - extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); - if (extra) { - cel_report_event(chan_snapshot, AST_CEL_CONF_ENTER, NULL, extra, NULL); - } + extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); + if (!extra) { + return; } + + cel_report_event(chan_snapshot, AST_CEL_BRIDGE_ENTER, NULL, extra); } static void cel_bridge_leave_cb( @@ -1298,41 +1071,18 @@ static void cel_bridge_leave_cb( struct ast_bridge_blob *blob = stasis_message_data(message); struct ast_bridge_snapshot *snapshot = blob->bridge; struct ast_channel_snapshot *chan_snapshot = blob->channel; + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); if (cel_filter_channel_snapshot(chan_snapshot)) { return; } - if (snapshot->capabilities & (AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE)) { - RAII_VAR(struct bridge_assoc *, assoc, - find_bridge_primary_by_bridge_id(snapshot->uniqueid), - ao2_cleanup); - - if (!assoc) { - return; - } - - if (assoc->track_as_conf) { - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); - if (extra) { - cel_report_event(chan_snapshot, AST_CEL_CONF_EXIT, NULL, extra, NULL); - } - return; - } - - if (ao2_container_count(snapshot->channels) == 1) { - cel_report_event(assoc->primary_snapshot, AST_CEL_BRIDGE_END, NULL, NULL, assoc->secondary_name); - remove_bridge_primary(assoc->primary_snapshot->uniqueid); - return; - } - } else if (snapshot->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) { - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); - extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); - if (extra) { - cel_report_event(chan_snapshot, AST_CEL_CONF_EXIT, NULL, extra, NULL); - } + extra = ast_json_pack("{s: s}", "bridge_id", snapshot->uniqueid); + if (!extra) { + return; } + + cel_report_event(chan_snapshot, AST_CEL_BRIDGE_EXIT, NULL, extra); } static void cel_parking_cb( @@ -1350,7 +1100,7 @@ static void cel_parking_cb( "parker_dial_string", parked_payload->parker_dial_string, "parking_lot", parked_payload->parkinglot); if (extra) { - cel_report_event(parked_payload->parkee, AST_CEL_PARK_START, NULL, extra, NULL); + cel_report_event(parked_payload->parkee, AST_CEL_PARK_START, NULL, extra); } return; case PARKED_CALL_TIMEOUT: @@ -1372,7 +1122,7 @@ static void cel_parking_cb( extra = ast_json_pack("{s: s}", "reason", reason); if (extra) { - cel_report_event(parked_payload->parkee, AST_CEL_PARK_END, NULL, extra, NULL); + cel_report_event(parked_payload->parkee, AST_CEL_PARK_END, NULL, extra); } } @@ -1404,7 +1154,7 @@ static void cel_dial_cb(void *data, struct stasis_subscription *sub, extra = ast_json_pack("{s: s}", "forward", get_blob_variable(blob, "forward")); if (extra) { - cel_report_event(caller, AST_CEL_FORWARD, NULL, extra, NULL); + cel_report_event(caller, AST_CEL_FORWARD, NULL, extra); } } @@ -1429,7 +1179,7 @@ static void cel_generic_cb( { const char *event = ast_json_string_get(ast_json_object_get(event_details, "event")); struct ast_json *extra = ast_json_object_get(event_details, "extra"); - cel_report_event(obj->snapshot, event_type, event, extra, NULL); + cel_report_event(obj->snapshot, event_type, event, extra); break; } default: @@ -1467,7 +1217,7 @@ static void cel_blind_transfer_cb( "bridge_id", bridge_snapshot->uniqueid); if (extra) { - cel_report_event(chan_snapshot, AST_CEL_BLINDTRANSFER, NULL, extra, NULL); + cel_report_event(chan_snapshot, AST_CEL_BLINDTRANSFER, NULL, extra); } } @@ -1521,7 +1271,7 @@ static void cel_attended_transfer_cb( } break; } - cel_report_event(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra, NULL); + cel_report_event(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra); } static void cel_pickup_cb( @@ -1532,12 +1282,18 @@ static void cel_pickup_cb( struct ast_multi_channel_blob *obj = stasis_message_data(message); struct ast_channel_snapshot *channel = ast_multi_channel_blob_get_channel(obj, "channel"); struct ast_channel_snapshot *target = ast_multi_channel_blob_get_channel(obj, "target"); + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); if (!channel || !target) { return; } - cel_report_event(target, AST_CEL_PICKUP, NULL, NULL, channel->name); + extra = ast_json_pack("{s: s}", "pickup_channel", channel->name); + if (!extra) { + return; + } + + cel_report_event(target, AST_CEL_PICKUP, NULL, extra); } static void cel_local_cb( @@ -1548,12 +1304,18 @@ static void cel_local_cb( struct ast_multi_channel_blob *obj = stasis_message_data(message); struct ast_channel_snapshot *localone = ast_multi_channel_blob_get_channel(obj, "1"); struct ast_channel_snapshot *localtwo = ast_multi_channel_blob_get_channel(obj, "2"); + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); if (!localone || !localtwo) { return; } - cel_report_event(localone, AST_CEL_LOCAL_OPTIMIZE, NULL, NULL, localtwo->name); + extra = ast_json_pack("{s: s}", "local_two", localtwo->name); + if (!extra) { + return; + } + + cel_report_event(localone, AST_CEL_LOCAL_OPTIMIZE, NULL, extra); } static void ast_cel_engine_term(void) @@ -1570,8 +1332,6 @@ static void ast_cel_engine_term(void) cel_bridge_forwarder = stasis_unsubscribe_and_join(cel_bridge_forwarder); cel_parking_forwarder = stasis_unsubscribe_and_join(cel_parking_forwarder); cel_cel_forwarder = stasis_unsubscribe_and_join(cel_cel_forwarder); - ao2_cleanup(bridge_primaries); - bridge_primaries = NULL; ast_cli_unregister(&cli_status); ao2_cleanup(cel_dialstatus_store); cel_dialstatus_store = NULL; @@ -1599,11 +1359,6 @@ int ast_cel_engine_init(void) return -1; } - bridge_primaries = ao2_container_alloc(BRIDGE_PRIMARY_BUCKETS, bridge_assoc_hash, bridge_assoc_cmp); - if (!bridge_primaries) { - return -1; - } - cel_backends = ao2_container_alloc(BACKEND_BUCKETS, cel_backend_hash, cel_backend_cmp); if (!cel_backends) { return -1; @@ -1756,6 +1511,11 @@ struct stasis_topic *ast_cel_topic(void) struct ast_cel_general_config *ast_cel_get_config(void) { RAII_VAR(struct cel_config *, mod_cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup); + + if (!mod_cfg->general) { + return NULL; + } + ao2_ref(mod_cfg->general, +1); return mod_cfg->general; } @@ -1763,9 +1523,12 @@ struct ast_cel_general_config *ast_cel_get_config(void) void ast_cel_set_config(struct ast_cel_general_config *config) { RAII_VAR(struct cel_config *, mod_cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup); - ao2_cleanup(mod_cfg->general); + RAII_VAR(struct ast_cel_general_config *, cleanup_config, mod_cfg->general, ao2_cleanup); + mod_cfg->general = config; - ao2_ref(mod_cfg->general, +1); + if (mod_cfg->general) { + ao2_ref(mod_cfg->general, +1); + } } int ast_cel_backend_unregister(const char *name) diff --git a/tests/test_cel.c b/tests/test_cel.c index 0ad92f475f5d82471288b19539a010c3550c23a8..d440ebf534bb6d3f6c4a276109314b900fd374b8 100644 --- a/tests/test_cel.c +++ b/tests/test_cel.c @@ -90,14 +90,14 @@ static void do_sleep(void) while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); } -#define APPEND_EVENT(chan, ev_type, userevent, extra, peer) do { \ - if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \ +#define APPEND_EVENT(chan, ev_type, userevent, extra) do { \ + if (append_expected_event(chan, ev_type, userevent, extra)) { \ return AST_TEST_FAIL; \ } \ } while (0) -#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer) do { \ - if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \ +#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra) do { \ + if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra)) { \ return AST_TEST_FAIL; \ } \ } while (0) @@ -108,40 +108,38 @@ static void do_sleep(void) } \ } while (0) -#define CONF_EXIT(channel, bridge) do { \ +#define BRIDGE_EXIT(channel, bridge) do { \ ast_test_validate(test, 0 == ast_bridge_depart(channel)); \ - CONF_EXIT_EVENT(channel, bridge); \ + BRIDGE_EXIT_EVENT(channel, bridge); \ mid_test_sync(); \ } while (0) -#define CONF_EXIT_EVENT(channel, bridge) do { \ +#define BRIDGE_EXIT_EVENT(channel, bridge) do { \ RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \ extra = ast_json_pack("{s: s}", "bridge_id", bridge->uniqueid); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(channel, AST_CEL_CONF_EXIT, NULL, extra, NULL); \ + APPEND_EVENT(channel, AST_CEL_BRIDGE_EXIT, NULL, extra); \ } while (0) -#define CONF_EXIT_SNAPSHOT(channel, bridge) do { \ +#define BRIDGE_EXIT_SNAPSHOT(channel, bridge) do { \ RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \ extra = ast_json_pack("{s: s}", "bridge_id", bridge->uniqueid); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT_SNAPSHOT(channel, AST_CEL_CONF_EXIT, NULL, extra, NULL); \ + APPEND_EVENT_SNAPSHOT(channel, AST_CEL_BRIDGE_EXIT, NULL, extra); \ } while (0) -#define CONF_ENTER_EVENT(channel, bridge) do { \ - RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \ - extra = ast_json_pack("{s: s}", "bridge_id", bridge->uniqueid); \ - ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(channel, AST_CEL_CONF_ENTER, NULL, extra, NULL); \ +#define BRIDGE_ENTER(channel, bridge) do { \ + ast_test_validate(test, 0 == ast_bridge_impart(bridge, channel, NULL, NULL, 0)); \ + do_sleep(); \ + BRIDGE_ENTER_EVENT(channel, bridge); \ + mid_test_sync(); \ } while (0) -#define BRIDGE_TO_CONF(first, second, third, bridge) do { \ +#define BRIDGE_ENTER_EVENT(channel, bridge) do { \ RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \ - extra = ast_json_pack("{s: s, s: s}", \ - "channel_name", ast_channel_name(third), \ - "bridge_id", bridge->uniqueid); \ + extra = ast_json_pack("{s: s}", "bridge_id", bridge->uniqueid); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(first, AST_CEL_BRIDGE_TO_CONF, NULL, extra, ast_channel_name(second)); \ + APPEND_EVENT(channel, AST_CEL_BRIDGE_ENTER, NULL, extra); \ } while (0) #define BLINDTRANSFER_EVENT(channel, bridge, extension, context) do { \ @@ -151,7 +149,7 @@ static void do_sleep(void) "context", context, \ "bridge_id", bridge->uniqueid); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(channel, AST_CEL_BLINDTRANSFER, NULL, extra, NULL); \ + APPEND_EVENT(channel, AST_CEL_BLINDTRANSFER, NULL, extra); \ } while (0) #define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2) do { \ @@ -161,7 +159,7 @@ static void do_sleep(void) "channel2_name", ast_channel_name(channel2), \ "bridge2_id", bridge2->uniqueid); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra, NULL); \ + APPEND_EVENT(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra); \ } while (0) /*! \brief Alice's Caller ID */ @@ -179,25 +177,25 @@ static void do_sleep(void) /*! \brief Create a \ref test_cel_chan_tech for Alice. */ #define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, 0, CHANNEL_TECH_NAME "/Alice"); \ - APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \ + APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \ } while (0) /*! \brief Create a \ref test_cel_chan_tech for Bob. */ #define CREATE_BOB_CHANNEL(channel_var, caller_id) do { \ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob"); \ - APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \ + APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \ } while (0) /*! \brief Create a \ref test_cel_chan_tech for Charlie. */ #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id) do { \ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \ - APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \ + APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \ } while (0) /*! \brief Create a \ref test_cel_chan_tech for David. */ #define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \ - APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \ + APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \ } while (0) /*! \brief Emulate a channel entering into an application */ @@ -217,7 +215,7 @@ static void do_sleep(void) #define ANSWER_NO_APP(chan) do { \ ast_setstate(chan, AST_STATE_UP); \ - APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL, NULL); \ + APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \ } while (0) /*! \brief Hang up a test channel safely */ @@ -226,7 +224,7 @@ static void do_sleep(void) ao2_ref(channel, +1); \ ast_hangup((channel)); \ HANGUP_EVENT(channel, cause, dialstatus); \ - APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL, NULL); \ + APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL); \ stasis_topic_wait(ast_channel_topic_all_cached()); \ ao2_cleanup(stasis_cache_get(ast_channel_cache(), \ ast_channel_snapshot_type(), ast_channel_uniqueid(channel))); \ @@ -241,7 +239,7 @@ static void do_sleep(void) "hangupsource", "", \ "dialstatus", dialstatus); \ ast_test_validate(test, extra != NULL); \ - APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, extra, NULL); \ + APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, extra); \ } while (0) static void mid_test_sync(void); @@ -250,13 +248,13 @@ 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); + struct ast_json *extra); 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); + struct ast_json *extra); static int append_dummy_event(void); @@ -408,11 +406,11 @@ AST_TEST_DEFINE(test_cel_single_bridge) EMULATE_APP_DATA(chan, 2, "Bridge", ""); do_sleep(); - ast_bridge_impart(bridge, chan, NULL, NULL, 0); + BRIDGE_ENTER(chan, bridge); do_sleep(); - ast_bridge_depart(chan); + BRIDGE_EXIT(chan, bridge); HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, ""); @@ -446,11 +444,11 @@ AST_TEST_DEFINE(test_cel_single_bridge_continue) EMULATE_APP_DATA(chan, 2, "Bridge", ""); do_sleep(); - ast_bridge_impart(bridge, chan, NULL, NULL, 0); + BRIDGE_ENTER(chan, bridge); do_sleep(); - ast_bridge_depart(chan); + BRIDGE_EXIT(chan, bridge); EMULATE_APP_DATA(chan, 3, "Wait", ""); @@ -491,19 +489,16 @@ AST_TEST_DEFINE(test_cel_single_twoparty_bridge_a) ANSWER_CHANNEL(chan_alice); EMULATE_APP_DATA(chan_alice, 2, "Bridge", ""); - ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0); + BRIDGE_ENTER(chan_alice, bridge); do_sleep(); ANSWER_CHANNEL(chan_bob); EMULATE_APP_DATA(chan_bob, 2, "Bridge", ""); - ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0); - do_sleep(); - APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_bob)); + BRIDGE_ENTER(chan_bob, bridge); - ast_bridge_depart(chan_alice); - ast_bridge_depart(chan_bob); - APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_bob)); + BRIDGE_EXIT(chan_alice, bridge); + BRIDGE_EXIT(chan_bob, bridge); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, ""); @@ -546,16 +541,12 @@ AST_TEST_DEFINE(test_cel_single_twoparty_bridge_b) EMULATE_APP_DATA(chan_bob, 2, "Bridge", ""); do_sleep(); - ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0); - do_sleep(); + BRIDGE_ENTER(chan_bob, bridge); - ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0); - do_sleep(); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_ENTER(chan_alice, bridge); - ast_bridge_depart(chan_alice); - ast_bridge_depart(chan_bob); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_EXIT(chan_alice, bridge); + BRIDGE_EXIT(chan_bob, bridge); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, ""); @@ -566,7 +557,7 @@ AST_TEST_DEFINE(test_cel_single_twoparty_bridge_b) /* XXX Validation needs to be reworked on a per-channel basis before * test_cel_single_multiparty_bridge and test_cel_dial_answer_multiparty * can operate properly. */ -#if 0 +#ifdef RACEY_TESTS AST_TEST_DEFINE(test_cel_single_multiparty_bridge) { RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release); @@ -602,26 +593,22 @@ AST_TEST_DEFINE(test_cel_single_multiparty_bridge) do_sleep(); - ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0); + BRIDGE_ENTER(chan_alice, bridge); ANSWER_CHANNEL(chan_bob); EMULATE_APP_DATA(chan_bob, 2, "Bridge", ""); do_sleep(); - ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0); - do_sleep(); - APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_bob)); + BRIDGE_ENTER(chan_bob, bridge); ANSWER_CHANNEL(chan_charlie); EMULATE_APP_DATA(chan_charlie, 2, "Bridge", ""); do_sleep(); - ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0); - do_sleep(); - BRIDGE_TO_CONF(chan_alice, chan_bob, chan_charlie, bridge); + BRIDGE_ENTER(chan_charlie, bridge); - CONF_EXIT(chan_alice, bridge); - CONF_EXIT(chan_bob, bridge); - CONF_EXIT(chan_charlie, bridge); + BRIDGE_EXIT(chan_alice, bridge); + BRIDGE_EXIT(chan_bob, bridge); + BRIDGE_EXIT(chan_charlie, bridge); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, ""); @@ -633,7 +620,7 @@ AST_TEST_DEFINE(test_cel_single_multiparty_bridge) #define EMULATE_DIAL(channel, dialstring) do { \ EMULATE_APP_DATA(channel, 1, "Dial", dialstring); \ - if (append_expected_event(channel, AST_CEL_APP_START, NULL, NULL, NULL)) { \ + if (append_expected_event(channel, AST_CEL_APP_START, NULL, NULL)) { \ return AST_TEST_FAIL; \ } \ } while (0) @@ -643,7 +630,7 @@ AST_TEST_DEFINE(test_cel_single_multiparty_bridge) #define START_DIALED_FULL(caller, callee, number, name) do { \ callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, ast_channel_linkedid(caller), 0, CHANNEL_TECH_NAME "/" name); \ - if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL, NULL)) { \ + if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL)) { \ return AST_TEST_FAIL; \ } \ ast_set_flag(ast_channel_flags(callee), AST_FLAG_OUTGOING); \ @@ -955,15 +942,11 @@ AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_a) do_sleep(); - ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0); - do_sleep(); - ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0); - do_sleep(); - APPEND_EVENT(chan_caller, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_callee)); + BRIDGE_ENTER(chan_caller, bridge); + BRIDGE_ENTER(chan_callee, bridge); - ast_bridge_depart(chan_caller); - ast_bridge_depart(chan_callee); - APPEND_EVENT(chan_caller, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_callee)); + BRIDGE_EXIT(chan_caller, bridge); + BRIDGE_EXIT(chan_callee, bridge); HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER"); HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, ""); @@ -1005,15 +988,11 @@ AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_b) ANSWER_NO_APP(chan_callee); do_sleep(); - ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0); - do_sleep(); - ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0); - do_sleep(); - APPEND_EVENT(chan_callee, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_caller)); + BRIDGE_ENTER(chan_callee, bridge); + BRIDGE_ENTER(chan_caller, bridge); - ast_bridge_depart(chan_caller); - ast_bridge_depart(chan_callee); - APPEND_EVENT(chan_callee, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_caller)); + BRIDGE_EXIT(chan_caller, bridge); + BRIDGE_EXIT(chan_callee, bridge); HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER"); HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, ""); @@ -1021,7 +1000,7 @@ AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_b) return AST_TEST_PASS; } -#if 0 +#ifdef RACEY_TESTS AST_TEST_DEFINE(test_cel_dial_answer_multiparty) { RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release); @@ -1079,24 +1058,15 @@ AST_TEST_DEFINE(test_cel_dial_answer_multiparty) do_sleep(); do_sleep(); - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0)); - do_sleep(); - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_david, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_david)); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0)); - do_sleep(); - BRIDGE_TO_CONF(chan_charlie, chan_david, chan_bob, bridge); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0)); - do_sleep(); - CONF_ENTER_EVENT(chan_alice, bridge); + BRIDGE_ENTER(chan_charlie, bridge); + BRIDGE_ENTER(chan_david, bridge); + BRIDGE_ENTER(chan_bob, bridge); + BRIDGE_ENTER(chan_alice, bridge); - CONF_EXIT(chan_alice, bridge); - CONF_EXIT(chan_bob, bridge); - CONF_EXIT(chan_charlie, bridge); - CONF_EXIT(chan_david, bridge); + BRIDGE_EXIT(chan_alice, bridge); + BRIDGE_EXIT(chan_bob, bridge); + BRIDGE_EXIT(chan_charlie, bridge); + BRIDGE_EXIT(chan_david, bridge); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "ANSWER"); HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, ""); @@ -1137,12 +1107,8 @@ AST_TEST_DEFINE(test_cel_blind_transfer) ANSWER_NO_APP(chan_alice); ANSWER_NO_APP(chan_bob); - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0)); - do_sleep(); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_ENTER(chan_bob, bridge); + BRIDGE_ENTER(chan_alice, bridge); pair.bridge = bridge; pair.channel = chan_alice; @@ -1150,10 +1116,8 @@ AST_TEST_DEFINE(test_cel_blind_transfer) &pair, "transfer_context", "transfer_extension"); BLINDTRANSFER_EVENT(chan_alice, bridge, "transfer_extension", "transfer_context"); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_alice)); - ast_test_validate(test, 0 == ast_bridge_depart(chan_alice)); - - ast_test_validate(test, 0 == ast_bridge_depart(chan_bob)); + BRIDGE_EXIT(chan_alice, bridge); + BRIDGE_EXIT(chan_bob, bridge); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); do_sleep(); @@ -1197,12 +1161,8 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_swap) ANSWER_NO_APP(chan_alice); ANSWER_NO_APP(chan_bob); - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_bob, NULL, NULL, 0)); - do_sleep(); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_alice, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_ENTER(chan_bob, bridge1); + BRIDGE_ENTER(chan_alice, bridge1); /* Create second set of bridged parties */ bridge2 = ast_bridge_basic_new(); @@ -1213,26 +1173,24 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_swap) ANSWER_NO_APP(chan_david); ANSWER_NO_APP(chan_charlie); - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0)); - do_sleep(); + BRIDGE_ENTER(chan_charlie, bridge2); - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_david, NULL, NULL, 0)); + BRIDGE_ENTER(chan_david, bridge2); + BRIDGE_EXIT_EVENT(chan_bob, bridge1); do_sleep(); - APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_david)); /* Perform attended transfer */ - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_alice)); - ast_bridge_transfer_attended(chan_alice, chan_david); do_sleep(); - BRIDGE_TO_CONF(chan_charlie, chan_david, chan_bob, bridge2); - CONF_EXIT_EVENT(chan_david, bridge2); + BRIDGE_ENTER_EVENT(chan_bob, bridge2); + BRIDGE_EXIT_EVENT(chan_david, bridge2); ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2); + BRIDGE_EXIT_EVENT(chan_alice, bridge1); do_sleep(); - CONF_EXIT(chan_bob, bridge2); - CONF_EXIT(chan_charlie, bridge2); + BRIDGE_EXIT(chan_bob, bridge2); + BRIDGE_EXIT(chan_charlie, bridge2); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); do_sleep(); @@ -1282,12 +1240,8 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_merge) ANSWER_NO_APP(chan_alice); ANSWER_NO_APP(chan_bob); - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_bob, NULL, NULL, 0)); - do_sleep(); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_alice, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_ENTER(chan_bob, bridge1); + BRIDGE_ENTER(chan_alice, bridge1); /* Create second set of bridged parties */ bridge2 = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_MULTIMIX, @@ -1299,26 +1253,23 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_merge) ANSWER_NO_APP(chan_david); ANSWER_NO_APP(chan_charlie); - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0)); - do_sleep(); + BRIDGE_ENTER(chan_charlie, bridge2); - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_david, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_david)); + BRIDGE_ENTER(chan_david, bridge2); /* Perform attended transfer */ - APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_david)); - ast_bridge_transfer_attended(chan_alice, chan_david); do_sleep(); - BRIDGE_TO_CONF(chan_bob, chan_alice, chan_charlie, bridge1); - CONF_EXIT_EVENT(chan_alice, bridge1); + BRIDGE_EXIT_EVENT(chan_charlie, bridge2); + BRIDGE_ENTER_EVENT(chan_charlie, bridge1); + BRIDGE_EXIT_EVENT(chan_david, bridge2); + BRIDGE_EXIT_EVENT(chan_alice, bridge1); ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2); do_sleep(); - CONF_EXIT(chan_bob, bridge1); - CONF_EXIT(chan_charlie, bridge1); + BRIDGE_EXIT(chan_bob, bridge1); + BRIDGE_EXIT(chan_charlie, bridge1); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); do_sleep(); @@ -1370,12 +1321,8 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link) ANSWER_NO_APP(chan_alice); ANSWER_NO_APP(chan_bob); - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_bob, NULL, NULL, 0)); - do_sleep(); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_alice, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice)); + BRIDGE_ENTER(chan_bob, bridge1); + BRIDGE_ENTER(chan_alice, bridge1); /* Create second set of bridged parties */ bridge2 = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_MULTIMIX, @@ -1389,12 +1336,8 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link) ANSWER_NO_APP(chan_david); ANSWER_NO_APP(chan_charlie); - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0)); - do_sleep(); - - ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_david, NULL, NULL, 0)); - do_sleep(); - APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_david)); + BRIDGE_ENTER(chan_charlie, bridge2); + BRIDGE_ENTER(chan_david, bridge2); /* Perform attended transfer */ @@ -1407,27 +1350,21 @@ AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link) ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2); - /* The two BRIDGE_TO_CONFs and CONF_EXITs are all racing to be first */ - - /* BRIDGE_TO_CONF with primary charlie, peer david, and trigger channel ;2 */ - APPEND_DUMMY_EVENT(); - ast_bridge_transfer_attended(chan_alice, chan_david); do_sleep(); - /* BRIDGE_TO_CONF with primary bob, peer alice, and trigger channel ;1 */ + /* ;1 and ;2 BRIDGE_ENTER and ;1 ANSWER */ APPEND_DUMMY_EVENT(); - - /* CONF_EXIT alice and david */ APPEND_DUMMY_EVENT(); APPEND_DUMMY_EVENT(); - /* ANSWER ;1 */ + /* BRIDGE_EXIT alice and david */ + APPEND_DUMMY_EVENT(); APPEND_DUMMY_EVENT(); do_sleep(); - CONF_EXIT(chan_bob, bridge1); - CONF_EXIT(chan_charlie, bridge2); + BRIDGE_EXIT(chan_bob, bridge1); + BRIDGE_EXIT(chan_charlie, bridge2); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); do_sleep(); @@ -1473,8 +1410,13 @@ AST_TEST_DEFINE(test_cel_dial_pickup) CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller); { + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); SCOPED_CHANNELLOCK(lock, chan_callee); - APPEND_EVENT(chan_callee, AST_CEL_PICKUP, NULL, NULL, ast_channel_name(chan_charlie)); + + extra = ast_json_pack("{s: s}", "pickup_channel", ast_channel_name(chan_charlie)); + ast_test_validate(test, extra != NULL); + + APPEND_EVENT(chan_callee, AST_CEL_PICKUP, NULL, extra); ast_test_validate(test, 0 == ast_do_pickup(chan_charlie, chan_callee)); } @@ -1500,6 +1442,7 @@ AST_TEST_DEFINE(test_cel_local_optimize) RAII_VAR(struct ast_channel_snapshot *, bob_snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, local_opt_begin, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, local_opt_end, NULL, ao2_cleanup); + RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); switch (cmd) { case TEST_INIT: @@ -1538,7 +1481,11 @@ AST_TEST_DEFINE(test_cel_local_optimize) stasis_publish(ast_channel_topic(chan_alice), local_opt_begin); stasis_publish(ast_channel_topic(chan_alice), local_opt_end); - APPEND_EVENT_SNAPSHOT(alice_snapshot, AST_CEL_LOCAL_OPTIMIZE, NULL, NULL, bob_snapshot->name); + + extra = ast_json_pack("{s: s}", "local_two", bob_snapshot->name); + ast_test_validate(test, extra != NULL); + + APPEND_EVENT_SNAPSHOT(alice_snapshot, AST_CEL_LOCAL_OPTIMIZE, NULL, extra); HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, ""); HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, ""); @@ -1621,10 +1568,10 @@ 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) + struct ast_json *extra) { RAII_VAR(struct ast_event *, ev, NULL, ast_free); - ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer); + ev = ast_cel_create_event(snapshot, type, userdefevname, extra); if (!ev) { return -1; } @@ -1636,7 +1583,7 @@ 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) + struct ast_json *extra) { RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); snapshot = ast_channel_snapshot_create(chan); @@ -1644,7 +1591,7 @@ static int append_expected_event( return -1; } - return append_expected_event_snapshot(snapshot, type, userdefevname, extra, peer); + return append_expected_event_snapshot(snapshot, type, userdefevname, extra); } static void test_sub(struct ast_event *event) @@ -1904,7 +1851,9 @@ static int unload_module(void) AST_TEST_UNREGISTER(test_cel_single_bridge_continue); AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_a); AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_b); - /*AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge);*/ +#ifdef RACEY_TESTS + AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge); +#endif AST_TEST_UNREGISTER(test_cel_dial_unanswered); AST_TEST_UNREGISTER(test_cel_dial_congestion); @@ -1915,7 +1864,9 @@ static int unload_module(void) AST_TEST_UNREGISTER(test_cel_dial_answer_no_bridge); AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_a); AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_b); - /*AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty);*/ +#ifdef RACEY_TESTS + AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty); +#endif AST_TEST_UNREGISTER(test_cel_blind_transfer); AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_swap); @@ -1956,11 +1907,8 @@ static int load_module(void) cel_test_config->events |= 1<<AST_CEL_CHANNEL_END; cel_test_config->events |= 1<<AST_CEL_ANSWER; cel_test_config->events |= 1<<AST_CEL_HANGUP; - cel_test_config->events |= 1<<AST_CEL_BRIDGE_START; - cel_test_config->events |= 1<<AST_CEL_BRIDGE_END; - cel_test_config->events |= 1<<AST_CEL_BRIDGE_TO_CONF; - cel_test_config->events |= 1<<AST_CEL_CONF_ENTER; - cel_test_config->events |= 1<<AST_CEL_CONF_EXIT; + cel_test_config->events |= 1<<AST_CEL_BRIDGE_ENTER; + cel_test_config->events |= 1<<AST_CEL_BRIDGE_EXIT; cel_test_config->events |= 1<<AST_CEL_BLINDTRANSFER; cel_test_config->events |= 1<<AST_CEL_ATTENDEDTRANSFER; cel_test_config->events |= 1<<AST_CEL_PICKUP; @@ -1977,7 +1925,9 @@ static int load_module(void) AST_TEST_REGISTER(test_cel_single_bridge_continue); AST_TEST_REGISTER(test_cel_single_twoparty_bridge_a); AST_TEST_REGISTER(test_cel_single_twoparty_bridge_b); - /*AST_TEST_REGISTER(test_cel_single_multiparty_bridge);*/ +#ifdef RACEY_TESTS + AST_TEST_REGISTER(test_cel_single_multiparty_bridge); +#endif AST_TEST_REGISTER(test_cel_dial_unanswered); AST_TEST_REGISTER(test_cel_dial_congestion); @@ -1988,7 +1938,9 @@ static int load_module(void) AST_TEST_REGISTER(test_cel_dial_answer_no_bridge); AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_a); AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_b); - /*AST_TEST_REGISTER(test_cel_dial_answer_multiparty);*/ +#ifdef RACEY_TESTS + AST_TEST_REGISTER(test_cel_dial_answer_multiparty); +#endif AST_TEST_REGISTER(test_cel_blind_transfer); AST_TEST_REGISTER(test_cel_attended_transfer_bridges_swap);