AcmDevice.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android.android_acm_serial;
00018 
00019 import android.hardware.usb.UsbConstants;
00020 import android.hardware.usb.UsbDevice;
00021 import android.hardware.usb.UsbDeviceConnection;
00022 import android.hardware.usb.UsbEndpoint;
00023 import android.hardware.usb.UsbInterface;
00024 
00025 import com.google.common.base.Preconditions;
00026 
00027 import org.apache.commons.logging.Log;
00028 import org.apache.commons.logging.LogFactory;
00029 import org.ros.exception.RosRuntimeException;
00030 
00031 import java.io.IOException;
00032 import java.io.InputStream;
00033 import java.io.OutputStream;
00034 import java.nio.ByteBuffer;
00035 import java.nio.ByteOrder;
00036 
00040 public class AcmDevice {
00041 
00042   private static final int CONTROL_TRANSFER_TIMEOUT = 3000; // ms
00043 
00044   private final UsbDeviceConnection usbDeviceConnection;
00045   private final UsbDevice usbDevice;
00046   private final UsbInterface usbInterface;
00047   private final InputStream inputStream;
00048   private final OutputStream outputStream;
00049   private final UsbRequestPool usbRequestPool;
00050 
00051   private static final Log log = LogFactory.getLog(AcmDevice.class);
00052 
00057   private class AcmUsbEndpoints {
00058       private final UsbEndpoint incoming;
00059       private final UsbEndpoint outgoing;
00060 
00061       public AcmUsbEndpoints(UsbEndpoint incoming, UsbEndpoint outgoing) {
00062           this.incoming = incoming;
00063           this.outgoing = outgoing;
00064       }
00065 
00066       private UsbEndpoint getOutgoing() {
00067           return outgoing;
00068       }
00069 
00070       private UsbEndpoint getIncoming() {
00071           return incoming;
00072       }
00073   }
00074 
00075   public AcmDevice(UsbDeviceConnection usbDeviceConnection, UsbDevice usbDevice) {
00076     Preconditions.checkNotNull(usbDeviceConnection);
00077     this.usbDeviceConnection = usbDeviceConnection;
00078 
00079     // Go through all declared interfaces and automatically select the one that looks
00080     // like an ACM interface
00081     UsbInterface usbInterface = null;
00082     AcmUsbEndpoints acmUsbEndpoints = null;
00083     for(int i=0;i<usbDevice.getInterfaceCount() && acmUsbEndpoints == null;i++) {
00084         usbInterface = usbDevice.getInterface(i);
00085         Preconditions.checkNotNull(usbInterface);
00086         Preconditions.checkState(usbDeviceConnection.claimInterface(usbInterface, true));
00087         acmUsbEndpoints = getAcmEndpoints(usbInterface);
00088     }
00089     if(acmUsbEndpoints == null) {
00090         throw new IllegalArgumentException("Couldn't find an interface that looks like ACM on this USB device: " + usbDevice);
00091     }
00092 
00093     this.usbInterface = usbInterface;
00094     this.usbDevice = usbDevice;
00095     usbRequestPool = new UsbRequestPool(usbDeviceConnection);
00096     usbRequestPool.addEndpoint(acmUsbEndpoints.getOutgoing(), null);
00097     usbRequestPool.start();
00098 
00099     outputStream = new AcmOutputStream(usbRequestPool, acmUsbEndpoints.getOutgoing());
00100     inputStream = new AcmInputStream(usbDeviceConnection, acmUsbEndpoints.getIncoming());
00101   }
00102 
00109   private AcmUsbEndpoints getAcmEndpoints(UsbInterface usbInterface) {
00110       UsbEndpoint outgoingEndpoint = null;
00111       UsbEndpoint incomingEndpoint = null;
00112       for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
00113           UsbEndpoint endpoint = usbInterface.getEndpoint(i);
00114           log.info("Interface: " + i + "/" + "Class: " + usbInterface.getInterfaceClass());
00115           if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
00116               if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
00117                   log.info("Endpoint " + i + "/" + usbInterface.getEndpointCount() + ": " + endpoint + ". Type = " + endpoint.getType());
00118                   outgoingEndpoint = endpoint;
00119               } else if(endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
00120                   log.info("Endpoint " + i + "/" + usbInterface.getEndpointCount() + ": " + endpoint + ". Type = " + endpoint.getType());
00121                   incomingEndpoint = endpoint;
00122               }
00123           }
00124       }
00125       if(outgoingEndpoint == null || incomingEndpoint == null) {
00126           return null;
00127       } else {
00128           return new AcmUsbEndpoints(incomingEndpoint, outgoingEndpoint);
00129       }
00130   }
00131 
00132   public void setLineCoding(BitRate bitRate, StopBits stopBits, Parity parity, DataBits dataBits) {
00133     ByteBuffer buffer = ByteBuffer.allocate(7);
00134     buffer.order(ByteOrder.LITTLE_ENDIAN);
00135     buffer.putInt(bitRate.getBitRate());
00136     buffer.put(stopBits.getStopBits());
00137     buffer.put(parity.getParity());
00138     buffer.put(dataBits.getDataBits());
00139     setLineCoding(buffer.array());
00140   }
00141 
00142   private void setLineCoding(byte[] lineCoding) {
00143     int byteCount;
00144     byteCount =
00145         usbDeviceConnection.controlTransfer(0x21, 0x20, 0, 0, lineCoding, lineCoding.length,
00146             CONTROL_TRANSFER_TIMEOUT);
00147     Preconditions.checkState(byteCount == lineCoding.length, "Failed to set line coding.");
00148   }
00149 
00150   public UsbDevice getUsbDevice() {
00151     return this.usbDevice;
00152   }
00153 
00154   public UsbInterface getUsbInterface() {
00155     return usbInterface;
00156   }
00157 
00158   public InputStream getInputStream() {
00159     return inputStream;
00160   }
00161 
00162   public OutputStream getOutputStream() {
00163     return outputStream;
00164   }
00165 
00166   public void close() {
00167     usbDeviceConnection.releaseInterface(usbInterface);
00168     usbDeviceConnection.close();
00169     try {
00170       inputStream.close();
00171       outputStream.close();
00172     } catch (IOException e) {
00173       throw new RosRuntimeException(e);
00174     }
00175   }
00176 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Aug 27 2015 12:11:33