1b5eaa809da69865cbde156007ae5363f9209f932Paul McLean/*
2b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * Copyright (C) 2017 The Android Open Source Project
3b5eaa809da69865cbde156007ae5363f9209f932Paul McLean *
4b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * Licensed under the Apache License, Version 2.0 (the "License");
5b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * you may not use this file except in compliance with the License.
6b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * You may obtain a copy of the License at
7b5eaa809da69865cbde156007ae5363f9209f932Paul McLean *
8b5eaa809da69865cbde156007ae5363f9209f932Paul McLean *      http://www.apache.org/licenses/LICENSE-2.0
9b5eaa809da69865cbde156007ae5363f9209f932Paul McLean *
10b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * Unless required by applicable law or agreed to in writing, software
11b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * distributed under the License is distributed on an "AS IS" BASIS,
12b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * See the License for the specific language governing permissions and
14b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * limitations under the License.
15b5eaa809da69865cbde156007ae5363f9209f932Paul McLean */
16b5eaa809da69865cbde156007ae5363f9209f932Paul McLeanpackage com.android.server.usb.descriptors;
17b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
18fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLeanimport com.android.server.usb.descriptors.report.ReportCanvas;
19fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
20b5eaa809da69865cbde156007ae5363f9209f932Paul McLean/**
21b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * @hide
22b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * A Usb Endpoint Descriptor.
23b5eaa809da69865cbde156007ae5363f9209f932Paul McLean * see usb11.pdf section 9.6.4
24b5eaa809da69865cbde156007ae5363f9209f932Paul McLean */
25b5eaa809da69865cbde156007ae5363f9209f932Paul McLeanpublic class UsbEndpointDescriptor extends UsbDescriptor {
26fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    private static final String TAG = "UsbEndpointDescriptor";
27b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
28fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte MASK_ENDPOINT_ADDRESS = 0b0001111;
29fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte MASK_ENDPOINT_DIRECTION = (byte) 0b10000000;
30fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte DIRECTION_OUTPUT = 0x00;
31fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte DIRECTION_INPUT = (byte) 0x80;
32b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
33b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public static final byte MASK_ATTRIBS_TRANSTYPE = 0b00000011;
34fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte TRANSTYPE_CONTROL = 0x00;
35fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte TRANSTYPE_ISO = 0x01;
36fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte TRANSTYPE_BULK = 0x02;
37fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte TRANSTYPE_INTERRUPT = 0x03;
38fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
39fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte MASK_ATTRIBS_SYNCTYPE = 0b00001100;
40fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte SYNCTYPE_NONE = 0b00000000;
41fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte SYNCTYPE_ASYNC = 0b00000100;
42fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte SYNCTYPE_ADAPTSYNC = 0b00001000;
43fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte SYNCTYPE_RESERVED = 0b00001100;
44fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
45fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte MASK_ATTRIBS_USEAGE = 0b00110000;
46fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte USEAGE_DATA = 0b00000000;
47fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte USEAGE_FEEDBACK = 0b00010000;
48fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte USEAGE_EXPLICIT = 0b00100000;
49fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public static final byte USEAGE_RESERVED = 0b00110000;
50b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
51b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private byte mEndpointAddress;  // 2:1 Endpoint Address
52b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                    // Bits 0..3b Endpoint Number.
53b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                    // Bits 4..6b Reserved. Set to Zero
54b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                    // Bits 7 Direction 0 = Out, 1 = In
55b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                    // (Ignored for Control Endpoints)
56b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private byte mAttributes;   // 3:1 Various flags
57b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // Bits 0..1 Transfer Type:
58b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //     00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
59b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // Bits 2..7 are reserved. If Isochronous endpoint,
60b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // Bits 3..2 = Synchronisation Type (Iso Mode)
61b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  00 = No Synchonisation
62b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  01 = Asynchronous
63b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  10 = Adaptive
64b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  11 = Synchronous
65b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // Bits 5..4 = Usage Type (Iso Mode)
66b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  00: Data Endpoint
67b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  01:Feedback Endpoint 10
68b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  Explicit Feedback Data Endpoint
69b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                //  11: Reserved
70b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private int mPacketSize;    // 4:2 Maximum Packet Size this endpoint is capable of
71b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // sending or receiving
72b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private byte mInterval;     // 6:1 Interval for polling endpoint data transfers. Value in
73b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // frame counts.
74b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // Ignored for Bulk & Control Endpoints. Isochronous must equal
75b5eaa809da69865cbde156007ae5363f9209f932Paul McLean                                // 1 and field may range from 1 to 255 for interrupt endpoints.
76b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private byte mRefresh;
77b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    private byte mSyncAddress;
78b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
79b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public UsbEndpointDescriptor(int length, byte type) {
80b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        super(length, type);
81fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        mHierarchyLevel = 4;
82b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
83b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
84b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public byte getEndpointAddress() {
85b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mEndpointAddress;
86b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
87b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
88b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public byte getAttributes() {
89b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mAttributes;
90b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
91b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
92b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public int getPacketSize() {
93b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mPacketSize;
94b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
95b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
96b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public byte getInterval() {
97b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mInterval;
98b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
99b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
100b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public byte getRefresh() {
101b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mRefresh;
102b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
103b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
104b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public byte getSyncAddress() {
105b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mSyncAddress;
106b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
107b5eaa809da69865cbde156007ae5363f9209f932Paul McLean
108b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    @Override
109b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    public int parseRawDescriptors(ByteStream stream) {
110b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        mEndpointAddress = stream.getByte();
111b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        mAttributes = stream.getByte();
112fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        mPacketSize = stream.unpackUsbShort();
113b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        mInterval = stream.getByte();
114b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        if (mLength == 9) {
115b5eaa809da69865cbde156007ae5363f9209f932Paul McLean            mRefresh = stream.getByte();
116b5eaa809da69865cbde156007ae5363f9209f932Paul McLean            mSyncAddress = stream.getByte();
117b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        }
118b5eaa809da69865cbde156007ae5363f9209f932Paul McLean        return mLength;
119b5eaa809da69865cbde156007ae5363f9209f932Paul McLean    }
120fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
121fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    @Override
122fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    public void report(ReportCanvas canvas) {
123fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        super.report(canvas);
124fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
125fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.openList();
126fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
127fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        byte address = getEndpointAddress();
128fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.writeListItem("Address: "
129fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                + ReportCanvas.getHexString(address & UsbEndpointDescriptor.MASK_ENDPOINT_ADDRESS)
130fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                + ((address & UsbEndpointDescriptor.MASK_ENDPOINT_DIRECTION)
131fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                == UsbEndpointDescriptor.DIRECTION_OUTPUT ? " [out]" : " [in]"));
132fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
133fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        byte attributes = getAttributes();
134fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.openListItem();
135fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.write("Attributes: " + ReportCanvas.getHexString(attributes) + " ");
136fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE) {
137fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            case UsbEndpointDescriptor.TRANSTYPE_CONTROL:
138fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                canvas.write("Control");
139fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                break;
140fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            case UsbEndpointDescriptor.TRANSTYPE_ISO:
141fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                canvas.write("Iso");
142fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                break;
143fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            case UsbEndpointDescriptor.TRANSTYPE_BULK:
144fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                canvas.write("Bulk");
145fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                break;
146fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            case UsbEndpointDescriptor.TRANSTYPE_INTERRUPT:
147fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                canvas.write("Interrupt");
148fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                break;
149fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        }
150fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.closeListItem();
151fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
152fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        // These flags are only relevant for ISO transfer type
153fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        if ((attributes & UsbEndpointDescriptor.MASK_ATTRIBS_TRANSTYPE)
154fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                == UsbEndpointDescriptor.TRANSTYPE_ISO) {
155fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.openListItem();
156fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.write("Aync: ");
157fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_SYNCTYPE) {
158fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.SYNCTYPE_NONE:
159fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("NONE");
160fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
161fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.SYNCTYPE_ASYNC:
162fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("ASYNC");
163fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
164fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.SYNCTYPE_ADAPTSYNC:
165fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("ADAPTIVE ASYNC");
166fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
167fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            }
168fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.closeListItem();
169fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean
170fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.openListItem();
171fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.write("Useage: ");
172fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            switch (attributes & UsbEndpointDescriptor.MASK_ATTRIBS_USEAGE) {
173fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.USEAGE_DATA:
174fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("DATA");
175fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
176fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.USEAGE_FEEDBACK:
177fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("FEEDBACK");
178fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
179fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.USEAGE_EXPLICIT:
180fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("EXPLICIT FEEDBACK");
181fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
182fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                case UsbEndpointDescriptor.USEAGE_RESERVED:
183fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    canvas.write("RESERVED");
184fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean                    break;
185fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            }
186fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean            canvas.closeListItem();
187fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        }
188fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.writeListItem("Package Size: " + getPacketSize());
189fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.writeListItem("Interval: " + getInterval());
190fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean        canvas.closeList();
191fd7cb85feff517f3cc94384102933aa4485e1fc5Paul McLean    }
192b5eaa809da69865cbde156007ae5363f9209f932Paul McLean}
193