bool MTPDevice::connect(LIBMTP_raw_device_t *dev)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(dev);
    StreamHelper::on();

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    // Retrieve capabilities.
    m_capabilities = MTPDevice::getCapabilities(*this);

    logmsg("Connected.\n");
    return true;
}
bool MTPDevice::connect(const std::string &dev_file)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    LIBMTP_raw_device_t *raw_device = smtpfs_raw_device_new(dev_file);
    if (!raw_device) {
        logerr("Can not open such device '", dev_file, "'.\n");
        return false;
    }

#ifdef HAVE_LIBUSB1
    // Try to reset USB device, so we don't wait until LIBMTP times out.
    // We do this every time we are about to mount a device, but better
    // connect on first try, than wait for 60s timeout.
    smtpfs_reset_device(raw_device);
#endif // HAVE_LIBUSB1

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    smtpfs_raw_device_free(raw_device);

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    logmsg("Connected.\n");
    return true;
}
bool MTPDevice::connect_priv(int dev_no, const std::string &dev_file)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    int raw_devices_cnt;
    LIBMTP_raw_device_t *raw_devices;

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices(
        &raw_devices, &raw_devices_cnt);
    StreamHelper::on();

    if (err != LIBMTP_ERROR_NONE) {
        switch(err) {
        case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
            logerr("No raw devices found.\n");
            break;
        case LIBMTP_ERROR_CONNECTING:
            logerr("There has been an error connecting. Exiting.\n");
            break;
        case LIBMTP_ERROR_MEMORY_ALLOCATION:
            logerr("Encountered a Memory Allocation Error. Exiting.\n");
            break;
        case LIBMTP_ERROR_GENERAL:
            logerr("General error occured. Exiting.\n");
            break;
        case LIBMTP_ERROR_USB_LAYER:
            logerr("USB Layer error occured. Exiting.\n");
            break;
        default:
            break;
        }
        return false;
    }

#ifndef HAVE_LIBUSB1
    if (!dev_file.empty()) {
        uint8_t bnum, dnum;
        dev_no = raw_devices_cnt;

        if (smtpfs_usb_devpath(dev_file, &bnum, &dnum))
            for (dev_no = 0; dev_no < raw_devices_cnt; ++dev_no)
                if (bnum == raw_devices[dev_no].bus_location &&
                    dnum == raw_devices[dev_no].devnum)
                    break;

        if (dev_no == raw_devices_cnt) {
            logerr("Can not open such device '", dev_file, "'.\n");
            free(static_cast<void*>(raw_devices));
            return false;
        }
    }
#endif // !HAVE_LIBUSB1

    if (dev_no < 0 || dev_no >= raw_devices_cnt) {
        logerr("Can not connect to device no. ", dev_no + 1, ".\n");
        free(static_cast<void*>(raw_devices));
        return false;
    }

    LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no];

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    free(static_cast<void*>(raw_devices));

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    // Retrieve capabilities.
    m_capabilities = MTPDevice::getCapabilities(*this);

    logmsg("Connected.\n");
    return true;
}
bool MTPDevice::connect(int dev_no)
{
    if (m_device) {
        logerr("Already connected.\n");
        return true;
    }

    int raw_devices_cnt;
    LIBMTP_raw_device_t *raw_devices;

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    LIBMTP_error_number_t err = LIBMTP_Detect_Raw_Devices(
        &raw_devices, &raw_devices_cnt);
    StreamHelper::on();

    if (dev_no < 0 || dev_no >= raw_devices_cnt) {
        logerr("Can not connect to device no. ", dev_no + 1, ".\n");
        free(static_cast<void*>(raw_devices));
        return false;
    }

    if (err != LIBMTP_ERROR_NONE) {
        switch(err) {
        case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
            logerr("No raw devices found.\n");
            break;
        case LIBMTP_ERROR_CONNECTING:
            logerr("There has been an error connecting. Exiting.\n");
            break;
        case LIBMTP_ERROR_MEMORY_ALLOCATION:
            logerr("Encountered a Memory Allocation Error. Exiting.\n");
            break;
        case LIBMTP_ERROR_GENERAL:
            logerr("General error occured. Exiting.\n");
            break;
        case LIBMTP_ERROR_USB_LAYER:
            logerr("USB Layer error occured. Exiting.\n");
            break;
        default:
            break;
        }
        return false;
    }

    LIBMTP_raw_device_t *raw_device = &raw_devices[dev_no];

#ifdef HAVE_LIBUSB1
    // Try to reset USB device, so we don't wait until LIBMTP times out.
    // We do this every time we are about to mount a device, but better
    // connect on first try, than wait for 60s timeout.
    smtpfs_reset_device(raw_device);
#endif // HAVE_LIBUSB1

    // Do not output LIBMTP debug stuff
    StreamHelper::off();
    m_device = LIBMTP_Open_Raw_Device_Uncached(raw_device);
    StreamHelper::on();
    free(static_cast<void*>(raw_devices));

    if (!m_device) {
        LIBMTP_Dump_Errorstack(m_device);
        return false;
    }

    if (!enumStorages())
        return false;

    logmsg("Connected.\n");
    return true;
}