3 /// Base class interface for handling Mode connections to device
7 Copyright (C) 2011-2012, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "connector.h"
24 #include "controller.h"
25 #include "m_desktop.h"
29 using namespace Barry
;
33 //////////////////////////////////////////////////////////////////////////////
34 // Connector base class
36 // we use a const char *password here because we don't want the
37 // responsibility of clear its memory... that's the application's job
38 Connector::Connector(const char *password
,
39 const std::string
&locale
,
41 : m_password(password
)
42 , m_needs_reconnect(false)
43 , m_ic(locale
.c_str())
44 , m_probe_result(FindDevice(pin
))
46 , m_last_disconnect(0)
51 Connector::Connector(const char *password
,
52 const std::string
&locale
,
53 const Barry::ProbeResult
&result
)
54 : m_password(password
)
55 , m_needs_reconnect(false)
56 , m_ic(locale
.c_str())
57 , m_probe_result(result
)
59 , m_last_disconnect(0)
64 Connector::~Connector()
68 Barry::ProbeResult
Connector::FindDevice(Barry::Pin pin
)
71 int i
= probe
.FindActive(pin
);
75 throw Barry::PinNotFound(pin
, probe
.GetCount());
78 void Connector::ClearPassword()
80 // blank the memory first
81 size_t len
= m_password
.size();
84 m_password
[len
] = '0';
91 void Connector::SetPassword(const char *password
)
94 m_password
= password
;
97 bool Connector::Connect()
101 bool started
= false;
107 StartConnect(m_password
.c_str());
110 RetryPassword(m_password
.c_str());
118 catch( BadPassword
&bp
) {
119 if( bp
.out_of_tries() ) {
125 // fall through to password prompt
128 // ask user for device password
130 if( !PasswordPrompt(m_bpcopy
, m_password
) ) {
137 void Connector::Disconnect()
139 m_needs_reconnect
= false;
140 if( !IsDisconnected() ) {
142 m_last_disconnect
= time(NULL
);
146 bool Connector::Reconnect(int total_tries
)
156 if( m_connect_count
) {
157 // let the device settle... this seems to help prevent
158 // the firmware hang, and therefore ultimately speeds
160 if( (time(NULL
) - m_last_disconnect
) < 2 ) {
161 // don't bother sleeping if 2 seconds have
166 // temporary fix for odd reconnect message...
167 // without this probe, the reconnect will often fail on
168 // newer Blackberries due to an unexpected close socket
171 // It is unclear if this is really a message from
172 // the device, but until then, we add this probe.
173 m_probe_result
= FindDevice(m_probe_result
.m_pin
);
178 catch( Usb::Timeout
& ) {
179 if( tries
>= total_tries
) {
183 dout("Timeout in Connector::Reconnect()... trying again");
188 bool Connector::ReconnectForDirtyFlags()
190 if( m_needs_reconnect
) {
198 void Connector::RequireDirtyReconnect()
200 m_needs_reconnect
= true;
204 //////////////////////////////////////////////////////////////////////////////
205 // DesktopConnector class
207 DesktopConnector::DesktopConnector(const char *password
,
208 const std::string
&locale
,
210 Barry::SocketRoutingQueue
*router
,
212 : Connector(password
, locale
, pin
)
214 , m_connect_timeout(connect_timeout
)
218 DesktopConnector::DesktopConnector(const char *password
,
219 const std::string
&locale
,
220 const Barry::ProbeResult
&result
,
221 Barry::SocketRoutingQueue
*router
,
223 : Connector(password
, locale
, result
)
225 , m_connect_timeout(connect_timeout
)
229 void DesktopConnector::StartConnect(const char *password
)
231 // Note that there is a firmware issue that causes the firmware
232 // to sometimes hang during a connect and it fails to respond
233 // to a Desktop::Open() call. To work around this, set the
234 // timeout to something lower than the usual 30 seconds.
235 // The default in DesktopConnector is 10 seconds, which should
238 // If this bug triggers, a Timeout exception will be thrown,
239 // which will be caught by the Reconnect() method, and Reconnect()
240 // will retry according to the total number of retries it is
244 m_con
.reset( new Barry::Controller(m_probe_result
,
245 *m_router
, m_connect_timeout
) );
248 m_con
.reset( new Barry::Controller(m_probe_result
,
249 m_connect_timeout
) );
251 m_desktop
.reset( new Barry::Mode::Desktop(*m_con
, m_ic
) );
252 m_desktop
->Open(password
);
255 void DesktopConnector::RetryPassword(const char *password
)
257 m_desktop
->RetryPassword(password
);
260 void DesktopConnector::FinishConnect()
264 void DesktopConnector::DoDisconnect()
270 bool DesktopConnector::IsDisconnected()
272 // return true if DoDisconnect can safely be skipped
273 return !m_con
.get() && !m_desktop
.get();
276 bool DesktopConnector::IsConnected()
278 if( m_con
.get() && m_desktop
.get() )