3 /// USB Blackberry detection routines
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 unsigned char Intro_Sends
[][32] = {
36 { 0x00, 0x00, 0x10, 0x00, 0x01, 0xff, 0x00, 0x00,
37 0xa8, 0x18, 0xda, 0x8d, 0x6c, 0x02, 0x00, 0x00 },
40 { 0x00, 0x00, 0x0c, 0x00, 0x05, 0xff, 0x00, 0x01,
41 0x14, 0x00, 0x01, 0x00 },
44 { 0x00, 0x00, 0x0c, 0x00, 0x05, 0xff, 0x00, 0x02,
45 0x08, 0x00, 0x04, 0x00 }
49 unsigned char Intro_Receives
[][32] = {
50 // response to packet #1
51 { 0x00, 0x00, 0x10, 0x00, 0x02, 0xff, 0x00, 0x00,
52 0xa8, 0x18, 0xda, 0x8d, 0x6c, 0x02, 0x00, 0x00 },
54 // response to packet #2
55 { 0x00, 0x00, 0x20, 0x00, 0x06, 0xff, 0x00, 0x01,
56 0x14, 0x00, 0x01, 0x00, 0x51, 0xe1, 0x33, 0x6b,
57 0xf3, 0x09, 0xbc, 0x37, 0x3b, 0xa3, 0x5e, 0xed,
58 0xff, 0x30, 0xa1, 0x3a, 0x60, 0xc9, 0x81, 0x8e },
60 { 0x00, 0x00, 0x14, 0x00, 0x06, 0xff, 0x00, 0x02,
61 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
62 0xe3, 0xef, 0x09, 0x30 }
67 unsigned int GetSize(const unsigned char *packet
)
69 return *((uint16_t *)&packet
[2]);
72 bool Intro(int IntroIndex
, const EndpointPair
&ep
, Device
&dev
, Data
&response
)
74 IO rd
= dev
.ABulkRead(ep
.read
, response
);
75 IO wr
= dev
.ABulkWrite(ep
.write
, Intro_Sends
[IntroIndex
],
76 GetSize(Intro_Sends
[IntroIndex
]));
81 response
.ReleaseBuffer(rd
.GetStatus() >= 0 ? rd
.GetSize() : 0);
82 return rd
.GetStatus() >= 0;
85 } // anonymous namespace
88 bool Probe::Parse(const Data
&data
, ProbeResult
&result
)
90 // validate response data
91 const unsigned char *pd
= data
.GetData();
92 if( GetSize(pd
) != (unsigned int) data
.GetSize() ||
93 data
.GetSize() < 0x14 ||
97 // throw BError("Probe: Unexpected reponse data in parse");
101 result
.m_pin
= *((uint32_t *) &pd
[16]);
107 Match
match(VENDOR_RIM
, PRODUCT_RIM_BLACKBERRY
);
109 libusb_device_id_t devid
;
110 while( match
.next_device(&devid
) ) {
112 // skip if we can't properly discover device config
113 DeviceDiscovery
discover(devid
);
114 EndpointDiscovery
&ed
= discover
.configs
[BLACKBERRY_CONFIGURATION
]
115 .interfaces
[BLACKBERRY_INTERFACE
]
117 if( !ed
.IsValid() || ed
.GetEndpointPairs().size() == 0 )
122 result
.m_dev
= devid
;
124 // find the first bulk read/write endpoint pair that answers
125 // to our probe commands
126 // Search in reverse, since evidence indicates the last pairs
127 // are the ones we need.
128 for(size_t i
= ed
.GetEndpointPairs().size(); i
; i
-- ) {
129 const EndpointPair
&ep
= ed
.GetEndpointPairs()[i
-1];
130 if( ep
.type
== USB_ENDPOINT_TYPE_BULK
) {
137 if( !dev
.SetConfiguration(BLACKBERRY_CONFIGURATION
) )
138 throw BError(dev
.GetLastError(),
139 "Probe: SetConfiguration failed");
141 Interface
iface(dev
, BLACKBERRY_INTERFACE
);
144 if( Intro(0, ep
, dev
, data
) && Intro(1, ep
, dev
, data
) &&
145 Intro(2, ep
, dev
, data
) && Parse(data
, result
) )
147 // all info obtained, add to list
148 m_results
.push_back(result
);
149 ddout("Using ReadEndpoint: " << (unsigned int)result
.m_ep
.read
);
150 ddout(" WriteEndpoint: " << (unsigned int)result
.m_ep
.write
);
156 if( !result
.m_ep
.IsComplete() )
157 ddout("Unable to discover endpoint pair for one device.");
161 int Probe::FindActive(uint32_t pin
) const
163 for( int i
= 0; i
< GetCount(); i
++ ) {
164 if( Get(i
).m_pin
== pin
)
168 // can we default to a single device?
169 if( GetCount() == 1 )
177 std::ostream
& operator<< (std::ostream
&os
, const ProbeResult
&pr
)
179 os
<< "Device ID: " << pr
.m_dev
<< std::setbase(16) << ". PIN: "