1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2010-2013 Licq developers <licq-dev@googlegroups.com>
4  *
5  * Please refer to the COPYRIGHT file distributed with this source
6  * distribution for the names of the individual contributors.
7  *
8  * Licq is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Licq is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Licq; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #ifndef LICQJABBER_CLIENT_H
24 #define LICQJABBER_CLIENT_H
25 
26 #include <boost/noncopyable.hpp>
27 #include <boost/optional.hpp>
28 #include <gloox/client.h>
29 #include <gloox/connectionlistener.h>
30 #include <gloox/loghandler.h>
31 #include <gloox/messagehandler.h>
32 #include <gloox/rosterlistener.h>
33 #include <gloox/vcardmanager.h>
34 #include <gloox/vcardhandler.h>
35 
36 #include <licq/mainloop.h>
37 #include <licq/thread/mutex.h>
38 
39 #include "handler.h"
40 
41 namespace gloox
42 {
43 class Client;
44 class ConnectionTCPClient;
45 class RosterManager;
46 }
47 
48 namespace LicqJabber
49 {
50 
51 class Config;
52 class Handler;
53 class SessionManager;
54 class UserToVCard;
55 
56 class GlooxClient : private boost::noncopyable,
57                     public gloox::Client
58 {
59 public:
60   GlooxClient(const gloox::JID& jid, const std::string& password);
61 
62 protected:
63   // From gloox::Client
64   virtual bool checkStreamVersion(const std::string& version);
65 };
66 
67 class Client : private boost::noncopyable,
68                public gloox::ConnectionListener,
69                public gloox::RosterListener,
70                public gloox::LogHandler,
71                public gloox::VCardHandler,
72                public Licq::MainLoopCallback
73 {
74 public:
75   Client(Licq::MainLoop& mainLoop, const Licq::UserId& ownerId,
76       const std::string& user, const std::string& password,
77       const std::string& host, int port, const std::string& resource,
78       gloox::TLSPolicy tlsPolicy);
79   virtual ~Client();
80 
81   int getSocket();
82 
getSessionManager()83   SessionManager* getSessionManager() { return mySessionManager; }
84 
85   void setPassword(const std::string& password);
86   bool connect(unsigned status);
87   bool isConnected();
88   void changeStatus(unsigned status, bool notifyHandler = true);
89   void getVCard(const std::string& user);
90   void setOwnerVCard(const UserToVCard& wrapper);
91   void addUser(const std::string& user, const gloox::StringList& groupNames,
92                bool notify);
93   void changeUserGroups(const std::string& user,
94                         const gloox::StringList& groups);
95   void removeUser(const std::string& user);
96   void renameUser(const std::string& user, const std::string& newName);
97   void grantAuthorization(const std::string& user);
98   void refuseAuthorization(const std::string& user);
99   void requestAuthorization(const std::string& user, const std::string& msg);
100 
101   // gloox::ConnectionListener
102   void onConnect();
103   bool onTLSConnect(const gloox::CertInfo& info);
104   void onDisconnect(gloox::ConnectionError error);
105 
106   // gloox::RosterListener
107   void handleItemAdded(const gloox::JID& jid);
108   void handleItemSubscribed(const gloox::JID& jid);
109   void handleItemRemoved(const gloox::JID& jid);
110   void handleItemUpdated(const gloox::JID& jid);
111   void handleItemUnsubscribed(const gloox::JID& jid);
112   void handleRoster(const gloox::Roster& roster);
113   void handleRosterPresence(const gloox::RosterItem& item,
114                             const std::string& resource,
115                             gloox::Presence::PresenceType presence,
116                             const std::string& msg);
117   void handleSelfPresence(const gloox::RosterItem& item,
118                           const std::string& resource,
119                           gloox::Presence::PresenceType presence,
120                           const std::string& msg);
121   bool handleSubscriptionRequest(const gloox::JID& jid,
122                                  const std::string& msg);
123   bool handleUnsubscriptionRequest(const gloox::JID& jid,
124                                    const std::string& msg);
125   void handleNonrosterPresence(const gloox::Presence& presence);
126   void handleRosterError(const gloox::IQ& iq);
127 
128   // gloox::LogHandler
129   void handleLog(gloox::LogLevel level, gloox::LogArea area,
130                  const std::string& message);
131 
132   // gloox::VCardHandler
133   void handleVCard(const gloox::JID& jid, const gloox::VCard* vcard);
134   void handleVCardResult(gloox::VCardHandler::VCardContext context,
135                          const gloox::JID& jid,
136                          gloox::StanzaError error);
137 
138 private:
139   static Licq::Mutex myGlooxMutex;
140 
141   // Licq::MainLoopCallback
142   void rawFileEvent(int id, int fd, int revents);
143   void timeoutEvent(int id);
144 
145   Licq::MainLoop& myMainLoop;
146   Handler myHandler;
147   SessionManager* mySessionManager;
148   gloox::JID myJid;
149   GlooxClient myClient;
150   gloox::ConnectionTCPClient* myTcpClient;
151   gloox::RosterManager* myRosterManager;
152   gloox::VCardManager myVCardManager;
153   boost::optional<std::string> myPendingPhotoHash;
154 
155   void broadcastPhotoHash(const boost::optional<std::string>& hash);
156 
157   bool addRosterItem(const gloox::RosterItem& item);
158 
159   unsigned presenceToStatus(gloox::Presence::PresenceType presence);
160   gloox::Presence::PresenceType statusToPresence(unsigned status);
161 };
162 
163 } // namespace LicqJabber
164 
165 #endif
166