usb4java USB error 4: Unable to open USB device: No such device (it may have been disconnected) - usb4java

I have this code:
package prospa8wusb;
import javax.swing.JOptionPane;
import org.usb4java.Device;
import org.usb4java.DeviceDescriptor;
import org.usb4java.DeviceHandle;
import org.usb4java.DeviceList;
import org.usb4java.LibUsb;
import org.usb4java.LibUsbException;
public class Test {
public static short VENDOR_ID = (short)0x04B8;
public static short PRODUCT_ID = (short)0x0005;
public static void main(String[] args) {
LibUsb.init(null) ;
Device device=findDevice(VENDOR_ID,PRODUCT_ID);
DeviceHandle handle = new DeviceHandle();
int result = LibUsb.open(device, handle);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to open USB device", result);
try
{
// Use device handle here
}
finally
{
LibUsb.close(handle);
}
}
public static Device findDevice(short vendorId, short productId)
{
// Read the USB device list
DeviceList list = new DeviceList();
int result = LibUsb.getDeviceList(null, list);
if (result < 0) throw new LibUsbException("Unable to get device list", result);
try
{
// Iterate over all devices and scan for the right one
for (Device device: list)
{
DeviceDescriptor descriptor = new DeviceDescriptor();
result = LibUsb.getDeviceDescriptor(device, descriptor);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to read device descriptor", result);
if (descriptor.idVendor() == vendorId && descriptor.idProduct() == productId)
JOptionPane.showMessageDialog(null, "ok");
return device;
}
}
finally
{
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
System.out.println("Device not found");
return null;
}
}
and I get this error:
USB error 4: Unable to open USB device: No such device (it may have been disconnected)
although the usb printer that I want to communicate is connected to the usb port.
can somebody help me?

Comment this line
LibUsb.freeDeviceList(list, true);
You are freeing the device before using it.

Related

How to do IPC using Unix Domain Socket in D?

Here I have a program that wants to
detect whether if it's the only instance
1.1. it does that by trying to create a Unix Domain Socket
and trying to binding it to a specific address.
if a duplicate program is not running, establish an UDS
and then listen to the socket.
2.1. if any message comes through that socket, the program will log the incoming message
2.2. otherwise it should keep listening to the socket forever
if there's a duplicate program it should send a message and then exit.
Here's what I have:
import std.socket, std.experimental.logger;
immutable string socketAddress = "\0/tmp/com.localserver.myapp";
void main()
{
auto socket = new std.socket.Socket(std.socket.AddressFamily.UNIX,
std.socket.SocketType.STREAM);
auto addr = new std.socket.UnixAddress(socketAddress);
auto isUnique = () {
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(addr);
result = true;
}
catch (std.socket.SocketOSException e)
result = false;
// else throw error
return result;
}();
if (isUnique)
{
log("Unique instance detected. Listening...");
// works upto now
char[] buffer = [];
while (1)
{
socket.listen(0);
socket.receive(buffer);
if (buffer != []) {
log("Received message: ", buffer);
}
buffer = [];
}
}
else
{
log("Duplicate instance detected.");
socket.connect(addr);
import std.stdio;
stdout.write("Enter your message:\t");
socket.send(readln());
log("Message has been sent. Exiting.");
}
}
The documentation does not seem very friendly to those who does not have any experience in socket programming. How can I send and receive message with std.socket.Socket?
After binding, you actually need to accept. It will return a new Socket instance which you can actually receive from. Your client side branch looks ok. I think that is your key mistake here.
I also have a code sample in my book that shows basic functionality of std.socket which can help as an example:
http://arsdnet.net/dcode/book/chapter_02/03/
it is tcp, but making it unix just means changing the family, like you already did in your code.
You can also look up socket tutorials for C and so on, the D socket is just a thin wrapper around those same BSD style socket functions.
As Adam pointed out I had use listen() method first and then apply the accept() method which returns a socket that can receive message. Then the receiver socket takes a char[N] buffer.
import std.socket, std.experimental.logger;
class UDSIPC
{
private:
static immutable string socketAddress = "\0/tmp/com.localserver.myapp";
static immutable size_t messageBufferSize = 64;
static immutable string socketAddressName = "\0/tmp/com.localserver.myapp";
Socket socket;
UnixAddress uaddr;
public:
this(in string socketAddressName = socketAddressName)
{
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
uaddr = new UnixAddress(socketAddress);
}
bool getUniqueness()
{
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(uaddr);
result = true;
}
catch (SocketOSException e)
result = false;
// else throw error
return result;
}
string getMessage()
{
socket.listen(0);
auto receiverSocket = socket.accept();
char[messageBufferSize] buffer;
auto amount = receiverSocket.receive(buffer);
import std.string;
return format!"%s"(buffer[0 .. amount]);
}
void sendMessage(in string message)
{
socket.connect(uaddr);
socket.send(message);
}
}
void main()
{
auto ipc = new UDSIPC();
if (ipc.getUniqueness())
{
while (true)
{
log(ipc.getMessage());
}
}
else
{
import std.stdio, std.string;
ipc.sendMessage(readln().chomp());
}
}

Linux C++ LibUSB Write Register in USB HUB

In Linux, I have a USB hub with the 'register' shown in the image below. This register is supposed to disable power on a certain port on the hub.
I tried to use LibUSB ( my code is shown below ) to write the register, 0x0A, with all zeros to disable all ports. The problem is, the hub is controlled by the standard Linux USB Hub driver and so the Kernel driver is detached. The write also fails. The failure messages are shown below.
Error messages:
$ /mnt/apps/UsbPowerControl
5 Devices in list.
Vendor:Device = 1908:1320
Vendor:Device = 0403:6001
Vendor:Device = 289d:0010
Vendor:Device = 0424:2513
Vendor:Device = 1d6b:0002
Opening Device = 0424:2513
Device Opened
Kernel Driver Active
Kernel Driver Detached!
Claimed Interface
Data-><-
Writing Data...
libusb: error [submit_bulk_transfer] submiturb failed error -1 errno=2
Write Error
Released Interface
How can I use LibUSB to write this Hub register, to dynamically disable and enable the ports, without unregistering the Linux driver and having my write fail?
#include <iostream>
#include <cassert>
#include <libusb-1.0/libusb.h>
using namespace std;
#define VENDOR_ID 0x0424
#define PRODUCT_ID 0x2513
int main() {
libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
libusb_device_handle *dev_handle; //a device handle
libusb_context *ctx = NULL; //a libusb session
int r; //for return values
ssize_t cnt; //holding number of devices in list
r = libusb_init(&ctx); //initialize the library for the session we just declared
if(r < 0) {
cout<<"Init Error "<<r<<endl; //there was an error
return 1;
}
libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
cout<<"Get Device Error"<<endl; //there was an error
return 1;
}
cout<<cnt<<" Devices in list."<<endl;
for (size_t idx = 0; idx < cnt; ++idx) {
libusb_device *device = devs[idx];
libusb_device_descriptor desc = {0};
int rc = libusb_get_device_descriptor(device, &desc);
assert(rc == 0);
printf("Vendor:Device = %04x:%04x\n", desc.idVendor, desc.idProduct);
}
printf("Opening Device = %04x:%04x\n", VENDOR_ID, PRODUCT_ID);
dev_handle = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID); //these are vendorID and productID I found for my usb device
if(dev_handle == NULL)
cout<<"Cannot open device"<<endl;
else
cout<<"Device Opened"<<endl;
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
unsigned char *data = new unsigned char[1]; //data to write
data[0]=0b00000000;
int actual; //used to find out how many bytes were written
if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached
cout<<"Kernel Driver Active"<<endl;
if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
cout<<"Kernel Driver Detached!"<<endl;
}
r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
if(r < 0) {
cout<<"Cannot Claim Interface"<<endl;
return 1;
}
cout<<"Claimed Interface"<<endl;
cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd
cout<<"Writing Data..."<<endl;
r = libusb_bulk_transfer(dev_handle, (0x0A | LIBUSB_ENDPOINT_OUT), data, 1, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
if(r == 0 && actual == 1) //we wrote the 1 bytes successfully
cout<<"Writing Successful!"<<endl;
else
cout<<"Write Error"<<endl;
r = libusb_release_interface(dev_handle, 0); //release the claimed interface
if(r!=0) {
cout<<"Cannot Release Interface"<<endl;
return 1;
}
cout<<"Released Interface"<<endl;
libusb_close(dev_handle); //close the device we opened
libusb_exit(ctx); //needs to be called to end the
delete[] data; //delete the allocated memory for data
return 0;
}
int libusb_detach_kernel_driver ( libusb_device_handle * dev,
int interface_number
)
...
If successful, you will then be able to claim the interface and perform I/O.
...
int libusb_kernel_driver_active ( libusb_device_handle * dev,
int interface_number
)
...
If a kernel driver is active, you cannot claim the interface, and libusb will be unable to perform I/O.
...
Due to what is written above, the short answer to the question "How to do I/O without detaching driver" is "You can't".
Why write fails? This is another matter. I'd suggest looking into a number of things:
Check out the value returned from libusb_bulk_transfer, maybe it will give you the idea of what is happening.
Sounds stupid, but I always check it out before anything else: process privileges.
Also, I can suggest another way of approaching the solution, namely sysfs.
I assume that your device(am I right?) supports EEPROM and SMBus access. It means that this support should be manifested in the kernel somewhere around /sys/bus/i2c/devices/[some_device_id]/eeprom (probably another device number, another directory position, etc, because it is all driver-related), but if it can be found and read just as any other file (which is likely, unless something is wrong with the device), then it probably should be able to write into it as well. If the read works, then I suggest to compare the hexdump -C of the found file to the datasheet, and if the data seems legit, try writing directly into your register(file offset).
Anyway, accessing character device files and sysfs files is a general way of accessing drivers' data in linux. Probably you don't even need to use libusb's API to write that single byte.

DEBUG : MP3Player.h error loading a new music path : abort()

I'm using a library which is called MP3Player.h and can be found here. I use it for helping me writing my own MP3 player in windows with c++ .
Everything is fine until today, i have progress and when i'm debugging an error abort() pop up .
screenies :
error
The error reffer to a function called in MP3Player.h :
// Sequence of call to get the MediaType
// WAVEFORMATEX for mp3 can then be extract from MediaType
mp3Assert(wmSyncReader->QueryInterface(&wmProfile));
mp3Assert(wmProfile->GetStream(0, &wmStreamConfig));
mp3Assert(wmStreamConfig->QueryInterface(&wmMediaProperties));
// Retrieve sizeof MediaType
mp3Assert(wmMediaProperties->GetMediaType(NULL, &sizeMediaType));
// Retrieve MediaType
WM_MEDIA_TYPE* mediaType = (WM_MEDIA_TYPE*)LocalAlloc(LPTR, sizeMediaType);
mp3Assert(wmMediaProperties->GetMediaType(mediaType, &sizeMediaType));
// Check that MediaType is audio
assert(mediaType->majortype == WMMEDIATYPE_Audio);
// assert(mediaType->pbFormat == WMFORMAT_WaveFormatEx);
// Check that input is mp3
WAVEFORMATEX* inputFormat = (WAVEFORMATEX*)mediaType->pbFormat;
assert(inputFormat->wFormatTag == WAVE_FORMAT_MPEGLAYER3);
assert(inputFormat->nSamplesPerSec == 44100);
assert(inputFormat->nChannels == 2); // CRASHING HERE
// Release COM interface
// wmSyncReader->Close();
wmMediaProperties->Release();
wmStreamConfig->Release();
wmProfile->Release();
wmHeaderInfo->Release();
wmSyncReader->Release();
// Free allocated mem
LocalFree(mediaType);
And there is the code i'm using in my main :
int main(void){
MP3Player player;
DIR* rep = NULL;
int timeRead = 0;
const size_t concatenated_size = 512;
char concatenated[concatenated_size];
double time;
struct dirent* fichierLu = NULL;
rep = opendir("C:/Users/paul/Music/Playlisty");
if (rep == NULL)
exit(1);
while ((fichierLu = readdir(rep)) != NULL) {
printf("Le fichier lu s'appelle '%s'\n", fichierLu->d_name);
// Open the mp3 from a file...
timeRead++;
if (timeRead > 79) {
printf("DEBUG : ");
printf(fichierLu->d_name);
printf("\n");
concatenated[0] = '\0'; // set char array content to null
time = 0;
snprintf(concatenated, concatenated_size, "C:/Users/paul/Music/Playlisty/%s", fichierLu->d_name); // load music path name into char array
player.OpenFromFile(concatenated); // load music from path
player.Play();
time = player.GetDuration(); // get time music
Sleep(time * 1000); // wait music time : Time(s) * 1000 = milli
player.Close(); // Close the player with current music
}
}
if (closedir(rep) == -1)
exit(-1);
system("Pause");
return 0;}
Thanks for reading my code , do you think the error come from my bad coding skill in the main or from the header MP3Player.h and how can i fix it ?
Thanks a lot .

COM port handle for reading data in c++ vs2012

I have a code to open and read serial COM port in vs2012 c++ which is working fine when I run the code separately in an individual solution.The code is as follow:
Serial* SP = new Serial("\\\\.\\COM3"); // adjust as needed
if (SP->IsConnected()) // check com port availability
printf("We're connected"); // send the result
char incomingData[512] = ""; // don't forget to pre-allocate memory
int dataLength = 256;
int readResult = 0; //if there is no reading it is -1
while(SP->IsConnected())
{
readResult = SP->ReadData(incomingData,dataLength);
//std::string test(incomingData);
res1=strtol(incomingData,&pos1,10); //receive data in right patern
res2=atof(pos1); //convert the character to integer
res3=(double)res2; // convert integer to double (as my desired output is a double)
printf("%f\n",res2); // print the result
Sleep(50); // pause so that I can see the coming data
}
in which Serial,ReadData and other functions and headers are defined in a separate header and .cpp file.
My problem occurs when I want to plug the code in my other solution (SOFA Simulation) which I want to use to make a graphical interface. but I get the INVALID_HANDLE_VALUE error and the get last error gives me ERROR_FILE_NOT_FOUND. this is my code in the solution I want to use:
namespace sofa
{
namespace component
{
namespace behaviormodel
{
MyBehaviorModel::MyBehaviorModel():
customUnsignedData(initData(&customUnsignedData, (unsigned)1,"Custom Unsigned Data","Example of unsigned data with custom widget")),
regularUnsignedData(initData(&regularUnsignedData, (unsigned)1,"Unsigned Data","Example of unsigned data with standard widget"))
{
customUnsignedData.setWidget("widget_myData");
}
MyBehaviorModel::~MyBehaviorModel()
{
}
void MyBehaviorModel::init()
{
}
void MyBehaviorModel::reinit()
{
}
void MyBehaviorModel::updatePosition(SReal dt)
{
Serial* SP = new Serial("\\\\.\\COM3"); // adjust as needed
if (SP->IsConnected())
printf("We're connected");
char incomingData[512] = ""; // don't forget to pre-allocate memory
int dataLength = 256;
int readResult = 0;
while(SP->IsConnected())
{
readResult = SP->ReadData(incomingData,dataLength);
//std::string test(incomingData);
res1=strtol(incomingData,&pos1,10);
res2=atof(pos1);
res3=(double)res2;
printf("%f\n",res2);
Sleep(50);
}
dx=0.01;
dy=0.01;
dz+=0.01;
using core::behavior::MechanicalState;
mState1 = dynamic_cast<MechanicalState<sofa::defaulttype::Rigid3dTypes> *> (this->getContext()->getMechanicalState());
helper::WriteAccessor<sofa::core::objectmodel:: Data<sofa::defaulttype::Rigid3dTypes::VecCoord> > xp = *mState1- >write(core::VecCoordId::position());
xp[0].getCenter()=sofa::defaulttype::Vec<3,Real>((Real)dx,(Real)dy,(Real)(res2);
}
SOFA_DECL_CLASS(MyBehaviorModel)
int MyBehaviorModelClass = core::RegisterObject("Dummy component with a custom widget.").add< MyBehaviorModel >();
} // namespace behaviormodel
} // namespace component
} // namespace sofa
I really can not figure out what the problem is because as I said the problem is not from my serial reader code as I tested it and I know it works fine separately.can you find out where the problem lies?
thanks in advance!
This is my Serial constructor:
Serial::Serial(char *portName)
{//We're not yet connected
this->connected = false;
//Try to connect to the given port throuh CreateFile
this->hSerial = CreateFile((LPCWSTR)portName,
GENERIC_READ ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
//Check if the connection was successfull
if(this->hSerial==INVALID_HANDLE_VALUE)
{
//If not success full display an Error
if(GetLastError()==ERROR_FILE_NOT_FOUND){
//Print Error if neccessary
printf("ERROR: Handle was not attached. Reason: %s not available.\n", portName);
}
else
{
printf("ERROR!!!");
}
}
else
{
//If connected we try to set the comm parameters
DCB dcbSerialParams = {0};
//Try to get the current
if (!GetCommState(this->hSerial, &dcbSerialParams))
{
//If impossible, show an error
printf("failed to get current serial parameters!");
}
else
{
//Define serial connection parameters for the arduino board
dcbSerialParams.BaudRate=CBR_9600;
dcbSerialParams.ByteSize=8;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
//Setting the DTR to Control_Enable ensures that the Arduino is properly
//reset upon establishing a connection
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
//Set the parameters and check for their proper application
if(!SetCommState(hSerial, &dcbSerialParams))
{
printf("ALERT: Could not set Serial Port parameters");
}
else
{
//If everything went fine we're connected
this->connected = true;
//Flush any remaining characters in the buffers
PurgeComm(this->hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
//We wait 2s as the arduino board will be reseting
Sleep(ARDUINO_WAIT_TIME);
}
}
}
}
The function CreateFile is actually a Macro that is mapped to either CreateFileA or CreateFileW depending on your project (unicode) configuration. As others have mentioned, you should not use a type cast to LPCWSTR to hide the fact that your code is not correct, you just need to use the right type of string.
If a function expects a widestring (LPCWSTR) and you pass it a chunk of memory that contains an ANSI string, it will never work. In this particular case, you can use the function CreateFileA directly so that you can pass your ANSI string to it.

What is the interface I have to inspect for detecting connected USB?

I'm trying to detect that a USB device was plugged or removed from within a qt programm via the method: http://doc.qt.io/qt-4.8/qdbusconnection.html#connect
My current code of the corresponding class looks like this:
#include "usbhandler.h"
#include <QDebug>
USBHandler::USBHandler()
{
QDBusConnection *bus;
bool success;
bus = new QDBusConnection("DeviceAdded");
if (bus == NULL)
{
qDebug() << "Allocation Error";
return;
}
if (!QDBusConnection::systemBus().isConnected())
{
qDebug() << "Cannot connect to system bus";
}
success = QDBusConnection::systemBus().connect(
"org.freedesktop.UDisks",
"/org/freedesktop/UDisks",
"org.freedesktop.UDisks",
"DeviceAdded",
this, SLOT(deviceAdded(QDBusObjectPath)));
if (success != true)
{
qDebug() << "Unsuccesfully connected!";
delete bus;
return;
}
}
void USBHandler::deviceAdded(QDBusObjectPath dev)
{
qDebug() << "device added!"<<dev.path();
}
When I'm running solid-hardware listen I get when plugging / unplugging, the following notifications:
Device Added:
udi = '/org/freedesktop/UDisks2/block_devices/sdb'
"/org/freedesktop/UDisks2/block_devices/sdb1" has new interfaces: ("org.freedesktop.UDisks2.Block", "org.freedesktop.UDisks2.Filesystem", "org.freedesktop.UDisks2.Partition")
Device Added:
udi = '/org/freedesktop/UDisks2/block_devices/sdb1'
"/org/freedesktop/UDisks2/block_devices/sdb1" lost interfaces: ("org.freedesktop.UDisks2.Partition", "org.freedesktop.UDisks2.Filesystem", "org.freedesktop.UDisks2.Block")
Device Removed:
udi = '/org/freedesktop/UDisks2/block_devices/sdb1'
"/org/freedesktop/UDisks2/block_devices/sdb" lost interfaces: ("org.freedesktop.UDisks2.PartitionTable", "org.freedesktop.UDisks2.Block")
Device Removed:
udi = '/org/freedesktop/UDisks2/block_devices/sdb'
So I was sure that the system notifys the USB stickAnd I'm now allready playing around for hours with the for the usb named interfaces but I can't get any success for my apllication reacting on pluggining/unplugging the stick.
So what Am I doing wrong?
What should be the interface and name paramter of connect() be like?
And can you explain me what exactly they do?
Device Added:
udi = '/org/freedesktop/UDisks2/block_devices/sdb'
"/org/freedesktop/UDisks2/block_devices/sdb1" has new interfaces:
I am not sure it is your problem, but the udi contains UDisks2, not UDisks. I suggest you adjust your call to connect(). Something like this:
success = QDBusConnection::systemBus().connect(
"org.freedesktop.UDisks",
"/org/freedesktop/UDisks2",
"org.freedesktop.UDisks2",
[...]);