1/*
2 * Originally released under the Be Sample Code License.
3 * Copyright 2000, Be Incorporated. All rights reserved.
4 *
5 * Modified for Haiku by Fran��ois Revol and Michael Lotz.
6 * Copyright 2007-2016, Haiku Inc. All rights reserved.
7 */
8
9#include <USBKit.h>
10#include <stdio.h>
11
12#include <usb/USB_cdc.h>
13
14#include "listusb.h"
15
16void
17DumpCDCDescriptor(const usb_generic_descriptor* descriptor, int subclass)
18{
19	if (descriptor->descriptor_type == 0x24) {
20		printf("                    Type ............. CDC interface descriptor\n");
21		printf("                    Subtype .......... ");
22		switch (descriptor->data[0]) {
23			case USB_CDC_HEADER_FUNCTIONAL_DESCRIPTOR:
24				printf("Header\n");
25				printf("                    CDC Version ...... %x.%x\n",
26					descriptor->data[2], descriptor->data[1]);
27				return;
28			case USB_CDC_CM_FUNCTIONAL_DESCRIPTOR:
29			{
30				printf("Call management\n");
31				const usb_cdc_cm_functional_descriptor* cmDesc
32					= (const usb_cdc_cm_functional_descriptor*)descriptor;
33				printf("                    Capabilities ..... ");
34				bool somethingPrinted = false;
35				if ((cmDesc->capabilities & USB_CDC_CM_DOES_CALL_MANAGEMENT) != 0) {
36					printf("Call management");
37					somethingPrinted = true;
38				}
39				if ((cmDesc->capabilities & USB_CDC_CM_OVER_DATA_INTERFACE) != 0) {
40					if (somethingPrinted)
41						printf(", ");
42					printf("Over data interface");
43					somethingPrinted = true;
44				}
45				if (!somethingPrinted)
46					printf("None");
47				printf("\n");
48				printf("                    Data interface ... %d\n", cmDesc->data_interface);
49				return;
50			}
51			case USB_CDC_ACM_FUNCTIONAL_DESCRIPTOR:
52			{
53				printf("Abstract control management\n");
54				const usb_cdc_acm_functional_descriptor* acmDesc
55					= (const usb_cdc_acm_functional_descriptor*)descriptor;
56				printf("                    Capabilities ..... ");
57				bool somethingPrinted = false;
58				if ((acmDesc->capabilities & USB_CDC_ACM_HAS_COMM_FEATURES) != 0) {
59					printf("Communication features");
60					somethingPrinted = true;
61				}
62				if ((acmDesc->capabilities & USB_CDC_ACM_HAS_LINE_CONTROL) != 0) {
63					if (somethingPrinted)
64						printf(", ");
65					printf("Line control");
66					somethingPrinted = true;
67				}
68				if ((acmDesc->capabilities & USB_CDC_ACM_HAS_SEND_BREAK) != 0) {
69					if (somethingPrinted)
70						printf(", ");
71					printf("Send break");
72					somethingPrinted = true;
73				}
74				if ((acmDesc->capabilities & USB_CDC_ACM_HAS_NETWORK_CONNECTION) != 0) {
75					if (somethingPrinted)
76						printf(", ");
77					printf("Network connection");
78					somethingPrinted = true;
79				}
80				if (!somethingPrinted)
81					printf("None");
82				printf("\n");
83				return;
84			}
85			case 0x03:
86				printf("Direct line management\n");
87				break;
88			case 0x04:
89				printf("Telephone ringer management\n");
90				break;
91			case 0x05:
92				printf("Telephone call and line state reporting\n");
93				break;
94			case USB_CDC_UNION_FUNCTIONAL_DESCRIPTOR:
95				printf("Union\n");
96				printf("                    Control interface  %d\n", descriptor->data[1]);
97				for (int32 i = 2; i < descriptor->length - 2; i++)
98					printf("                    Subordinate .....  %d\n", descriptor->data[i]);
99				return;
100			case 0x07:
101				printf("Country selection\n");
102				break;
103			case 0x08:
104				printf("Telephone operational mode\n");
105				break;
106			case 0x09:
107				printf("USB Terminal\n");
108				break;
109			case 0x0A:
110				printf("Network channel\n");
111				break;
112			case 0x0B:
113				printf("Protocol init\n");
114				break;
115			case 0x0C:
116				printf("Extension unit\n");
117				break;
118			case 0x0D:
119				printf("Multi-channel management\n");
120				break;
121			case 0x0E:
122				printf("CAPI control\n");
123				break;
124			case 0x0F:
125				printf("Ethernet\n");
126				break;
127			case 0x10:
128				printf("ATM\n");
129				break;
130			case 0x11:
131				printf("Wireless handset\n");
132				break;
133			case 0x12:
134				printf("Mobile direct line\n");
135				break;
136			case 0x13:
137				printf("Mobile direct line detail\n");
138				break;
139			case 0x14:
140				printf("Device management\n");
141				break;
142			case 0x15:
143				printf("Object Exchange\n");
144				break;
145			case 0x16:
146				printf("Command set\n");
147				break;
148			case 0x17:
149				printf("Command set detail\n");
150				break;
151			case 0x18:
152				printf("Telephone control\n");
153				break;
154			case 0x19:
155				printf("Object Exchange service identifier\n");
156				break;
157			case 0x1A:
158				printf("NCM\n");
159				break;
160			default:
161				printf("0x%02x\n", descriptor->data[0]);
162		}
163
164		printf("                    Data ............. ");
165		// len includes len and descriptor_type field
166		// start at i = 1 because we already dumped the first byte as subtype
167		for (int32 i = 1; i < descriptor->length - 2; i++)
168			printf("%02x ", descriptor->data[i]);
169		printf("\n");
170		return;
171	}
172
173#if 0
174	if (descriptor->descriptor_type == 0x25) {
175		printf("                    Type ............. CDC endpoint descriptor\n",
176		return;
177	}
178#endif
179
180	DumpDescriptorData(descriptor);
181}
182