# connector.h

    00001 //
    00002 // \file        connector.h
    00003 //              Base class interface for handling Mode connections to device
    00004 //
    00005
    00006 /*
    00007     Copyright (C) 2011, Net Direct Inc. (http://www.netdirect.ca/)
    00008
    00009     This program is free software; you can redistribute it and/or modify
    00010     it under the terms of the GNU General Public License as published by
    00011     the Free Software Foundation; either version 2 of the License, or
    00012     (at your option) any later version.
    00013
    00014     This program is distributed in the hope that it will be useful,
    00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00017
    00018     See the GNU General Public License in the COPYING file at the
    00019     root directory of this project for more details.
    00020 */
    00021
    00022 #ifndef __BARRY_CONNECT_H__
    00023 #define __BARRY_CONNECT_H__
    00024
    00025 #include "dll.h"
    00026 #include "iconv.h"
    00027 #include "pin.h"
    00028 #include "probe.h"
    00029 #include <string>
    00030 #include <memory>
    00031 #include <time.h>
    00032
    00033 namespace Barry {
    00034
    00035 class SocketRoutingQueue;
    00036 class Controller;
    00037 namespace Mode {
    00038         class Desktop;
    00039 }
    00040
    00041 class BXEXPORT Connector
    00042 {
    00043 protected:
    00044         std::string m_password;
    00045         bool m_needs_reconnect;
    00046         Barry::IConverter m_ic;
    00047         Barry::ProbeResult m_probe_result;
    00048         int m_connect_count;
    00049         time_t m_last_disconnect;
    00050
    00051 protected:
    00052         // helper functions
    00053         static Barry::ProbeResult FindDevice(Barry::Pin pin);
    00054
    00055         // required overrides by derived classes
    00056         virtual void StartConnect(const char *password) = 0;
    00057         virtual void RetryPassword(const char *password) = 0;
    00058         virtual void FinishConnect() = 0;
    00059         virtual void DoDisconnect() = 0;
    00060         /// slightly different than IsConnected()... this returns true
    00061         /// even if there is a partial connection in progress...
    00062         /// i.e. this returns true if DoDisconnect() can be safely skipped
    00063         virtual bool IsDisconnected() = 0;
    00064
    00065 public:
    00066         Connector(const char *password, const std::string &locale,
    00067                 Barry::Pin pin = 0);
    00068         Connector(const char *password, const std::string &locale,
    00069                 const Barry::ProbeResult &result);
    00070         virtual ~Connector();
    00071
    00072         IConverter& GetIConverter() { return m_ic; }
    00073         const IConverter& GetIConverter() const { return m_ic; }
    00074         Barry::ProbeResult& GetProbeResult() { return m_probe_result; }
    00075         const Barry::ProbeResult& GetProbeResult() const { return m_probe_result; }
    00076
    00077         virtual void ClearPassword();
    00078         virtual void SetPassword(const char *password);
    00079
    00080         /// Returns true if connected, false if user cancelled, throws
    00081         /// Barry exception on error.
    00082         virtual bool Connect();
    00083
    00084         /// Disconnects from the device
    00085         virtual void Disconnect();
    00086
    00087         /// Returns same as Connect(), but normally remembers the password
    00088         /// and so avoids prompting the user if possible.  Password prompts
    00089         /// are still possible though, if you have called ClearPassword().
    00090         ///
    00091         /// It is valid to call Reconnect() without ever calling Connect(),
    00092         /// since Reconnect() is simply a wrapper that handles retries.
    00093         virtual bool Reconnect(int total_tries = 2);
    00094
    00095         /// Calls Reconnect() (and returns it's result) only if you have
    00096         /// called RequireDirtyReconnect().  Otherwise, does nothing, but
    00097         /// returns true.
    00098         virtual bool ReconnectForDirtyFlags();
    00099
    00100         /// Returns true if connected, false if not
    00101         virtual bool IsConnected() = 0;
    00102
    00103         /// This function flags the Connector object so that a future
    00104         /// call to ReconnectForDirtyFlags() will actually Reconnect().
    00105         /// This is needed in cases where you are updating the device,
    00106         /// and require that the dirty flags on the device itself are
    00107         /// properly cleared and updated.  In this case, you must call
    00108         /// ReconnectForDirtyFlags() before Desktop::GetRecordStateTable().
    00109         /// Disconnecting from the device, or reconnecting, clears the flag.
    00110         virtual void RequireDirtyReconnect();
    00111
    00112         //
    00113         // Callbacks, overridden by the application
    00114         //
    00115
    00116         /// App should prompt user for password, fill password_result with
    00117         /// what he enters and then return true.  Return false if user
    00118         /// wishes to stop trying.
    00119         ///
    00120         /// This function is *not* called from inside a catch() routine,
    00121         /// so it is safe to throw exceptions from it if you must.
    00122         virtual bool PasswordPrompt(const Barry::BadPassword &bp,
    00123                                         std::string &password_result) = 0;
    00124 };
    00125
    00126 class BXEXPORT DesktopConnector : public Connector
    00127 {
    00128         Barry::SocketRoutingQueue *m_router;
    00129         std::auto_ptr<Barry::Controller> m_con;
    00130         std::auto_ptr<Mode::Desktop> m_desktop;
    00131         int m_connect_timeout;
    00132
    00133 protected:
    00134         virtual void StartConnect(const char *password);
    00135         virtual void RetryPassword(const char *password);
    00136         virtual void FinishConnect();
    00137         virtual void DoDisconnect();
    00138         virtual bool IsDisconnected();
    00139
    00140 public:
    00141         // Override the timeout due to a firmware issue... sometimes
    00142         // the firmware will hang during a Reconnect, and fail to
    00143         // respond to a Desktop::Open().  To work around this, we
    00144         // set the default timeout to 10 seconds so that we find this
    00145         // failure early enough to fix it within opensync's 30 second timeout.
    00146         // Then if we get such a timeout, we do the Reconnect again and
    00147         // hope for the best... this often fixes it.
    00148         //
    00149         DesktopConnector(const char *password, const std::string &locale,
    00150                 Barry::Pin pin = 0, Barry::SocketRoutingQueue *router = 0,
    00151                 int connect_timeout = 10000);
    00152
    00153         DesktopConnector(const char *password, const std::string &locale,
    00154                 const Barry::ProbeResult &result,
    00155                 Barry::SocketRoutingQueue *router = 0,
    00156                 int connect_timeout = 10000);
    00157
    00158         virtual bool IsConnected();
    00159
    00160         virtual bool PasswordPrompt(const Barry::BadPassword &bp,
    00161                                         std::string &password_result)
    00162         {
    00163                 // default to only trying the existing password once
    00164                 return false;
    00165         }
    00166
    00167         //
    00168         // Do not use these functions if IsConnected() returns false
    00169         //
    00170
    00171         Controller& GetController() { return *m_con; }
    00172         Mode::Desktop& GetDesktop() { return *m_desktop; }
    00173
    00174         const Controller& GetController() const { return *m_con; }
    00175         const Mode::Desktop& GetDesktop()  const{ return *m_desktop; }
    00176 };
    00177
    00178 }
    00179
    00180 #endif
    00181