summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES8
-rw-r--r--UPGRADE.txt4
-rw-r--r--apps/app_queue.c25
-rw-r--r--channels/chan_oss.c2
-rw-r--r--codecs/codec_speex.c83
-rw-r--r--configs/samples/codecs.conf.sample3
-rw-r--r--funcs/func_frame_trace.c3
-rw-r--r--funcs/func_strings.c1
-rw-r--r--include/asterisk/ari.h14
-rw-r--r--include/asterisk/frame.h2
-rw-r--r--include/asterisk/mod_format.h6
-rw-r--r--include/asterisk/options.h27
-rw-r--r--include/asterisk/stasis_app.h50
-rw-r--r--include/asterisk/translate.h12
-rw-r--r--main/app.c26
-rw-r--r--main/asterisk.c1
-rw-r--r--main/astobj2.c14
-rw-r--r--main/channel.c20
-rw-r--r--main/format_compatibility.c4
-rw-r--r--main/frame.c77
-rw-r--r--main/libasteriskpj.c2
-rw-r--r--main/strings.c21
-rw-r--r--main/translate.c11
-rw-r--r--res/ari/ari_websockets.c14
-rw-r--r--res/ari/cli.c175
-rw-r--r--res/ari/resource_events.c10
-rw-r--r--res/res_ari.c77
-rw-r--r--res/res_ari_applications.c42
-rw-r--r--res/res_ari_asterisk.c120
-rw-r--r--res/res_ari_bridges.c162
-rw-r--r--res/res_ari_channels.c354
-rw-r--r--res/res_ari_device_states.c27
-rw-r--r--res/res_ari_endpoints.c45
-rw-r--r--res/res_ari_events.c18
-rw-r--r--res/res_ari_mailboxes.c27
-rw-r--r--res/res_ari_playbacks.c24
-rw-r--r--res/res_ari_recordings.c51
-rw-r--r--res/res_ari_sounds.c21
-rw-r--r--res/res_musiconhold.c5
-rw-r--r--res/res_pjproject.c29
-rw-r--r--res/res_pjsip/pjsip_configuration.c6
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c56
-rw-r--r--res/res_pjsip_pubsub.c623
-rw-r--r--res/res_rtp_asterisk.c41
-rw-r--r--res/res_stasis.c23
-rw-r--r--res/stasis/app.c73
-rw-r--r--res/stasis/app.h27
-rw-r--r--res/stasis/cli.c214
-rw-r--r--res/stasis/cli.h43
-rw-r--r--res/stasis/stasis_bridge.c6
-rw-r--r--rest-api-templates/param_parsing.mustache15
-rw-r--r--rest-api-templates/res_ari_resource.c.mustache3
-rw-r--r--tests/test_ari.c22
-rw-r--r--tests/test_substitution.c9
-rw-r--r--tests/test_voicemail_api.c50
-rw-r--r--third-party/pjproject/Makefile2
-rw-r--r--third-party/pjproject/patches/0000-set_apps_initial_log_level.patch39
57 files changed, 1560 insertions, 1309 deletions
diff --git a/CHANGES b/CHANGES
index 5921e9b32..1671d3635 100644
--- a/CHANGES
+++ b/CHANGES
@@ -121,6 +121,14 @@ res_pjsip_endpoint_identifier_ip
source IP addresses for requests. This is configurable using the
"srv_lookups" option on the identify and defaults to "yes".
+ARI
+------------------
+ * The 'ari set debug' command has been enhanced to accept 'all' as an
+ application name. This allows dumping of all apps even if an app
+ hasn't registered yet.
+
+ * 'ari set debug' now displays requests and responses as well as events.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 14.1.0 to Asterisk 14.2.0 ------------
------------------------------------------------------------------------------
diff --git a/UPGRADE.txt b/UPGRADE.txt
index 6cb614807..569cc9222 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -33,6 +33,10 @@ Queue:
their ringinuse value updated to the value of the queue. Previously, the
ringinuse value for dynamic members was not updated on reload.
+Queue log:
+ - New RINGCANCELED event is logged when the caller hangs up while ringing.
+ The data1 field contains number of miliseconds since start of ringing.
+
Channel Drivers:
chan_dahdi:
diff --git a/apps/app_queue.c b/apps/app_queue.c
index 68ee6165f..da24c51d6 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -4791,6 +4791,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
#endif
char *inchan_name;
struct timeval start_time_tv = ast_tvnow();
+ int canceled_by_caller = 0; /* 1 when caller hangs up or press digit or press * */
ast_channel_lock(qe->chan);
inchan_name = ast_strdupa(ast_channel_name(qe->chan));
@@ -5229,29 +5230,33 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
/* Got hung up */
*to = -1;
- publish_dial_end_event(in, outgoing, NULL, "CANCEL");
if (f) {
if (f->data.uint32) {
ast_channel_hangupcause_set(in, f->data.uint32);
}
ast_frfree(f);
}
- return NULL;
- }
-
- if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass.integer == '*')) {
+ canceled_by_caller = 1;
+ } else if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass.integer == '*')) {
ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
*to = 0;
- publish_dial_end_event(in, outgoing, NULL, "CANCEL");
ast_frfree(f);
- return NULL;
- }
- if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass.integer)) {
+ canceled_by_caller = 1;
+ } else if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass.integer)) {
ast_verb(3, "User pressed digit: %c\n", f->subclass.integer);
*to = 0;
- publish_dial_end_event(in, outgoing, NULL, "CANCEL");
*digit = f->subclass.integer;
ast_frfree(f);
+ canceled_by_caller = 1;
+ }
+ /* When caller hung up or pressed * or digit. */
+ if (canceled_by_caller) {
+ publish_dial_end_event(in, outgoing, NULL, "CANCEL");
+ for (o = start; o; o = o->call_next) {
+ if (o->chan) {
+ ast_queue_log(qe->parent->name, ast_channel_uniqueid(qe->chan), o->member->membername, "RINGCANCELED", "%d", (int) ast_tvdiff_ms(ast_tvnow(), start_time_tv));
+ }
+ }
return NULL;
}
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 0d1e24ab7..3e1e38d37 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -725,7 +725,7 @@ static struct ast_frame *oss_read(struct ast_channel *c)
return f;
/* ok we can build and deliver the frame to the caller */
f->frametype = AST_FRAME_VOICE;
- f->subclass.format = ao2_bump(ast_format_slin);
+ f->subclass.format = ast_format_slin;
f->samples = FRAME_SIZE;
f->datalen = FRAME_SIZE * 2;
f->data.ptr = o->oss_read_buf + AST_FRIENDLY_OFFSET;
diff --git a/codecs/codec_speex.c b/codecs/codec_speex.c
index 49990e988..72ac22023 100644
--- a/codecs/codec_speex.c
+++ b/codecs/codec_speex.c
@@ -55,6 +55,9 @@
#include "asterisk/frame.h"
#include "asterisk/linkedlists.h"
+/* For struct ast_rtp_rtcp_report and struct ast_rtp_rtcp_report_block */
+#include "asterisk/rtp_engine.h"
+
/* codec variables */
static int quality = 3;
static int complexity = 2;
@@ -64,6 +67,7 @@ static int vbr = 0;
static float vbr_quality = 4;
static int abr = 0;
static int dtx = 0; /* set to 1 to enable silence detection */
+static int exp_rtcp_fb = 0; /* set to 1 to use experimental RTCP feedback for changing bitrate */
static int preproc = 0;
static int pp_vad = 0;
@@ -91,6 +95,11 @@ struct speex_coder_pvt {
SpeexBits bits;
int framesize;
int silent_state;
+
+ int fraction_lost;
+ int quality;
+ int default_quality;
+
#ifdef _SPEEX_TYPES_H
SpeexPreprocessState *pp;
spx_int16_t buf[BUFFER_SAMPLES];
@@ -137,6 +146,11 @@ static int speex_encoder_construct(struct ast_trans_pvt *pvt, const SpeexMode *p
speex_encoder_ctl(tmp->speex, SPEEX_SET_DTX, &dtx);
tmp->silent_state = 0;
+ tmp->fraction_lost = 0;
+ tmp->default_quality = vbr ? vbr_quality : quality;
+ tmp->quality = tmp->default_quality;
+ ast_debug(3, "Default quality (%s): %d\n", vbr ? "vbr" : "cbr", tmp->default_quality);
+
return 0;
}
@@ -342,6 +356,69 @@ static struct ast_frame *lintospeex_frameout(struct ast_trans_pvt *pvt)
return result;
}
+/*! \brief handle incoming RTCP feedback and possibly edit encoder settings */
+static void lintospeex_feedback(struct ast_trans_pvt *pvt, struct ast_frame *feedback)
+{
+ struct speex_coder_pvt *tmp = pvt->pvt;
+
+ struct ast_rtp_rtcp_report *rtcp_report;
+ struct ast_rtp_rtcp_report_block *report_block;
+
+ int fraction_lost;
+ int percent;
+ int bitrate;
+ int q;
+
+ if(!exp_rtcp_fb)
+ return;
+
+ rtcp_report = (struct ast_rtp_rtcp_report *)feedback->data.ptr;
+ if (rtcp_report->reception_report_count == 0)
+ return;
+ report_block = rtcp_report->report_block[0];
+ fraction_lost = report_block->lost_count.fraction;
+ if (fraction_lost == tmp->fraction_lost)
+ return;
+ /* Per RFC3550, fraction lost is defined to be the number of packets lost
+ * divided by the number of packets expected. Since it's a 8-bit value,
+ * and we want a percentage value, we multiply by 100 and divide by 256. */
+ percent = (fraction_lost*100)/256;
+ bitrate = 0;
+ q = -1;
+ ast_debug(3, "Fraction lost changed: %d --> %d percent loss\n", fraction_lost, percent);
+ /* Handle change */
+ speex_encoder_ctl(tmp->speex, SPEEX_GET_BITRATE, &bitrate);
+ ast_debug(3, "Current bitrate: %d\n", bitrate);
+ ast_debug(3, "Current quality: %d/%d\n", tmp->quality, tmp->default_quality);
+ /* FIXME BADLY Very ugly example of how this could be handled: probably sucks */
+ if (percent < 10) {
+ /* Not that bad, default quality is fine */
+ q = tmp->default_quality;
+ } else if (percent < 20) {
+ /* Quite bad, let's go down a bit */
+ q = tmp->default_quality-1;
+ } else if (percent < 30) {
+ /* Very bad, let's go down even more */
+ q = tmp->default_quality-2;
+ } else {
+ /* Really bad, use the lowest quality possible */
+ q = 0;
+ }
+ if (q < 0)
+ q = 0;
+ if (q != tmp->quality) {
+ ast_debug(3, " -- Setting to %d\n", q);
+ if (vbr) {
+ float vbr_q = q;
+ speex_encoder_ctl(tmp->speex, SPEEX_SET_VBR_QUALITY, &vbr_q);
+ } else {
+ speex_encoder_ctl(tmp->speex, SPEEX_SET_QUALITY, &q);
+ }
+ tmp->quality = q;
+ }
+ tmp->fraction_lost = fraction_lost;
+}
+
static void speextolin_destroy(struct ast_trans_pvt *arg)
{
struct speex_coder_pvt *pvt = arg->pvt;
@@ -400,6 +477,7 @@ static struct ast_translator lintospeex = {
.newpvt = lintospeex_new,
.framein = lintospeex_framein,
.frameout = lintospeex_frameout,
+ .feedback = lintospeex_feedback,
.destroy = lintospeex_destroy,
.sample = slin8_sample,
.desc_size = sizeof(struct speex_coder_pvt),
@@ -446,6 +524,7 @@ static struct ast_translator lin16tospeexwb = {
.newpvt = lin16tospeexwb_new,
.framein = lintospeex_framein,
.frameout = lintospeex_frameout,
+ .feedback = lintospeex_feedback,
.destroy = lintospeex_destroy,
.sample = slin16_sample,
.desc_size = sizeof(struct speex_coder_pvt),
@@ -491,6 +570,7 @@ static struct ast_translator lin32tospeexuwb = {
.newpvt = lin32tospeexuwb_new,
.framein = lintospeex_framein,
.frameout = lintospeex_frameout,
+ .feedback = lintospeex_feedback,
.destroy = lintospeex_destroy,
.desc_size = sizeof(struct speex_coder_pvt),
.buffer_samples = BUFFER_SAMPLES,
@@ -586,6 +666,9 @@ static int parse_config(int reload)
pp_dereverb_level = res_f;
} else
ast_log(LOG_ERROR,"Error! Preprocessor Dereverb Level must be >= 0\n");
+ } else if (!strcasecmp(var->name, "experimental_rtcp_feedback")) {
+ exp_rtcp_fb = ast_true(var->value) ? 1 : 0;
+ ast_verb(3, "CODEC SPEEX: Experimental RTCP Feedback. [%s]\n",exp_rtcp_fb ? "on" : "off");
}
}
ast_config_destroy(cfg);
diff --git a/configs/samples/codecs.conf.sample b/configs/samples/codecs.conf.sample
index 63d0352a8..e40aa35a3 100644
--- a/configs/samples/codecs.conf.sample
+++ b/configs/samples/codecs.conf.sample
@@ -57,6 +57,9 @@ pp_dereverb => false
pp_dereverb_decay => 0.4
pp_dereverb_level => 0.3
+; experimental bitrate changes depending on RTCP feedback [true / false]
+experimental_rtcp_feedback => false
+
[plc]
; for all codecs which do not support native PLC
diff --git a/funcs/func_frame_trace.c b/funcs/func_frame_trace.c
index 08c426161..8a0b3dd59 100644
--- a/funcs/func_frame_trace.c
+++ b/funcs/func_frame_trace.c
@@ -370,6 +370,9 @@ static void print_frame(struct ast_frame *frame)
}
ast_verbose("Bytes: %d\n", frame->datalen);
break;
+ case AST_FRAME_RTCP:
+ ast_verbose("FrameType: RTCP\n");
+ break;
case AST_FRAME_NULL:
ast_verbose("FrameType: NULL\n");
break;
diff --git a/funcs/func_strings.c b/funcs/func_strings.c
index 885de61c5..2d03c15e8 100644
--- a/funcs/func_strings.c
+++ b/funcs/func_strings.c
@@ -617,7 +617,6 @@ static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, ch
}
ast_str_substitute_variables(&orig_list, 0, chan, varsubst);
if (!ast_str_strlen(orig_list)) {
- ast_log(LOG_ERROR, "List variable '%s' not found\n", args.listname);
if (chan) {
ast_channel_unlock(chan);
}
diff --git a/include/asterisk/ari.h b/include/asterisk/ari.h
index 4019e94e3..865b4b00c 100644
--- a/include/asterisk/ari.h
+++ b/include/asterisk/ari.h
@@ -59,7 +59,8 @@ struct ast_ari_response;
typedef void (*stasis_rest_callback)(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response);
+ struct ast_variable *headers, struct ast_json *body,
+ struct ast_ari_response *response);
/*!
* \brief Handler for a single RESTful path segment.
@@ -136,7 +137,7 @@ int ast_ari_remove_handler(struct stasis_rest_handlers *handler);
void ast_ari_invoke(struct ast_tcptls_session_instance *ser,
const char *uri, enum ast_http_method method,
struct ast_variable *get_params, struct ast_variable *headers,
- struct ast_ari_response *response);
+ struct ast_json *body, struct ast_ari_response *response);
/*!
* \internal
@@ -201,6 +202,15 @@ const char *ast_ari_websocket_session_id(
const struct ast_ari_websocket_session *session);
/*!
+ * \brief Get the remote address from an ARI WebSocket.
+ *
+ * \param session Session to write to.
+ * \return ast_sockaddr (does not have to be freed)
+ */
+struct ast_sockaddr *ast_ari_websocket_session_get_remote_addr(
+ struct ast_ari_websocket_session *session);
+
+/*!
* \brief The stock message to return when out of memory.
*
* The refcount is NOT bumped on this object, so ast_json_ref() if you want to
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 108dcafe0..90f8aa086 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -127,6 +127,8 @@ enum ast_frame_type {
* directly into bridges.
*/
AST_FRAME_BRIDGE_ACTION_SYNC,
+ /*! RTCP feedback */
+ AST_FRAME_RTCP,
};
#define AST_FRAME_DTMF AST_FRAME_DTMF_END
diff --git a/include/asterisk/mod_format.h b/include/asterisk/mod_format.h
index bcd31deaa..7e05a282b 100644
--- a/include/asterisk/mod_format.h
+++ b/include/asterisk/mod_format.h
@@ -114,7 +114,11 @@ struct ast_filestream {
int lasttimeout;
struct ast_channel *owner;
FILE *f;
- struct ast_frame fr; /*!< frame produced by read, typically */
+ /*!
+ * \brief frame produced by read, typically
+ * \note This frame holds a fr.subclass.format ref.
+ */
+ struct ast_frame fr;
char *buf; /*!< buffer pointed to by ast_frame; */
void *_private; /*!< pointer to private buffer */
const char *orig_chan_name;
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index ff35c16c4..05ad6c560 100644
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -143,6 +143,33 @@ enum ast_option_flags {
*/
#define DEFAULT_PJ_LOG_MAX_LEVEL 2
+/*!
+ * \brief Get maximum log level pjproject was compiled with.
+ *
+ * \details
+ * Determine the maximum log level the pjproject we are running
+ * with supports.
+ *
+ * When pjproject is initially loaded the default log level in
+ * effect is the maximum log level the library was compiled to
+ * generate. We must save this value off somewhere before we
+ * change it to what we want to use as the default level.
+ *
+ * \note This must be done before calling pj_init() so the level
+ * we want to use as the default level is in effect while the
+ * library initializes.
+ */
+#define AST_PJPROJECT_INIT_LOG_LEVEL() \
+ do { \
+ if (ast_pjproject_max_log_level < 0) { \
+ ast_pjproject_max_log_level = pj_log_get_level(); \
+ } \
+ pj_log_set_level(ast_option_pjproject_log_level); \
+ } while (0)
+
+/*! Current linked pjproject maximum logging level */
+extern int ast_pjproject_max_log_level;
+
/*! Current pjproject logging level */
extern int ast_option_pjproject_log_level;
diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index 137cbb945..e131833a9 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -903,6 +903,56 @@ int stasis_app_control_dial(struct stasis_app_control *control,
* allocated during the time that res_stasis was loaded.
*/
void stasis_app_control_shutdown(void);
+
+/*!
+ * \brief Enable/disable request/response and event logging on an application
+ *
+ * \param app The app to debug
+ * \param debug If non-zero, enable debugging. If zero, disable.
+ */
+void stasis_app_set_debug(struct stasis_app *app, int debug);
+
+/*!
+ * \brief Enable/disable request/response and event logging on an application
+ *
+ * \param app_name The app name to debug
+ * \param debug If non-zero, enable debugging. If zero, disable.
+ */
+void stasis_app_set_debug_by_name(const char *app_name, int debug);
+
+/*!
+ * \brief Get debug status of an application
+ *
+ * \param app The app to check
+ * \return The debug flag for the app || the global debug flag
+ */
+int stasis_app_get_debug(struct stasis_app *app);
+
+/*!
+ * \brief Get debug status of an application
+ *
+ * \param app_name The app_name to check
+ * \return The debug flag for the app || the global debug flag
+ */
+int stasis_app_get_debug_by_name(const char *app_name);
+
+/*!
+ * \brief Enable/disable request/response and event logging on all applications
+ *
+ * \param debug If non-zero, enable debugging. If zero, disable.
+ */
+void stasis_app_set_global_debug(int debug);
+
+struct ast_cli_args;
+
+/*!
+ * \brief Dump properties of a \c stasis_app to the CLI
+ *
+ * \param app The application
+ * \param a The CLI arguments
+ */
+void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a);
+
/*! @} */
#endif /* _ASTERISK_STASIS_APP_H */
diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h
index 8188eb8eb..a52e13347 100644
--- a/include/asterisk/translate.h
+++ b/include/asterisk/translate.h
@@ -121,7 +121,7 @@ enum ast_trans_cost_table {
*
* As a minimum, a translator should supply name, srcfmt and dstfmt,
* the required buf_size (in bytes) and buffer_samples (in samples),
- * and a few callbacks (framein, frameout, sample).
+ * and a few callbacks (framein, frameout, feedback, sample).
* The outbuf is automatically prepended by AST_FRIENDLY_OFFSET
* spare bytes so generic routines can place data in there.
*
@@ -159,6 +159,10 @@ struct ast_translator {
/*!< Output frame callback. Generate a frame
* with outbuf content. */
+ void (*feedback)(struct ast_trans_pvt *pvt, struct ast_frame *feedback);
+ /*!< Feedback frame callback. Handle
+ * input frame. */
+
void (*destroy)(struct ast_trans_pvt *pvt);
/*!< cleanup private data, if needed
* (often unnecessary). */
@@ -208,7 +212,7 @@ struct ast_translator {
*/
struct ast_trans_pvt {
struct ast_translator *t;
- struct ast_frame f; /*!< used in frameout */
+ struct ast_frame f; /*!< used in frameout. This frame holds a f.subclass.format ref. */
int samples; /*!< samples available in outbuf */
/*! \brief actual space used in outbuf */
int datalen;
@@ -316,7 +320,9 @@ void ast_translator_free_path(struct ast_trans_pvt *tr);
/*!
* \brief translates one or more frames
* Apply an input frame into the translator and receive zero or one output frames. Consume
- * determines whether the original frame should be freed
+ * determines whether the original frame should be freed. In case the frame type is
+ * AST_FRAME_RTCP, the frame is not translated but passed to the translator codecs
+ * via the feedback callback, and a pointer to ast_null_frame is returned after that.
* \param path tr translator structure to use for translation
* \param f frame to translate
* \param consume Whether or not to free the original frame
diff --git a/main/app.c b/main/app.c
index f2e3a0fe0..1eb0741ee 100644
--- a/main/app.c
+++ b/main/app.c
@@ -1422,22 +1422,20 @@ static struct ast_frame *make_silence(const struct ast_frame *orig)
size_t size;
size_t datalen;
size_t samples = 0;
- struct ast_frame *next;
if (!orig) {
return NULL;
}
+ do {
+ if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
+ ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
+ return NULL;
+ }
- if (ast_format_cmp(orig->subclass.format, ast_format_slin) == AST_FORMAT_CMP_NOT_EQUAL) {
- ast_log(LOG_WARNING, "Attempting to silence non-slin frame\n");
- return NULL;
- }
-
- for (next = AST_LIST_NEXT(orig, frame_list);
- orig;
- orig = next, next = orig ? AST_LIST_NEXT(orig, frame_list) : NULL) {
samples += orig->samples;
- }
+
+ orig = AST_LIST_NEXT(orig, frame_list);
+ } while (orig);
ast_verb(4, "Silencing %zu samples\n", samples);
@@ -1455,7 +1453,7 @@ static struct ast_frame *make_silence(const struct ast_frame *orig)
silence->samples = samples;
silence->datalen = datalen;
- silence->subclass.format = ast_format_slin;
+ silence->subclass.format = ao2_bump(ast_format_slin);
return silence;
}
@@ -1661,14 +1659,13 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
/* It's all good */
res = 0;
} else {
- RAII_VAR(struct ast_frame *, silence, NULL, ast_frame_dtor);
+ struct ast_frame *silence = NULL;
struct ast_frame *orig = f;
if (muted) {
silence = make_silence(orig);
if (!silence) {
- ast_log(LOG_WARNING,
- "Error creating silence\n");
+ ast_log(LOG_WARNING, "Error creating silence\n");
break;
}
f = silence;
@@ -1679,6 +1676,7 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
}
res = ast_writestream(others[x], f);
}
+ ast_frame_dtor(silence);
f = orig;
}
diff --git a/main/asterisk.c b/main/asterisk.c
index 338c1f53b..69183c1f3 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -330,6 +330,7 @@ int ast_verb_sys_level;
int option_verbose; /*!< Verbosity level */
int option_debug; /*!< Debug level */
+int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */
int ast_option_pjproject_log_level;
double ast_option_maxload; /*!< Max load avg on system */
int ast_option_maxcalls; /*!< Max number of active calls */
diff --git a/main/astobj2.c b/main/astobj2.c
index c8e48bbf5..1529e91b0 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -524,6 +524,20 @@ int __ao2_ref(void *user_data, int delta,
if (0 < current_value) {
/* The object still lives. */
+#define EXCESSIVE_REF_COUNT 100000
+
+ if (EXCESSIVE_REF_COUNT <= current_value && ret < EXCESSIVE_REF_COUNT) {
+ char excessive_ref_buf[100];
+
+ /* We just reached or went over the excessive ref count trigger */
+ snprintf(excessive_ref_buf, sizeof(excessive_ref_buf),
+ "Excessive refcount %d reached on ao2 object %p",
+ current_value, user_data);
+ ast_log(__LOG_ERROR, file, line, func, "%s\n", excessive_ref_buf);
+
+ __ast_assert_failed(0, excessive_ref_buf, file, line, func);
+ }
+
if (ref_log && tag) {
fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data,
(delta < 0 ? "" : "+"), delta, ast_get_tid(),
diff --git a/main/channel.c b/main/channel.c
index 4f8471743..6e88a2906 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1531,6 +1531,7 @@ int ast_is_deferrable_frame(const struct ast_frame *frame)
case AST_FRAME_IAX:
case AST_FRAME_CNG:
case AST_FRAME_MODEM:
+ case AST_FRAME_RTCP:
return 0;
}
return 0;
@@ -2866,6 +2867,7 @@ int __ast_answer(struct ast_channel *chan, unsigned int delay)
case AST_FRAME_IMAGE:
case AST_FRAME_HTML:
case AST_FRAME_MODEM:
+ case AST_FRAME_RTCP:
done = 1;
break;
case AST_FRAME_CONTROL:
@@ -4355,6 +4357,14 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
*/
ast_read_generator_actions(chan, f);
break;
+ case AST_FRAME_RTCP:
+ /* Incoming RTCP feedback needs to get to the translator for
+ * outgoing media, which means we treat it as an ast_write */
+ if (ast_channel_writetrans(chan)) {
+ ast_translate(ast_channel_writetrans(chan), f, 0);
+ }
+ ast_frfree(f);
+ f = &ast_null_frame;
default:
/* Just pass it on! */
break;
@@ -4887,16 +4897,18 @@ int ast_sendtext(struct ast_channel *chan, const char *text)
if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) {
struct ast_frame f;
+ memset(&f, 0, sizeof(f));
f.frametype = AST_FRAME_TEXT;
f.src = "DIALPLAN";
f.mallocd = AST_MALLOCD_DATA;
f.datalen = strlen(text);
f.data.ptr = ast_strdup(text);
- f.offset = 0;
- f.seqno = 0;
-
f.subclass.format = ast_format_t140;
- res = ast_channel_tech(chan)->write_text(chan, &f);
+
+ if (f.data.ptr) {
+ res = ast_channel_tech(chan)->write_text(chan, &f);
+ ast_frfree(&f);
+ }
} else if (ast_channel_tech(chan)->send_text) {
res = ast_channel_tech(chan)->send_text(chan, text);
}
diff --git a/main/format_compatibility.c b/main/format_compatibility.c
index 84514ac8c..256d3a53c 100644
--- a/main/format_compatibility.c
+++ b/main/format_compatibility.c
@@ -262,10 +262,10 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield)
/*! T.140 RED Text format RFC 4103 */
case AST_FORMAT_T140_RED:
- return ast_format_t140;
+ return ast_format_t140_red;
/*! T.140 Text format - ITU T.140, RFC 4103 */
case AST_FORMAT_T140:
- return ast_format_t140_red;
+ return ast_format_t140;
}
return NULL;
}
diff --git a/main/frame.c b/main/frame.c
index 0175c7226..c284a8e1c 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -82,9 +82,9 @@ static struct ast_frame *ast_frame_header_new(void)
if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
size_t mallocd_len = f->mallocd_hdr_len;
+
memset(f, 0, sizeof(*f));
f->mallocd_hdr_len = mallocd_len;
- f->mallocd = AST_MALLOCD_HDR;
frames->size--;
return f;
}
@@ -139,12 +139,12 @@ static void __frame_free(struct ast_frame *fr, int cache)
#endif
if (fr->mallocd & AST_MALLOCD_DATA) {
- if (fr->data.ptr)
+ if (fr->data.ptr) {
ast_free(fr->data.ptr - fr->offset);
+ }
}
if (fr->mallocd & AST_MALLOCD_SRC) {
- if (fr->src)
- ast_free((void *) fr->src);
+ ast_free((void *) fr->src);
}
if (fr->mallocd & AST_MALLOCD_HDR) {
if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
@@ -206,14 +206,14 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
return NULL;
}
out->frametype = fr->frametype;
+ out->subclass = fr->subclass;
if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
(fr->frametype == AST_FRAME_IMAGE)) {
- out->subclass.format = ao2_bump(fr->subclass.format);
- } else {
- memcpy(&out->subclass, &fr->subclass, sizeof(out->subclass));
+ ao2_bump(out->subclass.format);
}
out->datalen = fr->datalen;
out->samples = fr->samples;
+ out->mallocd = AST_MALLOCD_HDR;
out->offset = fr->offset;
/* Copy the timing data */
ast_copy_flags(out, fr, AST_FLAGS_ALL);
@@ -226,47 +226,64 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
out = fr;
}
- if (!(fr->mallocd & AST_MALLOCD_SRC) && fr->src) {
- if (!(out->src = ast_strdup(fr->src))) {
- if (out != fr) {
- ast_free(out);
+ if (fr->src) {
+ /* The original frame has a source string */
+ if (!(fr->mallocd & AST_MALLOCD_SRC)) {
+ /*
+ * The original frame has a non-malloced source string.
+ *
+ * Duplicate the string and put it into the isolated frame
+ * which may also be the original frame.
+ */
+ newdata = ast_strdup(fr->src);
+ if (!newdata) {
+ if (out != fr) {
+ ast_frame_free(out, 0);
+ }
+ return NULL;
}
- return NULL;
+ out->src = newdata;
+ out->mallocd |= AST_MALLOCD_SRC;
+ } else if (out != fr) {
+ /* Steal the source string from the original frame. */
+ out->src = fr->src;
+ fr->src = NULL;
+ fr->mallocd &= ~AST_MALLOCD_SRC;
+ out->mallocd |= AST_MALLOCD_SRC;
}
- } else {
- out->src = fr->src;
- fr->src = NULL;
- fr->mallocd &= ~AST_MALLOCD_SRC;
}
if (!(fr->mallocd & AST_MALLOCD_DATA)) {
+ /* The original frame has a non-malloced data buffer. */
if (!fr->datalen) {
+ /* Actually it's just an int so we can simply copy it. */
out->data.uint32 = fr->data.uint32;
- out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC;
return out;
}
- if (!(newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET))) {
- if (out->src != fr->src) {
- ast_free((void *) out->src);
- }
+ /*
+ * Duplicate the data buffer and put it into the isolated frame
+ * which may also be the original frame.
+ */
+ newdata = ast_malloc(fr->datalen + AST_FRIENDLY_OFFSET);
+ if (!newdata) {
if (out != fr) {
- ast_free(out);
+ ast_frame_free(out, 0);
}
return NULL;
}
newdata += AST_FRIENDLY_OFFSET;
out->offset = AST_FRIENDLY_OFFSET;
- out->datalen = fr->datalen;
memcpy(newdata, fr->data.ptr, fr->datalen);
out->data.ptr = newdata;
- } else {
+ out->mallocd |= AST_MALLOCD_DATA;
+ } else if (out != fr) {
+ /* Steal the data buffer from the original frame. */
out->data = fr->data;
memset(&fr->data, 0, sizeof(fr->data));
fr->mallocd &= ~AST_MALLOCD_DATA;
+ out->mallocd |= AST_MALLOCD_DATA;
}
- out->mallocd = AST_MALLOCD_HDR | AST_MALLOCD_SRC | AST_MALLOCD_DATA;
-
return out;
}
@@ -533,6 +550,8 @@ void ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, ch
break;
}
break;
+ case AST_FRAME_RTCP:
+ ast_copy_string(subclass, "RTCP", slen);
default:
ast_copy_string(subclass, "Unknown Subclass", slen);
break;
@@ -584,6 +603,9 @@ void ast_frame_type2str(enum ast_frame_type frame_type, char *ftype, size_t len)
case AST_FRAME_VIDEO:
ast_copy_string(ftype, "Video", len);
break;
+ case AST_FRAME_RTCP:
+ ast_copy_string(ftype, "RTCP", len);
+ break;
default:
snprintf(ftype, len, "Unknown Frametype '%u'", frame_type);
break;
@@ -621,6 +643,9 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
if (f->frametype == AST_FRAME_VIDEO) {
return;
}
+ if (f->frametype == AST_FRAME_RTCP) {
+ return;
+ }
ast_frame_type2str(f->frametype, ftype, sizeof(ftype));
ast_frame_subclass2str(f, subclass, sizeof(subclass), moreinfo, sizeof(moreinfo));
diff --git a/main/libasteriskpj.c b/main/libasteriskpj.c
index 0f893a2cf..40efa9276 100644
--- a/main/libasteriskpj.c
+++ b/main/libasteriskpj.c
@@ -45,7 +45,7 @@
int ast_pj_init(void)
{
#ifdef HAVE_PJPROJECT_BUNDLED
- pj_log_set_level(ast_option_pjproject_log_level);
+ AST_PJPROJECT_INIT_LOG_LEVEL();
pj_init();
#endif
return 0;
diff --git a/main/strings.c b/main/strings.c
index b8f1ccbfd..d29da67bc 100644
--- a/main/strings.c
+++ b/main/strings.c
@@ -184,15 +184,32 @@ static int str_hash(const void *obj, const int flags)
return ast_str_hash(obj);
}
+static int str_sort(const void *lhs, const void *rhs, int flags)
+{
+ if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) {
+ return strncmp(lhs, rhs, strlen(rhs));
+ } else {
+ return strcmp(lhs, rhs);
+ }
+}
+
static int str_cmp(void *lhs, void *rhs, int flags)
{
- return strcmp(lhs, rhs) ? 0 : CMP_MATCH;
+ int cmp = 0;
+
+ if ((flags & OBJ_SEARCH_MASK) == OBJ_SEARCH_PARTIAL_KEY) {
+ cmp = strncmp(lhs, rhs, strlen(rhs));
+ } else {
+ cmp = strcmp(lhs, rhs);
+ }
+
+ return cmp ? 0 : CMP_MATCH;
}
//struct ao2_container *ast_str_container_alloc_options(enum ao2_container_opts opts, int buckets)
struct ao2_container *ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
{
- return ao2_container_alloc_options(opts, buckets, str_hash, str_cmp);
+ return ao2_container_alloc_hash(opts, 0, buckets, str_hash, str_sort, str_cmp);
}
int ast_str_container_add(struct ao2_container *str_container, const char *add)
diff --git a/main/translate.c b/main/translate.c
index fa606e71b..168a72a4b 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -530,6 +530,17 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
long len;
int seqno;
+ if (f->frametype == AST_FRAME_RTCP) {
+ /* Just pass the feedback to the right callback, if it exists.
+ * This "translation" does nothing so return a null frame. */
+ struct ast_trans_pvt *tp;
+ for (tp = p; tp; tp = tp->next) {
+ if (tp->t->feedback)
+ tp->t->feedback(tp, f);
+ }
+ return &ast_null_frame;
+ }
+
has_timing_info = ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO);
ts = f->ts;
len = f->len;
diff --git a/res/ari/ari_websockets.c b/res/ari/ari_websockets.c
index f1e63d398..4f8d6dffd 100644
--- a/res/ari/ari_websockets.c
+++ b/res/ari/ari_websockets.c
@@ -21,6 +21,7 @@
#include "asterisk/ari.h"
#include "asterisk/astobj2.h"
#include "asterisk/http_websocket.h"
+#include "asterisk/stasis_app.h"
#include "internal.h"
/*! \file
@@ -137,6 +138,7 @@ struct ast_json *ast_ari_websocket_session_read(
ast_log(LOG_WARNING,
"WebSocket input failed to parse\n");
}
+
break;
default:
/* Ignore all other message types */
@@ -172,16 +174,20 @@ int ast_ari_websocket_session_write(struct ast_ari_websocket_session *session,
return -1;
}
-#ifdef AST_DEVMODE
- ast_debug(3, "Examining ARI event (length %u): \n%s\n", (unsigned int) strlen(str), str);
-#endif
if (ast_websocket_write_string(session->ws_session, str)) {
- ast_log(LOG_NOTICE, "Problem occurred during websocket write, websocket closed\n");
+ ast_log(LOG_NOTICE, "Problem occurred during websocket write to %s, websocket closed\n",
+ ast_sockaddr_stringify(ast_ari_websocket_session_get_remote_addr(session)));
return -1;
}
return 0;
}
+struct ast_sockaddr *ast_ari_websocket_session_get_remote_addr(
+ struct ast_ari_websocket_session *session)
+{
+ return ast_websocket_remote_address(session->ws_session);
+}
+
void ari_handle_websocket(struct ast_websocket_server *ws_server,
struct ast_tcptls_session_instance *ser, const char *uri,
enum ast_http_method method, struct ast_variable *get_params,
diff --git a/res/ari/cli.c b/res/ari/cli.c
index 9d156f21e..9d0eb3099 100644
--- a/res/ari/cli.c
+++ b/res/ari/cli.c
@@ -26,6 +26,7 @@
#include "asterisk/astobj2.h"
#include "asterisk/cli.h"
+#include "asterisk/stasis_app.h"
#include "internal.h"
static char *ari_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -249,11 +250,185 @@ static char *ari_mkpasswd(struct ast_cli_entry *e, int cmd, struct ast_cli_args
return CLI_SUCCESS;
}
+static char *ari_show_apps(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ struct ao2_container *apps;
+ struct ao2_iterator it_apps;
+ char *app;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "ari show apps";
+ e->usage =
+ "Usage: ari show apps\n"
+ " Lists all registered applications.\n"
+ ;
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ default:
+ break;
+ }
+
+ if (a->argc != 3) {
+ return CLI_SHOWUSAGE;
+ }
+
+ apps = stasis_app_get_all();
+ if (!apps) {
+ ast_cli(a->fd, "Unable to retrieve registered applications!\n");
+ return CLI_FAILURE;
+ }
+
+ ast_cli(a->fd, "Application Name \n");
+ ast_cli(a->fd, "=========================\n");
+ it_apps = ao2_iterator_init(apps, 0);
+ while ((app = ao2_iterator_next(&it_apps))) {
+ ast_cli(a->fd, "%-25.25s\n", app);
+ ao2_ref(app, -1);
+ }
+
+ ao2_iterator_destroy(&it_apps);
+ ao2_ref(apps, -1);
+
+ return CLI_SUCCESS;
+}
+
+struct app_complete {
+ /*! Nth app to search for */
+ int state;
+ /*! Which app currently on */
+ int which;
+};
+
+static int complete_ari_app_search(void *obj, void *arg, void *data, int flags)
+{
+ struct app_complete *search = data;
+
+ if (++search->which > search->state) {
+ return CMP_MATCH;
+ }
+ return 0;
+}
+
+static char *complete_ari_app(struct ast_cli_args *a, int include_all)
+{
+ RAII_VAR(struct ao2_container *, apps, stasis_app_get_all(), ao2_cleanup);
+ RAII_VAR(char *, app, NULL, ao2_cleanup);
+
+ struct app_complete search = {
+ .state = a->n,
+ };
+
+ if (a->pos != 3) {
+ return NULL;
+ }
+
+ if (!apps) {
+ ast_cli(a->fd, "Error getting ARI applications\n");
+ return CLI_FAILURE;
+ }
+
+ if (include_all && ast_strlen_zero(a->word)) {
+ ast_str_container_add(apps, " all");
+ }
+
+ app = ao2_callback_data(apps,
+ ast_strlen_zero(a->word) ? 0 : OBJ_SEARCH_PARTIAL_KEY,
+ complete_ari_app_search, (char*)a->word, &search);
+
+ return app ? ast_strdup(app) : NULL;
+}
+
+static char *ari_show_app(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ void *app;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "ari show app";
+ e->usage =
+ "Usage: ari show app <application>\n"
+ " Provide detailed information about a registered application.\n"
+ ;
+ return NULL;
+ case CLI_GENERATE:
+ return complete_ari_app(a, 0);
+ default:
+ break;
+ }
+
+ if (a->argc != 4) {
+ return CLI_SHOWUSAGE;
+ }
+
+ app = stasis_app_get_by_name(a->argv[3]);
+ if (!app) {
+ return CLI_FAILURE;
+ }
+
+ stasis_app_to_cli(app, a);
+
+ ao2_ref(app, -1);
+
+ return CLI_SUCCESS;
+}
+
+static char *ari_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ void *app;
+ int debug;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "ari set debug";
+ e->usage =
+ "Usage: ari set debug <application|all> <on|off>\n"
+ " Enable or disable debugging on a specific application.\n"
+ ;
+ return NULL;
+ case CLI_GENERATE:
+ return complete_ari_app(a, 1);
+ default:
+ break;
+ }
+
+ if (a->argc != 5) {
+ return CLI_SHOWUSAGE;
+ }
+
+ debug = !strcmp(a->argv[4], "on");
+
+ if (!strcmp(a->argv[3], "all")) {
+ stasis_app_set_global_debug(debug);
+ ast_cli(a->fd, "Debugging on all applications %s\n",
+ debug ? "enabled" : "disabled");
+ return CLI_SUCCESS;
+ }
+
+ app = stasis_app_get_by_name(a->argv[3]);
+ if (!app) {
+ return CLI_FAILURE;
+ }
+
+ stasis_app_set_debug(app, debug);
+ ast_cli(a->fd, "Debugging on '%s' %s\n",
+ stasis_app_name(app),
+ debug ? "enabled" : "disabled");
+
+ ao2_ref(app, -1);
+
+ return CLI_SUCCESS;
+}
+
static struct ast_cli_entry cli_ari[] = {
AST_CLI_DEFINE(ari_show, "Show ARI settings"),
AST_CLI_DEFINE(ari_show_users, "List ARI users"),
AST_CLI_DEFINE(ari_show_user, "List single ARI user"),
AST_CLI_DEFINE(ari_mkpasswd, "Encrypts a password"),
+ AST_CLI_DEFINE(ari_show_apps, "List registered ARI applications"),
+ AST_CLI_DEFINE(ari_show_app, "Display details of a registered ARI application"),
+ AST_CLI_DEFINE(ari_set_debug, "Enable/disable debugging of an ARI application"),
};
int ast_ari_cli_register(void) {
diff --git a/res/ari/resource_events.c b/res/ari/resource_events.c
index 597f4dfeb..ed936f732 100644
--- a/res/ari/resource_events.c
+++ b/res/ari/resource_events.c
@@ -27,6 +27,7 @@
#include "resource_events.h"
#include "asterisk/astobj2.h"
+#include "asterisk/http_websocket.h"
#include "asterisk/stasis_app.h"
#include "asterisk/vector.h"
@@ -108,6 +109,15 @@ static void stasis_app_message_handler(
msg_type,
msg_application);
} else {
+ if (stasis_app_get_debug_by_name(app_name)) {
+ char *str = ast_json_dump_string_format(message, ast_ari_json_format());
+
+ ast_verbose("<--- Sending ARI event to %s --->\n%s\n",
+ ast_sockaddr_stringify(ast_ari_websocket_session_get_remote_addr(session->ws_session)),
+ str);
+ ast_json_free(str);
+ }
+
/* We are ready to publish the message */
ast_ari_websocket_session_write(session->ws_session, message);
}
diff --git a/res/res_ari.c b/res/res_ari.c
index e362a5811..549d78353 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -148,6 +148,7 @@
#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/paths.h"
+#include "asterisk/stasis_app.h"
#include <string.h>
#include <sys/stat.h>
@@ -491,7 +492,7 @@ static void handle_options(struct stasis_rest_handlers *handler,
void ast_ari_invoke(struct ast_tcptls_session_instance *ser,
const char *uri, enum ast_http_method method,
struct ast_variable *get_params, struct ast_variable *headers,
- struct ast_ari_response *response)
+ struct ast_json *body, struct ast_ari_response *response)
{
RAII_VAR(struct stasis_rest_handlers *, root, NULL, ao2_cleanup);
struct stasis_rest_handlers *handler;
@@ -506,8 +507,10 @@ void ast_ari_invoke(struct ast_tcptls_session_instance *ser,
while ((path_segment = strsep(&path, "/")) && (strlen(path_segment) > 0)) {
struct stasis_rest_handlers *found_handler = NULL;
int i;
+
ast_uri_decode(path_segment, ast_uri_http_legacy);
ast_debug(3, "Finding handler for %s\n", path_segment);
+
for (i = 0; found_handler == NULL && i < handler->num_children; ++i) {
struct stasis_rest_handlers *child = handler->children[i];
@@ -569,7 +572,7 @@ void ast_ari_invoke(struct ast_tcptls_session_instance *ser,
return;
}
- callback(ser, get_params, path_vars, headers, response);
+ callback(ser, get_params, path_vars, headers, body, response);
if (response->message == NULL && response->response_code == 0) {
/* Really should not happen */
ast_log(LOG_ERROR, "ARI %s %s not implemented\n",
@@ -879,6 +882,10 @@ static int ast_ari_callback(struct ast_tcptls_session_instance *ser,
RAII_VAR(struct ast_ari_conf_user *, user, NULL, ao2_cleanup);
struct ast_ari_response response = { .fd = -1, 0 };
RAII_VAR(struct ast_variable *, post_vars, NULL, ast_variables_destroy);
+ struct ast_variable *var;
+ const char *app_name = NULL;
+ RAII_VAR(struct ast_json *, body, ast_json_null(), ast_json_free);
+ int debug_app = 0;
if (!response_body) {
ast_http_request_close_on_completion(ser);
@@ -926,6 +933,25 @@ static int ast_ari_callback(struct ast_tcptls_session_instance *ser,
"Bad Request", "Error parsing request body");
goto request_failed;
}
+
+ /* Look for a JSON request entity only if there were no post_vars.
+ * If there were post_vars, then the request body would already have
+ * been consumed and can not be read again.
+ */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(&response, 413, "Request Entity Too Large", "Request body too large");
+ goto request_failed;
+ case ENOMEM:
+ ast_ari_response_error(&response, 500, "Internal Server Error", "Error processing request");
+ goto request_failed;
+ case EIO:
+ ast_ari_response_error(&response, 400, "Bad Request", "Error parsing request body");
+ goto request_failed;
+ }
+ }
}
if (get_params == NULL) {
get_params = post_vars;
@@ -942,6 +968,41 @@ static int ast_ari_callback(struct ast_tcptls_session_instance *ser,
get_params = post_vars;
}
+ /* At this point, get_params will contain post_vars (if any) */
+ app_name = ast_variable_find_in_list(get_params, "app");
+ if (!app_name) {
+ struct ast_json *app = ast_json_object_get(body, "app");
+
+ app_name = (app ? ast_json_string_get(app) : NULL);
+ }
+
+ /* stasis_app_get_debug_by_name returns an "||" of the app's debug flag
+ * and the global debug flag.
+ */
+ debug_app = stasis_app_get_debug_by_name(app_name);
+ if (debug_app) {
+ struct ast_str *buf = ast_str_create(512);
+ char *str = ast_json_dump_string_format(body, ast_ari_json_format());
+
+ if (!buf) {
+ ast_http_request_close_on_completion(ser);
+ ast_http_error(ser, 500, "Server Error", "Out of memory");
+ goto request_failed;
+ }
+
+ ast_str_append(&buf, 0, "<--- ARI request received from: %s --->\n",
+ ast_sockaddr_stringify(&ser->remote_address));
+ for (var = headers; var; var = var->next) {
+ ast_str_append(&buf, 0, "%s: %s\n", var->name, var->value);
+ }
+ for (var = get_params; var; var = var->next) {
+ ast_str_append(&buf, 0, "%s: %s\n", var->name, var->value);
+ }
+ ast_verbose("%sbody:\n%s\n\n", ast_str_buffer(buf), str);
+ ast_json_free(str);
+ ast_free(buf);
+ }
+
user = authenticate_user(get_params, headers);
if (response.response_code > 0) {
/* POST parameter processing error. Do nothing. */
@@ -980,7 +1041,7 @@ static int ast_ari_callback(struct ast_tcptls_session_instance *ser,
}
} else {
/* Other RESTful resources */
- ast_ari_invoke(ser, uri, method, get_params, headers,
+ ast_ari_invoke(ser, uri, method, get_params, headers, body,
&response);
}
@@ -992,6 +1053,7 @@ static int ast_ari_callback(struct ast_tcptls_session_instance *ser,
}
request_failed:
+
/* If you explicitly want to have no content, set message to
* ast_json_null().
*/
@@ -1014,8 +1076,13 @@ request_failed:
}
}
- ast_debug(3, "Examining ARI response:\n%d %s\n%s\n%s\n", response.response_code,
- response.response_text, ast_str_buffer(response.headers), ast_str_buffer(response_body));
+ if (debug_app) {
+ ast_verbose("<--- Sending ARI response to %s --->\n%d %s\n%s%s\n\n",
+ ast_sockaddr_stringify(&ser->remote_address), response.response_code,
+ response.response_text, ast_str_buffer(response.headers),
+ ast_str_buffer(response_body));
+ }
+
ast_http_send(ser, method, response.response_code,
response.response_text, response.headers, response_body,
response.fd != -1 ? response.fd : 0, 0);
diff --git a/res/res_ari_applications.c b/res/res_ari_applications.c
index 006d30ca8..951ee85b7 100644
--- a/res/res_ari_applications.c
+++ b/res/res_ari_applications.c
@@ -60,10 +60,9 @@
static void ast_ari_applications_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_applications_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -111,11 +110,10 @@ fin: __attribute__((unused))
static void ast_ari_applications_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_applications_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -208,11 +206,10 @@ int ast_ari_applications_subscribe_parse_body(
static void ast_ari_applications_subscribe_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_applications_subscribe_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -270,21 +267,6 @@ static void ast_ari_applications_subscribe_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_applications_subscribe_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -374,11 +356,10 @@ int ast_ari_applications_unsubscribe_parse_body(
static void ast_ari_applications_unsubscribe_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_applications_unsubscribe_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -436,21 +417,6 @@ static void ast_ari_applications_unsubscribe_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_applications_unsubscribe_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c
index 5dbf3415c..1dbd850bb 100644
--- a/res/res_ari_asterisk.c
+++ b/res/res_ari_asterisk.c
@@ -60,11 +60,10 @@
static void ast_ari_asterisk_get_object_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_object_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -133,11 +132,10 @@ int ast_ari_asterisk_update_object_parse_body(
static void ast_ari_asterisk_update_object_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_update_object_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -155,21 +153,6 @@ static void ast_ari_asterisk_update_object_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.fields = body;
ast_ari_asterisk_update_object(headers, &args, response);
#if defined(AST_DEVMODE)
@@ -216,11 +199,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_delete_object_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_delete_object_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -320,11 +302,10 @@ int ast_ari_asterisk_get_info_parse_body(
static void ast_ari_asterisk_get_info_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_info_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -376,21 +357,6 @@ static void ast_ari_asterisk_get_info_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_asterisk_get_info_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -439,10 +405,9 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_list_modules_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_list_modules_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -490,11 +455,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_get_module_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_module_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -550,11 +514,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_load_module_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_load_module_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -609,11 +572,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_unload_module_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_unload_module_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -669,11 +631,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_reload_module_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_reload_module_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -729,10 +690,9 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_list_log_channels_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_list_log_channels_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -793,11 +753,10 @@ int ast_ari_asterisk_add_log_parse_body(
static void ast_ari_asterisk_add_log_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_add_log_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -815,21 +774,6 @@ static void ast_ari_asterisk_add_log_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_asterisk_add_log_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -878,11 +822,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_delete_log_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_delete_log_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -937,11 +880,10 @@ fin: __attribute__((unused))
static void ast_ari_asterisk_rotate_log_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_rotate_log_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1009,11 +951,10 @@ int ast_ari_asterisk_get_global_var_parse_body(
static void ast_ari_asterisk_get_global_var_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_get_global_var_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1025,21 +966,6 @@ static void ast_ari_asterisk_get_global_var_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_asterisk_get_global_var_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1104,11 +1030,10 @@ int ast_ari_asterisk_set_global_var_parse_body(
static void ast_ari_asterisk_set_global_var_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_asterisk_set_global_var_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1123,21 +1048,6 @@ static void ast_ari_asterisk_set_global_var_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_asterisk_set_global_var_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
diff --git a/res/res_ari_bridges.c b/res/res_ari_bridges.c
index 0b370c299..e61865e31 100644
--- a/res/res_ari_bridges.c
+++ b/res/res_ari_bridges.c
@@ -60,10 +60,9 @@
static void ast_ari_bridges_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -132,11 +131,10 @@ int ast_ari_bridges_create_parse_body(
static void ast_ari_bridges_create_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_create_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -154,21 +152,6 @@ static void ast_ari_bridges_create_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_create_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -232,11 +215,10 @@ int ast_ari_bridges_create_with_id_parse_body(
static void ast_ari_bridges_create_with_id_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_create_with_id_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -257,21 +239,6 @@ static void ast_ari_bridges_create_with_id_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_create_with_id_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -318,11 +285,10 @@ fin: __attribute__((unused))
static void ast_ari_bridges_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -377,11 +343,10 @@ fin: __attribute__((unused))
static void ast_ari_bridges_destroy_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_destroy_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -478,11 +443,10 @@ int ast_ari_bridges_add_channel_parse_body(
static void ast_ari_bridges_add_channel_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_add_channel_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -543,21 +507,6 @@ static void ast_ari_bridges_add_channel_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_add_channel_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -648,11 +597,10 @@ int ast_ari_bridges_remove_channel_parse_body(
static void ast_ari_bridges_remove_channel_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_remove_channel_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -710,21 +658,6 @@ static void ast_ari_bridges_remove_channel_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_remove_channel_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -777,11 +710,10 @@ fin: __attribute__((unused))
static void ast_ari_bridges_set_video_source_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_set_video_source_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -841,11 +773,10 @@ fin: __attribute__((unused))
static void ast_ari_bridges_clear_video_source_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_clear_video_source_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -913,11 +844,10 @@ int ast_ari_bridges_start_moh_parse_body(
static void ast_ari_bridges_start_moh_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_start_moh_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -935,21 +865,6 @@ static void ast_ari_bridges_start_moh_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_start_moh_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -998,11 +913,10 @@ fin: __attribute__((unused))
static void ast_ari_bridges_stop_moh_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_stop_moh_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1112,11 +1026,10 @@ int ast_ari_bridges_play_parse_body(
static void ast_ari_bridges_play_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_play_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1186,21 +1099,6 @@ static void ast_ari_bridges_play_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_play_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1301,11 +1199,10 @@ int ast_ari_bridges_play_with_id_parse_body(
static void ast_ari_bridges_play_with_id_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_play_with_id_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1375,21 +1272,6 @@ static void ast_ari_bridges_play_with_id_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_play_with_id_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1477,11 +1359,10 @@ int ast_ari_bridges_record_parse_body(
static void ast_ari_bridges_record_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_bridges_record_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1517,21 +1398,6 @@ static void ast_ari_bridges_record_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_bridges_record_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c
index 252bc4fff..739eb0135 100644
--- a/res/res_ari_channels.c
+++ b/res/res_ari_channels.c
@@ -60,10 +60,9 @@
static void ast_ari_channels_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -172,11 +171,10 @@ int ast_ari_channels_originate_parse_body(
static void ast_ari_channels_originate_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_originate_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -224,21 +222,6 @@ static void ast_ari_channels_originate_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.variables = body;
ast_ari_channels_originate(headers, &args, response);
#if defined(AST_DEVMODE)
@@ -321,11 +304,10 @@ int ast_ari_channels_create_parse_body(
static void ast_ari_channels_create_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_create_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -355,21 +337,6 @@ static void ast_ari_channels_create_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_create_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -417,11 +384,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -533,11 +499,10 @@ int ast_ari_channels_originate_with_id_parse_body(
static void ast_ari_channels_originate_with_id_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_originate_with_id_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -588,21 +553,6 @@ static void ast_ari_channels_originate_with_id_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.variables = body;
ast_ari_channels_originate_with_id(headers, &args, response);
#if defined(AST_DEVMODE)
@@ -661,11 +611,10 @@ int ast_ari_channels_hangup_parse_body(
static void ast_ari_channels_hangup_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_hangup_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -683,21 +632,6 @@ static void ast_ari_channels_hangup_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_hangup_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -771,11 +705,10 @@ int ast_ari_channels_continue_in_dialplan_parse_body(
static void ast_ari_channels_continue_in_dialplan_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_continue_in_dialplan_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -802,21 +735,6 @@ static void ast_ari_channels_continue_in_dialplan_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_continue_in_dialplan_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -879,11 +797,10 @@ int ast_ari_channels_redirect_parse_body(
static void ast_ari_channels_redirect_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_redirect_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -901,21 +818,6 @@ static void ast_ari_channels_redirect_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_redirect_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -967,11 +869,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_answer_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_answer_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1028,11 +929,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_ring_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_ring_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1089,11 +989,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_ring_stop_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_ring_stop_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1179,11 +1078,10 @@ int ast_ari_channels_send_dtmf_parse_body(
static void ast_ari_channels_send_dtmf_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_send_dtmf_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1213,21 +1111,6 @@ static void ast_ari_channels_send_dtmf_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_send_dtmf_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1291,11 +1174,10 @@ int ast_ari_channels_mute_parse_body(
static void ast_ari_channels_mute_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_mute_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1313,21 +1195,6 @@ static void ast_ari_channels_mute_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_mute_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1390,11 +1257,10 @@ int ast_ari_channels_unmute_parse_body(
static void ast_ari_channels_unmute_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_unmute_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1412,21 +1278,6 @@ static void ast_ari_channels_unmute_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_unmute_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1476,11 +1327,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_hold_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_hold_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1537,11 +1387,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_unhold_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_unhold_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1611,11 +1460,10 @@ int ast_ari_channels_start_moh_parse_body(
static void ast_ari_channels_start_moh_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_start_moh_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1633,21 +1481,6 @@ static void ast_ari_channels_start_moh_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_start_moh_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -1697,11 +1530,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_stop_moh_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_stop_moh_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1758,11 +1590,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_start_silence_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_start_silence_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1819,11 +1650,10 @@ fin: __attribute__((unused))
static void ast_ari_channels_stop_silence_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_stop_silence_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -1934,11 +1764,10 @@ int ast_ari_channels_play_parse_body(
static void ast_ari_channels_play_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_play_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2008,21 +1837,6 @@ static void ast_ari_channels_play_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_play_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2124,11 +1938,10 @@ int ast_ari_channels_play_with_id_parse_body(
static void ast_ari_channels_play_with_id_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_play_with_id_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2198,21 +2011,6 @@ static void ast_ari_channels_play_with_id_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_play_with_id_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2301,11 +2099,10 @@ int ast_ari_channels_record_parse_body(
static void ast_ari_channels_record_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_record_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2341,21 +2138,6 @@ static void ast_ari_channels_record_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_record_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2419,11 +2201,10 @@ int ast_ari_channels_get_channel_var_parse_body(
static void ast_ari_channels_get_channel_var_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_get_channel_var_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2441,21 +2222,6 @@ static void ast_ari_channels_get_channel_var_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_get_channel_var_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2522,11 +2288,10 @@ int ast_ari_channels_set_channel_var_parse_body(
static void ast_ari_channels_set_channel_var_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_set_channel_var_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2547,21 +2312,6 @@ static void ast_ari_channels_set_channel_var_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_set_channel_var_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2640,11 +2390,10 @@ int ast_ari_channels_snoop_channel_parse_body(
static void ast_ari_channels_snoop_channel_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_snoop_channel_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2674,21 +2423,6 @@ static void ast_ari_channels_snoop_channel_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_snoop_channel_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2762,11 +2496,10 @@ int ast_ari_channels_snoop_channel_with_id_parse_body(
static void ast_ari_channels_snoop_channel_with_id_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_snoop_channel_with_id_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2796,21 +2529,6 @@ static void ast_ari_channels_snoop_channel_with_id_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_snoop_channel_with_id_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -2876,11 +2594,10 @@ int ast_ari_channels_dial_parse_body(
static void ast_ari_channels_dial_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_channels_dial_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -2901,21 +2618,6 @@ static void ast_ari_channels_dial_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_channels_dial_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
diff --git a/res/res_ari_device_states.c b/res/res_ari_device_states.c
index 39e678fc4..b2aea525e 100644
--- a/res/res_ari_device_states.c
+++ b/res/res_ari_device_states.c
@@ -60,10 +60,9 @@
static void ast_ari_device_states_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_device_states_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -111,11 +110,10 @@ fin: __attribute__((unused))
static void ast_ari_device_states_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_device_states_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -182,11 +180,10 @@ int ast_ari_device_states_update_parse_body(
static void ast_ari_device_states_update_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_device_states_update_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -204,21 +201,6 @@ static void ast_ari_device_states_update_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_device_states_update_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -267,11 +249,10 @@ fin: __attribute__((unused))
static void ast_ari_device_states_delete_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_device_states_delete_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_endpoints.c b/res/res_ari_endpoints.c
index 5307cd1de..944146fcb 100644
--- a/res/res_ari_endpoints.c
+++ b/res/res_ari_endpoints.c
@@ -60,10 +60,9 @@
static void ast_ari_endpoints_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_endpoints_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -132,11 +131,10 @@ int ast_ari_endpoints_send_message_parse_body(
static void ast_ari_endpoints_send_message_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_endpoints_send_message_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -154,21 +152,6 @@ static void ast_ari_endpoints_send_message_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.variables = body;
ast_ari_endpoints_send_message(headers, &args, response);
#if defined(AST_DEVMODE)
@@ -214,11 +197,10 @@ fin: __attribute__((unused))
static void ast_ari_endpoints_list_by_tech_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_endpoints_list_by_tech_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -273,11 +255,10 @@ fin: __attribute__((unused))
static void ast_ari_endpoints_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_endpoints_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -353,11 +334,10 @@ int ast_ari_endpoints_send_message_to_endpoint_parse_body(
static void ast_ari_endpoints_send_message_to_endpoint_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_endpoints_send_message_to_endpoint_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -381,21 +361,6 @@ static void ast_ari_endpoints_send_message_to_endpoint_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.variables = body;
ast_ari_endpoints_send_message_to_endpoint(headers, &args, response);
#if defined(AST_DEVMODE)
diff --git a/res/res_ari_events.c b/res/res_ari_events.c
index 36c9b06d8..8ccb8870c 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -287,11 +287,10 @@ int ast_ari_events_user_event_parse_body(
static void ast_ari_events_user_event_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_events_user_event_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -352,21 +351,6 @@ static void ast_ari_events_user_event_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
args.variables = body;
ast_ari_events_user_event(headers, &args, response);
#if defined(AST_DEVMODE)
diff --git a/res/res_ari_mailboxes.c b/res/res_ari_mailboxes.c
index 4d418fe53..2eac60987 100644
--- a/res/res_ari_mailboxes.c
+++ b/res/res_ari_mailboxes.c
@@ -60,10 +60,9 @@
static void ast_ari_mailboxes_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_mailboxes_list_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -111,11 +110,10 @@ fin: __attribute__((unused))
static void ast_ari_mailboxes_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_mailboxes_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -187,11 +185,10 @@ int ast_ari_mailboxes_update_parse_body(
static void ast_ari_mailboxes_update_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_mailboxes_update_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -212,21 +209,6 @@ static void ast_ari_mailboxes_update_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_mailboxes_update_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -274,11 +256,10 @@ fin: __attribute__((unused))
static void ast_ari_mailboxes_delete_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_mailboxes_delete_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_playbacks.c b/res/res_ari_playbacks.c
index 9678830ce..8267a91b5 100644
--- a/res/res_ari_playbacks.c
+++ b/res/res_ari_playbacks.c
@@ -60,11 +60,10 @@
static void ast_ari_playbacks_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_playbacks_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -119,11 +118,10 @@ fin: __attribute__((unused))
static void ast_ari_playbacks_stop_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_playbacks_stop_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -191,11 +189,10 @@ int ast_ari_playbacks_control_parse_body(
static void ast_ari_playbacks_control_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_playbacks_control_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -213,21 +210,6 @@ static void ast_ari_playbacks_control_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_playbacks_control_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
diff --git a/res/res_ari_recordings.c b/res/res_ari_recordings.c
index a43bbdd93..e82605c7b 100644
--- a/res/res_ari_recordings.c
+++ b/res/res_ari_recordings.c
@@ -60,10 +60,9 @@
static void ast_ari_recordings_list_stored_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_list_stored_args args = {};
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -111,11 +110,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_get_stored_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_get_stored_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -170,11 +168,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_delete_stored_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_delete_stored_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -229,11 +226,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_get_stored_file_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_get_stored_file_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -302,11 +298,10 @@ int ast_ari_recordings_copy_stored_parse_body(
static void ast_ari_recordings_copy_stored_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_copy_stored_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -324,21 +319,6 @@ static void ast_ari_recordings_copy_stored_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_recordings_copy_stored_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -387,11 +367,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_get_live_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_get_live_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -446,11 +425,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_cancel_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_cancel_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -505,11 +483,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_stop_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_stop_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -564,11 +541,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_pause_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_pause_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -624,11 +600,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_unpause_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_unpause_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -684,11 +659,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_mute_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_mute_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -744,11 +718,10 @@ fin: __attribute__((unused))
static void ast_ari_recordings_unmute_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_recordings_unmute_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_ari_sounds.c b/res/res_ari_sounds.c
index eb4bbb3f7..fe0692f16 100644
--- a/res/res_ari_sounds.c
+++ b/res/res_ari_sounds.c
@@ -77,11 +77,10 @@ int ast_ari_sounds_list_parse_body(
static void ast_ari_sounds_list_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_sounds_list_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
@@ -96,21 +95,6 @@ static void ast_ari_sounds_list_cb(
} else
{}
}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
if (ast_ari_sounds_list_parse_body(body, &args)) {
ast_ari_response_alloc_failed(response);
goto fin;
@@ -157,11 +141,10 @@ fin: __attribute__((unused))
static void ast_ari_sounds_get_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_sounds_get_args args = {};
struct ast_variable *i;
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index 3a751ecce..70bb04018 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -1058,13 +1058,14 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
ast_set_flag(mohclass, MOH_RANDSTART);
}
} else if (!strcasecmp(var->name, "format")) {
+ ao2_cleanup(mohclass->format);
mohclass->format = ast_format_cache_get(var->value);
if (!mohclass->format) {
ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value);
mohclass->format = ao2_bump(ast_format_slin);
}
- }
- }
+ }
+ }
}
static int moh_add_file(struct mohclass *class, const char *filepath)
diff --git a/res/res_pjproject.c b/res/res_pjproject.c
index 476defb41..1d9d73eaa 100644
--- a/res/res_pjproject.c
+++ b/res/res_pjproject.c
@@ -410,18 +410,22 @@ static char *handle_pjproject_set_log_level(struct ast_cli_entry *e, int cmd, st
}
/* Update pjproject logging level */
+ if (ast_pjproject_max_log_level < level_new) {
+ level_new = ast_pjproject_max_log_level;
+ ast_cli(a->fd,
+ "Asterisk built or linked with pjproject PJ_LOG_MAX_LEVEL=%d.\n"
+ "Lowering request to the max supported level.\n",
+ ast_pjproject_max_log_level);
+ }
level_old = ast_option_pjproject_log_level;
if (level_old == level_new) {
ast_cli(a->fd, "pjproject log level is still %d.\n", level_old);
} else {
ast_cli(a->fd, "pjproject log level was %d and is now %d.\n",
level_old, level_new);
+ ast_option_pjproject_log_level = level_new;
pj_log_set_level(level_new);
}
- ast_option_pjproject_log_level = pj_log_get_level();
- if (ast_option_pjproject_log_level != level_new) {
- ast_log(LOG_WARNING, "Asterisk built with pjproject PJ_LOG_MAX_LEVEL set too low.\n");
- }
return CLI_SUCCESS;
}
@@ -495,7 +499,7 @@ static int load_module(void)
ast_sorcery_load(pjproject_sorcery);
- pj_log_set_level(ast_option_pjproject_log_level);
+ AST_PJPROJECT_INIT_LOG_LEVEL();
pj_init();
decor_orig = pj_log_get_decor();
@@ -512,12 +516,19 @@ static int load_module(void)
pj_log_set_decor(0);
pj_log_set_level(MAX_PJ_LOG_MAX_LEVEL);/* Set level to guarantee the dump output. */
pj_dump_config();
- pj_log_set_level(ast_option_pjproject_log_level);
pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_INDENT);
pj_log_set_log_func(log_forwarder);
- if (!AST_VECTOR_SIZE(&buildopts)
- || ast_option_pjproject_log_level != pj_log_get_level()) {
- ast_log(LOG_WARNING, "Asterisk built or linked with pjproject PJ_LOG_MAX_LEVEL set too low.\n");
+ if (ast_pjproject_max_log_level < ast_option_pjproject_log_level) {
+ ast_log(LOG_WARNING,
+ "Asterisk built or linked with pjproject PJ_LOG_MAX_LEVEL=%d which is too low for startup level: %d.\n",
+ ast_pjproject_max_log_level, ast_option_pjproject_log_level);
+ ast_option_pjproject_log_level = ast_pjproject_max_log_level;
+ }
+ pj_log_set_level(ast_option_pjproject_log_level);
+ if (!AST_VECTOR_SIZE(&buildopts)) {
+ ast_log(LOG_NOTICE,
+ "Asterisk built or linked with pjproject PJ_LOG_MAX_LEVEL=%d which is too low to get buildopts.\n",
+ ast_pjproject_max_log_level);
}
ast_cli_register_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 00c223330..1111664dc 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1708,9 +1708,7 @@ static int cli_endpoint_print_body(void *obj, void *arg, int flags)
if (number) {
print_name_len = strlen(id) + strlen(number) + 2;
- if (!(print_name = alloca(print_name_len))) {
- return -1;
- }
+ print_name = ast_alloca(print_name_len);
snprintf(print_name, print_name_len, "%s/%s", id, number);
}
@@ -2071,6 +2069,8 @@ static void endpoint_destructor(void* obj)
ast_variables_destroy(endpoint->channel_vars);
AST_VECTOR_FREE(&endpoint->ident_method_order);
ast_free(endpoint->contact_user);
+ ast_free_acl_list(endpoint->contact_acl);
+ ast_free_acl_list(endpoint->acl);
}
static int init_subscription_configuration(struct ast_sip_endpoint_subscription_configuration *subscription)
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index e095a9630..86a5afbdb 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -66,6 +66,9 @@
</configInfo>
***/
+/*! \brief The number of buckets for storing hosts for resolution */
+#define HOSTS_BUCKETS 53
+
/*! \brief Structure for an IP identification matching object */
struct ip_identify_match {
/*! \brief Sorcery object details */
@@ -79,6 +82,8 @@ struct ip_identify_match {
struct ast_ha *matches;
/*! \brief Perform SRV resolution of hostnames */
unsigned int srv_lookups;
+ /*! \brief Hosts to be resolved after applying configuration */
+ struct ao2_container *hosts;
};
/*! \brief Destructor function for a matching object */
@@ -88,6 +93,7 @@ static void ip_identify_destroy(void *obj)
ast_string_field_free_memory(identify);
ast_free_ha(identify->matches);
+ ao2_cleanup(identify->hosts);
}
/*! \brief Allocator function for a matching object */
@@ -241,8 +247,7 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
while ((current_string = ast_strip(strsep(&input_string, ",")))) {
char *mask = strrchr(current_string, '/');
- struct ast_sockaddr address;
- int error, results = 0;
+ int error = 0;
if (ast_strlen_zero(current_string)) {
continue;
@@ -260,6 +265,42 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
continue;
}
+ if (!identify->hosts) {
+ identify->hosts = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, HOSTS_BUCKETS);
+ if (!identify->hosts) {
+ ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
+ ast_sorcery_object_get_id(obj));
+ return -1;
+ }
+ }
+
+ error = ast_str_container_add(identify->hosts, current_string);
+ if (error) {
+ ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
+ current_string, ast_sorcery_object_get_id(obj));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*! \brief Apply handler for identify type */
+static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
+{
+ struct ip_identify_match *identify = obj;
+ char *current_string;
+ struct ao2_iterator i;
+
+ if (!identify->hosts) {
+ return 0;
+ }
+
+ i = ao2_iterator_init(identify->hosts, 0);
+ while ((current_string = ao2_iterator_next(&i))) {
+ struct ast_sockaddr address;
+ int results = 0;
+
/* If the provided string is not an IP address perform SRV resolution on it */
if (identify->srv_lookups && !ast_sockaddr_parse(&address, current_string, 0)) {
results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string);
@@ -282,14 +323,21 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
} else if (results == -1) {
ast_log(LOG_ERROR, "An error occurred when adding resolution results of '%s' on '%s'\n",
current_string, ast_sorcery_object_get_id(obj));
+ ao2_ref(current_string, -1);
+ ao2_iterator_destroy(&i);
return -1;
}
+
+ ao2_ref(current_string, -1);
}
+ ao2_iterator_destroy(&i);
+
+ ao2_ref(identify->hosts, -1);
+ identify->hosts = NULL;
return 0;
}
-
static int match_to_str(const void *obj, const intptr_t *args, char **buf)
{
RAII_VAR(struct ast_str *, str, ast_str_create(MAX_OBJECT_FIELD), ast_free);
@@ -537,7 +585,7 @@ static int load_module(void)
ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
- if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, NULL)) {
+ if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, ip_identify_apply)) {
return AST_MODULE_LOAD_DECLINE;
}
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 43a9d4ba6..42f0dc11e 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -42,6 +42,7 @@
#include "asterisk/res_pjsip.h"
#include "asterisk/callerid.h"
#include "asterisk/manager.h"
+#include "asterisk/cli.h"
#include "asterisk/test.h"
#include "res_pjsip/include/res_pjsip_private.h"
#include "asterisk/res_pjsip_presence_xml.h"
@@ -889,8 +890,9 @@ static void build_node_children(struct ast_sip_endpoint *endpoint, const struct
if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
current = tree_node_alloc(resource, visited, 0);
if (!current) {
- ast_debug(1, "Subscription to leaf resource %s was successful, but encountered"
- "allocation error afterwards\n", resource);
+ ast_debug(1,
+ "Subscription to leaf resource %s was successful, but encountered allocation error afterwards\n",
+ resource);
continue;
}
ast_debug(2, "Subscription to leaf resource %s resulted in success. Adding to parent %s\n",
@@ -1017,14 +1019,16 @@ static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct a
static void add_subscription(struct sip_subscription_tree *obj)
{
- SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_WRLOCK(&subscriptions);
AST_RWLIST_INSERT_TAIL(&subscriptions, obj, next);
+ AST_RWLIST_UNLOCK(&subscriptions);
}
static void remove_subscription(struct sip_subscription_tree *obj)
{
struct sip_subscription_tree *i;
- SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+ AST_RWLIST_WRLOCK(&subscriptions);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&subscriptions, i, next) {
if (i == obj) {
AST_RWLIST_REMOVE_CURRENT(next);
@@ -1036,6 +1040,7 @@ static void remove_subscription(struct sip_subscription_tree *obj)
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&subscriptions);
}
static void destroy_subscription(struct ast_sip_subscription *sub)
@@ -1578,18 +1583,19 @@ static int for_each_subscription(on_subscription_t on_subscription, void *arg)
{
int num = 0;
struct sip_subscription_tree *i;
- SCOPED_LOCK(lock, &subscriptions, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
if (!on_subscription) {
return num;
}
+ AST_RWLIST_RDLOCK(&subscriptions);
AST_RWLIST_TRAVERSE(&subscriptions, i, next) {
if (on_subscription(i, arg)) {
break;
}
++num;
}
+ AST_RWLIST_UNLOCK(&subscriptions);
return num;
}
@@ -2489,8 +2495,9 @@ static int publication_cmp_fn(void *obj, void *arg, int flags)
static void publish_add_handler(struct ast_sip_publish_handler *handler)
{
- SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_WRLOCK(&publish_handlers);
AST_RWLIST_INSERT_TAIL(&publish_handlers, handler, next);
+ AST_RWLIST_UNLOCK(&publish_handlers);
}
int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler)
@@ -2517,7 +2524,8 @@ int ast_sip_register_publish_handler(struct ast_sip_publish_handler *handler)
void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler)
{
struct ast_sip_publish_handler *iter;
- SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+ AST_RWLIST_WRLOCK(&publish_handlers);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&publish_handlers, iter, next) {
if (handler == iter) {
AST_RWLIST_REMOVE_CURRENT(next);
@@ -2527,27 +2535,30 @@ void ast_sip_unregister_publish_handler(struct ast_sip_publish_handler *handler)
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&publish_handlers);
}
AST_RWLIST_HEAD_STATIC(subscription_handlers, ast_sip_subscription_handler);
static void sub_add_handler(struct ast_sip_subscription_handler *handler)
{
- SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_WRLOCK(&subscription_handlers);
AST_RWLIST_INSERT_TAIL(&subscription_handlers, handler, next);
ast_module_ref(ast_module_info->self);
+ AST_RWLIST_UNLOCK(&subscription_handlers);
}
static struct ast_sip_subscription_handler *find_sub_handler_for_event_name(const char *event_name)
{
struct ast_sip_subscription_handler *iter;
- SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_RDLOCK(&subscription_handlers);
AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
if (!strcmp(iter->event_name, event_name)) {
break;
}
}
+ AST_RWLIST_UNLOCK(&subscription_handlers);
return iter;
}
@@ -2565,8 +2576,9 @@ int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *h
existing = find_sub_handler_for_event_name(handler->event_name);
if (existing) {
- ast_log(LOG_ERROR, "Unable to register subscription handler for event %s."
- "A handler is already registered\n", handler->event_name);
+ ast_log(LOG_ERROR,
+ "Unable to register subscription handler for event %s. A handler is already registered\n",
+ handler->event_name);
return -1;
}
@@ -2586,7 +2598,8 @@ int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *h
void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler)
{
struct ast_sip_subscription_handler *iter;
- SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+ AST_RWLIST_WRLOCK(&subscription_handlers);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&subscription_handlers, iter, next) {
if (handler == iter) {
AST_RWLIST_REMOVE_CURRENT(next);
@@ -2595,6 +2608,7 @@ void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&subscription_handlers);
}
static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype_nolock(const char *type, const char *subtype)
@@ -2764,7 +2778,6 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(resource);
expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
-
if (expires_header) {
if (expires_header->ivalue == 0) {
ast_log(LOG_WARNING, "Subscription request from endpoint %s rejected. Expiration of 0 is invalid\n",
@@ -2823,8 +2836,8 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
static struct ast_sip_publish_handler *find_pub_handler(const char *event)
{
struct ast_sip_publish_handler *iter = NULL;
- SCOPED_LOCK(lock, &publish_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_RDLOCK(&publish_handlers);
AST_RWLIST_TRAVERSE(&publish_handlers, iter, next) {
if (strcmp(event, iter->event_name)) {
ast_debug(3, "Event %s does not match %s\n", event, iter->event_name);
@@ -2833,6 +2846,7 @@ static struct ast_sip_publish_handler *find_pub_handler(const char *event)
ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name);
break;
}
+ AST_RWLIST_UNLOCK(&publish_handlers);
return iter;
}
@@ -3201,8 +3215,8 @@ int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator
void ast_sip_pubsub_unregister_body_generator(struct ast_sip_pubsub_body_generator *generator)
{
struct ast_sip_pubsub_body_generator *iter;
- SCOPED_LOCK(lock, &body_generators, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_WRLOCK(&body_generators);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&body_generators, iter, list) {
if (iter == generator) {
AST_LIST_REMOVE_CURRENT(list);
@@ -3210,6 +3224,7 @@ void ast_sip_pubsub_unregister_body_generator(struct ast_sip_pubsub_body_generat
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&body_generators);
}
int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplement *supplement)
@@ -3224,8 +3239,8 @@ int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplemen
void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supplement *supplement)
{
struct ast_sip_pubsub_body_supplement *iter;
- SCOPED_LOCK(lock, &body_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_WRLOCK(&body_supplements);
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&body_supplements, iter, list) {
if (iter == supplement) {
AST_LIST_REMOVE_CURRENT(list);
@@ -3233,6 +3248,7 @@ void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supple
}
}
AST_RWLIST_TRAVERSE_SAFE_END;
+ AST_RWLIST_UNLOCK(&body_supplements);
}
const char *ast_sip_subscription_get_body_type(struct ast_sip_subscription *sub)
@@ -3586,6 +3602,8 @@ static int ami_subscription_detail(struct sip_subscription_tree *sub_tree,
sip_subscription_to_ami(sub_tree, &buf);
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
ast_free(buf);
+
+ ++ami->count;
return 0;
}
@@ -3604,14 +3622,13 @@ static int ami_subscription_detail_outbound(struct sip_subscription_tree *sub_tr
static int ami_show_subscriptions_inbound(struct mansession *s, const struct message *m)
{
struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
- int num;
astman_send_listack(s, m, "Following are Events for each inbound Subscription",
"start");
- num = for_each_subscription(ami_subscription_detail_inbound, &ami);
+ for_each_subscription(ami_subscription_detail_inbound, &ami);
- astman_send_list_complete_start(s, m, "InboundSubscriptionDetailComplete", num);
+ astman_send_list_complete_start(s, m, "InboundSubscriptionDetailComplete", ami.count);
astman_send_list_complete_end(s);
return 0;
}
@@ -3619,14 +3636,13 @@ static int ami_show_subscriptions_inbound(struct mansession *s, const struct mes
static int ami_show_subscriptions_outbound(struct mansession *s, const struct message *m)
{
struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
- int num;
astman_send_listack(s, m, "Following are Events for each outbound Subscription",
"start");
- num = for_each_subscription(ami_subscription_detail_outbound, &ami);
+ for_each_subscription(ami_subscription_detail_outbound, &ami);
- astman_send_list_complete_start(s, m, "OutboundSubscriptionDetailComplete", num);
+ astman_send_list_complete_start(s, m, "OutboundSubscriptionDetailComplete", ami.count);
astman_send_list_complete_end(s);
return 0;
}
@@ -3647,21 +3663,21 @@ static int format_ami_resource_lists(void *obj, void *arg, int flags)
return CMP_STOP;
}
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
-
ast_free(buf);
+
+ ++ami->count;
return 0;
}
static int ami_show_resource_lists(struct mansession *s, const struct message *m)
{
struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
- int num;
struct ao2_container *lists;
lists = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "resource_list",
AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
- if (!lists || !(num = ao2_container_count(lists))) {
+ if (!lists || !ao2_container_count(lists)) {
astman_send_error(s, m, "No resource lists found\n");
return 0;
}
@@ -3671,7 +3687,7 @@ static int ami_show_resource_lists(struct mansession *s, const struct message *m
ao2_callback(lists, OBJ_NODATA, format_ami_resource_lists, &ami);
- astman_send_list_complete_start(s, m, "ResourceListDetailComplete", num);
+ astman_send_list_complete_start(s, m, "ResourceListDetailComplete", ami.count);
astman_send_list_complete_end(s);
return 0;
}
@@ -3679,6 +3695,541 @@ static int ami_show_resource_lists(struct mansession *s, const struct message *m
#define AMI_SHOW_SUBSCRIPTIONS_INBOUND "PJSIPShowSubscriptionsInbound"
#define AMI_SHOW_SUBSCRIPTIONS_OUTBOUND "PJSIPShowSubscriptionsOutbound"
+#define MAX_REGEX_ERROR_LEN 128
+
+struct cli_sub_parms {
+ /*! CLI handler entry e parameter */
+ struct ast_cli_entry *e;
+ /*! CLI handler entry a parameter */
+ struct ast_cli_args *a;
+ /*! CLI subscription entry output line(s) */
+ struct ast_str *buf;
+ /*! Compiled regular expression to select if buf is written to CLI when not NULL. */
+ regex_t *like;
+ int count;
+};
+
+struct cli_sub_complete_parms {
+ struct ast_cli_args *a;
+ /*! Found callid for search position */
+ char *callid;
+ int wordlen;
+ int which;
+};
+
+static int cli_complete_subscription_common(struct sip_subscription_tree *sub_tree, struct cli_sub_complete_parms *cli)
+{
+ pj_str_t *callid;
+
+ if (!sub_tree->dlg) {
+ return 0;
+ }
+
+ callid = &sub_tree->dlg->call_id->id;
+ if (cli->wordlen <= pj_strlen(callid)
+ && !strncasecmp(cli->a->word, pj_strbuf(callid), cli->wordlen)
+ && (++cli->which > cli->a->n)) {
+ cli->callid = ast_malloc(pj_strlen(callid) + 1);
+ if (cli->callid) {
+ ast_copy_pj_str(cli->callid, callid, pj_strlen(callid) + 1);
+ }
+ return -1;
+ }
+ return 0;
+}
+
+static int cli_complete_subscription_inbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_NOTIFIER
+ ? cli_complete_subscription_common(sub_tree, arg) : 0;
+}
+
+static int cli_complete_subscription_outbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_SUBSCRIBER
+ ? cli_complete_subscription_common(sub_tree, arg) : 0;
+}
+
+static char *cli_complete_subscription_callid(struct ast_cli_args *a)
+{
+ struct cli_sub_complete_parms cli;
+ on_subscription_t on_subscription;
+
+ if (a->pos != 4) {
+ return NULL;
+ }
+
+ if (!strcasecmp(a->argv[3], "inbound")) {
+ on_subscription = cli_complete_subscription_inbound;
+ } else if (!strcasecmp(a->argv[3], "outbound")) {
+ on_subscription = cli_complete_subscription_outbound;
+ } else {
+ /* Should never get here */
+ ast_assert(0);
+ return NULL;
+ }
+
+ cli.a = a;
+ cli.callid = NULL;
+ cli.wordlen = strlen(a->word);
+ cli.which = 0;
+ for_each_subscription(on_subscription, &cli);
+
+ return cli.callid;
+}
+
+static int cli_subscription_expiry(struct sip_subscription_tree *sub_tree)
+{
+ int expiry;
+
+ expiry = sub_tree->persistence
+ ? ast_tvdiff_ms(sub_tree->persistence->expires, ast_tvnow()) / 1000
+ : 0;
+ if (expiry < 0) {
+ /* Subscription expired */
+ expiry = 0;
+ }
+ return expiry;
+}
+
+static int cli_show_subscription_common(struct sip_subscription_tree *sub_tree, struct cli_sub_parms *cli)
+{
+ const char *callid = (const char *) cli->buf;/* Member repurposed to pass in callid */
+ pj_str_t *sub_callid;
+ struct ast_str *buf;
+ char *src;
+ char *dest;
+ char *key;
+ char *value;
+ char *value_end;
+ int key_len;
+ int key_filler_width;
+ int value_len;
+
+ if (!sub_tree->dlg) {
+ return 0;
+ }
+ sub_callid = &sub_tree->dlg->call_id->id;
+ if (pj_strcmp2(sub_callid, callid)) {
+ return 0;
+ }
+
+ buf = ast_str_create(512);
+ if (!buf) {
+ return -1;
+ }
+
+ ast_cli(cli->a->fd,
+ "%-20s: %s\n"
+ "===========================================================================\n",
+ "ParameterName", "ParameterValue");
+
+ ast_str_append(&buf, 0, "Resource: %s\n", sub_tree->root->resource);
+ ast_str_append(&buf, 0, "Event: %s\n", sub_tree->root->handler->event_name);
+ ast_str_append(&buf, 0, "Expiry: %d\n", cli_subscription_expiry(sub_tree));
+
+ sip_subscription_to_ami(sub_tree, &buf);
+
+ /* Convert AMI \r\n to \n line terminators. */
+ src = strchr(ast_str_buffer(buf), '\r');
+ if (src) {
+ dest = src;
+ ++src;
+ while (*src) {
+ if (*src == '\r') {
+ ++src;
+ continue;
+ }
+ *dest++ = *src++;
+ }
+ *dest = '\0';
+ ast_str_update(buf);
+ }
+
+ /* Reformat AMI key value pairs to pretty columns */
+ key = ast_str_buffer(buf);
+ do {
+ value = strchr(key, ':');
+ if (!value) {
+ break;
+ }
+ value_end = strchr(value, '\n');
+ if (!value_end) {
+ break;
+ }
+
+ /* Calculate field lengths */
+ key_len = value - key;
+ key_filler_width = 20 - key_len;
+ if (key_filler_width < 0) {
+ key_filler_width = 0;
+ }
+ value_len = value_end - value;
+
+ ast_cli(cli->a->fd, "%.*s%*s%.*s\n",
+ key_len, key, key_filler_width, "",
+ value_len, value);
+
+ key = value_end + 1;
+ } while (*key);
+ ast_cli(cli->a->fd, "\n");
+
+ ast_free(buf);
+
+ return -1;
+}
+
+static int cli_show_subscription_inbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_NOTIFIER
+ ? cli_show_subscription_common(sub_tree, arg) : 0;
+}
+
+static int cli_show_subscription_outbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_SUBSCRIBER
+ ? cli_show_subscription_common(sub_tree, arg) : 0;
+}
+
+static char *cli_show_subscription_inout(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ on_subscription_t on_subscription;
+ struct cli_sub_parms cli;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "pjsip show subscription {inbound|outbound}";
+ e->usage = "Usage:\n"
+ " pjsip show subscription inbound <call-id>\n"
+ " pjsip show subscription outbound <call-id>\n"
+ " Show active subscription with the dialog call-id\n";
+ return NULL;
+ case CLI_GENERATE:
+ return cli_complete_subscription_callid(a);
+ }
+
+ if (a->argc != 5) {
+ return CLI_SHOWUSAGE;
+ }
+
+ if (!strcasecmp(a->argv[3], "inbound")) {
+ on_subscription = cli_show_subscription_inbound;
+ } else if (!strcasecmp(a->argv[3], "outbound")) {
+ on_subscription = cli_show_subscription_outbound;
+ } else {
+ /* Should never get here */
+ ast_assert(0);
+ return NULL;
+ }
+
+ /* Find the subscription with the specified call-id */
+ cli.a = a;
+ cli.e = e;
+ cli.buf = (void *) a->argv[4];/* Repurpose the buf member to pass in callid */
+ for_each_subscription(on_subscription, &cli);
+
+ return CLI_SUCCESS;
+}
+
+#define CLI_SHOW_SUB_FORMAT_HEADER \
+ "Endpoint: <Endpoint/Caller-ID.............................................>\n" \
+ "Resource: <Resource/Event.................................................>\n" \
+ " Expiry: <Expiry> <Call-id..............................................>\n" \
+ "===========================================================================\n\n"
+#define CLI_SHOW_SUB_FORMAT_ENTRY \
+ "Endpoint: %s/%s\n" \
+ "Resource: %s/%s\n" \
+ " Expiry: %8d %s\n\n"
+
+static int cli_show_subscriptions_detail(struct sip_subscription_tree *sub_tree, struct cli_sub_parms *cli)
+{
+ char caller_id[256];
+ char callid[256];
+
+ ast_callerid_merge(caller_id, sizeof(caller_id),
+ S_COR(sub_tree->endpoint->id.self.name.valid,
+ sub_tree->endpoint->id.self.name.str, NULL),
+ S_COR(sub_tree->endpoint->id.self.number.valid,
+ sub_tree->endpoint->id.self.number.str, NULL),
+ "<none>");
+
+ /* Call-id */
+ if (sub_tree->dlg) {
+ ast_copy_pj_str(callid, &sub_tree->dlg->call_id->id, sizeof(callid));
+ } else {
+ ast_copy_string(callid, "<unknown>", sizeof(callid));
+ }
+
+ ast_str_set(&cli->buf, 0, CLI_SHOW_SUB_FORMAT_ENTRY,
+ ast_sorcery_object_get_id(sub_tree->endpoint), caller_id,
+ sub_tree->root->resource, sub_tree->root->handler->event_name,
+ cli_subscription_expiry(sub_tree), callid);
+
+ if (cli->like) {
+ if (regexec(cli->like, ast_str_buffer(cli->buf), 0, NULL, 0)) {
+ /* Output line did not match the regex */
+ return 0;
+ }
+ }
+
+ ast_cli(cli->a->fd, "%s", ast_str_buffer(cli->buf));
+ ++cli->count;
+
+ return 0;
+}
+
+static int cli_show_subscriptions_inbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_NOTIFIER
+ ? cli_show_subscriptions_detail(sub_tree, arg) : 0;
+}
+
+static int cli_show_subscriptions_outbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_SUBSCRIBER
+ ? cli_show_subscriptions_detail(sub_tree, arg) : 0;
+}
+
+static char *cli_show_subscriptions_inout(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ on_subscription_t on_subscription;
+ struct cli_sub_parms cli;
+ regex_t like;
+ const char *regex;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "pjsip show subscriptions {inbound|outbound} [like]";
+ e->usage = "Usage:\n"
+ " pjsip show subscriptions inbound [like <regex>]\n"
+ " Show active inbound subscriptions\n"
+ " pjsip show subscriptions outbound [like <regex>]\n"
+ " Show active outbound subscriptions\n"
+ "\n"
+ " The regex selects a subscriptions output that matches.\n"
+ " i.e., All output lines for a subscription are checked\n"
+ " as a block by the regex.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc != 4 && a->argc != 6) {
+ return CLI_SHOWUSAGE;
+ }
+ if (!strcasecmp(a->argv[3], "inbound")) {
+ on_subscription = cli_show_subscriptions_inbound;
+ } else if (!strcasecmp(a->argv[3], "outbound")) {
+ on_subscription = cli_show_subscriptions_outbound;
+ } else {
+ /* Should never get here */
+ ast_assert(0);
+ return CLI_SHOWUSAGE;
+ }
+ if (a->argc == 6) {
+ int rc;
+
+ if (strcasecmp(a->argv[4], "like")) {
+ return CLI_SHOWUSAGE;
+ }
+
+ /* Setup regular expression */
+ memset(&like, 0, sizeof(like));
+ cli.like = &like;
+ regex = a->argv[5];
+ rc = regcomp(cli.like, regex, REG_EXTENDED | REG_NOSUB);
+ if (rc) {
+ char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
+
+ regerror(rc, cli.like, regerr, MAX_REGEX_ERROR_LEN);
+ ast_cli(a->fd, "Regular expression '%s' failed to compile: %s\n",
+ regex, regerr);
+ return CLI_FAILURE;
+ }
+ } else {
+ cli.like = NULL;
+ regex = NULL;
+ }
+
+ cli.a = a;
+ cli.e = e;
+ cli.count = 0;
+ cli.buf = ast_str_create(256);
+ if (!cli.buf) {
+ if (cli.like) {
+ regfree(cli.like);
+ }
+ return CLI_FAILURE;
+ }
+
+ ast_cli(a->fd, CLI_SHOW_SUB_FORMAT_HEADER);
+ for_each_subscription(on_subscription, &cli);
+ ast_cli(a->fd, "%d active subscriptions%s%s%s\n",
+ cli.count,
+ regex ? " matched \"" : "",
+ regex ?: "",
+ regex ? "\"" : "");
+
+ ast_free(cli.buf);
+ if (cli.like) {
+ regfree(cli.like);
+ }
+
+ return CLI_SUCCESS;
+}
+
+#define CLI_LIST_SUB_FORMAT_HEADER "%-30.30s %-30.30s %6.6s %s\n"
+#define CLI_LIST_SUB_FORMAT_ENTRY "%-30.30s %-30.30s %6d %s\n"
+
+static int cli_list_subscriptions_detail(struct sip_subscription_tree *sub_tree, struct cli_sub_parms *cli)
+{
+ char ep_cid_buf[50];
+ char res_evt_buf[50];
+ char callid[256];
+
+ /* Endpoint/CID column */
+ snprintf(ep_cid_buf, sizeof(ep_cid_buf), "%s/%s",
+ ast_sorcery_object_get_id(sub_tree->endpoint),
+ S_COR(sub_tree->endpoint->id.self.name.valid, sub_tree->endpoint->id.self.name.str,
+ S_COR(sub_tree->endpoint->id.self.number.valid,
+ sub_tree->endpoint->id.self.number.str, "<none>")));
+
+ /* Resource/Event column */
+ snprintf(res_evt_buf, sizeof(res_evt_buf), "%s/%s",
+ sub_tree->root->resource,
+ sub_tree->root->handler->event_name);
+
+ /* Call-id column */
+ if (sub_tree->dlg) {
+ ast_copy_pj_str(callid, &sub_tree->dlg->call_id->id, sizeof(callid));
+ } else {
+ ast_copy_string(callid, "<unknown>", sizeof(callid));
+ }
+
+ ast_str_set(&cli->buf, 0, CLI_LIST_SUB_FORMAT_ENTRY,
+ ep_cid_buf,
+ res_evt_buf,
+ cli_subscription_expiry(sub_tree),
+ callid);
+
+ if (cli->like) {
+ if (regexec(cli->like, ast_str_buffer(cli->buf), 0, NULL, 0)) {
+ /* Output line did not match the regex */
+ return 0;
+ }
+ }
+
+ ast_cli(cli->a->fd, "%s", ast_str_buffer(cli->buf));
+ ++cli->count;
+
+ return 0;
+}
+
+static int cli_list_subscriptions_inbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_NOTIFIER
+ ? cli_list_subscriptions_detail(sub_tree, arg) : 0;
+}
+
+static int cli_list_subscriptions_outbound(struct sip_subscription_tree *sub_tree, void *arg)
+{
+ return sub_tree->role == AST_SIP_SUBSCRIBER
+ ? cli_list_subscriptions_detail(sub_tree, arg) : 0;
+}
+
+static char *cli_list_subscriptions_inout(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ on_subscription_t on_subscription;
+ struct cli_sub_parms cli;
+ regex_t like;
+ const char *regex;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "pjsip list subscriptions {inbound|outbound} [like]";
+ e->usage = "Usage:\n"
+ " pjsip list subscriptions inbound [like <regex>]\n"
+ " List active inbound subscriptions\n"
+ " pjsip list subscriptions outbound [like <regex>]\n"
+ " List active outbound subscriptions\n"
+ "\n"
+ " The regex selects output lines that match.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc != 4 && a->argc != 6) {
+ return CLI_SHOWUSAGE;
+ }
+ if (!strcasecmp(a->argv[3], "inbound")) {
+ on_subscription = cli_list_subscriptions_inbound;
+ } else if (!strcasecmp(a->argv[3], "outbound")) {
+ on_subscription = cli_list_subscriptions_outbound;
+ } else {
+ /* Should never get here */
+ ast_assert(0);
+ return CLI_SHOWUSAGE;
+ }
+ if (a->argc == 6) {
+ int rc;
+
+ if (strcasecmp(a->argv[4], "like")) {
+ return CLI_SHOWUSAGE;
+ }
+
+ /* Setup regular expression */
+ memset(&like, 0, sizeof(like));
+ cli.like = &like;
+ regex = a->argv[5];
+ rc = regcomp(cli.like, regex, REG_EXTENDED | REG_NOSUB);
+ if (rc) {
+ char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
+
+ regerror(rc, cli.like, regerr, MAX_REGEX_ERROR_LEN);
+ ast_cli(a->fd, "Regular expression '%s' failed to compile: %s\n",
+ regex, regerr);
+ return CLI_FAILURE;
+ }
+ } else {
+ cli.like = NULL;
+ regex = NULL;
+ }
+
+ cli.a = a;
+ cli.e = e;
+ cli.count = 0;
+ cli.buf = ast_str_create(256);
+ if (!cli.buf) {
+ if (cli.like) {
+ regfree(cli.like);
+ }
+ return CLI_FAILURE;
+ }
+
+ ast_cli(a->fd, CLI_LIST_SUB_FORMAT_HEADER,
+ "Endpoint/CLI", "Resource/Event", "Expiry", "Call-id");
+ for_each_subscription(on_subscription, &cli);
+ ast_cli(a->fd, "\n%d active subscriptions%s%s%s\n",
+ cli.count,
+ regex ? " matched \"" : "",
+ regex ?: "",
+ regex ? "\"" : "");
+
+ ast_free(cli.buf);
+ if (cli.like) {
+ regfree(cli.like);
+ }
+
+ return CLI_SUCCESS;
+}
+
+static struct ast_cli_entry cli_commands[] = {
+ AST_CLI_DEFINE(cli_list_subscriptions_inout, "List active inbound/outbound subscriptions"),
+ AST_CLI_DEFINE(cli_show_subscription_inout, "Show active subscription details"),
+ AST_CLI_DEFINE(cli_show_subscriptions_inout, "Show active inbound/outbound subscriptions"),
+};
+
static int persistence_endpoint_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
struct subscription_persistence *persistence = obj;
@@ -4620,6 +5171,8 @@ static int load_module(void)
ast_manager_register_xml("PJSIPShowResourceLists", EVENT_FLAG_SYSTEM,
ami_show_resource_lists);
+ ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
+
AST_TEST_REGISTER(resource_tree);
AST_TEST_REGISTER(complex_resource_tree);
AST_TEST_REGISTER(bad_resource);
@@ -4633,6 +5186,16 @@ static int load_module(void)
static int unload_module(void)
{
+ AST_TEST_UNREGISTER(resource_tree);
+ AST_TEST_UNREGISTER(complex_resource_tree);
+ AST_TEST_UNREGISTER(bad_resource);
+ AST_TEST_UNREGISTER(bad_branch);
+ AST_TEST_UNREGISTER(duplicate_resource);
+ AST_TEST_UNREGISTER(loop);
+ AST_TEST_UNREGISTER(bad_event);
+
+ ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
+
ast_manager_unregister(AMI_SHOW_SUBSCRIPTIONS_OUTBOUND);
ast_manager_unregister(AMI_SHOW_SUBSCRIPTIONS_INBOUND);
ast_manager_unregister("PJSIPShowResourceLists");
@@ -4642,14 +5205,6 @@ static int unload_module(void)
ast_sched_context_destroy(sched);
}
- AST_TEST_UNREGISTER(resource_tree);
- AST_TEST_UNREGISTER(complex_resource_tree);
- AST_TEST_UNREGISTER(bad_resource);
- AST_TEST_UNREGISTER(bad_branch);
- AST_TEST_UNREGISTER(duplicate_resource);
- AST_TEST_UNREGISTER(loop);
- AST_TEST_UNREGISTER(bad_event);
-
return 0;
}
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 4c79f8f5b..c4608db6c 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -230,6 +230,7 @@ struct dtls_details {
/*! \brief RTP session description */
struct ast_rtp {
int s;
+ /*! \note The f.subclass.format holds a ref. */
struct ast_frame f;
unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */
@@ -2765,6 +2766,7 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance)
if (rtp->red) {
AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
ast_free(rtp->red);
+ rtp->red = NULL;
}
#ifdef HAVE_PJPROJECT
@@ -3485,7 +3487,8 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
return 0;
}
-static struct ast_frame *red_t140_to_red(struct rtp_red *red) {
+static struct ast_frame *red_t140_to_red(struct rtp_red *red)
+{
unsigned char *data = red->t140red.data.ptr;
int len = 0;
int i;
@@ -4320,6 +4323,29 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
rtcp_report,
message_blob);
ast_json_unref(message_blob);
+
+ /* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report
+ * object as a its data */
+ rtp->f.frametype = AST_FRAME_RTCP;
+ rtp->f.data.ptr = rtp->rawdata + AST_FRIENDLY_OFFSET;
+ memcpy(rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report));
+ rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report);
+ if (rc > 0) {
+ /* There's always a single report block stored, here */
+ struct ast_rtp_rtcp_report *rtcp_report2;
+ report_block = rtp->f.data.ptr + rtp->f.datalen + sizeof(struct ast_rtp_rtcp_report_block *);
+ memcpy(report_block, rtcp_report->report_block[report_counter-1], sizeof(struct ast_rtp_rtcp_report_block));
+ rtcp_report2 = (struct ast_rtp_rtcp_report *)rtp->f.data.ptr;
+ rtcp_report2->report_block[report_counter-1] = report_block;
+ rtp->f.datalen += sizeof(struct ast_rtp_rtcp_report_block);
+ }
+ rtp->f.offset = AST_FRIENDLY_OFFSET;
+ rtp->f.samples = 0;
+ rtp->f.mallocd = 0;
+ rtp->f.delivery.tv_sec = 0;
+ rtp->f.delivery.tv_usec = 0;
+ rtp->f.src = "RTP";
+ f = &rtp->f;
break;
case RTCP_PT_FUR:
/* Handle RTCP FIR as FUR */
@@ -5059,22 +5085,21 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
int x;
- if (!(rtp->red = ast_calloc(1, sizeof(*rtp->red)))) {
+ rtp->red = ast_calloc(1, sizeof(*rtp->red));
+ if (!rtp->red) {
return -1;
}
rtp->red->t140.frametype = AST_FRAME_TEXT;
- ao2_replace(rtp->red->t140.subclass.format, ast_format_t140_red);
+ rtp->red->t140.subclass.format = ast_format_t140_red;
rtp->red->t140.data.ptr = &rtp->red->buf_data;
- rtp->red->t140.ts = 0;
rtp->red->t140red = rtp->red->t140;
rtp->red->t140red.data.ptr = &rtp->red->t140red_data;
- rtp->red->t140red.datalen = 0;
+
rtp->red->ti = buffer_time;
rtp->red->num_gen = generations;
rtp->red->hdrlen = generations * 4 + 1;
- rtp->red->prev_ts = 0;
for (x = 0; x < generations; x++) {
rtp->red->pt[x] = payloads[x];
@@ -5084,8 +5109,6 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */
rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance);
- rtp->red->t140.datalen = 0;
-
return 0;
}
@@ -5666,7 +5689,7 @@ static int load_module(void)
#ifdef HAVE_PJPROJECT
pj_lock_t *lock;
- pj_log_set_level(ast_option_pjproject_log_level);
+ AST_PJPROJECT_INIT_LOG_LEVEL();
if (pj_init() != PJ_SUCCESS) {
return AST_MODULE_LOAD_DECLINE;
}
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 24c2b6598..196720984 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -65,7 +65,6 @@
#include "stasis/app.h"
#include "stasis/control.h"
#include "stasis/messaging.h"
-#include "stasis/cli.h"
#include "stasis/stasis_bridge.h"
#include "asterisk/core_unreal.h"
#include "asterisk/musiconhold.h"
@@ -176,11 +175,6 @@ static struct ast_json *stasis_start_to_json(struct stasis_message *message,
STASIS_MESSAGE_TYPE_DEFN_LOCAL(start_message_type,
.to_json = stasis_start_to_json);
-const char *stasis_app_name(const struct stasis_app *app)
-{
- return app_name(app);
-}
-
/*! AO2 hash function for \ref app */
static int app_hash(const void *obj, const int flags)
{
@@ -956,7 +950,7 @@ static int send_start_msg_snapshots(struct ast_channel *chan, struct stasis_app
if (app_subscribe_channel(app, chan)) {
ast_log(LOG_ERROR, "Error subscribing app '%s' to channel '%s'\n",
- app_name(app), ast_channel_name(chan));
+ stasis_app_name(app), ast_channel_name(chan));
return -1;
}
@@ -970,7 +964,7 @@ static int send_start_msg_snapshots(struct ast_channel *chan, struct stasis_app
payload->replace_channel = ao2_bump(replace_channel_snapshot);
json_blob = ast_json_pack("{s: s, s: o, s: []}",
- "app", app_name(app),
+ "app", stasis_app_name(app),
"timestamp", ast_json_timeval(ast_tvnow(), NULL),
"args");
if (!json_blob) {
@@ -1040,7 +1034,7 @@ int app_send_end_msg(struct stasis_app *app, struct ast_channel *chan)
return 0;
}
- blob = ast_json_pack("{s: s}", "app", app_name(app));
+ blob = ast_json_pack("{s: s}", "app", stasis_app_name(app));
if (!blob) {
ast_log(LOG_ERROR, "Error packing JSON for StasisEnd message\n");
return -1;
@@ -1486,10 +1480,6 @@ static struct stasis_app *find_app_by_name(const char *app_name)
res = ao2_find(apps_registry, app_name, OBJ_SEARCH_KEY);
}
- if (!res) {
- ast_log(LOG_WARNING, "Could not find app '%s'\n",
- app_name ? : "(null)");
- }
return res;
}
@@ -1970,8 +1960,6 @@ static int unload_module(void)
{
stasis_app_unregister_event_sources();
- cli_cleanup();
-
messaging_cleanup();
cleanup();
@@ -2131,11 +2119,6 @@ static int load_module(void)
return AST_MODULE_LOAD_FAILURE;
}
- if (cli_init()) {
- unload_module();
- return AST_MODULE_LOAD_FAILURE;
- }
-
bridge_stasis_init();
stasis_app_register_event_sources();
diff --git a/res/stasis/app.c b/res/stasis/app.c
index 0b75ed5d7..b0bcf3c42 100644
--- a/res/stasis/app.c
+++ b/res/stasis/app.c
@@ -41,6 +41,9 @@
#define CHANNEL_ALL "__AST_CHANNEL_ALL_TOPIC"
#define ENDPOINT_ALL "__AST_ENDPOINT_ALL_TOPIC"
+/*! Global debug flag. No need for locking */
+int global_debug;
+
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate);
struct stasis_app {
@@ -840,15 +843,64 @@ static void bridge_default_handler(void *data, struct stasis_subscription *sub,
}
}
-void app_set_debug(struct stasis_app *app, int debug)
+void stasis_app_set_debug(struct stasis_app *app, int debug)
{
if (!app) {
return;
}
- {
- SCOPED_AO2LOCK(lock, app);
- app->debug = debug;
+ app->debug = debug;
+}
+
+void stasis_app_set_debug_by_name(const char *app_name, int debug)
+{
+ struct stasis_app *app = stasis_app_get_by_name(app_name);
+
+ if (!app) {
+ return;
+ }
+
+ app->debug = debug;
+ ao2_cleanup(app);
+}
+
+int stasis_app_get_debug(struct stasis_app *app)
+{
+ return (app ? app->debug : 0) || global_debug;
+}
+
+int stasis_app_get_debug_by_name(const char *app_name)
+{
+ RAII_VAR(struct stasis_app *, app, stasis_app_get_by_name(app_name), ao2_cleanup);
+
+ return (app ? app->debug : 0) || global_debug;
+}
+
+void stasis_app_set_global_debug(int debug)
+{
+ global_debug = debug;
+ if (!global_debug) {
+ struct ao2_container *app_names = stasis_app_get_all();
+ struct ao2_iterator it_app_names;
+ char *app_name;
+ struct stasis_app *app;
+
+ if (!app_names || !ao2_container_count(app_names)) {
+ ao2_cleanup(app_names);
+ return;
+ }
+
+ it_app_names = ao2_iterator_init(app_names, 0);
+ while ((app_name = ao2_iterator_next(&it_app_names))) {
+ if ((app = stasis_app_get_by_name(app_name))) {
+ stasis_app_set_debug(app, 0);
+ }
+
+ ao2_cleanup(app_name);
+ ao2_cleanup(app);
+ }
+ ao2_iterator_cleanup(&it_app_names);
+ ao2_cleanup(app_names);
}
}
@@ -949,7 +1001,6 @@ struct stasis_topic *ast_app_get_topic(struct stasis_app *app)
void app_send(struct stasis_app *app, struct ast_json *message)
{
stasis_app_cb handler;
- int debug;
char eid[20];
RAII_VAR(void *, data, NULL, ao2_cleanup);
@@ -962,7 +1013,6 @@ void app_send(struct stasis_app *app, struct ast_json *message)
/* Copy off mutable state with lock held */
{
SCOPED_AO2LOCK(lock, app);
- debug = app->debug;
handler = app->handler;
if (app->data) {
ao2_ref(app->data, +1);
@@ -971,13 +1021,6 @@ void app_send(struct stasis_app *app, struct ast_json *message)
/* Name is immutable; no need to copy */
}
- if (debug) {
- char *dump = ast_json_dump_string_format(message, AST_JSON_PRETTY);
- ast_verb(0, "Dispatching message to Stasis app '%s':\n%s\n",
- app->name, dump);
- ast_json_free(dump);
- }
-
if (!handler) {
ast_verb(3,
"Inactive Stasis app '%s' missed message\n", app->name);
@@ -1050,7 +1093,7 @@ void app_update(struct stasis_app *app, stasis_app_cb handler, void *data)
app->data = data;
}
-const char *app_name(const struct stasis_app *app)
+const char *stasis_app_name(const struct stasis_app *app)
{
return app->name;
}
@@ -1067,7 +1110,7 @@ static int forwards_filter_by_type(void *obj, void *arg, int flags)
return 0;
}
-void app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
+void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
{
struct ao2_iterator *channels;
struct ao2_iterator *endpoints;
diff --git a/res/stasis/app.h b/res/stasis/app.h
index 6ed6a295b..ac4ac59fb 100644
--- a/res/stasis/app.h
+++ b/res/stasis/app.h
@@ -109,15 +109,6 @@ int app_is_finished(struct stasis_app *app);
void app_update(struct stasis_app *app, stasis_app_cb handler, void *data);
/*!
- * \brief Return an application's name.
- *
- * \param app Application.
- * \return Name of the application.
- * \return \c NULL is \a app is \c NULL.
- */
-const char *app_name(const struct stasis_app *app);
-
-/*!
* \brief Send a message to an application.
*
* \param app Application.
@@ -137,16 +128,6 @@ struct app_forwards;
*/
struct ast_json *app_to_json(const struct stasis_app *app);
-struct ast_cli_args;
-
-/*!
- * \brief Dump properties of a \c stasis_app to the CLI
- *
- * \param app The application
- * \param a The CLI arguments
- */
-void app_to_cli(const struct stasis_app *app, struct ast_cli_args *a);
-
/*!
* \brief Subscribes an application to a channel.
*
@@ -300,12 +281,4 @@ char *app_get_replace_channel_app(struct ast_channel *chan);
*/
int app_send_end_msg(struct stasis_app *app, struct ast_channel *chan);
-/*!
- * \brief Enable/disable debugging on an application
- *
- * \param app The app to debug
- * \param debug If non-zero, enable debugging. If zero, disable.
- */
-void app_set_debug(struct stasis_app *app, int debug);
-
#endif /* _ASTERISK_RES_STASIS_APP_H */
diff --git a/res/stasis/cli.c b/res/stasis/cli.c
deleted file mode 100644
index e6065b0ac..000000000
--- a/res/stasis/cli.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2016, Digium, Inc.
- *
- * Matt Jordan <mjordan@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Stasis CLI commands.
- *
- * \author Matt Jordan <mjordan@digium.com>
- */
-
-#include "asterisk.h"
-
-#include "asterisk/cli.h"
-#include "asterisk/astobj2.h"
-
-#include "cli.h"
-#include "app.h"
-
-
-static char *ari_show_apps(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
- struct ao2_container *apps;
- struct ao2_iterator it_apps;
- char *app;
-
- switch (cmd) {
- case CLI_INIT:
- e->command = "ari show apps";
- e->usage =
- "Usage: ari show apps\n"
- " Lists all registered applications.\n"
- ;
- return NULL;
- case CLI_GENERATE:
- return NULL;
- default:
- break;
- }
-
- if (a->argc != 3) {
- return CLI_SHOWUSAGE;
- }
-
- apps = stasis_app_get_all();
- if (!apps) {
- ast_cli(a->fd, "Unable to retrieve registered applications!\n");
- return CLI_FAILURE;
- }
-
- ast_cli(a->fd, "Application Name \n");
- ast_cli(a->fd, "=========================\n");
- it_apps = ao2_iterator_init(apps, 0);
- while ((app = ao2_iterator_next(&it_apps))) {
- ast_cli(a->fd, "%-25.25s\n", app);
- ao2_ref(app, -1);
- }
-
- ao2_iterator_destroy(&it_apps);
- ao2_ref(apps, -1);
-
- return CLI_SUCCESS;
-}
-
-struct app_complete {
- /*! Nth app to search for */
- int state;
- /*! Which app currently on */
- int which;
-};
-
-static int complete_ari_app_search(void *obj, void *arg, void *data, int flags)
-{
- struct app_complete *search = data;
-
- if (++search->which > search->state) {
- return CMP_MATCH;
- }
- return 0;
-}
-
-static char *complete_ari_app(struct ast_cli_args *a)
-{
- RAII_VAR(struct ao2_container *, apps, stasis_app_get_all(), ao2_cleanup);
- RAII_VAR(char *, app, NULL, ao2_cleanup);
-
- struct app_complete search = {
- .state = a->n,
- };
-
- if (!apps) {
- ast_cli(a->fd, "Error getting ARI applications\n");
- return CLI_FAILURE;
- }
-
- app = ao2_callback_data(apps,
- ast_strlen_zero(a->word) ? 0 : OBJ_PARTIAL_KEY,
- complete_ari_app_search, (char*)a->word, &search);
-
- return app ? ast_strdup(app) : NULL;
-}
-
-static char *complete_ari_show_app(struct ast_cli_args *a)
-{
- if (a->pos == 3) {
- return complete_ari_app(a);
- }
-
- return NULL;
-}
-
-static char *ari_show_app(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
- void *app;
-
- switch (cmd) {
- case CLI_INIT:
- e->command = "ari show app";
- e->usage =
- "Usage: ari show app <application>\n"
- " Provide detailed information about a registered application.\n"
- ;
- return NULL;
- case CLI_GENERATE:
- return complete_ari_show_app(a);
- default:
- break;
- }
-
- if (a->argc != 4) {
- return CLI_SHOWUSAGE;
- }
-
- app = stasis_app_get_by_name(a->argv[3]);
- if (!app) {
- return CLI_FAILURE;
- }
-
- app_to_cli(app, a);
-
- ao2_ref(app, -1);
-
- return CLI_SUCCESS;
-}
-
-static char *ari_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
-{
- void *app;
- int debug;
-
- switch (cmd) {
- case CLI_INIT:
- e->command = "ari set debug";
- e->usage =
- "Usage: ari set debug <application> <on|off>\n"
- " Enable or disable debugging on a specific application.\n"
- ;
- return NULL;
- case CLI_GENERATE:
- return complete_ari_show_app(a);
- default:
- break;
- }
-
- if (a->argc != 5) {
- return CLI_SHOWUSAGE;
- }
-
- app = stasis_app_get_by_name(a->argv[3]);
- if (!app) {
- return CLI_FAILURE;
- }
-
- debug = !strcmp(a->argv[4], "on");
- app_set_debug(app, debug);
- ast_cli(a->fd, "Debugging on '%s' %s\n",
- app_name(app),
- debug ? "enabled" : "disabled");
-
- ao2_ref(app, -1);
-
- return CLI_SUCCESS;
-}
-
-static struct ast_cli_entry cli_ari[] = {
- AST_CLI_DEFINE(ari_show_apps, "List registered ARI applications"),
- AST_CLI_DEFINE(ari_show_app, "Display details of a registered ARI application"),
- AST_CLI_DEFINE(ari_set_debug, "Enable/disable debugging of an ARI application"),
-};
-
-
-int cli_init(void)
-{
- return ast_cli_register_multiple(cli_ari, ARRAY_LEN(cli_ari));
-}
-
-void cli_cleanup(void)
-{
- ast_cli_unregister_multiple(cli_ari, ARRAY_LEN(cli_ari));
-}
diff --git a/res/stasis/cli.h b/res/stasis/cli.h
deleted file mode 100644
index 49235c7b3..000000000
--- a/res/stasis/cli.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2016, Digium, Inc.
- *
- * Matt Jordan <mjordan@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-#ifndef _ASTERISK_RES_STASIS_CLI_H
-#define _ASTERISK_RES_STASIS_CLI_H
-
-/*! \file
- *
- * \brief Internal API for Stasis application CLI commands
- *
- * \author Matt Jordan <mjordan@digium.com>
- * \since 13.13.0
- */
-
-/*!
- * \brief Initialize the CLI commands
- *
- * \retval 0 on success
- * \retval non-zero on error
- */
-int cli_init(void);
-
-/*!
- * \brief Cleanup the CLI commands
- */
-void cli_cleanup(void);
-
-#endif /* _ASTERISK_RES_STASIS_CLI_H */
diff --git a/res/stasis/stasis_bridge.c b/res/stasis/stasis_bridge.c
index 95e549a29..7ce675cb9 100644
--- a/res/stasis/stasis_bridge.c
+++ b/res/stasis/stasis_bridge.c
@@ -155,13 +155,13 @@ static int bridge_stasis_push_peek(struct ast_bridge *self, struct ast_bridge_ch
}
to_be_replaced = ast_channel_snapshot_get_latest(ast_channel_uniqueid(swap->chan));
- ast_debug(3, "Copying stasis app name %s from %s to %s\n", app_name(control_app(swap_control)),
+ ast_debug(3, "Copying stasis app name %s from %s to %s\n", stasis_app_name(control_app(swap_control)),
ast_channel_name(swap->chan), ast_channel_name(bridge_channel->chan));
ast_channel_lock(bridge_channel->chan);
/* copy the app name from the swap channel */
- app_set_replace_channel_app(bridge_channel->chan, app_name(control_app(swap_control)));
+ app_set_replace_channel_app(bridge_channel->chan, stasis_app_name(control_app(swap_control)));
/* set the replace channel snapshot */
app_set_replace_channel_snapshot(bridge_channel->chan, to_be_replaced);
@@ -215,6 +215,7 @@ static int bridge_stasis_push(struct ast_bridge *self, struct ast_bridge_channel
*/
return -1;
}
+ ao2_cleanup(control);
/*
* If going into a holding bridge, default the role to participant, if
@@ -234,7 +235,6 @@ static int bridge_stasis_push(struct ast_bridge *self, struct ast_bridge_channel
}
}
- ao2_cleanup(control);
if (self->allowed_capabilities & STASIS_BRIDGE_MIXING_CAPABILITIES) {
ast_bridge_channel_update_linkedids(bridge_channel, swap);
if (ast_test_flag(&self->feature_flags, AST_BRIDGE_FLAG_SMART)) {
diff --git a/rest-api-templates/param_parsing.mustache b/rest-api-templates/param_parsing.mustache
index 247c121d9..d156ab799 100644
--- a/rest-api-templates/param_parsing.mustache
+++ b/rest-api-templates/param_parsing.mustache
@@ -85,21 +85,6 @@
{{/has_path_parameters}}
{{^is_websocket}}
{{#parse_body}}
- /* Look for a JSON request entity */
- body = ast_http_get_json(ser, headers);
- if (!body) {
- switch (errno) {
- case EFBIG:
- ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
- goto fin;
- case ENOMEM:
- ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
- goto fin;
- case EIO:
- ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
- goto fin;
- }
- }
{{#body_parameter}}
args.{{c_name}} = body;
{{/body_parameter}}
diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache
index d5c86158b..c28a62cd9 100644
--- a/rest-api-templates/res_ari_resource.c.mustache
+++ b/rest-api-templates/res_ari_resource.c.mustache
@@ -76,13 +76,12 @@
static void ast_ari_{{c_name}}_{{c_nickname}}_cb(
struct ast_tcptls_session_instance *ser,
struct ast_variable *get_params, struct ast_variable *path_vars,
- struct ast_variable *headers, struct ast_ari_response *response)
+ struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
{
struct ast_ari_{{c_name}}_{{c_nickname}}_args args = {};
{{#has_parameters}}
struct ast_variable *i;
{{/has_parameters}}
- RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
#if defined(AST_DEVMODE)
int is_valid;
int code;
diff --git a/tests/test_ari.c b/tests/test_ari.c
index 1bd77496f..bce5f95d6 100644
--- a/tests/test_ari.c
+++ b/tests/test_ari.c
@@ -61,6 +61,7 @@ static void handler(const char *name,
struct ast_variable *get_params,
struct ast_variable *path_vars,
struct ast_variable *headers,
+ struct ast_json *body,
struct ast_ari_response *response)
{
struct ast_json *message = ast_json_pack("{s: s, s: {}, s: {}, s: {}}",
@@ -98,9 +99,10 @@ static void handler(const char *name,
struct ast_variable *get_params, \
struct ast_variable *path_vars, \
struct ast_variable *headers, \
+ struct ast_json *body, \
struct ast_ari_response *response) \
{ \
- handler(#name, response_code, get_params, path_vars, headers, response); \
+ handler(#name, response_code, get_params, path_vars, headers, body, response); \
}
HANDLER(bang_get, 200)
@@ -343,7 +345,8 @@ AST_TEST_DEFINE(invoke_get)
"head2", "head-two",
"path_vars");
- ast_ari_invoke(NULL, "foo", AST_HTTP_GET, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo", AST_HTTP_GET, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 1 == invocation_count);
ast_test_validate(test, 200 == response->response_code);
@@ -380,7 +383,8 @@ AST_TEST_DEFINE(invoke_wildcard)
"path_vars",
"bam", "foshizzle");
- ast_ari_invoke(NULL, "foo/foshizzle", AST_HTTP_GET, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo/foshizzle", AST_HTTP_GET, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 1 == invocation_count);
ast_test_validate(test, 200 == response->response_code);
@@ -417,7 +421,8 @@ AST_TEST_DEFINE(invoke_delete)
"path_vars",
"bam", "foshizzle");
- ast_ari_invoke(NULL, "foo/foshizzle/bang", AST_HTTP_DELETE, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo/foshizzle/bang", AST_HTTP_DELETE, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 1 == invocation_count);
ast_test_validate(test, 204 == response->response_code);
@@ -467,7 +472,8 @@ AST_TEST_DEFINE(invoke_post)
"head2", "head-two",
"path_vars");
- ast_ari_invoke(NULL, "foo/bar", AST_HTTP_POST, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo/bar", AST_HTTP_POST, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 1 == invocation_count);
ast_test_validate(test, 200 == response->response_code);
@@ -496,7 +502,8 @@ AST_TEST_DEFINE(invoke_bad_post)
fixture = setup_invocation_test();
response = response_alloc();
- ast_ari_invoke(NULL, "foo", AST_HTTP_POST, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo", AST_HTTP_POST, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 0 == invocation_count);
ast_test_validate(test, 405 == response->response_code);
@@ -524,7 +531,8 @@ AST_TEST_DEFINE(invoke_not_found)
fixture = setup_invocation_test();
response = response_alloc();
- ast_ari_invoke(NULL, "foo/fizzle/i-am-not-a-resource", AST_HTTP_GET, get_params, headers, response);
+ ast_ari_invoke(NULL, "foo/fizzle/i-am-not-a-resource", AST_HTTP_GET, get_params, headers,
+ ast_json_null(), response);
ast_test_validate(test, 0 == invocation_count);
ast_test_validate(test, 404 == response->response_code);
diff --git a/tests/test_substitution.c b/tests/test_substitution.c
index ca84d0023..3a1dc1fba 100644
--- a/tests/test_substitution.c
+++ b/tests/test_substitution.c
@@ -285,7 +285,16 @@ AST_TEST_DEFINE(test_substitution)
TEST(test_expected_result(test, c, "A${${baz}o:-2:1}A", "A2A"));
TEST(test_expected_result(test, c, "A${${baz}o:-2:-1}A", "A2A"));
pbx_builtin_setvar_helper(c, "list1", "ab&cd&ef");
+ TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,ab)}", "cd&ef"));
TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,cd)}", "ab&ef"));
+ TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,ef)}", "ab&cd"));
+ TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,gh)}", "ab&cd&ef"));
+ TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,c)}", "ab&cd&ef"));
+ TEST(test_expected_result(test, c, "${LISTFILTER(list1,&,d)}", "ab&cd&ef"));
+ pbx_builtin_setvar_helper(c, "list2", "ab");
+ TEST(test_expected_result(test, c, "${LISTFILTER(list2,&,ab)}", ""));
+ pbx_builtin_setvar_helper(c, "list_empty", "");
+ TEST(test_expected_result(test, c, "${LISTFILTER(list_empty,&,ab)}", ""));
TEST(test_expected_result(test, c, "${SHELL(printf '%d' 123)},${SHELL(printf '%d' 456)}", "123,456"));
TEST(test_expected_result(test, c, "${foo},${CDR(answer)},${SHELL(printf '%d' 456)}", "123,,456"));
TEST(test_expected_result(test, c, "${foo},${CDR(answer,u)},${SHELL(printf '%d' 456)}", "123,0.000000,456"));
diff --git a/tests/test_voicemail_api.c b/tests/test_voicemail_api.c
index 77b538ef8..802b6bf1b 100644
--- a/tests/test_voicemail_api.c
+++ b/tests/test_voicemail_api.c
@@ -240,7 +240,7 @@
return AST_TEST_FAIL; \
} \
VM_API_SNAPSHOT_CREATE((mailbox), (context), (folder), 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0); \
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 0); \
+ VM_API_INT_VERIFY(0, test_mbox_snapshot->total_msg_num); \
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot); \
} while (0)
@@ -1002,10 +1002,10 @@ AST_TEST_DEFINE(voicemail_api_nominal_move)
test_vm_api_update_test_snapshots(test_mbox_snapshot);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
- VM_API_STRING_FIELD_VERIFY(test_snapshots[0]->folder_name, "Family");
- VM_API_STRING_FIELD_VERIFY(test_snapshots[1]->folder_name, "Family");
- VM_API_INT_VERIFY(test_snapshots[1]->msg_number, 0);
- VM_API_INT_VERIFY(test_snapshots[0]->msg_number, 1);
+ VM_API_STRING_FIELD_VERIFY("Family", test_snapshots[0]->folder_name);
+ VM_API_STRING_FIELD_VERIFY("Family", test_snapshots[1]->folder_name);
+ VM_API_INT_VERIFY(0, test_snapshots[1]->msg_number);
+ VM_API_INT_VERIFY(1, test_snapshots[0]->msg_number);
/* Move both of the 2345 messages to Family */
ast_test_status_update(test, "Test move of test_vm_api_2345 messages from Inbox to Family\n");
@@ -1016,8 +1016,8 @@ AST_TEST_DEFINE(voicemail_api_nominal_move)
test_vm_api_update_test_snapshots(test_mbox_snapshot);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
- VM_API_STRING_FIELD_VERIFY(test_snapshots[2]->folder_name, "Family");
- VM_API_STRING_FIELD_VERIFY(test_snapshots[3]->folder_name, "Family");
+ VM_API_STRING_FIELD_VERIFY("Family", test_snapshots[2]->folder_name);
+ VM_API_STRING_FIELD_VERIFY("Family", test_snapshots[3]->folder_name);
ast_test_status_update(test, "Test move of test_vm_api_2345 message from Family to INBOX\n");
VM_API_MOVE_MESSAGE("test_vm_api_2345", "default", 2, "Family", multi_msg_ids, "INBOX");
@@ -1026,8 +1026,8 @@ AST_TEST_DEFINE(voicemail_api_nominal_move)
test_vm_api_update_test_snapshots(test_mbox_snapshot);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
- VM_API_STRING_FIELD_VERIFY(test_snapshots[2]->folder_name, "INBOX");
- VM_API_STRING_FIELD_VERIFY(test_snapshots[3]->folder_name, "INBOX");
+ VM_API_STRING_FIELD_VERIFY("INBOX", test_snapshots[2]->folder_name);
+ VM_API_STRING_FIELD_VERIFY("INBOX", test_snapshots[3]->folder_name);
VM_API_TEST_CLEANUP;
@@ -1248,12 +1248,12 @@ AST_TEST_DEFINE(voicemail_api_nominal_forward)
/* Make sure we didn't delete the message */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 1);
+ VM_API_INT_VERIFY(1, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 3 messages in test_vm_api_2345 INBOX */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 3);
+ VM_API_INT_VERIFY(3, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_test_status_update(test, "Test forwarding message 0 from test_vm_api_1234 INBOX with default context to test_vm_api_2345 INBOX\n");
@@ -1261,12 +1261,12 @@ AST_TEST_DEFINE(voicemail_api_nominal_forward)
/* Make sure we didn't delete the message */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 1);
+ VM_API_INT_VERIFY(1, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 4 messages in test_vm_api_2345 INBOX */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 4);
+ VM_API_INT_VERIFY(4, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_test_status_update(test, "Test forwarding message 0 from test_vm_api_1234 INBOX to test_vm_api_2345 INBOX with default context\n");
@@ -1274,12 +1274,12 @@ AST_TEST_DEFINE(voicemail_api_nominal_forward)
/* Make sure we didn't delete the message */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 1);
+ VM_API_INT_VERIFY(1, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 5 messages in test_vm_api_2345 INBOX */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 5);
+ VM_API_INT_VERIFY(5, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_test_status_update(test, "Test forwarding message 0 from test_vm_api_1234 INBOX to test_vm_api_2345 INBOX, deleting original\n");
@@ -1287,12 +1287,12 @@ AST_TEST_DEFINE(voicemail_api_nominal_forward)
/* Make sure we deleted the message */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 0);
+ VM_API_INT_VERIFY(0, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 6 messages in test_vm_api_2345 INBOX */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 6);
+ VM_API_INT_VERIFY(6, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_test_status_update(test, "Test forwarding 2 messages from test_vm_api_2345 INBOX to test_vm_api_1234 INBOX");
@@ -1300,24 +1300,24 @@ AST_TEST_DEFINE(voicemail_api_nominal_forward)
/* Make sure we didn't delete the messages */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 6);
+ VM_API_INT_VERIFY(6, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 2 messages in test_vm_api_1234 INBOX */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 2);
+ VM_API_INT_VERIFY(2, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_test_status_update(test, "Test forwarding 2 messages from test_vm_api_2345 INBOX to test_vm_api_1234 Family, deleting original\n");
VM_API_FORWARD_MESSAGE("test_vm_api_2345", "default", "INBOX", "test_vm_api_1234", "default", "Family", 2, multi_msg_ids, 1);
/* Make sure we deleted the messages */
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "INBOX", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 4);
+ VM_API_INT_VERIFY(4, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
/* We should now have a total of 2 messages in test_vm_api_1234 Family */
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "Family", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 2);
+ VM_API_INT_VERIFY(2, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
VM_API_TEST_CLEANUP;
@@ -1447,20 +1447,20 @@ AST_TEST_DEFINE(voicemail_api_nominal_msg_playback)
ast_test_status_update(test, "Playing back message from test_vm_api_2345 to callback function\n");
VM_API_PLAYBACK_MESSAGE(test_channel, "test_vm_api_2345", "default", "INBOX", message_id_2345[0], &message_playback_callback_fn);
- VM_API_INT_VERIFY(global_entered_playback_callback, 1);
+ VM_API_INT_VERIFY(1, global_entered_playback_callback);
global_entered_playback_callback = 0;
ast_test_status_update(test, "Playing back message from test_vm_api_2345 to callback function with default context\n");
VM_API_PLAYBACK_MESSAGE(test_channel, "test_vm_api_2345", NULL, "INBOX", message_id_2345[1], &message_playback_callback_fn);
- VM_API_INT_VERIFY(global_entered_playback_callback, 1);
+ VM_API_INT_VERIFY(1, global_entered_playback_callback);
global_entered_playback_callback = 0;
VM_API_SNAPSHOT_CREATE("test_vm_api_1234", "default", "Old", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 2);
+ VM_API_INT_VERIFY(2, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
VM_API_SNAPSHOT_CREATE("test_vm_api_2345", "default", "Old", 0, AST_VM_SNAPSHOT_SORT_BY_TIME, 0);
- VM_API_INT_VERIFY(test_mbox_snapshot->total_msg_num, 2);
+ VM_API_INT_VERIFY(2, test_mbox_snapshot->total_msg_num);
test_mbox_snapshot = ast_vm_mailbox_snapshot_destroy(test_mbox_snapshot);
ast_hangup(test_channel);
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
index 2398ec428..bfd1c27fc 100644
--- a/third-party/pjproject/Makefile
+++ b/third-party/pjproject/Makefile
@@ -187,13 +187,11 @@ source/pjsip-apps/lib/libasterisk_malloc_debug.a: source/pjsip-apps/lib/asterisk
$(CMD_PREFIX) ar qs $@ $< >/dev/null 2>&1
$(apps): APP = $(filter pj%,$(subst -, ,$(notdir $@)))
-$(apps): CFLAGS += -DPJ_LOG_MAX_LEVEL=2
$(apps): LDFLAGS += $(MALLOC_DEBUG_LDFLAGS)
$(apps): $(MALLOC_DEBUG_LIBS) pjproject.symbols $(APP_THIRD_PARTY_LIB_FILES)
$(ECHO_PREFIX) Compiling $(APP)
$(CMD_PREFIX) +$(MAKE) -C source/pjsip-apps/build $(filter pj%,$(subst -, ,$(notdir $@))) $(REALLY_QUIET)
-source/pjsip-apps/src/python/_pjsua.o: CFLAGS += -DPJ_LOG_MAX_LEVEL=2
source/pjsip-apps/src/python/_pjsua.o: source/pjsip-apps/src/python/_pjsua.c $(apps)
$(ECHO_PREFIX) Compiling python bindings
$(CMD_PREFIX) $(CC) -o $@ -c $< $(PYTHONDEV_INCLUDE) $(CFLAGS) $(PJ_CFLAGS)
diff --git a/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch b/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch
new file mode 100644
index 000000000..fc0f57023
--- /dev/null
+++ b/third-party/pjproject/patches/0000-set_apps_initial_log_level.patch
@@ -0,0 +1,39 @@
+diff --git a/pjsip-apps/src/pjsua/main.c b/pjsip-apps/src/pjsua/main.c
+index 2baaf82..11831f2 100644
+--- a/pjsip-apps/src/pjsua/main.c
++++ b/pjsip-apps/src/pjsua/main.c
+@@ -126,5 +126,7 @@ int main_func(int argc, char *argv[])
+
+ int main(int argc, char *argv[])
+ {
++ pj_log_set_level(1);
++
+ return pj_run_app(&main_func, argc, argv, 0);
+ }
+diff --git a/pjsip-apps/src/pjsystest/main_console.c b/pjsip-apps/src/pjsystest/main_console.c
+index 122cdc7..dc79eab 100644
+--- a/pjsip-apps/src/pjsystest/main_console.c
++++ b/pjsip-apps/src/pjsystest/main_console.c
+@@ -133,6 +133,8 @@ void gui_sleep(unsigned sec)
+
+ int main()
+ {
++ pj_log_set_level(1);
++
+ if (systest_init() != PJ_SUCCESS)
+ return 1;
+
+diff --git a/pjsip-apps/src/python/_pjsua.c b/pjsip-apps/src/python/_pjsua.c
+index fb80e23..c9b21d8 100644
+--- a/pjsip-apps/src/python/_pjsua.c
++++ b/pjsip-apps/src/python/_pjsua.c
+@@ -4437,7 +4437,8 @@ init_pjsua(void)
+ PyObject* m = NULL;
+ #define ADD_CONSTANT(mod,name) PyModule_AddIntConstant(mod,#name,name)
+
+-
++ pj_log_set_level(1);
++
+ PyEval_InitThreads();
+
+ if (PyType_Ready(&PyTyp_pjsua_callback) < 0)