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