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)
GetDEVICE_COUNTS()10 int CRKScan::GetDEVICE_COUNTS()
11 {
12 return m_list.size();
13 }
14
GetMSC_TIMEOUT()15 UINT CRKScan::GetMSC_TIMEOUT()
16 {
17 return m_waitMscSecond;
18 }
19
GetRKUSB_TIMEOUT()20 UINT CRKScan::GetRKUSB_TIMEOUT()
21 {
22 return m_waitRKusbSecond;
23 }
24
SetMSC_TIMEOUT(UINT value)25 void CRKScan::SetMSC_TIMEOUT(UINT value)
26 {
27 m_waitMscSecond = value;
28 }
29
SetRKUSB_TIMEOUT(UINT value)30 void CRKScan::SetRKUSB_TIMEOUT(UINT value)
31 {
32 m_waitRKusbSecond = value;
33 }
34
CRKScan(UINT uiMscTimeout,UINT uiRKusbTimeout)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 }
FindRockusbVidPid(ENUM_RKDEVICE_TYPE type,USHORT & usVid,USHORT & usPid)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 }
AddRockusbVidPid(USHORT newVid,USHORT newPid,USHORT oldVid,USHORT oldPid)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
SetVidPid(USHORT mscVid,USHORT mscPid)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 }
FindWaitSetPos(const RKDEVICE_CONFIG_SET & waitDeviceSet,USHORT vid,USHORT pid)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 }
FindConfigSetPos(RKDEVICE_CONFIG_SET & devConfigSet,USHORT vid,USHORT pid)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 }
EnumerateUsbDevice(RKDEVICE_DESC_SET & list,UINT & uiTotalMatchDevices)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
FreeDeviceList(RKDEVICE_DESC_SET & list)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 }
IsRockusbDevice(ENUM_RKDEVICE_TYPE & type,USHORT vid,USHORT pid)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 }
Search(UINT type)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 }
MutexWait(UINT_VECTOR & vecExistedDevice,STRUCT_RKDEVICE_DESC & device,ENUM_RKUSB_TYPE usbType,USHORT usVid,USHORT usPid)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
MutexWaitPrepare(UINT_VECTOR & vecExistedDevice,DWORD uiOfflineDevice)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
Wait(STRUCT_RKDEVICE_DESC & device,ENUM_RKUSB_TYPE usbType,USHORT usVid,USHORT usPid)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 }
GetPos(UINT locationID)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 }
GetDevice(STRUCT_RKDEVICE_DESC & device,int pos)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
SetLogObject(CRKLog * pLog)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 }
~CRKScan()612 CRKScan::~CRKScan()
613 {
614 FreeDeviceList(m_list);
615 if (m_log) {
616 delete m_log;
617 m_log = NULL;
618 }
619 }
620