diff -ruN pjproject-2.10/pjsip/include/pjsip/sip_msg.h pjsip/pjsip/include/pjsip/sip_msg.h
--- pjproject-2.10/pjsip/include/pjsip/sip_msg.h	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/include/pjsip/sip_msg.h	2021-02-06 19:48:20.570302003 +0100
@@ -675,6 +675,23 @@
 };
 
 /**
+ * General purpose function to print a SIP message body.
+ * Uses the appropriate internal functions to print the string representation
+ * of a SIP message body. It sets the output buffer to a statically allocated
+ * buffer, so the caller is responsible to copy it.
+ *
+ * @param msg_body     The message body.
+ * @param buf          Pointer to get the result buffer (statically allocated).
+ * @param size         The size of the buffer.
+ *
+ * @return             The length copied to the buffer, or -1.
+ */
+PJ_DECL(int) pjsip_print_body( pjsip_msg_body *msg_body,
+                                   char **buf, int *len);
+
+
+
+/**
  * General purpose function to textual data in a SIP body. Attach this function
  * in a SIP message body only if the data in pjsip_msg_body is a textual 
  * message ready to be embedded in a SIP message. If the data in the message
@@ -894,6 +911,20 @@
 PJ_DECL(void*)  pjsip_msg_find_remove_hdr( pjsip_msg *msg, 
 					   pjsip_hdr_e hdr, void *start);
 
+/**
+ * Find and remove a header in the message.
+ *
+ * @param msg      The message.
+ * @param name     The header name to find.
+ * @param start            The first header field where the search should begin,
+ *                 or NULL to search from the first header in the message.
+ *
+ * @return         The header field, or NULL if not found.
+ */
+PJ_DECL(void*)  pjsip_msg_find_remove_hdr_by_name( pjsip_msg *msg,
+                                                   pj_str_t *name,
+                                                   void *start);
+
 /** 
  * Add a header to the message, putting it last in the header list.
  *
diff -ruN pjproject-2.10/pjsip/include/pjsip-simple/evsub.h pjsip/pjsip/include/pjsip-simple/evsub.h
--- pjproject-2.10/pjsip/include/pjsip-simple/evsub.h	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/include/pjsip-simple/evsub.h	2021-02-06 19:49:09.127691820 +0100
@@ -524,6 +524,18 @@
 					 pj_uint32_t seconds);
 
 
+/* Update evbsub internal refresh_time with the given interval */
+PJ_DECL(void) pjsip_evsub_update_expires( pjsip_evsub *sub,
+                                          pj_uint32_t interval );
+
+
+/* Set the specified timer (UAC or UAS) to the specified time */
+PJ_DECL(void) pjsip_evsub_set_timer( pjsip_evsub *sub,
+                                     int timer_id,
+                                     pj_int32_t seconds );
+
+
+
 PJ_END_DECL
 
 /**
diff -ruN pjproject-2.10/pjsip/src/pjsip/sip_msg.c pjsip/pjsip/src/pjsip/sip_msg.c
--- pjproject-2.10/pjsip/src/pjsip/sip_msg.c	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/src/pjsip/sip_msg.c	2021-02-06 19:39:21.510782607 +0100
@@ -394,6 +394,18 @@
     return hdr;
 }
 
+PJ_DEF(void*) pjsip_msg_find_remove_hdr_by_name( pjsip_msg *msg,
+                                                 pj_str_t *name,
+                                                 void *start)
+{
+    pjsip_hdr *hdr = (pjsip_hdr*) pjsip_msg_find_hdr_by_name(msg, name, start);
+    if (hdr) {
+       pj_list_erase(hdr);
+    }
+    return hdr;
+}
+
+
 PJ_DEF(pj_ssize_t) pjsip_msg_print( const pjsip_msg *msg, 
 				    char *buf, pj_size_t size)
 {
@@ -2146,6 +2158,21 @@
 /*
  * Message body manipulations.
  */
+
+PJ_DEF(int) pjsip_print_body(pjsip_msg_body *msg_body, char **buf, int *len)
+{
+    static char s_buf[PJSIP_MAX_PKT_LEN];
+    int res;
+
+    res = (*msg_body->print_body)(msg_body, s_buf, PJSIP_MAX_PKT_LEN);
+    if (res < 0) {
+        return -1;
+    }
+    *buf = s_buf;
+    *len = res;
+    return 0;
+}
+
 PJ_DEF(int) pjsip_print_text_body(pjsip_msg_body *msg_body, char *buf, pj_size_t size)
 {
     if (size < msg_body->len)
diff -ruN pjproject-2.10/pjsip/src/pjsip-simple/evsub.c pjsip/pjsip/src/pjsip-simple/evsub.c
--- pjproject-2.10/pjsip/src/pjsip-simple/evsub.c	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/src/pjsip-simple/evsub.c	2021-02-06 19:40:40.321065814 +0100
@@ -495,6 +495,12 @@
 }
 
 
+PJ_DEF(void) pjsip_evsub_update_expires( pjsip_evsub *sub, pj_uint32_t interval )
+{
+    update_expires(sub, interval);
+}
+
+
 /* 
  * Schedule timer.
  */
@@ -538,6 +544,13 @@
 }
 
 
+PJ_DEF(void) pjsip_evsub_set_timer( pjsip_evsub *sub, int timer_id,
+                                   pj_int32_t seconds)
+{
+    set_timer(sub, timer_id, seconds);
+}
+
+
 /*
  * Destructor.
  */
diff -ruN pjproject-2.10/pjsip/src/pjsip-simple/evsub_msg.c pjsip/pjsip/src/pjsip-simple/evsub_msg.c
--- pjproject-2.10/pjsip/src/pjsip-simple/evsub_msg.c	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/src/pjsip-simple/evsub_msg.c	2021-02-06 19:41:44.190911650 +0100
@@ -293,6 +293,45 @@
 }
 
 /*
+ * Parse Allow-Events header.
+ */
+static pjsip_hdr* parse_hdr_allow_events(pjsip_parse_ctx *ctx)
+{
+    pjsip_allow_events_hdr *allow_events =
+             pjsip_allow_events_hdr_create(ctx->pool);
+    const pjsip_parser_const_t *pc = pjsip_parser_const();
+    pj_scanner *scanner = ctx->scanner;
+
+    /* Some header fields allow empty elements in the value:
+     *   Accept, Allow, Supported
+     */
+    if (pj_scan_is_eof(scanner) ||
+    *scanner->curptr == '\r' || *scanner->curptr == '\n')
+    {
+    goto end;
+    }
+
+    pj_scan_get( scanner, &pc->pjsip_NOT_COMMA_OR_NEWLINE,
+             &allow_events->values[0]);
+    allow_events->count++;
+
+    while (*scanner->curptr == ',') {
+    pj_scan_get_char(scanner);
+    pj_scan_get( scanner, &pc->pjsip_NOT_COMMA_OR_NEWLINE,
+             &allow_events->values[allow_events->count]);
+    allow_events->count++;
+
+    if (allow_events->count >= PJSIP_MAX_ALLOW_EVENTS)
+        break;
+    }
+
+end:
+    pjsip_parse_end_hdr_imp(scanner);
+    return (pjsip_hdr*)allow_events;
+}
+
+
+/*
  * Register header parsers.
  */
 PJ_DEF(void) pjsip_evsub_init_parser(void)
diff -ruN pjproject-2.10/pjsip/src/pjsip-ua/sip_inv.c pjsip/pjsip/src/pjsip-ua/sip_inv.c
--- pjproject-2.10/pjsip/src/pjsip-ua/sip_inv.c	2020-02-14 10:48:27.000000000 +0100
+++ pjsip/pjsip/src/pjsip-ua/sip_inv.c	2021-02-06 19:46:19.602835344 +0100
@@ -2006,6 +2006,20 @@
 	return PJMEDIA_SDP_EINSDP;
     }
 
+    /* Only accept SDP in INVITE, UPDATE and ACK requests, 18x (reliable) and 183 provisional responses
+     * and 200 final response.
+     */
+    if (!(msg->type == PJSIP_REQUEST_MSG && msg->line.req.method.id == PJSIP_INVITE_METHOD) &&
+        !(msg->type == PJSIP_REQUEST_MSG && msg->line.req.method.id == PJSIP_ACK_METHOD) &&
+        !(msg->type == PJSIP_REQUEST_MSG && pjsip_method_cmp(&msg->line.req.method, &pjsip_update_method)==0) &&
+        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code/10==18 && pjsip_100rel_is_reliable(rdata)) &&
+        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code == 183) &&
+        !(msg->type == PJSIP_RESPONSE_MSG && msg->line.status.code == 200)) {
+           PJ_LOG(4,(inv->obj_name, "ignored SDP body"));
+        return PJ_SUCCESS;
+    }
+
+
     /* Get/attach invite session's transaction data */
     tsx_inv_data = (struct tsx_inv_data*) tsx->mod_data[mod_inv.mod.id];
     if (tsx_inv_data == NULL) {
@@ -2233,6 +2247,11 @@
 	{
 	    status = pjmedia_sdp_neg_set_local_answer(inv->pool_prov, inv->neg,
 						      local_sdp);
+	} else if (pjmedia_sdp_neg_get_state(inv->neg)==
+                  PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)
+       {
+           /* Go forward with our local offer */
+           status = PJ_SUCCESS;
 	} else {
 
 	    /* Can not specify local SDP at this state. */
--- pjsip/pjsip/src/pjsip/sip_transport_tls.c
+++ pjsip/pjsip/src/pjsip/sip_transport_tls.c
@@ -88,6 +88,7 @@ struct tls_transport
     pjsip_transport	     base;
     pj_bool_t		     is_server;
     pj_str_t		     remote_name;
+    pj_str_t		     tls_name;
 
     pj_bool_t		     is_registered;
     pj_bool_t		     is_closing;
@@ -162,6 +163,7 @@ static pj_status_t tls_create(struct tls_listener *listener,
 			      const pj_sockaddr *local,
 			      const pj_sockaddr *remote,
 			      const pj_str_t *remote_name,
+			      const pj_str_t *tls_name,
 			      pj_grp_lock_t *glock,
 			      struct tls_transport **p_tls);
 
@@ -796,6 +798,7 @@ static pj_status_t tls_create( struct tls_listener *listener,
 			       const pj_sockaddr *local,
 			       const pj_sockaddr *remote,
 			       const pj_str_t *remote_name,
+			       const pj_str_t *tls_name,
 			       pj_grp_lock_t *glock,
 			       struct tls_transport **p_tls)
 {
@@ -839,6 +842,9 @@ static pj_status_t tls_create( struct tls_listener *listener,
     if (remote_name)
 	pj_strdup(pool, &tls->remote_name, remote_name);
 
+    if (tls_name)
+	pj_strdup(pool, &tls->tls_name, tls_name);
+
     tls->base.key.type = listener->factory.type;
     pj_sockaddr_cp(&tls->base.key.rem_addr, remote);
     tls->base.type_name = (char*)pjsip_transport_get_type_name(
@@ -1142,7 +1148,11 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
     pj_ssl_sock_param ssock_param;
     pj_sockaddr local_addr;
     pj_str_t remote_name;
+    pj_str_t tls_name;
     pj_status_t status;
+    pjsip_param *p = NULL;
+    pjsip_sip_uri *sip_uri = NULL;
+    pjsip_route_hdr *route_hdr = NULL;
 
     /* Sanity checks */
     PJ_ASSERT_RETURN(factory && mgr && endpt && rem_addr &&
@@ -1162,8 +1172,27 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
     PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
 
     /* Get remote host name from tdata */
-    if (tdata)
-	remote_name = tdata->dest_info.name;
+    if (tdata) {
+	remote_name = tdata->dest_info.name;
+	/* Get tls_name from sip route if defined */
+	route_hdr = (pjsip_route_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ROUTE, NULL);
+	if (route_hdr != NULL) {
+	    if (PJSIP_URI_SCHEME_IS_SIPS(route_hdr->name_addr.uri) ||
+		PJSIP_URI_SCHEME_IS_SIP(route_hdr->name_addr.uri)) {
+		sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(route_hdr->name_addr.uri);
+		p = sip_uri->other_param.next;
+		while (p != &sip_uri->other_param) {
+		    const pj_str_t st_name = {"tls_name", 8};
+		    if (pj_stricmp(&p->name, &st_name) == 0) {
+			pj_strdup(pool, &tls_name, &p->value);
+			//tls_name.ptr[tls_name.slen] = '\x00';
+			break;
+		    }
+		p = p->next;
+		}
+	    }
+	}
+    }
     else
 	pj_bzero(&remote_name, sizeof(remote_name));
 
@@ -1237,7 +1266,7 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
 
     /* Create the transport descriptor */
     status = tls_create(listener, pool, ssock, PJ_FALSE, &local_addr, 
-			rem_addr, &remote_name, glock, &tls);
+			rem_addr, &remote_name, &tls_name, glock, &tls);
     if (status != PJ_SUCCESS)
 	return status;
 
@@ -1398,7 +1427,7 @@ static pj_bool_t on_accept_complete2(pj_ssl_sock_t *ssock,
      */
     status = tls_create( listener, NULL, new_ssock, PJ_TRUE,
 			 &ssl_info.local_addr, &tmp_src_addr, NULL,
-			 ssl_info.grp_lock, &tls);
+			 NULL, ssl_info.grp_lock, &tls);
     
     if (status != PJ_SUCCESS) {
 	if (listener->tls_setting.on_accept_fail_cb) {
@@ -1821,8 +1850,11 @@ static pj_bool_t on_connect_complete(pj_ssl_sock_t *ssock,
 	pj_bool_t matched = PJ_FALSE;
 	unsigned i;

-	/* Remote name may be hostname or IP address */
-	if (tls->remote_name.slen)
+	/* Remote name may be hostname or IP address 
+	 * but might as well be defined in tls_name */
+	if (tls->tls_name.slen)
+	    remote_name = &tls->tls_name;
+	else if (tls->remote_name.slen)
 	    remote_name = &tls->remote_name;
 	else
 	    remote_name = &tls->base.remote_name.host;
--- pjsip/pjsip/src/pjsip/sip_transport_tls.c
+++ pjsip/pjsip/src/pjsip/sip_transport_tls.c
@@ -1206,7 +1206,10 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
     ssock_param.async_cnt = 1;
     ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);
     ssock_param.timer_heap = pjsip_endpt_get_timer_heap(listener->endpt);
-    ssock_param.server_name = remote_name;
+    if (tls_name.slen)
+        ssock_param.server_name = tls_name;
+    else
+        ssock_param.server_name = remote_name;
     ssock_param.timeout = listener->tls_setting.timeout;
     ssock_param.user_data = NULL; /* pending, must be set later */
     ssock_param.verify_peer = PJ_FALSE; /* avoid SSL socket closing the socket
