mirror of
https://github.com/asterisk/asterisk.git
synced 2025-12-04 12:12:05 +00:00
ISDN AOC: Fix crash from an AOC-E message that doesn't have a channel association.
Processing an AOC-E event that does not or no longer has a channel association causes a crash. The problem with posting AOC events to the channel topic is that AOC-E events don't always have a channel association and posting the event to the all channels topic is just wrong. AOC-E events do however have their own charging association method to refer to the agreement with the charging entity. * Changed the AOC events to post to the AMI manager topic instead of the channel topics. If a channel is associated with the event then channel snapshot information is supplied with the AMI event. * Eliminated RAII_VAR() usage in aoc_to_ami() and ast_aoc_manager_event(). This patch supercedes the patch on Review: https://reviewboard.asterisk.org/r/4427/ ASTERISK-22670 #close Reported by: klaus3000 ASTERISK-24689 #close Reported by: Marcel Manz ASTERISK-24740 #close Reported by: Panos Gkikakis Review: https://reviewboard.asterisk.org/r/4430/ ........ Merged revisions 431974 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@431975 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
86
main/aoc.c
86
main/aoc.c
@@ -1793,26 +1793,89 @@ static struct ast_json *e_to_json(const struct ast_aoc_decoded *decoded)
|
|||||||
"Charge", charge_to_json(decoded));
|
"Charge", charge_to_json(decoded));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct aoc_event_blob {
|
||||||
|
/*! Channel AOC event is associated with (NULL for unassociated) */
|
||||||
|
struct ast_channel_snapshot *snapshot;
|
||||||
|
/*! AOC JSON blob of data */
|
||||||
|
struct ast_json *blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void aoc_event_blob_dtor(void *obj)
|
||||||
|
{
|
||||||
|
struct aoc_event_blob *aoc_event = obj;
|
||||||
|
|
||||||
|
ao2_cleanup(aoc_event->snapshot);
|
||||||
|
ast_json_unref(aoc_event->blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* \brief Publish an AOC event.
|
||||||
|
* \since 13.3.0
|
||||||
|
*
|
||||||
|
* \param chan Channel associated with the AOC event. (May be NULL if no channel)
|
||||||
|
* \param msg_type What kind of AOC event.
|
||||||
|
* \param blob AOC data blob to publish.
|
||||||
|
*
|
||||||
|
* \return Nothing
|
||||||
|
*/
|
||||||
|
static void aoc_publish_blob(struct ast_channel *chan, struct stasis_message_type *msg_type, struct ast_json *blob)
|
||||||
|
{
|
||||||
|
struct stasis_message *msg;
|
||||||
|
struct aoc_event_blob *aoc_event;
|
||||||
|
|
||||||
|
if (!blob || ast_json_is_null(blob)) {
|
||||||
|
/* No AOC blob information? Nothing to send an event about. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc_event = ao2_alloc_options(sizeof(*aoc_event), aoc_event_blob_dtor,
|
||||||
|
AO2_ALLOC_OPT_LOCK_NOLOCK);
|
||||||
|
if (!aoc_event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan) {
|
||||||
|
aoc_event->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
|
||||||
|
if (!aoc_event->snapshot) {
|
||||||
|
ao2_ref(aoc_event, -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aoc_event->blob = ast_json_ref(blob);
|
||||||
|
|
||||||
|
msg = stasis_message_create(msg_type, aoc_event);
|
||||||
|
ao2_ref(aoc_event, -1);
|
||||||
|
|
||||||
|
stasis_publish(ast_manager_get_topic(), msg);
|
||||||
|
}
|
||||||
|
|
||||||
static struct ast_manager_event_blob *aoc_to_ami(struct stasis_message *message,
|
static struct ast_manager_event_blob *aoc_to_ami(struct stasis_message *message,
|
||||||
const char *event_name)
|
const char *event_name)
|
||||||
{
|
{
|
||||||
struct ast_channel_blob *obj = stasis_message_data(message);
|
struct aoc_event_blob *aoc_event = stasis_message_data(message);
|
||||||
RAII_VAR(struct ast_str *, channel, NULL, ast_free);
|
struct ast_str *channel = NULL;
|
||||||
RAII_VAR(struct ast_str *, aoc, NULL, ast_free);
|
struct ast_str *aoc;
|
||||||
|
struct ast_manager_event_blob *ev = NULL;
|
||||||
|
|
||||||
if (!(channel = ast_manager_build_channel_state_string(
|
if (aoc_event->snapshot) {
|
||||||
obj->snapshot))) {
|
channel = ast_manager_build_channel_state_string(aoc_event->snapshot);
|
||||||
|
if (!channel) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(aoc = ast_manager_str_from_json_object(obj->blob, NULL))) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast_manager_event_blob_create(EVENT_FLAG_AOC, event_name, "%s%s",
|
aoc = ast_manager_str_from_json_object(aoc_event->blob, NULL);
|
||||||
|
if (aoc && !ast_strlen_zero(ast_str_buffer(aoc))) {
|
||||||
|
ev = ast_manager_event_blob_create(EVENT_FLAG_AOC, event_name, "%s%s",
|
||||||
AS_OR(channel, ""), ast_str_buffer(aoc));
|
AS_OR(channel, ""), ast_str_buffer(aoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast_free(aoc);
|
||||||
|
ast_free(channel);
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ast_manager_event_blob *aoc_s_to_ami(struct stasis_message *message)
|
static struct ast_manager_event_blob *aoc_s_to_ami(struct stasis_message *message)
|
||||||
{
|
{
|
||||||
return aoc_to_ami(message, "AOC-S");
|
return aoc_to_ami(message, "AOC-S");
|
||||||
@@ -1846,7 +1909,7 @@ STASIS_MESSAGE_TYPE_DEFN(
|
|||||||
|
|
||||||
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
|
int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_channel *chan)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
|
struct ast_json *blob;
|
||||||
struct stasis_message_type *msg_type;
|
struct stasis_message_type *msg_type;
|
||||||
|
|
||||||
if (!decoded) {
|
if (!decoded) {
|
||||||
@@ -1871,7 +1934,8 @@ int ast_aoc_manager_event(const struct ast_aoc_decoded *decoded, struct ast_chan
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_channel_publish_cached_blob(chan, msg_type, blob);
|
aoc_publish_blob(chan, msg_type, blob);
|
||||||
|
ast_json_unref(blob);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user