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