2 /// \file controller.cc
3 /// High level Barry API class
7 Copyright (C) 2005-2008, 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 "controller.h"
26 #include "protostructs.h"
30 #define __DEBUG_MODE__
36 // Controller constructor
38 /// Constructor for the Controller class. Requires a valid ProbeResult
39 /// object to find the USB device to talk to.
41 /// \param[in] device One of the ProbeResult objects from the
44 Controller::Controller(const ProbeResult
&device
)
49 , m_zero(m_dev
, device
.m_ep
.write
, device
.m_ep
.read
, device
.m_zeroSocketSequence
)
56 // Controller constructor
58 /// Constructor for the Controller class. Requires a valid ProbeResult
59 /// object to find the USB device to talk to.
61 /// \param[in] device One of the ProbeResult objects from the
63 /// \param[in] queue Plugin router object for reading data
66 Controller::Controller(const ProbeResult
&device
, SocketRoutingQueue
&queue
)
71 , m_zero(queue
, device
.m_ep
.write
, device
.m_zeroSocketSequence
)
76 // set the queue to use our device
77 queue
.SetUsbDevice(&m_dev
, device
.m_ep
.write
, device
.m_ep
.read
);
80 void Controller::SetupUsb(const ProbeResult
&device
)
83 if( !m_dev
.GetConfiguration(cfg
) )
84 throw Usb::Error(m_dev
.GetLastError(),
85 "Controller: GetConfiguration failed");
87 if( cfg
!= BLACKBERRY_CONFIGURATION
) {
88 if( !m_dev
.SetConfiguration(BLACKBERRY_CONFIGURATION
) )
89 throw Usb::Error(m_dev
.GetLastError(),
90 "Controller: SetConfiguration failed");
93 m_iface
= new Usb::Interface(m_dev
, device
.m_interface
);
95 m_dev
.ClearHalt(device
.m_ep
.read
);
96 m_dev
.ClearHalt(device
.m_ep
.write
);
99 Controller::~Controller()
101 // // trap exceptions in the destructor
103 // // a non-default socket has been opened, close it
106 // catch( std::runtime_error &re ) {
107 // // do nothing... log it?
108 // dout("Exception caught in ~Socket: " << re.what());
111 // detach the router from our device
113 m_queue
->ClearUsbDevice();
117 // cleanup the interface
120 // this happens when for some reason the Desktop mode
121 // is not fully opened, but the device has already recommended
122 // a socket to open... in this case, reset the device
123 // in the hopes that on next open, it will be in a
124 // recognizable state.
126 // FIXME - this should not be necessary, and someday we
127 // we should figure out how to handle the "already open"
128 // response we get for the Desktop
130 // FIXME - halfOpen now seems to be handled in the Socket class...
131 // perhaps move this there if needed
135 dout("Controller object destroyed in halfopen state, resetting device");
141 ///////////////////////////////////////////////////////////////////////////////
145 // Tells device which mode is desired, and returns the suggested
146 // socket ID to use for that mode.
148 uint16_t Controller::SelectMode(ModeType mode
)
151 Protocol::Packet packet
;
153 packet
.size
= htobs(SB_MODE_PACKET_COMMAND_SIZE
);
154 packet
.command
= SB_COMMAND_SELECT_MODE
;
155 packet
.u
.socket
.socket
= htobs(SB_MODE_REQUEST_SOCKET
);
156 packet
.u
.socket
.sequence
= 0; // updated by Socket::Send()
157 memset(packet
.u
.socket
.u
.mode
.name
, 0, sizeof(packet
.u
.socket
.u
.mode
.name
));
159 char *modeName
= (char *) packet
.u
.socket
.u
.mode
.name
;
163 strcpy(modeName
, "RIM Bypass");
167 strcpy(modeName
, "RIM Desktop");
171 strcpy(modeName
, "RIM_JavaLoader");
175 strcpy(modeName
, "RIM_UsbSerData");
179 strcpy(modeName
, "RIM_UsbSerCtrl");
183 throw std::logic_error("Controller: Invalid mode in SelectMode");
187 // send mode command before we open, as a default socket is socket 0
188 Data
command(&packet
, btohs(packet
.size
));
192 m_zero
.Send(command
, response
);
194 // get the data socket number
195 // indicates the socket number that
196 // should be used below in the Open() call
197 Protocol::CheckSize(response
, SB_MODE_PACKET_RESPONSE_SIZE
);
198 MAKE_PACKET(modepack
, response
);
199 if( modepack
->command
!= SB_COMMAND_MODE_SELECTED
) {
200 eeout(command
, response
);
201 throw Error("Controller: mode not selected");
204 // return the socket that the device is expecting us to use
205 return btohs(modepack
->u
.socket
.socket
);
207 catch( Usb::Error
& ) {
208 eout("Controller: error setting desktop mode");
209 eeout(command
, response
);
215 ///////////////////////////////////////////////////////////////////////////////