Android USB होस्ट डिवाइस से पढ़ा जाता है



host cdc (1)

आप several से UsbSerial Lib का उपयोग कर सकते हैं

मेरा उदाहरण कोड:

    UsbManager usbManager = null;
    UsbDeviceConnection connection = null;
    UsbSerialDriver driver = null;
    UsbSerialPort port = null;

    usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

    List<UsbSerialDriver> availableDrivers =  UsbSerialProber.getDefaultProber().findAllDrivers(manager);
    // Open a connection to the first available driver.

    for (UsbSerialDriver usd : availableDrivers) {
        UsbDevice udv = usd.getDevice(); 
        if (udv.getVendorId()==0x067B || udv.getProductId()==2303){
            driver = usd;
            break;
        }
    }
        connection = usbManager.openDevice(driver.getDevice());

        port = driver.getPorts().get(0);

        driver.getDevice().

    }

        if (connection == null) return;

        try{

            port.open(connection);
            port.setParameters(4800, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

                try{

                    byte buffer[] = new byte[250];
                    //Log.d("GPS_REQ", "->");
                    int numBytesRead = port.read(buffer, 500); //5000; 

                }catch (Exception e) {
                    Log.d("GPS_ERR", e.getLocalizedMessage());
                }

मैं अपने एंड्रॉइड फोन से जुड़े यूएसबी डिवाइस से कुछ डेटा प्राप्त करने की कोशिश कर रहा हूं जो होस्ट मोड पर है। मैं इसे डेटा भेजने में सक्षम हूं, लेकिन पढ़ना विफल है।

मैंने several examples देखा है और सभी की कोशिश की है, लेकिन मुझे यूएसबी संचार में कोई अनुभव नहीं है, हालांकि अब तक मैं थोड़ा जानता हूं, और मैं इस समय पर अटक गया हूं कि मैं मानता हूं।

मैं समापन बिंदु कॉन्फ़िगरेशन से बहुत परिचित नहीं हूं, लेकिन मुझे पता है कि मेरा डिवाइस एक सीडीसी प्रकार संचार विधि का उपयोग करता है और आउटपुट (फोन से डिवाइस तक) और इनपुट दोनों पंजीकृत हैं।

यहाँ पूरी क्लास है जो केवल उसी डिवाइस के साथ USB कनेक्शन का प्रबंधन करती है जो फोन से जुड़ा है, यह किसी भी तरह से समाप्त नहीं हुआ है, लेकिन मैं आगे पढ़ने से पहले उस रीडिंग पार्ट को काम करना चाहूंगा।

public class UsbCommunicationManager
{
    static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    UsbManager usbManager;
    UsbDevice usbDevice;
    UsbInterface intf = null;
    UsbEndpoint input, output;
    UsbDeviceConnection connection;

    PendingIntent permissionIntent;

    Context context;

    byte[] readBytes = new byte[64];

    public UsbCommunicationManager(Context context)
    {
        this.context = context;
        usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

        // ask permission from user to use the usb device
        permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        context.registerReceiver(usbReceiver, filter);
    }

    public void connect()
    {
        // check if there's a connected usb device
        if(usbManager.getDeviceList().isEmpty())
        {
            Log.d("trebla", "No connected devices");
            return;
        }

        // get the first (only) connected device
        usbDevice = usbManager.getDeviceList().values().iterator().next();

        // user must approve of connection
        usbManager.requestPermission(usbDevice, permissionIntent);
    }

    public void stop()
    {
        context.unregisterReceiver(usbReceiver);
    }

    public String send(String data)
    {
        if(usbDevice == null)
        {
            return "no usb device selected";
        }

        int sentBytes = 0;
        if(!data.equals(""))
        {
            synchronized(this)
            {
                // send data to usb device
                byte[] bytes = data.getBytes();
                sentBytes = connection.bulkTransfer(output, bytes, bytes.length, 1000);
            }
        }

        return Integer.toString(sentBytes);
    }

    public String read()
    {
        // reinitialize read value byte array
        Arrays.fill(readBytes, (byte) 0);

        // wait for some data from the mcu
        int recvBytes = connection.bulkTransfer(input, readBytes, readBytes.length, 3000);

        if(recvBytes > 0)
        {
            Log.d("trebla", "Got some data: " + new String(readBytes));
        }
        else
        {
            Log.d("trebla", "Did not get any data: " + recvBytes);
        }

        return Integer.toString(recvBytes);
    }

    public String listUsbDevices()
    {
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

        if(deviceList.size() == 0)
        {
            return "no usb devices found";
        }

        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        String returnValue = "";
        UsbInterface usbInterface;

        while(deviceIterator.hasNext())
        {
            UsbDevice device = deviceIterator.next();
            returnValue += "Name: " + device.getDeviceName();
            returnValue += "\nID: " + device.getDeviceId();
            returnValue += "\nProtocol: " + device.getDeviceProtocol();
            returnValue += "\nClass: " + device.getDeviceClass();
            returnValue += "\nSubclass: " + device.getDeviceSubclass();
            returnValue += "\nProduct ID: " + device.getProductId();
            returnValue += "\nVendor ID: " + device.getVendorId();
            returnValue += "\nInterface count: " + device.getInterfaceCount();

            for(int i = 0; i < device.getInterfaceCount(); i++)
            {
                usbInterface = device.getInterface(i);
                returnValue += "\n  Interface " + i;
                returnValue += "\n\tInterface ID: " + usbInterface.getId();
                returnValue += "\n\tClass: " + usbInterface.getInterfaceClass();
                returnValue += "\n\tProtocol: " + usbInterface.getInterfaceProtocol();
                returnValue += "\n\tSubclass: " + usbInterface.getInterfaceSubclass();
                returnValue += "\n\tEndpoint count: " + usbInterface.getEndpointCount();

                for(int j = 0; j < usbInterface.getEndpointCount(); j++)
                {
                    returnValue += "\n\t  Endpoint " + j;
                    returnValue += "\n\t\tAddress: " + usbInterface.getEndpoint(j).getAddress();
                    returnValue += "\n\t\tAttributes: " + usbInterface.getEndpoint(j).getAttributes();
                    returnValue += "\n\t\tDirection: " + usbInterface.getEndpoint(j).getDirection();
                    returnValue += "\n\t\tNumber: " + usbInterface.getEndpoint(j).getEndpointNumber();
                    returnValue += "\n\t\tInterval: " + usbInterface.getEndpoint(j).getInterval();
                    returnValue += "\n\t\tType: " + usbInterface.getEndpoint(j).getType();
                    returnValue += "\n\t\tMax packet size: " + usbInterface.getEndpoint(j).getMaxPacketSize();
                }
            }
        }

        return returnValue;
    }

    private void setupConnection()
    {
        // find the right interface
        for(int i = 0; i < usbDevice.getInterfaceCount(); i++)
        {
            // communications device class (CDC) type device
            if(usbDevice.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
            {
                intf = usbDevice.getInterface(i);

                // find the endpoints
                for(int j = 0; j < intf.getEndpointCount(); j++)
                {
                    if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                    {
                        // from android to device
                        output = intf.getEndpoint(j);
                    }

                    if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                    {
                        // from device to android
                        input = intf.getEndpoint(j);
                    }
                }
            }
        }
    }

    private final BroadcastReceiver usbReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if(ACTION_USB_PERMISSION.equals(action))
            {
                // broadcast is like an interrupt and works asynchronously with the class, it must be synced just in case
                synchronized(this)
                {
                    if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
                    {
                        setupConnection();

                        connection = usbManager.openDevice(usbDevice);
                        connection.claimInterface(intf, true);

                        // set flow control to 8N1 at 9600 baud
                        int baudRate = 9600;
                        byte stopBitsByte = 1;
                        byte parityBitesByte = 0;
                        byte dataBits = 8;
                        byte[] msg = {
                            (byte) (baudRate & 0xff),
                            (byte) ((baudRate >> 8) & 0xff),
                            (byte) ((baudRate >> 16) & 0xff),
                            (byte) ((baudRate >> 24) & 0xff),
                            stopBitsByte,
                            parityBitesByte,
                            (byte) dataBits
                        };

                        connection.controlTransfer(UsbConstants.USB_TYPE_CLASS | 0x01, 0x20, 0, 0, msg, msg.length, 5000);
                    }
                    else
                    {
                        Log.d("trebla", "Permission denied for USB device");
                    }
                }
            }
            else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
            {
                Log.d("trebla", "USB device detached");
            }
        }
    };
}

मैं read() विधि से -1 प्राप्त करता रहता हूं जो किसी प्रकार की त्रुटि को इंगित करता है, यह हमेशा बाहर रहता है। शायद समस्या कनेक्शन कॉन्फ़िगरेशन से आती है, मैंने कई कोशिश की है (पढ़ें: परीक्षण और त्रुटि) और कोई भी काम नहीं किया, आश्चर्यजनक रूप से मुझे डिवाइस को डेटा भेजने के लिए किसी भी कॉन्फ़िगरेशन की आवश्यकता नहीं है।

संपादित करें

यह भी ध्यान दिया जाना चाहिए कि मैं जिस केबल का उपयोग कर रहा हूं वह माइक्रो-यूएसबी से माइक्रो-यूएसबी है और यह केवल एक ही तरह से काम करता है, यह मेरा डिवाइस मेरे फोन द्वारा केवल तभी संचालित होता है जब प्लग ए फोन से जुड़ा होता है और प्लग बी से जुड़ा होता है डिवाइस, अन्य तरीके से नहीं ... यह बहुत अजीब लगता है। तथ्य यह है कि मैं सही तरीके से प्लग किए जाने पर डेटा भेजने और प्राप्त करने में सक्षम हूं।

EDIT 2

मैंने पाया कि किसी और को भी यही समस्या थी लेकिन ऐसा लगता है कि वह इसे हल नहीं कर पा रहा था।

EDIT 3

मैंने आखिरकार इस पृष्ठ पर समाधान ढूंढ लिया:

एक अन्य प्रमुख निरीक्षण यह है कि डिवाइस को सूचित करने के लिए होस्ट के लिए कोई तंत्र नहीं है कि डेटा को स्वीकार करने के लिए तैयार होस्ट की तरफ एक डेटा सिंक है। इसका मतलब है कि डिवाइस डेटा भेजने की कोशिश कर सकता है, जबकि मेजबान सुन नहीं रहा है, जिससे ट्रांसमिशन रूटीन में लंबे समय तक अवरुद्ध समय लग सकता है। इस प्रकार यह अत्यधिक अनुशंसा की जाती है कि वर्चुअल सीरियल लाइन DTR (डेटा टर्मिनल रेडी) सिग्नल का उपयोग किया जाए जहां यह निर्धारित करना संभव है कि होस्ट एप्लिकेशन डेटा के लिए तैयार है या नहीं।

तो DTR सिग्नल अनिवार्य था और मुझे केवल यह करना था कि इसे इंटरफ़ेस कॉन्फ़िगरेशन में जोड़ा जाए:

connection.controlTransfer(0x21, 0x22, 0x1, 0, null, 0, 0);

EDIT 4

अगर किसी को दिलचस्पी है, तो मैंने इस परियोजना को पूरा किया और यह खुला स्रोत है और मेरे GitHub खाते पर प्रकाशित हुआ है । हालांकि यह हर समय स्थिर नहीं होता ( notes देखें) और मैं अब इस पर काम करने की योजना नहीं बनाता, लेकिन यह काम करता है। बेझिझक इसे अपनी परियोजनाओं के लिए उपयोग करें।





cdc