1 /* 2 * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd 3 * Seth Liu 2017.03.01 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include "RKScan.h" 9 #define BUSID(id) ((id & 0x0000FF00) >> 8) 10 int CRKScan::GetDEVICE_COUNTS() 11 { 12 return m_list.size(); 13 } 14 15 UINT CRKScan::GetMSC_TIMEOUT() 16 { 17 return m_waitMscSecond; 18 } 19 20 UINT CRKScan::GetRKUSB_TIMEOUT() 21 { 22 return m_waitRKusbSecond; 23 } 24 25 void CRKScan::SetMSC_TIMEOUT(UINT value) 26 { 27 m_waitMscSecond = value; 28 } 29 30 void CRKScan::SetRKUSB_TIMEOUT(UINT value) 31 { 32 m_waitRKusbSecond = value; 33 } 34 35 CRKScan::CRKScan(UINT uiMscTimeout, UINT uiRKusbTimeout) 36 { 37 DEVICE_COUNTS.setContainer(this); 38 DEVICE_COUNTS.getter(&CRKScan::GetDEVICE_COUNTS); 39 40 MSC_TIMEOUT.setContainer(this); 41 MSC_TIMEOUT.getter(&CRKScan::GetMSC_TIMEOUT); 42 MSC_TIMEOUT.setter(&CRKScan::SetMSC_TIMEOUT); 43 44 RKUSB_TIMEOUT.setContainer(this); 45 RKUSB_TIMEOUT.getter(&CRKScan::GetRKUSB_TIMEOUT); 46 RKUSB_TIMEOUT.setter(&CRKScan::SetRKUSB_TIMEOUT); 47 48 m_waitMscSecond = uiMscTimeout; 49 m_waitRKusbSecond = uiRKusbTimeout; 50 m_log = NULL; 51 m_list.clear(); 52 m_deviceConfigSet.clear(); 53 m_deviceMscConfigSet.clear(); 54 } 55 bool CRKScan::FindRockusbVidPid(ENUM_RKDEVICE_TYPE type, USHORT &usVid, USHORT &usPid) 56 { 57 UINT i; 58 bool bRet = false; 59 for (i = 0; i < m_deviceConfigSet.size(); i++) { 60 if (m_deviceConfigSet[i].emDeviceType == type) { 61 usVid = m_deviceConfigSet[i].usVid; 62 usPid = m_deviceConfigSet[i].usPid; 63 bRet = true; 64 break; 65 } 66 } 67 return bRet; 68 } 69 void CRKScan::AddRockusbVidPid(USHORT newVid, USHORT newPid, USHORT oldVid, USHORT oldPid) 70 { 71 if ((newVid == 0) || (newPid == 0) || (oldVid == 0) || (oldPid == 0)) { 72 return; 73 } 74 STRUCT_DEVICE_CONFIG config; 75 unsigned int i; 76 for (i = 0; i < m_deviceConfigSet.size(); i++) { 77 if ((m_deviceConfigSet[i].usVid == oldVid) && (m_deviceConfigSet[i].usPid == oldPid)) { 78 config.usVid = newVid; 79 config.usPid = newPid; 80 config.emDeviceType = m_deviceConfigSet[i].emDeviceType; 81 break; 82 } 83 } 84 if (i < m_deviceConfigSet.size()) 85 m_deviceConfigSet.push_back(config); 86 } 87 88 void CRKScan::SetVidPid(USHORT mscVid, USHORT mscPid) 89 { 90 STRUCT_DEVICE_CONFIG config; 91 m_deviceConfigSet.clear(); 92 93 config.emDeviceType = RK27_DEVICE; 94 config.usPid = 0x3201; 95 config.usVid = 0x071B; 96 m_deviceConfigSet.push_back(config); 97 98 config.emDeviceType = RK28_DEVICE; 99 config.usPid = 0x3228; 100 config.usVid = 0x071B; 101 m_deviceConfigSet.push_back(config); 102 103 config.emDeviceType = RKNANO_DEVICE; 104 config.usPid = 0x3226; 105 config.usVid = 0x071B; 106 m_deviceConfigSet.push_back(config); 107 108 config.emDeviceType = RKCROWN_DEVICE; 109 config.usPid = 0x261A; 110 config.usVid = 0x2207; 111 m_deviceConfigSet.push_back(config); 112 113 config.emDeviceType = RK281X_DEVICE; 114 config.usPid = 0x281A; 115 config.usVid = 0x2207; 116 m_deviceConfigSet.push_back(config); 117 118 config.emDeviceType = RKCAYMAN_DEVICE; 119 config.usPid = 0x273A; 120 config.usVid = 0x2207; 121 m_deviceConfigSet.push_back(config); 122 123 config.emDeviceType = RK29_DEVICE; 124 config.usPid = 0x290A; 125 config.usVid = 0x2207; 126 m_deviceConfigSet.push_back(config); 127 128 config.emDeviceType = RKPANDA_DEVICE; 129 config.usPid = 0x282B; 130 config.usVid = 0x2207; 131 m_deviceConfigSet.push_back(config); 132 133 config.emDeviceType = RKSMART_DEVICE; 134 config.usPid = 0x262C; 135 config.usVid = 0x2207; 136 m_deviceConfigSet.push_back(config); 137 138 config.emDeviceType = RK292X_DEVICE; 139 config.usPid = 0x292A; 140 config.usVid = 0x2207; 141 m_deviceConfigSet.push_back(config); 142 143 config.emDeviceType = RK30_DEVICE; 144 config.usPid = 0x300A; 145 config.usVid = 0x2207; 146 m_deviceConfigSet.push_back(config); 147 148 config.emDeviceType = RK30B_DEVICE; 149 config.usPid = 0x300B; 150 config.usVid = 0x2207; 151 m_deviceConfigSet.push_back(config); 152 153 config.emDeviceType = RK31_DEVICE; 154 config.usPid = 0x310B; 155 config.usVid = 0x2207; 156 m_deviceConfigSet.push_back(config); 157 158 config.emDeviceType = RK32_DEVICE; 159 config.usPid = 0x320A; 160 config.usVid = 0x2207; 161 m_deviceConfigSet.push_back(config); 162 163 m_deviceMscConfigSet.clear(); 164 165 config.emDeviceType = RKNONE_DEVICE; 166 config.usPid = 0x3203; 167 config.usVid = 0x071B; 168 m_deviceMscConfigSet.push_back(config); 169 170 config.emDeviceType = RKNONE_DEVICE; 171 config.usPid = 0x3205; 172 config.usVid = 0x071B; 173 m_deviceMscConfigSet.push_back(config); 174 175 config.emDeviceType = RKNONE_DEVICE; 176 config.usPid = 0x2910; 177 config.usVid = 0x0BB4; 178 m_deviceMscConfigSet.push_back(config); 179 180 config.emDeviceType = RKNONE_DEVICE; 181 config.usPid = 0x0000; 182 config.usVid = 0x2207; 183 m_deviceMscConfigSet.push_back(config); 184 185 config.emDeviceType = RKNONE_DEVICE; 186 config.usPid = 0x0010; 187 config.usVid = 0x2207; 188 m_deviceMscConfigSet.push_back(config); 189 190 if ((mscVid != 0) || (mscPid != 0)) { 191 if (FindConfigSetPos(m_deviceMscConfigSet, mscVid, mscPid) == -1) { 192 config.emDeviceType = RKNONE_DEVICE; 193 config.usPid = mscPid; 194 config.usVid = mscVid; 195 m_deviceMscConfigSet.push_back(config); 196 } 197 } 198 } 199 int CRKScan::FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid) 200 { 201 int pos=-1; 202 UINT i; 203 for ( i = 0; i < waitDeviceSet.size(); i++ ) { 204 if ( (vid == waitDeviceSet[i].usVid) && (pid == waitDeviceSet[i].usPid) ) { 205 pos = i; 206 break; 207 } 208 } 209 return pos; 210 } 211 int CRKScan::FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid) 212 { 213 int pos = -1; 214 UINT i; 215 for ( i = 0; i < devConfigSet.size(); i++ ) { 216 if ( (vid == devConfigSet[i].usVid) && (pid == devConfigSet[i].usPid) ) { 217 pos = i; 218 break; 219 } 220 } 221 return pos; 222 } 223 void CRKScan::EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices) 224 { 225 STRUCT_RKDEVICE_DESC desc; 226 struct libusb_device_descriptor descriptor; 227 int ret,i,cnt; 228 229 uiTotalMatchDevices = 0; 230 libusb_device **pDevs = NULL; 231 libusb_device *dev; 232 ret = libusb_get_device_list(NULL, &pDevs); 233 if (ret < 0) { 234 if (m_log) 235 m_log->Record("Error:EnumerateUsbDevice-->get_device_list failed,err=%d!", ret); 236 return; 237 } 238 cnt = ret; 239 for (i = 0; i < cnt; i++) { 240 dev = pDevs[i]; 241 if (dev) { 242 ret = libusb_get_device_descriptor (dev, &descriptor); 243 if (ret < 0) { 244 libusb_free_device_list(pDevs, 1); 245 if (m_log) 246 m_log->Record("Error:EnumerateUsbDevice-->get_device_descriptor failed,err=%d!", ret); 247 return; 248 } 249 desc.emDeviceType = RKNONE_DEVICE; 250 desc.emUsbType = RKUSB_NONE; 251 desc.pUsbHandle = (void *)dev; 252 desc.usbcdUsb = descriptor.bcdUSB; 253 desc.usVid = descriptor.idVendor; 254 desc.usPid = descriptor.idProduct; 255 desc.uiLocationID = libusb_get_bus_number(dev); 256 desc.uiLocationID <<= 8; 257 desc.uiLocationID += libusb_get_port_number(dev); 258 libusb_ref_device(dev); 259 uiTotalMatchDevices++; 260 list.push_back(desc); 261 } 262 263 } 264 libusb_free_device_list(pDevs, 1); 265 266 } 267 268 void CRKScan::FreeDeviceList(RKDEVICE_DESC_SET &list) 269 { 270 device_list_iter iter; 271 for (iter = list.begin(); iter != list.end(); iter++) { 272 if ((*iter).pUsbHandle) { 273 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 274 (*iter).pUsbHandle = NULL; 275 } 276 } 277 list.clear(); 278 } 279 bool CRKScan::IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid) 280 { 281 int iPos; 282 iPos = FindConfigSetPos(m_deviceConfigSet, vid, pid); 283 if (iPos != -1) { 284 type = m_deviceConfigSet[iPos].emDeviceType; 285 return true; 286 } 287 if (vid == 0x2207) { 288 if ((pid >> 8) > 0) { 289 type = RKNONE_DEVICE; 290 return true; 291 } 292 } 293 return false; 294 } 295 int CRKScan::Search(UINT type) 296 { 297 device_list_iter iter,new_iter; 298 ENUM_RKDEVICE_TYPE devType; 299 UINT uiTotalDevice; 300 int iPos; 301 302 FreeDeviceList(m_list); 303 EnumerateUsbDevice( m_list, uiTotalDevice ); 304 305 for ( iter = m_list.begin(); iter != m_list.end(); ) { 306 if( (iPos = FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid)) != -1 ) { 307 (*iter).emDeviceType = RKNONE_DEVICE; 308 iter++; 309 continue; 310 } else if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid) ) { 311 (*iter).emDeviceType = devType; 312 iter++; 313 continue; 314 } else { 315 if ((*iter).pUsbHandle) { 316 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 317 (*iter).pUsbHandle = NULL; 318 } 319 iter = m_list.erase(iter); 320 uiTotalDevice--; 321 } 322 } 323 324 if (m_list.size() <= 0) { 325 return 0; 326 } 327 328 if ( (type & RKUSB_MASKROM) == 0 ) { 329 for ( iter = m_list.begin(); iter != m_list.end(); ) { 330 if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 0) ) { 331 if ((*iter).pUsbHandle) { 332 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 333 (*iter).pUsbHandle = NULL; 334 } 335 iter = m_list.erase(iter); 336 uiTotalDevice--; 337 } else { 338 iter++; 339 continue; 340 } 341 } 342 } 343 if (m_list.size() <= 0) { 344 return 0; 345 } 346 347 if ( (type & RKUSB_LOADER) == 0 ) { 348 for ( iter = m_list.begin(); iter != m_list.end(); ) { 349 if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 1) ) { 350 if ((*iter).pUsbHandle) { 351 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 352 (*iter).pUsbHandle = NULL; 353 } 354 iter = m_list.erase(iter); 355 uiTotalDevice--; 356 } else { 357 iter++; 358 continue; 359 } 360 } 361 } 362 if (m_list.size() <= 0) { 363 return 0; 364 } 365 366 if ( (type & RKUSB_MSC) == 0 ) { 367 for ( iter = m_list.begin(); iter != m_list.end(); ) { 368 if(FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 369 if ((*iter).pUsbHandle) { 370 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 371 (*iter).pUsbHandle = NULL; 372 } 373 iter = m_list.erase(iter); 374 uiTotalDevice--; 375 } else { 376 iter++; 377 continue; 378 } 379 } 380 } 381 if (m_list.size() <= 0) { 382 return 0; 383 } 384 385 for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 386 if (FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 387 (*iter).emUsbType = RKUSB_MSC; 388 } else { 389 USHORT usTemp; 390 usTemp = (*iter).usbcdUsb; 391 usTemp= usTemp & 0x1; 392 if ( usTemp == 0 ) 393 (*iter).emUsbType = RKUSB_MASKROM; 394 else 395 (*iter).emUsbType = RKUSB_LOADER; 396 } 397 } 398 return m_list.size(); 399 } 400 bool CRKScan::MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 401 { 402 device_list_iter iter; 403 int uiWaitSecond; 404 int iFoundCount = 0; 405 UINT iRet,i; 406 bool bFound = false; 407 if (usbType == RKUSB_MSC) 408 uiWaitSecond = m_waitMscSecond; 409 else 410 uiWaitSecond = m_waitRKusbSecond; 411 time_t tmInit, tmNow; 412 time(&tmInit); 413 device.uiLocationID = 0; 414 while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 415 iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 416 if ( iRet == vecExistedDevice.size() + 1 ) { 417 for (i = 0; i < vecExistedDevice.size(); i++) { 418 for (iter = m_list.begin(); iter != m_list.end(); ) { 419 if ((*iter).uiLocationID == vecExistedDevice[i]) { 420 iter = m_list.erase(iter); 421 } else 422 iter++; 423 } 424 } 425 if (m_list.size() != 1) { 426 device.uiLocationID = 0; 427 iFoundCount = 0; 428 } else { 429 iter = m_list.begin(); 430 if (device.uiLocationID == 0) { 431 iFoundCount++; 432 device.uiLocationID = (*iter).uiLocationID; 433 } else { 434 if (device.uiLocationID == (*iter).uiLocationID) { 435 iFoundCount++; 436 } else { 437 device.uiLocationID = 0; 438 iFoundCount = 0; 439 } 440 } 441 } 442 } else { 443 device.uiLocationID = 0; 444 iFoundCount = 0; 445 } 446 if (iFoundCount >= 10) { 447 bFound = true; 448 break; 449 } 450 } 451 if (!bFound) { 452 return false; 453 } 454 bFound = Wait(device, usbType, usVid, usPid); 455 return bFound; 456 } 457 458 bool CRKScan::MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice) 459 { 460 int iRet, iRet2; 461 device_list_iter iter; 462 time_t timeInit, timeNow; 463 time(&timeInit); 464 iRet = iRet2 =0; 465 while ((time(&timeNow) - timeInit) <= 3) { 466 iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 467 usleep(20000); 468 iRet2 = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 469 if (iRet2 == iRet) { 470 break; 471 } 472 } 473 if ((iRet <= 0) || (iRet2 != iRet)) { 474 return false; 475 } 476 vecExistedDevice.clear(); 477 bool bFound = false; 478 for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 479 if ((*iter).uiLocationID != uiOfflineDevice) { 480 vecExistedDevice.push_back((*iter).uiLocationID); 481 } else 482 bFound = true; 483 } 484 if (!bFound) { 485 return false; 486 } 487 return true; 488 489 } 490 491 bool CRKScan::Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 492 { 493 RKDEVICE_DESC_SET deviceList; 494 ENUM_RKUSB_TYPE curDeviceType; 495 ENUM_RKDEVICE_TYPE devType; 496 device_list_iter iter; 497 UINT totalDevice; 498 int uiWaitSecond; 499 int iFoundCount = 0; 500 bool bRet = false; 501 if (usbType == RKUSB_MSC) 502 uiWaitSecond = m_waitMscSecond; 503 else 504 uiWaitSecond = m_waitRKusbSecond; 505 time_t tmInit, tmNow; 506 time(&tmInit); 507 while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 508 FreeDeviceList(deviceList); 509 EnumerateUsbDevice(deviceList, totalDevice); 510 for ( iter = deviceList.begin(); iter != deviceList.end(); iter++ ) { 511 if ((BUSID((*iter).uiLocationID) != BUSID(device.uiLocationID)) || 512 ((BUSID((*iter).uiLocationID) == BUSID(device.uiLocationID)) && ((*iter).uiLocationID >= device.uiLocationID))) { 513 if ((usVid != 0) || (usPid != 0)) { 514 if ( ((*iter).usVid != usVid) || ((*iter).usPid != usPid) ) 515 continue; 516 } 517 if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) { 518 if ( ((*iter).usbcdUsb & 0x0001) == 0 ) 519 curDeviceType = RKUSB_MASKROM; 520 else 521 curDeviceType = RKUSB_LOADER; 522 } else if ( FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1 ) { 523 curDeviceType = RKUSB_MSC; 524 } else 525 curDeviceType = RKUSB_NONE; 526 527 if ( curDeviceType == usbType ) { 528 iFoundCount++; 529 break; 530 } 531 } 532 } 533 if ( iter == deviceList.end() ) { 534 iFoundCount = 0; 535 } 536 if ( iFoundCount >= 8 ) { 537 device.usVid = (*iter).usVid; 538 device.usPid = (*iter).usPid; 539 device.uiLocationID = (*iter).uiLocationID; 540 device.pUsbHandle= (*iter).pUsbHandle; 541 device.emUsbType = usbType; 542 device.usbcdUsb = (*iter).usbcdUsb; 543 libusb_ref_device((libusb_device *)device.pUsbHandle); 544 545 if (usbType == RKUSB_MSC) { 546 device.emDeviceType = RKNONE_DEVICE; 547 } else { 548 if (IsRockusbDevice(devType, device.usVid, device.usPid)) 549 device.emDeviceType = devType; 550 } 551 bRet = true; 552 break; 553 } 554 usleep(50000); 555 } 556 557 FreeDeviceList(deviceList); 558 return bRet; 559 } 560 int CRKScan::GetPos(UINT locationID) 561 { 562 device_list_iter iter; 563 int pos = 0; 564 bool bFound = false; 565 for (iter = m_list.begin(); iter != m_list.end(); iter++) { 566 if (locationID == (*iter).uiLocationID) { 567 bFound=true; 568 break; 569 } 570 pos++; 571 } 572 return (bFound ? pos : -1); 573 } 574 bool CRKScan::GetDevice(STRUCT_RKDEVICE_DESC &device, int pos) 575 { 576 if ( (pos < 0) || (pos >= (int)m_list.size()) ) { 577 return false; 578 } 579 device_list_iter iter; 580 for (iter = m_list.begin(); iter != m_list.end(); iter++) { 581 if (pos == 0) { 582 break; 583 } 584 pos--; 585 } 586 device.usVid = (*iter).usVid; 587 device.usPid = (*iter).usPid; 588 device.emDeviceType = (*iter).emDeviceType; 589 device.emUsbType = (*iter).emUsbType; 590 device.uiLocationID = (*iter).uiLocationID; 591 device.pUsbHandle= (*iter).pUsbHandle; 592 device.usbcdUsb = (*iter).usbcdUsb; 593 return true; 594 } 595 596 bool CRKScan::SetLogObject(CRKLog *pLog) 597 { 598 if (pLog) { 599 if (m_log) { 600 delete m_log; 601 } 602 m_log = pLog; 603 } else 604 return false; 605 return true; 606 } 607 CRKScan::~CRKScan() 608 { 609 FreeDeviceList(m_list); 610 if (m_log) { 611 delete m_log; 612 m_log = NULL; 613 } 614 } 615