2013-04-11 6 views
14

मैं एक निश्चित सी-प्रोग्राम को संकलित करने का प्रयास करने पर विचार करता हूं जो एंड्रॉइड के लिए यूएसबी के माध्यम से गेम्बार्ड सिल्वरशील्ड पावर आउटलेट के नियंत्रण की अनुमति देता है। मेरे एंड्रॉइड एचडीएमआई टीवी-स्टिक पर यह बहुत उपयोगी होगा। this के लिए एक खुली परियोजना है। यह लिनक्स के तहत काम करता है और libusb पर निर्भर करता है। लक्ष्य मंच एंड्रॉइड आईसीएस है। मैं उबंटू लिनक्स पर विकसित करना चाहता हूं। मुझे क्या काम करने की संभावना है? आवश्यक कदम क्या हैं। सेटअप एंड्रॉइड एसडीके, एनडीके, क्रॉसकंपेलर ...
एंड्रॉइड पर libusb से संबंधित एक पुराना प्रश्न here है लेकिन कोई जानकारी नहीं है।
क्या यूएसबी लाइब्रेरी के एंड्रॉइड को एप्लिकेशन पोर्ट करना आसान हो सकता है?एंड्रॉइड के लिए libusb के खिलाफ संकलन और लिंक

+0

यहाँ एक परियोजना कहा जाता libusbdroid है http://sourceforge.net/projects/libusbdroid/। मैं sispmctl को इसके खिलाफ कैसे स्थापित करूं? – highsciguy

उत्तर

23

लिबसब गैर-रूट वाले एंड्रॉइड पर काम कर सकता है (बशर्ते डिवाइस यूएसबी होस्ट का समर्थन करता है ... यह बहुत महत्वपूर्ण है क्योंकि सभी डिवाइस नहीं करते हैं)। आपको मानक एंड्रॉइड यूएसबी स्टैक का उपयोग करने की आवश्यकता है। फिर आप USBDevice से डिवाइस डिस्क्रिप्टर प्राप्त कर सकते हैं और इसे libusb पर भेज सकते हैं।

दुर्भाग्यवश आपको libusb को संशोधित करने की भी आवश्यकता है। सौभाग्य से अन्य लोगों ने समझाया है कि आपको LibUSB को संशोधित करने की आवश्यकता है।

LibUSB को here संशोधित किया गया है।

शुभकामनाएं!

संपादित:

सबसे पहले आप एक प्रसारण रिसीवर परिभाषित करने की जरूरत:

mUsbManager   = (UsbManager) getSystemService(Context.USB_SERVICE); 
    HashMap< String, UsbDevice > stringDeviceMap =  mUsbManager.getDeviceList(); 
    Collection<UsbDevice> usbDevices    = stringDeviceMap.values(); 

    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); 
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); 
    registerReceiver(mUsbReceiver, filter); 

    Iterator<UsbDevice> usbDeviceIter    = usbDevices.iterator(); 
    while(usbDeviceIter.hasNext()) 
    { 
     if (USBDeviceValid(usbDevice)) 
     { 
      // Request permission to access the device. 
      mUsbManager.requestPermission(usbDevice, mPermissionIntent); 

      // Open the device. 
      UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice); 
      int fd = connection.getFileDescriptor(); 

      // Now pass the file descriptor to libusb through a native call. 
     } 
    } 

:

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() 
{ 
    public void onReceive(Context context, Intent intent) 
    { 
     String action = intent.getAction(); 
     if (ACTION_USB_PERMISSION.equals(action)) 
     { 
      synchronized (this) 
      { 
       UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); 

       if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) 
       { 
        if(device != null) 
        { 
         UsbDeviceConnection deviceConnection = mUsbManager.openDevice(device); 
         Log.d("USB", deviceConnection.getSerial()); 
        } 
       } 
       else 
       { 
        Log.d("USB", "permission denied for device " + device); 
       } 
      } 
     } 
    } 
} 

अब आप एक USBManager बना सकते हैं और उपकरणों की गणना करने की जरूरत है संपादित करें 2:

include $(CLEAR_VARS) 
LOCAL_MODULE := libusb 
LOCAL_SRC_FILES := libusb/core.c libusb/descriptor.c libusb/io.c libusb/sync.c libusb/os/linux_usbfs.c 

LOCAL_LDLIBS := -llog 
include $(BUILD_SHARED_LIBRARY) 
+0

में कैसे उपयोग कर सकता हूं क्या मुझे कहीं सृजन और उत्तीर्ण करने के लिए एक उदाहरण मिल सकता है डिवाइस डिस्क्रिप्टर। – highsciguy

+0

@highsciguy: पोस्ट संपादित करें। – Goz

+0

@highsciguy: क्या यह मदद मिली? – Goz

1

भले ही आप इसे संकलित कर लें, फिर भी एंड्रॉइड शायद आपको यूएसबी डिवाइस तक libusb तक पहुंचने नहीं देगा जब तक कि आपका डिवाइस रूट न हो जाए। यदि आपके ऐप को Android's native USB stack पर पोर्ट करना संभव है, तो यह लगभग निश्चित रूप से एक अधिक स्थिर समाधान होगा।

+1

डिवाइस रूट है। यह सभी अन्य रिकोमैजिक III एचडीएमआई-स्टिक्स के लिए अद्यतित फर्मवेयर के साथ भी सच है। यदि libusb का उपयोग न करने का यही एकमात्र कारण है, तो मैं इसे आज़मा दूंगा। लेकिन यह जानना भी दिलचस्प होगा कि एंड्रॉइड के यूएसबी स्टैक और libusb कैसे हैं, यदि आप इसके बारे में कुछ भी जानते हैं ... इसके अलावा: मैं इसे सी – highsciguy

1

आप:

का निर्माण करने के libusb हो रही फ़ाइलें कहीं काम (मैं उन्हें JNI/libusb में डाल) डालने और फिर अपने Android.mk को निम्नलिखित लाइनों को जोड़ने का मामला है android serial port api

का उपयोग करने का भी प्रयास कर सकते हैं यहां सीरियल पोर्ट इनिट का उदाहरण दिया गया है।

private FileDescriptor mFd; 
private FileInputStream mFileInputStream; 
private FileOutputStream mFileOutputStream; 

public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException { 

    /* Check access permission */ 
    if (!device.canRead() || !device.canWrite()) { 
     try { 
      /* Missing read/write permission, trying to chmod the file */ 
      Process su; 
      su = Runtime.getRuntime().exec("/system/bin/su"); 
      String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" 
        + "exit\n"; 
      su.getOutputStream().write(cmd.getBytes()); 
      if ((su.waitFor() != 0) || !device.canRead() 
        || !device.canWrite()) { 
       throw new SecurityException(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new SecurityException(); 
     } 
    } 

    mFd = open("/dev/ttyACM0", 9600, 0); 
    if (mFd == null) { 
     Log.e(TAG, "native open returns null"); 
     throw new IOException(); 
    } 
    mFileInputStream = new FileInputStream(mFd); 
    mFileOutputStream = new FileOutputStream(mFd); 
} 

तो यूएसबी होस्ट पर उपयोग उपकरणों के साथ ऐसा किया।

4

मैंने जो समाधान लागू किया है वह जावा एपीआई का उपयोग करके यूएसबी डिवाइस खोलना है और फिर libusb के साथ फ़ाइल डिस्क्रिप्टर का उपयोग करना है।जावा कोड में डिवाइस खुलने (मुख्य थ्रेड पर चल नहीं

int LibUsbAndroid::android_open(libusb_device *device, libusb_device_handle **devHandle) 
{ 
    int fd = USBJNICallbacks::getCallback()->getDeviceFd(device->bus_number, device->device_address); 

    __android_log_print(ANDROID_LOG_VERBOSE,"USB","Got FD:%d",fd); 
    if(fd==-1) 
    { 
     __android_log_print(ANDROID_LOG_ERROR,"USB","android_open, bad fd"); 
     return -1; 
    } 

    return libusb_open(device, devHandle, fd); 
} 

: मैं primesense (https://github.com/OpenNI/OpenNI2) द्वारा openni परियोजना से libusb इस्तेमाल किया

कोड बिट्स:

डिवाइस खुलने (बड़ा घूँट का उपयोग करना)!):

public int getDeviceFd(int busNumber, int deviceAddress) { 
     UsbDevice device = findDevice(busNumber, deviceAddress); 

     if(device!=null) 
     { 
      mReceivedPermission = false; 
      PermissionRequester pr = new PermissionRequester(device); 
      pr.run(); 

      if(!mUsbManager.hasPermission(device)) 
      { 
       Log.v("USB", "Requesting permissiom to device"); 
       mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_USB_PERMISSION), 0); 
       IntentFilter filterPermission = new IntentFilter(ACTION_USB_PERMISSION); 
       mContext.registerReceiver(mUsbPermissionReceiver, filterPermission); 
       mUsbManager.requestPermission(device, mPermissionIntent); 
      } 
      else 
      { 
       Log.v("USB", "Already has permission"); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

       mReceivedPermission = true; 

       Log.v("USB", "Opening device"); 
       OpenDevice od = openDevice(device); 
       Log.v("USB", "Adding to open devices"); 
       mOpenDevices.put(""+busNumber+"/"+deviceAddress, od); 


      } 

      Log.v("USB", "Waiting for permission"); 
      waitForPermissionResult(); 
      OpenDevice od = mOpenDevices.get(""+busNumber+"/"+deviceAddress); 
      if(od!=null) 
      { 
       Log.v("USB", "Getting FD"); 
       int result = od.mConnection.getFileDescriptor(); 

       Log.i("USB","USB File desc:"+result); 
       return result; 
      } 
      else 
      { 
       Log.v("USB", "Error getting FD"); 
       return -1; 
      } 
     } 

     return -1; 
    } 

अनुमति हैंडलिंग कोड:

निजी BroadcastReceiver mUsbPermissionReceiver = नए BroadcastReceiver() {

@Override 
public void onReceive(Context context, Intent intent) { 

    Log.v("USB", "Received permission result"); 
    String action = intent.getAction(); 
    if (ACTION_USB_PERMISSION.equals(action)) { 
     synchronized (this) { 
      UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); 
      if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { 
       Log.v("USB", "Received permission result OK"); 
       if(device != null){ 
        Log.v("USB", "Device OK"); 
        mContext.unregisterReceiver(this);  
        Log.v("USB", "Openning device"); 
        OpenDevice od = openDevice(device); 
        Log.v("USB", "Adding to open device list"); 
        mOpenDevices.put(""+od.mBus+"/"+od.mAddress,od); 

        Log.v("USB", "Received permission is true"); 
        mReceivedPermission = true; 
       } 
       else { 
        Log.d(TAG, "permission denied for device " + device); 
       } 
      } 
     } 
    } 
} 

};

ओपन समारोह:

public OpenDevice openDevice(UsbDevice device) { 
     UsbDeviceConnection connection = mUsbManager.openDevice(device); 

     Log.i("USB","Device name="+device.getDeviceName()); 

     int bus = getBusNumber(device.getDeviceName()); 
     int address = getAddress(device.getDeviceName()); 

     return new OpenDevice(device, connection, bus, address); 

    } 

यूएसबी lib परिवर्तन (core.c):

int API_EXPORTED libusb_open(libusb_device *dev, 
    libusb_device_handle **handle, int fd) 
{ 
    struct libusb_context *ctx = DEVICE_CTX(dev); 
    struct libusb_device_handle *_handle; 
    size_t priv_size = usbi_backend->device_handle_priv_size; 
    int r; 
    usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); 

    _handle = malloc(sizeof(*_handle) + priv_size); 
    if (!_handle) 
     return LIBUSB_ERROR_NO_MEM; 

    r = usbi_mutex_init(&_handle->lock, NULL); 
    if (r) { 
     free(_handle); 
     return LIBUSB_ERROR_OTHER; 
    } 

    _handle->dev = libusb_ref_device(dev); 
    _handle->claimed_interfaces = 0; 
    memset(&_handle->os_priv, 0, priv_size); 

    r = usbi_backend->open(_handle,fd); 
    if (r < 0) { 
     usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); 
     libusb_unref_device(dev); 
     usbi_mutex_destroy(&_handle->lock); 
     free(_handle); 
     return r; 
    } 

    usbi_mutex_lock(&ctx->open_devs_lock); 
    list_add(&_handle->list, &ctx->open_devs); 
    usbi_mutex_unlock(&ctx->open_devs_lock); 
    *handle = _handle; 
    /* At this point, we want to interrupt any existing event handlers so 
    * that they realise the addition of the new device's poll fd. One 
    * example when this is desirable is if the user is running a separate 
    * dedicated libusb events handling thread, which is running with a long 
    * or infinite timeout. We want to interrupt that iteration of the loop, 
    * so that it picks up the new fd, and then continues. */ 
    usbi_fd_notification(ctx); 

    return 0; 
} 

op_open (libusb_fs.c) परिवर्तन:

static int op_open(struct libusb_device_handle *handle, int fd) 
{ 
    struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); 
    char filename[PATH_MAX]; 

    _get_usbfs_path(handle->dev, filename); 
    usbi_dbg("opening %s", filename); 

    hpriv->fd = fd; 

    if (hpriv->fd < 0) { 
     if (errno == EACCES) { 
      usbi_err(HANDLE_CTX(handle), "libusb couldn't open USB device %s: " 
       "Permission denied.", filename); 
      usbi_err(HANDLE_CTX(handle), 
       "libusb requires write access to USB device nodes."); 
      return LIBUSB_ERROR_ACCESS; 
     } else if (errno == ENOENT) { 
      usbi_err(HANDLE_CTX(handle), "libusb couldn't open USB device %s: " 
       "No such file or directory.", filename); 
      return LIBUSB_ERROR_NO_DEVICE; 
     } else { 
      usbi_err(HANDLE_CTX(handle), 
       "open failed, code %d errno %d", hpriv->fd, errno); 
      return LIBUSB_ERROR_IO; 
     } 
    } 

    return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); 
} 
+0

धन्यवाद, यह काफी उपयोगी है। क्या आप libusb_deen * को कॉल करने के लिए आवश्यक libusb_device * को भी साझा कर सकते हैं? – rsp1984

संबंधित मुद्दे