Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 354394) +++ channels/chan_sip.c (working copy) @@ -7503,7 +7503,13 @@ } break; case 5: - f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */ + if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38_P2P)) { + struct ast_channel *c = ast_bridged_channel(ast); + struct sip_pvt *t = c->tech_pvt; + f = ast_udptl_read(p->udptl, t->udptl); /* UDPTL for T.38 in p2p mode*/ + } else { + f = ast_udptl_read(p->udptl, NULL); /* UDPTL for T.38 */ + } break; default: f = &ast_null_frame; @@ -27660,6 +27666,9 @@ } else if (!strcasecmp(v->name, "t38pt_usertpsource")) { ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION); ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION); + } else if (!strcasecmp(v->name, "t38pt_p2p")) { + ast_set_flag(&mask[1], SIP_PAGE2_T38_P2P); + ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_T38_P2P); } else { res = 0; } Index: channels/sip/include/sip.h =================================================================== --- channels/sip/include/sip.h (revision 354394) +++ channels/sip/include/sip.h (working copy) @@ -351,6 +351,7 @@ #define SIP_PAGE2_VIDEOSUPPORT_ALWAYS (1 << 27) /*!< DP: Always set up video, even if endpoints don't support it */ #define SIP_PAGE2_HAVEPEERCONTEXT (1 << 28) /*< Are we associated with a configured peer context? */ #define SIP_PAGE2_USE_SRTP (1 << 29) /*!< DP: Whether we should offer (only) SRTP */ +#define SIP_PAGE2_T38_P2P (1 << 30) /*!< Directly forward T.38 UDPTL pakets without extrac them in passthrough mode */ #define SIP_PAGE2_FLAGS_TO_COPY \ (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \ @@ -358,7 +359,7 @@ SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \ SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \ SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP |\ - SIP_PAGE2_Q850_REASON | SIP_PAGE2_HAVEPEERCONTEXT | SIP_PAGE2_USE_SRTP) + SIP_PAGE2_Q850_REASON | SIP_PAGE2_HAVEPEERCONTEXT | SIP_PAGE2_USE_SRTP | SIP_PAGE2_T38_P2P) #define SIP_PAGE3_SNOM_AOC (1 << 0) /*!< DPG: Allow snom aoc messages */ Index: include/asterisk/udptl.h =================================================================== --- include/asterisk/udptl.h (revision 354394) +++ include/asterisk/udptl.h (working copy) @@ -90,7 +90,7 @@ int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f); -struct ast_frame *ast_udptl_read(struct ast_udptl *udptl); +struct ast_frame *ast_udptl_read(struct ast_udptl *udptl, struct ast_udptl *p2p_udptl); int ast_udptl_fd(const struct ast_udptl *udptl); Index: main/udptl.c =================================================================== --- main/udptl.c (revision 354394) +++ main/udptl.c (working copy) @@ -654,14 +654,14 @@ struct ast_udptl *udptl = cbdata; struct ast_frame *f; - if ((f = ast_udptl_read(udptl))) { + if ((f = ast_udptl_read(udptl, NULL))) { if (udptl->callback) udptl->callback(udptl, f, udptl->data); } return 1; } -struct ast_frame *ast_udptl_read(struct ast_udptl *udptl) +struct ast_frame *ast_udptl_read(struct ast_udptl *udptl, struct ast_udptl *p2p_udptl) { int res; struct ast_sockaddr addr; @@ -710,7 +710,20 @@ ast_verb(1, "UDPTL (%s): packet from %s (seq %d, len %d)\n", LOG_TAG(udptl), ast_sockaddr_stringify(&addr), seq_no, res); + + if(p2p_udptl && !ast_sockaddr_isnull(&p2p_udptl->them)) + ast_verb(1, "UDPTL (%s): send packet p2p to %s (seq %d, len %d)\n", + LOG_TAG(udptl), ast_sockaddr_stringify(&p2p_udptl->them), seq_no, res); + } + /* dont unpack the udptl paket. forward it directly */ + if(p2p_udptl && !ast_sockaddr_isnull(&p2p_udptl->them)) { + if ((res = ast_sendto(p2p_udptl->fd, buf, res, 0, &p2p_udptl->them)) < 0) + ast_log(LOG_NOTICE, "UPTL Transmission error to %s: %s\n", ast_sockaddr_stringify(&p2p_udptl->them), strerror(errno)); + return &ast_null_frame; + } + + /* do the full interpretation of the udptl paket */ if (udptl_rx_packet(udptl, buf, res) < 1) { return &ast_null_frame; }