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 = RK31_DEVICE; 159 config.usPid = 0x310C; 160 config.usVid = 0x2207; 161 m_deviceConfigSet.push_back(config); 162 163 config.emDeviceType = RK32_DEVICE; 164 config.usPid = 0x320A; 165 config.usVid = 0x2207; 166 m_deviceConfigSet.push_back(config); 167 168 m_deviceMscConfigSet.clear(); 169 170 config.emDeviceType = RKNONE_DEVICE; 171 config.usPid = 0x3203; 172 config.usVid = 0x071B; 173 m_deviceMscConfigSet.push_back(config); 174 175 config.emDeviceType = RKNONE_DEVICE; 176 config.usPid = 0x3205; 177 config.usVid = 0x071B; 178 m_deviceMscConfigSet.push_back(config); 179 180 config.emDeviceType = RKNONE_DEVICE; 181 config.usPid = 0x2910; 182 config.usVid = 0x0BB4; 183 m_deviceMscConfigSet.push_back(config); 184 185 config.emDeviceType = RKNONE_DEVICE; 186 config.usPid = 0x0000; 187 config.usVid = 0x2207; 188 m_deviceMscConfigSet.push_back(config); 189 190 config.emDeviceType = RKNONE_DEVICE; 191 config.usPid = 0x0010; 192 config.usVid = 0x2207; 193 m_deviceMscConfigSet.push_back(config); 194 195 if ((mscVid != 0) || (mscPid != 0)) { 196 if (FindConfigSetPos(m_deviceMscConfigSet, mscVid, mscPid) == -1) { 197 config.emDeviceType = RKNONE_DEVICE; 198 config.usPid = mscPid; 199 config.usVid = mscVid; 200 m_deviceMscConfigSet.push_back(config); 201 } 202 } 203 } 204 int CRKScan::FindWaitSetPos(const RKDEVICE_CONFIG_SET &waitDeviceSet, USHORT vid, USHORT pid) 205 { 206 int pos=-1; 207 UINT i; 208 for ( i = 0; i < waitDeviceSet.size(); i++ ) { 209 if ( (vid == waitDeviceSet[i].usVid) && (pid == waitDeviceSet[i].usPid) ) { 210 pos = i; 211 break; 212 } 213 } 214 return pos; 215 } 216 int CRKScan::FindConfigSetPos(RKDEVICE_CONFIG_SET &devConfigSet, USHORT vid, USHORT pid) 217 { 218 int pos = -1; 219 UINT i; 220 for ( i = 0; i < devConfigSet.size(); i++ ) { 221 if ( (vid == devConfigSet[i].usVid) && (pid == devConfigSet[i].usPid) ) { 222 pos = i; 223 break; 224 } 225 } 226 return pos; 227 } 228 void CRKScan::EnumerateUsbDevice(RKDEVICE_DESC_SET &list, UINT &uiTotalMatchDevices) 229 { 230 STRUCT_RKDEVICE_DESC desc; 231 struct libusb_device_descriptor descriptor; 232 int ret,i,cnt; 233 234 uiTotalMatchDevices = 0; 235 libusb_device **pDevs = NULL; 236 libusb_device *dev; 237 ret = libusb_get_device_list(NULL, &pDevs); 238 if (ret < 0) { 239 if (m_log) 240 m_log->Record("Error:EnumerateUsbDevice-->get_device_list failed,err=%d!", ret); 241 return; 242 } 243 cnt = ret; 244 for (i = 0; i < cnt; i++) { 245 dev = pDevs[i]; 246 if (dev) { 247 ret = libusb_get_device_descriptor (dev, &descriptor); 248 if (ret < 0) { 249 libusb_free_device_list(pDevs, 1); 250 if (m_log) 251 m_log->Record("Error:EnumerateUsbDevice-->get_device_descriptor failed,err=%d!", ret); 252 return; 253 } 254 desc.emDeviceType = RKNONE_DEVICE; 255 desc.emUsbType = RKUSB_NONE; 256 desc.pUsbHandle = (void *)dev; 257 desc.usbcdUsb = descriptor.bcdUSB; 258 desc.usVid = descriptor.idVendor; 259 desc.usPid = descriptor.idProduct; 260 desc.uiLocationID = libusb_get_bus_number(dev); 261 desc.uiLocationID <<= 8; 262 desc.uiLocationID += libusb_get_port_number(dev); 263 libusb_ref_device(dev); 264 uiTotalMatchDevices++; 265 list.push_back(desc); 266 } 267 268 } 269 libusb_free_device_list(pDevs, 1); 270 271 } 272 273 void CRKScan::FreeDeviceList(RKDEVICE_DESC_SET &list) 274 { 275 device_list_iter iter; 276 for (iter = list.begin(); iter != list.end(); iter++) { 277 if ((*iter).pUsbHandle) { 278 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 279 (*iter).pUsbHandle = NULL; 280 } 281 } 282 list.clear(); 283 } 284 bool CRKScan::IsRockusbDevice(ENUM_RKDEVICE_TYPE &type, USHORT vid, USHORT pid) 285 { 286 int iPos; 287 iPos = FindConfigSetPos(m_deviceConfigSet, vid, pid); 288 if (iPos != -1) { 289 type = m_deviceConfigSet[iPos].emDeviceType; 290 return true; 291 } 292 if (vid == 0x2207) { 293 if ((pid >> 8) > 0) { 294 type = RKNONE_DEVICE; 295 return true; 296 } 297 } 298 return false; 299 } 300 int CRKScan::Search(UINT type) 301 { 302 device_list_iter iter,new_iter; 303 ENUM_RKDEVICE_TYPE devType; 304 UINT uiTotalDevice; 305 int iPos; 306 307 FreeDeviceList(m_list); 308 EnumerateUsbDevice( m_list, uiTotalDevice ); 309 310 for ( iter = m_list.begin(); iter != m_list.end(); ) { 311 if( (iPos = FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid)) != -1 ) { 312 (*iter).emDeviceType = RKNONE_DEVICE; 313 iter++; 314 continue; 315 } else if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid) ) { 316 (*iter).emDeviceType = devType; 317 iter++; 318 continue; 319 } else { 320 if ((*iter).pUsbHandle) { 321 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 322 (*iter).pUsbHandle = NULL; 323 } 324 iter = m_list.erase(iter); 325 uiTotalDevice--; 326 } 327 } 328 329 if (m_list.size() <= 0) { 330 return 0; 331 } 332 333 if ( (type & RKUSB_MASKROM) == 0 ) { 334 for ( iter = m_list.begin(); iter != m_list.end(); ) { 335 if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 0) ) { 336 if ((*iter).pUsbHandle) { 337 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 338 (*iter).pUsbHandle = NULL; 339 } 340 iter = m_list.erase(iter); 341 uiTotalDevice--; 342 } else { 343 iter++; 344 continue; 345 } 346 } 347 } 348 if (m_list.size() <= 0) { 349 return 0; 350 } 351 352 if ( (type & RKUSB_LOADER) == 0 ) { 353 for ( iter = m_list.begin(); iter != m_list.end(); ) { 354 if( (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) && (((*iter).usbcdUsb & 0x1) == 1) ) { 355 if ((*iter).pUsbHandle) { 356 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 357 (*iter).pUsbHandle = NULL; 358 } 359 iter = m_list.erase(iter); 360 uiTotalDevice--; 361 } else { 362 iter++; 363 continue; 364 } 365 } 366 } 367 if (m_list.size() <= 0) { 368 return 0; 369 } 370 371 if ( (type & RKUSB_MSC) == 0 ) { 372 for ( iter = m_list.begin(); iter != m_list.end(); ) { 373 if(FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 374 if ((*iter).pUsbHandle) { 375 libusb_unref_device((libusb_device *)((*iter).pUsbHandle)); 376 (*iter).pUsbHandle = NULL; 377 } 378 iter = m_list.erase(iter); 379 uiTotalDevice--; 380 } else { 381 iter++; 382 continue; 383 } 384 } 385 } 386 if (m_list.size() <= 0) { 387 return 0; 388 } 389 390 for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 391 if (FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1) { 392 (*iter).emUsbType = RKUSB_MSC; 393 } else { 394 USHORT usTemp; 395 usTemp = (*iter).usbcdUsb; 396 usTemp= usTemp & 0x1; 397 if ( usTemp == 0 ) 398 (*iter).emUsbType = RKUSB_MASKROM; 399 else 400 (*iter).emUsbType = RKUSB_LOADER; 401 } 402 } 403 return m_list.size(); 404 } 405 bool CRKScan::MutexWait(UINT_VECTOR &vecExistedDevice, STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 406 { 407 device_list_iter iter; 408 int uiWaitSecond; 409 int iFoundCount = 0; 410 UINT iRet,i; 411 bool bFound = false; 412 if (usbType == RKUSB_MSC) 413 uiWaitSecond = m_waitMscSecond; 414 else 415 uiWaitSecond = m_waitRKusbSecond; 416 time_t tmInit, tmNow; 417 time(&tmInit); 418 device.uiLocationID = 0; 419 while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 420 iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 421 if ( iRet == vecExistedDevice.size() + 1 ) { 422 for (i = 0; i < vecExistedDevice.size(); i++) { 423 for (iter = m_list.begin(); iter != m_list.end(); ) { 424 if ((*iter).uiLocationID == vecExistedDevice[i]) { 425 iter = m_list.erase(iter); 426 } else 427 iter++; 428 } 429 } 430 if (m_list.size() != 1) { 431 device.uiLocationID = 0; 432 iFoundCount = 0; 433 } else { 434 iter = m_list.begin(); 435 if (device.uiLocationID == 0) { 436 iFoundCount++; 437 device.uiLocationID = (*iter).uiLocationID; 438 } else { 439 if (device.uiLocationID == (*iter).uiLocationID) { 440 iFoundCount++; 441 } else { 442 device.uiLocationID = 0; 443 iFoundCount = 0; 444 } 445 } 446 } 447 } else { 448 device.uiLocationID = 0; 449 iFoundCount = 0; 450 } 451 if (iFoundCount >= 10) { 452 bFound = true; 453 break; 454 } 455 } 456 if (!bFound) { 457 return false; 458 } 459 bFound = Wait(device, usbType, usVid, usPid); 460 return bFound; 461 } 462 463 bool CRKScan::MutexWaitPrepare(UINT_VECTOR &vecExistedDevice, DWORD uiOfflineDevice) 464 { 465 int iRet, iRet2; 466 device_list_iter iter; 467 time_t timeInit, timeNow; 468 time(&timeInit); 469 iRet = iRet2 =0; 470 while ((time(&timeNow) - timeInit) <= 3) { 471 iRet = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 472 usleep(20000); 473 iRet2 = Search(RKUSB_MASKROM | RKUSB_LOADER | RKUSB_MSC); 474 if (iRet2 == iRet) { 475 break; 476 } 477 } 478 if ((iRet <= 0) || (iRet2 != iRet)) { 479 return false; 480 } 481 vecExistedDevice.clear(); 482 bool bFound = false; 483 for ( iter = m_list.begin(); iter != m_list.end(); iter++ ) { 484 if ((*iter).uiLocationID != uiOfflineDevice) { 485 vecExistedDevice.push_back((*iter).uiLocationID); 486 } else 487 bFound = true; 488 } 489 if (!bFound) { 490 return false; 491 } 492 return true; 493 494 } 495 496 bool CRKScan::Wait(STRUCT_RKDEVICE_DESC &device, ENUM_RKUSB_TYPE usbType, USHORT usVid, USHORT usPid) 497 { 498 RKDEVICE_DESC_SET deviceList; 499 ENUM_RKUSB_TYPE curDeviceType; 500 ENUM_RKDEVICE_TYPE devType; 501 device_list_iter iter; 502 UINT totalDevice; 503 int uiWaitSecond; 504 int iFoundCount = 0; 505 bool bRet = false; 506 if (usbType == RKUSB_MSC) 507 uiWaitSecond = m_waitMscSecond; 508 else 509 uiWaitSecond = m_waitRKusbSecond; 510 time_t tmInit, tmNow; 511 time(&tmInit); 512 while( difftime(time(&tmNow), tmInit) <= uiWaitSecond ) { 513 FreeDeviceList(deviceList); 514 EnumerateUsbDevice(deviceList, totalDevice); 515 for ( iter = deviceList.begin(); iter != deviceList.end(); iter++ ) { 516 if ((BUSID((*iter).uiLocationID) != BUSID(device.uiLocationID)) || 517 ((BUSID((*iter).uiLocationID) == BUSID(device.uiLocationID)) && ((*iter).uiLocationID >= device.uiLocationID))) { 518 if ((usVid != 0) || (usPid != 0)) { 519 if ( ((*iter).usVid != usVid) || ((*iter).usPid != usPid) ) 520 continue; 521 } 522 if (IsRockusbDevice(devType, (*iter).usVid, (*iter).usPid)) { 523 if ( ((*iter).usbcdUsb & 0x0001) == 0 ) 524 curDeviceType = RKUSB_MASKROM; 525 else 526 curDeviceType = RKUSB_LOADER; 527 } else if ( FindConfigSetPos(m_deviceMscConfigSet, (*iter).usVid, (*iter).usPid) != -1 ) { 528 curDeviceType = RKUSB_MSC; 529 } else 530 curDeviceType = RKUSB_NONE; 531 532 if ( curDeviceType == usbType ) { 533 iFoundCount++; 534 break; 535 } 536 } 537 } 538 if ( iter == deviceList.end() ) { 539 iFoundCount = 0; 540 } 541 if ( iFoundCount >= 8 ) { 542 device.usVid = (*iter).usVid; 543 device.usPid = (*iter).usPid; 544 device.uiLocationID = (*iter).uiLocationID; 545 device.pUsbHandle= (*iter).pUsbHandle; 546 device.emUsbType = usbType; 547 device.usbcdUsb = (*iter).usbcdUsb; 548 libusb_ref_device((libusb_device *)device.pUsbHandle); 549 550 if (usbType == RKUSB_MSC) { 551 device.emDeviceType = RKNONE_DEVICE; 552 } else { 553 if (IsRockusbDevice(devType, device.usVid, device.usPid)) 554 device.emDeviceType = devType; 555 } 556 bRet = true; 557 break; 558 } 559 usleep(50000); 560 } 561 562 FreeDeviceList(deviceList); 563 return bRet; 564 } 565 int CRKScan::GetPos(UINT locationID) 566 { 567 device_list_iter iter; 568 int pos = 0; 569 bool bFound = false; 570 for (iter = m_list.begin(); iter != m_list.end(); iter++) { 571 if (locationID == (*iter).uiLocationID) { 572 bFound=true; 573 break; 574 } 575 pos++; 576 } 577 return (bFound ? pos : -1); 578 } 579 bool CRKScan::GetDevice(STRUCT_RKDEVICE_DESC &device, int pos) 580 { 581 if ( (pos < 0) || (pos >= (int)m_list.size()) ) { 582 return false; 583 } 584 device_list_iter iter; 585 for (iter = m_list.begin(); iter != m_list.end(); iter++) { 586 if (pos == 0) { 587 break; 588 } 589 pos--; 590 } 591 device.usVid = (*iter).usVid; 592 device.usPid = (*iter).usPid; 593 device.emDeviceType = (*iter).emDeviceType; 594 device.emUsbType = (*iter).emUsbType; 595 device.uiLocationID = (*iter).uiLocationID; 596 device.pUsbHandle= (*iter).pUsbHandle; 597 device.usbcdUsb = (*iter).usbcdUsb; 598 return true; 599 } 600 601 bool CRKScan::SetLogObject(CRKLog *pLog) 602 { 603 if (pLog) { 604 if (m_log) { 605 delete m_log; 606 } 607 m_log = pLog; 608 } else 609 return false; 610 return true; 611 } 612 CRKScan::~CRKScan() 613 { 614 FreeDeviceList(m_list); 615 if (m_log) { 616 delete m_log; 617 m_log = NULL; 618 } 619 } 620