1269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/* 2269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * 4269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org */ 10269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 11269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/pubsub_task.h" 12269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 13269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <map> 14269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include <string> 15269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 16269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/constants.h" 17269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/libjingle/xmpp/xmppengine.h" 18269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/common.h" 19269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 20269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgnamespace buzz { 21269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 22269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgPubsubTask::PubsubTask(XmppTaskParentInterface* parent, 23269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::Jid& pubsub_node_jid) 24269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org : buzz::XmppTask(parent, buzz::XmppEngine::HL_SENDER), 25269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pubsub_node_jid_(pubsub_node_jid) { 26269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 27269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 28269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgPubsubTask::~PubsubTask() { 29269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 30269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 31269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Checks for pubsub publish events as well as responses to get IQs. 32269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool PubsubTask::HandleStanza(const buzz::XmlElement* stanza) { 33269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::QName& stanza_name(stanza->Name()); 34269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (stanza_name == buzz::QN_MESSAGE) { 35269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (MatchStanzaFrom(stanza, pubsub_node_jid_)) { 36269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* pubsub_event_item = 37269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org stanza->FirstNamed(QN_PUBSUB_EVENT); 38269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (pubsub_event_item != NULL) { 39269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org QueueStanza(pubsub_event_item); 40269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 41269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 42269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 43269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } else if (stanza_name == buzz::QN_IQ) { 44269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (MatchResponseIq(stanza, pubsub_node_jid_, task_id())) { 45269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* pubsub_item = stanza->FirstNamed(QN_PUBSUB); 46269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (pubsub_item != NULL) { 47269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org QueueStanza(pubsub_item); 48269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 49269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 50269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 51269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 52269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 53269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 54269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 55269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgint PubsubTask::ProcessResponse() { 56269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* stanza = NextStanza(); 57269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (stanza == NULL) { 58269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return STATE_BLOCKED; 59269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 60269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 61269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (stanza->Attr(buzz::QN_TYPE) == buzz::STR_ERROR) { 62269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org OnPubsubError(stanza->FirstNamed(buzz::QN_ERROR)); 63269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return STATE_RESPONSE; 64269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 65269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 66269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::QName& stanza_name(stanza->Name()); 67269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (stanza_name == QN_PUBSUB_EVENT) { 68269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org HandlePubsubEventMessage(stanza); 69269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } else if (stanza_name == QN_PUBSUB) { 70269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org HandlePubsubIqGetResponse(stanza); 71269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 72269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 73269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return STATE_RESPONSE; 74269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 75269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 76269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Registers a function pointer to be called when the value of the pubsub 77269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// node changes. 78269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Note that this does not actually change the XMPP pubsub 79269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// subscription. All publish events are always received by everyone in the 80269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// MUC. This function just controls whether the handle function will get 81269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// called when the event is received. 82269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgbool PubsubTask::SubscribeToNode(const std::string& pubsub_node, 83269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org NodeHandler handler) { 84269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org subscribed_nodes_[pubsub_node] = handler; 85269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org rtc::scoped_ptr<buzz::XmlElement> get_iq_request( 86269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org MakeIq(buzz::STR_GET, pubsub_node_jid_, task_id())); 87269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (!get_iq_request) { 88269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 89269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 90269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org buzz::XmlElement* pubsub_element = new buzz::XmlElement(QN_PUBSUB, true); 91269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org buzz::XmlElement* items_element = new buzz::XmlElement(QN_PUBSUB_ITEMS, true); 92269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 93269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org items_element->AddAttr(buzz::QN_NODE, pubsub_node); 94269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org pubsub_element->AddElement(items_element); 95269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org get_iq_request->AddElement(pubsub_element); 96269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 97269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (SendStanza(get_iq_request.get()) != buzz::XMPP_RETURN_OK) { 98269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return false; 99269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 100269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 101269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return true; 102269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 103269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 104269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PubsubTask::UnsubscribeFromNode(const std::string& pubsub_node) { 105269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org subscribed_nodes_.erase(pubsub_node); 106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PubsubTask::OnPubsubError(const buzz::XmlElement* error_stanza) { 109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Checks for a pubsub event message like the following: 112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <message from="muvc-private-chat-some-id@groupchat.google.com" 114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// to="john@site.com/gcomm582B14C9"> 115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <event xmlns:"http://jabber.org/protocol/pubsub#event"> 116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <items node="node-name"> 117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <item id="some-id"> 118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <payload/> 119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </item> 120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </items> 121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </event> 122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </message> 123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// It also checks for retraction event messages like the following: 125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <message from="muvc-private-chat-some-id@groupchat.google.com" 127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// to="john@site.com/gcomm582B14C9"> 128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <event xmlns:"http://jabber.org/protocol/pubsub#event"> 129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <items node="node-name"> 130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <retract id="some-id"/> 131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </items> 132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </event> 133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </message> 134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PubsubTask::HandlePubsubEventMessage( 135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* pubsub_event) { 136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org ASSERT(pubsub_event->Name() == QN_PUBSUB_EVENT); 137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (const buzz::XmlChild* child = pubsub_event->FirstChild(); 138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org child != NULL; 139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org child = child->NextChild()) { 140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* child_element = child->AsElement(); 141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::QName& child_name(child_element->Name()); 142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (child_name == QN_PUBSUB_EVENT_ITEMS) { 143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org HandlePubsubItems(child_element); 144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Checks for a response to an pubsub IQ get like the following: 149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <iq from="muvc-private-chat-some-id@groupchat.google.com" 151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// to="john@site.com/gcomm582B14C9" 152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// type="result"> 153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <pubsub xmlns:"http://jabber.org/protocol/pubsub"> 154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <items node="node-name"> 155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <item id="some-id"> 156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// <payload/> 157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </item> 158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </items> 159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </event> 160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// </message> 161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PubsubTask::HandlePubsubIqGetResponse( 162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* pubsub_iq_response) { 163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org ASSERT(pubsub_iq_response->Name() == QN_PUBSUB); 164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org for (const buzz::XmlChild* child = pubsub_iq_response->FirstChild(); 165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org child != NULL; 166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org child = child->NextChild()) { 167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* child_element = child->AsElement(); 168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::QName& child_name(child_element->Name()); 169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (child_name == QN_PUBSUB_ITEMS) { 170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org HandlePubsubItems(child_element); 171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Calls registered handlers in response to pubsub event or response to 176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// IQ pubsub get. 177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// 'items' is the child of a pubsub#event:event node or pubsub:pubsub node. 178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PubsubTask::HandlePubsubItems(const buzz::XmlElement* items) { 179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org ASSERT(items->HasAttr(QN_NODE)); 180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const std::string& node_name(items->Attr(QN_NODE)); 181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org NodeSubscriptions::iterator iter = subscribed_nodes_.find(node_name); 182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (iter != subscribed_nodes_.end()) { 183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org NodeHandler handler = iter->second; 184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::XmlElement* item = items->FirstElement(); 185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org while (item != NULL) { 186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org const buzz::QName& item_name(item->Name()); 187269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org if (item_name != QN_PUBSUB_EVENT_ITEM && 188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org item_name != QN_PUBSUB_EVENT_RETRACT && 189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org item_name != QN_PUBSUB_ITEM) { 190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org continue; 191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org (this->*handler)(item); 194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org item = item->NextElement(); 195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org return; 197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org } 198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org 200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org} 201