Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: remoting/protocol/jingle_messages.cc

Issue 8046018: Parse termination reason and propagate the error to the Session interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/protocol/jingle_messages.h ('k') | remoting/protocol/jingle_session.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/protocol/jingle_messages.h" 5 #include "remoting/protocol/jingle_messages.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_number_conversions.h" 8 #include "base/string_number_conversions.h"
9 #include "remoting/base/constants.h" 9 #include "remoting/base/constants.h"
10 #include "remoting/protocol/content_description.h" 10 #include "remoting/protocol/content_description.h"
11 #include "third_party/libjingle/source/talk/p2p/base/candidate.h" 11 #include "third_party/libjingle/source/talk/p2p/base/candidate.h"
12 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 12 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
13 13
14 using buzz::QName; 14 using buzz::QName;
15 using buzz::XmlElement; 15 using buzz::XmlElement;
16 16
17 namespace remoting { 17 namespace remoting {
18 namespace protocol { 18 namespace protocol {
19 19
20 const char kJabberNamespace[] = "jabber:client"; 20 const char kJabberNamespace[] = "jabber:client";
21 const char kJingleNamespace[] = "urn:xmpp:jingle:1"; 21 const char kJingleNamespace[] = "urn:xmpp:jingle:1";
22 const char kP2PTransportNamespace[] = "http://www.google.com/transport/p2p"; 22 const char kP2PTransportNamespace[] = "http://www.google.com/transport/p2p";
23 23
24 namespace { 24 namespace {
25 25
26 const char kEmptyNamespace[] = ""; 26 const char kEmptyNamespace[] = "";
27 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace"; 27 const char kXmlNamespace[] = "http://www.w3.org/XML/1998/namespace";
28 28
29 const char kSessionInitiateAction[] = "session-initiate";
30 const char kSessionAcceptAction[] = "session-accept";
31 const char kSessionTerminateAction[] = "session-terminate";
32 const char kTransportInfoAction[] = "transport-info";
33
34 const int kPortMin = 1000; 29 const int kPortMin = 1000;
35 const int kPortMax = 65535; 30 const int kPortMax = 65535;
36 31
32 template <typename T>
33 struct NameMapElement {
34 const T value;
35 const char* const name;
36 };
37
38 template <typename T>
39 const char* ValueToName(const NameMapElement<T> map[], size_t map_size,
40 T value) {
41 for (size_t i = 0; i < map_size; ++i) {
42 if (map[i].value == value)
43 return map[i].name;
44 }
45 return NULL;
46 }
47
48 template <typename T>
49 T NameToValue(const NameMapElement<T> map[], size_t map_size,
50 const std::string& name, T default_value) {
51 for (size_t i = 0; i < map_size; ++i) {
52 if (map[i].name == name)
53 return map[i].value;
54 }
55 return default_value;
56 }
57
58 static const NameMapElement<JingleMessage::ActionType> kActionTypes[] = {
59 { JingleMessage::SESSION_INITIATE, "session-initiate" },
60 { JingleMessage::SESSION_ACCEPT, "session-accept" },
61 { JingleMessage::SESSION_TERMINATE, "session-terminate" },
62 { JingleMessage::TRANSPORT_INFO, "transport-info" },
63 };
64
65 static const NameMapElement<JingleMessage::Reason> kReasons[] = {
66 { JingleMessage::SUCCESS, "success" },
67 { JingleMessage::DECLINE, "decline" },
68 { JingleMessage::INCOMPATIBLE_PARAMETERS, "incompatible-parameters" },
69 };
70
37 bool ParseCandidate(const buzz::XmlElement* element, 71 bool ParseCandidate(const buzz::XmlElement* element,
38 cricket::Candidate* candidate) { 72 cricket::Candidate* candidate) {
39 DCHECK(element->Name() == QName(kP2PTransportNamespace, "candidate")); 73 DCHECK(element->Name() == QName(kP2PTransportNamespace, "candidate"));
40 74
41 const std::string& name = element->Attr(QName(kEmptyNamespace, "name")); 75 const std::string& name = element->Attr(QName(kEmptyNamespace, "name"));
42 const std::string& address = element->Attr(QName(kEmptyNamespace, "address")); 76 const std::string& address = element->Attr(QName(kEmptyNamespace, "address"));
43 const std::string& port_str = element->Attr(QName(kEmptyNamespace, "port")); 77 const std::string& port_str = element->Attr(QName(kEmptyNamespace, "port"));
44 const std::string& type = element->Attr(QName(kEmptyNamespace, "type")); 78 const std::string& type = element->Attr(QName(kEmptyNamespace, "type"));
45 const std::string& protocol = 79 const std::string& protocol =
46 element->Attr(QName(kEmptyNamespace, "protocol")); 80 element->Attr(QName(kEmptyNamespace, "protocol"));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 131
98 } // namespace 132 } // namespace
99 133
100 // static 134 // static
101 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) { 135 bool JingleMessage::IsJingleMessage(const buzz::XmlElement* stanza) {
102 return stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != NULL; 136 return stanza->FirstNamed(QName(kJingleNamespace, "jingle")) != NULL;
103 } 137 }
104 138
105 JingleMessage::JingleMessage() 139 JingleMessage::JingleMessage()
106 : action(UNKNOWN_ACTION), 140 : action(UNKNOWN_ACTION),
107 termination_reason(kJingleNamespace, "success") { 141 reason(UNKNOWN_REASON) {
108 } 142 }
109 143
110 JingleMessage::JingleMessage( 144 JingleMessage::JingleMessage(
111 const std::string& to_value, 145 const std::string& to_value,
112 ActionType action_value, 146 ActionType action_value,
113 const std::string& sid_value) 147 const std::string& sid_value)
114 : to(to_value), 148 : to(to_value),
115 action(action_value), 149 action(action_value),
116 sid(sid_value) { 150 sid(sid_value) {
117 } 151 }
(...skipping 10 matching lines...) Expand all
128 return false; 162 return false;
129 } 163 }
130 164
131 from = stanza->Attr(QName(kEmptyNamespace, "from")); 165 from = stanza->Attr(QName(kEmptyNamespace, "from"));
132 to = stanza->Attr(QName(kEmptyNamespace, "to")); 166 to = stanza->Attr(QName(kEmptyNamespace, "to"));
133 167
134 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action")); 168 std::string action_str = jingle_tag->Attr(QName(kEmptyNamespace, "action"));
135 if (action_str.empty()) { 169 if (action_str.empty()) {
136 *error = "action attribute is missing"; 170 *error = "action attribute is missing";
137 return false; 171 return false;
138 } else if (action_str == kSessionInitiateAction) { 172 }
139 action = SESSION_INITIATE; 173 action = NameToValue(
140 } else if (action_str == kSessionAcceptAction) { 174 kActionTypes, arraysize(kActionTypes), action_str, UNKNOWN_ACTION);
141 action = SESSION_ACCEPT; 175 if (action == UNKNOWN_ACTION) {
142 } else if (action_str == kSessionTerminateAction) {
143 action = SESSION_TERMINATE;
144 } else if (action_str == kTransportInfoAction) {
145 action = TRANSPORT_INFO;
146 } else {
147 *error = "Unknown action " + action_str; 176 *error = "Unknown action " + action_str;
148 return false; 177 return false;
149 } 178 }
150 179
151 sid = jingle_tag->Attr(QName(kEmptyNamespace, "sid")); 180 sid = jingle_tag->Attr(QName(kEmptyNamespace, "sid"));
152 if (sid.empty()) { 181 if (sid.empty()) {
153 *error = "sid attribute is missing"; 182 *error = "sid attribute is missing";
154 return false; 183 return false;
155 } 184 }
156 185
157 if (action == SESSION_TERMINATE) { 186 const XmlElement* reason_tag =
158 const XmlElement* reason_tag = 187 jingle_tag->FirstNamed(QName(kJingleNamespace, "reason"));
159 jingle_tag->FirstNamed(QName(kJingleNamespace, "reason")); 188 if (reason_tag && reason_tag->FirstElement()) {
160 if (reason_tag && reason_tag->FirstElement()) 189 reason = NameToValue(
161 termination_reason = reason_tag->FirstElement()->Name(); 190 kReasons, arraysize(kReasons),
191 reason_tag->FirstElement()->Name().LocalPart(), UNKNOWN_REASON);
192 }
193
194 if (action == SESSION_TERMINATE)
162 return true; 195 return true;
163 }
164 196
165 const XmlElement* content_tag = 197 const XmlElement* content_tag =
166 jingle_tag->FirstNamed(QName(kJingleNamespace, "content")); 198 jingle_tag->FirstNamed(QName(kJingleNamespace, "content"));
167 if (!content_tag) { 199 if (!content_tag) {
168 *error = "content tag is missing"; 200 *error = "content tag is missing";
169 return false; 201 return false;
170 } 202 }
171 203
172 std::string content_name = content_tag->Attr(QName(kEmptyNamespace, "name")); 204 std::string content_name = content_tag->Attr(QName(kEmptyNamespace, "name"));
173 if (content_name != ContentDescription::kChromotingContentName) { 205 if (content_name != ContentDescription::kChromotingContentName) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 root->AddAttr(QName(kEmptyNamespace, "to"), to); 252 root->AddAttr(QName(kEmptyNamespace, "to"), to);
221 if (!from.empty()) 253 if (!from.empty())
222 root->AddAttr(QName(kEmptyNamespace, "from"), from); 254 root->AddAttr(QName(kEmptyNamespace, "from"), from);
223 root->SetAttr(QName(kEmptyNamespace, "type"), "set"); 255 root->SetAttr(QName(kEmptyNamespace, "type"), "set");
224 256
225 XmlElement* jingle_tag = 257 XmlElement* jingle_tag =
226 new XmlElement(QName(kJingleNamespace, "jingle"), true); 258 new XmlElement(QName(kJingleNamespace, "jingle"), true);
227 root->AddElement(jingle_tag); 259 root->AddElement(jingle_tag);
228 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid); 260 jingle_tag->AddAttr(QName(kEmptyNamespace, "sid"), sid);
229 261
230 std::string action_attr; 262 const char* action_attr = ValueToName(
231 switch (action) { 263 kActionTypes, arraysize(kActionTypes), action);
232 case SESSION_INITIATE: 264 if (!action_attr)
233 action_attr = kSessionInitiateAction; 265 LOG(FATAL) << "Invalid action value " << action;
234 break;
235 case SESSION_ACCEPT:
236 action_attr = kSessionAcceptAction;
237 break;
238 case SESSION_TERMINATE:
239 action_attr = kSessionTerminateAction;
240 break;
241 case TRANSPORT_INFO:
242 action_attr = kTransportInfoAction;
243 break;
244 default:
245 NOTREACHED();
246 break;
247 }
248 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr); 266 jingle_tag->AddAttr(QName(kEmptyNamespace, "action"), action_attr);
249 267
250 if (action == SESSION_INITIATE) 268 if (action == SESSION_INITIATE)
251 jingle_tag->AddAttr(QName(kEmptyNamespace, "initiator"), from); 269 jingle_tag->AddAttr(QName(kEmptyNamespace, "initiator"), from);
252 270
253 if (action == SESSION_TERMINATE) { 271 if (reason != UNKNOWN_REASON) {
254 XmlElement* reason_tag = new XmlElement(QName(kJingleNamespace, "reason")); 272 XmlElement* reason_tag = new XmlElement(QName(kJingleNamespace, "reason"));
255 jingle_tag->AddElement(reason_tag); 273 jingle_tag->AddElement(reason_tag);
274 const char* reason_string =
275 ValueToName(kReasons, arraysize(kReasons), reason);
276 if (reason_string == NULL)
277 LOG(FATAL) << "Invalid reason: " << reason;
278 reason_tag->AddElement(new XmlElement(
279 QName(kJingleNamespace, reason_string)));
280 }
256 281
257 reason_tag->AddElement(new XmlElement(termination_reason)); 282 if (action != SESSION_TERMINATE) {
258 } else {
259 XmlElement* content_tag = 283 XmlElement* content_tag =
260 new XmlElement(QName(kJingleNamespace, "content")); 284 new XmlElement(QName(kJingleNamespace, "content"));
261 jingle_tag->AddElement(content_tag); 285 jingle_tag->AddElement(content_tag);
262 286
263 content_tag->AddAttr(QName(kEmptyNamespace, "name"), 287 content_tag->AddAttr(QName(kEmptyNamespace, "name"),
264 ContentDescription::kChromotingContentName); 288 ContentDescription::kChromotingContentName);
265 content_tag->AddAttr(QName(kEmptyNamespace, "creator"), "initiator"); 289 content_tag->AddAttr(QName(kEmptyNamespace, "creator"), "initiator");
266 290
267 if (description.get()) 291 if (description.get())
268 content_tag->AddElement(description->ToXml()); 292 content_tag->AddElement(description->ToXml());
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 text_elem->SetAttr(QName(kXmlNamespace, "lang"), "en"); 394 text_elem->SetAttr(QName(kXmlNamespace, "lang"), "en");
371 text_elem->SetBodyText(error_text); 395 text_elem->SetBodyText(error_text);
372 error->AddElement(text_elem); 396 error->AddElement(text_elem);
373 } 397 }
374 398
375 return iq; 399 return iq;
376 } 400 }
377 401
378 } // namespace protocol 402 } // namespace protocol
379 } // namespace remoting 403 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/jingle_messages.h ('k') | remoting/protocol/jingle_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698