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