View Javadoc

1   package org.minetti.astrodevice.server.usb.object;
2   
3   import java.io.Serializable;
4   import java.util.Collections;
5   import java.util.HashMap;
6   import java.util.Map;
7   import org.minetti.astrodevice.server.plugin.device.BaseDeviceSignature;
8   
9   /**
10   * Signature used for recognize the USB devices.
11   * <p>
12   * It is composed of:
13   * </p>
14   * <ul>
15   * <li>value of <code>idVendor</code>,</li>
16   * <li>value of <code>idProduct</code>,</li>
17   * <li>string indexed by <code>iManufacturer</code>,</li>
18   * <li>string indexed by <code>iProduct</code>,</li>
19   * <li>value of <code>bcdDevice</code>,</li>
20   * <li>string indexed by <code>iSerialNumber</code>,</li>
21   * <li>value of <code>bDeviceClass</code>,</li>
22   * <li>value of <code>bDeviceSubClass</code>,</li>
23   * <li>value of <code>bDeviceProtocol</code>.</li>
24   * </ul>
25   * @author Jean-Philippe MINETTI
26   */
27  public final class UsbDeviceSignature
28  		extends BaseDeviceSignature
29  		implements Serializable {
30  
31  	/**
32  	 * Serial number.
33  	 */
34  	private static final long serialVersionUID = 9204288865719875362L;
35  
36  	/**
37  	 * DESCRIPTION MAP KEY CONSTANT: Vendor ID of USB device.
38  	 * <p>
39  	 * This corresponds to <code>idVendor</code> field of USB specification (assigned by the
40  	 * USB-IF).
41  	 * </p>
42  	 * <p>
43  	 * Vendor ID must be between 0 and 65535 (0xFFFF).
44  	 * </p>
45  	 */
46  	public static final String VENDOR_ID_MAP_KEY = "idVendor";
47  
48  	/**
49  	 * DESCRIPTION MAP KEY CONSTANT: Product ID of USB device.
50  	 * <p>
51  	 * This corresponds to <code>idProduct</code> field of USB specification (assigned by the
52  	 * manufacturer).
53  	 * </p>
54  	 * <p>
55  	 * Product ID must be between 0 and 65535 (0xFFFF).
56  	 * </p>
57  	 */
58  	public static final String PRODUCT_ID_MAP_KEY = "idProduct";
59  
60  	/**
61  	 * DESCRIPTION MAP KEY CONSTANT: Manufacturer name of USB device.
62  	 * <p>
63  	 * This corresponds to string indexed by the <code>iManufacturer</code> field of USB
64  	 * specification.
65  	 * </p>
66  	 * <p>
67  	 * Manufacturer name must be less or equal than 127 characters.
68  	 * </p>
69  	 */
70  	public static final String MANUFACTURER_NAME_MAP_KEY = "manufacturer";
71  
72  	/**
73  	 * DESCRIPTION MAP KEY CONSTANT: Product name of USB device.
74  	 * <p>
75  	 * This corresponds to string indexed by the <code>iProduct</code> field of USB specification.
76  	 * </p>
77  	 * <p>
78  	 * Product description must be less or equal than 127 characters.
79  	 * </p>
80  	 */
81  	public static final String PRODUCT_NAME_MAP_KEY = "product";
82  
83  	/**
84  	 * DESCRIPTION MAP KEY CONSTANT: Product version of USB device.
85  	 * <p>
86  	 * This corresponds to <code>bcdDevice</code> field of USB specification.
87  	 * </p>
88  	 * <p>
89  	 * Product version must be between 0 and 65535 (0xFFFF).
90  	 * </p>
91  	 */
92  	public static final String PRODUCT_VERSION_MAP_KEY = "bcdDevice";
93  
94  	/**
95  	 * DESCRIPTION MAP KEY CONSTANT: Serial number of USB device.
96  	 * <p>
97  	 * This corresponds to string indexed by the <code>iSerialNumber</code> field of USB
98  	 * specification.
99  	 * </p>
100 	 * <p>
101 	 * Product description must be less or equal than 127 characters.
102 	 * </p>
103 	 */
104 	public static final String SERIAL_NUMBER_MAP_KEY = "serialNumber";
105 
106 	/**
107 	 * DESCRIPTION MAP KEY CONSTANT: Class code of USB device.
108 	 * <p>
109 	 * This corresponds to <code>bDeviceClass</code> field of USB specification (assigned by the
110 	 * USB-IF).
111 	 * </p>
112 	 * <p>
113 	 * Class code must be between 0 and 255 (0xFF).
114 	 * </p>
115 	 */
116 	public static final String DEVICE_CLASS_MAP_KEY = "bDeviceClass";
117 
118 	/**
119 	 * DESCRIPTION MAP KEY CONSTANT: Subclass code of USB device.
120 	 * <p>
121 	 * This corresponds to <code>bDeviceSubClass</code> field of USB specification (assigned by the
122 	 * USB-IF).
123 	 * </p>
124 	 * <p>
125 	 * Class code must be between 0 and 255 (0xFF).
126 	 * </p>
127 	 */
128 	public static final String DEVICE_SUB_CLASS_MAP_KEY = "bDeviceSubClass";
129 
130 	/**
131 	 * DESCRIPTION MAP KEY CONSTANT: Protocol code of USB device.
132 	 * <p>
133 	 * This corresponds to <code>bDeviceProtocol</code> field of USB specification (assigned by the
134 	 * USB-IF).
135 	 * </p>
136 	 * <p>
137 	 * Class code must be between 0 and 255 (0xFF).
138 	 * </p>
139 	 */
140 	public static final String DEVICE_PROTOCOL_MAP_KEY = "bDeviceProtocol";
141 
142 	/**
143 	 * Unique identifier identifying the device product, composed of:
144 	 * <ul>
145 	 * <li><code>idVendor</code>,</li>
146 	 * <li><code>idProduct</code>.</li>
147 	 * </ul>
148 	 */
149 	private final String productId;
150 
151 	/**
152 	 * General description of device, composed of:
153 	 * <ul>
154 	 * <li><code>iManufacturer</code>,</li>
155 	 * <li><code>iProduct</code>.</li>
156 	 * </ul>
157 	 */
158 	private final String productDescription;
159 
160 	/**
161 	 * Product version of device, composed of <code>bcdDevice</code> with the high byte as major
162 	 * version and the low byte as minor version.
163 	 */
164 	private final String productVersion;
165 
166 	/**
167 	 * Map containing all properties of the device.
168 	 */
169 	private final Map<String, Object> properties;
170 
171 	/**
172 	 * Constructor.
173 	 * @param vendorId Vendor ID of USB device (must be between 0 and 65535). This corresponds to
174 	 *            <code>idVendor</code> field of USB specification (assigned by the USB-IF).
175 	 * @param productId Product ID of USB device (must be between 0 and 65535). This corresponds to
176 	 *            <code>idProduct</code> field of USB specification (assigned by the manufacturer).
177 	 * @param manufacturerName Manufacturer name of USB device (must be less or equal than 127
178 	 *            characters). This corresponds to string indexed by the <code>iManufacturer</code>
179 	 *            field of USB specification.
180 	 * @param productName Product name of USB device (must be less or equal than 127 characters).
181 	 *            This corresponds to string indexed by the <code>iProduct</code> field of USB
182 	 *            specification.
183 	 * @param productVersion Product version of USB device (must be between 0 and 65535). This
184 	 *            corresponds to <code>bcdDevice</code> field of USB specification (assigned by the
185 	 *            manufacturer).
186 	 * @param serialNumber Serial number of USB device (must be less or equal than 127 characters).
187 	 *            This corresponds to string indexed by the <code>iSerialNumber</code> field of USB
188 	 *            specification.
189 	 * @param deviceClass Class code of USB device (must be between 0 and 255). This corresponds to
190 	 *            <code>bDeviceClass</code> field of USB specification (assigned by the USB-IF).
191 	 * @param deviceSubClass Subclass code of USB device (must be between 0 and 255). This
192 	 *            corresponds to <code>bDeviceSubClass</code> field of USB specification (assigned
193 	 *            by the USB-IF).
194 	 * @param deviceProtocol Protocol code of USB device (must be between 0 and 255). This
195 	 *            corresponds to <code>bDeviceProtocol</code> field of USB specification (assigned
196 	 *            by the USB-IF).
197 	 */
198 	public UsbDeviceSignature (final int vendorId, final int productId, final String manufacturerName, final String productName, final int productVersion,
199 			final String serialNumber, final short deviceClass, final short deviceSubClass, final short deviceProtocol) {
200 		super();
201 
202 		// productId building
203 		String desc = Integer.toHexString(productId).toUpperCase();
204 		while (desc.length() < 4) {
205 			desc = "0" + desc;
206 		}
207 		desc = Integer.toHexString(vendorId).toUpperCase() + ":" + desc;
208 		while (desc.length() < 9) {
209 			desc = "0" + desc;
210 		}
211 		this.productId = desc;
212 
213 		// productDescription building
214 		desc = productName;
215 		if (manufacturerName != null) {
216 			desc = (desc != null ? manufacturerName + " " + desc : manufacturerName);
217 		}
218 		if (desc == null) {
219 			switch (deviceClass) {
220 				case 0x01:
221 					desc = "Audio device";
222 					break;
223 				case 0x02:
224 					desc = "Communication device";
225 					break;
226 				case 0x03:
227 					desc = "HID device";
228 					break;
229 				case 0x05:
230 					desc = "Physical device";
231 					break;
232 				case 0x06:
233 					if ((deviceSubClass == 0x01) && (deviceProtocol == 0x01)) {
234 						desc = "Still imaging device";
235 					}
236 					else {
237 						desc = "Imaging device";
238 					}
239 					break;
240 				case 0x07:
241 					desc = "Printer device";
242 					break;
243 				case 0x08:
244 					desc = "Mass storage device";
245 					break;
246 				case 0x09:
247 					switch (deviceSubClass) {
248 						case 0x00:
249 							switch (deviceProtocol) {
250 								case 0x00:
251 									desc = "Full speed hub";
252 									break;
253 								case 0x01:
254 									desc = "Hi-speed hub with single TT";
255 									break;
256 								case 0x02:
257 									desc = "Hi-speed hub with multiple TTs";
258 									break;
259 								default:
260 									desc = "Hub";
261 									break;
262 							}
263 							break;
264 						default:
265 							desc = "Hub";
266 							break;
267 					}
268 					break;
269 				case 0x0A:
270 					desc = "CDC data device";
271 					break;
272 				case 0x0B:
273 					desc = "Smart card device";
274 					break;
275 				case 0x0D:
276 					desc = "Content security device";
277 					break;
278 				case 0x0E:
279 					desc = "Video device";
280 					break;
281 				case 0x0F:
282 					desc = "Personal healthcare device";
283 					break;
284 				case 0x10:
285 					switch (deviceProtocol) {
286 						case 0x00:
287 							switch (deviceSubClass) {
288 								case 0x01:
289 									desc = "Audio/video device – AVControl interface";
290 									break;
291 								case 0x02:
292 									desc = "Audio/video device – AVData video streaming interface";
293 									break;
294 								case 0x03:
295 									desc = "Audio/video device – AVData audio streaming interface";
296 									break;
297 								default:
298 									desc = "Audio/video device";
299 									break;
300 							}
301 							break;
302 						default:
303 							desc = "Audio/video device";
304 							break;
305 					}
306 					break;
307 				case 0xDC:
308 					desc = "Diagnostic device";
309 					break;
310 				case 0xE0:
311 					switch (deviceSubClass) {
312 						case 0x01:
313 							switch (deviceProtocol) {
314 								case 0x01:
315 									desc = "Bluetooth interface";
316 									break;
317 								case 0x02:
318 									desc = "UWB radio control interface";
319 									break;
320 								case 0x03:
321 									desc = "Remote NDIS";
322 									break;
323 								case 0x04:
324 									desc = "Bluetooth AMP controller";
325 									break;
326 								default:
327 									desc = "Wireless controller";
328 									break;
329 							}
330 							break;
331 						case 0x02:
332 							switch (deviceProtocol) {
333 								case 0x01:
334 									desc = "Host wire adapter control/data interface";
335 									break;
336 								case 0x02:
337 									desc = "Device wire adapter control/data interface";
338 									break;
339 								case 0x03:
340 									desc = "Device wire adapter isochronous interface";
341 									break;
342 								default:
343 									desc = "Wireless controller";
344 									break;
345 							}
346 							break;
347 						default:
348 							desc = "Wireless controller";
349 							break;
350 					}
351 					break;
352 				case 0xEF:
353 					switch (deviceSubClass) {
354 						case 0x01:
355 							switch (deviceProtocol) {
356 								case 0x01:
357 									desc = "Active sync device";
358 									break;
359 								case 0x02:
360 									desc = "Palm sync";
361 									break;
362 							}
363 							break;
364 						case 0x02:
365 							switch (deviceProtocol) {
366 								case 0x01:
367 									desc = "Interface association descriptor";
368 									break;
369 								case 0x02:
370 									desc = "Wire adapter multifunction peripheral programming interface";
371 									break;
372 							}
373 							break;
374 						case 0x03:
375 							switch (deviceProtocol) {
376 								case 0x01:
377 									desc = "Cable based association framework";
378 									break;
379 							}
380 							break;
381 					}
382 					break;
383 				case 0xFE:
384 					switch (deviceSubClass) {
385 						case 0x01:
386 							switch (deviceProtocol) {
387 								case 0x01:
388 									desc = "Device firmware upgrade";
389 									break;
390 							}
391 							break;
392 						case 0x02:
393 							switch (deviceProtocol) {
394 								case 0x00:
395 									desc = "IRDA bridge device";
396 									break;
397 							}
398 							break;
399 						case 0x03:
400 							switch (deviceProtocol) {
401 								case 0x00:
402 									desc = "USB test and measurement device";
403 									break;
404 								case 0x01:
405 									desc = "USB test and measurement device conforming to the USBTMC USB488 subclass specification";
406 									break;
407 							}
408 							break;
409 					}
410 					break;
411 			}
412 		}
413 		if (desc == null) {
414 			desc = this.productId;
415 		}
416 		this.productDescription = desc;
417 
418 		// productVersion building
419 		desc = Integer.toHexString(productVersion % 256).toUpperCase();
420 		while (desc.length() < 2) {
421 			desc = "0" + desc;
422 		}
423 		desc = Integer.toHexString(productVersion / 256).toUpperCase() + "." + desc;
424 		this.productVersion = desc;
425 
426 		// properties building
427 		final Map<String, Object> map = new HashMap<String, Object>();
428 		map.put(UsbDeviceSignature.VENDOR_ID_MAP_KEY, new Integer(vendorId));
429 		map.put(UsbDeviceSignature.PRODUCT_ID_MAP_KEY, new Integer(productId));
430 		if (manufacturerName != null) {
431 			map.put(UsbDeviceSignature.MANUFACTURER_NAME_MAP_KEY, manufacturerName);
432 		}
433 		if (productName != null) {
434 			map.put(UsbDeviceSignature.PRODUCT_NAME_MAP_KEY, productName);
435 		}
436 		map.put(UsbDeviceSignature.PRODUCT_VERSION_MAP_KEY, new Integer(productVersion));
437 		if (serialNumber != null) {
438 			map.put(UsbDeviceSignature.SERIAL_NUMBER_MAP_KEY, serialNumber);
439 		}
440 		if ((deviceClass != 0) && (deviceSubClass != 0) && (deviceProtocol != 0)) {
441 			map.put(UsbDeviceSignature.DEVICE_CLASS_MAP_KEY, new Short(deviceClass));
442 			map.put(UsbDeviceSignature.DEVICE_SUB_CLASS_MAP_KEY, new Short(deviceSubClass));
443 			map.put(UsbDeviceSignature.DEVICE_PROTOCOL_MAP_KEY, new Short(deviceProtocol));
444 		}
445 		this.properties = Collections.unmodifiableMap(map);
446 
447 	}
448 
449 	/*
450 	 * (non-Javadoc)
451 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getBus()
452 	 */
453 	public String getBus () {
454 		return "USB";
455 	}
456 
457 	/*
458 	 * (non-Javadoc)
459 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getProductId()
460 	 */
461 	public String getProductId () {
462 		return this.productId;
463 	}
464 
465 	/*
466 	 * (non-Javadoc)
467 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getProductDescription()
468 	 */
469 	public String getProductDescription () {
470 		return this.productDescription;
471 	}
472 
473 	/*
474 	 * (non-Javadoc)
475 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getProductVersion()
476 	 */
477 	public String getProductVersion () {
478 		return this.productVersion;
479 	}
480 
481 	/*
482 	 * (non-Javadoc)
483 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getSerialNumber()
484 	 */
485 	public String getSerialNumber () {
486 		return (String) this.properties.get(UsbDeviceSignature.SERIAL_NUMBER_MAP_KEY);
487 	}
488 
489 	/*
490 	 * (non-Javadoc)
491 	 * @see org.minetti.astrodevice.common.device.DeviceSignature#getProperties()
492 	 */
493 	public Map<String, Object> getProperties () {
494 		return this.properties;
495 	}
496 
497 }