7 Copyright (C) 2005-2006, 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.
34 #define DATA_PATH "data"
35 #define WAIT_TIMEOUT 5 // currently in seconds
37 bool bTestMode
= false;
40 IO
WaitOnRead(Device
&dev
, int read_ep
)
42 cout
<< "WaitOnRead" << endl
;
45 return IO::InvalidIO();
48 time_t start
= time(NULL
);
49 unsigned long nLoopCount
= 0;
50 while( time(NULL
) - start
< WAIT_TIMEOUT
) {
54 IO io
= dev
.PollCompletions();
56 if( io
.GetEndpoint() == read_ep
) {
60 // not the completion we were expecting, free
61 cout
<< "completion found: "
65 io
.GetEndpoint() << endl
;
70 // if we get here, we've timed out, quit
72 cout
<< "WaitOnRead loop count: " << nLoopCount
<< endl
;
73 throw std::runtime_error("Timeout in WaitOnRead");
76 void Process(const Data
&expected
, Data
&readbuf
, IO io
)
78 cout
<< "Process" << endl
;
80 readbuf
.ReleaseBuffer();
81 cout
<< Diff(expected
, readbuf
) << endl
;
86 return; // nothing to do
88 // io is an io handle of the expected read, so get the data
89 cout
<< "read complete: "
90 << io
.GetStatus() << endl
;
91 readbuf
.ReleaseBuffer(io
.GetSize());
92 cout
<< "endpoint: " << io
.GetEndpoint() << endl
;
93 cout
<< "diff of expected/readbuf:" << endl
;
94 cout
<< Diff(expected
, readbuf
) << endl
;
97 void ClearIO(Device
&dev
)
99 cout
<< "ClearIO" << endl
;
100 // wait for all pending IO to finish, and throw away (for now)
101 time_t start
= time(NULL
);
102 unsigned long nLoopCount
= 0;
103 while( dev
.GetIOCount() && (time(NULL
) - start
) < WAIT_TIMEOUT
) {
107 IO io
= dev
.PollCompletions();
110 if( time(NULL
) - start
>= WAIT_TIMEOUT
) {
111 cout
<< "ClearIO loop count: " << nLoopCount
<< endl
;
112 throw std::runtime_error("Timeout in ClearIO");
116 void sequence(Device
&dev
, int write_ep
, int read_ep
, const string
¶m
)
118 typedef vector
<Data
> DataVec
;
120 if( !LoadDataArray(param
, sequence
) ) {
121 cout
<< "Unable to load data sequence from: " << param
<< endl
;
125 // keep a space for reading
126 Data
readbuf(-1, 0x4000);
128 DataVec::iterator b
= sequence
.begin(), e
= sequence
.end();
129 bool bReadPending
= false;
131 for( ; b
!= e
; b
++ ) {
135 if( b
->GetEndpoint() == write_ep
) {
136 // according to the captures, every write of a
137 // command sets up a read first, to get the
138 // response... so do that now
139 cout
<< ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n";
143 cout
<< "SetupRead(" << read_ep
<< ")" << endl
;
144 dev
.TrackBulkRead(read_ep
, readbuf
);
146 cout
<< "SetupWrite()" << endl
;
147 cout
<< "Sending data to endpoint: " << write_ep
148 << " (" << ++WriteCount
<< ")" << endl
;
150 dev
.TrackBulkWrite(write_ep
, *b
);
155 // this is a read... if we have a read pending,
156 // wait for data from the device and then compare it
157 // otherwise, setup the read and then wait
158 cout
<< "Read Cycle" << endl
;
160 if( !bReadPending
) {
161 // no read pending, and we have a read buffer
162 // setup read before waiting
163 cout
<< "Read Cycle: SetupRead("
164 << read_ep
<< ")" << endl
;
167 dev
.TrackBulkRead(read_ep
, readbuf
);
170 bReadPending
= false;
172 // wait and process data read
173 Process(*b
, readbuf
, WaitOnRead(dev
, read_ep
));
176 // } catch( std::runtime_error &re ) {
177 // cout << "Caught: " << re.what() << endl;
182 void commandline(Device
&dev
)
185 string command
, param
;
188 if( command
== "s" ) {
190 cin
>> setbase(16) >> wr_ep
>> rd_ep
>> param
;
192 sequence(dev
, wr_ep
, rd_ep
, param
);
194 else if( command
== "help" || command
== "h" ) {
196 << "s [write_ep] [read_ep] [file] - data sequence\n"
197 << "help, h - help\n"
201 else if( command
== "q" ) {
205 cout
<< "\nunknown command: " << command
<< endl
;
208 if( cin
.fail() && !cin
.eof() ) {
210 cin
.ignore(1024, '\n');
216 int main(int argc
, char *argv
[])
218 cout
.sync_with_stdio(true); // leave this on, since libusb uses
219 // stdio for debug messages
226 if( argc
>= 2 && string(argv
[1]) == "-t" ) {
227 // special test mode, without a device
234 Match
match(VENDOR_RIM
, PRODUCT_RIM_BLACKBERRY
);
236 libusb_device_id_t devid
;
237 if (match
.next_device(&devid
)) {
238 cout
<< "found device id " << devid
<< endl
;
243 Interface
iface(dev
, 0);
245 if( !dev
.SetConfiguration(1) )
246 throw std::runtime_error("SetConfiguration failed");
251 cout
<< "No Blackberry devices found!" << endl
;
255 catch( std::runtime_error
&re
) {
256 std::cerr
<< re
.what() << endl
;