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