From d9b06a0b219602be8252201ca61ca8107a3fd49f Mon Sep 17 00:00:00 2001 From: Sebastian Kemper Date: Fri, 11 Oct 2019 18:17:38 +0200 Subject: [PATCH] asterisk-16.x: bump to 16.6.0 Also adds two new modules, app-attended-transfer and app-blind-transfer. Patches refreshed, the ones that are part of the source tarball are dropped. Signed-off-by: Sebastian Kemper --- net/asterisk-16.x/Makefile | 10 +- ...semaphores-on-uclibc-otherwise-allow.patch | 2 +- ...tection-of-re-entrant-resolver-funct.patch | 2 +- net/asterisk-16.x/patches/120-loader.patch | 247 ------------------ net/asterisk-16.x/patches/130-eventfd.patch | 2 +- .../patches/140-AST-2019-002-16.diff | 40 --- .../patches/150-AST-2019-003-16.diff | 39 --- .../patches/160-AST-2019-004-16.patch | 171 ------------ 8 files changed, 10 insertions(+), 503 deletions(-) delete mode 100644 net/asterisk-16.x/patches/120-loader.patch delete mode 100644 net/asterisk-16.x/patches/140-AST-2019-002-16.diff delete mode 100644 net/asterisk-16.x/patches/150-AST-2019-003-16.diff delete mode 100644 net/asterisk-16.x/patches/160-AST-2019-004-16.patch diff --git a/net/asterisk-16.x/Makefile b/net/asterisk-16.x/Makefile index b8682df..0bf68a9 100644 --- a/net/asterisk-16.x/Makefile +++ b/net/asterisk-16.x/Makefile @@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk AST_MAJOR_VERSION:=16 PKG_NAME:=asterisk$(AST_MAJOR_VERSION) -PKG_VERSION:=$(AST_MAJOR_VERSION).3.0 -PKG_RELEASE:=8 +PKG_VERSION:=$(AST_MAJOR_VERSION).6.0 +PKG_RELEASE:=1 PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases -PKG_HASH:=8b22ee7c0c0b5557eff273118703c6fce8b743c12bbeb679ed86b3f197444a8e +PKG_HASH:=2cbc23c9dcd316c35e51fa16b7d1dbcd31f19d2509d1a910b61d6839ccd56384 PKG_BUILD_DIR:=$(BUILD_DIR)/asterisk-$(PKG_VERSION) PKG_BUILD_DEPENDS:=libxml2/host @@ -43,7 +43,9 @@ MODULES_AVAILABLE:= \ app-agent-pool \ app-alarmreceiver \ app-amd \ + app-attended-transfer \ app-authenticate \ + app-blind-transfer \ app-bridgeaddchan \ app-bridgewait \ app-celgenuserevent \ @@ -757,7 +759,9 @@ $(eval $(call BuildAsteriskModule,app-adsiprog,ADSI programming,Asterisk ADSI pr $(eval $(call BuildAsteriskModule,app-agent-pool,Call center agent pool,Call center agent pool applications.,,agents.conf,app_agent_pool,,)) $(eval $(call BuildAsteriskModule,app-alarmreceiver,Alarm receiver,Alarm receiver for Asterisk.,,,app_alarmreceiver,,)) $(eval $(call BuildAsteriskModule,app-amd,Answering machine detection,Answering Machine Detection application.,,amd.conf,app_amd,,)) +$(eval $(call BuildAsteriskModule,app-attended-transfer,Attended transfer,Queues up an attended transfer to a given extension.,,,app_attended_transfer,,)) $(eval $(call BuildAsteriskModule,app-authenticate,Authenticate commands,Authentication application.,,,app_authenticate,,)) +$(eval $(call BuildAsteriskModule,app-blind-transfer,Blind transfer,Redirects all channels currently bridged to the caller channel to a specified destination.,,,app_blind_transfer,,)) $(eval $(call BuildAsteriskModule,app-bridgeaddchan,Bridge add channel,Bridge-add-channel application.,,,app_bridgeaddchan,,)) $(eval $(call BuildAsteriskModule,app-bridgewait,Holding bridge,Application to place a channel into a holding bridge.,+$(PKG_NAME)-bridge-holding,,app_bridgewait,,)) $(eval $(call BuildAsteriskModule,app-celgenuserevent,User-defined CEL event,Generate a user defined CEL event.,,,app_celgenuserevent,,)) diff --git a/net/asterisk-16.x/patches/001-disable-semaphores-on-uclibc-otherwise-allow.patch b/net/asterisk-16.x/patches/001-disable-semaphores-on-uclibc-otherwise-allow.patch index 7485608..c295cc6 100644 --- a/net/asterisk-16.x/patches/001-disable-semaphores-on-uclibc-otherwise-allow.patch +++ b/net/asterisk-16.x/patches/001-disable-semaphores-on-uclibc-otherwise-allow.patch @@ -1,6 +1,6 @@ --- a/configure.ac +++ b/configure.ac -@@ -1018,15 +1018,18 @@ AC_LINK_IFELSE( +@@ -1033,15 +1033,18 @@ AC_LINK_IFELSE( # Some platforms define sem_init(), but only support sem_open(). joyous. AC_MSG_CHECKING(for working unnamed semaphores) diff --git a/net/asterisk-16.x/patches/002-configure-fix-detection-of-re-entrant-resolver-funct.patch b/net/asterisk-16.x/patches/002-configure-fix-detection-of-re-entrant-resolver-funct.patch index e35ef4c..c7b91e7 100644 --- a/net/asterisk-16.x/patches/002-configure-fix-detection-of-re-entrant-resolver-funct.patch +++ b/net/asterisk-16.x/patches/002-configure-fix-detection-of-re-entrant-resolver-funct.patch @@ -18,7 +18,7 @@ Signed-off-by: Bernd Kuhls --- a/configure.ac +++ b/configure.ac -@@ -1412,7 +1412,11 @@ AC_LINK_IFELSE( +@@ -1427,7 +1427,11 @@ AC_LINK_IFELSE( #include #endif #include ], diff --git a/net/asterisk-16.x/patches/120-loader.patch b/net/asterisk-16.x/patches/120-loader.patch deleted file mode 100644 index c9dd9f2..0000000 --- a/net/asterisk-16.x/patches/120-loader.patch +++ /dev/null @@ -1,247 +0,0 @@ -commit 02fda2b478f98cf3b8a1df76f772bf0be73bddd5 -Author: Sebastian Kemper -Date: Tue Apr 2 22:49:52 2019 +0200 - - loader: support for permanent dlopen() - - Asterisk assumes that dlopen() will always run the constructor of a - shared library and every dlclose() will run its destructor. But dlopen() - may be permanent, meaning the constructor will only be run once, as is - the case with musl libc. - - With a permanent dlopen() the Asterisk module loader does not work - correctly, because it's expectations regarding when the constructors and - destructors are run are not met. In fact a segmentation fault will occur - when the first module is "re-opened" that has AST_MODFLAG_GLOBAL_SYMBOLS - set (the dlopen() does not call the constructor, resource_being_loaded - is not set to NULL, then strlen is called with NULL instead of a string, - see issue ASTERISK-28319). - - This commit adds code to the loader that will manually run the - constructors/destructors of the (non-builtin) modules where needed. To - achieve this a new ao2 container (linked list) is started and filled - with objects that contain the names of the modules and the pointers to - their respective info structs. - - This behavior can be activated when configuring Asterisk - (--enable-permanent-dlopen). By default this is disabled, of course. - - ASTERISK-28319 #close - - Signed-off-by: Sebastian Kemper - Change-Id: I86693a0ecf25d5ba81c73773a03df4abc3426875 - ---- a/configure.ac -+++ b/configure.ac -@@ -727,6 +727,20 @@ if test "${DISABLE_XMLDOC}" != "yes"; th - - fi - -+AC_ARG_ENABLE([permanent-dlopen], -+ [AS_HELP_STRING([--enable-permanent-dlopen], -+ [Enable when your libc has a permanent dlopen like musl])], -+ [case "${enableval}" in -+ y|ye|yes) PERMANENT_DLOPEN=yes ;; -+ n|no) PERMANENT_DLOPEN=no ;; -+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-permanent-dlopen) ;; -+ esac], [PERMANENT_DLOPEN=no]) -+ -+AC_SUBST([PERMANENT_DLOPEN]) -+if test "${PERMANENT_DLOPEN}" == "yes"; then -+ AC_DEFINE([HAVE_PERMANENT_DLOPEN], 1, [Define to support libc with permanent dlopen.]) -+fi -+ - # some embedded systems omit internationalization (locale) support - AC_CHECK_HEADERS([xlocale.h]) - ---- a/main/loader.c -+++ b/main/loader.c -@@ -153,6 +153,117 @@ static unsigned int loader_ready; - static struct ast_vector_string startup_errors; - static struct ast_str *startup_error_builder; - -+#if defined(HAVE_PERMANENT_DLOPEN) -+#define FIRST_DLOPEN 999 -+ -+struct ao2_container *info_list = NULL; -+ -+struct info_list_obj { -+ const struct ast_module_info *info; -+ int dlopened; -+ char name[0]; -+}; -+ -+static struct info_list_obj *info_list_obj_alloc(const char *name, -+ const struct ast_module_info *info) -+{ -+ struct info_list_obj *new_entry; -+ -+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL); -+ -+ if (!new_entry) { -+ return NULL; -+ } -+ -+ strcpy(new_entry->name, name); /* SAFE */ -+ new_entry->info = info; -+ new_entry->dlopened = FIRST_DLOPEN; -+ -+ return new_entry; -+} -+ -+AO2_STRING_FIELD_CMP_FN(info_list_obj, name) -+ -+static char *get_name_from_resource(const char *resource) -+{ -+ int len; -+ const char *last_three; -+ char *mod_name; -+ -+ if (!resource) { -+ return NULL; -+ } -+ -+ len = strlen(resource); -+ if (len > 3) { -+ last_three = &resource[len-3]; -+ if (!strcasecmp(last_three, ".so")) { -+ mod_name = ast_calloc(1, len - 2); -+ if (mod_name) { -+ ast_copy_string(mod_name, resource, len - 2); -+ return mod_name; -+ } else { -+ /* Unable to allocate memory. */ -+ return NULL; -+ } -+ } -+ } -+ -+ /* Resource is the name - happens when manually unloading a module. */ -+ mod_name = ast_calloc(1, len + 1); -+ if (mod_name) { -+ ast_copy_string(mod_name, resource, len + 1); -+ return mod_name; -+ } -+ -+ /* Unable to allocate memory. */ -+ return NULL; -+} -+ -+static void manual_mod_reg(const void *lib, const char *resource) -+{ -+ struct info_list_obj *obj_tmp; -+ char *mod_name; -+ -+ if (lib) { -+ mod_name = get_name_from_resource(resource); -+ if (mod_name) { -+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY); -+ if (obj_tmp) { -+ if (obj_tmp->dlopened == FIRST_DLOPEN) { -+ obj_tmp->dlopened = 1; -+ } else { -+ ast_module_register(obj_tmp->info); -+ } -+ ao2_ref(obj_tmp, -1); -+ } -+ ast_free(mod_name); -+ } -+ } -+} -+ -+static void manual_mod_unreg(const char *resource) -+{ -+ struct info_list_obj *obj_tmp; -+ char *mod_name; -+ -+ /* When Asterisk shuts down the destructor is called automatically. */ -+ if (ast_shutdown_final()) { -+ return; -+ } -+ -+ mod_name = get_name_from_resource(resource); -+ if (mod_name) { -+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY); -+ if (obj_tmp) { -+ ast_module_unregister(obj_tmp->info); -+ ao2_ref(obj_tmp, -1); -+ } -+ ast_free(mod_name); -+ } -+} -+#endif -+ - static __attribute__((format(printf, 1, 2))) void module_load_error(const char *fmt, ...) - { - char *copy = NULL; -@@ -597,6 +708,23 @@ void ast_module_register(const struct as - - /* give the module a copy of its own handle, for later use in registrations and the like */ - *((struct ast_module **) &(info->self)) = mod; -+ -+#if defined(HAVE_PERMANENT_DLOPEN) -+ if (mod->flags.builtin != 1) { -+ struct info_list_obj *obj_tmp = ao2_find(info_list, info->name, -+ OBJ_SEARCH_KEY); -+ -+ if (!obj_tmp) { -+ obj_tmp = info_list_obj_alloc(info->name, info); -+ if (obj_tmp) { -+ ao2_link(info_list, obj_tmp); -+ ao2_ref(obj_tmp, -1); -+ } -+ } else { -+ ao2_ref(obj_tmp, -1); -+ } -+ } -+#endif - } - - static int module_post_register(struct ast_module *mod) -@@ -843,6 +971,10 @@ static void logged_dlclose(const char *n - error = dlerror(); - ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n", - S_OR(name, "unknown"), S_OR(error, "Unknown error")); -+#if defined(HAVE_PERMANENT_DLOPEN) -+ } else { -+ manual_mod_unreg(name); -+#endif - } - } - -@@ -949,6 +1081,9 @@ static struct ast_module *load_dlopen(co - - resource_being_loaded = mod; - mod->lib = dlopen(filename, flags); -+#if defined(HAVE_PERMANENT_DLOPEN) -+ manual_mod_reg(mod->lib, mod->resource); -+#endif - if (resource_being_loaded) { - struct ast_str *list; - int c = 0; -@@ -968,6 +1103,9 @@ static struct ast_module *load_dlopen(co - - resource_being_loaded = mod; - mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); -+#if defined(HAVE_PERMANENT_DLOPEN) -+ manual_mod_reg(mod->lib, mod->resource); -+#endif - if (resource_being_loaded) { - resource_being_loaded = NULL; - -@@ -2206,6 +2344,15 @@ int load_modules(void) - - ast_verb(1, "Asterisk Dynamic Loader Starting:\n"); - -+#if defined(HAVE_PERMANENT_DLOPEN) -+ info_list = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, -+ info_list_obj_cmp_fn); /* must not be cleaned at shutdown */ -+ if (!info_list) { -+ fprintf(stderr, "Module info list allocation failure.\n"); -+ return 1; -+ } -+#endif -+ - AST_LIST_HEAD_INIT_NOLOCK(&load_order); - AST_DLLIST_LOCK(&module_list); - diff --git a/net/asterisk-16.x/patches/130-eventfd.patch b/net/asterisk-16.x/patches/130-eventfd.patch index c783a52..de4441b 100644 --- a/net/asterisk-16.x/patches/130-eventfd.patch +++ b/net/asterisk-16.x/patches/130-eventfd.patch @@ -1,6 +1,6 @@ --- a/configure.ac +++ b/configure.ac -@@ -1205,7 +1205,7 @@ if test "${ac_cv_have_variable_fdset}x" +@@ -1206,7 +1206,7 @@ if test "${ac_cv_have_variable_fdset}x" fi AC_MSG_CHECKING([if we have usable eventfd support]) diff --git a/net/asterisk-16.x/patches/140-AST-2019-002-16.diff b/net/asterisk-16.x/patches/140-AST-2019-002-16.diff deleted file mode 100644 index 635d837..0000000 --- a/net/asterisk-16.x/patches/140-AST-2019-002-16.diff +++ /dev/null @@ -1,40 +0,0 @@ -From 785bf3a755e47d92caef110e6040295764d08127 Mon Sep 17 00:00:00 2001 -From: George Joseph -Date: Wed, 12 Jun 2019 12:03:04 -0600 -Subject: [PATCH] res_pjsip_messaging: Check for body in in-dialog message - -We now check that a body exists and it has a length > 0 before -attempting to process it. - -ASTERISK-28447 -Reported-by: Gil Richard - -Change-Id: Ic469544b22ab848734636588d4c93426cc6f4b1f ---- - res/res_pjsip_messaging.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c -index 0e10a8f047..930cf84a53 100644 ---- a/res/res_pjsip_messaging.c -+++ b/res/res_pjsip_messaging.c -@@ -90,10 +90,13 @@ static enum pjsip_status_code check_content_type_in_dialog(const pjsip_rx_data * - static const pj_str_t text = { "text", 4}; - static const pj_str_t application = { "application", 11}; - -+ if (!(rdata->msg_info.msg->body && rdata->msg_info.msg->body->len > 0)) { -+ return res; -+ } -+ - /* We'll accept any text/ or application/ content type */ -- if (rdata->msg_info.msg->body && rdata->msg_info.msg->body->len -- && (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0 -- || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0)) { -+ if (pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &text) == 0 -+ || pj_stricmp(&rdata->msg_info.msg->body->content_type.type, &application) == 0) { - res = PJSIP_SC_OK; - } else if (rdata->msg_info.ctype - && (pj_stricmp(&rdata->msg_info.ctype->media.type, &text) == 0 --- -2.21.0 - diff --git a/net/asterisk-16.x/patches/150-AST-2019-003-16.diff b/net/asterisk-16.x/patches/150-AST-2019-003-16.diff deleted file mode 100644 index 90b9d5d..0000000 --- a/net/asterisk-16.x/patches/150-AST-2019-003-16.diff +++ /dev/null @@ -1,39 +0,0 @@ -From 1e4df0215af4f192ed06a7fc7589c799f1ec6091 Mon Sep 17 00:00:00 2001 -From: Francesco Castellano -Date: Fri, 28 Jun 2019 18:15:31 +0200 -Subject: [PATCH] chan_sip: Handle invalid SDP answer to T.38 re-invite - -The chan_sip module performs a T.38 re-invite using a single media -stream of udptl, and expects the SDP answer to be the same. - -If an SDP answer is received instead that contains an additional -media stream with no joint codec a crash will occur as the code -assumes that at least one joint codec will exist in this -scenario. - -This change removes this assumption. - -ASTERISK-28465 - -Change-Id: I8b02845b53344c6babe867a3f0a5231045c7ac87 ---- - -diff --git a/channels/chan_sip.c b/channels/chan_sip.c -index 898b646..a609ff8 100644 ---- a/channels/chan_sip.c -+++ b/channels/chan_sip.c -@@ -10965,7 +10965,13 @@ - ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0)); - } - -- if (portno != -1 || vportno != -1 || tportno != -1) { -+ /* When UDPTL is negotiated it is expected that there are no compatible codecs as audio or -+ * video is not being transported, thus we continue in this function further up if that is -+ * the case. If we receive an SDP answer containing both a UDPTL stream and another media -+ * stream however we need to check again to ensure that there is at least one joint codec -+ * instead of assuming there is one. -+ */ -+ if ((portno != -1 || vportno != -1 || tportno != -1) && ast_format_cap_count(newjointcapability)) { - /* We are now ready to change the sip session and RTP structures with the offered codecs, since - they are acceptable */ - unsigned int framing; diff --git a/net/asterisk-16.x/patches/160-AST-2019-004-16.patch b/net/asterisk-16.x/patches/160-AST-2019-004-16.patch deleted file mode 100644 index b97b911..0000000 --- a/net/asterisk-16.x/patches/160-AST-2019-004-16.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 69ed619a6d9b64a297d3099b6455756912e21d0b Mon Sep 17 00:00:00 2001 -From: Kevin Harwell -Date: Tue, 20 Aug 2019 15:05:45 -0500 -Subject: [PATCH] AST-2019-004 - res_pjsip_t38.c: Add NULL checks before using session media - -After receiving a 200 OK with a declined stream in response to a T.38 -initiated re-invite Asterisk would crash when attempting to dereference -a NULL session media object. - -This patch checks to make sure the session media object is not NULL before -attempting to use it. - -ASTERISK-28495 -patches: - ast-2019-004.patch submitted by Alexei Gradinari (license 5691) - -Change-Id: I168f45f4da29cfe739acf87e597baa2aae7aa572 ---- - -diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c -index 11804e2..e5c6090 100644 ---- a/res/res_pjsip_t38.c -+++ b/res/res_pjsip_t38.c -@@ -203,7 +203,6 @@ - { - RAII_VAR(struct ast_sip_session *, session, obj, ao2_cleanup); - RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "t38"), ao2_cleanup); -- struct ast_sip_session_media *session_media; - - if (!datastore) { - return 0; -@@ -212,8 +211,7 @@ - ast_debug(2, "Automatically rejecting T.38 request on channel '%s'\n", - session->channel ? ast_channel_name(session->channel) : ""); - -- session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(session, session_media, datastore->data, T38_REJECTED); -+ t38_change_state(session, NULL, datastore->data, T38_REJECTED); - ast_sip_session_resume_reinvite(session); - - return 0; -@@ -322,28 +320,37 @@ - int index; - - session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(session, session_media, state, T38_ENABLED); -+ if (!session_media) { -+ ast_log(LOG_WARNING, "Received %d response to T.38 re-invite on '%s' but no active session media\n", -+ status.code, session->channel ? ast_channel_name(session->channel) : "unknown channel"); -+ } else { -+ t38_change_state(session, session_media, state, T38_ENABLED); - -- /* Stop all the streams in the stored away active state, they'll go back to being active once -- * we reinvite back. -- */ -- for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) { -- struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index); -+ /* Stop all the streams in the stored away active state, they'll go back to being active once -+ * we reinvite back. -+ */ -+ for (index = 0; index < AST_VECTOR_SIZE(&state->media_state->sessions); ++index) { -+ struct ast_sip_session_media *session_media = AST_VECTOR_GET(&state->media_state->sessions, index); - -- if (session_media && session_media->handler && session_media->handler->stream_stop) { -- session_media->handler->stream_stop(session_media); -+ if (session_media && session_media->handler && session_media->handler->stream_stop) { -+ session_media->handler->stream_stop(session_media); -+ } - } -+ -+ return 0; - } - } else { - session_media = session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(session, session_media, state, T38_REJECTED); -- -- /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */ -- ast_sip_session_media_state_free(state->media_state); -- state->media_state = NULL; -- ast_sip_session_media_state_reset(session->pending_media_state); - } - -+ /* If no session_media then response contained a declined stream, so disable */ -+ t38_change_state(session, NULL, state, session_media ? T38_REJECTED : T38_DISABLED); -+ -+ /* Abort this attempt at switching to T.38 by resetting the pending state and freeing our stored away active state */ -+ ast_sip_session_media_state_free(state->media_state); -+ state->media_state = NULL; -+ ast_sip_session_media_state_reset(session->pending_media_state); -+ - return 0; - } - -@@ -426,12 +433,10 @@ - /* Negotiation can not take place without a valid max_ifp value. */ - if (!parameters->max_ifp) { - if (data->session->t38state == T38_PEER_REINVITE) { -- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(data->session, session_media, state, T38_REJECTED); -+ t38_change_state(data->session, NULL, state, T38_REJECTED); - ast_sip_session_resume_reinvite(data->session); - } else if (data->session->t38state == T38_ENABLED) { -- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(data->session, session_media, state, T38_DISABLED); -+ t38_change_state(data->session, NULL, state, T38_DISABLED); - ast_sip_session_refresh(data->session, NULL, NULL, NULL, - AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state); - state->media_state = NULL; -@@ -454,6 +459,11 @@ - state->our_parms.version = MIN(state->our_parms.version, state->their_parms.version); - state->our_parms.rate_management = state->their_parms.rate_management; - session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -+ if (!session_media) { -+ ast_log(LOG_ERROR, "Failed to negotiate parameters for reinvite on channel '%s' (No pending session media).\n", -+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel"); -+ break; -+ } - ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp); - t38_change_state(data->session, session_media, state, T38_ENABLED); - ast_sip_session_resume_reinvite(data->session); -@@ -468,8 +478,13 @@ - } - state->our_parms = *parameters; - session_media = media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -+ if (!session_media) { -+ ast_log(LOG_ERROR, "Failed to negotiate parameters on channel '%s' (No default session media).\n", -+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel"); -+ break; -+ } - ast_udptl_set_local_max_ifp(session_media->udptl, state->our_parms.max_ifp); -- t38_change_state(data->session, session_media, state, T38_LOCAL_REINVITE); -+ t38_change_state(data->session, NULL, state, T38_LOCAL_REINVITE); - ast_sip_session_refresh(data->session, NULL, t38_reinvite_sdp_cb, t38_reinvite_response_cb, - AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, media_state); - } -@@ -478,12 +493,10 @@ - case AST_T38_REFUSED: - case AST_T38_REQUEST_TERMINATE: /* Shutdown T38 */ - if (data->session->t38state == T38_PEER_REINVITE) { -- session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(data->session, session_media, state, T38_REJECTED); -+ t38_change_state(data->session, NULL, state, T38_REJECTED); - ast_sip_session_resume_reinvite(data->session); - } else if (data->session->t38state == T38_ENABLED) { -- session_media = data->session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -- t38_change_state(data->session, session_media, state, T38_DISABLED); -+ t38_change_state(data->session, NULL, state, T38_DISABLED); - ast_sip_session_refresh(data->session, NULL, NULL, NULL, AST_SIP_SESSION_REFRESH_METHOD_INVITE, 1, state->media_state); - state->media_state = NULL; - } -@@ -493,6 +506,11 @@ - - if (data->session->t38state == T38_PEER_REINVITE) { - session_media = data->session->pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE]; -+ if (!session_media) { -+ ast_log(LOG_ERROR, "Failed to request parameters for reinvite on channel '%s' (No pending session media).\n", -+ data->session->channel ? ast_channel_name(data->session->channel) : "unknown channel"); -+ break; -+ } - parameters.max_ifp = ast_udptl_get_far_max_ifp(session_media->udptl); - parameters.request_response = AST_T38_REQUEST_NEGOTIATE; - ast_queue_control_data(data->session->channel, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); -@@ -788,7 +806,7 @@ - - if ((session->t38state == T38_REJECTED) || (session->t38state == T38_DISABLED)) { - ast_debug(3, "Declining; T.38 state is rejected or declined\n"); -- t38_change_state(session, session_media, state, T38_DISABLED); -+ t38_change_state(session, NULL, state, T38_DISABLED); - return 0; - } - -- 2.30.2