0

The goal I'm looking to achieve is to send/receive data to/from an Android device from a Linux server. I feel like I've tried all the examples I could find on the Internet as well as reading the libusb APIs, which don't talk at my level of a total noob. Here's what I've got so far:

I've written a program that runs on a Ubuntu server (ARMx64), from examples, I have the following code:

//Error handling removed for brevity
#define BULK_EP_IN      0x08

main(int argc, char* argv) {
    libusb_context* libusb_ctxt;
    int status;
    bool libusb_err = false;
    libusb_device** libusb_dvcs = NULL;
    bool error = false;
    unsigned vid = 0, pid = 0;
    unsigned busnum = 0, devaddr = 0, _busnum, _devaddr;
    struct libusb_device_descriptor desc;

    status = libusb_init(&libusb_ctxt);
    if (status < 0) {
        libusb_err = true;
    }

    if (libusb_get_device_list(NULL, &libusb_dvcs) < 0) {
        error = true;
    } else {
        libusb_device *dev = NULL;

        for (uint16_t idx = 0; (dev = libusb_dvcs[idx]) != NULL; idx++) {
            _busnum = libusb_get_bus_number(dev);
            _devaddr = libusb_get_device_address(dev);

            status = libusb_get_device_descriptor(dev, &desc);
            if (status >= 0) {
                if (desc.idVendor == vid_arg && desc.idProduct == pid_arg) {
                    vid = desc.idVendor;
                    pid = desc.idProduct;
                    busnum = _busnum;
                    devaddr = _devaddr;

                    fnd_dev = dev;
                    break;
                }
            }
        }

        if (fnd_dev == NULL) {
            error = true;
        } else {
            libusb_device_handle* dev_hnd = NULL;

            //Connect to device and write data to it.
            dev_hnd = libusb_open_device_with_vid_pid(NULL, vid, pid);
            if (dev_hnd) {
                char str1[64], str2[64];
                int e = 0,config2;
                char my_string[64];
                int length = 0;
                int transferred = 0;

                e = libusb_get_string_descriptor_ascii(dev_hnd, desc.iManufacturer, (unsigned char*)str1, sizeof(str1));
                if (e < 0) {
                    break;
                }

                e = libusb_get_string_descriptor_ascii(dev_hnd, desc.iProduct, (unsigned char*)str2, sizeof(str2));
                if(e < 0) {
                    break;
                }

                e = libusb_get_configuration(dev_hnd, &config2);
                if (e == 0) {
                    if (config2 != 1)
                    {
                        libusb_set_configuration(dev_hnd, 1);
                        if (e!=0) {
                            libusb_err = true;
                        }
                    }

                    if (!libusb_err) {
                        if (libusb_kernel_driver_active(dev_hnd, 0) == 1) {
                            if (libusb_detach_kernel_driver(dev_hnd, 0) == 1) { 
                                libusb_err = true;
                            }
                        }

                        if (!libusb_err) {
                            e = libusb_claim_interface(dev_hnd, 0);
                            if (e < 0) {
                                libusb_err = true;
                            }

                            if (!libusb_err) {
                                active_config(dev, dev_hnd);

                                memset(my_string, '\0', 64);
                                strcpy(my_string, "hello sally");
                                length = strlen(my_string);

                                e = libusb_bulk_transfer(dev_hnd, BULK_EP_IN | LIBUSB_ENDPOINT_IN, (unsigned char*)my_string, length, &transferred, 0);
                                if (e == 0 && transferred == length) {
                                    child_log("Write successful!");
                                    child_log("Sent %d bytes with string: %s", transferred, my_string);
                                }
                                else {
                                    child_log("Error in write! e = %d and transferred = %d, error desc: %s", e, transferred, libusb_error_name(e));
                                }
                            }
                        }
                    }
                }

                e = libusb_release_interface(dev_hnd, 0); 
                libusb_close(dev_hnd);
            }
        }

        if (libusb_dvcs != NULL) {
            libusb_free_device_list(libusb_dvcs, 1);
        }
    }

    if (!libusb_err) {
        libusb_exit(libusb_ctxt);
    }
}

Everything works, at least doesn't report an error, until I get to the libusb_bulk_transfer call, which it returns a -1, which translates to a LIBUSB_ERROR_IO.

The USB device I'm connecting to is a Samsung Z-Fold3 mobile phone. I'm using the phone as a test OS as I don't have access to the Android tablet that will be used in the final application.

Here's my questions:

  1. How do I know which interface to connect to?
     a) I'll have an application running on the Android device that will be using the same library, hopefully, that will receive the data sent from the Ubuntu server.
  2. How do I know which configuration to use?
  3. Am I doing everything correctly?
  4. Does anyone have any code that can run on the Android to read the data that I'm sending from this code? My goal was to write a program in C that pretty much runs like the one that runs on the Ubuntu server, but reads the data. Once I have that, my next step will be to write data from the Android device to the Ubuntu server using libusb again.

Any help, advice, alternative APIs is very much appreciated. Thank you!

0 Answers0