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