1 /* 2 * This file is part of Licq, an instant messaging client for UNIX. 3 * Copyright (C) 2004-2014 Licq developers <licq-dev@googlegroups.com> 4 * 5 * Licq is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * Licq is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Licq; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 #ifndef LICQMSN_MSN_H 21 #define LICQMSN_MSN_H 22 23 #include <licq/plugin/protocolpluginhelper.h> 24 25 #include <list> 26 #include <string> 27 #include <vector> 28 29 #include <licq/mainloop.h> 30 #include <licq/userid.h> 31 32 #include "msnbuffer.h" 33 #include "msnevent.h" 34 35 namespace Licq 36 { 37 class Event; 38 class INetSocket; 39 class TCPSocket; 40 class User; 41 } 42 43 namespace LicqMsn 44 { 45 46 const char CONTACT_LIST[] = "FL"; 47 const char ALLOW_LIST[] = "AL"; 48 const char BLOCK_LIST[] = "BL"; 49 50 const unsigned short FLAG_CONTACT_LIST = 1; 51 const unsigned short FLAG_ALLOW_LIST = 2; 52 const unsigned short FLAG_BLOCK_LIST = 4; 53 const unsigned short FLAG_REVERSE_LIST = 8; 54 55 #ifndef HAVE_STRNDUP 56 char *strndup(const char *s, size_t n); 57 #endif 58 59 60 const unsigned long MSN_DP_EVENT = 1; 61 62 class CMSNPacket; 63 class CMSNDataEvent; 64 65 struct SBuffer 66 { 67 CMSNBuffer *m_pBuf; 68 Licq::UserId myUserId; 69 bool m_bStored; 70 }; 71 72 typedef std::list<SBuffer *> BufferList; 73 74 struct SStartMessage 75 { 76 CMSNPacket *m_pPacket; 77 Licq::Event* m_pEvent; 78 Licq::UserId userId; 79 unsigned long m_nSeq; 80 bool m_bConnecting, 81 m_bDataConnection; 82 }; 83 84 typedef std::list<SStartMessage*> StartList; 85 86 struct TypingTimeout 87 { 88 int timeoutId; 89 Licq::UserId userId; 90 unsigned long convoId; 91 }; 92 93 typedef std::list<TypingTimeout> TypingTimeoutList; 94 95 class CMSN : public Licq::ProtocolPluginHelper, public Licq::MainLoopCallback 96 { 97 public: 98 CMSN(); 99 ~CMSN(); 100 101 // From Licq::PluginInterface 102 int run(); 103 104 std::string defaultServerHost() const; 105 int defaultServerPort() const; 106 Connected()107 bool Connected() { return myServerSocket != NULL; } 108 void Logon(const Licq::UserId& ownerId, unsigned status, std::string host = std::string(), int port = 0); 109 void MSNLogoff(bool = false); 110 111 void closeSocket(Licq::TCPSocket* sock, bool clearUser = true); 112 113 private: 114 // From Licq::MainLoopCallback 115 void rawFileEvent(int id, int fd, int revents); 116 void socketEvent(int id, Licq::INetSocket* inetSocket, int revents); 117 void timeoutEvent(int id); 118 119 void ProcessSignal(const Licq::ProtocolSignal* s); 120 void ProcessPipe(); 121 void ProcessServerPacket(CMSNBuffer *); 122 void ProcessSSLServerPacket(CMSNBuffer &); 123 void ProcessSBPacket(const Licq::UserId& socketUserId, CMSNBuffer*, 124 Licq::TCPSocket* sock); 125 126 // Network functions 127 void sendServerPing(); 128 void SendPacket(CMSNPacket *); 129 void Send_SB_Packet(const Licq::UserId& userId, CMSNPacket* p, Licq::TCPSocket* sock, 130 bool bDelete = true); 131 void MSNAuthenticate(const std::string& host = "login.passport.com", 132 const std::string& path = "/login2.srf"); 133 bool MSNSBConnectStart(const std::string& server, const std::string& cookie); 134 bool MSNSBConnectAnswer(const std::string& server, const std::string& sessionId, 135 const std::string& cookie, const Licq::UserId& userId); 136 137 void MSNSendInvitation(const Licq::UserId& userId, CMSNPacket* _pPacket); 138 void MSNSendMessage(unsigned long eventId, const Licq::UserId& userId, const std::string& message, 139 pthread_t _tPlugin, unsigned long _nCID); 140 void MSNSendTypingNotification(const Licq::UserId& userId, unsigned long convoId); 141 void MSNChangeStatus(unsigned status); 142 void MSNAddUser(const Licq::UserId& userId); 143 void MSNRemoveUser(const Licq::UserId& userId); 144 void MSNRenameUser(const Licq::UserId& userId); 145 void MSNGrantAuth(const Licq::UserId& userId); 146 void MSNUpdateUser(const std::string& alias); 147 void MSNBlockUser(const Licq::UserId& userId); 148 void MSNUnblockUser(const Licq::UserId& userId); 149 void MSNGetDisplayPicture(const Licq::UserId& userId, const std::string& msnObject); 150 151 // Internal functions HashValue(int n)152 int HashValue(int n) { return n % 211; } 153 void StorePacket(SBuffer *, int); 154 void RemovePacket(const Licq::UserId& userId, int socketId, int size = 0); 155 SBuffer* RetrievePacket(const Licq::UserId& userId, int socketId); 156 Licq::Event* RetrieveEvent(unsigned long); 157 void HandlePacket(Licq::TCPSocket* sock, CMSNBuffer&, const Licq::UserId& userId); 158 unsigned long SocketToCID(int); 159 static std::string Decode(const std::string& strIn); 160 static std::string Encode(const std::string& strIn); 161 void WaitDataEvent(CMSNDataEvent *); 162 bool RemoveDataEvent(CMSNDataEvent *); 163 CMSNDataEvent* FetchDataEvent(const Licq::UserId& userId, Licq::TCPSocket* sock); 164 CMSNDataEvent* FetchStartDataEvent(const Licq::UserId& userId); 165 166 /** 167 * Kill a conversation and all users associated with it 168 * Called when a new socket is opened to make sure it isn't associated with any old conversations 169 * 170 * @param sock Socket to clear conversations for 171 */ 172 void killConversation(Licq::TCPSocket* sock); 173 174 /** 175 * Get a unique id for scheudling a timeout callback 176 */ 177 int getNextTimeoutId(); 178 179 /** 180 * Update typing status for a user 181 * 182 * @param u User object 183 * @param typing New typing status 184 * @param cid Conversation id 185 */ 186 void setIsTyping(Licq::User* u, bool typing, unsigned long cid); 187 188 /** 189 * Update our typing status towards a user 190 * 191 * @param u User object 192 * @param typing New typing status 193 * @param cid Conversation id 194 */ 195 void sendIsTyping(const Licq::UserId& userId, bool typing, unsigned long cid); 196 197 /** 198 * Handle timeouts for typing notifications 199 * 200 * @param id Timeout id from mainloop 201 */ 202 void typingTimeout(int id); 203 204 // Variables 205 Licq::UserId myOwnerId; 206 Licq::MainLoop myMainLoop; 207 Licq::TCPSocket* myServerSocket; 208 Licq::TCPSocket* mySslSocket; 209 CMSNBuffer *m_pPacketBuf, 210 *m_pSSLPacket; 211 std::vector<BufferList> m_vlPacketBucket; 212 std::list<Licq::Event*> m_pEvents; 213 std::list<CMSNDataEvent*> m_lMSNEvents; 214 StartList m_lStart; 215 bool m_bWaitingPingReply, 216 m_bCanPing; 217 TypingTimeoutList myUserTypingTimeouts; 218 TypingTimeoutList myOwnerTypingTimeouts; 219 int myNextTimeoutId; 220 221 // Server variables 222 unsigned myStatus; 223 unsigned long m_nSessionStart; 224 std::string m_strMSPAuth, 225 m_strSID, 226 m_strKV; 227 std::string myCookie; 228 std::string myPassword; 229 230 friend class CMSNDataEvent; 231 }; 232 233 } // namespace LicqMsn 234 235 #endif 236