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/xmllite/xmlelement.h"
     36 #include "talk/p2p/base/constants.h"
     37 #include "talk/p2p/base/sessiondescription.h"  // Needed to delete contents.
     38 #include "talk/base/basictypes.h"
     39 
     40 namespace cricket {
     41 
     42 struct ParseError;
     43 struct WriteError;
     44 class Candidate;
     45 class ContentParser;
     46 class TransportParser;
     47 
     48 typedef std::vector<buzz::XmlElement*> XmlElements;
     49 typedef std::vector<Candidate> Candidates;
     50 typedef std::map<std::string, ContentParser*> ContentParserMap;
     51 typedef std::map<std::string, TransportParser*> TransportParserMap;
     52 
     53 enum ActionType {
     54   ACTION_UNKNOWN,
     55 
     56   ACTION_SESSION_INITIATE,
     57   ACTION_SESSION_INFO,
     58   ACTION_SESSION_ACCEPT,
     59   ACTION_SESSION_REJECT,
     60   ACTION_SESSION_TERMINATE,
     61 
     62   ACTION_TRANSPORT_INFO,
     63   ACTION_TRANSPORT_ACCEPT,
     64 
     65   // TODO: Make better names for these when we think of a
     66   // "jingley" way of signaling them.  Even better, remove them from
     67   // being needed at all.
     68   ACTION_NOTIFY,
     69   ACTION_UPDATE,
     70   ACTION_VIEW,
     71 };
     72 
     73 // Abstraction of a <jingle> element within an <iq> stanza, per XMPP
     74 // standard XEP-166.  Can be serialized into multiple protocols,
     75 // including the standard (Jingle) and the draft standard (Gingle).
     76 // In general, used to communicate actions related to a p2p session,
     77 // such accept, initiate, terminate, etc.
     78 
     79 struct SessionMessage {
     80   SessionMessage() : action_elem(NULL), stanza(NULL) {}
     81 
     82   SessionMessage(SignalingProtocol protocol, ActionType type,
     83                  const std::string& sid, const std::string& initiator) :
     84       protocol(protocol), type(type), sid(sid), initiator(initiator),
     85       action_elem(NULL), stanza(NULL) {}
     86 
     87   std::string id;
     88   std::string from;
     89   std::string to;
     90   SignalingProtocol protocol;
     91   ActionType type;
     92   std::string sid;  // session id
     93   std::string initiator;
     94 
     95   // Used for further parsing when necessary.
     96   // Represents <session> or <jingle>.
     97   const buzz::XmlElement* action_elem;
     98   // Mostly used for debugging.
     99   const buzz::XmlElement* stanza;
    100 };
    101 
    102 // A TransportInfo is NOT a transport-info message.  It is comparable
    103 // to a "ContentInfo". A transport-info message is basically just a
    104 // collection of TransportInfos.
    105 struct TransportInfo {
    106   TransportInfo() {}
    107 
    108   TransportInfo(const std::string& content_name,
    109                 const std::string& transport_type,
    110                 const Candidates& candidates)
    111       : content_name(content_name),
    112         transport_type(transport_type),
    113         candidates(candidates) {}
    114 
    115   std::string content_name;
    116   std::string transport_type;  // xmlns of <transport>
    117   Candidates candidates;
    118 };
    119 
    120 typedef std::vector<TransportInfo> TransportInfos;
    121 
    122 struct SessionInitiate {
    123   SessionInitiate() : owns_contents(false) {}
    124 
    125   ~SessionInitiate() {
    126     if (owns_contents) {
    127       for (ContentInfos::iterator content = contents.begin();
    128            content != contents.end(); content++) {
    129         delete content->description;
    130       }
    131     }
    132   }
    133 
    134   // Caller takes ownership of contents.
    135   ContentInfos ClearContents() {
    136     ContentInfos out;
    137     contents.swap(out);
    138     owns_contents = false;
    139     return out;
    140   }
    141 
    142   bool owns_contents;
    143   ContentInfos contents;
    144   TransportInfos transports;
    145 };
    146 
    147 // Right now, a SessionAccept is functionally equivalent to a SessionInitiate.
    148 typedef SessionInitiate SessionAccept;
    149 
    150 struct SessionTerminate {
    151   SessionTerminate() {}
    152 
    153   explicit SessionTerminate(const std::string& reason) :
    154       reason(reason) {}
    155 
    156   std::string reason;
    157   std::string debug_reason;
    158 };
    159 
    160 struct SessionRedirect {
    161   std::string target;
    162 };
    163 
    164 // Holds the ssrcs for a user's media streams.
    165 struct MediaSources {
    166   uint32 audio_ssrc;
    167   uint32 video_ssrc;
    168   MediaSources() : audio_ssrc(0), video_ssrc(0) {}
    169 };
    170 
    171 typedef std::map<std::string, MediaSources> StringToMediaSourcesMap;
    172 
    173 struct SessionNotify {
    174   // A mapping of room users (identified by their nicknames) to their ssrcs.
    175   StringToMediaSourcesMap nickname_to_sources;
    176 };
    177 
    178 // TODO: Populate the update message.
    179 struct SessionUpdate {
    180 };
    181 
    182 // Represents an individual <view> element in the <session type="view">
    183 // message.
    184 struct VideoViewRequest {
    185   std::string nick_name;
    186   uint32 ssrc;
    187   uint32 width;
    188   uint32 height;
    189   uint32 framerate;
    190 
    191   VideoViewRequest(const std::string& nick_name, uint32 ssrc, uint32 width,
    192             uint32 height, uint32 framerate) :
    193       nick_name(nick_name), ssrc(ssrc), width(width), height(height),
    194       framerate(framerate) {}
    195 };
    196 
    197 typedef std::vector<VideoViewRequest> VideoViewRequestVector;
    198 
    199 struct SessionView {
    200   VideoViewRequestVector view_requests;
    201 };
    202 
    203 bool IsSessionMessage(const buzz::XmlElement* stanza);
    204 bool ParseSessionMessage(const buzz::XmlElement* stanza,
    205                          SessionMessage* msg,
    206                          ParseError* error);
    207 // Will return an error if there is more than one content type.
    208 bool ParseContentType(SignalingProtocol protocol,
    209                       const buzz::XmlElement* action_elem,
    210                       std::string* content_type,
    211                       ParseError* error);
    212 void WriteSessionMessage(const SessionMessage& msg,
    213                          const XmlElements& action_elems,
    214                          buzz::XmlElement* stanza);
    215 bool ParseSessionInitiate(SignalingProtocol protocol,
    216                           const buzz::XmlElement* action_elem,
    217                           const ContentParserMap& content_parsers,
    218                           const TransportParserMap& transport_parsers,
    219                           SessionInitiate* init,
    220                           ParseError* error);
    221 bool WriteSessionInitiate(SignalingProtocol protocol,
    222                           const ContentInfos& contents,
    223                           const TransportInfos& tinfos,
    224                           const ContentParserMap& content_parsers,
    225                           const TransportParserMap& transport_parsers,
    226                           XmlElements* elems,
    227                           WriteError* error);
    228 bool ParseSessionAccept(SignalingProtocol protocol,
    229                         const buzz::XmlElement* action_elem,
    230                         const ContentParserMap& content_parsers,
    231                         const TransportParserMap& transport_parsers,
    232                         SessionAccept* accept,
    233                         ParseError* error);
    234 bool WriteSessionAccept(SignalingProtocol protocol,
    235                         const ContentInfos& contents,
    236                         const TransportInfos& tinfos,
    237                         const ContentParserMap& content_parsers,
    238                         const TransportParserMap& transport_parsers,
    239                         XmlElements* elems,
    240                         WriteError* error);
    241 bool ParseSessionTerminate(SignalingProtocol protocol,
    242                            const buzz::XmlElement* action_elem,
    243                            SessionTerminate* term,
    244                            ParseError* error);
    245 void WriteSessionTerminate(SignalingProtocol protocol,
    246                            const SessionTerminate& term,
    247                            XmlElements* elems);
    248 // Since a TransportInfo is not a transport-info message, and a
    249 // transport-info message is just a collection of TransportInfos, we
    250 // say Parse/Write TransportInfos for transport-info messages.
    251 bool ParseTransportInfos(SignalingProtocol protocol,
    252                          const buzz::XmlElement* action_elem,
    253                          const ContentInfos& contents,
    254                          const TransportParserMap& trans_parsers,
    255                          TransportInfos* tinfos,
    256                          ParseError* error);
    257 bool WriteTransportInfos(SignalingProtocol protocol,
    258                          const TransportInfos& tinfos,
    259                          const TransportParserMap& trans_parsers,
    260                          XmlElements* elems,
    261                          WriteError* error);
    262 bool ParseSessionNotify(const buzz::XmlElement* action_elem,
    263                         SessionNotify* notify, ParseError* error);
    264 bool ParseSessionUpdate(const buzz::XmlElement* action_elem,
    265                         SessionUpdate* update, ParseError* error);
    266 void WriteSessionView(const SessionView& view, XmlElements* elems);
    267 // Handles both Gingle and Jingle syntax.
    268 bool FindSessionRedirect(const buzz::XmlElement* stanza,
    269                          SessionRedirect* redirect);
    270 }  // namespace cricket
    271 
    272 #endif  // TALK_P2P_BASE_SESSIONMESSAGES_H_
    273