static void parse_apps(const char *val) { char *apps = ast_strdupa(val); char *cur_app; if (!ast_cel_track_event(AST_CEL_APP_START) && !ast_cel_track_event(AST_CEL_APP_END)) { ast_log(LOG_WARNING, "An apps= config line, but not tracking APP events\n"); return; } while ((cur_app = strsep(&apps, ","))) { char *app; cur_app = ast_strip(cur_app); if (ast_strlen_zero(cur_app)) { continue; } if (!(app = ao2_alloc(strlen(cur_app) + 1, NULL))) { continue; } strcpy(app, cur_app); ao2_link(appset, app); ao2_ref(app, -1); app = NULL; } }
void ast_cel_check_retire_linkedid(struct ast_channel *chan) { const char *linkedid = chan->linkedid; struct channel_find_data find_dat; /* make sure we need to do all this work */ if (!ast_strlen_zero(linkedid) && ast_cel_track_event(AST_CEL_LINKEDID_END)) { struct ast_channel *tmp = NULL; find_dat.chan = chan; find_dat.linkedid = linkedid; if ((tmp = ast_channel_callback(linkedid_match, NULL, &find_dat, 0))) { tmp = ast_channel_unref(tmp); } else { ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); } } }
/* called whenever a channel is destroyed or a linkedid is changed to * potentially emit a CEL_LINKEDID_END event */ void ast_cel_check_retire_linkedid(struct ast_channel *chan) { const char *linkedid = ast_channel_linkedid(chan); char *lid; /* make sure we need to do all this work */ if (ast_strlen_zero(linkedid) || !ast_cel_track_event(AST_CEL_LINKEDID_END)) { return; } if (!(lid = ao2_find(linkedids, (void *) linkedid, OBJ_POINTER))) { ast_log(LOG_ERROR, "Something weird happened, couldn't find linkedid %s\n", linkedid); return; } /* We have a ref for each channel with this linkedid, the link and the above find, so if * before unreffing the channel we have a refcount of 3, we're done. Unlink and report. */ if (ao2_ref(lid, -1) == 3) { ao2_unlink(linkedids, lid); ast_cel_report_event(chan, AST_CEL_LINKEDID_END, NULL, NULL, NULL); } ao2_ref(lid, -1); }
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2) { struct timeval eventtime; struct ast_event *ev; const char *peername = ""; struct ast_channel *peer; ast_channel_lock(chan); peer = ast_bridged_channel(chan); if (peer) { ast_channel_ref(peer); } ast_channel_unlock(chan); /* Make sure a reload is not occurring while we're checking to see if this * is an event that we care about. We could lose an important event in this * process otherwise. */ ast_mutex_lock(&reload_lock); if (!cel_enabled || !ast_cel_track_event(event_type)) { ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_unref(peer); } return 0; } if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { char *app; if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) { ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_unref(peer); } return 0; } ao2_ref(app, -1); } ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_lock(peer); peername = ast_strdupa(peer->name); ast_channel_unlock(peer); } else if (peer2) { ast_channel_lock(peer2); peername = ast_strdupa(peer2->name); ast_channel_unlock(peer2); } if (!userdefevname) { userdefevname = ""; } if (!extra) { extra = ""; } eventtime = ast_tvnow(); ast_channel_lock(chan); ev = ast_event_new(AST_EVENT_CEL, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""), AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""), AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->dialed.number.str, ""), AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten, AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context, AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name, AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""), AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""), AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags, AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode, AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount, AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid, AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid, AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield, AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, AST_EVENT_IE_END); ast_channel_unlock(chan); if (peer) { peer = ast_channel_unref(peer); } if (ev && ast_event_queue(ev)) { ast_event_destroy(ev); return -1; } return 0; }
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2) { struct timeval eventtime; struct ast_event *ev; const char *peername = ""; struct ast_channel *peer; char *linkedid = ast_strdupa(ast_channel_linkedid(chan)); /* Make sure a reload is not occurring while we're checking to see if this * is an event that we care about. We could lose an important event in this * process otherwise. */ ast_mutex_lock(&reload_lock); /* 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 (cel_enabled && ast_cel_track_event(AST_CEL_LINKEDID_END) && event_type == AST_CEL_CHANNEL_START && linkedid) { if (ast_cel_linkedid_ref(linkedid)) { ast_mutex_unlock(&reload_lock); return -1; } } if (!cel_enabled || !ast_cel_track_event(event_type)) { ast_mutex_unlock(&reload_lock); return 0; } if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { char *app; if (!(app = ao2_find(appset, (char *) ast_channel_appl(chan), OBJ_POINTER))) { ast_mutex_unlock(&reload_lock); return 0; } ao2_ref(app, -1); } ast_mutex_unlock(&reload_lock); ast_channel_lock(chan); peer = ast_bridged_channel(chan); if (peer) { ast_channel_ref(peer); } ast_channel_unlock(chan); if (peer) { ast_channel_lock(peer); peername = ast_strdupa(ast_channel_name(peer)); ast_channel_unlock(peer); } else if (peer2) { ast_channel_lock(peer2); peername = ast_strdupa(ast_channel_name(peer2)); ast_channel_unlock(peer2); } if (!userdefevname) { userdefevname = ""; } if (!extra) { extra = ""; } eventtime = ast_tvnow(); ast_channel_lock(chan); ev = ast_event_new(AST_EVENT_CEL, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""), AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""), AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""), AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""), AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_dialed(chan)->number.str, ""), AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, ast_channel_exten(chan), AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, ast_channel_context(chan), AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, ast_channel_name(chan), AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_appl(chan), ""), AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_data(chan), ""), AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, ast_channel_amaflags(chan), AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, ast_channel_accountcode(chan), AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, ast_channel_peeraccount(chan), AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, ast_channel_uniqueid(chan), AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, ast_channel_linkedid(chan), AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, ast_channel_userfield(chan), AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, AST_EVENT_IE_END); ast_channel_unlock(chan); if (peer) { peer = ast_channel_unref(peer); } if (ev && ast_event_queue(ev)) { ast_event_destroy(ev); return -1; } return 0; }