Yate
yatecbase.h
00001 /*
00002  * yatecbase.h
00003  * This file is part of the YATE Project http://YATE.null.ro
00004  *
00005  * Common base classes for all telephony clients
00006  *
00007  * Yet Another Telephony Engine - a fully featured software PBX and IVR
00008  * Copyright (C) 2004-2006 Null Team
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00023  */
00024 
00025 #ifndef __YATECBASE_H
00026 #define __YATECBASE_H
00027 
00028 #ifndef __cplusplus
00029 #error C++ is required
00030 #endif
00031 
00032 #include <yatephone.h>
00033 
00037 namespace TelEngine {
00038 
00039 class Window;                            // A generic window
00040 class UIWidget;                          // A custom widget
00041 class UIFactory;                         // Base factory used to build custom widgets
00042 class Client;                            // The client
00043 class ClientChannel;                     // A client telephony channel
00044 class ClientDriver;                      // The client telephony driver
00045 class ClientLogic;                       // Base class for all client logics
00046 class DefaultLogic;                      // The client's default logic
00047 class ClientWizard;                      // A client wizard
00048 class ClientAccount;                     // A client account
00049 class ClientAccountList;                 // A client account list
00050 class ClientContact;                     // A client contact
00051 class ClientResource;                    // A client contact's resource
00052 class MucRoomMember;                     // A MUC room member
00053 class MucRoom;                           // An account's MUC room contact
00054 class DurationUpdate;                    // Class used to update UI durations
00055 class ClientSound;                       // A sound file
00056 
00057 
00063 class YATE_API Window : public GenObject
00064 {
00065     friend class Client;
00066     YNOCOPY(Window); // no automatic copies please
00067 public:
00072     explicit Window(const char* id = 0);
00073 
00077     virtual ~Window();
00078 
00083     virtual const String& toString() const;
00084 
00085     /*
00086      * Get the window's title (may not be displayed on screen)
00087      * @return Title of this window
00088      */
00089     virtual void title(const String& text);
00090 
00095     virtual void context(const String& text);
00096 
00102     virtual bool setParams(const NamedList& params);
00103 
00108     virtual void setOver(const Window* parent) = 0;
00109 
00115     virtual bool hasElement(const String& name) = 0;
00116 
00123     virtual bool setActive(const String& name, bool active) = 0;
00124 
00131     virtual bool setFocus(const String& name, bool select = false) = 0;
00132 
00139     virtual bool setShow(const String& name, bool visible) = 0;
00140 
00148     virtual bool setText(const String& name, const String& text,
00149         bool richText = false) = 0;
00150 
00157     virtual bool setCheck(const String& name, bool checked) = 0;
00158 
00165     virtual bool setSelect(const String& name, const String& item) = 0;
00166 
00173     virtual bool setUrgent(const String& name, bool urgent) = 0;
00174 
00181     virtual bool hasOption(const String& name, const String& item) = 0;
00182 
00191     virtual bool addOption(const String& name, const String& item, bool atStart = false,
00192         const String& text = String::empty()) = 0;
00193 
00200     virtual bool getOptions(const String& name, NamedList* items) = 0;
00201 
00208     virtual bool delOption(const String& name, const String& item) = 0;
00209 
00218     virtual bool addLines(const String& name, const NamedList* lines, unsigned int max,
00219         bool atStart = false);
00220 
00229     virtual bool addTableRow(const String& name, const String& item,
00230         const NamedList* data = 0, bool atStart = false);
00231 
00239     virtual bool setMultipleRows(const String& name, const NamedList& data, const String& prefix = String::empty());
00240 
00249     virtual bool insertTableRow(const String& name, const String& item,
00250         const String& before, const NamedList* data = 0);
00251 
00258     virtual bool delTableRow(const String& name, const String& item);
00259 
00267     virtual bool setTableRow(const String& name, const String& item, const NamedList* data);
00268 
00277     virtual bool updateTableRow(const String& name, const String& item,
00278         const NamedList* data = 0, bool atStart = false);
00279 
00291     virtual bool updateTableRows(const String& name, const NamedList* data,
00292         bool atStart = false);
00293 
00301     virtual bool getTableRow(const String& name, const String& item, NamedList* data = 0);
00302 
00308     virtual bool clearTable(const String& name);
00309 
00317     virtual bool getText(const String& name, String& text, bool richText = false) = 0;
00318 
00325     virtual bool getCheck(const String& name, bool& checked) = 0;
00326 
00333     virtual bool getSelect(const String& name, String& item) = 0;
00334 
00341     virtual bool buildMenu(const NamedList& params) = 0;
00342 
00349     virtual bool removeMenu(const NamedList& params) = 0;
00350 
00358     virtual bool setImage(const String& name, const String& image, bool fit = false) = 0;
00359 
00367     virtual bool setProperty(const String& name, const String& item, const String& value)
00368         { return false; }
00369 
00377     virtual bool getProperty(const String& name, const String& item, String& value)
00378         { return false; }
00379 
00383     inline void populate() {
00384             if (m_populated)
00385                 return;
00386             doPopulate();
00387             m_populated = true;
00388         }
00389 
00393     inline void init() {
00394             if (m_initialized)
00395                 return;
00396             doInit();
00397             m_initialized = true;
00398         }
00399 
00403     virtual void show() = 0;
00404 
00408     virtual void hide() = 0;
00409 
00415     virtual void size(int width, int height) = 0;
00416 
00422     virtual void move(int x, int y) = 0;
00423 
00429     virtual void moveRel(int dx, int dy) = 0;
00430 
00436     virtual bool related(const Window* wnd) const;
00437 
00438     virtual void menu(int x, int y) = 0;
00439 
00444     virtual bool canClose()
00445         { return true; }
00446 
00451     inline const String& id() const
00452         { return m_id; }
00453 
00454     /*
00455      * Get the window's title (may not be displayed on screen)
00456      * @return Title of this window
00457      */
00458     inline const String& title() const
00459         { return m_title; }
00460 
00465     inline const String& context() const
00466         { return m_context; }
00467 
00472     inline bool visible() const
00473         { return m_visible; }
00474 
00479     inline void visible(bool yes)
00480         { if (yes) show(); else hide(); }
00481 
00486     inline bool active() const
00487         { return m_active; }
00488 
00493     inline bool master() const
00494         { return m_master; }
00495 
00500     inline bool popup() const
00501         { return m_popup; }
00502 
00511     virtual bool createDialog(const String& name, const String& title,
00512         const String& alias = String::empty(), const NamedList* params = 0) = 0;
00513 
00519     virtual bool closeDialog(const String& name) = 0;
00520 
00527     static bool isValidParamPrefix(const String& prefix);
00528 
00529 protected:
00530     virtual void doPopulate() = 0;
00531     virtual void doInit() = 0;
00532 
00533     String m_id;
00534     String m_title;
00535     String m_context;
00536     bool m_visible;
00537     bool m_active;
00538     bool m_master;
00539     bool m_popup;
00540     bool m_saveOnClose;                  // Save window's data when destroyed
00541 
00542 private:
00543     bool m_populated;                    // Already populated flag
00544     bool m_initialized;                  // Already initialized flag
00545 };
00546 
00547 class YATE_API UIWidget : public String
00548 {
00549     YNOCOPY(UIWidget); // no automatic copies please
00550 public:
00555     inline explicit UIWidget(const char* name = 0)
00556         : String(name)
00557         { }
00558 
00562     virtual ~UIWidget()
00563         { }
00564 
00569     inline const String& name() const
00570         { return toString(); }
00571 
00577     virtual bool setParams(const NamedList& params)
00578         { return false; }
00579 
00585     virtual bool getOptions(NamedList& items)
00586         { return false; }
00587 
00595     virtual bool addTableRow(const String& item, const NamedList* data = 0,
00596         bool atStart = false)
00597         { return false; }
00598 
00604     virtual bool setMultipleRows(const NamedList& data, const String& prefix = String::empty())
00605         { return false; }
00606 
00617     virtual bool updateTableRows(const NamedList* data, bool atStart = false)
00618         { return false; }
00619 
00627     virtual bool insertTableRow(const String& item, const String& before,
00628         const NamedList* data = 0)
00629         { return false; }
00630 
00636     virtual bool delTableRow(const String& item)
00637         { return false; }
00638 
00645     virtual bool setTableRow(const String& item, const NamedList* data)
00646         { return false; }
00647 
00654     virtual bool getTableRow(const String& item, NamedList* data = 0)
00655         { return false; }
00656 
00661     virtual bool clearTable()
00662         { return false; }
00663 
00669     virtual bool setSelect(const String& item)
00670         { return false; }
00671 
00677     virtual bool getSelect(String& item)
00678         { return false; }
00679 
00687     virtual bool addLines(const NamedList& lines, unsigned int max, bool atStart = false)
00688         { return false; }
00689 
00696     virtual bool setText(const String& text, bool richText = false)
00697         { return false; }
00698 
00705     virtual bool getText(String& text, bool richText = false)
00706         { return false; }
00707 };
00708 
00714 class YATE_API UIFactory : public String
00715 {
00716     YNOCOPY(UIFactory); // no automatic copies please
00717 public:
00721     explicit UIFactory(const char* name);
00722 
00726     virtual ~UIFactory();
00727 
00733     inline bool canBuild(const String& type)
00734         { return 0 != m_types.find(type); }
00735 
00743     virtual void* create(const String& type, const char* name, NamedList* params = 0) = 0;
00744 
00754     static void* build(const String& type, const char* name, NamedList* params = 0,
00755         const char* factory = 0);
00756 
00757 protected:
00758     ObjList m_types;                     // List of object types this factory can build
00759 
00760 private:
00761     static ObjList s_factories;          // Registered factories list
00762 };
00763 
00768 class YATE_API Client : public MessageReceiver
00769 {
00770     friend class Window;
00771     friend class ClientChannel;
00772     friend class ClientDriver;
00773     friend class ClientLogic;
00774 public:
00778     enum MsgID {
00779         CallCdr = 0,
00780         UiAction,
00781         UserLogin,
00782         UserNotify,
00783         ResourceNotify,
00784         ResourceSubscribe,
00785         ClientChanUpdate,
00786         UserRoster,
00787         ContactInfo,
00788         // Handlers not automatically installed
00789         ChanNotify,
00790         MucRoom,
00791         // IDs used only to postpone messages
00792         MsgExecute,
00793         EngineStart,
00794         TransferNotify,
00795         UserData,
00796         // Starting value for custom relays
00797         MsgIdCount
00798     };
00799 
00803     enum ClientToggle {
00804         OptMultiLines = 0,               // Accept incoming calls
00805         OptAutoAnswer,                   // Auto answer incoming calls
00806         OptRingIn,                       // Enable/disable incoming ringer
00807         OptRingOut,                      // Enable/disable outgoing ringer
00808         OptActivateLastOutCall,          // Set the last outgoing call active
00809         OptActivateLastInCall,           // Set the last incoming call active
00810         OptActivateCallOnSelect,         // Set the active call when selected in channel
00811                                          //  list (don't require double click)
00812         OptKeypadVisible,                // Show/hide keypad
00813         OptOpenIncomingUrl,              // Open an incoming URL in call.execute message
00814         OptAddAccountOnStartup,          // Open account add window on startup
00815         OptDockedChat,                   // Show all contacts chat in the same window
00816         OptDestroyChat,                  // Destroy contact chat when contact is removed/destroyed
00817         OptNotifyChatState,              // Notify chat states
00818         OptShowEmptyChat,                // Display received empty chat in chat history
00819         OptSendEmptyChat,                // Send empty chat
00820         OptCount
00821     };
00822 
00826     enum TrayIconType {
00827         TrayIconMain = 0,
00828         TrayIconInfo = 1000,
00829         TrayIconIncomingChat = 3000,
00830         TrayIconNotification = 5000,
00831         TrayIconIncomingCall = 10000,
00832     };
00833 
00838     explicit Client(const char *name = 0);
00839 
00843     virtual ~Client();
00844 
00849     virtual bool startup();
00850 
00854     virtual void run();
00855 
00859     virtual void cleanup();
00860 
00864     virtual void main() = 0;
00865 
00869     virtual void lock() = 0;
00870 
00874     virtual void unlock() = 0;
00875 
00879     inline void lockOther()
00880         { if (!m_oneThread) lock(); }
00881 
00885     inline void unlockOther()
00886         { if (!m_oneThread) unlock(); }
00887 
00892     inline void setThread(Thread* th)
00893         { m_clientThread = th; }
00894 
00898     virtual void allHidden() = 0;
00899 
00905     void loadUI(const char* file = 0, bool init = true);
00906 
00910     virtual void quit() = 0;
00911 
00917     bool openUrlSafe(const String& url);
00918 
00924     virtual bool openUrl(const String& url) = 0;
00925 
00932     virtual bool received(Message& msg, int id);
00933 
00941     virtual bool createWindowSafe(const String& name,
00942         const String& alias = String::empty());
00943 
00953     virtual bool createDialog(const String& name, Window* parent, const String& title,
00954         const String& alias = String::empty(), const NamedList* params = 0);
00955 
00964     virtual bool createObject(void** dest, const String& type, const char* name,
00965         NamedList* params = 0);
00966 
00973     virtual bool closeWindow(const String& name, bool hide = true);
00974 
00982     virtual bool closeDialog(const String& name, Window* wnd, Window* skip = 0);
00983 
00989     virtual bool debugHook(bool active);
00990 
00996     virtual bool addToLog(const String& text);
00997 
01004     virtual bool setStatus(const String& text, Window* wnd = 0);
01005 
01012     bool setStatusLocked(const String& text, Window* wnd = 0);
01013 
01021     bool setParams(const NamedList* params, Window* wnd = 0, Window* skip = 0);
01022 
01031     virtual bool action(Window* wnd, const String& name, NamedList* params = 0);
01032 
01041     virtual bool toggle(Window* wnd, const String& name, bool active);
01042 
01052     virtual bool select(Window* wnd, const String& name, const String& item, const String& text = String::empty());
01053 
01058     inline bool oneThread() const
01059         { return m_oneThread; }
01060 
01065     inline int line() const
01066         { return m_line; }
01067 
01072     void line(int newLine);
01073 
01074     bool hasElement(const String& name, Window* wnd = 0, Window* skip = 0);
01075     bool setActive(const String& name, bool active, Window* wnd = 0, Window* skip = 0);
01076     bool setFocus(const String& name, bool select = false, Window* wnd = 0, Window* skip = 0);
01077     bool setShow(const String& name, bool visible, Window* wnd = 0, Window* skip = 0);
01078     bool setText(const String& name, const String& text, bool richText = false,
01079         Window* wnd = 0, Window* skip = 0);
01080     bool setCheck(const String& name, bool checked, Window* wnd = 0, Window* skip = 0);
01081     bool setSelect(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
01082     bool setUrgent(const String& name, bool urgent, Window* wnd = 0, Window* skip = 0);
01083     bool hasOption(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
01084 
01093     virtual bool getOptions(const String& name, NamedList* items,
01094         Window* wnd = 0, Window* skip = 0);
01095 
01096     bool addOption(const String& name, const String& item, bool atStart,
01097         const String& text = String::empty(), Window* wnd = 0, Window* skip = 0);
01098     bool delOption(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
01099 
01110     bool addLines(const String& name, const NamedList* lines, unsigned int max,
01111         bool atStart = false, Window* wnd = 0, Window* skip = 0);
01112 
01113     bool addTableRow(const String& name, const String& item, const NamedList* data = 0,
01114         bool atStart = false, Window* wnd = 0, Window* skip = 0);
01115 
01124     bool setMultipleRows(const String& name, const NamedList& data, const String& prefix = String::empty(), Window* wnd = 0, Window* skip = 0);
01125 
01136     bool insertTableRow(const String& name, const String& item,
01137         const String& before, const NamedList* data = 0,
01138         Window* wnd = 0, Window* skip = 0);
01139 
01140     bool delTableRow(const String& name, const String& item, Window* wnd = 0, Window* skip = 0);
01141     bool setTableRow(const String& name, const String& item, const NamedList* data,
01142         Window* wnd = 0, Window* skip = 0);
01143     bool getTableRow(const String& name, const String& item, NamedList* data = 0,
01144         Window* wnd = 0, Window* skip = 0);
01145     bool clearTable(const String& name, Window* wnd = 0, Window* skip = 0);
01146 
01157     bool updateTableRow(const String& name, const String& item, const NamedList* data = 0,
01158         bool atStart = false, Window* wnd = 0, Window* skip = 0);
01159 
01173     bool updateTableRows(const String& name, const NamedList* data, bool atStart = false,
01174         Window* wnd = 0, Window* skip = 0);
01175 
01185     bool getText(const String& name, String& text, bool richText = false, Window* wnd = 0, Window* skip = 0);
01186 
01187     bool getCheck(const String& name, bool& checked, Window* wnd = 0, Window* skip = 0);
01188     bool getSelect(const String& name, String& item, Window* wnd = 0, Window* skip = 0);
01189 
01214     bool buildMenu(const NamedList& params, Window* wnd = 0, Window* skip = 0);
01215 
01226     bool removeMenu(const NamedList& params, Window* wnd = 0, Window* skip = 0);
01227 
01236     virtual bool setImage(const String& name, const String& image,
01237         Window* wnd = 0, Window* skip = 0);
01238 
01247     virtual bool setImageFit(const String& name, const String& image,
01248         Window* wnd = 0, Window* skip = 0);
01249 
01259     virtual bool setProperty(const String& name, const String& item, const String& value,
01260         Window* wnd = 0, Window* skip = 0);
01261 
01271     virtual bool getProperty(const String& name, const String& item, String& value,
01272         Window* wnd = 0, Window* skip = 0);
01273 
01274     void moveRelated(const Window* wnd, int dx, int dy);
01275     inline bool initialized() const
01276         { return m_initialized; }
01277     inline static Client* self()
01278         { return s_client; }
01279     inline static void setSelf(Client* client)
01280         { s_client = client; }
01281 
01286     static inline bool valid()
01287         { return self() && (self()->isUIThread() || !(exiting() || Engine::exiting())); }
01288 
01294     static bool isClientMsg(Message& msg);
01295 
01296     inline static bool changing()
01297         { return (s_changing > 0); }
01298     static Window* getWindow(const String& name);
01299     static bool setVisible(const String& name, bool show = true, bool activate = false);
01300     static bool getVisible(const String& name);
01301     static bool openPopup(const String& name, const NamedList* params = 0, const Window* parent = 0);
01302     static bool openMessage(const char* text, const Window* parent = 0, const char* context = 0);
01303     static bool openConfirm(const char* text, const Window* parent = 0, const char* context = 0);
01304     static ObjList* listWindows();
01305     void idleActions();
01306 
01314     bool postpone(const Message& msg, int id, bool copyUserData = false);
01315 
01324     virtual bool chooseFile(Window* parent, NamedList& params)
01325         { return false; }
01326 
01337     virtual bool setClientParam(const String& param, const String& value,
01338         bool save, bool update);
01339 
01346     virtual bool backspace(const String& name, Window* wnd = 0);
01347 
01355     void installRelay(const char* name, int id, int prio);
01356 
01361     virtual bool callRouting(Message& msg)
01362         { return true;}
01363 
01368     virtual bool imRouting(Message& msg)
01369         { return true;}
01370 
01375     virtual bool imExecute(Message& msg);
01376 
01387     virtual bool buildIncomingChannel(Message& msg, const String& dest);
01388 
01394     virtual bool buildOutgoingChannel(NamedList& params);
01395 
01403     bool callIncoming(Message& msg, const String& dest);
01404 
01411     void callAnswer(const String& id, bool setActive = true);
01412 
01420     void callTerminate(const String& id, const char* reason = 0, const char* error = 0);
01421 
01426     ClientChannel* getActiveChannel();
01427 
01435     virtual bool ringer(bool in, bool on);
01436 
01444     virtual bool createSound(const char* name, const char* file, const char* device = 0)
01445         { return false; }
01446 
01453     bool emitDigits(const char* digits, const String& id = String::empty());
01454 
01461     inline bool emitDigit(char digit, const String& id = String::empty()) {
01462             char s[2] = {digit,0};
01463             return emitDigits(s,id);
01464         }
01465 
01471     inline bool getBoolOpt(ClientToggle toggle)
01472         { return toggle < OptCount ? m_toggles[toggle] : false; }
01473 
01481     bool setBoolOpt(ClientToggle toggle, bool value, bool updateUi = false);
01482 
01491     virtual bool formatDateTime(String& dest, unsigned int secs, const char* format,
01492         bool utc = false)
01493         { return false; }
01494 
01499     static inline bool exiting()
01500         { return s_exiting; }
01501 
01507     static bool getActive(const String& name);
01508 
01517     static Message* buildMessage(const char* msg, const String& account,
01518         const char* oper = 0);
01519 
01527     static Message* buildNotify(bool online, const String& account,
01528         const ClientResource* from = 0);
01529 
01540     static Message* buildSubscribe(bool request, bool ok, const String& account,
01541         const String& contact, const char* proto = 0);
01542 
01551     static Message* buildUserRoster(bool update, const String& account,
01552         const String& contact, const char* proto = 0);
01553 
01559     static bool addLogic(ClientLogic* logic);
01560 
01565     static void removeLogic(ClientLogic* logic);
01566 
01572     static ClientLogic* findLogic(const String& name);
01573 
01582     static Message* eventMessage(const String& event, Window* wnd = 0,
01583         const char* name = 0, NamedList* params = 0);
01584 
01592     static bool save(Configuration& cfg, Window* parent = 0, bool showErr = true);
01593 
01599     static ClientToggle getBoolOpt(const String& name);
01600 
01604     static inline void setLogicsTick()
01605         { s_idleLogicsTick = true; }
01606 
01614     static void appendEscape(String& buf, ObjList& list, char sep = ',', bool force = false);
01615 
01623     static ObjList* splitUnescape(const String& buf, char sep = ',', bool emptyOk = false);
01624 
01630     static void removeChars(String& buf, const char* chars);
01631 
01640     static void fixPhoneNumber(String& number, const char* chars = 0);
01641 
01651     static bool addTrayIcon(const String& wndName, int prio, NamedList* params);
01652 
01661     static bool removeTrayIcon(const String& wndName, const String& name);
01662 
01670     static bool updateTrayIcon(const String& wndName);
01671 
01677     static void generateGuid(String& buf, const String& extra = String::empty());
01678 
01684     static void plain2html(String& buf, bool spaceEol = false);
01685 
01686     static Configuration s_settings;     // Client settings
01687     static Configuration s_actions;      // Logic preferrences
01688     static Configuration s_accounts;     // Accounts
01689     static Configuration s_contacts;     // Contacts
01690     static Configuration s_providers;    // Provider settings
01691     static Configuration s_history;      // Call log
01692     static Configuration s_calltoHistory;  // Dialed destinations history
01693     // Holds a not selected/set value match
01694     static Regexp s_notSelected;
01695     // Regexp used to check if a string is a GUID in the format
01696     // 8*HEX-4*HEX-4*HEX-4*HEX-12*HEX
01697     static Regexp s_guidRegexp;
01698     // Paths
01699     static String s_skinPath;
01700     static String s_soundPath;
01701     // Ring name for incoming channels
01702     static String s_ringInName;
01703     // Ring name for outgoing channels
01704     static String s_ringOutName;
01705     // Status widget's name
01706     static String s_statusWidget;
01707     // Widget displaying the debug text
01708     static String s_debugWidget;
01709     // The list of cient's toggles
01710     static String s_toggles[OptCount];
01711     // Maximum remote users allowed to enter in conference
01712     static int s_maxConfPeers;
01713     // Engine started flag
01714     static bool s_engineStarted;
01715 
01716 protected:
01722     virtual ClientLogic* createDefaultLogic();
01723     virtual bool createWindow(const String& name,
01724         const String& alias = String::empty()) = 0;
01725     virtual void loadWindows(const char* file = 0) = 0;
01726     virtual void initWindows();
01727     virtual void initClient();
01728     virtual void exitClient()
01729         {}
01730     virtual bool isUIThread()
01731         { return Thread::current() == m_clientThread; }
01732     inline bool needProxy() const
01733         { return m_oneThread && !(Client::self() && Client::self()->isUIThread()); }
01734     bool driverLockLoop();
01735     static bool driverLock(long maxwait = 0);
01736     static void driverUnlock();
01737 
01738     static bool s_exiting;               // Exiting flag
01739 
01740     ObjList m_windows;
01741     bool m_initialized;
01742     int m_line;
01743     bool m_oneThread;
01744     bool m_toggles[OptCount];
01745     ObjList m_relays;                    // Message relays installed by this receiver
01746     ClientLogic* m_defaultLogic;         // The default logic
01747     static Client* s_client;
01748     static int s_changing;
01749     static ObjList s_logics;
01750     static bool s_idleLogicsTick;        // Call logics' timerTick()
01751     Thread* m_clientThread;
01752 };
01753 
01758 class YATE_API ClientChannel : public Channel
01759 {
01760     friend class ClientDriver;
01761     YNOCOPY(ClientChannel); // no automatic copies please
01762 public:
01766     enum Notification {
01767         Startup,
01768         Destroyed,
01769         Active,
01770         OnHold,
01771         Mute,
01772         Noticed,
01773         AddrChanged,
01774         Routed,
01775         Accepted,
01776         Rejected,
01777         Progressing,
01778         Ringing,
01779         Answered,
01780         Transfer,
01781         Conference,
01782         AudioSet,
01783         Unknown
01784     };
01785 
01789     enum SlaveType {
01790         SlaveNone = 0,
01791         SlaveTransfer,
01792         SlaveConference,
01793     };
01794 
01800     ClientChannel(const Message& msg, const String& peerid);
01801 
01809     ClientChannel(const String& target, const NamedList& params, int st = SlaveNone,
01810         const String& masterChan = String::empty());
01811 
01816     explicit ClientChannel(const String& soundId);
01817 
01818     virtual ~ClientChannel();
01819 
01826     bool start(const String& target, const NamedList& params);
01827 
01828     virtual bool msgProgress(Message& msg);
01829     virtual bool msgRinging(Message& msg);
01830     virtual bool msgAnswered(Message& msg);
01831     virtual bool msgDrop(Message& msg, const char* reason);
01832     virtual bool callRouted(Message& msg);
01833     virtual void callAccept(Message& msg);
01834     virtual void callRejected(const char* error, const char* reason, const Message* msg);
01835 
01840     void callAnswer(bool setActive = true);
01841 
01846     inline int slave() const
01847         { return m_slave; }
01848 
01854     inline ObjList& slaves()
01855         { return m_slaves; }
01856 
01861     inline unsigned int slavesCount() const {
01862             Lock lock(m_mutex);
01863             return m_slaves.count();
01864         }
01865 
01870     inline void addSlave(const String& sid) {
01871             Lock lock(m_mutex);
01872             if (!m_slaves.find(sid))
01873                 m_slaves.append(new String(sid));
01874         }
01875 
01880     inline void removeSlave(const String& sid) {
01881             Lock lock(m_mutex);
01882             m_slaves.remove(sid);
01883         }
01884 
01889     inline const String& master() const
01890         { return m_master; }
01891 
01896     inline const NamedList& clientParams() const
01897         { return m_clientParams; }
01898 
01903     inline const String& party() const
01904         { return m_party; }
01905 
01910     inline const String& partyName() const
01911         { return m_partyName ? m_partyName : m_party; }
01912 
01917     inline bool conference() const
01918         { return m_conference; }
01919 
01924     inline const String& transferId() const
01925         { return m_transferId; }
01926 
01931     inline RefObject* clientData() const
01932         { return m_clientData; }
01933 
01939     inline void setClientData(RefObject* obj = 0) {
01940             TelEngine::destruct(m_clientData);
01941             if (obj && obj->ref())
01942                 m_clientData = obj;
01943         }
01944 
01951     bool setMedia(bool open = false, bool replace = false);
01952 
01959     bool setActive(bool active, bool update = true);
01960 
01967     bool setMuted(bool on, bool update = true);
01968 
01974     void setTransfer(const String& target = String::empty());
01975 
01981     void setConference(const String& target = String::empty());
01982 
01987     inline const String& peerOutFormat() const
01988         { return m_peerOutFormat; }
01989 
01994     inline const String& peerInFormat() const
01995         { return m_peerInFormat; }
01996 
02001     inline bool active() const
02002         { return m_active; }
02003 
02008     inline bool muted() const
02009         { return m_muted; }
02010 
02015     inline bool isNoticed() const
02016         { return m_noticed; }
02017 
02021     void noticed();
02022 
02027     inline int line() const
02028         { return m_line; }
02029 
02034     void line(int newLine);
02035 
02046     void update(int notif, bool chan = true,
02047         bool updatePeer = true, const char* engineMsg = 0,
02048         bool minimal = false, bool data = false);
02049 
02054     inline void getReconnPeer(String& buf) {
02055             Lock lck(m_mutex);
02056             buf = m_peerId;
02057         }
02062     inline bool hasReconnPeer()
02063         { return 0 != getReconnPeer(false); }
02064 
02070     CallEndpoint* getReconnPeer(bool ref = true);
02071 
02075     void dropReconnPeer(const char* reason = 0);
02076 
02083     static int lookup(const char* notif, int def = Unknown)
02084         { return TelEngine::lookup(notif,s_notification,def); }
02085 
02092     static const char* lookup(int notif, const char* def = 0)
02093         { return TelEngine::lookup(notif,s_notification,def); }
02094 
02101     static int lookupSlaveType(const char* notif, int def = SlaveNone)
02102         { return TelEngine::lookup(notif,s_slaveTypes,def); }
02103 
02107     static const TokenDict s_notification[];
02108 
02112     static const TokenDict s_slaveTypes[];
02113 
02114 protected:
02115     virtual void destroyed();
02116     virtual void connected(const char* reason);
02117     virtual void disconnected(bool final, const char* reason);
02118     // Check for a source in channel's peer or a received message's user data
02119     inline bool peerHasSource(Message& msg) {
02120             CallEndpoint* ch = getPeer();
02121             if (!ch)
02122                 ch = static_cast<CallEndpoint*>(msg.userObject(YSTRING("CallEndpoint")));
02123             return ch && ch->getSource();
02124         }
02125     // Check if our consumer's source sent any data
02126     // Don't set the silence flag is already reset
02127     void checkSilence();
02128 
02129     int m_slave;                         // Slave type
02130     String m_master;                     // Master channel id
02131     String m_party;                      // Remote party
02132     String m_partyName;                  // Remote party name
02133     String m_peerOutFormat;              // Peer consumer's data format
02134     String m_peerInFormat;               // Peer source's data format
02135     String m_reason;                     // Termination reason
02136     String m_peerId;                     // Peer's id (used to re-connect)
02137     bool m_noticed;                      // Incoming channel noticed flag
02138     int m_line;                          // Channel's line (address)
02139     bool m_active;                       // Channel active flag
02140     bool m_silence;                      // True if the peer did't sent us any audio data
02141     bool m_conference;                   // True if this channel is in conference
02142     bool m_muted;                        // True if this channel is muted (no data source))
02143     String m_transferId;                 // Transferred id or empty if not transferred
02144     RefObject* m_clientData;             // Obscure data used by client logics
02145     bool m_utility;                      // Regular client channel flag
02146     String m_soundId;                    // The id of the sound to play
02147     ObjList m_slaves;                    // Data managed by the default logic
02148     NamedList m_clientParams;            // Channel client parameters
02149 };
02150 
02155 class YATE_API ClientDriver : public Driver
02156 {
02157     friend class ClientChannel;          // Reset active channel's id
02158     YNOCOPY(ClientDriver);               // No automatic copies please
02159 public:
02160     ClientDriver();
02161     virtual ~ClientDriver();
02162     virtual void initialize() = 0;
02163     virtual bool msgExecute(Message& msg, String& dest);
02164     virtual void msgTimer(Message& msg);
02165     virtual bool msgRoute(Message& msg);
02166     virtual bool received(Message& msg, int id);
02167 
02172     inline const String& activeId() const
02173         { return m_activeId; }
02174 
02183     bool setActive(const String& id = String::empty());
02184 
02190     ClientChannel* findLine(int line);
02191 
02196     inline static ClientDriver* self()
02197         { return s_driver; }
02198 
02203     inline static const String& device()
02204         { return s_device; }
02205 
02210     static void dropCalls(const char* reason = 0);
02211 
02218     static bool setAudioTransfer(const String& id, const String& target = String::empty());
02219 
02229     static bool setConference(const String& id, bool in, const String* confName = 0,
02230         bool buildFromChan = false);
02231 
02237     static ClientChannel* findChan(const String& id);
02238 
02244     static ClientChannel* findChanByPeer(const String& peer);
02245 
02250     static inline ClientChannel* findActiveChan()
02251         { return self() ? findChan(self()->activeId()) : 0; }
02252 
02259     static void dropChan(const String& chan, const char* reason = 0, bool peer = false);
02260 
02264     static String s_confName;
02265 
02270     static bool s_dropConfPeer;
02271 
02272 protected:
02273     void setup();
02274     static ClientDriver* s_driver;
02275     static String s_device;
02276     String m_activeId;                   // The active channel's id
02277 };
02278 
02285 class YATE_API ClientLogic : public GenObject
02286 {
02287     friend class Client;
02288     YNOCOPY(ClientLogic); // no automatic copies please
02289 public:
02293     virtual ~ClientLogic();
02294 
02299     inline const String& name() const
02300         { return m_name; }
02301 
02306     inline int priority() const
02307         { return m_prio; }
02308 
02313     virtual const String& toString() const;
02314 
02320     bool setParams(const NamedList& params);
02321 
02329     virtual bool action(Window* wnd, const String& name, NamedList* params = 0)
02330         { return false; }
02331 
02339     virtual bool toggle(Window* wnd, const String& name, bool active)
02340         { return false; }
02341 
02350     virtual bool select(Window* wnd, const String& name, const String& item,
02351         const String& text = String::empty())
02352         { return false; }
02353 
02362     virtual bool setClientParam(const String& param, const String& value,
02363         bool save, bool update)
02364         { return false; }
02365 
02370     virtual bool imIncoming(Message& msg)
02371         { return false; }
02372 
02380     virtual bool callIncoming(Message& msg, const String& dest)
02381         { return false; }
02382 
02389     virtual bool validateCall(NamedList& params, Window* wnd = 0)
02390         { return true; }
02391 
02400     virtual bool callStart(NamedList& params, Window* wnd = 0,
02401         const String& cmd = String::empty())
02402         { return false; }
02403 
02410     virtual bool line(const String& name, Window* wnd = 0);
02411 
02419     virtual bool display(NamedList& params, bool widget, Window* wnd = 0);
02420 
02427     virtual bool backspace(const String& name, Window* wnd = 0);
02428 
02435     virtual bool command(const String& name, Window* wnd = 0);
02436 
02447     virtual bool debug(const String& name, bool active, Window* wnd = 0);
02448 
02456     virtual bool editAccount(bool newAcc, NamedList* params, Window* wnd = 0)
02457         { return false; }
02458 
02465     virtual bool acceptAccount(NamedList* params, Window* wnd = 0)
02466         { return false; }
02467 
02474     virtual bool delAccount(const String& account, Window* wnd = 0)
02475         { return false; }
02476 
02484     virtual bool updateAccount(const NamedList& account, bool login, bool save)
02485         { return false; }
02486 
02493     virtual bool loginAccount(const NamedList& account, bool login)
02494         { return false; }
02495 
02504     virtual bool updateContact(const NamedList& contact, bool save, bool update)
02505         { return false; }
02506 
02513     virtual bool acceptContact(NamedList* params, Window* wnd = 0)
02514         { return false; }
02515 
02523     virtual bool editContact(bool newCont, NamedList* params = 0, Window* wnd = 0)
02524         { return false; }
02525 
02532     virtual bool delContact(const String& contact, Window* wnd = 0)
02533         { return false; }
02534 
02541     virtual bool callContact(NamedList* params = 0, Window* wnd = 0)
02542         { return false; }
02543 
02551     virtual bool updateProviders(const NamedList& provider, bool save, bool update)
02552         { return false; }
02553 
02561     virtual bool callLogUpdate(const NamedList& params, bool save, bool update)
02562         { return false; }
02563 
02569     virtual bool callLogDelete(const String& billid)
02570         { return false; }
02571 
02580     virtual bool callLogClear(const String& table, const String& direction)
02581         { return false; }
02582 
02589     virtual bool callLogCall(const String& billid, Window* wnd = 0)
02590         { return false; }
02591 
02597     virtual bool callLogCreateContact(const String& billid)
02598         { return false; }
02599 
02606     virtual bool help(const String& action, Window* wnd)
02607         { return false; }
02608 
02613     virtual bool calltoLoaded()
02614         { return false; }
02615 
02619     virtual void loadedWindows()
02620         {}
02621 
02625     virtual void initializedWindows()
02626         {}
02627 
02634     virtual bool initializedClient()
02635         { return false; }
02636 
02641     virtual void exitingClient()
02642         {}
02643 
02650     virtual bool handleUiAction(Message& msg, bool& stopLogic)
02651         { return false; }
02652 
02659     virtual bool handleCallCdr(Message& msg, bool& stopLogic)
02660         { return false; }
02661 
02668     virtual bool handleUserLogin(Message& msg, bool& stopLogic)
02669         { return false; }
02670 
02677     virtual bool handleUserNotify(Message& msg, bool& stopLogic)
02678         { return false; }
02679 
02686     virtual bool handleUserRoster(Message& msg, bool& stopLogic)
02687         { return false; }
02688 
02695     virtual bool handleResourceNotify(Message& msg, bool& stopLogic)
02696         { return false; }
02697 
02704     virtual bool handleResourceSubscribe(Message& msg, bool& stopLogic)
02705         { return false; }
02706 
02713     virtual bool handleClientChanUpdate(Message& msg, bool& stopLogic)
02714         { return false; }
02715 
02722     virtual bool handleContactInfo(Message& msg, bool& stopLogic)
02723         { return false; }
02724 
02734     virtual bool defaultMsgHandler(Message& msg, int id, bool& stopLogic)
02735         { return false; }
02736 
02741     virtual void engineStart(Message& msg)
02742         {}
02743 
02750     virtual bool addDurationUpdate(DurationUpdate* duration, bool autoDelete = false);
02751 
02758     virtual bool removeDurationUpdate(const String& name, bool delObj = false);
02759 
02766     virtual bool removeDurationUpdate(DurationUpdate* duration, bool delObj = false);
02767 
02774     virtual DurationUpdate* findDurationUpdate(const String& name, bool ref = true);
02775 
02779     virtual void clearDurationUpdate();
02780 
02784     virtual void destruct();
02785 
02792     static const String& cdrRemoteParty(const NamedList& params, bool outgoing)
02793         { return outgoing ? params[YSTRING("called")] : params[YSTRING("caller")]; }
02794 
02800     static const String& cdrRemoteParty(const NamedList& params) {
02801             const String& dir = params[YSTRING("direction")];
02802             if (dir == YSTRING("incoming"))
02803                 return cdrRemoteParty(params,true);
02804             if (dir == YSTRING("outgoing"))
02805                 return cdrRemoteParty(params,false);
02806             return String::empty();
02807         }
02808 
02813     static void initStaticData();
02814 
02822     static bool saveContact(Configuration& cfg, ClientContact* c, bool save = true);
02823 
02831     static bool clearContact(Configuration& cfg, ClientContact* c, bool save = true);
02832 
02833     // Account options string list
02834     static ObjList s_accOptions;
02835     // Parameters that are applied from provider template
02836     static const char* s_provParams[];
02837     // The list of protocols supported by the client
02838     static ObjList s_protocols;
02839     // Mutext used to lock protocol list
02840     static Mutex s_protocolsMutex;
02841 
02842 protected:
02848     ClientLogic(const char* name, int priority);
02849 
02855     virtual void idleTimerTick(Time& time)
02856         {}
02857 
02858     ObjList m_durationUpdate;            // Duration updates
02859     Mutex m_durationMutex;               // Lock duration operations
02860 
02861 private:
02862     ClientLogic() {}                     // No default constructor
02863 
02864     String m_name;                       // Logic's name
02865     int m_prio;                          // Logics priority
02866 };
02867 
02868 
02873 class YATE_API DefaultLogic : public ClientLogic
02874 {
02875     YNOCOPY(DefaultLogic); // no automatic copies please
02876 public:
02882     explicit DefaultLogic(const char* name = "default", int prio = -100);
02883 
02887     ~DefaultLogic();
02888 
02896     virtual bool action(Window* wnd, const String& name, NamedList* params = 0);
02897 
02905     virtual bool toggle(Window* wnd, const String& name, bool active);
02906 
02915     virtual bool select(Window* wnd, const String& name, const String& item,
02916         const String& text = String::empty());
02917 
02926     virtual bool setClientParam(const String& param, const String& value,
02927         bool save, bool update);
02928 
02933     virtual bool imIncoming(Message& msg);
02934 
02942     virtual bool callIncoming(Message& msg, const String& dest);
02943 
02950     virtual bool validateCall(NamedList& params, Window* wnd = 0);
02951 
02960     virtual bool callStart(NamedList& params, Window* wnd = 0,
02961         const String& cmd = String::empty());
02962 
02970     virtual bool digitPressed(NamedList& params, Window* wnd = 0);
02971 
02979     virtual bool editAccount(bool newAcc, NamedList* params, Window* wnd = 0);
02980 
02987     virtual bool acceptAccount(NamedList* params, Window* wnd = 0);
02988 
02995     virtual bool delAccount(const String& account, Window* wnd = 0);
02996 
03004     virtual bool updateAccount(const NamedList& account, bool login, bool save);
03005 
03012     virtual bool loginAccount(const NamedList& account, bool login);
03013 
03022     virtual bool updateContact(const NamedList& contact, bool save, bool update);
03023 
03030     virtual bool acceptContact(NamedList* params, Window* wnd = 0);
03031 
03039     virtual bool editContact(bool newCont, NamedList* params = 0, Window* wnd = 0);
03040 
03047     virtual bool delContact(const String& contact, Window* wnd = 0);
03048 
03055     virtual bool callContact(NamedList* params = 0, Window* wnd = 0);
03056 
03064     virtual bool updateProviders(const NamedList& provider, bool save, bool update);
03065 
03073     virtual bool callLogUpdate(const NamedList& params, bool save, bool update);
03074 
03080     virtual bool callLogDelete(const String& billid);
03081 
03090     virtual bool callLogClear(const String& table, const String& direction);
03091 
03098     virtual bool callLogCall(const String& billid, Window* wnd = 0);
03099 
03105     virtual bool callLogCreateContact(const String& billid);
03106 
03113     virtual bool help(const String& action, Window* wnd);
03114 
03119     virtual bool calltoLoaded();
03120 
03124     virtual void loadedWindows()
03125         {}
03126 
03130     virtual void initializedWindows();
03131 
03138     virtual bool initializedClient();
03139 
03144     virtual void exitingClient();
03145 
03152     virtual bool handleUiAction(Message& msg, bool& stopLogic);
03153 
03160     virtual bool handleCallCdr(Message& msg, bool& stopLogic);
03161 
03168     virtual bool handleUserLogin(Message& msg, bool& stopLogic);
03169 
03176     virtual bool handleUserNotify(Message& msg, bool& stopLogic);
03177 
03184     virtual bool handleUserRoster(Message& msg, bool& stopLogic);
03185 
03192     virtual bool handleResourceNotify(Message& msg, bool& stopLogic);
03193 
03200     virtual bool handleResourceSubscribe(Message& msg, bool& stopLogic);
03201 
03208     virtual bool handleClientChanUpdate(Message& msg, bool& stopLogic);
03209 
03216     virtual bool handleContactInfo(Message& msg, bool& stopLogic);
03217 
03227     virtual bool defaultMsgHandler(Message& msg, int id, bool& stopLogic);
03228 
03234     virtual void updateSelectedChannel(const String* item = 0);
03235 
03240     virtual void engineStart(Message& msg);
03241 
03250     static inline String& buildAccountId(String& accId, const String& proto,
03251         const String& user, const String& host) {
03252             accId = proto + ":" + user + "@" + host;
03253             return accId;
03254         }
03255 
03256 protected:
03262     virtual void idleTimerTick(Time& time);
03263 
03269     virtual bool enableCallActions(const String& id);
03270 
03277     virtual bool fillCallStart(NamedList& p, Window* wnd = 0);
03278 
03284     virtual void channelSelectionChanged(const String& old);
03285 
03293     virtual void fillContactEditActive(NamedList& list, bool active, const String* item = 0,
03294         bool del = true);
03295 
03302     virtual void fillLogContactActive(NamedList& list, bool active, const String* item = 0);
03303 
03311     virtual bool clearList(const String& action, Window* wnd);
03312 
03321     virtual bool deleteItem(const String& list, const String& item, Window* wnd,
03322         bool confirm);
03323 
03332     virtual bool deleteCheckedItems(const String& list, Window* wnd, bool confirm);
03333 
03343     virtual bool deleteSelectedItem(const String& action, Window* wnd, bool checked = false);
03344 
03351     virtual bool handleTextChanged(NamedList* params, Window* wnd);
03352 
03360     virtual bool handleFileTransferAction(const String& name, Window* wnd, NamedList* params = 0);
03361 
03369     virtual bool handleFileTransferNotify(Message& msg, bool& stopLogic);
03370 
03377     virtual bool handleUserData(Message& msg, bool& stopLogic);
03378 
03386     virtual void notifyGenericError(const String& text,
03387         const String& account = String::empty(),
03388         const String& contact = String::empty(),
03389         const char* title = "Error");
03390 
03398     virtual void notifyNoAudio(bool show, bool micOk = false, bool speakerOk = false,
03399         ClientChannel* chan = 0);
03400 
03407     virtual void updateChatRoomsContactList(bool load, ClientAccount* acc,
03408         MucRoom* room = 0);
03409 
03415     virtual void joinRoom(MucRoom* room, bool force = false);
03416 
03417     String m_selectedChannel;            // The currently selected channel
03418     String m_transferInitiated;          // Tranfer initiated id
03419 
03420 private:
03421     // Add/set an account changed in UI
03422     // replace: Optional editing account to replace
03423     bool updateAccount(const NamedList& account, bool save,
03424         const String& replace = String::empty(), bool loaded = false);
03425     // Add/edit an account
03426     bool internalEditAccount(bool newAcc, const String* account, NamedList* params, Window* wnd);
03427     // Handle dialog actions. Return true if handled
03428     bool handleDialogAction(const String& name, bool& retVal, Window* wnd);
03429     // Handle chat and contact related actions. Return true if handled
03430     bool handleChatContactAction(const String& name, Window* wnd);
03431     // Handle chat contact edit ok button press. Return true if handled
03432     bool handleChatContactEditOk(const String& name, Window* wnd);
03433     // Handle chat room contact edit ok button press. Return true if handled
03434     bool handleChatRoomEditOk(const String& name, Window* wnd);
03435     // Handle actions from MUCS window. Return true if handled
03436     bool handleMucsAction(const String& name, Window* wnd, NamedList* params);
03437     // Handle ok button in muc invite window. Return true if handled
03438     bool handleMucInviteOk(Window* wnd);
03439     // Handle select from MUCS window. Return true if handled
03440     bool handleMucsSelect(const String& name, const String& item, Window* wnd,
03441         const String& text = String::empty());
03442     // Handle resource.notify messages from MUC rooms
03443     // The account was already checked
03444     bool handleMucResNotify(Message& msg, ClientAccount* acc, const String& contact,
03445         const String& instance, const String& operation);
03446     // Show/hide the notification area (messages).
03447     // Update rows if requested. Add/remove tray notification/info icon
03448     bool showNotificationArea(bool show, Window* wnd, NamedList* upd = 0,
03449         const char* notif = "notification");
03450     // Show a roster change or failure notification
03451     void showUserRosterNotification(ClientAccount* a, const String& oper,
03452         Message& msg, const String& contactUri = String::empty(),
03453         bool newContact = true);
03454     // Handle actions from notification area. Return true if handled
03455     bool handleNotificationAreaAction(const String& action, Window* wnd);
03456     // Save a contact to config. Save chat rooms if the contact is a chat room
03457     bool storeContact(ClientContact* c);
03458     // Handle ok from account password/credentials input window
03459     bool handleAccCredInput(Window* wnd, const String& name, bool inputPwd);
03460     // Handle channel show/hide transfer/conference toggles
03461     bool handleChanShowExtra(Window* wnd, bool show, const String& chan, bool conf);
03462     // Handle conf/transfer start actions in channel item
03463     bool handleChanItemConfTransfer(bool conf, const String& name, Window* wnd);
03464 
03465     ClientAccountList* m_accounts;       // Accounts list (always valid)
03466 };
03467 
03468 
03473 class YATE_API ClientAccount : public RefObject, public Mutex
03474 {
03475     friend class ClientContact;
03476     friend class MucRoom;
03477     YNOCOPY(ClientAccount); // no automatic copies please
03478 public:
03487     explicit ClientAccount(const char* proto, const char* user, const char* host,
03488         bool startup, ClientContact* contact = 0);
03489 
03496     explicit ClientAccount(const NamedList& params, ClientContact* contact = 0);
03497 
03502     inline const NamedList& params() const
03503         { return m_params; }
03504 
03509     inline ObjList& contacts()
03510         { return m_contacts; }
03511 
03516     inline ObjList& mucs()
03517         { return m_mucs; }
03518 
03523     inline ClientContact* contact() const
03524         { return m_contact; }
03525 
03530     void setContact(ClientContact* contact);
03531 
03536     inline const String& protocol() const
03537         { return m_params[YSTRING("protocol")]; }
03538 
03543     inline bool hasChat() const
03544         { return protocol() == YSTRING("jabber"); }
03545 
03550     inline bool hasPresence() const
03551         { return protocol() == YSTRING("jabber"); }
03552 
03557     inline bool startup() const
03558         { return m_params.getBoolValue(YSTRING("enabled"),true); }
03559 
03564     inline void startup(bool ok)
03565         { m_params.setParam("enabled",String::boolText(ok)); }
03566 
03571     virtual const String& toString() const
03572         { return m_params; }
03573 
03578     ClientResource* resource(bool ref);
03579 
03584     inline ClientResource& resource() const
03585         { return *m_resource; }
03586 
03591     void setResource(ClientResource* res);
03592 
03600     bool save(bool ok = true, bool savePwd = true);
03601 
03608     virtual ClientContact* findContact(const String& id, bool ref = false);
03609 
03618     virtual ClientContact* findContact(const String* name = 0, const String* uri = 0,
03619         const String* skipId = 0, bool ref = false);
03620 
03628     virtual ClientContact* findContact(const String& id, const String& resid,
03629         bool ref = false);
03630 
03637     virtual ClientContact* findContactByUri(const String& uri, bool ref = false);
03638 
03645     virtual MucRoom* findRoom(const String& id, bool ref = false);
03646 
03653     virtual MucRoom* findRoomByUri(const String& uri, bool ref = false);
03654 
03661     virtual ClientContact* findAnyContact(const String& id, bool ref = false);
03662 
03670     virtual ClientContact* appendContact(const String& id, const char* name,
03671         const char* uri = 0);
03672 
03678     virtual ClientContact* appendContact(const NamedList& params);
03679 
03686     virtual ClientContact* removeContact(const String& id, bool delObj = true);
03687 
03693     virtual void clearRooms(bool saved, bool temp);
03694 
03701     virtual Message* userlogin(bool login, const char* msg = "user.login");
03702 
03711     virtual Message* userData(bool update, const String& data,
03712         const char* msg = "user.data");
03713 
03718     virtual void fillItemParams(NamedList& list);
03719 
03724     inline const String& dataDir() const
03725         { return m_params[YSTRING("datadirectory")]; }
03726 
03734     virtual bool setupDataDir(String* errStr = 0, bool saveAcc = true);
03735 
03743     virtual bool loadDataDirCfg(Configuration* cfg = 0,
03744         const char* file = "account.conf");
03745 
03751     virtual void loadContacts(Configuration* cfg = 0);
03752 
03758     virtual bool clearDataDir(String* errStr = 0);
03759 
03760     NamedList m_params;                  // Account parameters
03761     Configuration m_cfg;                 // Account conf file
03762 
03763 protected:
03764     // Remove from owner. Release data
03765     virtual void destroyed();
03766     // Method used by the contact to append itself to this account's list
03767     virtual void appendContact(ClientContact* contact, bool muc = false);
03768 
03769     ObjList m_contacts;                  // Account's contacts
03770     ObjList m_mucs;                      // Account's MUC contacts
03771 
03772 private:
03773     ClientResource* m_resource;          // Account's resource
03774     ClientContact* m_contact;            // Account's contact data
03775 };
03776 
03781 class YATE_API ClientAccountList : public String, public Mutex
03782 {
03783     YNOCOPY(ClientAccountList); // no automatic copies please
03784 public:
03790     inline explicit ClientAccountList(const char* name, ClientAccount* localContacts = 0)
03791         : String(name), Mutex(true,"ClientAccountList"),
03792           m_localContacts(localContacts)
03793         { }
03794 
03798     ~ClientAccountList();
03799 
03804     inline ObjList& accounts()
03805         { return m_accounts; }
03806 
03811     inline ClientAccount* localContacts() const
03812         { return m_localContacts; }
03813 
03819     bool isLocalContact(ClientContact* c) const;
03820 
03826     inline bool isLocalContact(const String& id) const
03827         { return m_localContacts && m_localContacts->findContact(id); }
03828 
03835     virtual ClientAccount* findAccount(const String& id, bool ref = false);
03836 
03844     virtual ClientContact* findContactByUri(const String& account, const String& uri,
03845         bool ref = false);
03846 
03854     virtual ClientContact* findContact(const String& account, const String& id, bool ref = false);
03855 
03862     virtual ClientContact* findContact(const String& builtId, bool ref = false);
03863 
03871     virtual ClientContact* findContactByInstance(const String& id, String* instance = 0,
03872         bool ref = false);
03873 
03880     virtual MucRoom* findRoom(const String& id, bool ref = false);
03881 
03888     virtual MucRoom* findRoomByMember(const String& id, bool ref = false);
03889 
03896     virtual ClientContact* findAnyContact(const String& id, bool ref = false);
03897 
03904     virtual ClientAccount* findSingleRegAccount(const String* skipProto = 0,
03905         bool ref = false);
03906 
03912     virtual bool appendAccount(ClientAccount* account);
03913 
03918     virtual void removeAccount(const String& id);
03919 
03920 protected:
03921     ObjList m_accounts;
03922 
03923 private:
03924     ClientAccountList() {}               // Avoid using the default constructor
03925     ClientAccount* m_localContacts;      // Account owning locally stored contacts
03926 };
03927 
03933 class YATE_API ClientContact : public RefObject
03934 {
03935     friend class ClientAccount;
03936     YNOCOPY(ClientContact); // no automatic copies please
03937 public:
03945     explicit ClientContact(ClientAccount* owner, const char* id, const char* name = 0,
03946         const char* uri = 0);
03947 
03956     explicit ClientContact(ClientAccount* owner, const NamedList& params, const char* id = 0,
03957         const char* uri = 0);
03958 
03963     inline ClientAccount* account()
03964         { return m_owner; }
03965 
03970     inline const String& accountName() const
03971         { return m_owner ? m_owner->toString() : String::empty(); }
03972 
03977     inline const URI& uri() const
03978         { return m_uri; }
03979 
03984     inline void setUri(const char* u)
03985         { m_uri = u; }
03986 
03991     inline ObjList& resources()
03992         { return m_resources; }
03993 
03998     inline bool online() const
03999         { return m_online || 0 != m_resources.skipNull(); }
04000 
04005     inline void setOnline(bool on)
04006         { m_online = on; }
04007 
04012     inline ObjList& groups()
04013         { return m_groups; }
04014 
04020     inline bool local(bool defVal = false) const
04021         { return m_params.getBoolValue(YSTRING("local"),defVal); }
04022 
04027     inline void setLocal(bool on)
04028         { m_params.setParam("local",String::boolText(on)); }
04029 
04035     inline bool remote(bool defVal = false) const
04036         { return m_params.getBoolValue(YSTRING("remote"),defVal); }
04037 
04042     inline void setRemote(bool on)
04043         { m_params.setParam("remote",String::boolText(on)); }
04044 
04049     inline void setDockedChat(bool on) {
04050             if (!mucRoom())
04051                 m_dockedChat = on;
04052         }
04053 
04058     inline void getContactSection(String& buf) {
04059             String pref;
04060             buf = toString();
04061             buf.startSkip(buildContactId(pref,accountName(),String::empty()),false);
04062             buf = buf.uriUnescape();
04063         }
04064 
04069     virtual const String& toString() const
04070         { return m_id; }
04071 
04076     virtual MucRoom* mucRoom()
04077         { return 0; }
04078 
04085     inline String& buildInstanceId(String& dest, const String& inst = String::empty()) {
04086             dest << m_id << "|" << inst.uriEscape('|');
04087             return dest;
04088         }
04089 
04095     inline void buildIdHash(String& buf, const String& prefix = String::empty()) {
04096             MD5 md5(m_id);
04097             buf = prefix + md5.hexDigest();
04098         }
04099 
04105     inline bool isChatWnd(Window* wnd)
04106         { return wnd && wnd->toString() == m_chatWndName; }
04107 
04112     bool hasChat();
04113 
04118     virtual void flashChat(bool on = true);
04119 
04128     virtual bool sendChat(const char* body, const String& res = String::empty(),
04129         const String& type = String::empty(), const char* state = "active");
04130 
04136     virtual void getChatInput(String& text, const String& name = "message");
04137 
04143     virtual void setChatInput(const String& text = String::empty(),
04144         const String& name = "message");
04145 
04152     virtual void getChatHistory(String& text, bool richText = false,
04153         const String& name = "history");
04154 
04161     virtual void setChatHistory(const String& text, bool richText = false,
04162         const String& name = "history");
04163 
04170     virtual void addChatHistory(const String& what, NamedList*& params,
04171         const String& name = "history");
04172 
04179     virtual void getChatProperty(const String& name, const String& prop, String& value);
04180 
04187     virtual void setChatProperty(const String& name, const String& prop, const String& value);
04188 
04193     inline bool isChatVisible()
04194         { return Client::self() && Client::self()->getVisible(m_chatWndName); }
04195 
04202     virtual bool showChat(bool visible, bool active = false);
04203 
04208     Window* getChatWnd();
04209 
04215     virtual void createChatWindow(bool force = false, const char* name = 0);
04216 
04223     virtual void updateChatWindow(const NamedList& params, const char* title = 0,
04224         const char* icon = 0);
04225 
04230     virtual bool isChatActive();
04231 
04235     void destroyChatWindow();
04236 
04242     virtual String* findGroup(const String& group);
04243 
04249     virtual bool appendGroup(const String& group);
04250 
04256     virtual bool removeGroup(const String& group);
04257 
04264     virtual bool setGroups(const NamedList& list, const String& param);
04265 
04271     virtual ClientResource* status(bool ref = false);
04272 
04279     virtual ClientResource* findResource(const String& id, bool ref = false);
04280 
04286     virtual ClientResource* findAudioResource(bool ref = false);
04287 
04293     virtual ClientResource* findFileTransferResource(bool ref = false);
04294 
04300     virtual ClientResource* appendResource(const String& id);
04301 
04308     virtual bool insertResource(ClientResource* res);
04309 
04315     virtual bool removeResource(const String& id);
04316 
04324     static inline String& buildContactId(String& dest, const String& account,
04325         const String& contact) {
04326             dest << account.uriEscape('|') << "|" << String::uriEscape(contact,'|').toLower();
04327             return dest;
04328         }
04329 
04335     static inline void splitContactId(const String& src, String& account) {
04336             int pos = src.find('|');
04337             if (pos >= 0)
04338                 account = src.substr(0,pos).uriUnescape();
04339             else
04340                 account = src.uriUnescape();
04341         }
04342 
04350     static void splitContactInstanceId(const String& src, String& account,
04351         String& contact, String* instance = 0);
04352 
04353     // Chat window prefix
04354     static String s_chatPrefix;
04355     // Docked chat window name
04356     static String s_dockedChatWnd;
04357     // Docked chat widget name
04358     static String s_dockedChatWidget;
04359     // MUC rooms window name
04360     static String s_mucsWnd;
04361     // Chat input widget name
04362     static String s_chatInput;
04363 
04364     String m_name;                       // Contact's display name
04365     String m_subscription;               // Presence subscription state
04366     NamedList m_params;                  // Optional contact extra params
04367 
04368 protected:
04375     explicit ClientContact(ClientAccount* owner, const char* id, bool mucRoom);
04376 
04380     void removeFromOwner();
04381 
04385     virtual void destroyed();
04386 
04387     ClientAccount* m_owner;              // The account owning this contact
04388     bool m_online;                       // Online flag
04389     String m_id;                         // The contact's id
04390     URI m_uri;                           // The contact's URI
04391     ObjList m_resources;                 // The contact's resource list
04392     ObjList m_groups;                    // The group(s) this contact belongs to
04393     bool m_dockedChat;                   // Docked chat flag
04394     String m_chatWndName;                // Chat window name if any
04395 };
04396 
04401 class YATE_API ClientResource : public RefObject
04402 {
04403     YCLASS(ClientResource,RefObject)
04404     YNOCOPY(ClientResource); // no automatic copies please
04405 public:
04409     enum Status {
04410         Unknown = 0,
04411         Offline = 1,
04412         Connecting = 2,
04413         Online = 3,
04414         Busy = 4,
04415         Dnd = 5,
04416         Away = 6,
04417         Xa = 7,
04418     };
04419 
04426     inline explicit ClientResource(const char* id, const char* name = 0, bool audio = true)
04427         : m_id(id), m_name(name ? name : id), m_audio(audio), m_fileTransfer(false),
04428         m_priority(0), m_status(Offline)
04429         { }
04430 
04435     virtual const String& toString() const
04436         { return m_id; }
04437 
04442     inline bool online() const
04443         { return m_status > Connecting; }
04444 
04449     inline bool offline() const
04450         { return m_status == Offline; }
04451 
04456     inline const char* statusName() const
04457         { return lookup(m_status,s_statusName); }
04458 
04463     inline const char* text() const
04464         { return m_text ? m_text.c_str() : statusDisplayText(m_status); }
04465 
04471     inline bool setAudio(bool ok) {
04472             if (m_audio == ok)
04473                 return false;
04474             m_audio = ok;
04475             return true;
04476         }
04477 
04483     inline bool setFileTransfer(bool ok) {
04484             if (m_fileTransfer == ok)
04485                 return false;
04486             m_fileTransfer = ok;
04487             return true;
04488         }
04489 
04495     inline bool setPriority(int prio) {
04496             if (m_priority == prio)
04497                 return false;
04498             m_priority = prio;
04499             return true;
04500         }
04501 
04507     inline bool setStatus(int stat) {
04508             if (m_status == stat)
04509                 return false;
04510             m_status = stat;
04511             return true;
04512         }
04513 
04519     inline bool setStatusText(const String& text = String::empty()) {
04520             if (m_text == text)
04521                 return false;
04522             m_text = text;
04523             return true;
04524         }
04525 
04532     static inline const char* statusDisplayText(int status, const char* defVal = 0)
04533         { return lookup(status,s_statusName,defVal); }
04534 
04538     static const TokenDict s_statusName[];
04539 
04540     String m_id;                         // The resource id
04541     String m_name;                       // Resource display name
04542     bool m_audio;                        // Audio capability flag
04543     bool m_fileTransfer;                 // File transfer capability flag
04544     int m_priority;                      // Resource priority
04545     int m_status;                        // Resource status
04546     String m_text;                       // Resource status text
04547 };
04548 
04554 class YATE_API MucRoomMember : public ClientResource
04555 {
04556     YCLASS(MucRoomMember,ClientResource)
04557     YNOCOPY(MucRoomMember); // no automatic copies please
04558 public:
04562     enum Affiliation {
04563         AffUnknown = 0,
04564         AffNone,
04565         Outcast,
04566         Member,
04567         Admin,
04568         Owner
04569     };
04570 
04574     enum Role {
04575         RoleUnknown = 0,
04576         RoleNone,                        // No role (out of room)
04577         Visitor,                         // Can view room chat
04578         Participant,                     // Can only send chat
04579         Moderator                        // Room moderator: can kick members
04580     };
04581 
04588     inline explicit MucRoomMember(const char* id, const char* nick, const char* uri = 0)
04589         : ClientResource(id,nick),
04590         m_uri(uri), m_affiliation(AffNone), m_role(RoleNone)
04591         {}
04592 
04596     static const TokenDict s_affName[];
04597 
04601     static const TokenDict s_roleName[];
04602 
04603     String m_uri;                        // Member uri, if known
04604     String m_instance;                   // Member instance, if known
04605     int m_affiliation;                   // Member affiliation to the room
04606     int m_role;                          // Member role when present in room ('none' means not present)
04607 };
04608 
04618 class YATE_API MucRoom : public ClientContact
04619 {
04620     YCLASS(MucRoom,ClientContact)
04621     YNOCOPY(MucRoom); // no automatic copies please
04622 public:
04631     explicit MucRoom(ClientAccount* owner, const char* id, const char* name, const char* uri,
04632         const char* nick = 0);
04633 
04638     inline MucRoomMember& resource()
04639         { return *m_resource; }
04640 
04646     inline bool ownMember(MucRoomMember* item) const
04647         { return m_resource == item; }
04648 
04654     inline bool ownMember(const String& item) const
04655         { return m_resource->toString() == item; }
04656 
04661     inline bool available() const {
04662             return m_resource->online() &&
04663                 m_resource->m_role > MucRoomMember::RoleNone;
04664         }
04665 
04670     inline bool canChat() const
04671         { return available() && m_resource->m_role >= MucRoomMember::Visitor; }
04672 
04677     inline bool canChatPrivate() const
04678         { return available(); }
04679 
04684     inline bool canChangeSubject() const
04685         { return available() && m_resource->m_role == MucRoomMember::Moderator; }
04686 
04691     inline bool canInvite() const
04692         { return available(); }
04693 
04699     bool canKick(MucRoomMember* member) const;
04700 
04706     bool canBan(MucRoomMember* member) const;
04707 
04713     inline Message* buildMucRoom(const char* oper) {
04714             Message* m = Client::buildMessage("muc.room",accountName(),oper);
04715             m->addParam("room",uri());
04716             return m;
04717         }
04718 
04726     Message* buildJoin(bool join, bool history = true, unsigned int sNewer = 0);
04727 
04732     virtual MucRoom* mucRoom()
04733         { return this; }
04734 
04740     virtual ClientResource* status(bool ref = false)
04741         { return (!ref || m_resource->ref()) ? m_resource : 0; }
04742 
04748     MucRoomMember* findMember(const String& nick);
04749 
04756     MucRoomMember* findMember(const String& contact, const String& instance);
04757 
04763     MucRoomMember* findMemberById(const String& id);
04764 
04770     bool hasChat(const String& id);
04771 
04777     virtual void flashChat(const String& id, bool on = true);
04778 
04785     virtual void getChatInput(const String& id, String& text, const String& name = "message");
04786 
04793     virtual void setChatInput(const String& id, const String& text = String::empty(),
04794         const String& name = "message");
04795 
04803     virtual void getChatHistory(const String& id, String& text, bool richText = false,
04804         const String& name = "history");
04805 
04813     virtual void setChatHistory(const String& id, const String& text, bool richText = false,
04814         const String& name = "history");
04815 
04823     virtual void addChatHistory(const String& id, const String& what, NamedList*& params,
04824         const String& name = "history");
04825 
04833     virtual void setChatProperty(const String& id, const String& name, const String& prop,
04834         const String& value);
04835 
04843     virtual bool showChat(const String& id, bool visible, bool active = false);
04844 
04851     virtual void createChatWindow(const String& id, bool force = false, const char* name = 0);
04852 
04858     virtual void updateChatWindow(const String& id, const NamedList& params);
04859 
04864     virtual bool isChatActive(const String& id);
04865 
04870     void destroyChatWindow(const String& id = String::empty());
04871 
04878     virtual ClientResource* findResource(const String& id, bool ref = false);
04879 
04885     virtual ClientResource* appendResource(const String& nick);
04886 
04893     virtual bool insertResource(ClientResource* res)
04894         { return false; }
04895 
04902     virtual bool removeResource(const String& nick, bool delChat = false);
04903 
04907     String m_password;
04908 
04909 protected:
04910     // Release data. Destroy all chats
04911     virtual void destroyed();
04912 
04913 private:
04914     unsigned int m_index;                // Index used to build member id
04915     MucRoomMember* m_resource;           // Account room identity and status
04916 };
04917 
04923 class YATE_API DurationUpdate : public RefObject
04924 {
04925     YNOCOPY(DurationUpdate); // no automatic copies please
04926 public:
04935     inline DurationUpdate(ClientLogic* logic, bool owner, const char* id,
04936         const char* name, unsigned int start = Time::secNow())
04937         : m_id(id), m_logic(0), m_name(name),   m_startTime(start)
04938         { setLogic(logic,owner); }
04939 
04943     virtual ~DurationUpdate();
04944 
04949     virtual const String& toString() const;
04950 
04956     void setLogic(ClientLogic* logic = 0, bool owner = true);
04957 
04967     virtual unsigned int update(unsigned int secNow, const String* table = 0,
04968         Window* wnd = 0, Window* skip = 0, bool force = false);
04969 
04977     virtual unsigned int buildTimeParam(NamedList& dest, unsigned int secNow,
04978         bool force = false);
04979 
04987     virtual unsigned int buildTimeString(String& dest, unsigned int secNow,
04988         bool force = false);
04989 
04999     static unsigned int buildTimeParam(NamedList& dest, const char* param, unsigned int secStart,
05000         unsigned int secNow, bool force = false);
05001 
05010     static unsigned int buildTimeString(String& dest, unsigned int secStart, unsigned int secNow,
05011         bool force = false);
05012 
05013 protected:
05017     virtual void destroyed();
05018 
05019     String m_id;                         // Duration's id
05020     ClientLogic* m_logic;                // Client logic having this object in its list
05021     String m_name;                       // Widget/column name
05022     unsigned int m_startTime;            // Start time
05023 };
05024 
05029 class YATE_API ClientSound : public String
05030 {
05031     YNOCOPY(ClientSound); // no automatic copies please
05032 public:
05039     inline ClientSound(const char* name, const char* file, const char* device = 0)
05040         : String(name), m_native(false), m_file(file), m_device(device), m_repeat(0),
05041         m_started(false), m_stereo(false)
05042         { }
05043 
05047     virtual ~ClientSound()
05048         { stop(); }
05049 
05053     virtual void destruct() {
05054             stop();
05055             String::destruct();
05056         }
05057 
05063     inline bool native() const
05064         { return m_native; }
05065 
05070     inline bool started() const
05071         { return m_started; }
05072 
05077     inline const String& device() const
05078         { return m_device; }
05079 
05084     inline void device(const char* dev)
05085         { Lock lock(s_soundsMutex); m_device = dev; }
05086 
05091     inline const String& file() const
05092         { return m_file; }
05093 
05100     inline void file(const char* filename, bool stereo)
05101         { Lock lock(s_soundsMutex); m_file = filename; m_stereo = stereo; }
05102 
05108     inline void setRepeat(unsigned int count)
05109         { m_repeat = count; }
05110 
05115     inline bool stereo() const
05116         { return m_stereo; }
05117 
05123     bool start(bool force = true);
05124 
05128     void stop();
05129 
05135     void setChannel(const String& chan, bool ok);
05136 
05142     bool attachSource(ClientChannel* chan);
05143 
05155     static bool build(const String& id, const char* file, const char* device = 0,
05156         unsigned int repeat = 0, bool resetExisting = true, bool stereo = false);
05157 
05163     static bool started(const String& name);
05164 
05171     static bool start(const String& name, bool force = true);
05172 
05177     static void stop(const String& name);
05178 
05185     static ClientSound* find(const String& token, bool byName = true);
05186 
05190     static ObjList s_sounds;
05191 
05195     static Mutex s_soundsMutex;
05196 
05201     static String s_calltoPrefix;
05202 
05203 protected:
05204     virtual bool doStart();
05205     virtual void doStop();
05206 
05207     bool m_native;                       // Native (system dependent) sound
05208     String m_file;
05209     String m_device;
05210     unsigned int m_repeat;
05211     bool m_started;
05212     bool m_stereo;
05213     String m_channel;                    // Utility channel using this sound
05214 };
05215 
05216 }; // namespace TelEngine
05217 
05218 #endif /* __YATECBASE_H */
05219 
05220 /* vi: set ts=8 sw=4 sts=4 noet: */