Added IsSupportingRTP function to simplify detecting when STUN supports RTP
[pwlib.git] / src / ptclib / xmpp_muc.cxx
blob54d3b37fd9572bc58bca42d77b22ff18ea4bf1c4
1 /*
2 * xmpp_muc.cxx
4 * Extensible Messaging and Presence Protocol (XMPP)
5 * JEP-0045 Multi-User Chat
7 * Portable Windows Library
9 * Copyright (c) 2004 Reitek S.p.A.
11 * The contents of this file are subject to the Mozilla Public License
12 * Version 1.0 (the "License"); you may not use this file except in
13 * compliance with the License. You may obtain a copy of the License at
14 * http://www.mozilla.org/MPL/
16 * Software distributed under the License is distributed on an "AS IS"
17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18 * the License for the specific language governing rights and limitations
19 * under the License.
21 * The Original Code is Portable Windows Library.
23 * The Initial Developer of the Original Code is Post Increment
25 * Contributor(s): ______________________________________.
27 * $Log$
28 * Revision 1.1 2004/05/09 07:23:50 rjongbloed
29 * More work on XMPP, thanks Federico Pinna and Reitek S.p.A.
34 #ifdef __GNUC__
35 #pragma implementation "xmpp_muc.h"
36 #endif
38 #include <ptlib.h>
39 #include <ptclib/xmpp_muc.h>
41 #if P_EXPAT
44 PObject::Comparison XMPP::MUC::User::Compare(const PObject & obj) const
46 if (PIsDescendant(&obj, XMPP::MUC::User))
47 return m_Nick.Compare(((const XMPP::MUC::User&)obj).m_Nick);
48 else if (PIsDescendant(&obj, PString))
49 return m_Nick.Compare((const PString&)obj);
51 PAssertAlways(PInvalidCast);
52 return PObject::LessThan;
55 ///////////////////////////////////////////////////////
57 PString XMPP::MUC::Namespace("http://jabber.org/protocol/muc");
58 PString XMPP::MUC::User::Namespace("http://jabber.org/protocol/muc#user");
60 XMPP::MUC::Room::Room(C2S::StreamHandler * handler, const JID& jid, const PString& nick)
61 : m_Handler(handler), m_RoomJID(jid)
63 PCREATE_SMART_NOTIFIEE;
65 if (PAssertNULL(m_Handler) == NULL)
66 return;
68 m_User.m_Nick = nick;
69 m_User.m_Role = XMPP::MUC::User::None;
70 m_User.m_Affiliation = XMPP::MUC::User::None_a;
72 m_RoomJID.SetResource(PString::Empty());
73 m_Handler->SessionReleasedHandlers().Add(new PCREATE_SMART_NOTIFIER(OnSessionReleased));
74 m_Handler->PresenceHandlers().Add(new PCREATE_SMART_NOTIFIER(OnPresence));
75 m_Handler->MessageSenderHandlers(m_RoomJID).Add(new PCREATE_SMART_NOTIFIER(OnMessage));
79 BOOL XMPP::MUC::Room::Enter()
81 if (PAssertNULL(m_Handler) == NULL)
82 return FALSE;
84 JID ourUser(m_RoomJID);
85 ourUser.SetResource(m_User.m_Nick);
87 XMPP::Presence pre;
88 pre.SetTo(ourUser);
89 pre.SetStatus("Available");
90 pre.SetPriority(0);
92 PXMLElement * x = new PXMLElement(NULL, "x");
93 x->SetAttribute(XMPP::Namespace, XMPP::MUC::Namespace);
95 pre.AddElement(x);
97 return m_Handler->Write(pre);
101 BOOL XMPP::MUC::Room::Leave()
103 if (PAssertNULL(m_Handler) == NULL)
104 return FALSE;
106 XMPP::Presence pre;
107 pre.SetTo(m_RoomJID);
108 pre.SetType(XMPP::Presence::Unavailable);
110 return m_Handler->Write(pre);
114 BOOL XMPP::MUC::Room::SendMessage(const PString& msg)
116 XMPP::Message _msg;
117 _msg.SetBody(msg);
119 return SendMessage(_msg);
123 BOOL XMPP::MUC::Room::SendMessage(Message& msg)
125 if (PAssertNULL(m_Handler) == NULL)
126 return FALSE;
128 msg.SetTo(m_RoomJID);
129 msg.SetType(XMPP::Message::GroupChat);
131 return m_Handler->Write(msg);
135 void XMPP::MUC::Room::OnMessage(Message& msg)
136 { m_MessageHandlers.Fire(msg); }
138 void XMPP::MUC::Room::OnRoomJoined()
139 { m_RoomJoinedHandlers.Fire(*this); }
142 void XMPP::MUC::Room::OnRoomLeft()
143 { m_RoomLeftHandlers.Fire(*this); }
146 void XMPP::MUC::Room::OnUserAdded(User& user)
147 { m_UserAddedHandlers.Fire(user); }
150 void XMPP::MUC::Room::OnUserRemoved(User& user)
151 { m_UserRemovedHandlers.Fire(user); }
154 void XMPP::MUC::Room::OnUserChanged(User& user)
155 { m_UserChangedHandlers.Fire(user); }
158 void XMPP::MUC::Room::OnSessionReleased(C2S::StreamHandler&, INT)
160 m_User.m_Role = XMPP::MUC::User::None;
161 m_User.m_Affiliation = XMPP::MUC::User::None_a;
162 OnRoomLeft();
166 void XMPP::MUC::Room::OnMessage(XMPP::Message& msg, INT)
168 OnMessage(msg);
172 void XMPP::MUC::Room::OnPresence(XMPP::Presence& msg, INT)
174 JID from = msg.GetFrom();
175 PString res = from.GetResource();
177 if (m_RoomJID != from) // It's not about this room
178 return;
180 XMPP::MUC::User::Role role = XMPP::MUC::User::Role::Unknown;
181 XMPP::MUC::User::Affiliation affiliation = XMPP::MUC::User::Affiliation::Unknown_a;
183 PXMLElement * x = msg.GetElement("x");
185 if (x != NULL && x->GetAttribute(XMPP::Namespace) == XMPP::MUC::User::Namespace) {
186 PXMLElement * item = x->GetElement("item");
188 if (item != NULL) {
189 PString attr = item->GetAttribute("role");
190 if (attr *= "none")
191 role = XMPP::MUC::User::None;
192 else if (attr *= "moderator")
193 role = XMPP::MUC::User::Moderator;
194 else if (attr *= "participant")
195 role = XMPP::MUC::User::Participant;
196 else if (attr *= "visitor")
197 role = XMPP::MUC::User::Visitor;
199 attr = item->GetAttribute("affiliation");
200 if (attr *= "none")
201 affiliation = XMPP::MUC::User::None_a;
202 else if (attr *= "owner")
203 affiliation = XMPP::MUC::User::Owner;
204 else if (attr *= "admin")
205 affiliation = XMPP::MUC::User::Admin;
206 else if (attr *= "member")
207 affiliation = XMPP::MUC::User::Member;
208 else if (attr *= "outcast")
209 affiliation = XMPP::MUC::User::Outcast;
213 if (res == m_User.m_Nick) { // is this about us?
214 if (msg.GetType() == XMPP::Presence::Unavailable) {
215 OnRoomLeft();
216 m_User.m_Role = XMPP::MUC::User::None;
217 m_User.m_Affiliation = XMPP::MUC::User::None_a;
219 else if (m_User.m_Role == XMPP::MUC::User::None) {
220 m_User.m_Role = role;
221 m_User.m_Affiliation = affiliation;
222 OnRoomJoined();
224 else {
225 m_User.m_Role = role;
226 m_User.m_Affiliation = affiliation;
227 // TODO: raise a "LocalUserChanged" event...
230 else {
231 XMPP::MUC::User user;
232 user.m_Nick = res;
233 user.m_Role = role;
234 user.m_Affiliation = affiliation;
236 XMPP::MUC::User * puser;
238 PINDEX i = m_OtherUsers.GetValuesIndex(user);
240 if (i != P_MAX_INDEX) { // known user?
241 if (msg.GetType() == XMPP::Presence::Unavailable) {
242 OnUserRemoved(user);
243 m_OtherUsers.RemoveAt(i);
245 else {
246 puser = (XMPP::MUC::User *)m_OtherUsers.GetAt(i);
247 puser->m_Role = role;
248 puser->m_Affiliation = affiliation;
249 OnUserChanged(user);
252 else { // new user!
253 puser = new XMPP::MUC::User;
254 puser->m_Role = role;
255 puser->m_Affiliation = affiliation;
256 m_OtherUsers.Append(puser);
257 OnUserAdded(user);
262 #endif // P_EXPAT
264 // End of File ///////////////////////////////////////////////////////////////