xref: /rkdeveloptool/RKScan.cpp (revision 21545e35b9435781dd7621cffa02ceeca8e16d25)
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