struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, unsigned long session_id) { size_t priv_size = usbi_backend->device_priv_size; struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size); int r; if (!dev) return NULL; r = usbi_mutex_init(&dev->lock, NULL); if (r) { free(dev); return NULL; } dev->ctx = ctx; dev->refcnt = 1; dev->session_data = session_id; dev->speed = LIBUSB_SPEED_UNKNOWN; if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { usbi_connect_device (dev); } return dev; }
WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref) : fMessenger(messenger), fIsDirectory(false), fDevice(NULL), fEntries(NULL), fLink(NULL), fInitCheck(false) { BEntry entry(ref); entry.GetNodeRef(&fNode); BDirectory directory; if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) { fIsDirectory = true; while (directory.GetNextEntry(&entry) >= B_OK) { if (entry.GetRef(ref) < B_OK) continue; WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref); if (child == NULL) continue; if (child->InitCheck() == false) { delete child; continue; } child->fLink = fEntries; fEntries = child; } watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger); } else { if (strncmp(ref->name, "raw", 3) == 0) return; BPath path, parent_path; entry.GetPath(&path); fDevice = new(std::nothrow) USBDevice(path.Path()); if (fDevice != NULL && fDevice->InitCheck() == true) { // Add this new device to each active context's device list struct libusb_context *ctx; unsigned long session_id = (unsigned long)&fDevice; usbi_mutex_lock(&active_contexts_lock); list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id); if (dev) { usbi_dbg("using previously allocated device with location %lu", session_id); libusb_unref_device(dev); continue; } usbi_dbg("allocating new device with location %lu", session_id); dev = usbi_alloc_device(ctx, session_id); if (!dev) { usbi_dbg("device allocation failed"); continue; } *((USBDevice **)dev->os_priv) = fDevice; // Calculate pseudo-device-address int addr, tmp; if (strcmp(path.Leaf(), "hub") == 0) tmp = 100; //Random Number else sscanf(path.Leaf(), "%d", &tmp); addr = tmp + 1; path.GetParent(&parent_path); while (strcmp(parent_path.Leaf(), "usb") != 0) { sscanf(parent_path.Leaf(), "%d", &tmp); addr += tmp + 1; parent_path.GetParent(&parent_path); } sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number); dev->device_address = addr - (dev->bus_number + 1); if (usbi_sanitize_device(dev) < 0) { usbi_dbg("device sanitization failed"); libusb_unref_device(dev); continue; } usbi_connect_device(dev); } usbi_mutex_unlock(&active_contexts_lock); } else if (fDevice) { delete fDevice; fDevice = NULL; return; } }