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 { SessionMessageSessionMessage80 SessionMessage() : action_elem(NULL), stanza(NULL) {} 81 SessionMessageSessionMessage82 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 { TransportInfoTransportInfo106 TransportInfo() {} 107 TransportInfoTransportInfo108 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 { SessionInitiateSessionInitiate123 SessionInitiate() : owns_contents(false) {} 124 ~SessionInitiateSessionInitiate125 ~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. ClearContentsSessionInitiate135 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 { SessionTerminateSessionTerminate151 SessionTerminate() {} 152 SessionTerminateSessionTerminate153 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; MediaSourcesMediaSources168 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 VideoViewRequestVideoViewRequest191 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