stream pushing ok without access permission of /dev/video0
[rtmpclient.git] / app / src / main / jni / libusb-1.0.22 / libusb / os / linux_usbfs.c
index 768e7d5..25dbd5f 100644 (file)
@@ -160,6 +160,7 @@ struct linux_device_priv {
        unsigned char *descriptors;
        int descriptors_len;
        int active_config; /* cache val for !sysfs_can_relate_devices  */
+    int fd;
 };
 
 struct linux_device_handle_priv {
@@ -926,23 +927,26 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
                /* we hit this error path frequently with buggy devices :( */
                usbi_warn(DEVICE_CTX(dev),
                        "get_configuration failed ret=%d errno=%d", r, errno);
-               priv->active_config = -1;
-       } else {
-               if (active_config > 0) {
-                       priv->active_config = active_config;
-               } else {
-                       /* some buggy devices have a configuration 0, but we're
-                        * reaching into the corner of a corner case here, so let's
-                        * not support buggy devices in these circumstances.
-                        * stick to the specs: a configuration value of 0 means
-                        * unconfigured. */
-                       usbi_warn(DEVICE_CTX(dev),
-                               "active cfg 0? assuming unconfigured device");
-                       priv->active_config = -1;
-               }
-       }
-
-       return LIBUSB_SUCCESS;
+               //priv->active_config = -1;
+        return LIBUSB_ERROR_IO;
+       } 
+//    else {
+//             if (active_config > 0) {
+//                     priv->active_config = active_config;
+//             } else {
+//                     /* some buggy devices have a configuration 0, but we're
+//                      * reaching into the corner of a corner case here, so let's
+//                      * not support buggy devices in these circumstances.
+//                      * stick to the specs: a configuration value of 0 means
+//                      * unconfigured. */
+//                     usbi_warn(DEVICE_CTX(dev),
+//                             "active cfg 0? assuming unconfigured device");
+//                     priv->active_config = -1;
+//             }
+//     }
+//
+    return active_config;
+//     return LIBUSB_SUCCESS;
 }
 
 static int initialize_device(struct libusb_device *dev, uint8_t busnum,
@@ -1115,6 +1119,137 @@ retry:
        return LIBUSB_SUCCESS;
 }
 
+static int linux_initialize_device(struct libusb_device *dev,
+       uint8_t busnum, uint8_t devaddr, int fd) {
+
+       usbi_dbg("linux_initialize_device");
+
+       struct linux_device_priv *priv = _device_priv(dev);
+       struct libusb_context *ctx = DEVICE_CTX(dev);
+       uint8_t desc[4096]; // max descriptor size is 4096 bytes
+       int speed;
+       ssize_t r;
+
+       dev->bus_number = busnum;
+       dev->device_address = devaddr;
+
+       usbi_dbg("cache descriptors in memory");
+
+       priv->descriptors_len = 0;
+       priv->fd = 0;
+       memset(desc, 0, sizeof(desc));
+    if (!lseek(fd, 0, SEEK_SET)) {
+        // ディスクリプタを読み込んでローカルキャッシュする
+        int length = read(fd, desc, sizeof(desc));
+        usbi_dbg("Device::init read returned %d errno %d\n", length, errno);
+               if (length > 0) {
+                       priv->fd = fd;
+                       priv->descriptors = usbi_reallocf(priv->descriptors, length);
+                       if (!priv->descriptors) {
+                return (int)LIBUSB_ERROR_NO_MEM;
+                               //RETURN(LIBUSB_ERROR_NO_MEM, int);
+                       }
+                       priv->descriptors_len = length;
+                       memcpy(priv->descriptors, desc, length);
+               }
+       }
+
+       if (priv->descriptors_len < DEVICE_DESC_LENGTH) {
+               usbi_err(ctx, "short descriptor read (%d)", priv->descriptors_len);
+               //LOGE("short descriptor read (%d)", priv->descriptors_len);
+        return (int)LIBUSB_ERROR_IO;
+               //RETURN(LIBUSB_ERROR_IO, int);
+       }
+
+       if (fd < 0) {   // if could not get fd of usbfs with read/write access
+               /* cannot send a control message to determine the active
+                * config. just assume the first one is active. */
+               usbi_warn(ctx, "Missing rw usbfs access; cannot determine "
+                               "active configuration descriptor");
+               if (priv->descriptors_len
+                               >= (DEVICE_DESC_LENGTH + LIBUSB_DT_CONFIG_SIZE)) {
+                       struct libusb_config_descriptor config;
+                       usbi_parse_descriptor(priv->descriptors + DEVICE_DESC_LENGTH,
+                               "bbwbbbbb", &config, 0);
+                       priv->active_config = config.bConfigurationValue;
+               } else
+                       priv->active_config = -1; /* No config dt */
+
+        return (int)LIBUSB_SUCCESS;
+               //RETURN(LIBUSB_SUCCESS, int);
+       }
+       // if we could get fd of usbfs with read/write access
+       r = usbfs_get_active_config(dev, fd);
+       if (r > 0) {
+               priv->active_config = r;
+               r = LIBUSB_SUCCESS;
+       } else if (r == 0) {
+               /* some buggy devices have a configuration 0, but we're
+                * reaching into the corner of a corner case here, so let's
+                * not support buggy devices in these circumstances.
+                * stick to the specs: a configuration value of 0 means
+                * unconfigured. */
+               usbi_dbg("active cfg 0? assuming unconfigured device");
+               priv->active_config = -1;
+               r = LIBUSB_SUCCESS;
+       } else if (r == LIBUSB_ERROR_IO) {
+               /* buggy devices sometimes fail to report their active config.
+                * assume unconfigured and continue the probing */
+               usbi_warn(ctx, "couldn't query active configuration, assuming"
+                                       " unconfigured");
+               priv->active_config = -1;
+               r = LIBUSB_SUCCESS;
+       } /* else r < 0, just return the error code */
+
+    return (int)r;
+       //RETURN(r, int);
+}
+
+
+
+int linux_generate_device(struct libusb_context *ctx, struct libusb_device **dev,
+       int vid, int pid, const char *serial, int fd, int busnum, int devaddr) {
+
+       usbi_dbg("linux_generate_device, fd:%d, serial:%s", fd, serial);
+       unsigned long session_id;
+       int r = 0;
+
+       *dev = NULL;
+       /* FIXME: session ID is not guaranteed unique as addresses can wrap and
+        * will be reused. instead we should add a simple sysfs attribute with
+        * a session ID. */
+       session_id = busnum << 8 | devaddr;
+       usbi_dbg("allocating new device for %d/%d (session %ld)", busnum, devaddr, session_id);
+       *dev = usbi_alloc_device(ctx, session_id);      // この時点で参照カウンタ=1
+       if (!dev) {
+        usbi_dbg("ret %d", LIBUSB_ERROR_NO_MEM);
+        return (int)LIBUSB_ERROR_NO_MEM;
+       }
+
+       r = linux_initialize_device(*dev, busnum, devaddr, fd);
+       if (r < 0) {
+               usbi_err("initialize_device failed: ret=%d", r);
+               goto out;
+       }
+       r = usbi_sanitize_device(*dev);
+       if (r < 0) {
+           usbi_err("usbi_sanitize_device failed: ret=%d", r);
+               goto out;
+       }
+
+out:
+       if (r < 0) {
+               libusb_unref_device(*dev);      // ここで参照カウンタが0になって破棄される
+               *dev = NULL;
+       } else {
+               usbi_connect_device(*dev);
+       }
+
+    usbi_dbg("linux_generate_device ret=%d", r);
+    return (int)r;
+}
+
+
 int linux_enumerate_device(struct libusb_context *ctx,
        uint8_t busnum, uint8_t devaddr, const char *sysfs_dir)
 {