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