1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2010, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <stdio.h> 294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <string> 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/sessionmessages.h" 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "talk/base/logging.h" 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/scoped_ptr.h" 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/base/stringutils.h" 354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "talk/xmllite/xmlconstants.h" 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/constants.h" 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/constants.h" 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/p2ptransport.h" 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/parsing.h" 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/sessionclient.h" 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/p2p/base/sessiondescription.h" 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/transport.h" 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/xmllite/xmlconstants.h" 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace cricket { 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochActionType ToActionType(const std::string& type) { 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_INITIATE) 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_SESSION_INITIATE; 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_INFO) 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_SESSION_INFO; 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_ACCEPT) 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_SESSION_ACCEPT; 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_REJECT) 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_SESSION_REJECT; 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_TERMINATE) 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_SESSION_TERMINATE; 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == GINGLE_ACTION_CANDIDATES) 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_TRANSPORT_INFO; 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_SESSION_INITIATE) 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_SESSION_INITIATE; 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_TRANSPORT_INFO) 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_TRANSPORT_INFO; 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_TRANSPORT_ACCEPT) 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_TRANSPORT_ACCEPT; 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_SESSION_INFO) 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_SESSION_INFO; 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_SESSION_ACCEPT) 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_SESSION_ACCEPT; 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (type == JINGLE_ACTION_SESSION_TERMINATE) 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ACTION_SESSION_TERMINATE; 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type == JINGLE_ACTION_TRANSPORT_INFO) 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_TRANSPORT_INFO; 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (type == JINGLE_ACTION_TRANSPORT_ACCEPT) 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ACTION_TRANSPORT_ACCEPT; 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (type == GINGLE_ACTION_NOTIFY) 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return ACTION_NOTIFY; 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (type == GINGLE_ACTION_UPDATE) 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return ACTION_UPDATE; 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ACTION_UNKNOWN; 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string ToJingleString(ActionType type) { 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick switch (type) { 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_SESSION_INITIATE: 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_SESSION_INITIATE; 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_SESSION_INFO: 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_SESSION_INFO; 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_SESSION_ACCEPT: 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_SESSION_ACCEPT; 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Notice that reject and terminate both go to 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // "session-terminate", but there is no "session-reject". 94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_SESSION_REJECT: 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_SESSION_TERMINATE: 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_SESSION_TERMINATE; 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_TRANSPORT_INFO: 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_TRANSPORT_INFO; 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case ACTION_TRANSPORT_ACCEPT: 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return JINGLE_ACTION_TRANSPORT_ACCEPT; 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default: 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ""; 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string ToGingleString(ActionType type) { 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_SESSION_INITIATE: 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GINGLE_ACTION_INITIATE; 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_SESSION_INFO: 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GINGLE_ACTION_INFO; 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_SESSION_ACCEPT: 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GINGLE_ACTION_ACCEPT; 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_SESSION_REJECT: 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GINGLE_ACTION_REJECT; 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_SESSION_TERMINATE: 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return GINGLE_ACTION_TERMINATE; 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case ACTION_VIEW: 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return GINGLE_ACTION_VIEW; 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case ACTION_TRANSPORT_INFO: 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return GINGLE_ACTION_CANDIDATES; 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return ""; 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool IsJingleMessage(const buzz::XmlElement* stanza) { 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE); 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (jingle == NULL) 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return (jingle->HasAttr(buzz::QN_ACTION) && 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen (jingle->HasAttr(QN_SID) 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: This works around a bug in old jingle 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // clients that set QN_ID instead of QN_SID. Once we know 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // there are no clients which have this bug, we can remove 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // this code. 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen || jingle->HasAttr(QN_ID))); 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool IsGingleMessage(const buzz::XmlElement* stanza) { 143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION); 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (session == NULL) 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return (session->HasAttr(buzz::QN_TYPE) && 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->HasAttr(buzz::QN_ID) && 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->HasAttr(QN_INITIATOR)); 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool IsSessionMessage(const buzz::XmlElement* stanza) { 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return (stanza->Name() == buzz::QN_IQ && 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stanza->Attr(buzz::QN_TYPE) == buzz::STR_SET && 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (IsJingleMessage(stanza) || 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick IsGingleMessage(stanza))); 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseGingleSessionMessage(const buzz::XmlElement* session, 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMessage* msg, 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->protocol = PROTOCOL_GINGLE; 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string type_string = session->Attr(buzz::QN_TYPE); 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->type = ToActionType(type_string); 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->sid = session->Attr(buzz::QN_ID); 166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->initiator = session->Attr(QN_INITIATOR); 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->action_elem = session; 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (msg->type == ACTION_UNKNOWN) 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("unknown action: " + type_string, error); 171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseJingleSessionMessage(const buzz::XmlElement* jingle, 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMessage* msg, 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->protocol = PROTOCOL_JINGLE; 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string type_string = jingle->Attr(buzz::QN_ACTION); 180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->type = ToActionType(type_string); 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen msg->sid = jingle->Attr(QN_SID); 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: This works around a bug in old jingle clients 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // that set QN_ID instead of QN_SID. Once we know there are no 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // clients which have this bug, we can remove this code. 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (msg->sid.empty()) { 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen msg->sid = jingle->Attr(buzz::QN_ID); 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch msg->initiator = GetXmlAttr(jingle, QN_INITIATOR, buzz::STR_EMPTY); 189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->action_elem = jingle; 190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (msg->type == ACTION_UNKNOWN) 192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("unknown action: " + type_string, error); 193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseHybridSessionMessage(const buzz::XmlElement* jingle, 198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMessage* msg, 199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseJingleSessionMessage(jingle, msg, error)) 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick msg->protocol = PROTOCOL_HYBRID; 203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseSessionMessage(const buzz::XmlElement* stanza, 208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMessage* msg, 209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch msg->id = stanza->Attr(buzz::QN_ID); 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch msg->from = stanza->Attr(buzz::QN_FROM); 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch msg->to = stanza->Attr(buzz::QN_TO); 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch msg->stanza = stanza; 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* jingle = stanza->FirstNamed(QN_JINGLE); 216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* session = stanza->FirstNamed(QN_GINGLE_SESSION); 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (jingle && session) 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseHybridSessionMessage(jingle, msg, error); 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (jingle != NULL) 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseJingleSessionMessage(jingle, msg, error); 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (session != NULL) 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseGingleSessionMessage(session, msg, error); 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbuzz::XmlElement* WriteGingleAction(const SessionMessage& msg, 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const XmlElements& action_elems) { 228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* session = new buzz::XmlElement(QN_GINGLE_SESSION, true); 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->AddAttr(buzz::QN_TYPE, ToGingleString(msg.type)); 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->AddAttr(buzz::QN_ID, msg.sid); 231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session->AddAttr(QN_INITIATOR, msg.initiator); 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddXmlChildren(session, action_elems); 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return session; 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbuzz::XmlElement* WriteJingleAction(const SessionMessage& msg, 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const XmlElements& action_elems) { 238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* jingle = new buzz::XmlElement(QN_JINGLE, true); 239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick jingle->AddAttr(buzz::QN_ACTION, ToJingleString(msg.type)); 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen jingle->AddAttr(QN_SID, msg.sid); 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: This works around a bug in old jingle clinets 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // that expected QN_ID instead of QN_SID. Once we know there are no 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // clients which have this bug, we can remove this code. 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen jingle->AddAttr(QN_ID, msg.sid); 245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Right now, the XMPP server rejects a jingle-only 246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // (non hybrid) message with "feature-not-implemented" if there is 247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // no initiator. Fix the server, and then only set the initiator on 248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // session-initiate messages here. 249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick jingle->AddAttr(QN_INITIATOR, msg.initiator); 250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddXmlChildren(jingle, action_elems); 251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return jingle; 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid WriteSessionMessage(const SessionMessage& msg, 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const XmlElements& action_elems, 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buzz::XmlElement* stanza) { 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch stanza->SetAttr(buzz::QN_TO, msg.to); 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch stanza->SetAttr(buzz::QN_TYPE, buzz::STR_SET); 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (msg.protocol == PROTOCOL_GINGLE) { 261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stanza->AddElement(WriteGingleAction(msg, action_elems)); 262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick stanza->AddElement(WriteJingleAction(msg, action_elems)); 264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochTransportParser* GetTransportParser(const TransportParserMap& trans_parsers, 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& name) { 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch TransportParserMap::const_iterator map = trans_parsers.find(name); 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (map == trans_parsers.end()) { 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return NULL; 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return map->second; 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseCandidates(SignalingProtocol protocol, 279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* candidates_elem, 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const TransportParserMap& trans_parsers, 281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& transport_type, 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Candidates* candidates, 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseError* error) { 284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportParser* trans_parser = 285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GetTransportParser(trans_parsers, transport_type); 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (trans_parser == NULL) 287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("unknown transport type: " + transport_type, error); 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return trans_parser->ParseCandidates(protocol, candidates_elem, 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick candidates, error); 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseGingleTransportInfos(const buzz::XmlElement* action_elem, 294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfos& contents, 295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfos* tinfos, 297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfo tinfo(CN_OTHER, NS_GINGLE_P2P, Candidates()); 299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseCandidates(PROTOCOL_GINGLE, action_elem, 300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trans_parsers, NS_GINGLE_P2P, 301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &tinfo.candidates, error)) 302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool has_audio = FindContentInfoByName(contents, CN_AUDIO) != NULL; 305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool has_video = FindContentInfoByName(contents, CN_VIDEO) != NULL; 306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If we don't have media, no need to separate the candidates. 308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!has_audio && !has_audio) { 309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos->push_back(tinfo); 310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If we have media, separate the candidates. Create the 314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TransportInfo here to avoid copying the candidates. 315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfo audio_tinfo(CN_AUDIO, NS_GINGLE_P2P, Candidates()); 316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfo video_tinfo(CN_VIDEO, NS_GINGLE_P2P, Candidates()); 317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (Candidates::iterator cand = tinfo.candidates.begin(); 318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cand != tinfo.candidates.end(); cand++) { 319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (cand->name() == GINGLE_CANDIDATE_NAME_RTP || 320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cand->name() == GINGLE_CANDIDATE_NAME_RTCP) { 321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick audio_tinfo.candidates.push_back(*cand); 322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTP || 323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick cand->name() == GINGLE_CANDIDATE_NAME_VIDEO_RTCP) { 324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick video_tinfo.candidates.push_back(*cand); 325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (has_audio) { 329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos->push_back(audio_tinfo); 330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (has_video) { 333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos->push_back(video_tinfo); 334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseJingleTransportInfo(const buzz::XmlElement* trans_elem, 340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfo& content, 341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 342731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfos* tinfos, 343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseError* error) { 344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string transport_type = trans_elem->Name().Namespace(); 345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfo tinfo(content.name, transport_type, Candidates()); 346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseCandidates(PROTOCOL_JINGLE, trans_elem, 347731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trans_parsers, transport_type, 348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &tinfo.candidates, error)) 349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos->push_back(tinfo); 352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseJingleTransportInfos(const buzz::XmlElement* jingle, 356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfos& contents, 357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap trans_parsers, 358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfos* tinfos, 359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (const buzz::XmlElement* pair_elem 361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick = jingle->FirstNamed(QN_JINGLE_CONTENT); 362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem != NULL; 363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { 364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string content_name; 365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME, 366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &content_name, error)) 367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfo* content = FindContentInfoByName(contents, content_name); 370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!content) 371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("Unknown content name: " + content_name, error); 372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* trans_elem; 374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!RequireXmlChild(pair_elem, LN_TRANSPORT, &trans_elem, error)) 375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseJingleTransportInfo(trans_elem, *content, trans_parsers, 378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos, error)) 379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbuzz::XmlElement* NewTransportElement(const std::string& name) { 386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new buzz::XmlElement(buzz::QName(true, name, LN_TRANSPORT), true); 387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 389731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteCandidates(SignalingProtocol protocol, 390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& trans_type, 391731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const Candidates& candidates, 392731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportParser* trans_parser = GetTransportParser(trans_parsers, trans_type); 396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (trans_parser == NULL) 397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadWrite("unknown transport type: " + trans_type, error); 398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return trans_parser->WriteCandidates(protocol, candidates, elems, error); 400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteGingleTransportInfos(const TransportInfos& tinfos, 403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (TransportInfos::const_iterator tinfo = tinfos.begin(); 407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfo != tinfos.end(); ++tinfo) { 408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteCandidates(PROTOCOL_GINGLE, 409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfo->transport_type, tinfo->candidates, 410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick trans_parsers, elems, error)) 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteJingleTransportInfo(const TransportInfo& tinfo, 418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements candidate_elems; 422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteCandidates(PROTOCOL_JINGLE, 423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfo.transport_type, tinfo.candidates, trans_parsers, 424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &candidate_elems, error)) 425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 427731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* trans_elem = NewTransportElement(tinfo.transport_type); 428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddXmlChildren(trans_elem, candidate_elems); 429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems->push_back(trans_elem); 430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid WriteJingleContentPair(const std::string name, 434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const XmlElements& pair_elems, 435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems) { 436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* pair_elem = new buzz::XmlElement(QN_JINGLE_CONTENT); 437731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem->SetAttr(QN_JINGLE_CONTENT_NAME, name); 438731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem->SetAttr(QN_CREATOR, LN_INITIATOR); 439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick AddXmlChildren(pair_elem, pair_elems); 440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems->push_back(pair_elem); 442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteJingleTransportInfos(const TransportInfos& tinfos, 445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (TransportInfos::const_iterator tinfo = tinfos.begin(); 449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfo != tinfos.end(); ++tinfo) { 450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements pair_elems; 451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteJingleTransportInfo(*tinfo, trans_parsers, 452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &pair_elems, error)) 453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteJingleContentPair(tinfo->content_name, pair_elems, elems); 456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 461731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickContentParser* GetContentParser(const ContentParserMap& content_parsers, 462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& type) { 4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentParserMap::const_iterator map = content_parsers.find(type); 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (map == content_parsers.end()) { 465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return NULL; 466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return map->second; 468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 471731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseContentInfo(SignalingProtocol protocol, 472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& name, 473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& type, 474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* elem, 475731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& parsers, 476731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ContentInfos* contents, 477731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentParser* parser = GetContentParser(parsers, type); 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (parser == NULL) 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return BadParse("unknown application content: " + type, error); 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentDescription* desc; 483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!parser->ParseContent(protocol, elem, &desc, error)) 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick contents->push_back(ContentInfo(name, type, desc)); 487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseContentType(const buzz::XmlElement* parent_elem, 491731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string* content_type, 492731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement** content_elem, 493731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 494731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!RequireXmlChild(parent_elem, LN_DESCRIPTION, content_elem, error)) 495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 4973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *content_type = (*content_elem)->Name().Namespace(); 4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseGingleContentInfos(const buzz::XmlElement* session, 502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& content_parsers, 503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ContentInfos* contents, 504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string content_type; 5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const buzz::XmlElement* content_elem; 507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(session, &content_type, &content_elem, error)) 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 5093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (content_type == NS_GINGLE_VIDEO) { 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // A parser parsing audio or video content should look at the 5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // namespace and only parse the codecs relevant to that namespace. 513731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // We use this to control which codecs get parsed: first audio, 514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // then video. 5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick talk_base::scoped_ptr<buzz::XmlElement> audio_elem( 5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new buzz::XmlElement(QN_GINGLE_AUDIO_CONTENT)); 5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CopyXmlChildren(content_elem, audio_elem.get()); 518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP, 519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick audio_elem.get(), content_parsers, 520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, error)) 521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentInfo(PROTOCOL_GINGLE, CN_VIDEO, NS_JINGLE_RTP, 524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_elem, content_parsers, 525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, error)) 526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (content_type == NS_GINGLE_AUDIO) { 528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentInfo(PROTOCOL_GINGLE, CN_AUDIO, NS_JINGLE_RTP, 529731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_elem, content_parsers, 530731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, error)) 5313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 533731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentInfo(PROTOCOL_GINGLE, CN_OTHER, content_type, 534731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_elem, content_parsers, 535731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, error)) 5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 541731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseJingleContentInfos(const buzz::XmlElement* jingle, 542731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& content_parsers, 543731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ContentInfos* contents, 544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (const buzz::XmlElement* pair_elem 546731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick = jingle->FirstNamed(QN_JINGLE_CONTENT); 547731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem != NULL; 548731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { 549731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string content_name; 550731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!RequireXmlAttr(pair_elem, QN_JINGLE_CONTENT_NAME, 551731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &content_name, error)) 552731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 553731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string content_type; 555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* content_elem; 556731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(pair_elem, &content_type, &content_elem, error)) 557731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 558731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 559731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentInfo(PROTOCOL_JINGLE, content_name, content_type, 560731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_elem, content_parsers, 561731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, error)) 562731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 563731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 564731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 567731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbuzz::XmlElement* WriteContentInfo(SignalingProtocol protocol, 568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfo& content, 569731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& parsers, 570731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ContentParser* parser = GetContentParser(parsers, content.type); 5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (parser == NULL) { 5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BadWrite("unknown content type: " + content.type, error); 5743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick buzz::XmlElement* elem = NULL; 578731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!parser->WriteContent(protocol, content.description, &elem, error)) 5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return elem; 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteGingleContentInfos(const ContentInfos& contents, 585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& parsers, 586731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (contents.size() == 1) { 589731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* elem = WriteContentInfo( 590731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PROTOCOL_GINGLE, contents.front(), parsers, error); 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!elem) 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick elems->push_back(elem); 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (contents.size() == 2 && 596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents.at(0).type == NS_JINGLE_RTP && 597731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents.at(1).type == NS_JINGLE_RTP) { 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Special-case audio + video contents so that they are "merged" 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // into one "video" content. 600731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* audio = WriteContentInfo( 601731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PROTOCOL_GINGLE, contents.at(0), parsers, error); 6023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!audio) 6033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 6043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* video = WriteContentInfo( 606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PROTOCOL_GINGLE, contents.at(1), parsers, error); 6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!video) { 6083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete audio; 6093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CopyXmlChildren(audio, video); 6133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick elems->push_back(video); 6143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete audio; 6153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 6163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return BadWrite("Gingle protocol may only have one content.", error); 6173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 6183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst TransportInfo* GetTransportInfoByContentName( 623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfos& tinfos, const std::string& content_name) { 624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (TransportInfos::const_iterator tinfo = tinfos.begin(); 625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfo != tinfos.end(); ++tinfo) { 626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (content_name == tinfo->content_name) { 627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return &*tinfo; 628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 629731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 630731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 633731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteJingleContentPairs(const ContentInfos& contents, 634731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentParserMap& content_parsers, 635731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfos& tinfos, 636731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 639731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (ContentInfos::const_iterator content = contents.begin(); 640731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content != contents.end(); ++content) { 641731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfo* tinfo = 642731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GetTransportInfoByContentName(tinfos, content->name); 643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!tinfo) 644731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadWrite("No transport for content: " + content->name, error); 645731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 646731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements pair_elems; 647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* elem = WriteContentInfo( 648731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PROTOCOL_JINGLE, *content, content_parsers, error); 649731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!elem) 650731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 651731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elems.push_back(elem); 652731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 653731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteJingleTransportInfo(*tinfo, trans_parsers, 654731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &pair_elems, error)) 655731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 656731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 657731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteJingleContentPair(content->name, pair_elems, elems); 658731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 659731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 660731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 661731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 662731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseContentType(SignalingProtocol protocol, 663731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* action_elem, 664731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string* content_type, 665731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 6663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const buzz::XmlElement* content_elem; 667731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 668731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(action_elem, content_type, &content_elem, error)) 669731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 670731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 671731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Internally, we only use NS_JINGLE_RTP. 672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (*content_type == NS_GINGLE_AUDIO || 673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *content_type == NS_GINGLE_VIDEO) 674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *content_type = NS_JINGLE_RTP; 675731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 676731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* pair_elem 677731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick = action_elem->FirstNamed(QN_JINGLE_CONTENT); 678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (pair_elem == NULL) 679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("No contents found", error); 680731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 681731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(pair_elem, content_type, &content_elem, error)) 682731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 683731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 684731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If there is more than one content type, return an error. 685731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (; pair_elem != NULL; 686731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pair_elem = pair_elem->NextNamed(QN_JINGLE_CONTENT)) { 687731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string content_type2; 688731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(pair_elem, &content_type2, &content_elem, error)) 689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 690731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 691731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (content_type2 != *content_type) 692731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return BadParse("More than one content type found", error); 693731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 694731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 695731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 696731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 697f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 698f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 699731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseSessionInitiate(SignalingProtocol protocol, 700731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* action_elem, 7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentParserMap& content_parsers, 702731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 703731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionInitiate* init, 704731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 705731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick init->owns_contents = true; 706731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 707731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseGingleContentInfos(action_elem, content_parsers, 708731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &init->contents, error)) 709731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 710f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 711731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseGingleTransportInfos(action_elem, init->contents, trans_parsers, 712731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &init->transports, error)) 713731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 714731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 715731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseJingleContentInfos(action_elem, content_parsers, 716731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &init->contents, error)) 717731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 718731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 719731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseJingleTransportInfos(action_elem, init->contents, trans_parsers, 720731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &init->transports, error)) 721731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 722731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 723f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 724f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 725f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 726f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 727731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 728731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteSessionInitiate(SignalingProtocol protocol, 729731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfos& contents, 730731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfos& tinfos, 7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentParserMap& content_parsers, 732731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& transport_parsers, 7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick XmlElements* elems, 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WriteError* error) { 735731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 736731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteGingleContentInfos(contents, content_parsers, elems, error)) 737731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 739731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteGingleTransportInfos(tinfos, transport_parsers, 740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems, error)) 741731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 742731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 743731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!WriteJingleContentPairs(contents, content_parsers, 744731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick tinfos, transport_parsers, 745731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems, error)) 746731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 747731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 750f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 751f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 752731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseSessionAccept(SignalingProtocol protocol, 753731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* action_elem, 7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentParserMap& content_parsers, 755731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& transport_parsers, 756731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionAccept* accept, 757731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 758731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseSessionInitiate(protocol, action_elem, 759731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_parsers, transport_parsers, 760731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick accept, error); 761f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 762f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 763731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteSessionAccept(SignalingProtocol protocol, 764731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfos& contents, 765731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfos& tinfos, 7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ContentParserMap& content_parsers, 767731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& transport_parsers, 7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick XmlElements* elems, 7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WriteError* error) { 770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return WriteSessionInitiate(protocol, contents, tinfos, 771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_parsers, transport_parsers, 772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems, error); 773f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 774f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseSessionTerminate(SignalingProtocol protocol, 776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* action_elem, 777731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionTerminate* term, 778731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 780731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* reason_elem = action_elem->FirstElement(); 781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (reason_elem != NULL) { 782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick term->reason = reason_elem->Name().LocalPart(); 783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement *debug_elem = reason_elem->FirstElement(); 784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (debug_elem != NULL) { 785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick term->debug_reason = debug_elem->Name().LocalPart(); 786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 787731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* reason_elem = 791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action_elem->FirstNamed(QN_JINGLE_REASON); 792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (reason_elem) { 793731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick reason_elem = reason_elem->FirstElement(); 794731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (reason_elem) { 795731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick term->reason = reason_elem->Name().LocalPart(); 796731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 797f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 798731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 799f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 800f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 801f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 802731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid WriteSessionTerminate(SignalingProtocol protocol, 803731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const SessionTerminate& term, 804731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems) { 805731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 806731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems->push_back(new buzz::XmlElement( 807731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::QName(true, NS_GINGLE, term.reason))); 808731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 809731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!term.reason.empty()) { 810731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::XmlElement* reason_elem = new buzz::XmlElement(QN_JINGLE_REASON); 811731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick reason_elem->AddElement(new buzz::XmlElement( 812731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick buzz::QName(true, NS_JINGLE, term.reason))); 813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems->push_back(reason_elem); 814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 816f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 817f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 818731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool ParseTransportInfos(SignalingProtocol protocol, 819731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const buzz::XmlElement* action_elem, 820731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const ContentInfos& contents, 821731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 822731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick TransportInfos* tinfos, 823731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ParseError* error) { 824731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 825731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseGingleTransportInfos( 826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action_elem, contents, trans_parsers, tinfos, error); 827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 828731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ParseJingleTransportInfos( 829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action_elem, contents, trans_parsers, tinfos, error); 830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 831f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 832f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool WriteTransportInfos(SignalingProtocol protocol, 834731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportInfos& tinfos, 835731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TransportParserMap& trans_parsers, 836731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick XmlElements* elems, 837731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WriteError* error) { 838731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (protocol == PROTOCOL_GINGLE) { 839731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return WriteGingleTransportInfos(tinfos, trans_parsers, 840731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems, error); 841731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 842731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return WriteJingleTransportInfos(tinfos, trans_parsers, 843731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick elems, error); 844731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 845f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 846f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 847dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ParseSessionNotify(const buzz::XmlElement* action_elem, 848dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SessionNotify* notify, ParseError* error) { 849dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const buzz::XmlElement* notify_elem; 850dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (notify_elem = action_elem->FirstNamed(QN_GINGLE_NOTIFY); 851dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notify_elem != NULL; 852dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notify_elem = notify_elem->NextNamed(QN_GINGLE_NOTIFY)) { 853dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Note that a subsequent notify element for the same user will override a 854dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // previous. We don't merge them. 855dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string nick(notify_elem->Attr(QN_GINGLE_NOTIFY_NICK)); 856dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (nick != buzz::STR_EMPTY) { 857dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen MediaSources sources; 858dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const buzz::XmlElement* source_elem; 859dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (source_elem = notify_elem->FirstNamed(QN_GINGLE_NOTIFY_SOURCE); 860dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen source_elem != NULL; 861dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen source_elem = source_elem->NextNamed(QN_GINGLE_NOTIFY_SOURCE)) { 862dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string ssrc = source_elem->Attr(QN_GINGLE_NOTIFY_SOURCE_SSRC); 863dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ssrc != buzz::STR_EMPTY) { 864dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string mtype = source_elem->Attr(QN_GINGLE_NOTIFY_SOURCE_MTYPE); 865dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (mtype == GINGLE_NOTIFY_SOURCE_MTYPE_AUDIO) { 866dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sources.audio_ssrc = strtoul(ssrc.c_str(), NULL, 10); 867dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (mtype == GINGLE_NOTIFY_SOURCE_MTYPE_VIDEO) { 868dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sources.video_ssrc = strtoul(ssrc.c_str(), NULL, 10); 869dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 870dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 871dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 872dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 873dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notify->nickname_to_sources.insert( 874dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::pair<std::string, MediaSources>(nick, sources)); 875dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 876dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 877dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 878dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 879dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 880dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 8814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool GetUriTarget(const std::string& prefix, const std::string& str, 8824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string* after) { 8834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch size_t pos = str.find(prefix); 8844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (pos == std::string::npos) 8854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 8864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 8874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch *after = str.substr(pos + prefix.size(), std::string::npos); 8884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 8894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 8904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 891dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ParseSessionUpdate(const buzz::XmlElement* action_elem, 892dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SessionUpdate* update, ParseError* error) { 893dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO: Parse the update message. 894dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 895dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 896dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 897dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid WriteSessionView(const SessionView& view, XmlElements* elems) { 898dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::vector<VideoViewRequest>::const_iterator it; 899dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (it = view.view_requests.begin(); it != view.view_requests.end(); it++) { 900dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::scoped_ptr<buzz::XmlElement> view_elem( 901dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new buzz::XmlElement(QN_GINGLE_VIEW)); 902dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (view_elem.get() == NULL) { 903dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 904dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 905dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 906dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen view_elem->SetAttr(QN_GINGLE_VIEW_TYPE, GINGLE_VIEW_TYPE_STATIC); 907dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen view_elem->SetAttr(QN_GINGLE_VIEW_NICK, it->nick_name); 908dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen view_elem->SetAttr(QN_GINGLE_VIEW_MEDIA_TYPE, 909dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GINGLE_VIEW_MEDIA_TYPE_VIDEO); 910dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 911dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // A 32-bit uint, expressed as decimal, has a max of 10 digits, plus one 912dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // for the null. 913dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char str[11]; 914dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int result = talk_base::sprintfn(str, ARRAY_SIZE(str), "%u", it->ssrc); 915dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (result < 0 || result >= ARRAY_SIZE(str)) { 916dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 917dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 918dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen view_elem->SetAttr(QN_GINGLE_VIEW_SSRC, str); 919dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 920dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Include video-specific parameters in a child <params> element. 921dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::scoped_ptr<buzz::XmlElement> params_elem( 922dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new buzz::XmlElement(QN_GINGLE_VIEW_PARAMS)); 923dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (params_elem.get() == NULL) { 924dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 925dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 926dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 927dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen result = talk_base::sprintfn(str, ARRAY_SIZE(str), "%u", it->width); 928dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (result < 0 || result >= ARRAY_SIZE(str)) { 929dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 930dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 931dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params_elem->SetAttr(QN_GINGLE_VIEW_PARAMS_WIDTH, str); 932dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 933dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen result = talk_base::sprintfn(str, ARRAY_SIZE(str), "%u", it->height); 934dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (result < 0 || result >= ARRAY_SIZE(str)) { 935dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 936dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 937dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params_elem->SetAttr(QN_GINGLE_VIEW_PARAMS_HEIGHT, str); 938dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 939dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen result = talk_base::sprintfn(str, ARRAY_SIZE(str), "%u", it->framerate); 940dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (result < 0 || result >= ARRAY_SIZE(str)) { 941dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 942dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 943dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen params_elem->SetAttr(QN_GINGLE_VIEW_PARAMS_FRAMERATE, str); 944dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 945dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen view_elem->AddElement(params_elem.release()); 946dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen elems->push_back(view_elem.release()); 947dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 948dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 949dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 9504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool FindSessionRedirect(const buzz::XmlElement* stanza, 9514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch SessionRedirect* redirect) { 9524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const buzz::XmlElement* error_elem = GetXmlChild(stanza, LN_ERROR); 9534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (error_elem == NULL) 9544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 9554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 9564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const buzz::XmlElement* redirect_elem = 9574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch error_elem->FirstNamed(QN_GINGLE_REDIRECT); 9584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (redirect_elem == NULL) 9594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch redirect_elem = error_elem->FirstNamed(buzz::QN_STANZA_REDIRECT); 9604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (redirect_elem == NULL) 9614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 9624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 9634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!GetUriTarget(STR_REDIRECT_PREFIX, redirect_elem->BodyText(), 9644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch &redirect->target)) 9654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 9664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 9674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 9684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 9694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 970f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace cricket 971