From: Joshua Colp Date: Mon, 28 Jan 2008 20:40:08 +0000 (+0000) Subject: Fix up some T38 state change issues. X-Git-Tag: 1.6.0-beta2~2^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1eeabcd41be2dc8a35175735728d44bb2b0c07d;p=thirdparty%2Fasterisk.git Fix up some T38 state change issues. (closes issue #11630) Reported by: dimas Patches: v2-sip-t38state.patch uploaded by dimas (license 88) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@100671 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2cb8988b7a..c6bcf054b6 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1662,6 +1662,12 @@ static struct ast_config *notify_types; /*!< The list of manual NOTIFY types we (head) = (element)->next; \ } while (0) +enum t38_action_flag { + SDP_T38_NONE = 0, /*!< Do not modify T38 information at all */ + SDP_T38_INITIATE, /*!< Remote side has requested T38 with us */ + SDP_T38_ACCEPT, /*!< Remote side accepted our T38 request */ +}; + /*---------------------------- Forward declarations of functions in chan_sip.c */ /*! \note This is added to help splitting up chan_sip.c into several files in coming releases */ @@ -1753,7 +1759,7 @@ static void try_suggested_sip_codec(struct sip_pvt *p); static const char* get_sdp_iterate(int* start, struct sip_request *req, const char *name); static const char *get_sdp(struct sip_request *req, const char *name); static int find_sdp(struct sip_request *req); -static int process_sdp(struct sip_pvt *p, struct sip_request *req); +static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action); static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size); @@ -6075,7 +6081,7 @@ static int find_sdp(struct sip_request *req) Return 0 on success, a negative value on errors. Must be called after find_sdp(). */ -static int process_sdp(struct sip_pvt *p, struct sip_request *req) +static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action) { const char *m; /* SDP media offer */ const char *c; @@ -6292,14 +6298,6 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid); udptlportno = x; numberofmediastreams++; - - if (p->owner && p->lastinvite) { - p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ - ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "" ); - } else { - p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ - ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : ""); - } } else ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m); if (numberofports > 1) @@ -6608,11 +6606,25 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req) p->t38.capability, p->t38.peercapability, p->t38.jointcapability); + + + /* Remote party offers T38, we need to update state */ + if (t38action == SDP_T38_ACCEPT) { + if (p->t38.state == T38_LOCAL_DIRECT || p->t38.state == T38_LOCAL_REINVITE) + p->t38.state = T38_ENABLED; + } else if (t38action == SDP_T38_INITIATE) { + if (p->owner && p->lastinvite) { + p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */ + } else { + p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */ + } + } } else { p->t38.state = T38_DISABLED; - ast_debug(3, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : ""); } + ast_debug(3, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : ""); + /* Now gather all of the codecs that we are asked for: */ ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); @@ -14278,7 +14290,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru if (find_sdp(req)) { if (p->invitestate != INV_CANCELLED) p->invitestate = INV_EARLY_MEDIA; - res = process_sdp(p, req); + res = process_sdp(p, req, SDP_T38_NONE); if (!req->ignore && p->owner) { /* Queue a progress frame only if we have SDP in 180 or 182 */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -14294,7 +14306,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru if (find_sdp(req)) { if (p->invitestate != INV_CANCELLED) p->invitestate = INV_EARLY_MEDIA; - res = process_sdp(p, req); + res = process_sdp(p, req, SDP_T38_NONE); if (!req->ignore && p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -14308,7 +14320,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); p->authtries = 0; if (find_sdp(req)) { - if ((res = process_sdp(p, req)) && !req->ignore) + if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore) if (!reinvite) /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */ /* For re-invites, we try to recover */ @@ -15114,7 +15126,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_ if (!req->ignore && sip_cancel_destroy(p)) ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n"); if (find_sdp(req)) - process_sdp(p, req); + process_sdp(p, req, SDP_T38_NONE); if (p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); @@ -16045,7 +16057,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int ast_clear_flag(&p->flags[0], SIP_OUTGOING); /* This is now an inbound dialog */ /* Handle SDP here if we already have an owner */ if (find_sdp(req)) { - if (process_sdp(p, req)) { + if (process_sdp(p, req, SDP_T38_INITIATE)) { transmit_response(p, "488 Not acceptable here", req); if (!p->lastinvite) sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); @@ -16086,7 +16098,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int /* We have a succesful authentication, process the SDP portion if there is one */ if (find_sdp(req)) { - if (process_sdp(p, req)) { + if (process_sdp(p, req, SDP_T38_INITIATE)) { /* Unacceptable codecs */ transmit_response_reliable(p, "488 Not acceptable here", req); p->invitestate = INV_COMPLETED; @@ -17712,7 +17724,7 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so p->pendinginvite = 0; __sip_ack(p, seqno, 1 /* response */, 0); if (find_sdp(req)) { - if (process_sdp(p, req)) + if (process_sdp(p, req, SDP_T38_NONE)) return -1; } check_pendings(p);