• 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_USBFFS_H
16 #define HDC_USBFFS_H
17 // clang-format off
18 #include <linux/usb/functionfs.h>
19 #include "daemon_common.h"
20 // clang-format on
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 
41 #define SHORT_LE(x) htole16(x)
42 #define LONG_LE(x) htole32(x)
43 #define HDC_INTERFACE_NAME "HDC Interface"
44 
45 struct UsbFunctionDesc {
46     struct usb_interface_descriptor ifDesc;
47     struct usb_endpoint_descriptor_no_audio from;
48     struct usb_endpoint_descriptor_no_audio to;
49 } __attribute__((packed));
50 
51 static const struct {
52     struct usb_functionfs_strings_head head;
53     struct {
54         __le16 code;
55         const char name[sizeof(HDC_INTERFACE_NAME)];
56     } __attribute__((packed)) firstItem;
57 } __attribute__((packed)) USB_FFS_VALUE = {
58     .head =
59         {
60             .magic = LONG_LE(FUNCTIONFS_STRINGS_MAGIC),
61             .length = LONG_LE(sizeof(USB_FFS_VALUE)),
62             .str_count = LONG_LE(1),
63             .lang_count = LONG_LE(1),
64         },
65     .firstItem =
66         {
67             SHORT_LE(0x0409),
68             HDC_INTERFACE_NAME,
69         },
70 };
71 
72 struct UsbFunctionfsDescsHeadOld {
73     __le32 magic;
74     __le32 length;
75     __le32 config1Count;
76     __le32 config2Count;
77 } __attribute__((packed));
78 
79 struct UsbFuncConfig {
80     struct usb_interface_descriptor ifDesc;
81     struct usb_endpoint_descriptor_no_audio from;
82     struct usb_ss_ep_comp_descriptor pairFrom;
83     struct usb_endpoint_descriptor_no_audio to;
84     struct usb_ss_ep_comp_descriptor pairTo;
85 } __attribute__((packed));
86 
87 static struct UsbFuncConfig config3 = {
88     .ifDesc = {
89         .bLength = sizeof(config3.ifDesc),
90         .bDescriptorType = USB_DT_INTERFACE,
91         .bInterfaceNumber = 0,
92         .bNumEndpoints = 2,
93         .bInterfaceClass = HDC_CLASS,
94         .bInterfaceSubClass = HDC_SUBCLASS,
95         .bInterfaceProtocol = VER_PROTOCOL,
96         .iInterface = 1
97     },
98     .from = {
99         .bLength = sizeof(config3.from),
100         .bDescriptorType = USB_DT_ENDPOINT,
101         .bEndpointAddress = 1 | USB_DIR_OUT,
102         .bmAttributes = USB_ENDPOINT_XFER_BULK,
103         .wMaxPacketSize = HDC_SSPKT_SIZE_MAX,
104     },
105     .pairFrom = {
106         .bLength = sizeof(config3.pairFrom),
107         .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
108         .bMaxBurst = 4,
109     },
110     .to = {
111         .bLength = sizeof(config3.to),
112         .bDescriptorType = USB_DT_ENDPOINT,
113         .bEndpointAddress = 2 | USB_DIR_IN,
114         .bmAttributes = USB_ENDPOINT_XFER_BULK,
115         .wMaxPacketSize = HDC_SSPKT_SIZE_MAX,
116     },
117     .pairTo = {
118         .bLength = sizeof(config3.pairTo),
119         .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
120         .bMaxBurst = 4,
121     },
122 };
123 
124 static struct UsbFunctionDesc config1 = {
125     .ifDesc = {
126         .bLength = sizeof(config1.ifDesc),
127         .bDescriptorType = USB_DT_INTERFACE,
128         .bInterfaceNumber = 0,
129         .bNumEndpoints = 2,
130         .bInterfaceClass = HDC_CLASS,
131         .bInterfaceSubClass = HDC_SUBCLASS,
132         .bInterfaceProtocol = VER_PROTOCOL,
133         .iInterface = 1
134     },
135     .from = {
136         .bLength = sizeof(config1.from),
137         .bDescriptorType = USB_DT_ENDPOINT,
138         .bEndpointAddress = 1 | USB_DIR_OUT,
139         .bmAttributes = USB_ENDPOINT_XFER_BULK,
140         .wMaxPacketSize = HDC_FSPKT_SIZE_MAX,
141     },
142     .to = {
143         .bLength = sizeof(config1.to),
144         .bDescriptorType = USB_DT_ENDPOINT,
145         .bEndpointAddress = 2 | USB_DIR_IN,
146         .bmAttributes = USB_ENDPOINT_XFER_BULK,
147         .wMaxPacketSize = HDC_FSPKT_SIZE_MAX,
148     },
149 };
150 
151 static struct UsbFunctionDesc config2 = {
152     .ifDesc = {
153         .bLength = sizeof(config2.ifDesc),
154         .bDescriptorType = USB_DT_INTERFACE,
155         .bInterfaceNumber = 0,
156         .bNumEndpoints = 2,
157         .bInterfaceClass = HDC_CLASS,
158         .bInterfaceSubClass = HDC_SUBCLASS,
159         .bInterfaceProtocol = VER_PROTOCOL,
160         .iInterface = 1
161     },
162     .from = {
163         .bLength = sizeof(config2.from),
164         .bDescriptorType = USB_DT_ENDPOINT,
165         .bEndpointAddress = 1 | USB_DIR_OUT,
166         .bmAttributes = USB_ENDPOINT_XFER_BULK,
167         .wMaxPacketSize = HDC_HSPKT_SIZE_MAX,
168     },
169     .to = {
170         .bLength = sizeof(config2.to),
171         .bDescriptorType = USB_DT_ENDPOINT,
172         .bEndpointAddress = 2 | USB_DIR_IN,
173         .bmAttributes = USB_ENDPOINT_XFER_BULK,
174         .wMaxPacketSize = HDC_HSPKT_SIZE_MAX,
175     },
176 };
177 
178 template <size_t PropertyNameLength, size_t PropertyDataLength>
179 struct UsbOsDescExtProp {
180     uint32_t size = sizeof(*this);
181     uint32_t propertyDataTypen = LONG_LE(1);
182     uint16_t propertyNameLength = SHORT_LE(PropertyNameLength);
183     char propertyName [PropertyNameLength];
184     uint32_t propertyDataLength = LONG_LE(PropertyDataLength);
185     char property [PropertyDataLength];
186 } __attribute__((packed));
187 
188 using UsbOsDescGuid = UsbOsDescExtProp<PROPERTY_NAME_LENGTH, PROPERTY_DATA_LENGTH>;
189 UsbOsDescGuid osDescGuid = {
190     .propertyName = "DeviceInterfaceGUID",
191     .property = "{f21cc96b-063d-52e1-e3fd-f39cc7a34c40}",
192 };
193 
194 struct UsbExtPropValues {
195     UsbOsDescGuid guid;
196 } __attribute__((packed));
197 
198 UsbExtPropValues g_osPropValues = {
199     .guid = osDescGuid,
200 };
201 
202 struct usb_ext_compat_desc g_wosDesc = {
203     .bFirstInterfaceNumber = 0,
204     .Reserved1 = LONG_LE(1),
205     .CompatibleID = {'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'},
206     .SubCompatibleID = { 0 },
207     .Reserved2 = { 0 },
208 };
209 
210 struct usb_os_desc_header g_wosHead = {
211     .interface = LONG_LE(0),
212     .dwLength = LONG_LE(sizeof(g_wosHead) + sizeof(g_wosDesc)),
213     .bcdVersion = LONG_LE(1),
214     .wIndex = LONG_LE(4),
215     .bCount = LONG_LE(1),
216     .Reserved = LONG_LE(0),
217 };
218 
219 struct usb_os_desc_header g_osPropHead = {
220     .interface = LONG_LE(0),
221     .dwLength = LONG_LE(sizeof(g_wosHead) + sizeof(g_osPropValues)),
222     .bcdVersion = LONG_LE(1),
223     .wIndex = LONG_LE(5),
224     .wCount = SHORT_LE(1),
225 };
226 
227 struct usb_functionfs_desc_v2 {
228     struct usb_functionfs_descs_head_v2 head;
229     __le32 config1Count;
230     __le32 config2Count;
231     __le32 config3Count;
232     __le32 configWosCount;
233     struct UsbFunctionDesc config1Desc, config2Desc;
234     struct UsbFuncConfig config3Desc;
235     struct usb_os_desc_header wosHead;
236     struct usb_ext_compat_desc wosDesc;
237     struct usb_os_desc_header osPropHead;
238     struct UsbExtPropValues osPropValues;
239 } __attribute__((packed));
240 
241 }  // namespace Hdc
242 #endif
243