3 // Base class interface for handling Mode connections to device
7 Copyright (C) 2011, 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)
50 Connector::Connector(const char *password
,
51 const std::string
&locale
,
52 const Barry::ProbeResult
&result
)
53 : m_password(password
)
54 , m_needs_reconnect(false)
55 , m_ic(locale
.c_str())
56 , m_probe_result(result
)
58 , m_last_disconnect(0)
62 Connector::~Connector()
66 Barry::ProbeResult
Connector::FindDevice(Barry::Pin pin
)
69 int i
= probe
.FindActive(pin
);
73 throw Barry::PinNotFound(pin
, probe
.GetCount());
76 void Connector::ClearPassword()
78 // blank the memory first
79 size_t len
= m_password
.size();
82 m_password
[len
] = '0';
89 void Connector::SetPassword(const char *password
)
92 m_password
= password
;
95 bool Connector::Connect()
100 BadPassword
bpcopy("", 0, 0);
106 StartConnect(m_password
.c_str());
109 RetryPassword(m_password
.c_str());
117 catch( BadPassword
&bp
) {
118 if( bp
.out_of_tries() ) {
124 // fall through to password prompt
127 // ask user for device password
129 if( !PasswordPrompt(bpcopy
, m_password
) ) {
136 void Connector::Disconnect()
138 m_needs_reconnect
= false;
139 if( !IsDisconnected() ) {
141 m_last_disconnect
= time(NULL
);
145 bool Connector::Reconnect(int total_tries
)
155 if( m_connect_count
) {
156 // let the device settle... this seems to help prevent
157 // the firmware hang, and therefore ultimately speeds
159 if( (time(NULL
) - m_last_disconnect
) < 2 ) {
160 // don't bother sleeping if 2 seconds have
165 // temporary fix for odd reconnect message...
166 // without this probe, the reconnect will often fail on
167 // newer Blackberries due to an unexpected close socket
170 // It is unclear if this is really a message from
171 // the device, but until then, we add this probe.
172 m_probe_result
= FindDevice(m_probe_result
.m_pin
);
177 catch( Usb::Timeout
& ) {
178 if( tries
>= total_tries
) {
182 dout("Timeout in Connector::Reconnect()... trying again");
187 bool Connector::ReconnectForDirtyFlags()
189 if( m_needs_reconnect
) {
197 void Connector::RequireDirtyReconnect()
199 m_needs_reconnect
= true;
203 //////////////////////////////////////////////////////////////////////////////
204 // DesktopConnector class
206 DesktopConnector::DesktopConnector(const char *password
,
207 const std::string
&locale
,
209 Barry::SocketRoutingQueue
*router
,
211 : Connector(password
, locale
, pin
)
213 , m_connect_timeout(connect_timeout
)
217 DesktopConnector::DesktopConnector(const char *password
,
218 const std::string
&locale
,
219 const Barry::ProbeResult
&result
,
220 Barry::SocketRoutingQueue
*router
,
222 : Connector(password
, locale
, result
)
224 , m_connect_timeout(connect_timeout
)
228 void DesktopConnector::StartConnect(const char *password
)
230 // Note that there is a firmware issue that causes the firmware
231 // to sometimes hang during a connect and it fails to respond
232 // to a Desktop::Open() call. To work around this, set the
233 // timeout to something lower than the usual 30 seconds.
234 // The default in DesktopConnector is 10 seconds, which should
237 // If this bug triggers, a Timeout exception will be thrown,
238 // which will be caught by the Reconnect() method, and Reconnect()
239 // will retry according to the total number of retries it is
243 m_con
.reset( new Barry::Controller(m_probe_result
,
244 *m_router
, m_connect_timeout
) );
247 m_con
.reset( new Barry::Controller(m_probe_result
,
248 m_connect_timeout
) );
250 m_desktop
.reset( new Barry::Mode::Desktop(*m_con
, m_ic
) );
251 m_desktop
->Open(password
);
254 void DesktopConnector::RetryPassword(const char *password
)
256 m_desktop
->RetryPassword(password
);
259 void DesktopConnector::FinishConnect()
263 void DesktopConnector::DoDisconnect()
269 bool DesktopConnector::IsDisconnected()
271 // return true if DoDisconnect can safely be skipped
272 return !m_con
.get() && !m_desktop
.get();
275 bool DesktopConnector::IsConnected()
277 if( m_con
.get() && m_desktop
.get() )