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"
30 using namespace Barry
;
34 //////////////////////////////////////////////////////////////////////////////
35 // Connector base class
37 // we use a const char *password here because we don't want the
38 // responsibility of clear its memory... that's the application's job
39 Connector::Connector(const char *password
,
40 const std::string
&locale
,
42 : m_password(password
)
43 , m_needs_reconnect(false)
44 , m_ic(locale
.c_str())
45 , m_probe_result(FindDevice(pin
))
47 , m_last_disconnect(0)
52 Connector::Connector(const char *password
,
53 const std::string
&locale
,
54 const Barry::ProbeResult
&result
)
55 : m_password(password
)
56 , m_needs_reconnect(false)
57 , m_ic(locale
.c_str())
58 , m_probe_result(result
)
60 , m_last_disconnect(0)
65 Connector::~Connector()
69 Barry::ProbeResult
Connector::FindDevice(Barry::Pin pin
)
72 int i
= probe
.FindActive(pin
);
76 throw Barry::PinNotFound(pin
, probe
.GetCount());
79 void Connector::ClearPassword()
81 // blank the memory first
82 size_t len
= m_password
.size();
85 m_password
[len
] = '0';
92 void Connector::SetPassword(const char *password
)
95 m_password
= password
;
98 bool Connector::Connect()
102 bool started
= false;
108 StartConnect(m_password
.c_str());
111 RetryPassword(m_password
.c_str());
119 catch( BadPassword
&bp
) {
120 if( bp
.out_of_tries() ) {
126 // fall through to password prompt
129 // ask user for device password
131 if( !PasswordPrompt(m_bpcopy
, m_password
) ) {
138 void Connector::Disconnect()
140 m_needs_reconnect
= false;
141 if( !IsDisconnected() ) {
143 m_last_disconnect
= time(NULL
);
147 bool Connector::Reconnect(int total_tries
)
157 if( m_connect_count
) {
158 // let the device settle... this seems to help prevent
159 // the firmware hang, and therefore ultimately speeds
161 if( (time(NULL
) - m_last_disconnect
) < 2 ) {
162 // don't bother sleeping if 2 seconds have
167 // temporary fix for odd reconnect message...
168 // without this probe, the reconnect will often fail on
169 // newer Blackberries due to an unexpected close socket
172 // It is unclear if this is really a message from
173 // the device, but until then, we add this probe.
174 m_probe_result
= FindDevice(m_probe_result
.m_pin
);
179 catch( Usb::Timeout
& ) {
180 if( tries
>= total_tries
) {
184 dout("Timeout in Connector::Reconnect()... trying again");
189 bool Connector::ReconnectForDirtyFlags()
191 if( m_needs_reconnect
) {
199 void Connector::RequireDirtyReconnect()
201 m_needs_reconnect
= true;
205 //////////////////////////////////////////////////////////////////////////////
206 // DesktopConnector class
208 DesktopConnector::DesktopConnector(const char *password
,
209 const std::string
&locale
,
211 Barry::SocketRoutingQueue
*router
,
213 : Connector(password
, locale
, pin
)
215 , m_connect_timeout(connect_timeout
)
219 DesktopConnector::DesktopConnector(const char *password
,
220 const std::string
&locale
,
221 const Barry::ProbeResult
&result
,
222 Barry::SocketRoutingQueue
*router
,
224 : Connector(password
, locale
, result
)
226 , m_connect_timeout(connect_timeout
)
230 void DesktopConnector::StartConnect(const char *password
)
232 // Note that there is a firmware issue that causes the firmware
233 // to sometimes hang during a connect and it fails to respond
234 // to a Desktop::Open() call. To work around this, set the
235 // timeout to something lower than the usual 30 seconds.
236 // The default in DesktopConnector is 10 seconds, which should
239 // If this bug triggers, a Timeout exception will be thrown,
240 // which will be caught by the Reconnect() method, and Reconnect()
241 // will retry according to the total number of retries it is
245 m_con
.reset( new Barry::Controller(m_probe_result
,
246 *m_router
, m_connect_timeout
) );
249 m_con
.reset( new Barry::Controller(m_probe_result
,
250 m_connect_timeout
) );
252 m_desktop
.reset( new Barry::Mode::Desktop(*m_con
, m_ic
) );
253 m_desktop
->Open(password
);
256 void DesktopConnector::RetryPassword(const char *password
)
258 m_desktop
->RetryPassword(password
);
261 void DesktopConnector::FinishConnect()
265 void DesktopConnector::DoDisconnect()
271 bool DesktopConnector::IsDisconnected()
273 // return true if DoDisconnect can safely be skipped
274 return !m_con
.get() && !m_desktop
.get();
277 bool DesktopConnector::IsConnected()
279 if( m_con
.get() && m_desktop
.get() )