Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:00:57 2007

Asterisk developer's documentation :: Codename Pineapple


sip3_sdprtp.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions)
00006  *
00007  * Mark Spencer <markster@digium.com>
00008  *
00009  * See http://www.asterisk.org for more information about
00010  * the Asterisk project. Please do not directly contact
00011  * any of the maintainers of this project for assistance;
00012  * the project provides a web site, mailing lists and IRC
00013  * channels for your use.
00014  *
00015  * This program is free software, distributed under the terms of
00016  * the GNU General Public License Version 2. See the LICENSE file
00017  * at the top of the source tree.
00018  */
00019 
00020 /*!
00021  * \file
00022  * \brief Various SIP SDP and RTP handling functions
00023  * Version 3 of chan_sip
00024  *
00025  * \author Mark Spencer <markster@digium.com>
00026  * \author Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)
00027  *
00028  * See Also:
00029  * \arg \ref AstCREDITS
00030  *
00031  */
00032 
00033 #include "asterisk.h"
00034 
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 53128 $")
00036 
00037 #include <stdio.h>
00038 #include <ctype.h>
00039 #include <string.h>
00040 #include <unistd.h>
00041 #include <sys/socket.h>
00042 #include <sys/ioctl.h>
00043 #include <net/if.h>
00044 #include <errno.h>
00045 #include <stdlib.h>
00046 #include <fcntl.h>
00047 #include <netdb.h>
00048 #include <signal.h>
00049 #include <sys/signal.h>
00050 #include <netinet/in.h>
00051 #include <netinet/in_systm.h>
00052 #include <arpa/inet.h>
00053 #include <netinet/ip.h>
00054 #include <regex.h>
00055 
00056 #include "asterisk/lock.h"
00057 #include "asterisk/channel.h"
00058 #include "asterisk/config.h"
00059 #include "asterisk/logger.h"
00060 #include "asterisk/module.h"
00061 #include "asterisk/pbx.h"
00062 #include "asterisk/options.h"
00063 #include "asterisk/io.h"
00064 #include "asterisk/rtp.h"
00065 #include "asterisk/udptl.h"
00066 #include "asterisk/acl.h"
00067 #include "asterisk/manager.h"
00068 #include "asterisk/callerid.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/app.h"
00071 #include "asterisk/musiconhold.h"
00072 #include "asterisk/dsp.h"
00073 #include "asterisk/features.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/srv.h"
00076 #include "asterisk/astdb.h"
00077 #include "asterisk/causes.h"
00078 #include "asterisk/utils.h"
00079 #include "asterisk/file.h"
00080 #include "asterisk/astobj.h"
00081 #include "asterisk/linkedlists.h"
00082 #include "asterisk/stringfields.h"
00083 #include "asterisk/monitor.h"
00084 #include "asterisk/abstract_jb.h"
00085 #include "asterisk/compiler.h"
00086 #include "sip3.h"
00087 #include "sip3funcs.h"
00088 
00089 /* Forward declarations */
00090 static int sip_get_codec(struct ast_channel *chan);
00091 static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
00092 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
00093 
00094 /*! \brief Interface structure with callbacks used to connect to RTP module */
00095 static struct ast_rtp_protocol sip_rtp = {
00096    type: "SIP",
00097    get_rtp_info: sip_get_rtp_peer,
00098    get_vrtp_info: sip_get_vrtp_peer,
00099    set_rtp_peer: sip_set_rtp_peer,
00100    get_codec: sip_get_codec,
00101 };
00102 
00103 /*! \brief Interface structure with callbacks used to connect to UDPTL module*/
00104 static struct ast_udptl_protocol sip_udptl = {
00105    type: "SIP",
00106    get_udptl_info: sip_get_udptl_peer,
00107    set_udptl_peer: sip_set_udptl_peer,
00108 };
00109 
00110 /*! \brief Register RTP and UDPTL to the subsystems */
00111 void register_rtp_and_udptl(void)
00112 {
00113    /* Tell the RTP subdriver that we're here */
00114    ast_rtp_proto_register(&sip_rtp);
00115 
00116    /* Tell the UDPTL subdriver that we're here */
00117    ast_udptl_proto_register(&sip_udptl);
00118 }
00119 
00120 /*! \brief UNRegister RTP and UDPTL to the subsystems */
00121 void unregister_rtp_and_udptl(void)
00122 {
00123    /* Tell the RTP subdriver that we're gone */
00124    ast_rtp_proto_unregister(&sip_rtp);
00125 
00126    /* Tell the UDPTL subdriver that we're gone */
00127    ast_udptl_proto_unregister(&sip_udptl);
00128 }
00129 
00130 
00131 /*! \brief Reads one line of SIP message body */
00132 static char *get_body_by_line(const char *line, const char *name, int nameLen)
00133 {
00134    if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=')
00135       return ast_skip_blanks(line + nameLen + 1);
00136 
00137    return "";
00138 }
00139 
00140 /*! \brief Lookup 'name' in the SDP starting
00141  * at the 'start' line. Returns the matching line, and 'start'
00142  * is updated with the next line number.
00143  */
00144 static const char *get_sdp_iterate(int *start, struct sip_request *req, const char *name)
00145 {
00146    int len = strlen(name);
00147 
00148    while (*start < req->sdp_end) {
00149       const char *r = get_body_by_line(req->line[(*start)++], name, len);
00150       if (r[0] != '\0')
00151          return r;
00152    }
00153 
00154    return "";
00155 }
00156 
00157 /*! \brief Get a line from an SDP message body */
00158 static const char *get_sdp(struct sip_request *req, const char *name) 
00159 {
00160    int dummy = 0;
00161 
00162    return get_sdp_iterate(&dummy, req, name);
00163 }
00164 
00165 /*! \brief Get the message body part identified by name= */
00166 char *get_body(struct sip_request *req, char *name) 
00167 {
00168    int x;
00169    int len = strlen(name);
00170    char *r;
00171 
00172    for (x = 0; x < req->lines; x++) {
00173       r = get_body_by_line(req->line[x], name, len);
00174       if (r[0] != '\0')
00175          return r;
00176    }
00177 
00178    return "";
00179 }
00180 
00181 /*! \brief Process SIP SDP offer, select formats and activate RTP channels
00182    If offer is rejected, we will not change any properties of the call
00183 
00184    The SDP contains
00185    - a session description
00186    - one or multiple media descriptions that starts with m=
00187 
00188 */
00189 int process_sdp(struct sip_dialog *p, struct sip_request *req)
00190 {
00191    const char *m;    /* SDP media offer */
00192    const char *c;
00193    const char *a;
00194    char host[258];
00195    int len = -1;
00196    int portno = -1;     /*!< RTP Audio port number */
00197    int vportno = -1;    /*!< RTP Video port number */
00198    int udptlportno = -1;
00199    int peert38capability = 0;
00200    char s[256];
00201    int old = 0;
00202 
00203    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
00204    int peercapability = 0, peernoncodeccapability = 0;
00205    int vpeercapability = 0, vpeernoncodeccapability = 0;
00206    struct sockaddr_in sin;    /*!< media socket address */
00207    struct sockaddr_in vsin;   /*!< Video socket address */
00208 
00209    const char *codecs;
00210    struct hostent *hp;     /*!< RTP Audio host IP */
00211    struct hostent *vhp = NULL;   /*!< RTP video host IP */
00212    struct ast_hostent audiohp;
00213    struct ast_hostent videohp;
00214    int codec;
00215    int destiterator = 0;
00216    int iterator;
00217    int sendonly = 0;
00218    int numberofports;
00219    struct ast_channel *bridgepeer = NULL;
00220    struct ast_rtp *newaudiortp, *newvideortp;   /* Buffers for codec handling */
00221    int newjointcapability;          /* Negotiated capability */
00222    int newpeercapability;
00223    int newnoncodeccapability;
00224    int numberofmediastreams = 0;
00225    int debug = sip_debug_test_pvt(p);
00226       
00227    int found_rtpmap_codecs[32];
00228    int last_rtpmap_codec=0;
00229 
00230    if (!p->rtp) {
00231       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
00232       return -1;
00233    }
00234 
00235    /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
00236    newaudiortp = alloca(ast_rtp_alloc_size());
00237    memset(newaudiortp, 0, ast_rtp_alloc_size());
00238    ast_rtp_new_init(newaudiortp);
00239    ast_rtp_pt_clear(newaudiortp);
00240 
00241    newvideortp = alloca(ast_rtp_alloc_size());
00242    memset(newvideortp, 0, ast_rtp_alloc_size());
00243    ast_rtp_new_init(newvideortp);
00244    ast_rtp_pt_clear(newvideortp);
00245 
00246    /* Update our last rtprx when we receive an SDP, too */
00247    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
00248 
00249 
00250    /* Try to find first media stream */
00251    m = get_sdp(req, "m");
00252    destiterator = req->sdp_start;
00253    c = get_sdp_iterate(&destiterator, req, "c");
00254    if (ast_strlen_zero(m) || ast_strlen_zero(c)) {
00255       ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
00256       return -1;
00257    }
00258 
00259    /* Check for IPv4 address (not IPv6 yet) */
00260    if (sscanf(c, "IN IP4 %256s", host) != 1) {
00261       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
00262       return -1;
00263    }
00264 
00265    /* XXX This could block for a long time, and block the main thread! XXX */
00266    hp = ast_gethostbyname(host, &audiohp);
00267    if (!hp) {
00268       ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c);
00269       return -1;
00270    }
00271    vhp = hp;   /* Copy to video address as default too */
00272    
00273    iterator = req->sdp_start;
00274    ast_set_flag(&p->flags[0], SIP_NOVIDEO);  
00275 
00276 
00277    /* Find media streams in this SDP offer */
00278    while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
00279       int x;
00280       int audio = FALSE;
00281 
00282       numberofports = 1;
00283       if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
00284           (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
00285          audio = TRUE;
00286          numberofmediastreams++;
00287          /* Found audio stream in this media definition */
00288          portno = x;
00289          /* Scan through the RTP payload types specified in a "m=" line: */
00290          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
00291             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
00292                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
00293                return -1;
00294             }
00295             if (debug)
00296                ast_verbose("Found RTP audio format %d\n", codec);
00297             ast_rtp_set_m_type(newaudiortp, codec);
00298          }
00299       } else if ((sscanf(m, "video %d/%d RTP/AVP %n", &x, &numberofports, &len) == 2) ||
00300           (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
00301          /* If it is not audio - is it video ? */
00302          ast_clear_flag(&p->flags[0], SIP_NOVIDEO);   
00303          numberofmediastreams++;
00304          vportno = x;
00305          /* Scan through the RTP payload types specified in a "m=" line: */
00306          for (codecs = m + len; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
00307             if (sscanf(codecs, "%d%n", &codec, &len) != 1) {
00308                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
00309                return -1;
00310             }
00311             if (debug)
00312                ast_verbose("Found RTP video format %d\n", codec);
00313             ast_rtp_set_m_type(newvideortp, codec);
00314          }
00315       } else if (p->udptl && ((sscanf(m, "image %d udptl t38%n", &x, &len) == 1))) {
00316          if (debug)
00317             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
00318          udptlportno = x;
00319          numberofmediastreams++;
00320          
00321          if (p->owner && p->lastinvite) {
00322             p->t38.state = T38_PEER_REINVITE; /* T38 Offered in re-invite from remote party */
00323             if (option_debug > 1)
00324                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>" );
00325          } else {
00326             p->t38.state = T38_PEER_DIRECT; /* T38 Offered directly from peer in first invite */
00327             if (option_debug > 1)
00328                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
00329          }
00330       } else 
00331          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
00332       if (numberofports > 1)
00333          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
00334       
00335 
00336       /* Check for Media-description-level-address for audio */
00337       c = get_sdp_iterate(&destiterator, req, "c");
00338       if (!ast_strlen_zero(c)) {
00339          if (sscanf(c, "IN IP4 %256s", host) != 1) {
00340             ast_log(LOG_WARNING, "Invalid secondary host in c= line, '%s'\n", c);
00341          } else {
00342             /* XXX This could block for a long time, and block the main thread! XXX */
00343             if (audio) {
00344                if ( !(hp = ast_gethostbyname(host, &audiohp)))
00345                   ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in secondary c= line, '%s'\n", c);
00346             } else if (!(vhp = ast_gethostbyname(host, &videohp)))
00347                ast_log(LOG_WARNING, "Unable to lookup RTP video host in secondary c= line, '%s'\n", c);
00348          }
00349 
00350       }
00351    }
00352    if (portno == -1 && vportno == -1 && udptlportno == -1)
00353       /* No acceptable offer found in SDP  - we have no ports */
00354       /* Do not change RTP or VRTP if this is a re-invite */
00355       return -2;
00356 
00357    if (numberofmediastreams > 2)
00358       /* We have too many fax, audio and/or video media streams, fail this offer */
00359       return -3;
00360 
00361    /* RTP addresses and ports for audio and video */
00362    sin.sin_family = AF_INET;
00363    vsin.sin_family = AF_INET;
00364    memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
00365    if (vhp)
00366       memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
00367       
00368    /* Setup UDPTL port number */
00369    if (p->udptl) {
00370       if (udptlportno > 0) {
00371          sin.sin_port = htons(udptlportno);
00372          ast_udptl_set_peer(p->udptl, &sin);
00373          if (debug)
00374             ast_log(LOG_DEBUG,"Peer T.38 UDPTL is at port %s:%d\n",ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
00375       } else {
00376          ast_udptl_stop(p->udptl);
00377          if (debug)
00378             ast_log(LOG_DEBUG, "Peer doesn't provide T.38 UDPTL\n");
00379       }
00380    }
00381    if (p->rtp) {
00382       if (portno > 0) {
00383          sin.sin_port = htons(portno);
00384          if (!sin.sin_port) 
00385             ast_log(LOG_WARNING, "No SIN structure here, will crash\n");
00386          ast_rtp_set_peer(p->rtp, &sin);
00387          if (debug)
00388             ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
00389       } else {
00390          if (udptlportno > 0) {
00391             if (debug)
00392                ast_log(LOG_DEBUG, "Got T.38 re-invite without audio. Keeping RTP active during T.38 session. Call-Id %s\n", p->callid);
00393          } else 
00394             ast_rtp_stop(p->rtp);
00395          if (debug)
00396             ast_verbose("Peer doesn't provide audio: Call-Id: %s\n", p->callid);
00397       }
00398    }
00399    /* Setup video port number */
00400    if (vportno != -1)
00401       vsin.sin_port = htons(vportno);
00402 
00403 
00404    /* Next, scan through each "a=rtpmap:" line, noting each
00405     * specified RTP payload type (with corresponding MIME subtype):
00406     */
00407    /* XXX This needs to be done per media stream, since it's media stream specific */
00408    iterator = req->sdp_start;
00409    while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
00410       char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
00411       if (option_debug > 1) {
00412          int breakout = FALSE;
00413       
00414          /* If we're debugging, check for unsupported sdp options */
00415          if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
00416             if (debug)
00417                ast_verbose("Got unsupported a:rtcp in SDP offer \n");
00418             breakout = TRUE;
00419          } else if (!strncasecmp(a, "fmtp:", (size_t) 5)) {
00420             /* Format parameters:  Not supported */
00421             /* Note: This is used for codec parameters, like bitrate for
00422                G722 and video formats for H263 and H264 
00423                See RFC2327 for an example */
00424             if (debug)
00425                ast_verbose("Got unsupported a:fmtp in SDP offer \n");
00426             breakout = TRUE;
00427          } else if (!strncasecmp(a, "framerate:", (size_t) 10)) {
00428             /* Video stuff:  Not supported */
00429             if (debug)
00430                ast_verbose("Got unsupported a:framerate in SDP offer \n");
00431             breakout = TRUE;
00432          } else if (!strncasecmp(a, "maxprate:", (size_t) 9)) {
00433             /* Video stuff:  Not supported */
00434             if (debug)
00435                ast_verbose("Got unsupported a:maxprate in SDP offer \n");
00436             breakout = TRUE;
00437          } else if (!strncasecmp(a, "crypto:", (size_t) 7)) {
00438             /* SRTP stuff, not yet supported */
00439             if (debug)
00440                ast_verbose("Got unsupported a:crypto in SDP offer \n");
00441             breakout = TRUE;
00442          }
00443          if (breakout)  /* We have a match, skip to next header */
00444             continue;
00445       }
00446       if (!strcasecmp(a, "sendonly")) {
00447          sendonly = 1;
00448          continue;
00449       } else if (!strcasecmp(a, "inactive")) {
00450          sendonly = 2;
00451          continue;
00452       }  else if (!strcasecmp(a, "sendrecv")) {
00453          sendonly = 0;
00454          continue;
00455       } else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
00456          char *tmp = strrchr(a, ':');
00457          long int framing = 0;
00458          if (tmp) {
00459             tmp++;
00460             framing = strtol(tmp, NULL, 10);
00461             if (framing == LONG_MIN || framing == LONG_MAX) {
00462                framing = 0;
00463                if (option_debug)
00464                   ast_log(LOG_DEBUG, "Can't read framing from SDP: %s\n", a);
00465             }
00466          }
00467          if (framing && last_rtpmap_codec) {
00468             if (p->autoframing || global.autoframing) {
00469                struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
00470                int codec_n;
00471                int format = 0;
00472                for (codec_n = 0; codec_n < last_rtpmap_codec; codec_n++) {
00473                   format = ast_rtp_codec_getformat(found_rtpmap_codecs[codec_n]);
00474                   if (!format)   /* non-codec or not found */
00475                      continue;
00476                   if (option_debug)
00477                      ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
00478                   ast_codec_pref_setsize(pref, format, framing);
00479                }
00480                ast_rtp_codec_setpref(p->rtp, pref);
00481             }
00482          }
00483          memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs));
00484          last_rtpmap_codec = 0;
00485          continue;
00486       } else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) {
00487          /* We have a rtpmap to handle */
00488          if (debug)
00489             ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec);
00490          found_rtpmap_codecs[last_rtpmap_codec] = codec;
00491          last_rtpmap_codec++;
00492 
00493          /* Note: should really look at the 'freq' and '#chans' params too */
00494          ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
00495                ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0);
00496          if (p->vrtp)
00497             ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0);
00498       }
00499    }
00500    
00501    if (udptlportno != -1) {
00502       int found = 0, x;
00503       
00504       old = 0;
00505       
00506       /* Scan trough the a= lines for T38 attributes and set apropriate fileds */
00507       iterator = req->sdp_start;
00508       while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
00509          if ((sscanf(a, "T38FaxMaxBuffer:%d", &x) == 1)) {
00510             found = 1;
00511             if (option_debug > 2)
00512                ast_log(LOG_DEBUG, "MaxBufferSize:%d\n",x);
00513          } else if ((sscanf(a, "T38MaxBitRate:%d", &x) == 1)) {
00514             found = 1;
00515             if (option_debug > 2)
00516                ast_log(LOG_DEBUG,"T38MaxBitRate: %d\n",x);
00517             switch (x) {
00518             case 14400:
00519                peert38capability |= T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
00520                break;
00521             case 12000:
00522                peert38capability |= T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
00523                break;
00524             case 9600:
00525                peert38capability |= T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
00526                break;
00527             case 7200:
00528                peert38capability |= T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400;
00529                break;
00530             case 4800:
00531                peert38capability |= T38FAX_RATE_4800 | T38FAX_RATE_2400;
00532                break;
00533             case 2400:
00534                peert38capability |= T38FAX_RATE_2400;
00535                break;
00536             }
00537          } else if ((sscanf(a, "T38FaxVersion:%d", &x) == 1)) {
00538             found = 1;
00539             if (option_debug > 2)
00540                ast_log(LOG_DEBUG, "FaxVersion: %d\n",x);
00541             if (x == 0)
00542                peert38capability |= T38FAX_VERSION_0;
00543             else if (x == 1)
00544                peert38capability |= T38FAX_VERSION_1;
00545          } else if ((sscanf(a, "T38FaxMaxDatagram:%d", &x) == 1)) {
00546             found = 1;
00547             if (option_debug > 2)
00548                ast_log(LOG_DEBUG, "FaxMaxDatagram: %d\n",x);
00549             ast_udptl_set_far_max_datagram(p->udptl, x);
00550             ast_udptl_set_local_max_datagram(p->udptl, x);
00551          } else if ((sscanf(a, "T38FaxFillBitRemoval:%d", &x) == 1)) {
00552             found = 1;
00553             if (option_debug > 2)
00554                ast_log(LOG_DEBUG, "FillBitRemoval: %d\n",x);
00555             if (x == 1)
00556                peert38capability |= T38FAX_FILL_BIT_REMOVAL;
00557          } else if ((sscanf(a, "T38FaxTranscodingMMR:%d", &x) == 1)) {
00558             found = 1;
00559             if (option_debug > 2)
00560                ast_log(LOG_DEBUG, "Transcoding MMR: %d\n",x);
00561             if (x == 1)
00562                peert38capability |= T38FAX_TRANSCODING_MMR;
00563          }
00564          if ((sscanf(a, "T38FaxTranscodingJBIG:%d", &x) == 1)) {
00565             found = 1;
00566             if (option_debug > 2)
00567                ast_log(LOG_DEBUG, "Transcoding JBIG: %d\n",x);
00568             if (x == 1)
00569                peert38capability |= T38FAX_TRANSCODING_JBIG;
00570          } else if ((sscanf(a, "T38FaxRateManagement:%s", s) == 1)) {
00571             found = 1;
00572             if (option_debug > 2)
00573                ast_log(LOG_DEBUG, "RateMangement: %s\n", s);
00574             if (!strcasecmp(s, "localTCF"))
00575                peert38capability |= T38FAX_RATE_MANAGEMENT_LOCAL_TCF;
00576             else if (!strcasecmp(s, "transferredTCF"))
00577                peert38capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
00578          } else if ((sscanf(a, "T38FaxUdpEC:%s", s) == 1)) {
00579             found = 1;
00580             if (option_debug > 2)
00581                ast_log(LOG_DEBUG, "UDP EC: %s\n", s);
00582             if (!strcasecmp(s, "t38UDPRedundancy")) {
00583                peert38capability |= T38FAX_UDP_EC_REDUNDANCY;
00584                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
00585             } else if (!strcasecmp(s, "t38UDPFEC")) {
00586                peert38capability |= T38FAX_UDP_EC_FEC;
00587                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
00588             } else {
00589                peert38capability |= T38FAX_UDP_EC_NONE;
00590                ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
00591             }
00592          }
00593       }
00594       if (found) { /* Some cisco equipment returns nothing beside c= and m= lines in 200 OK T38 SDP */
00595          p->t38.peercapability = peert38capability;
00596          p->t38.jointcapability = (peert38capability & 255); /* Put everything beside supported speeds settings */
00597          peert38capability &= (T38FAX_RATE_14400 | T38FAX_RATE_12000 | T38FAX_RATE_9600 | T38FAX_RATE_7200 | T38FAX_RATE_4800 | T38FAX_RATE_2400);
00598          p->t38.jointcapability |= (peert38capability & p->t38.capability); /* Put the lower of our's and peer's speed */
00599       }
00600       if (debug)
00601          ast_log(LOG_DEBUG, "Our T38 capability = (%d), peer T38 capability (%d), joint T38 capability (%d)\n",
00602             p->t38.capability,
00603             p->t38.peercapability,
00604             p->t38.jointcapability);
00605    } else {
00606       p->t38.state = T38_DISABLED;
00607       if (option_debug > 2)
00608          ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
00609    }
00610 
00611    /* Now gather all of the codecs that we are asked for: */
00612    ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
00613    ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
00614 
00615    newjointcapability = p->capability & (peercapability | vpeercapability);
00616    newpeercapability = (peercapability | vpeercapability);
00617    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
00618       
00619       
00620    if (debug) {
00621       /* shame on whoever coded this.... */
00622       char s1[BUFSIZ], s2[BUFSIZ], s3[BUFSIZ], s4[BUFSIZ];
00623 
00624       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s, combined - %s\n",
00625              ast_getformatname_multiple(s1, BUFSIZ, p->capability),
00626              ast_getformatname_multiple(s2, BUFSIZ, newpeercapability),
00627              ast_getformatname_multiple(s3, BUFSIZ, vpeercapability),
00628              ast_getformatname_multiple(s4, BUFSIZ, newjointcapability));
00629 
00630       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
00631              ast_rtp_lookup_mime_multiple(s1, BUFSIZ, p->noncodeccapability, 0, 0),
00632              ast_rtp_lookup_mime_multiple(s2, BUFSIZ, peernoncodeccapability, 0, 0),
00633              ast_rtp_lookup_mime_multiple(s3, BUFSIZ, newnoncodeccapability, 0, 0));
00634    }
00635    if (!newjointcapability) {
00636       /* If T.38 was not negotiated either, totally bail out... */
00637       if (!p->t38.jointcapability) {
00638          ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
00639          /* Do NOT Change current setting */
00640          return -1;
00641       } else {
00642          if (option_debug > 2)
00643             ast_log(LOG_DEBUG, "Have T.38 but no audio codecs, accepting offer anyway\n");
00644          return 0;
00645       }
00646    }
00647 
00648    /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
00649       they are acceptable */
00650    p->jointcapability = newjointcapability;  /* Our joint codec profile for this call */
00651    p->peercapability = newpeercapability;    /* The other sides capability in latest offer */
00652    p->jointnoncodeccapability = newnoncodeccapability;   /* DTMF capabilities */
00653 
00654    ast_rtp_pt_copy(p->rtp, newaudiortp);
00655    if (p->vrtp)
00656       ast_rtp_pt_copy(p->vrtp, newvideortp);
00657 
00658    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
00659       ast_clear_flag(&p->flags[0], SIP_DTMF);
00660       if (newnoncodeccapability & AST_RTP_DTMF) {
00661          /* XXX Would it be reasonable to drop the DSP at this point? XXX */
00662          ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
00663       } else {
00664          ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
00665       }
00666    }
00667 
00668    /* Setup audio port number */
00669    if (p->rtp && sin.sin_port) {
00670       ast_rtp_set_peer(p->rtp, &sin);
00671       if (debug)
00672          ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
00673    }
00674 
00675    /* Setup video port number */
00676    if (p->vrtp && vsin.sin_port) {
00677       ast_rtp_set_peer(p->vrtp, &vsin);
00678       if (debug) 
00679          ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
00680    }
00681 
00682    /* Ok, we're going with this offer */
00683    if (option_debug > 1) {
00684       char buf[BUFSIZ];
00685       ast_log(LOG_DEBUG, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, BUFSIZ, p->jointcapability));
00686    }
00687 
00688    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
00689       return 0;
00690 
00691    if (option_debug > 3)
00692       ast_log(LOG_DEBUG, "We have an owner, now see if we need to change this call\n");
00693 
00694    if (!(p->owner->nativeformats & p->jointcapability & AST_FORMAT_AUDIO_MASK) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
00695       if (debug) {
00696          char s1[BUFSIZ], s2[BUFSIZ];
00697          ast_log(LOG_DEBUG, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 
00698             ast_getformatname_multiple(s1, BUFSIZ, p->jointcapability),
00699             ast_getformatname_multiple(s2, BUFSIZ, p->owner->nativeformats));
00700       }
00701       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability);
00702       ast_set_read_format(p->owner, p->owner->readformat);
00703       ast_set_write_format(p->owner, p->owner->writeformat);
00704    }
00705    
00706    /* Turn on/off music on hold if we are holding/unholding */
00707    if ((bridgepeer = ast_bridged_channel(p->owner))) {
00708       if (sin.sin_addr.s_addr && !sendonly) {
00709          ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
00710          /* Activate a re-invite */
00711          ast_queue_frame(p->owner, &ast_null_frame);
00712       } else if (!sin.sin_addr.s_addr || sendonly) {
00713          ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
00714                       S_OR(p->mohsuggest, NULL),
00715                       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
00716          if (sendonly)
00717             ast_rtp_stop(p->rtp);
00718          /* RTCP needs to go ahead, even if we're on hold!!! */
00719          /* Activate a re-invite */
00720          ast_queue_frame(p->owner, &ast_null_frame);
00721       }
00722    }
00723 
00724    /* Manager Hold and Unhold events must be generated, if necessary */
00725    if (sin.sin_addr.s_addr && !sendonly) {
00726       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
00727          append_history(p, "Unhold", "%s", req->data);
00728          if (global.callevents)
00729             manager_event(EVENT_FLAG_CALL, "Unhold",
00730                "Channel: %s\r\n"
00731                "Uniqueid: %s\r\n",
00732                p->owner->name, 
00733                p->owner->uniqueid);
00734          sip_peer_hold(p, 0);
00735       } 
00736       ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);  /* Clear both flags */
00737    } else if (!sin.sin_addr.s_addr || sendonly ) {
00738       /* No address for RTP, we're on hold */
00739       append_history(p, "Hold", "%s", req->data);
00740 
00741       if (global.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
00742          manager_event(EVENT_FLAG_CALL, "Hold",
00743             "Channel: %s\r\n"
00744             "Uniqueid: %s\r\n",
00745             p->owner->name, 
00746             p->owner->uniqueid);
00747       }
00748       if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
00749          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
00750       else if (sendonly == 2) /* Inactive stream */
00751          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
00752       sip_peer_hold(p, 1);
00753    }
00754    
00755    return 0;
00756 }
00757 
00758 
00759 /*! \brief Set the RTP peer for this call */
00760 int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
00761 {
00762    struct sip_dialog *p;
00763    int changed = 0;
00764 
00765    p = chan->tech_pvt;
00766    if (!p) 
00767       return -1;
00768    dialog_lock(p, TRUE);
00769    if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) {
00770       /* If we're destroyed, don't bother */
00771       dialog_lock(p, FALSE);
00772       return 0;
00773    }
00774 
00775    /* if this peer cannot handle reinvites of the media stream to devices
00776       that are known to be behind a NAT, then stop the process now
00777    */
00778    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
00779       dialog_lock(p, FALSE);
00780       return 0;
00781    }
00782 
00783    if (rtp) {
00784       changed |= ast_rtp_get_peer(rtp, &p->redirip);
00785    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
00786       memset(&p->redirip, 0, sizeof(p->redirip));
00787       changed = 1;
00788    }
00789    if (vrtp) {
00790       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
00791    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
00792       memset(&p->vredirip, 0, sizeof(p->vredirip));
00793       changed = 1;
00794    }
00795    if (codecs && (p->redircodecs != codecs)) {
00796       p->redircodecs = codecs;
00797       changed = 1;
00798    }
00799    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
00800       if (chan->_state != AST_STATE_UP) { /* We are in early state */
00801          if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
00802             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
00803          if (option_debug)
00804             ast_log(LOG_DEBUG, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00805       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
00806          if (option_debug > 2) {
00807             ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00808          }
00809          transmit_reinvite_with_sdp(p, FALSE);
00810       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
00811          if (option_debug > 2) {
00812             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip));
00813          }
00814          /* We have a pending Invite. Send re-invite when we're done with the invite */
00815          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
00816       }
00817    }
00818    /* Reset lastrtprx timer */
00819    p->lastrtprx = p->lastrtptx = time(NULL);
00820    dialog_lock(p, FALSE);
00821    return 0;
00822 }
00823 
00824 /*! \brief Returns AST_RTP_GET_FAILED if we can't reinvite audio (part of RTP interface) */
00825 enum ast_rtp_get_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
00826 {
00827    struct sip_dialog *p = NULL;
00828    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
00829 
00830    if (!(p = chan->tech_pvt) || !(p->rtp))
00831       return AST_RTP_GET_FAILED;
00832 
00833    dialog_lock(p, TRUE);
00834 
00835    *rtp = p->rtp;
00836 
00837    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
00838       res = AST_RTP_TRY_PARTIAL;
00839    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
00840       res = AST_RTP_TRY_NATIVE;
00841    else if (ast_test_flag(&global.jbconf, AST_JB_FORCED))
00842       res = AST_RTP_GET_FAILED;
00843 
00844    dialog_lock(p, FALSE);
00845 
00846    return res;
00847 }
00848 
00849 /*! \brief Returns null if we can't reinvite video (part of RTP interface) */
00850 enum ast_rtp_get_result sip_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp **rtp)
00851 {
00852    struct sip_dialog *p = NULL;
00853    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
00854    
00855    if (!(p = chan->tech_pvt) || !(p->vrtp))
00856       return AST_RTP_GET_FAILED;
00857 
00858    ast_mutex_lock(&p->lock);
00859 
00860    *rtp = p->vrtp;
00861 
00862    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
00863       res = AST_RTP_TRY_NATIVE;
00864 
00865    /* The jitterbuffer is not implemented for video */
00866 
00867    ast_mutex_unlock(&p->lock);
00868 
00869    return res;
00870 }
00871 
00872 /*!
00873   \brief Determine whether a SIP message contains an SDP in its body
00874   \param req the SIP request to process
00875   \return TRUE if SDP found, FALSE if not found
00876 
00877   Also updates req->sdp_start and req->sdp_end to indicate where the SDP
00878   lives in the message body.
00879 */
00880 int find_sdp(struct sip_request *req)
00881 {
00882    const char *content_type;
00883    const char *search;
00884    char *boundary;
00885    unsigned int x;
00886 
00887    content_type = get_header(req, "Content-Type");
00888 
00889    /* if the body contains only SDP, this is easy */
00890    if (!strcasecmp(content_type, "application/sdp")) {
00891       req->sdp_start = 0;
00892       req->sdp_end = req->lines;
00893       return TRUE;
00894    }
00895 
00896    /* if it's not multipart/mixed, there cannot be an SDP */
00897    if (strncasecmp(content_type, "multipart/mixed", 15))
00898       return FALSE;
00899 
00900    /* if there is no boundary marker, it's invalid */
00901    if (!(search = strcasestr(content_type, ";boundary=")))
00902       return FALSE;
00903 
00904    search += 10;
00905 
00906    if (ast_strlen_zero(search))
00907       return FALSE;
00908 
00909    /* make a duplicate of the string, with two extra characters
00910       at the beginning */
00911    boundary = ast_strdupa(search - 2);
00912    boundary[0] = boundary[1] = '-';
00913 
00914    /* search for the boundary marker, but stop when there are not enough
00915       lines left for it, the Content-Type header and at least one line of
00916       body */
00917    for (x = 0; x < (req->lines - 2); x++) {
00918       if (!strncasecmp(req->line[x], boundary, strlen(boundary)) &&
00919           !strcasecmp(req->line[x + 1], "Content-Type: application/sdp")) {
00920          x += 2;
00921          req->sdp_start = x;
00922          /* search for the end of the body part */
00923          for ( ; x < req->lines; x++) {
00924             if (!strncasecmp(req->line[x], boundary, strlen(boundary)))
00925                break;
00926          }
00927          req->sdp_end = x;
00928          return TRUE;
00929       }
00930    }
00931 
00932    return FALSE;
00933 }
00934 
00935 /*! \brief Add RFC 2833 DTMF offer to SDP */
00936 static void add_noncodec_to_sdp(const struct sip_dialog *p, int format, int sample_rate,
00937             char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
00938             int debug)
00939 {
00940    int rtp_code;
00941 
00942    if (debug)
00943       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
00944    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
00945       return;
00946 
00947    ast_build_string(m_buf, m_size, " %d", rtp_code);
00948    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
00949           ast_rtp_lookup_mime_subtype(0, format, 0),
00950           sample_rate);
00951    if (format == AST_RTP_DTMF)
00952       /* Indicate we support DTMF and FLASH... */
00953       ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
00954 }
00955 
00956 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
00957 static void add_codec_to_sdp(const struct sip_dialog *p, int codec, int sample_rate,
00958               char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
00959               int debug, int *min_packet_size)
00960 {
00961    int rtp_code;
00962    struct ast_format_list fmt;
00963 
00964 
00965    if (debug)
00966       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
00967    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
00968       return;
00969 
00970    if (p->rtp) {
00971       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
00972       fmt = ast_codec_pref_getsize(pref, codec);
00973    } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
00974       return;
00975    ast_build_string(m_buf, m_size, " %d", rtp_code);
00976    ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
00977           ast_rtp_lookup_mime_subtype(1, codec,
00978                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
00979           sample_rate);
00980    if (codec == AST_FORMAT_G729A) {
00981       /* Indicate that we don't support VAD (G.729 annex B) */
00982       ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
00983    } else if (codec == AST_FORMAT_ILBC) {
00984       /* Add information about us using only 20/30 ms packetization */
00985       ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
00986    }
00987 
00988    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
00989       *min_packet_size = fmt.cur_ms;
00990 
00991    /* Our first codec packetization processed cannot be zero */
00992    if ((*min_packet_size)==0 && fmt.cur_ms)
00993       *min_packet_size = fmt.cur_ms;
00994 }
00995 
00996 /*! \brief Set all IP media addresses for this call 
00997        \note called from add_sdp()
00998 */
00999 static void get_our_media_address(struct sip_dialog *p, int needvideo, struct sockaddr_in *sin, struct sockaddr_in *vsin, struct sockaddr_in *dest, struct sockaddr_in *vdest)
01000 {
01001        /* First, get our address */
01002        ast_rtp_get_us(p->rtp, sin);
01003        if (p->vrtp)
01004                ast_rtp_get_us(p->vrtp, vsin);
01005 
01006        /* Now, try to figure out where we want them to send data */
01007        /* Is this a re-invite to move the media out, then use the original offer from caller  */
01008        if (p->redirip.sin_addr.s_addr) {       /* If we have a redirection IP, use it */
01009                dest->sin_port = p->redirip.sin_port;
01010                dest->sin_addr = p->redirip.sin_addr;
01011        } else {
01012                dest->sin_addr = p->ourip;
01013                dest->sin_port = sin->sin_port;
01014        }
01015        if (needvideo) {
01016                /* Determine video destination */
01017                if (p->vredirip.sin_addr.s_addr) {
01018                        vdest->sin_addr = p->vredirip.sin_addr;
01019                        vdest->sin_port = p->vredirip.sin_port;
01020                } else {
01021                        vdest->sin_addr = p->ourip;
01022                        vdest->sin_port = vsin->sin_port;
01023                }
01024        }
01025 
01026 }
01027 
01028 /*! \brief Add Session Description Protocol message */
01029 int add_sdp(struct sip_request *resp, struct sip_dialog *p)
01030 {
01031    int len = 0;
01032    int alreadysent = 0;
01033 
01034    struct sockaddr_in sin;
01035    struct sockaddr_in vsin;
01036    struct sockaddr_in dest;
01037    struct sockaddr_in vdest = { 0, };
01038 
01039    /* SDP fields */
01040    char *version =   "v=0\r\n";     /* Protocol version */
01041    char *subject =   "s=session\r\n";  /* Subject of the session */
01042    char owner[256];           /* Session owner/creator */
01043    char connection[256];            /* Connection data */
01044    char *stime = "t=0 0\r\n";          /* Time the session is active */
01045    char bandwidth[256] = "";        /* Max bitrate */
01046    char *hold;
01047    char m_audio[256];            /* Media declaration line for audio */
01048    char m_video[256];            /* Media declaration line for video */
01049    char a_audio[1024];           /* Attributes for audio */
01050    char a_video[1024];           /* Attributes for video */
01051    char *m_audio_next = m_audio;
01052    char *m_video_next = m_video;
01053    size_t m_audio_left = sizeof(m_audio);
01054    size_t m_video_left = sizeof(m_video);
01055    char *a_audio_next = a_audio;
01056    char *a_video_next = a_video;
01057    size_t a_audio_left = sizeof(a_audio);
01058    size_t a_video_left = sizeof(a_video);
01059 
01060    int x;
01061    int capability;
01062    int needvideo = FALSE;
01063    int debug = sip_debug_test_pvt(p);
01064    int min_audio_packet_size = 0;
01065    int min_video_packet_size = 0;
01066 
01067    m_video[0] = '\0';   /* Reset the video media string if it's not needed */
01068 
01069    if (!p->rtp) {
01070       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
01071       return -1;
01072    }
01073 
01074    /* Set RTP Session ID and version */
01075    if (!p->sessionid) {
01076       p->sessionid = getpid();
01077       p->sessionversion = p->sessionid;
01078    } else
01079       p->sessionversion++;
01080 
01081    /* Ok, let's start working with codec selection here */
01082    capability = p->jointcapability;
01083 
01084    if (option_debug > 1) {
01085       char codecbuf[BUFSIZ];
01086       ast_log(LOG_DEBUG, "** Our capability: %s Video flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), ast_test_flag(&p->flags[0], SIP_NOVIDEO) ? "True" : "False");
01087       ast_log(LOG_DEBUG, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
01088    }
01089    
01090 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
01091    if ((ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP))) {
01092       ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
01093       ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
01094    }
01095 #endif
01096 
01097    /* Check if we need video in this call */
01098    if((capability & AST_FORMAT_VIDEO_MASK) && !ast_test_flag(&p->flags[0], SIP_NOVIDEO)) {
01099       if (p->vrtp) {
01100          needvideo = TRUE;
01101          if (option_debug > 1)
01102             ast_log(LOG_DEBUG, "This call needs video offers! \n");
01103       } else if (option_debug > 1)
01104          ast_log(LOG_DEBUG, "This call needs video offers, but there's no video support enabled ! \n");
01105    }
01106 
01107    /* Get our media IP addresses for RTP */
01108    get_our_media_address(p, needvideo, &sin, &vsin, &dest, &vdest);
01109 
01110    /* Ok, we need video. Let's add what we need for video and set codecs.
01111       Video is handled differently than audio since we can not transcode. */
01112    if (needvideo) {
01113       ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
01114 
01115       /* Build max bitrate string */
01116       if (p->maxcallbitrate)
01117          snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
01118       if (debug) 
01119          ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(vsin.sin_port));   
01120 
01121       /*! \todo XXX We need to select one codec, not many, since there's no transcoding */
01122    }
01123    if (debug) 
01124       ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip), ntohs(sin.sin_port)); 
01125 
01126    /* Start building generic SDP headers */
01127 
01128    /* We break with the "recommendation" and send our IP, in order that our
01129       peer doesn't have to ast_gethostbyname() us */
01130 
01131    snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
01132    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
01133    ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
01134 
01135    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR))
01136       hold = "a=recvonly\r\n";
01137    else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE))
01138       hold = "a=inactive\r\n";
01139    else
01140       hold = "a=sendrecv\r\n";
01141 
01142    /* Now, start adding audio codecs. These are added in this order:
01143       - First what was requested by the calling channel
01144       - Then preferences in order from sip.conf device config for this peer/user
01145       - Then other codecs in capabilities, including video
01146    */
01147 
01148    /* Prefer the audio codec we were requested to use, first, no matter what 
01149       Note that p->prefcodec can include video codecs, so mask them out
01150     */
01151    if (capability & p->prefcodec) {
01152       add_codec_to_sdp(p, p->prefcodec & AST_FORMAT_AUDIO_MASK, 8000,
01153              &m_audio_next, &m_audio_left,
01154              &a_audio_next, &a_audio_left,
01155              debug, &min_audio_packet_size);
01156       alreadysent |= p->prefcodec & AST_FORMAT_AUDIO_MASK;
01157    }
01158 
01159 
01160    /* Start by sending our preferred audio codecs */
01161    for (x = 0; x < 32; x++) {
01162       int pref_codec;
01163 
01164       if (!(pref_codec = ast_codec_pref_index(&p->prefs, x)))
01165          break; 
01166 
01167       if (!(capability & pref_codec))
01168          continue;
01169 
01170       if (alreadysent & pref_codec)
01171          continue;
01172 
01173       add_codec_to_sdp(p, pref_codec, 8000,
01174              &m_audio_next, &m_audio_left,
01175              &a_audio_next, &a_audio_left,
01176              debug, &min_audio_packet_size);
01177       alreadysent |= pref_codec;
01178    }
01179 
01180    /* Now send any other common audio and video codecs, and non-codec formats: */
01181    for (x = 1; x <= (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO); x <<= 1) {
01182       if (!(capability & x))  /* Codec not requested */
01183          continue;
01184 
01185       if (alreadysent & x) /* Already added to SDP */
01186          continue;
01187 
01188       if (x <= AST_FORMAT_MAX_AUDIO)
01189          add_codec_to_sdp(p, x, 8000,
01190                 &m_audio_next, &m_audio_left,
01191                 &a_audio_next, &a_audio_left,
01192                 debug, &min_audio_packet_size);
01193       else 
01194          add_codec_to_sdp(p, x, 90000,
01195                 &m_video_next, &m_video_left,
01196                 &a_video_next, &a_video_left,
01197                 debug, &min_video_packet_size);
01198    }
01199 
01200    /* Now add DTMF RFC2833 telephony-event as a codec */
01201    for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
01202       if (!(p->jointnoncodeccapability & x))
01203          continue;
01204 
01205       add_noncodec_to_sdp(p, x, 8000,
01206                 &m_audio_next, &m_audio_left,
01207                 &a_audio_next, &a_audio_left,
01208                 debug);
01209    }
01210 
01211    if (option_debug > 2)
01212       ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
01213 
01214    if(!p->owner || !ast_internal_timing_enabled(p->owner))
01215       ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
01216    if (min_audio_packet_size)
01217       ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
01218 
01219    if (min_video_packet_size)
01220       ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
01221 
01222 
01223    if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
01224       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
01225 
01226    ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
01227    if (needvideo)
01228       ast_build_string(&m_video_next, &m_video_left, "\r\n");
01229 
01230    len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
01231    if (needvideo) /* only if video response is appropriate */
01232       len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
01233 
01234    add_header(resp, "Content-Type", "application/sdp");
01235    add_header_contentLength(resp, len);
01236    add_line(resp, version);
01237    add_line(resp, owner);
01238    add_line(resp, subject);
01239    add_line(resp, connection);
01240    if (needvideo)    /* only if video response is appropriate */
01241       add_line(resp, bandwidth);
01242    add_line(resp, stime);
01243    add_line(resp, m_audio);
01244    add_line(resp, a_audio);
01245    add_line(resp, hold);
01246    if (needvideo) { /* only if video response is appropriate */
01247       add_line(resp, m_video);
01248       add_line(resp, a_video);
01249       add_line(resp, hold);   /* Repeat hold for the video stream */
01250    }
01251 
01252    /* Update lastrtprx when we send our SDP */
01253    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
01254 
01255    if (option_debug > 2) {
01256       char buf[BUFSIZ];
01257       ast_log(LOG_DEBUG, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, BUFSIZ, capability));
01258    }
01259 
01260    return 0;
01261 }
01262 
01263 /*! \brief Return SIP UA's codec (part of the RTP interface) */
01264 static int sip_get_codec(struct ast_channel *chan)
01265 {
01266    struct sip_dialog *p = chan->tech_pvt;
01267    return p->peercapability;  
01268 }
01269 
01270 /*! \brief Read RTP from network */
01271 static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_dialog *p, int *faxdetect)
01272 {
01273    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
01274    struct ast_frame *f;
01275    
01276    if (!p->rtp) {
01277       /* We have no RTP allocated for this channel */
01278       return &ast_null_frame;
01279    }
01280 
01281    switch(ast->fdno) {
01282    case 0:
01283       f = ast_rtp_read(p->rtp);  /* RTP Audio */
01284       break;
01285    case 1:
01286       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
01287       break;
01288    case 2:
01289       f = ast_rtp_read(p->vrtp); /* RTP Video */
01290       break;
01291    case 3:
01292       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
01293       break;
01294    case 5:
01295       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
01296       break;
01297    default:
01298       f = &ast_null_frame;
01299    }
01300    /* Don't forward RFC2833 if we're not supposed to */
01301    if (f && (f->frametype == AST_FRAME_DTMF) &&
01302        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833))
01303       return &ast_null_frame;
01304 
01305    if (p->owner) {
01306       /* We already hold the channel lock */
01307       if (f->frametype == AST_FRAME_VOICE) {
01308          if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
01309             if (option_debug)
01310                ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
01311             p->owner->nativeformats = (p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass;
01312             ast_set_read_format(p->owner, p->owner->readformat);
01313             ast_set_write_format(p->owner, p->owner->writeformat);
01314          }
01315          if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
01316             f = ast_dsp_process(p->owner, p->vad, f);
01317             if (f && f->frametype == AST_FRAME_DTMF) {
01318                if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && f->subclass == 'f') {
01319                   if (option_debug)
01320                      ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
01321                   *faxdetect = 1;
01322                } else if (option_debug) {
01323                   ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
01324                }
01325             }
01326          }
01327       }
01328    }
01329    return f;
01330 }
01331 
01332 /*! \brief Read SIP RTP from channel */
01333 GNURK struct ast_frame *sip_read(struct ast_channel *ast)
01334 {
01335    struct ast_frame *fr;
01336    struct sip_dialog *p = ast->tech_pvt;
01337    int faxdetected = FALSE;
01338 
01339    dialog_lock(p, TRUE);
01340    fr = sip_rtp_read(ast, p, &faxdetected);
01341    p->lastrtprx = time(NULL);
01342 
01343    /* If we are NOT bridged to another channel, and we have detected fax tone we issue T38 re-invite to a peer */
01344    /* If we are bridged then it is the responsibility of the SIP device to issue T38 re-invite if it detects CNG or fax preamble */
01345    if (faxdetected && ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_UDPTL) && (p->t38.state == T38_DISABLED) && !(ast_bridged_channel(ast))) {
01346       if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
01347          if (!p->pendinginvite) {
01348             if (option_debug > 2)
01349                ast_log(LOG_DEBUG, "Sending reinvite on SIP (%s) for T.38 negotiation.\n",ast->name);
01350             p->t38.state = T38_LOCAL_REINVITE;
01351             transmit_reinvite_with_sdp(p, TRUE);
01352             if (option_debug > 1)
01353                ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, ast->name);
01354          } 
01355       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
01356          if (option_debug > 2)
01357             ast_log(LOG_DEBUG, "Deferring reinvite on SIP (%s) - it will be re-negotiated for T.38\n", ast->name);
01358          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
01359       }  else if (option_debug > 3) {
01360          ast_log(LOG_DEBUG, "Fax deteced but discarded because another transaction is already in progress.\n");
01361          /* \note Should we turn on a flag and send re-invite for fax at a later stage? */
01362       }
01363    }
01364    dialog_lock(p, FALSE);
01365 
01366    return fr;
01367 }
01368 
01369 /*! \brief Get UDPTL peer address (part of UDPTL interface) */
01370 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
01371 {
01372    struct sip_dialog *p;
01373    struct ast_udptl *udptl = NULL;
01374    
01375    p = chan->tech_pvt;
01376    if (!p || !(p->udptl))
01377       return NULL;
01378    
01379    dialog_lock(p, TRUE);
01380    /*  T38 reinvites is something very different from media re-invites to optimize
01381       the media stream. They should not rely on the CAN_REINVITE setting
01382       if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE)) */
01383    udptl = p->udptl;
01384    dialog_lock(p, FALSE);
01385    return udptl;
01386 }
01387 
01388 /*! \brief Determine UDPTL peer address for re-invite (part of UDPTL interface) */
01389 static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
01390 {
01391    struct sip_dialog *p;
01392    
01393    p = chan->tech_pvt;
01394    if (!p)
01395       return -1;
01396    ast_mutex_lock(&p->lock);
01397    if (udptl)
01398       ast_udptl_get_peer(udptl, &p->udptlredirip);
01399    else
01400       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
01401    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
01402       if (!p->pendinginvite) {
01403          if (option_debug > 2) 
01404             ast_log(LOG_DEBUG, "Sending T38 reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
01405          transmit_reinvite_with_sdp(p, TRUE);
01406       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
01407          if (option_debug > 2) {
01408             ast_log(LOG_DEBUG, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
01409          }
01410          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
01411       }
01412    }
01413    /* Reset lastrtprx timer */
01414    p->lastrtprx = p->lastrtptx = time(NULL);
01415    ast_mutex_unlock(&p->lock);
01416    return 0;
01417 }
01418 
01419 
01420 /*! \brief Immediately stop RTP, VRTP and UDPTL as applicable */
01421 void stop_media_flows(struct sip_dialog *dialog)
01422 {
01423    if (option_debug > 4 && sipdebug)
01424       ast_log(LOG_DEBUG, "Stopping media flow for %s\n", dialog->callid);
01425    /* Immediately stop RTP, VRTP and UDPTL as applicable */
01426    if (dialog->rtp)
01427       ast_rtp_stop(dialog->rtp);
01428    if (dialog->vrtp)
01429       ast_rtp_stop(dialog->vrtp);
01430    if (dialog->udptl)
01431       ast_udptl_stop(dialog->udptl);
01432 }

Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen