- added src/endian.h... still need to add configure support to
[barry.git] / src / connect.cc
blob7a6d61e223efb44305406203333e8b654da245db
1 ///
2 /// \file connect.cc
3 /// Connection tester.
4 ///
6 /*
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.
22 #include "common.h"
23 #include "usbwrap.h"
24 #include "data.h"
26 #include <iostream>
27 #include <iomanip>
28 #include <stdexcept>
29 #include <pthread.h>
31 using namespace std;
32 using namespace Usb;
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;
44 if( bTestMode )
45 return IO::InvalidIO();
47 // wait for responses
48 time_t start = time(NULL);
49 unsigned long nLoopCount = 0;
50 while( time(NULL) - start < WAIT_TIMEOUT ) {
51 nLoopCount++;
52 usleep(100);
53 // pthread_yield();
54 IO io = dev.PollCompletions();
55 if( io.IsValid() ) {
56 if( io.GetEndpoint() == read_ep ) {
57 return io;
59 else {
60 // not the completion we were expecting, free
61 cout << "completion found: "
62 << io.GetStatus()
63 << " -- "
64 << "endpoint: " <<
65 io.GetEndpoint() << endl;
70 // if we get here, we've timed out, quit
71 // dev.ClearIO();
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;
79 if( bTestMode ) {
80 readbuf.ReleaseBuffer();
81 cout << Diff(expected, readbuf) << endl;
82 return;
85 if( !io.IsValid() )
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 ) {
104 nLoopCount++;
105 usleep(100);
106 // pthread_yield();
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 &param)
118 typedef vector<Data> DataVec;
119 DataVec sequence;
120 if( !LoadDataArray(param, sequence) ) {
121 cout << "Unable to load data sequence from: " << param << endl;
122 return;
125 // keep a space for reading
126 Data readbuf(-1, 0x4000);
128 DataVec::iterator b = sequence.begin(), e = sequence.end();
129 bool bReadPending = false;
130 int WriteCount = 0;
131 for( ; b != e; b++ ) {
133 // try {
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";
141 ClearIO(dev);
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;
149 cout << *b;
150 dev.TrackBulkWrite(write_ep, *b);
152 bReadPending = true;
154 else {
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;
165 //pthread_yield();
166 //usleep(500000);
167 dev.TrackBulkRead(read_ep, readbuf);
169 else
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;
178 // }
182 void commandline(Device &dev)
184 while( cin ) {
185 string command, param;
186 cout << "> ";
187 cin >> command;
188 if( command == "s" ) {
189 int wr_ep, rd_ep;
190 cin >> setbase(16) >> wr_ep >> rd_ep >> param;
191 cout << endl;
192 sequence(dev, wr_ep, rd_ep, param);
194 else if( command == "help" || command == "h" ) {
195 cout << endl
196 << "s [write_ep] [read_ep] [file] - data sequence\n"
197 << "help, h - help\n"
198 << "q - quit\n"
199 << endl;
201 else if( command == "q" ) {
202 return;
204 else {
205 cout << "\nunknown command: " << command << endl;
208 if( cin.fail() && !cin.eof() ) {
209 cin.clear();
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
221 try {
223 libusb_set_debug(9);
224 libusb_init();
226 if( argc >= 2 && string(argv[1]) == "-t" ) {
227 // special test mode, without a device
228 bTestMode = true;
229 Device dev(1);
230 commandline(dev);
231 return 0;
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;
239 Device dev(devid);
240 dev.Reset();
241 sleep(5);
243 Interface iface(dev, 0);
245 if( !dev.SetConfiguration(1) )
246 throw std::runtime_error("SetConfiguration failed");
248 commandline(dev);
250 else {
251 cout << "No Blackberry devices found!" << endl;
255 catch( std::runtime_error &re ) {
256 std::cerr << re.what() << endl;
257 return 1;
260 return 0;