00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "common.h"
00023 #include "probe.h"
00024 #include "usbwrap.h"
00025 #include "data.h"
00026 #include "endian.h"
00027 #include "error.h"
00028 #include "debug.h"
00029 #include "packet.h"
00030 #include "socket.h"
00031 #include "protocol.h"
00032 #include "record-internal.h"
00033 #include "strnlen.h"
00034 #include <iomanip>
00035 #include <errno.h>
00036 #include <string.h>
00037
00038 using namespace Usb;
00039
00040 namespace Barry {
00041
00042 unsigned char Intro_Sends[][32] = {
00043
00044 { 0x00, 0x00, 0x10, 0x00, 0x01, 0xff, 0x00, 0x00,
00045 0xa8, 0x18, 0xda, 0x8d, 0x6c, 0x02, 0x00, 0x00 }
00046 };
00047
00048
00049 unsigned char Intro_Receives[][32] = {
00050
00051 { 0x00, 0x00, 0x10, 0x00, 0x02, 0xff, 0x00, 0x00,
00052 0xa8, 0x18, 0xda, 0x8d, 0x6c, 0x02, 0x00, 0x00 }
00053 };
00054
00055 namespace {
00056
00057 unsigned int GetSize(const unsigned char *packet)
00058 {
00059 uint16_t size = *((uint16_t *)&packet[2]);
00060 return btohs(size);
00061 }
00062
00063 bool Intro(int IntroIndex, const EndpointPair &ep, Device &dev, Data &response)
00064 {
00065 dev.BulkWrite(ep.write, Intro_Sends[IntroIndex],
00066 GetSize(Intro_Sends[IntroIndex]));
00067 try {
00068 dev.BulkRead(ep.read, response, 500);
00069 }
00070 catch( Usb::Timeout &to ) {
00071 ddout("BulkRead: " << to.what());
00072 return false;
00073 }
00074 ddout("BulkRead (" << (unsigned int)ep.read << "):\n" << response);
00075 return true;
00076 }
00077
00078 }
00079
00080
00081 bool Probe::CheckSize(const Data &data, unsigned int required)
00082 {
00083 const unsigned char *pd = data.GetData();
00084
00085 if( GetSize(pd) != (unsigned int) data.GetSize() ||
00086 data.GetSize() < required ||
00087 pd[4] != SB_COMMAND_FETCHED_ATTRIBUTE )
00088 {
00089 dout("Probe: Parse data failure: GetSize(pd): " << GetSize(pd)
00090 << ", data.GetSize(): " << data.GetSize()
00091 << ", pd[4]: " << (unsigned int) pd[4]);
00092 return false;
00093 }
00094
00095 return true;
00096 }
00097
00098 bool Probe::ParsePIN(const Data &data, uint32_t &pin)
00099 {
00100
00101 const unsigned char *pd = data.GetData();
00102
00103 if( !CheckSize(data, 0x14) )
00104 return false;
00105
00106
00107 pin = btohl(*((uint32_t *) &pd[16]));
00108
00109 return true;
00110 }
00111
00112 bool Probe::ParseDesc(const Data &data, std::string &desc)
00113 {
00114 if( !CheckSize(data, 29) )
00115 return false;
00116
00117
00118 const char *d = (const char*) &data.GetData()[28];
00119 int maxlen = data.GetSize() - 28;
00120 desc.assign(d, strnlen(d, maxlen));
00121
00122 return true;
00123 }
00124
00125 Probe::Probe(const char *busname, const char *devname,
00126 const Usb::EndpointPair *epp)
00127 : m_fail_count(0)
00128 , m_epp_override(epp)
00129 {
00130 if( m_epp_override ) {
00131 m_epp = *epp;
00132 }
00133
00134
00135 if( busname && !strlen(busname) )
00136 busname = 0;
00137 if( devname && !strlen(devname) )
00138 devname = 0;
00139
00140
00141 ProbeMatching(VENDOR_RIM, PRODUCT_RIM_BLACKBERRY, busname, devname);
00142
00143
00144
00145
00146
00147
00148
00149 ProbeMatching(VENDOR_RIM, PRODUCT_RIM_PEARL_DUAL, busname, devname);
00150
00151
00152 ProbeMatching(VENDOR_RIM, PRODUCT_RIM_PEARL_8120, busname, devname);
00153
00154 ProbeMatching(VENDOR_RIM, PRODUCT_RIM_PEARL_FLIP, busname, devname);
00155
00156
00157 ProbeMatching(VENDOR_RIM, PRODUCT_RIM_STORM, busname, devname);
00158 }
00159
00160 void Probe::ProbeMatching(int vendor, int product,
00161 const char *busname, const char *devname)
00162 {
00163 Usb::DeviceIDType devid;
00164
00165 Match match(vendor, product, busname, devname);
00166 while( match.next_device(&devid) ) try {
00167 ProbeDevice(devid);
00168 }
00169 catch( Usb::Error &e ) {
00170 dout("Usb::Error exception caught: " << e.what());
00171 if( e.libusb_errcode() == -EBUSY ) {
00172 m_fail_count++;
00173 m_fail_msgs.push_back(e.what());
00174 }
00175 else {
00176 throw;
00177 }
00178 }
00179 }
00180
00181 void Probe::ProbeDevice(Usb::DeviceIDType devid)
00182 {
00183
00184 DeviceDiscovery discover(devid);
00185 ConfigDesc &config = discover.configs[BLACKBERRY_CONFIGURATION];
00186
00187
00188 InterfaceDiscovery::base_type::iterator idi = config.interfaces.begin();
00189 for( ; idi != config.interfaces.end(); idi++ ) {
00190 if( idi->second.desc.bInterfaceClass == BLACKBERRY_DB_CLASS )
00191 break;
00192 }
00193 if( idi == config.interfaces.end() ) {
00194 dout("Probe: Interface with BLACKBERRY_DB_CLASS ("
00195 << BLACKBERRY_DB_CLASS << ") not found.");
00196 return;
00197 }
00198
00199 unsigned char InterfaceNumber = idi->second.desc.bInterfaceNumber;
00200 dout("Probe: using InterfaceNumber: " << (unsigned int) InterfaceNumber);
00201
00202
00203 EndpointDiscovery &ed = config.interfaces[InterfaceNumber].endpoints;
00204 if( !ed.IsValid() || ed.GetEndpointPairs().size() == 0 ) {
00205 dout("Probe: endpoint invalid. ed.IsValud() == "
00206 << (ed.IsValid() ? "true" : "false")
00207 << ", ed.GetEndpointPairs().size() == "
00208 << ed.GetEndpointPairs().size());
00209 return;
00210 }
00211
00212 ProbeResult result;
00213 result.m_dev = devid;
00214 result.m_interface = InterfaceNumber;
00215 result.m_zeroSocketSequence = 0;
00216
00217
00218 Device dev(devid);
00219
00220
00221
00222
00223 unsigned char cfg;
00224 if( !dev.GetConfiguration(cfg) )
00225 throw Usb::Error(dev.GetLastError(),
00226 "Probe: GetConfiguration failed");
00227 if( cfg != BLACKBERRY_CONFIGURATION ) {
00228 if( !dev.SetConfiguration(BLACKBERRY_CONFIGURATION) )
00229 throw Usb::Error(dev.GetLastError(),
00230 "Probe: SetConfiguration failed");
00231 }
00232
00233
00234 Interface iface(dev, InterfaceNumber);
00235
00236 if( m_epp_override ) {
00237
00238 uint32_t pin;
00239 uint8_t zeroSocketSequence;
00240 std::string desc;
00241 if( ProbePair(dev, m_epp, pin, desc, zeroSocketSequence) ) {
00242
00243 result.m_ep = m_epp;
00244 result.m_pin = pin;
00245 result.m_description = desc;
00246 result.m_zeroSocketSequence = zeroSocketSequence;
00247 }
00248 }
00249 else {
00250
00251
00252
00253
00254 size_t i;
00255 for(i = ed.GetEndpointPairs().size() > 1 ? 1 : 0;
00256 i < ed.GetEndpointPairs().size();
00257 i++ )
00258 {
00259 const EndpointPair &ep = ed.GetEndpointPairs()[i];
00260 if( ep.type == USB_ENDPOINT_TYPE_BULK ) {
00261
00262 uint32_t pin;
00263 uint8_t zeroSocketSequence;
00264 std::string desc;
00265 if( ProbePair(dev, ep, pin, desc, zeroSocketSequence) ) {
00266 result.m_ep = ep;
00267 result.m_pin = pin;
00268 result.m_description = desc;
00269 result.m_zeroSocketSequence = zeroSocketSequence;
00270 break;
00271 }
00272 }
00273 else {
00274 dout("Probe: Skipping non-bulk endpoint pair (offset: "
00275 << i-1 << ") ");
00276 }
00277 }
00278
00279
00280 i++;
00281 if( i < ed.GetEndpointPairs().size() ) {
00282 const EndpointPair &ep = ed.GetEndpointPairs()[i];
00283 if( ProbeModem(dev, ep) ) {
00284 result.m_epModem = ep;
00285 }
00286 }
00287 }
00288
00289
00290 if( result.m_ep.IsComplete() ) {
00291 m_results.push_back(result);
00292 ddout("Using ReadEndpoint: " << (unsigned int)result.m_ep.read);
00293 ddout(" WriteEndpoint: " << (unsigned int)result.m_ep.write);
00294 }
00295 else {
00296 ddout("Unable to discover endpoint pair for one device.");
00297 }
00298 }
00299
00300 bool Probe::ProbePair(Usb::Device &dev,
00301 const Usb::EndpointPair &ep,
00302 uint32_t &pin,
00303 std::string &desc,
00304 uint8_t &zeroSocketSequence)
00305 {
00306 dev.ClearHalt(ep.read);
00307 dev.ClearHalt(ep.write);
00308
00309 Data data;
00310 dev.BulkDrain(ep.read);
00311 if( !Intro(0, ep, dev, data) ) {
00312 dout("Probe: Intro(0) failed");
00313 return false;
00314 }
00315
00316 SocketZero socket(dev, ep.write, ep.read);
00317
00318 Data send, receive;
00319 ZeroPacket packet(send, receive);
00320
00321
00322 packet.GetAttribute(SB_OBJECT_INITIAL_UNKNOWN,
00323 SB_ATTR_INITIAL_UNKNOWN);
00324 socket.Send(packet);
00325
00326
00327 packet.GetAttribute(SB_OBJECT_PROFILE, SB_ATTR_PROFILE_PIN);
00328 socket.Send(packet);
00329 if( packet.ObjectID() != SB_OBJECT_PROFILE ||
00330 packet.AttributeID() != SB_ATTR_PROFILE_PIN ||
00331 !ParsePIN(receive, pin) )
00332 {
00333 dout("Probe: unable to fetch PIN");
00334 return false;
00335 }
00336
00337
00338 packet.GetAttribute(SB_OBJECT_PROFILE, SB_ATTR_PROFILE_DESC);
00339 socket.Send(packet);
00340
00341 if(
00342 packet.AttributeID() != SB_ATTR_PROFILE_DESC ||
00343 !ParseDesc(receive, desc) )
00344 {
00345 dout("Probe: unable to fetch description");
00346 }
00347
00348
00349 for( uint16_t attr = 5; attr < 9; attr++ ) {
00350 packet.GetAttribute(SB_OBJECT_SOCKET_UNKNOWN, attr);
00351 socket.Send(packet);
00352
00353
00354 }
00355
00356
00357 zeroSocketSequence = socket.GetZeroSocketSequence();
00358 return true;
00359 }
00360
00361 bool Probe::ProbeModem(Usb::Device &dev, const Usb::EndpointPair &ep)
00362 {
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 return true;
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 }
00397
00398 int Probe::FindActive(uint32_t pin) const
00399 {
00400 for( int i = 0; i < GetCount(); i++ ) {
00401 if( Get(i).m_pin == pin )
00402 return i;
00403 }
00404 if( pin == 0 ) {
00405
00406 if( GetCount() == 1 )
00407 return 0;
00408 }
00409
00410
00411 return -1;
00412 }
00413
00414 void ProbeResult::DumpAll(std::ostream &os) const
00415 {
00416 os << *this
00417 << ", Interface: 0x" << std::hex << (unsigned int) m_interface
00418 << ", Endpoints: (read: 0x" << std::hex << (unsigned int) m_ep.read
00419 << ", write: 0x" << std::hex << (unsigned int) m_ep.write
00420 << ", type: 0x" << std::hex << (unsigned int) m_ep.type
00421 << ", ZeroSocketSequence: 0x" << std::hex << (unsigned int) m_zeroSocketSequence;
00422 }
00423
00424 std::ostream& operator<< (std::ostream &os, const ProbeResult &pr)
00425 {
00426 os << "Device ID: " << pr.m_dev
00427 << std::hex << ". PIN: " << pr.m_pin
00428 << ", Description: " << pr.m_description;
00429 return os;
00430 }
00431
00432 }
00433