• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef HDC_USBFFS2_H
16 #define HDC_USBFFS2_H
17 // clang-format off
18 #include <linux/usb/functionfs.h>
19 // clang-format on
20 #include <endian.h>
21 
22 namespace Hdc {
23 constexpr auto HDC_USBDR_SND = 0x0;
24 constexpr auto HDC_USBDR_RCV = 0x80;
25 constexpr auto HDC_USBMD_BLK = 0X02;
26 constexpr auto HDC_USBMD_RCV = 0X03;
27 constexpr auto HDC_CLASS = 0xff;
28 constexpr auto HDC_SUBCLASS = 0x50;
29 constexpr auto HDC_FSPKT_SIZE_MAX = 64;
30 constexpr auto HDC_HSPKT_SIZE_MAX = 512;
31 constexpr uint16_t HDC_SSPKT_SIZE_MAX = 1024;
32 constexpr auto USB_FFS_BASE = "/dev/usb-ffs/";
33 constexpr auto HDC_USBTF_DEV = 0x01;
34 constexpr auto HDC_USBTF_CFG = 0x02;
35 constexpr auto HDC_USBTF_STR = 0x03;
36 constexpr auto HDC_USBTF_ITF = 0x04;
37 constexpr auto HDC_USBTF_EPS = 0x05;
38 constexpr auto PROPERTY_NAME_LENGTH = 20;
39 constexpr auto PROPERTY_DATA_LENGTH = 39;
40 constexpr uint16_t VER_PROTOCOL = 0x01;
41 
42 #define SHORT_LE(x) htole16(x)
43 #define LONG_LE(x) htole32(x)
44 #define HDC_INTERFACE_NAME "HDC Interface"
45 
46 struct UsbFunctionDesc {
47     struct usb_interface_descriptor ifDesc;
48     struct usb_endpoint_descriptor_no_audio from;
49     struct usb_endpoint_descriptor_no_audio to;
50 } __attribute__((packed));
51 
52 static const struct {
53     struct usb_functionfs_strings_head head;
54     struct {
55         __le16 code;
56         const char name[sizeof(HDC_INTERFACE_NAME)];
57     } __attribute__((packed)) firstItem;
58 } __attribute__((packed)) USB_FFS_VALUE = {
59     .head =
60         {
61             .magic = LONG_LE(FUNCTIONFS_STRINGS_MAGIC),
62             .length = LONG_LE(sizeof(USB_FFS_VALUE)),
63             .str_count = LONG_LE(1),
64             .lang_count = LONG_LE(1),
65         },
66     .firstItem =
67         {
68             SHORT_LE(0x0409),
69             HDC_INTERFACE_NAME,
70         },
71 };
72 
73 struct UsbFunctionfsDescsHeadOld {
74     __le32 magic;
75     __le32 length;
76     __le32 config1Count;
77     __le32 config2Count;
78 } __attribute__((packed));
79 
80 struct UsbFuncConfig {
81     struct usb_interface_descriptor ifDesc;
82     struct usb_endpoint_descriptor_no_audio from;
83     struct usb_ss_ep_comp_descriptor pairFrom;
84     struct usb_endpoint_descriptor_no_audio to;
85     struct usb_ss_ep_comp_descriptor pairTo;
86 } __attribute__((packed));
87 
88 static struct UsbFuncConfig config3 = {
89     .ifDesc = {
90         .bLength = sizeof(config3.ifDesc),
91         .bDescriptorType = USB_DT_INTERFACE,
92         .bInterfaceNumber = 0,
93         .bNumEndpoints = 2,
94         .bInterfaceClass = HDC_CLASS,
95         .bInterfaceSubClass = HDC_SUBCLASS,
96         .bInterfaceProtocol = VER_PROTOCOL,
97         .iInterface = 1
98     },
99     .from = {
100         .bLength = sizeof(config3.from),
101         .bDescriptorType = USB_DT_ENDPOINT,
102         .bEndpointAddress = 1 | USB_DIR_OUT,
103         .bmAttributes = USB_ENDPOINT_XFER_BULK,
104         .wMaxPacketSize = HDC_SSPKT_SIZE_MAX,
105     },
106     .pairFrom = {
107         .bLength = sizeof(config3.pairFrom),
108         .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
109         .bMaxBurst = 4,
110     },
111     .to = {
112         .bLength = sizeof(config3.to),
113         .bDescriptorType = USB_DT_ENDPOINT,
114         .bEndpointAddress = 2 | USB_DIR_IN,
115         .bmAttributes = USB_ENDPOINT_XFER_BULK,
116         .wMaxPacketSize = HDC_SSPKT_SIZE_MAX,
117     },
118     .pairTo = {
119         .bLength = sizeof(config3.pairTo),
120         .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
121         .bMaxBurst = 4,
122     },
123 };
124 
125 static struct UsbFunctionDesc config1 = {
126     .ifDesc = {
127         .bLength = sizeof(config1.ifDesc),
128         .bDescriptorType = USB_DT_INTERFACE,
129         .bInterfaceNumber = 0,
130         .bNumEndpoints = 2,
131         .bInterfaceClass = HDC_CLASS,
132         .bInterfaceSubClass = HDC_SUBCLASS,
133         .bInterfaceProtocol = VER_PROTOCOL,
134         .iInterface = 1
135     },
136     .from = {
137         .bLength = sizeof(config1.from),
138         .bDescriptorType = USB_DT_ENDPOINT,
139         .bEndpointAddress = 1 | USB_DIR_OUT,
140         .bmAttributes = USB_ENDPOINT_XFER_BULK,
141         .wMaxPacketSize = HDC_FSPKT_SIZE_MAX,
142     },
143     .to = {
144         .bLength = sizeof(config1.to),
145         .bDescriptorType = USB_DT_ENDPOINT,
146         .bEndpointAddress = 2 | USB_DIR_IN,
147         .bmAttributes = USB_ENDPOINT_XFER_BULK,
148         .wMaxPacketSize = HDC_FSPKT_SIZE_MAX,
149     },
150 };
151 
152 static struct UsbFunctionDesc config2 = {
153     .ifDesc = {
154         .bLength = sizeof(config2.ifDesc),
155         .bDescriptorType = USB_DT_INTERFACE,
156         .bInterfaceNumber = 0,
157         .bNumEndpoints = 2,
158         .bInterfaceClass = HDC_CLASS,
159         .bInterfaceSubClass = HDC_SUBCLASS,
160         .bInterfaceProtocol = VER_PROTOCOL,
161         .iInterface = 1
162     },
163     .from = {
164         .bLength = sizeof(config2.from),
165         .bDescriptorType = USB_DT_ENDPOINT,
166         .bEndpointAddress = 1 | USB_DIR_OUT,
167         .bmAttributes = USB_ENDPOINT_XFER_BULK,
168         .wMaxPacketSize = HDC_HSPKT_SIZE_MAX,
169     },
170     .to = {
171         .bLength = sizeof(config2.to),
172         .bDescriptorType = USB_DT_ENDPOINT,
173         .bEndpointAddress = 2 | USB_DIR_IN,
174         .bmAttributes = USB_ENDPOINT_XFER_BULK,
175         .wMaxPacketSize = HDC_HSPKT_SIZE_MAX,
176     },
177 };
178 
179 template <size_t PropertyNameLength, size_t PropertyDataLength>
180 struct UsbOsDescExtProp {
181     uint32_t size = sizeof(*this);
182     uint32_t propertyDataTypen = LONG_LE(1);
183     uint16_t propertyNameLength = SHORT_LE(PropertyNameLength);
184     char propertyName [PropertyNameLength];
185     uint32_t propertyDataLength = LONG_LE(PropertyDataLength);
186     char property [PropertyDataLength];
187 } __attribute__((packed));
188 
189 using UsbOsDescGuid = UsbOsDescExtProp<PROPERTY_NAME_LENGTH, PROPERTY_DATA_LENGTH>;
190 static UsbOsDescGuid g_osDescGuid = {
191     .propertyName = "DeviceInterfaceGUID",
192     .property = "{f21cc96b-063d-52e1-e3fd-f39cc7a34c40}",
193 };
194 
195 struct UsbExtPropValues {
196     UsbOsDescGuid guid;
197 } __attribute__((packed));
198 
199 static UsbExtPropValues g_osPropValues = {
200     .guid = g_osDescGuid,
201 };
202 
203 static struct usb_ext_compat_desc g_wosDesc = {
204     .bFirstInterfaceNumber = 0,
205     .Reserved1 = LONG_LE(1),
206     .CompatibleID = {'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'},
207     .SubCompatibleID = { 0 },
208     .Reserved2 = { 0 },
209 };
210 
211 static struct usb_os_desc_header g_wosHead = {
212     .interface = LONG_LE(0),
213     .dwLength = LONG_LE(sizeof(g_wosHead) + sizeof(g_wosDesc)),
214     .bcdVersion = LONG_LE(1),
215     .wIndex = LONG_LE(4),
216     {
217         {
218             .bCount = LONG_LE(1),
219             .Reserved = LONG_LE(0),
220         }
221     },
222 };
223 
224 static struct usb_os_desc_header g_osPropHead = {
225     .interface = LONG_LE(0),
226     .dwLength = LONG_LE(sizeof(g_wosHead) + sizeof(g_osPropValues)),
227     .bcdVersion = LONG_LE(1),
228     .wIndex = LONG_LE(5),
229     .wCount = SHORT_LE(1),
230 };
231 
232 
233 struct UsbFunctionfsDescV2 {
234     struct usb_functionfs_descs_head_v2 head;
235     __le32 config1Count;
236     __le32 config2Count;
237     __le32 config3Count;
238     __le32 configWosCount;
239     struct UsbFunctionDesc config1Desc, config2Desc;
240     struct UsbFuncConfig config3Desc;
241     struct usb_os_desc_header wosHead;
242     struct usb_ext_compat_desc wosDesc;
243     struct usb_os_desc_header osPropHead;
244     struct UsbExtPropValues osPropValues;
245 } __attribute__((packed));
246 
247 }  // namespace Hdc
248 #endif
249