diff options
57 files changed, 1560 insertions, 1309 deletions
@@ -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) |