Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2010, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifndef TALK_P2P_BASE_SESSIONMESSAGES_H_
     29 #define TALK_P2P_BASE_SESSIONMESSAGES_H_
     30 
     31 #include <string>
     32 #include <vector>
     33 #include <map>
     34 
     35 #include "talk/base/basictypes.h"
     36 #include "talk/p2p/base/constants.h"
     37 #include "talk/p2p/base/parsing.h"
     38 #include "talk/p2p/base/sessiondescription.h"  // Needed to delete contents.
     39 #include "talk/p2p/base/transportinfo.h"
     40 #include "talk/xmllite/xmlelement.h"
     41 
     42 namespace cricket {
     43 
     44 struct ParseError;
     45 struct WriteError;
     46 class Candidate;
     47 class ContentParser;
     48 class TransportParser;
     49 
     50 typedef std::vector<Candidate> Candidates;
     51 typedef std::map<std::string, ContentParser*> ContentParserMap;
     52 typedef std::map<std::string, TransportParser*> TransportParserMap;
     53 
     54 enum ActionType {
     55   ACTION_UNKNOWN,
     56 
     57   ACTION_SESSION_INITIATE,
     58   ACTION_SESSION_INFO,
     59   ACTION_SESSION_ACCEPT,
     60   ACTION_SESSION_REJECT,
     61   ACTION_SESSION_TERMINATE,
     62 
     63   ACTION_TRANSPORT_INFO,
     64   ACTION_TRANSPORT_ACCEPT,
     65 
     66   ACTION_DESCRIPTION_INFO,
     67 };
     68 
     69 // Abstraction of a <jingle> element within an <iq> stanza, per XMPP
     70 // standard XEP-166.  Can be serialized into multiple protocols,
     71 // including the standard (Jingle) and the draft standard (Gingle).
     72 // In general, used to communicate actions related to a p2p session,
     73 // such accept, initiate, terminate, etc.
     74 
     75 struct SessionMessage {
     76   SessionMessage() : action_elem(NULL), stanza(NULL) {}
     77 
     78   SessionMessage(SignalingProtocol protocol, ActionType type,
     79                  const std::string& sid, const std::string& initiator) :
     80       protocol(protocol), type(type), sid(sid), initiator(initiator),
     81       action_elem(NULL), stanza(NULL) {}
     82 
     83   std::string id;
     84   std::string from;
     85   std::string to;
     86   SignalingProtocol protocol;
     87   ActionType type;
     88   std::string sid;  // session id
     89   std::string initiator;
     90 
     91   // Used for further parsing when necessary.
     92   // Represents <session> or <jingle>.
     93   const buzz::XmlElement* action_elem;
     94   // Mostly used for debugging.
     95   const buzz::XmlElement* stanza;
     96 };
     97 
     98 // TODO: Break up this class so we don't have to typedef it into
     99 // different classes.
    100 struct ContentMessage {
    101   ContentMessage() : owns_contents(false) {}
    102 
    103   ~ContentMessage() {
    104     if (owns_contents) {
    105       for (ContentInfos::iterator content = contents.begin();
    106            content != contents.end(); content++) {
    107         delete content->description;
    108       }
    109     }
    110   }
    111 
    112   // Caller takes ownership of contents.
    113   ContentInfos ClearContents() {
    114     ContentInfos out;
    115     contents.swap(out);
    116     owns_contents = false;
    117     return out;
    118   }
    119 
    120   bool owns_contents;
    121   ContentInfos contents;
    122   TransportInfos transports;
    123   ContentGroups groups;
    124 };
    125 
    126 typedef ContentMessage SessionInitiate;
    127 typedef ContentMessage SessionAccept;
    128 // Note that a DescriptionInfo does not have TransportInfos.
    129 typedef ContentMessage DescriptionInfo;
    130 
    131 struct SessionTerminate {
    132   SessionTerminate() {}
    133 
    134   explicit SessionTerminate(const std::string& reason) :
    135       reason(reason) {}
    136 
    137   std::string reason;
    138   std::string debug_reason;
    139 };
    140 
    141 struct SessionRedirect {
    142   std::string target;
    143 };
    144 
    145 // Used during parsing and writing to map component to channel name
    146 // and back.  This is primarily for converting old G-ICE candidate
    147 // signalling to new ICE candidate classes.
    148 class CandidateTranslator {
    149  public:
    150   virtual bool GetChannelNameFromComponent(
    151       int component, std::string* channel_name) const = 0;
    152   virtual bool GetComponentFromChannelName(
    153       const std::string& channel_name, int* component) const = 0;
    154 };
    155 
    156 // Content name => translator
    157 typedef std::map<std::string, CandidateTranslator*> CandidateTranslatorMap;
    158 
    159 bool IsSessionMessage(const buzz::XmlElement* stanza);
    160 bool ParseSessionMessage(const buzz::XmlElement* stanza,
    161                          SessionMessage* msg,
    162                          ParseError* error);
    163 // Will return an error if there is more than one content type.
    164 bool ParseContentType(SignalingProtocol protocol,
    165                       const buzz::XmlElement* action_elem,
    166                       std::string* content_type,
    167                       ParseError* error);
    168 void WriteSessionMessage(const SessionMessage& msg,
    169                          const XmlElements& action_elems,
    170                          buzz::XmlElement* stanza);
    171 bool ParseSessionInitiate(SignalingProtocol protocol,
    172                           const buzz::XmlElement* action_elem,
    173                           const ContentParserMap& content_parsers,
    174                           const TransportParserMap& transport_parsers,
    175                           const CandidateTranslatorMap& translators,
    176                           SessionInitiate* init,
    177                           ParseError* error);
    178 bool WriteSessionInitiate(SignalingProtocol protocol,
    179                           const ContentInfos& contents,
    180                           const TransportInfos& tinfos,
    181                           const ContentParserMap& content_parsers,
    182                           const TransportParserMap& transport_parsers,
    183                           const CandidateTranslatorMap& translators,
    184                           const ContentGroups& groups,
    185                           XmlElements* elems,
    186                           WriteError* error);
    187 bool ParseSessionAccept(SignalingProtocol protocol,
    188                         const buzz::XmlElement* action_elem,
    189                         const ContentParserMap& content_parsers,
    190                         const TransportParserMap& transport_parsers,
    191                         const CandidateTranslatorMap& translators,
    192                         SessionAccept* accept,
    193                         ParseError* error);
    194 bool WriteSessionAccept(SignalingProtocol protocol,
    195                         const ContentInfos& contents,
    196                         const TransportInfos& tinfos,
    197                         const ContentParserMap& content_parsers,
    198                         const TransportParserMap& transport_parsers,
    199                         const CandidateTranslatorMap& translators,
    200                         const ContentGroups& groups,
    201                         XmlElements* elems,
    202                         WriteError* error);
    203 bool ParseSessionTerminate(SignalingProtocol protocol,
    204                            const buzz::XmlElement* action_elem,
    205                            SessionTerminate* term,
    206                            ParseError* error);
    207 void WriteSessionTerminate(SignalingProtocol protocol,
    208                            const SessionTerminate& term,
    209                            XmlElements* elems);
    210 bool ParseDescriptionInfo(SignalingProtocol protocol,
    211                           const buzz::XmlElement* action_elem,
    212                           const ContentParserMap& content_parsers,
    213                           const TransportParserMap& transport_parsers,
    214                           const CandidateTranslatorMap& translators,
    215                           DescriptionInfo* description_info,
    216                           ParseError* error);
    217 bool WriteDescriptionInfo(SignalingProtocol protocol,
    218                           const ContentInfos& contents,
    219                           const ContentParserMap& content_parsers,
    220                           XmlElements* elems,
    221                           WriteError* error);
    222 // Since a TransportInfo is not a transport-info message, and a
    223 // transport-info message is just a collection of TransportInfos, we
    224 // say Parse/Write TransportInfos for transport-info messages.
    225 bool ParseTransportInfos(SignalingProtocol protocol,
    226                          const buzz::XmlElement* action_elem,
    227                          const ContentInfos& contents,
    228                          const TransportParserMap& trans_parsers,
    229                          const CandidateTranslatorMap& translators,
    230                          TransportInfos* tinfos,
    231                          ParseError* error);
    232 bool WriteTransportInfos(SignalingProtocol protocol,
    233                          const TransportInfos& tinfos,
    234                          const TransportParserMap& trans_parsers,
    235                          const CandidateTranslatorMap& translators,
    236                          XmlElements* elems,
    237                          WriteError* error);
    238 // Handles both Gingle and Jingle syntax.
    239 bool FindSessionRedirect(const buzz::XmlElement* stanza,
    240                          SessionRedirect* redirect);
    241 }  // namespace cricket
    242 
    243 #endif  // TALK_P2P_BASE_SESSIONMESSAGES_H_
    244