# m_mode_base.cc

Go to the documentation of this file.

    00001 ///
    00002 /// \file       m_mode_base.cc
    00003 ///             Base for mode classes
    00004 ///
    00005
    00006 /*
    00007     Copyright (C) 2005-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 #include "m_mode_base.h"
    00023
    00024 namespace Barry { namespace Mode {
    00025
    00026 //////////////////////////////////////////////////////////////////////////////
    00027 // Mode base class
    00028
    00029 Mode::Mode(Controller &con, Controller::ModeType type)
    00030         : m_con(con)
    00031         , m_modetype(type)
    00032         , m_ModeSocket(0)
    00033 {
    00034 }
    00035
    00036 Mode::~Mode()
    00037 {
    00038 }
    00039
    00040 //
    00041 // Open
    00042 //
    00043 /// Select device mode.  This is required before using any other mode-based
    00044 /// operations, such as GetDBDB() and LoadDatabase().
    00045 ///
    00046 /// This function opens a socket to the device for communicating in Desktop
    00047 /// mode.  If the device requires it, specify the password with a const char*
    00048 /// string in password.  The password will not be stored in memory
    00049 /// inside this class, only a hash will be generated from it.  After
    00050 /// using the hash, the hash memory will be set to 0.  The application
    00051 /// is responsible for safely handling the raw password data.
    00052 ///
    00053 /// You can retry the password by catching Barry::BadPassword and
    00054 /// calling RetryPassword() with the new password.
    00055 ///
    00056 /// \exception  Barry::Error
    00057 ///             Thrown on protocol error.
    00058 ///
    00059 /// \exception  std::logic_error()
    00060 ///             Thrown if unsupported mode is requested, or if socket
    00061 ///             already open.
    00062 ///
    00063 /// \exception  Barry::BadPassword
    00064 ///             Thrown when password is invalid or if not enough retries
    00065 ///             left in the device.
    00066 ///
    00067 void Mode::Open(const char *password)
    00068 {
    00069         if( m_ModeSocket ) {
    00070                 m_socket->Close();
    00071                 m_socket.reset();
    00072                 m_ModeSocket = 0;
    00073         }
    00074
    00075         m_ModeSocket = m_con.SelectMode(m_modetype);
    00076         RetryPassword(password);
    00077 }
    00078
    00079 //
    00080 // Open
    00081 //
    00082 /// Select device mode.  This is required before using any other mode-based
    00083 /// operations, such as GetDBDB() and LoadDatabase().
    00084 ///
    00085 /// This function opens a socket to the device for communicating in Desktop
    00086 /// mode.  If the device requires it, specify the password with a const char*
    00087 /// string in password.  The password will not be stored in memory
    00088 /// inside this class, only a hash will be generated from it.  After
    00089 /// using the hash, the hash memory will be set to 0.  The application
    00090 /// is responsible for safely handling the raw password data.
    00091 ///
    00092 /// It uses the provided name as the name for the socket used in this mode.
    00093 /// Usually this shouldn't be needed unless using the raw channel mode.
    00094 ///
    00095 /// You can retry the password by catching Barry::BadPassword and
    00096 /// calling RetryPassword() with the new password.
    00097 ///
    00098 /// \exception  Barry::Error
    00099 ///             Thrown on protocol error.
    00100 ///
    00101 /// \exception  std::logic_error()
    00102 ///             Thrown if unsupported mode is requested, or if socket
    00103 ///             already open.
    00104 ///
    00105 /// \exception  Barry::BadPassword
    00106 ///             Thrown when password is invalid or if not enough retries
    00107 ///             left in the device.
    00108 ///
    00109 void Mode::Open(const char *password, const char *name)
    00110 {
    00111         if( m_ModeSocket ) {
    00112                 m_socket->Close();
    00113                 m_socket.reset();
    00114                 m_ModeSocket = 0;
    00115         }
    00116
    00117         m_ModeSocket = m_con.SelectMode(m_modetype, name);
    00118         RetryPassword(password);
    00119 }
    00120
    00121 //
    00122 // RetryPassword
    00123 //
    00124 /// Retry a failed password attempt from the first call to Open().
    00125 /// Only call this function in response to Barry::BadPassword exceptions
    00126 /// that are thrown from Open().
    00127 ///
    00128 /// \exception  Barry::Error
    00129 ///             Thrown on protocol error.
    00130 ///
    00131 /// \exception  std::logic_error()
    00132 ///             Thrown if in unsupported mode, or if socket already open.
    00133 ///
    00134 /// \exception  Barry::BadPassword
    00135 ///             Thrown when password is invalid or if not enough retries
    00136 ///             left in the device.
    00137 ///
    00138 void Mode::RetryPassword(const char *password)
    00139 {
    00140         if( m_socket.get() != 0 )
    00141                 throw std::logic_error("Socket alreay open in RetryPassword");
    00142
    00143         m_socket = m_con.m_zero.Open(m_ModeSocket, password);
    00144
    00145         // success... perform open-oriented setup
    00146         OnOpen();
    00147 }
    00148
    00149
    00150 void Mode::OnOpen()
    00151 {
    00152 }
    00153
    00154
    00155 // FIXME - is this necessary?  and if it is, wouldn't it be better
    00156 // in the m_jvmdebug mode class?  I'm not convinced that applications
    00157 // should have to bother with socket-level details.
    00158 //void Mode::Close()
    00159 //{
    00160 //      if( m_ModeSocket ) {
    00161 //              m_socket->Close();
    00162 //              m_socket.reset();
    00163 //              m_ModeSocket = 0;
    00164 //      }
    00165 //}
    00166
    00167 }} // namespace Barry::Mode
    00168