SdpSession.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:33k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const SdpSession_cxx_Version =
  51.     "$Id: SdpSession.cxx,v 1.33 2001/07/25 23:04:14 bko Exp $";
  52. #include "debug.h"
  53. #include <cassert>
  54. #include <time.h>
  55. #include <strstream>
  56. #include "SdpExceptions.hxx"
  57. #include "SdpSession.hxx"
  58. // Other files can include "SdpExterns.hxx" to reference the following
  59. // const char []s
  60. const char SdpNetworkTypeIN[] = "IN";
  61. const char SdpAddressTypeIP4[] = "IP4";
  62. const char SdpAddressTypeIP6[] = "IP6";
  63. const char SdpMediaTransportRTPAVP[] = "RTP/AVP";
  64. const char SdpMediaTransportUDP[] = "UDP";
  65. const char SdpBandwidthModifierAS[] = "AS";  // Application specific maximum
  66. const char SdpBandwidthModifierCT[] = "CT";  // Conference Total
  67. const char SdpMediaTypeAudio[] = "audio";
  68. const char SdpMediaTypeVideo[] = "video";
  69. const char SdpAttributeRecvonly[] = "recvonly";
  70. const char SdpAttributeSendrecv[] = "sendrecv";
  71. const char SdpAttributeSendonly[] = "sendonly";
  72. const char SdpEncryptkeyMethodClear[] = "clear";
  73. const char SdpEncryptkeyMethodBase64[] = "base64";
  74. const char SdpEncryptkeyMethodURI[] = "uri";
  75. const char SdpEncryptkeyMethodPrompt[] = "prompt";
  76. // When adding a new const char [], add the corresponding extern declaration
  77. // in "SdpExterns.hxx"
  78. ///
  79. SdpSession::SdpSession()
  80.         : emailList(), phoneList(), sdpTimeList()
  81. {
  82.     protocolType = SdpProtocolTypeSDP;
  83.     protocolVersion = 0;
  84.     username = "-";
  85.     // Use NTP time
  86.     sessionId = static_cast < unsigned int > (time(NULL) + SdpTime::NTP_UX_DIFF);
  87.     // Use NTP time
  88.     version = static_cast < unsigned int > (time(NULL) + SdpTime::NTP_UX_DIFF);
  89.     networkType = NetworkTypeInternet;
  90.     addressType = AddressTypeIPV4;
  91.     address = "0.0.0.0";
  92.     sessionName = "-";
  93.     sessionName = "";
  94.     uriInfo = "";
  95.     emailList.clear();
  96.     phoneList.clear();
  97.     connection = 0;
  98.     attribute = 0;
  99.     bandwidth = 0;
  100.     
  101.     encryptkey = 0;
  102.     SdpTime time;
  103.     sdpTimeList.push_back (time);
  104.     zoneAdjustmentList.clear();
  105.     flushMediaList();
  106.     isValid = false;
  107. }    // SdpSession::SdpSession
  108. ///
  109. SdpSession::SdpSession (const SdpSession& x)
  110. {
  111.     connection = 0;
  112.     attribute = 0;
  113.     bandwidth = 0;
  114.     encryptkey = 0;
  115.     flushMediaList();
  116.     *this = x;
  117. }    // SdpSession::SdpSession
  118. ///
  119. SdpSession::~SdpSession()
  120. {
  121.     if (connection)
  122.     {
  123.         delete connection;
  124.     }
  125.     if (attribute)
  126.     {
  127.         delete attribute;
  128.     }
  129.     if (bandwidth)
  130.     {
  131.         delete bandwidth;
  132.     }
  133.     if (encryptkey)
  134.     {
  135.         delete encryptkey;
  136.     }
  137.     flushMediaList();
  138. }    // SdpSession::~SdpSession
  139. SdpSession&
  140. SdpSession::operator= (const SdpSession& x)
  141. {
  142.     protocolVersion = x.protocolVersion;
  143.     username = x.username;
  144.     sessionId = x.sessionId;
  145.     version = x.version;
  146.     networkType = x.networkType;
  147.     addressType = x.addressType;
  148.     address = x.address;
  149.     sessionName = x.sessionName;
  150.     sessionInfo = x.sessionInfo;
  151.     uriInfo = x.uriInfo;
  152.     emailList = x.emailList;
  153.     phoneList = x.phoneList;
  154.     if (x.connection)
  155.     {
  156.         if (!connection)
  157.         {
  158.             connection = new SdpConnection;
  159.             assert(connection);
  160.         }
  161.         *(connection) = *(x.connection);
  162.         cpLog(LOG_DEBUG_STACK, "Copied connection");
  163.     }
  164.     else
  165.     {
  166.         if (connection)
  167.         {
  168.             delete connection;
  169.             connection = 0;
  170.         }
  171.     }
  172.     if (x.bandwidth)
  173.     {
  174.         if (!bandwidth)
  175.         {
  176.             bandwidth = new SdpBandwidth;
  177.             assert(bandwidth);
  178.         }
  179.         *(bandwidth) = *(x.bandwidth);
  180.         cpLog(LOG_DEBUG_STACK, "copied bandwidth");
  181.     }
  182.     else
  183.     {
  184.         if (bandwidth)
  185.         {
  186.             delete bandwidth;
  187.             bandwidth = 0;
  188.         }
  189.     }
  190.     sdpTimeList.clear();
  191.     sdpTimeList = x.getSdpTimeList();
  192.     zoneAdjustmentList = x.zoneAdjustmentList;;
  193.     if (x.encryptkey)
  194.     {
  195.         if (!encryptkey)
  196.         {
  197.             encryptkey = new SdpEncryptkey;
  198.             assert(encryptkey);
  199.         }
  200.         *(encryptkey) = *(x.encryptkey);
  201.         cpLog(LOG_DEBUG_STACK, "copied encryptkey");
  202.     }
  203.     else
  204.     {
  205.         if (encryptkey)
  206.         {
  207.             delete encryptkey;
  208.             encryptkey = 0;
  209.         }
  210.     }
  211.     if (x.attribute)
  212.     {
  213.         if (!attribute)
  214.         {
  215.             attribute = new SdpAttributes;
  216.             assert(attribute);
  217.         }
  218.         *(attribute) = *(x.attribute);
  219.         cpLog(LOG_DEBUG_STACK, "copied attribute");
  220.     }
  221.     else
  222.     {
  223.         if (attribute)
  224.         {
  225.             delete attribute;
  226.             attribute = 0;
  227.         }
  228.     }
  229.     //copy contents of objects pointed by the mediaList.
  230.     // we need to flush the previous values
  231.     vector < SdpMedia* > newMediaList = x.getMediaList();
  232.     flushMediaList();
  233.     if (newMediaList.size() > 0)
  234.     {
  235.         vector < SdpMedia* > ::iterator mediaiter;
  236.         mediaiter = newMediaList.begin();
  237.         while (mediaiter != newMediaList.end())
  238.         {
  239.             cpLog(LOG_DEBUG_STACK, "Obtained one mediaiter");
  240.             if (*mediaiter)
  241.             {
  242.                 // create new of media and assign values.
  243.                 SdpMedia* media = new SdpMedia;
  244.                 assert(media);
  245.                 *media = *(*mediaiter);
  246.                 //store in the vector.
  247.                 addMedia(media);
  248.             }
  249.             ++mediaiter;
  250.         }
  251.     }
  252.     buf[0] = '';
  253.     isValid = x.isValid;
  254.     return (*this);
  255. }    // SdpSession::operator=
  256. #if 0
  257. bool
  258. SdpSession::operator== (const SdpSession& x) const
  259. {
  260.     /// xxx not implemented
  261.     assert(0);
  262.     return false;
  263. }
  264. #endif
  265. void
  266. SdpSession::clearSdpTimeList ()
  267. {
  268.     sdpTimeList.clear();
  269.     isValid = false;
  270. }    // SdpSession::addTime
  271. void
  272. SdpSession::addTime (const SdpTime& time)
  273. {
  274.     sdpTimeList.push_back (time);
  275.     isValid = true;
  276. }    // SdpSession::addTime
  277. ///
  278. void
  279. SdpSession::setBandwidth (SdpBandwidth& bw)
  280. {
  281.     if (!bandwidth)
  282.     {
  283.         bandwidth = new SdpBandwidth;
  284.     }
  285.     *bandwidth = bw;
  286. }    // SdpSession::setBandwidth
  287. ///
  288. void
  289. SdpSession::setNcs ()
  290. {
  291.     setUserName (string("-"));
  292.     // User needs to call setAddress()
  293.     setSessionName (string("-"));
  294.     // No "i="
  295.     // No "u="
  296.     // No "e="
  297.     // No "p="
  298.     SdpConnection conn;
  299.     // User needs to call setUnicast()
  300.     setConnection (conn);
  301.     SdpBandwidth bw;
  302.     setBandwidth (bw);
  303.     sdpTimeList.clear();
  304.     SdpTime time;
  305.     addTime (time);
  306.     // No "k="
  307.     // User add attribute("a=") lines
  308.     SdpMedia* media = new SdpMedia;
  309.     // User needs to call SdpMedia::setPort()
  310.     addMedia (media);
  311. }    // SdpSession::setNcs
  312. ///
  313. void
  314. SdpSession::setProtocolType (SdpProtocolType protocol)
  315. {
  316.     protocolType = protocol;
  317.     // Setup this SDP according to the corresponding protocol
  318.     if (protocol == SdpProtocolTypeNCS)
  319.     {
  320.         setNcs ();
  321.     }
  322. }    // SdpSession::setProtocolType
  323. ///
  324. SdpProtocolType
  325. SdpSession::getProtocolType ()
  326. {
  327.     return protocolType;
  328. }    // SdpSession::getProtocolType
  329. ///
  330. void
  331. SdpSession::encodeVersion (ostrstream& s)
  332. {
  333.     // v=0 by default - no other value as of now
  334.     s << "v=" << protocolVersion << "rn";
  335. }    // SdpSession::encode
  336. ///
  337. string
  338. SdpSession::networkTypeString()
  339. {
  340.     string s;
  341.     switch (networkType)
  342.     {
  343.         case NetworkTypeInternet:
  344.         {
  345.             s = SdpNetworkTypeIN;
  346.             break;
  347.         }
  348.         default:
  349.         {
  350.     // Network type corrupted
  351.     assert(0);
  352.             break;
  353.         }
  354.     }
  355.     return s;
  356. }    // SdpSession::networkTypeString
  357. ///
  358. string
  359. SdpSession::addressTypeString()
  360. {
  361.     string s;
  362.     switch (addressType)
  363.     {
  364.         case AddressTypeIPV4:
  365.         {
  366.             s = SdpAddressTypeIP4;
  367.             break;
  368.         }
  369.         case AddressTypeIPV6:
  370.         {
  371.             s = SdpAddressTypeIP6;
  372.             break;
  373.         }
  374.         default:
  375.         {
  376.     // Address type corrupted
  377.     assert(0);
  378.             break;
  379.         }
  380.     }
  381.     return s;
  382. }    // SdpSession::addressTypeString
  383. ///
  384. void
  385. SdpSession::encodeOrigin (ostrstream& s)
  386. {
  387.     s << "o=" << username
  388.     << ' '
  389.     << sessionId
  390.     << ' '
  391.     << version
  392.     << ' '
  393.     << networkTypeString()
  394.     << ' '
  395.     << addressTypeString()
  396.     << ' '
  397.     << address
  398.     << "rn";
  399. }    // SdpSession::encodeOrigin
  400. ///
  401. void
  402. SdpSession::encodeSessionName (ostrstream& s)
  403. {
  404.     s << "s=" << sessionName << "rn";
  405. }    // SdpSession::encodeSessionName
  406. ///
  407. void
  408. SdpSession::encodeSessionInformation (ostrstream& s)
  409. {    
  410.     if (sessionInfo.size() > 0)
  411.     {
  412.         s << "i=" << sessionInfo << "rn";
  413.     }
  414. }    // SdpSession::encodeSessionInformation
  415. ///
  416. void
  417. SdpSession::encodeURI (ostrstream& s)
  418. {
  419.     if (uriInfo.size() > 0)
  420.     {
  421.         s << "u=" << uriInfo << "rn";
  422.     }
  423. }    // SdpSession::encodeURI
  424. ///
  425. void
  426. SdpSession::encodeEmailAddress (ostrstream& s)
  427. {
  428.     vector<string>::iterator iter = emailList.begin();
  429.     while (iter != emailList.end())
  430.     {
  431.         s << "e=" << *iter << "rn";
  432.         ++iter;
  433.     }
  434. }    // SdpSession::encodeEmailAddress
  435. ///
  436. void
  437. SdpSession::encodePhoneNumber (ostrstream& s)
  438. {
  439.     vector<string>::iterator iter = phoneList.begin();
  440.     while (iter != phoneList.end())
  441.     {
  442.                 s << "p=" << *iter << "rn";
  443.         ++iter;
  444.     }
  445. }    // SdpSession::encodePhoneNumber
  446. ///
  447. void
  448. SdpSession::encodeTime (ostrstream& s)
  449. {
  450.     vector < SdpTime > ::iterator iter = sdpTimeList.begin();
  451.     while (iter != sdpTimeList.end())
  452.     {
  453.         iter->encode (s);
  454.         ++iter;
  455.     }
  456. }    // SdpSession::encodeTime
  457. ///
  458. void
  459. SdpSession::encodeTimeZoneAdjustment (ostrstream& s)
  460. {
  461.     if (zoneAdjustmentList.size() > 0)
  462.     {
  463.         vector<SdpZoneAdjustment>::iterator iter;
  464.         iter = zoneAdjustmentList.begin();
  465.         s << "z=" << (*iter).getAdjustmentTime() << ' ' << (*iter).getOffset();
  466.         ++iter;
  467.         while (iter != zoneAdjustmentList.end())
  468.         {
  469.             s << ' ' << (*iter).getAdjustmentTime() << ' ' << (*iter).getOffset();
  470.             ++iter;
  471.         }
  472.     
  473.         s << "rn";
  474.     }
  475. }    // SdpSession::encodeTimeZoneAdjustment
  476. ///
  477. void
  478. SdpSession::encodeMedia (ostrstream& s)
  479. {
  480.     vector < SdpMedia* > ::iterator mediaIterator = mediaList.begin();
  481.     while (mediaIterator != mediaList.end())
  482.     {
  483.         (*mediaIterator)->encode (s);
  484.         ++mediaIterator;
  485.     }
  486. }    // SdpSession::encodeMedia
  487. ///
  488. void
  489. SdpSession::setConnection (const SdpConnection& conn)
  490. {
  491.     if (!connection)
  492.     {
  493.         connection = new SdpConnection;
  494.     }
  495.     *connection = conn;
  496. } // SdpSession::setConnection
  497. ///
  498. SdpConnection*
  499. SdpSession::getConnection ()
  500. {
  501.     return connection;
  502. } // SdpSession::getConnection
  503. ///
  504. static const int SdpTextPayloadLength = 1024;
  505. ///
  506. string
  507. SdpSession::encode()
  508. {
  509.     buf[0] = '';
  510.     ostrstream s (buf, SdpTextPayloadLength);
  511.     if (!isValid)
  512.     {
  513.         //TODO throw SdpExceptionInvalid ("Invalid SDP" , __FILE__, __LINE__ );
  514.         // or
  515.         // throw SDPExceptions (InvalidContent);
  516.     }
  517.     else
  518.     {
  519.         // Encoding order is important
  520.         // v=0 by default - no other value as of now
  521.         encodeVersion (s);
  522.         // o= owner/creator and session identifier
  523.         encodeOrigin (s);
  524.         // s= session name
  525.         encodeSessionName (s);
  526.         // i=* session information
  527.         encodeSessionInformation (s);
  528.         // u=* URI of description
  529.         encodeURI (s);
  530.         // e=* email address
  531.         encodeEmailAddress (s);
  532.         // p=* phone number
  533.         encodePhoneNumber (s);
  534.         // c=* connection information (not required if included in all media)
  535.         if (connection)
  536.         {
  537.             connection->encode (s);
  538.         }
  539.         // b=* bandwidth information
  540.         if (bandwidth)
  541.         {
  542.             bandwidth->encode (s);
  543.         }
  544.         // Time Description
  545.         encodeTime (s);
  546.         // z=* time zone adjustment
  547.         encodeTimeZoneAdjustment (s);
  548.         // k=* encryption key
  549. if ( encryptkey )
  550. {
  551.     encryptkey->encode(s);
  552. }
  553.         // a=* zero or more session attribute lines
  554.         if (attribute)
  555.         {
  556.             attribute->encode (s);
  557.         }
  558.         // Media Description
  559.         encodeMedia (s);
  560.     }
  561.     s << ends;
  562.     return s.str();
  563. }    // SdpSession::encode
  564. bool SdpSession::decode(const string& buffer)
  565. {
  566.     split_t lines(split(buffer, "n"));
  567.     bool result = decode(lines);
  568.     return result;
  569. }
  570. bool SdpSession::decode(split_t& lines)
  571. {
  572.     ODEBUG(DEBUG_SDP, 2, cout << "number of lines: " << lines.size() << endl; ) ;
  573.     if (lines.size() < 3)
  574.     {
  575.         cpLog( LOG_ERR, "Sdp decode fail, too few lines" );
  576.         isValid = false;
  577.         return false;
  578.     }
  579.     sdpTimeList.clear();
  580.     split_t::iterator linecount;
  581.     linecount = lines.begin();
  582.     {
  583.         // lines[0] is the version line -- ignore
  584.         string s = (*linecount);
  585.         chomp (&s);
  586.         if (!((*linecount) == "v=0r" || (*linecount) == "v=0"))
  587.             if (!(s == "v=0"))
  588.             {
  589.                 // no good
  590.                 cerr << "SDP: did not find version in:" << endl;
  591.                 cerr << (*linecount) << endl;
  592.                 return false;
  593.             }
  594.         ++linecount;
  595.         while (linecount != lines.end())
  596.         {
  597.             // this switch parses lines as they come
  598.             if ((*linecount)[0] == 'o')
  599.             {
  600.                 ODEBUG(DEBUG_SDP, 2, cout << "got o= line" << endl; ) ;
  601.                 // this is the options line -- do we care about it?
  602.                 // parse line 1 for the proper stuff
  603.                 s = (*linecount);
  604.                 s.erase(0, 2);
  605.                 chomp (&s);
  606.                 split_t optionsList(split(s, " "));
  607.                 if (optionsList.size() < 6)
  608.                 {
  609.                     // not enough parameters
  610.                     cpLog( LOG_ERR, "Parameter count < 6: %s", (*linecount).c_str() );
  611.                     if ( linecount != lines.end() )
  612.                     {
  613.                         ++linecount;
  614.                     }
  615.                     continue;
  616.                 }
  617.                 username = optionsList[0];
  618.                 sessionId = atoi(optionsList[1].c_str());
  619.                 version = atoi(optionsList[2].c_str());
  620.                 if (optionsList[3] == SdpNetworkTypeIN)
  621.                 {
  622.                     networkType = NetworkTypeInternet;
  623.                 }
  624.                 else
  625.                 {
  626.                     cpLog( LOG_ERR, "Unknown network type %s", optionsList[3].c_str() );
  627.                     if ( linecount != lines.end() )
  628.                     {
  629.                         ++linecount;
  630.                     }
  631.                     continue;
  632.                 }
  633.                 if (optionsList[4] == SdpAddressTypeIP4)
  634.                 {
  635.                     addressType = AddressTypeIPV4;
  636.                 }
  637.                 else if (optionsList[4] == SdpAddressTypeIP6)
  638.                 {
  639.                     addressType = AddressTypeIPV6;
  640.                 }
  641.                 else
  642.                 {
  643.                     cpLog( LOG_ERR, "Unknown address type %s", optionsList[4].c_str() );
  644.                     if ( linecount != lines.end() )
  645.                     {
  646.                         ++linecount;
  647.                     }
  648.                     continue;
  649.                 }
  650.                 address = optionsList[5].c_str();
  651.             }
  652.             else if ((*linecount)[0] == 's')
  653.             {
  654.                 ODEBUG(DEBUG_SDP, 2, cout << "got s= line" << endl; ) ;
  655.                 s = (*linecount);
  656.                 s.erase(0, 2);
  657.                 chomp (&s);
  658.                 sessionName = s;
  659.             }
  660.             else if((*linecount)[0] == 'i')
  661.             {
  662.                 ODEBUG(DEBUG_SDP, 2, cout << "got i= line" << endl; ) ;
  663.                 s = (*linecount);
  664.                 s.erase(0, 2);
  665.                 chomp (&s);
  666.                 sessionInfo = s;
  667.             }
  668.             else if((*linecount)[0] == 'u')
  669.             {
  670.                 ODEBUG(DEBUG_SDP, 2, cout << "got u= line" << endl; ) ;
  671.                 s = (*linecount);
  672.                 s.erase(0, 2);
  673.                 chomp (&s);
  674.                 uriInfo = s;
  675.             }
  676.     else if((*linecount)[0] == 'e')
  677.     {
  678. // Collect all email addresses
  679.                 while ((linecount != lines.end()) && ((*linecount)[0] == 'e'))
  680.                 {
  681.     cpLog(LOG_DEBUG, "Session: got %s", (*linecount).c_str());
  682.                     s = (*linecount);
  683.                     s.erase(0, 2);
  684.                     chomp (&s);
  685.                     emailList.push_back(s);
  686.     ++linecount;
  687. }
  688.                 if (linecount != lines.end())
  689. {
  690.     // Not done yet, adjust line position 
  691.     --linecount;
  692. }
  693.             }
  694.     else if((*linecount)[0] == 'p')
  695.     {
  696. // Collect all phone numbers
  697.                 while ((linecount != lines.end()) && ((*linecount)[0] == 'p'))
  698.                 {
  699.     cpLog(LOG_DEBUG, "Session: got %s", (*linecount).c_str());
  700.                     s = (*linecount);
  701.                     s.erase(0, 2);
  702.                     chomp (&s);
  703.                     phoneList.push_back(s);
  704.     ++linecount;
  705. }
  706.                 if (linecount != lines.end())
  707. {
  708.     // adjust line position for the next description
  709.     --linecount;
  710. }
  711.             }
  712.             else if ((*linecount)[0] == 'c')
  713.             {
  714.                 ODEBUG(DEBUG_SDP, 2, cout << "got c= line" << endl; ) ;
  715.                 // this is a c= line
  716.                 s = (*linecount);
  717.                 s.erase(0, 2);
  718.                 chomp (&s);
  719.                 //create the connection object, and store details there.
  720.                 try
  721.                 {
  722.                     if (!connection)
  723.                     {
  724.                         connection = new SdpConnection(s);
  725.                         assert (connection);
  726.                     }
  727.                     else
  728.                     {
  729.                         SdpConnection conn (s);
  730.                         (*connection) = conn;
  731.                     }
  732.                 }
  733.                 catch (SdpExceptions& exp)
  734.                 {
  735.                     switch (exp.value)
  736.                     {
  737.                         case UNKNOWN_NETTYPE :
  738.     return false;
  739.     break;
  740. case UNKNOWN_ADDRTYPE :
  741.     return false;
  742.     break;
  743.                         case PARAM_NUMERR :
  744.     return false;
  745.     break;
  746.                         default:
  747.     // Unknown exception
  748.     assert(0);
  749.     break;
  750.                     }
  751.                 }
  752.             }
  753.             else if ((*linecount)[0] == 't')
  754.             {
  755.                 // Collect all Time Descriptions
  756.                 while ((linecount != lines.end()) && ((*linecount)[0] == 't'))
  757.                 {
  758.                     cpLog(LOG_DEBUG_STACK, "Session: got %s", (*linecount).c_str());
  759.                     split_t timeDescriptionLines;  // Holding place for a
  760.    // Time Description
  761.                     timeDescriptionLines.push_back ((*linecount));
  762.                     ++linecount;
  763.                     // Get the optional "r=" line
  764.                     while ((linecount != lines.end()) && ((*linecount)[0] == 'r'))
  765.                     {
  766.                         timeDescriptionLines.push_back ((*linecount));
  767.                         ++linecount;
  768.                     }
  769.                     try
  770.                     {
  771.                         SdpTime time (timeDescriptionLines);
  772.                         sdpTimeList.push_back (time);
  773.                     }
  774.                     catch (SdpExceptions& exp)
  775.                     {
  776.                         if (exp.value == FAILED)
  777.                         {
  778.                             return false;
  779.                         }
  780.                     }
  781.                 }
  782.                 if (linecount != lines.end())
  783.                 {
  784.                     // adjust line position for the next description
  785.                     --linecount;
  786.                 }
  787.             }
  788.     else if((*linecount)[0] == 'z')
  789.     {
  790. cpLog(LOG_DEBUG, "Session: got the "z=" line");
  791. s = (*linecount);
  792. s.erase(0,2);
  793.                 chomp (&s);
  794.                 split_t adjustmentList(split(s, " "));
  795.                 split_t::iterator iter;
  796.                 iter = adjustmentList.begin();
  797.                 while (iter != adjustmentList.end())
  798.                 {
  799.                     SdpZoneAdjustment sza;
  800.                     sza.setAdjustmentTime((*iter));
  801.                     ++iter;
  802.                     if (iter != adjustmentList.end())
  803.                     {
  804. sza.setOffset((*iter));
  805.                         zoneAdjustmentList.push_back(sza);
  806.                         ++iter;
  807.                     }
  808.                     else    // <adjustment time> didn't followed by an <offset>
  809.                     {
  810. sza.setOffset("0");
  811.                         zoneAdjustmentList.push_back(sza);
  812.                         break;
  813.                     }
  814.                 }
  815.     }
  816.             else if ((*linecount)[0] == 'b')
  817.             {
  818.                 cpLog(LOG_DEBUG_STACK, "Session: got the "b=" line");
  819.                 s = (*linecount);
  820.                 s.erase(0, 2);
  821.                 chomp (&s);
  822.                 //create the bandwidth object, and store details there.
  823.                 try
  824.                 {
  825.                     if (!bandwidth)
  826.                     {
  827.                         bandwidth = new SdpBandwidth(s);
  828.                         assert (bandwidth);
  829.                     }
  830.                     else
  831.                     {
  832.                         SdpBandwidth bw (s);
  833.                         (*bandwidth) = bw;
  834.                     }
  835.                 }
  836.                 catch (SdpExceptions& error)
  837.                 {
  838.                     //bandwidth is optional. So do nothing if incorrect.
  839.                 }
  840.             }
  841.     else if((*linecount)[0] == 'k')
  842.     {
  843. cpLog(LOG_DEBUG, "Session: got the "k=" line: %s", 
  844. linecount[0].c_str());
  845. s = (*linecount);
  846. s.erase(0,2);
  847.                 chomp (&s);
  848. //create the encrypttion key object, and store details there.
  849. try
  850. {
  851.     if (!encryptkey)
  852.     {
  853. encryptkey = new SdpEncryptkey(s);
  854. assert (encryptkey);
  855.     }
  856.                     else
  857.                     {
  858.                         SdpEncryptkey key(s);
  859.                         (*encryptkey) = key;
  860.                     }
  861. }
  862. catch (SdpExceptions& error)
  863. {
  864.     //Encryption key is optional. So do nothing if incorrect.
  865. }
  866.             }
  867.             else if ((*linecount)[0] == 'a')
  868.             {
  869.                 //this is the attribute line.
  870.                 cpLog(LOG_DEBUG_STACK, "Session: got the a=line");
  871.                 s = (*linecount).c_str();
  872.                 s.erase(0, 2);
  873.                 chomp (&s);
  874.                 //create the attribute object, if not previously created.
  875.                 if (!attribute)
  876.                 {
  877.                     cpLog(LOG_DEBUG_STACK, "create a session attribute.");
  878.                     attribute = new SdpAttributes();
  879.                     assert(attribute);
  880.                 }
  881.                 try
  882.                 {
  883.                     attribute->setAttribute(s);
  884.                 }
  885.                 catch (SdpExceptions& exp)
  886.                 {
  887.                     //attribute is optional. So do nothing if incorrect.
  888.                 }
  889.             }
  890.             else if ((*linecount)[0] == 'm')
  891.             {
  892.                 string tempstr;
  893.                 //get all m lines until end of SDP msg.
  894.                 while (linecount != lines.end())
  895.                 {
  896.                     split_t mediaDetails;
  897.                     cpLog(LOG_DEBUG_STACK, "Session:got the m= line");
  898.                     cpLog(LOG_DEBUG_STACK, "Session: %s", (*linecount).c_str());
  899.                     (mediaDetails).push_back( (*linecount));  // substring copy.
  900.                     ++linecount;
  901.                     while ( (linecount != lines.end() ) && 
  902.     ((*linecount)[0] != 'm'))
  903.                     {
  904.                         cpLog(LOG_DEBUG_STACK, "%s", (*linecount).c_str());
  905.                         (mediaDetails).push_back( (*linecount));
  906.                         ++linecount;
  907.                     }
  908.                     try
  909.                     {
  910.                         SdpMedia* mediaItm = new SdpMedia(mediaDetails);
  911.                         assert(mediaItm);
  912.                         addMedia(mediaItm);
  913.                     }
  914.                     catch (SdpExceptions& exp)
  915.                     {
  916.                         if (exp.value == FAILED)
  917.                             return false;
  918.                     }
  919.                 } // end of processing of one m line
  920.             }// end of processing all m lines
  921.             else
  922.             {
  923.                 ODEBUG(DEBUG_SDP, 2, cout << "got unknown line" << endl; ) ;
  924.                 ODEBUG(DEBUG_SDP, 2, cout << "line: " << (*linecount) << endl; );
  925.             }
  926.             // We might have reached the end in processing m field.
  927.             // In that case, we don't increment linecount
  928.             if ( linecount != lines.end() )
  929.             {
  930.                 ++linecount;
  931.             }
  932.         }
  933.     }
  934.     isValid = true;
  935.     return true;
  936. }
  937. ///
  938. void
  939. SdpSession::flushMediaList()
  940. {
  941.     if (mediaList.empty())
  942.     {
  943.         return ;
  944.     }
  945.     vector < SdpMedia* > ::iterator iter = mediaList.begin();
  946.     while (iter != mediaList.end())
  947.     {
  948.         if (*iter)
  949.         {
  950.             delete (*iter);
  951.         }
  952.         ++iter;
  953.     }
  954.     mediaList.clear();
  955. }    // SdpSession::flushMediaList
  956. ///
  957. void
  958. SdpSession::reset()
  959. {
  960.     protocolType = SdpProtocolTypeSDP;
  961.     protocolVersion = 0;
  962.     username = "-";
  963.     //TODO Use NTP time
  964.     sessionId = static_cast < unsigned int > (time(NULL));
  965.     //TODO Use NTP time
  966.     version = static_cast < unsigned int > (time(NULL));
  967.     networkType = NetworkTypeInternet;
  968.     addressType = AddressTypeIPV4;
  969.     address = "0.0.0.0";
  970.     sessionName = "-";
  971.     if ( 0 != connection )
  972.     {
  973. delete connection;
  974. connection = 0;
  975.     }
  976.     if ( 0 != attribute )
  977.     {
  978. delete attribute;
  979. attribute = 0;
  980.     }
  981.     if ( 0 != bandwidth )
  982.     {
  983. delete bandwidth;
  984. bandwidth = 0;
  985.     }
  986.     if ( 0 != encryptkey )
  987.     {
  988. delete encryptkey;
  989. encryptkey = 0;
  990.     }
  991.     SdpTime time;
  992.     sdpTimeList.clear();
  993.     sdpTimeList.push_back (time);
  994.     isValid = false;
  995.     flushMediaList();
  996.     // Take care of some of the new components added.
  997.     zoneAdjustmentList.clear();
  998.     phoneList.clear();
  999.     emailList.clear();
  1000.     uriInfo = "";
  1001.     sessionInfo = "";
  1002. }    // SdpSession::SdpSession
  1003. ///
  1004. bool
  1005. SdpSession::conformToSdp ()
  1006. {
  1007.     bool rc = true;
  1008.     if (protocolVersion != 0)
  1009.     {
  1010.         cpLog (LOG_WARNING, "SdpSession::conformToSdp - protocol version %d",
  1011.                protocolVersion);
  1012.         rc = false;
  1013.     }
  1014.     if (networkType == NetworkTypeUnknown)
  1015.     {
  1016.         cpLog (LOG_WARNING, "SdpSession::conformToSdp - unknown network type");
  1017.         rc = false;
  1018.     }
  1019.     if (addressType == AddressTypeUnknown)
  1020.     {
  1021.         cpLog (LOG_WARNING, "SdpSession::conformToSdp - unknown address type");
  1022.         rc = false;
  1023.     }
  1024.     if (sdpTimeList.empty())
  1025.     {
  1026.         cpLog (LOG_WARNING, "SdpSession::conformToSdp - no time description");
  1027.         rc = false;
  1028.     }
  1029.     else
  1030.     {
  1031.         cpLog (LOG_DEBUG_STACK, "SdpSession::conformToSdp - PASSED");
  1032.     }
  1033.     return rc;
  1034. }    // SdpSession::conformToSdp
  1035. ///
  1036. bool
  1037. SdpSession::conformToNcs ()
  1038. {
  1039.     bool rc = true;
  1040.     if (protocolVersion != 0)
  1041.     {
  1042.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - protocol version %d",
  1043.                protocolVersion);
  1044.         rc = false;
  1045.     }
  1046.     if (username != "-")
  1047.     {
  1048.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - username %s",
  1049.                username.c_str());
  1050.         rc = false;
  1051.     }
  1052.     if (networkType != NetworkTypeInternet)
  1053.     {
  1054.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - network type %s",
  1055.                networkTypeString().c_str());
  1056.         rc = false;
  1057.     }
  1058.     if (addressType != AddressTypeIPV4)
  1059.     {
  1060.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - address type %s",
  1061.                addressTypeString().c_str());
  1062.         rc = false;
  1063.     }
  1064.     if (sessionName != "-")
  1065.     {
  1066.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - sessionName %s",
  1067.                sessionName.c_str());
  1068.         rc = false;
  1069.     }
  1070.     // No "i="
  1071.     // No "u="
  1072.     // No "e="
  1073.     // No "p="
  1074.     if (connection == 0)
  1075.     {
  1076.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - no connection");
  1077.         rc = false;
  1078.     }
  1079.     else if (connection->getNetworkType() != NetworkTypeInternet)
  1080.     {
  1081.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - network type %d",
  1082.                connection->getNetworkType());
  1083.         rc = false;
  1084.     }
  1085.     else if (connection->getAddressType() != AddressTypeIPV4)
  1086.     {
  1087.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - address type %d",
  1088.                connection->getAddressType());
  1089.         rc = false;
  1090.     }
  1091.     else if (connection->getMulticast() != 0)
  1092.     {
  1093.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - not unicast");
  1094.         rc = false;
  1095.     }
  1096.     if (bandwidth == 0)
  1097.     {
  1098.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - no bandwidth");
  1099.         rc = false;
  1100.     }
  1101.     else if (bandwidth->getModifier() != BandwidthModifierTypeAS)
  1102.     {
  1103.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - bandwidth modifier %d",
  1104.                bandwidth->getModifier());
  1105.         rc = false;
  1106.     }
  1107.     if (sdpTimeList.empty())
  1108.     {
  1109.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - no time description");
  1110.         rc = false;
  1111.     }
  1112.     //TODO more time checking of stopTime == 0, no Repeat, no Time Zones
  1113.     // No "k="
  1114.     //TODO attribute("a=") lines like a=ptime:<value>
  1115.     if (mediaList.empty())
  1116.     {
  1117.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - no media");
  1118.         rc = false;
  1119.     }
  1120.     else if (mediaList[0]->getMediaType() != MediaTypeAudio)
  1121.     {
  1122.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - not audio media");
  1123.         rc = false;
  1124.     }
  1125.     else if (mediaList[0]->getTransportType() != TransportTypeRTP)
  1126.     {
  1127.         cpLog (LOG_WARNING, "SdpSession::conformToNcs - not RTP/AVP");
  1128.         rc = false;
  1129.     }
  1130.     else
  1131.     {
  1132.         cpLog (LOG_DEBUG_STACK, "SdpSession::conformToNcs - PASSED");
  1133.     }
  1134.     return rc;
  1135. }    // SdpSession::conformToNcs
  1136. /// Verify if this a well formed SDP according to protocol
  1137. bool
  1138. SdpSession::verify (SdpProtocolType protocol /*Default Argument*/)
  1139. {
  1140.     bool rc = true;
  1141.     if (protocol == SdpProtocolTypeSDP)
  1142.     {
  1143.         rc = conformToSdp ();
  1144.     }
  1145.     else if (protocol == SdpProtocolTypeNCS)
  1146.     {
  1147.         rc = conformToNcs ();
  1148.     }
  1149.     //TODO verify other protocol types
  1150.     if (!rc)
  1151.     {
  1152.         cpLog (LOG_WARNING, "SdpSession::verify - FAILED");
  1153.     }
  1154.     return rc;
  1155. }    // SdpSession::verify
  1156. ///
  1157. void
  1158. SdpSession::setHold ()
  1159. {
  1160.     if (connection)
  1161.     {
  1162.         connection->setHold();
  1163.     }
  1164.     else
  1165.     {
  1166.         // TODO should we do something here
  1167.         cpLog (LOG_ERR, "SdpSession::setHold: Session connection doesn't exist");
  1168.     }
  1169.     return ;
  1170. }
  1171. ///
  1172. bool
  1173. SdpSession::isHold ()
  1174. {
  1175.     if (connection)
  1176.     {
  1177.         return connection->isHold();
  1178.     }
  1179.     else
  1180.     {
  1181.         // TODO should we do something here
  1182.         cpLog (LOG_ERR, "SdpSession::isHold: Session connection doesn't exist");
  1183.         return false;
  1184.     }
  1185. }