connector.h

Go to the documentation of this file.
00001 ///
00002 /// \file       connector.h
00003 ///             Base class interface for handling Mode connections to device
00004 ///
00005 
00006 /*
00007     Copyright (C) 2011-2012, 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         // bad password status
00052         BadPassword m_bpcopy;
00053 
00054 protected:
00055         // helper functions
00056         static Barry::ProbeResult FindDevice(Barry::Pin pin);
00057 
00058         // required overrides by derived classes
00059         virtual void StartConnect(const char *password) = 0;
00060         virtual void RetryPassword(const char *password) = 0;
00061         virtual void FinishConnect() = 0;
00062         virtual void DoDisconnect() = 0;
00063         /// slightly different than IsConnected()... this returns true
00064         /// even if there is a partial connection in progress...
00065         /// i.e. this returns true if DoDisconnect() can be safely skipped
00066         virtual bool IsDisconnected() = 0;
00067 
00068 public:
00069         Connector(const char *password, const std::string &locale,
00070                 Barry::Pin pin = 0);
00071         Connector(const char *password, const std::string &locale,
00072                 const Barry::ProbeResult &result);
00073         virtual ~Connector();
00074 
00075         IConverter& GetIConverter() { return m_ic; }
00076         const IConverter& GetIConverter() const { return m_ic; }
00077         Barry::ProbeResult& GetProbeResult() { return m_probe_result; }
00078         const Barry::ProbeResult& GetProbeResult() const { return m_probe_result; }
00079         const Barry::BadPassword& GetBadPassword() const { return m_bpcopy; }
00080 
00081         virtual void ClearPassword();
00082         virtual void SetPassword(const char *password);
00083 
00084         /// Returns true if connected, false if user cancelled, throws
00085         /// Barry exception on error.  Note that in the case of a bad
00086         /// password, this will return false on the first password try,
00087         /// unless you override PasswordPrompt() below.  In the default
00088         /// case, a false here means the password was invalid, and you
00089         /// should use GetBadPassword() to report the error.
00090         virtual bool Connect();
00091 
00092         /// Disconnects from the device
00093         virtual void Disconnect();
00094 
00095         /// Returns same as Connect(), but normally remembers the password
00096         /// and so avoids prompting the user if possible.  Password prompts
00097         /// are still possible though, if you have called ClearPassword().
00098         ///
00099         /// It is valid to call Reconnect() without ever calling Connect(),
00100         /// since Reconnect() is simply a wrapper that handles retries.
00101         virtual bool Reconnect(int total_tries = 2);
00102 
00103         /// Calls Reconnect() (and returns it's result) only if you have
00104         /// called RequireDirtyReconnect().  Otherwise, does nothing, but
00105         /// returns true.
00106         virtual bool ReconnectForDirtyFlags();
00107 
00108         /// Returns true if connected, false if not
00109         virtual bool IsConnected() = 0;
00110 
00111         /// This function flags the Connector object so that a future
00112         /// call to ReconnectForDirtyFlags() will actually Reconnect().
00113         /// This is needed in cases where you are updating the device,
00114         /// and require that the dirty flags on the device itself are
00115         /// properly cleared and updated.  In this case, you must call
00116         /// ReconnectForDirtyFlags() before Desktop::GetRecordStateTable().
00117         /// Disconnecting from the device, or reconnecting, clears the flag.
00118         virtual void RequireDirtyReconnect();
00119 
00120         //
00121         // Callbacks, overridden by the application
00122         //
00123 
00124         /// App should prompt user for password, fill password_result with
00125         /// what he enters and then return true.  Return false if user
00126         /// wishes to stop trying.
00127         ///
00128         /// This function is *not* called from inside a catch() routine,
00129         /// so it is safe to throw exceptions from it if you must.
00130         virtual bool PasswordPrompt(const Barry::BadPassword &bp,
00131                                         std::string &password_result) = 0;
00132 };
00133 
00134 class BXEXPORT DesktopConnector : public Connector
00135 {
00136         Barry::SocketRoutingQueue *m_router;
00137         std::auto_ptr<Barry::Controller> m_con;
00138         std::auto_ptr<Mode::Desktop> m_desktop;
00139         int m_connect_timeout;
00140 
00141 protected:
00142         virtual void StartConnect(const char *password);
00143         virtual void RetryPassword(const char *password);
00144         virtual void FinishConnect();
00145         virtual void DoDisconnect();
00146         virtual bool IsDisconnected();
00147 
00148 public:
00149         // Override the timeout due to a firmware issue... sometimes
00150         // the firmware will hang during a Reconnect, and fail to
00151         // respond to a Desktop::Open().  To work around this, we
00152         // set the default timeout to 10 seconds so that we find this
00153         // failure early enough to fix it within opensync's 30 second timeout.
00154         // Then if we get such a timeout, we do the Reconnect again and
00155         // hope for the best... this often fixes it.
00156         //
00157         DesktopConnector(const char *password, const std::string &locale,
00158                 Barry::Pin pin = 0, Barry::SocketRoutingQueue *router = 0,
00159                 int connect_timeout = 10000);
00160 
00161         DesktopConnector(const char *password, const std::string &locale,
00162                 const Barry::ProbeResult &result,
00163                 Barry::SocketRoutingQueue *router = 0,
00164                 int connect_timeout = 10000);
00165 
00166         virtual bool IsConnected();
00167 
00168         virtual bool PasswordPrompt(const Barry::BadPassword &bp,
00169                                         std::string &password_result)
00170         {
00171                 // default to only trying the existing password once
00172                 return false;
00173         }
00174 
00175         //
00176         // Do not use these functions if IsConnected() returns false
00177         //
00178 
00179         Controller& GetController() { return *m_con; }
00180         Mode::Desktop& GetDesktop() { return *m_desktop; }
00181 
00182         const Controller& GetController() const { return *m_con; }
00183         const Mode::Desktop& GetDesktop()  const{ return *m_desktop; }
00184 };
00185 
00186 }
00187 
00188 #endif
00189