henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame^] | 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_ |