Thread: C++ libusb usb_control_msg problem

  1. #1
    The Programming Dutchman
    Join Date
    Jan 2008
    Posts
    55

    C++ libusb usb_control_msg problem

    Hello Folks,

    I Try to create my own program that can control a USB missile launcher. I try to accomplish this with the libusb library.

    now i have a problem: I try to make my USB missile launcher move with the usb_control_msg function. know i got the problem that it does nothing, but give me a succesfull return value.

    Extra info:

    set active config: yes.
    set active alternate interface: yes.
    claimed a interface: yes.
    opened a device: yes.

    this is my code:
    Code:
    #include <usb.h>
    #include <iostream>
    #include <string.h>
    
    #define STOP 	0
    #define LEFT 	1
    #define RIGHT 	2
    #define UP 		4
    #define DOWN 	8
    #define FIRE 	16
    
    usb_dev_handle *locate_misslelauncher(void);
    
    using namespace std;
    
    int main()
    {
    	struct usb_dev_handle *misslelauncher_handle;
    
    	usb_init();
    	usb_set_debug(2);
    
    	if((misslelauncher_handle = locate_misslelauncher()) == 0)
    	{
    		cout << "kan device niet openen!" << endl;
    	}
    	else
    	{
    		cout << "device geopend!" << endl;
    
    		char msg = 0x00;
    		int cmd = msg |= FIRE;
    		int result = 0;
    
    
    	    int a = cmd & LEFT ? 1 : 0;
    	    int b = cmd & RIGHT ? 1 : 0;
    	    int c = cmd & UP ? 1 : 0;
    	    int d = cmd & DOWN ? 1 : 0;
    	    int e = cmd & FIRE ? 1 : 0;
    
    	    cout << "a is:\t" << a << endl;
    	    cout << "b is:\t" << b << endl;
    	    cout << "c is:\t" << c << endl;
    	    cout << "d is:\t" << d << endl;
    	    cout << "e is:\t" << e << endl;
    
    
    	   //result = usb_sendcommand(misslelauncher_handle, 0, a, b, c, d, e, 8, 8);
    
    		unsigned char buffer[64];
    		memset(buffer,0,64);
    
    		  buffer[0] = a;
    		  buffer[1] = b;
    		  buffer[2] = c;
    		  buffer[3] = d;
    		  buffer[4] = e;
    		  buffer[5] = 0;
    		  buffer[6] = 8;
    		  buffer[7] = 8;
    
    	   result = usb_control_msg(misslelauncher_handle, 0x21,9,0x2, 0x0, (char*) buffer, 64,100);
    
    
    	   cout << " result is:\t" << result << endl;
    	}
    
    	usb_release_interface(misslelauncher_handle,0);
    	usb_close(misslelauncher_handle);
    	return 0;
    }
    
    usb_dev_handle *locate_misslelauncher(void)
    {
    	unsigned int vendorid = 4400;
    	unsigned int productid = 514;
    	unsigned int located = 0;
    
    	struct usb_bus *bus;
    	struct usb_device *device;
    	usb_dev_handle *devicehandle = 0;
    
    	usb_find_busses();
    	usb_find_devices();
    
    	for(bus = usb_busses;bus;bus = bus->next)
    	{
    		for(device = bus->devices;device; device = device->next)
    		{
    			if(device->descriptor.idVendor == vendorid && device->descriptor.idProduct == productid)
    			{
    				located++;
    				devicehandle = usb_open(device);
    
    				int config = 0;
    
    				for(int c = 0; c < device->descriptor.bNumConfigurations; c++)
    				{
    					config = c;
    					for(int i = 0; i < device->config[config].bNumInterfaces; i++)
    					{
    						usb_detach_kernel_driver_np(devicehandle, i);
    					}
    				}
    
    				int setconfigstatus = usb_set_configuration(devicehandle, device->config[config].bConfigurationValue);
    				int claim = usb_claim_interface(devicehandle,0);
    				int setalternatestatus = usb_set_altinterface(devicehandle,device->config[config].interface[0].altsetting->bAlternateSetting);
    
    
    				cout << "setconfigstatus:\t" << setconfigstatus << endl;
    				cout << "claim:\t" << claim << endl;
    				cout << "setalternatestatus:\t" << setalternatestatus << endl;
    			}
    		}
    	}
    
    	if(devicehandle == 0)
    	{
    		return (0);
    	}
    	else
    	{
    		return (devicehandle);
    	}
    }
    this code below is the code i used as a example:

    Code:
    int missile_do(missile_usb *control, int cmd, int device_type) {
      int a, b, c, d, e;
        /* Two fixed-format initiator packets appear to be required */
        
        if (missile_usb_sendcommand(control, 'U', 'S', 'B', 'C', 0, 0, 4, 0 )) {
          fprintf(stderr, 
    	      "missile_usb_sendcommand() failed: %s\n", strerror(errno));
          return -1;
        }
        
        if (missile_usb_sendcommand(control, 'U', 'S', 'B', 'C', 0, 64, 2, 0 )) {
          fprintf(stderr, 
    	      "missile_usb_sendcommand() failed: %s\n", strerror(errno));
          return -1;
        }
        
        /* Now the actual movement command! */
        
        a = cmd & MISSILE_LAUNCHER_CMD_LEFT ? 1 : 0;
        b = cmd & MISSILE_LAUNCHER_CMD_RIGHT ? 1 : 0;
        c = cmd & MISSILE_LAUNCHER_CMD_UP ? 1 : 0;
        d = cmd & MISSILE_LAUNCHER_CMD_DOWN ? 1 : 0;
        e = cmd & MISSILE_LAUNCHER_CMD_FIRE ? 1 : 0;
        
        if (missile_usb_sendcommand64(control, 0, a, b, c, d, e, 8, 8 )) {
          fprintf(stderr, 
    	      "missile_usb_sendcommand() failed: %s\n", strerror(errno));
          return -1;
        }
    
    int missile_usb_sendcommand64(missile_usb *control, 
    			      int a, int b, int c, int d, 
    			      int e, int f, int g, int h) {
      
      unsigned char buf[64];
      int  ret;
      
      assert(control != NULL);
      
      ret = claim_interface(control);
      if (ret != 0) {
        return -1;
      }
      
      memset(buf, 0, 64 );
      buf[0] = a;
      buf[1] = b;
      buf[2] = c;
      buf[3] = d;
      buf[4] = e;
      buf[5] = f;
      buf[6] = g;
      buf[7] = h;
      
      if (control->debug) {
        printf("sending bytes %d, %d, %d, %d, %d, %d, %d, %d\n",
    	   a, b, c, d, e, f, g, h );
      }
      
      ret = usb_control_msg(control->handle, 0x21, 9, 
    			0x2, 0x0, (char*) buf, 64,  control->timeout);
    
      if (ret != 64) {
        perror("usb_control_msg failed\n");
        return -1;
      }
      
      return 0;
    }
    Can somebody see what is wrong?

    thanks for your help!

    Jelte.
    The Programming Dutchman

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Your actual buf is only 8 bytes of data, yet you always send 64?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    The Programming Dutchman
    Join Date
    Jan 2008
    Posts
    55
    Salem thanks for your reply!

    i test your suggestion tomorrow (it is close at midnight here in holland now) and post the result.

    Thanks!

    Jelte.
    The Programming Dutchman

  4. #4
    The Programming Dutchman
    Join Date
    Jan 2008
    Posts
    55
    Hello Folks,

    I changed my code so my program always send 8 bytes of data to the device (Thanks to Salem)
    At that moment i was able to control the device, this means that i could let it fire a missile. after that i had tot restart my PC. and when i restarted was not be able to control the device again.

    But the device works OK. with other drivers so the device is alright. So i gues there is some fault in my aplications but i cannot see what is.

    could anybody help me?

    Code:
    #define STOP 	0
    #define LEFT 	1
    #define RIGHT 	2
    #define UP 		4
    #define DOWN 	8
    #define FIRE 	16
    
    		char msg = 0x00;
    	    unsigned char buffer[8];
    	    memset(buffer,0,8);
    
    	    int cmd = 0;
    	    cmd = msg |= RIGHT;
    
    	    int a = cmd & LEFT ? 1 : 0;
    	    int b = cmd & RIGHT ? 1 : 0;
    	    int c = cmd & UP ? 1 : 0;
    	    int d = cmd & DOWN ? 1 : 0;
    	    int e = cmd & FIRE ? 1 : 0;
    
    	    buffer[0] = a;
    	    buffer[1] = b;
    	    buffer[2] = c;
    	    buffer[3] = d;
    	    buffer[4] = e;
    	    buffer[5] = 0;
    	    buffer[6] = 0;
    	    buffer[7] = 0;
    
    	   int result = usb_control_msg(misslelauncher_handle, 0x21,9,0x2, 0x0, (char*)buffer, 8,1000);
    
    	   cout << " result is:\t" << result << endl;
    Thanks,

    Jelte.

    EDIT:

    well i am back at the first situation, at this moment i can only fire the missile launcher. even ni i try to say when it has to go up or down/ left or right.

    and i also discovered that when i send commands that has to make no sense like "15778" it also fires. so always when i send a command , no matter what,it fires. but if i use other software to control the device it works nice. so there must be a bug somewhere in my code.
    Last edited by Jelte; 01-21-2010 at 08:16 AM.
    The Programming Dutchman

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Do you have a specification for the missile launcher?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    The Programming Dutchman
    Join Date
    Jan 2008
    Posts
    55
    it is this one:

    http://www.giftideasforeveryone.com/...e-launcher.jpg

    id-product: 514 - 0x1130
    id-vendor: 4400 - 0x0202

    i use:
    config - 0.
    alternate interface - 0.
    claimed interface: 0.

    this is some info i got earlier with usbsnoop:

    Code:
    Connection Information
    Port: 2
    Speed: Low Speed
    Device address: 1
    Open pipes: 2
    Connection status: Device connected
    
    Device Descriptor
    USB version: 1.10
    Device class: 0x0 - (Defined at Interface level)
    Device subclass: 0x0 - Unknown
    Device protocol: 0x0 - Unknown
    Control pipe max size: 8 bytes
    Vendor ID: 0x1130 (Tenx Technology, Inc.)
    Product ID: 0x202 (Unknown)
    Product version: 1.0
    Manufacturer: Not specified
    Product: Tenx Nonstandard Devic
    Serial Number: Not specified
    Configurations: 1
    The Programming Dutchman

  7. #7
    The Programming Dutchman
    Join Date
    Jan 2008
    Posts
    55
    Solved.

    I had to send to init commands to the device, and send my commands in 64-bytes.

    Thanks for your help.

    Jelte.
    The Programming Dutchman

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM