/*************************************************************************** reb1100.cpp - REB1100 communication class ------------------- begin : Thu Mar 27 2003 copyright : (C) 2003 by Igor Izyumin email : igor@mlug.missouri.edu ***************************************************************************/ /*************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. **********************************************************************/ #include "reb1100.h" REB1100::REB1100(){ struct usb_bus *bus; struct usb_device *dev; usb_init(); usb_find_busses(); usb_find_devices(); char string[256]; int found = 0; /* find ebook device */ for(bus = usb_busses; bus && !found; bus = bus->next) { for(dev = bus->devices; dev && !found; dev = dev->next) { if (dev->descriptor.idVendor == 0x993 && dev->descriptor.idProduct == 0x1) { hDevice = usb_open(dev); cerr << "Found eBook. Attempting to open... "; found = 1; if (hDevice) { // if (!usb_get_string_simple(hDevice, dev->descriptor.iSerialNumber, string, sizeof(string))) throw DevOpenError(); cerr << "Success.\n"; // cerr << "Serial number: " << string << endl; } else throw DevOpenError(); } } } if (!found) throw DevNotFoundError(); if (!usb_set_configuration(hDevice, 0x0)) throw DevOpenError(); if (!usb_claim_interface(hDevice, 0x1)) throw DevOpenError(); memTarget = INTERNAL; } REB1100::~REB1100(){ usb_release_interface(hDevice, 0x0); usb_close(hDevice); } void REB1100::getFile(string filename, string &data) { long flength = filename.length(); char buf[4096]; char zeros[4] = {0, 0, 0, 0}; int ret; string request; // first four bytes are the length of the filename // (low-endian) char *byte = reinterpret_cast(&flength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // the rest is the filename request += filename; // send a USB control request to tell the device what file we want char *temp; temp = new char[request.length()]; request.copy(temp, string::npos); ret = usb_control_msg(hDevice, 0x42, 0x01, 0x00, 0x00, temp, request.length(), 300); if (ret == -1) throw DevControlError(); delete temp; temp = NULL; // read the return code ret = usb_control_msg(hDevice, 0xc2, 0x02, 0x00, 0x00, zeros, 4, 300); if (ret == -1) throw DevControlError(); // read file from pipe do { ret = usb_bulk_read(hDevice, 2, buf, 4096, 1000); if (ret == -1) throw DevReadError(); for(int i = 0; i < ret; i++) { data += buf[i]; } } while(ret == 4096); } void REB1100::sendFile(string filename, string &data) { string prefix = ""; if (memTarget == MEMCARD) { // prefix with \SM\ when sending to memory card prefix = "\\SM\\"; } filename = prefix + filename; long flength = data.length(); long fnlength = filename.length(); // prepare initial request string request; // first four bytes are the length of the file // (low-endian) char *byte = reinterpret_cast(&flength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // next four bytes are the length of the filename // (low-endian) byte = reinterpret_cast(&fnlength); request += *byte; byte++; request += *byte; byte++; request += *byte; byte++; request += *byte; // append filename request += filename; // send message to device int ret; char *temp; temp = new char[request.length()]; request.copy(temp, string::npos); ret = usb_control_msg(hDevice, 0x42, 0x00, 0x00, 0x00, temp, request.length(), 3000); delete temp; temp = NULL; if (ret == -1) throw DevControlError(); // read from device and check for error char temp2[4] = {0, 0, 0, 0}; ret = usb_control_msg(hDevice, 0xc2, 0x03, 0x00, 0x00, temp2, 4, 3000); if (ret == -1) throw DevControlError(); if (temp2[0] || temp2[1] || temp2[2] || temp2[3]) throw DevControlError(); // now start bulk writing to the device string buf; int n, offset = 0; char *temp3; do { buf = data.substr(offset, 4096); n = buf.length(); if (buf.length() > 0) { temp3 = new char[buf.length()]; buf.copy(temp3, string::npos); // cout << "Sending block (" << n << " bytes)\n"; ret = usb_bulk_write(hDevice, 2, temp3, n, 3000); if (ret == -1) throw DevWriteError(); delete temp3; temp3 = NULL; offset += 4096; } } while(offset + 1 < data.length()); // send empty packet to signify end of file ret = usb_bulk_write(hDevice, 2, 0, 0, 3000); if (ret == -1) throw DevWriteError(); } void REB1100::setTarget(bool target) { memTarget = target; }