0

I am new in linux device driver. I wan to write a C/C++ code to perform file transfer from raspberry pi to usb flash drive. I having difficult for the starting point, so i try on libusb for HID device sample code from signal11 and the code works fine for detecting my optical mouse with its device ID. Then i try to obtain usb flash drive vendor id somehow it give me very wired number. Finally i come out with a very silly try out by writing a bash script for cp a file to usb flash drive and activate the script in C++ and it works but i feel it is not a proper way to do it. Then i start with SCSI protocol and i very hard to understand how it works.Any guideline is appreciated.

int scsi_get_serial(int fd, void *buf, size_t buf_len) {
// we shall retrieve page 0x80 as per http://en.wikipedia.org/wiki/SCSI_Inquiry_Command
unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, buf_len, 0};
unsigned char sense[32];
struct sg_io_hdr io_hdr;
        int result;

memset(&io_hdr, 0, sizeof (io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmdp = inq_cmd;
io_hdr.cmd_len = sizeof (inq_cmd);
io_hdr.dxferp = buf;
io_hdr.dxfer_len = buf_len;
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof (sense);
io_hdr.timeout = 5000;

result = ioctl(fd, SG_IO, &io_hdr);
if (result < 0)
    return result;

if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK)
    return 1;

return 0;
}

int main(int argc, char** argv) {
//char *dev = "/dev/sda";
char *dev = "/dev/sg2";
char scsi_serial[255];
int rc;
int fd;

fd = open(dev, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
    perror(dev);
}

memset(scsi_serial, 0, sizeof (scsi_serial));
rc = scsi_get_serial(fd, scsi_serial, 255);
// scsi_serial[3] is the length of the serial number
// scsi_serial[4] is serial number (raw, NOT null terminated)
if (rc < 0) {
    printf("FAIL, rc=%d, errno=%d\n", rc, errno);
} else
if (rc == 1) {
    printf("FAIL, rc=%d, drive doesn't report serial number\n", rc);
} else {
    if (!scsi_serial[3]) {
        printf("Failed to retrieve serial for %s\n", dev);
        return -1;
    }
    printf("Serial Number: %.*s\n", (size_t) scsi_serial[3], (char *) & scsi_serial[4]);
}
close(fd);

return (EXIT_SUCCESS);
}

I get this serial number: 00/1F

Then i try write this in test.sh

cp /home/Desktop/stl4.pdf /media/mini_flash

and run system("./test.sh") in C++

WenJuan
  • 624
  • 1
  • 8
  • 21
  • We need the relevant parts of your code, and the 'weird number' that you got from the device. Additionally, the output of `lspci` would really help us to determine what you have vs what was returned. – Tim Post Aug 12 '13 at 09:04
  • You're not making yourself clear. First you say you retrieve "Vendor ID", then you say you get "Serial Number" 00/1F. Those two properties are only marginally related (Products of a single vendor Serial should not recycle serial numbers, the tripled VID/PID/SN is unique) – MSalters Aug 12 '13 at 11:25
  • Ya i am lost and very hard to understand the concept. i will try make myself more clear about it.Any recommended reference? – WenJuan Aug 12 '13 at 15:13

1 Answers1

3

The question seems contradictory, at first you say you want to copy a file using a kernel driver, which seems strange to say the least. Then you say you use libusb, which is an userspace library. Then you say that you try to execute a shell script with cp. Maybe what you want is simply a code snippet that copies a file form an userspace C/C++ program? Try one of these snippets.

In detail, if all you want to do is a C++ equivalent of cp /home/Desktop/stl4.pdf /media/mini_flash, then this is enough:

ifstream in("/home/Desktop/stl4.pdf",ios::binary);
ofstream out("/media/mini_flash/stl4.pdf",ios::binary);
out<<in.rdbuf();
in.close();
out.close();
Community
  • 1
  • 1
user2671945
  • 315
  • 1
  • 6
  • Ya sorry for the confusion, my main purpose is just copy the file from an userspace to usb flash drive but i just try anythings and end up with a messy way. Thanks for the link it explained what i really need. – WenJuan Aug 12 '13 at 09:36