1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MTP_DESCRIPTORS_H
18 #define MTP_DESCRIPTORS_H
19 
20 #include <linux/usb/ch9.h>
21 #include <linux/usb/functionfs.h>
22 #include <sys/endian.h>
23 
24 namespace android {
25 
26 constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
27 constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
28 constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
29 constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
30 
31 constexpr char FFS_PTP_EP0[] = "/dev/usb-ffs/ptp/ep0";
32 constexpr char FFS_PTP_EP_IN[] = "/dev/usb-ffs/ptp/ep1";
33 constexpr char FFS_PTP_EP_OUT[] = "/dev/usb-ffs/ptp/ep2";
34 constexpr char FFS_PTP_EP_INTR[] = "/dev/usb-ffs/ptp/ep3";
35 
36 constexpr int MAX_PACKET_SIZE_FS = 64;
37 constexpr int MAX_PACKET_SIZE_HS = 512;
38 constexpr int MAX_PACKET_SIZE_SS = 1024;
39 constexpr int MAX_PACKET_SIZE_EV = 28;
40 
41 struct func_desc {
42     struct usb_interface_descriptor intf;
43     struct usb_endpoint_descriptor_no_audio sink;
44     struct usb_endpoint_descriptor_no_audio source;
45     struct usb_endpoint_descriptor_no_audio intr;
46 } __attribute__((packed));
47 
48 struct ss_func_desc {
49     struct usb_interface_descriptor intf;
50     struct usb_endpoint_descriptor_no_audio sink;
51     struct usb_ss_ep_comp_descriptor sink_comp;
52     struct usb_endpoint_descriptor_no_audio source;
53     struct usb_ss_ep_comp_descriptor source_comp;
54     struct usb_endpoint_descriptor_no_audio intr;
55     struct usb_ss_ep_comp_descriptor intr_comp;
56 } __attribute__((packed));
57 
58 struct desc_v1 {
59     struct usb_functionfs_descs_head_v1 {
60         __le32 magic;
61         __le32 length;
62         __le32 fs_count;
63         __le32 hs_count;
64     } __attribute__((packed)) header;
65     struct func_desc fs_descs, hs_descs;
66 } __attribute__((packed));
67 
68 struct desc_v2 {
69     struct usb_functionfs_descs_head_v2 header;
70     // The rest of the structure depends on the flags in the header.
71     __le32 fs_count;
72     __le32 hs_count;
73     __le32 ss_count;
74     __le32 os_count;
75     struct func_desc fs_descs, hs_descs;
76     struct ss_func_desc ss_descs;
77     struct usb_os_desc_header os_header;
78     struct usb_ext_compat_desc os_desc;
79 } __attribute__((packed));
80 
81 // OS descriptor contents should not be changed. See b/64790536.
82 static_assert(sizeof(struct desc_v2) == sizeof(usb_functionfs_descs_head_v2) +
83         16 + 2 * sizeof(struct func_desc) + sizeof(struct ss_func_desc) +
84         sizeof(usb_os_desc_header) + sizeof(usb_ext_compat_desc),
85         "Size of mtp descriptor is incorrect!");
86 
87 #define STR_INTERFACE "MTP"
88 struct functionfs_lang {
89     __le16 code;
90     char str1[sizeof(STR_INTERFACE)];
91 } __attribute__((packed));
92 
93 struct functionfs_strings {
94     struct usb_functionfs_strings_head header;
95     struct functionfs_lang lang0;
96 } __attribute__((packed));
97 
98 extern const struct desc_v2 mtp_desc_v2;
99 extern const struct desc_v2 ptp_desc_v2;
100 extern const struct desc_v1 mtp_desc_v1;
101 extern const struct desc_v1 ptp_desc_v1;
102 extern const struct functionfs_strings mtp_strings;
103 
104 bool writeDescriptors(int fd, bool ptp);
105 
106 }; // namespace android
107 
108 #endif // MTP_DESCRIPTORS_H
109