diff --git a/master/foe_request.c b/master/foe_request.c index 66a65e8f..440beab3 100644 --- a/master/foe_request.c +++ b/master/foe_request.c @@ -61,6 +61,7 @@ void ec_foe_request_init( INIT_LIST_HEAD(&req->list); req->buffer = NULL; req->file_name = file_name; + req->password = 0; req->buffer_size = 0; req->data_size = 0; req->dir = EC_DIR_INVALID; diff --git a/master/foe_request.h b/master/foe_request.h index 25b9e638..c2a4982d 100644 --- a/master/foe_request.h +++ b/master/foe_request.h @@ -65,6 +65,7 @@ typedef struct { unsigned long jiffies_sent; /**< Jiffies, when the upload/download request was sent. */ uint8_t *file_name; /**< Pointer to the filename. */ + uint32_t password; /**< Password needed for FoE. */ uint32_t result; /**< FoE request abort code. Zero on success. */ uint32_t error_code; /**< Error code from an FoE Error Request. */ } ec_foe_request_t; diff --git a/master/fsm_foe.c b/master/fsm_foe.c index dd998234..a26c2fd1 100644 --- a/master/fsm_foe.c +++ b/master/fsm_foe.c @@ -297,7 +297,7 @@ int ec_foe_prepare_wrq_send( } EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request - EC_WRITE_U32( data + 2, fsm->tx_packet_no ); + EC_WRITE_U32( data + 2, fsm->request->password ); #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "sending opcode %u packet %u\n", EC_FOE_OPCODE_WRQ, fsm->tx_packet_no); @@ -589,7 +589,7 @@ int ec_foe_prepare_rrq_send( } EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request - EC_WRITE_U32(data + 2, 0x00000000); // no passwd + EC_WRITE_U32(data + 2, fsm->request->password); memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size); #ifdef DEBUG_FOE EC_SLAVE_DBG(fsm->slave, 0, "sending opcode %u\n", EC_FOE_OPCODE_RRQ); diff --git a/master/ioctl.c b/master/ioctl.c index 01020687..ee54733e 100755 --- a/master/ioctl.c +++ b/master/ioctl.c @@ -4100,12 +4100,13 @@ static ATTRIBUTES int ec_ioctl_slave_foe_read( } ec_foe_request_init(&request, io.file_name); - ret = ec_foe_request_alloc(&request, 10000); // FIXME + ret = ec_foe_request_alloc(&request, io.buffer_size); // FIXME if (ret) { ec_foe_request_clear(&request); return ret; } + request.password = io.password; ec_foe_request_read(&request); if (down_interruptible(&master->master_sem)) { @@ -4210,6 +4211,7 @@ static ATTRIBUTES int ec_ioctl_slave_foe_write( } request.data_size = io.buffer_size; + request.password = io.password; ec_foe_request_write(&request); if (down_interruptible(&master->master_sem)) { diff --git a/master/ioctl.h b/master/ioctl.h index 67ea95ff..67fefd7d 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -426,6 +426,7 @@ typedef struct { typedef struct { // inputs + uint32_t password; uint16_t slave_position; uint16_t offset; size_t buffer_size; diff --git a/tool/CommandFoeRead.cpp b/tool/CommandFoeRead.cpp index c0666a44..308ffa0f 100644 --- a/tool/CommandFoeRead.cpp +++ b/tool/CommandFoeRead.cpp @@ -31,6 +31,7 @@ #include #include +#include using namespace std; #include "CommandFoeRead.h" @@ -51,7 +52,7 @@ string CommandFoeRead::helpString(const string &binaryBaseName) const stringstream str; str << binaryBaseName << " " << getName() - << " [OPTIONS] " << endl + << " [OPTIONS] []" << endl << endl << getBriefDescription() << endl << endl @@ -59,6 +60,7 @@ string CommandFoeRead::helpString(const string &binaryBaseName) const << endl << "Arguments:" << endl << " SOURCEFILE is the name of the source file on the slave." << endl + << " PASSWORD is the numeric password defined by the vendor." << endl << endl << "Command-specific options:" << endl << " --output-file -o Local target filename. If" << endl @@ -80,11 +82,12 @@ void CommandFoeRead::execute(const StringVector &args) SlaveList slaves; ec_ioctl_slave_t *slave; ec_ioctl_slave_foe_t data; - unsigned int i; stringstream err; + fstream out_file; + ostream* out = &cout; - if (args.size() != 1) { - err << "'" << getName() << "' takes exactly one argument!"; + if (args.size() < 1 || args.size() > 2) { + err << "'" << getName() << "' takes one or two arguments!"; throwInvalidUsageException(err); } @@ -98,14 +101,36 @@ void CommandFoeRead::execute(const StringVector &args) slave = &slaves.front(); data.slave_position = slave->position; + if (!getOutputFile().empty() && getOutputFile() != "-") { + out_file.open(getOutputFile().c_str(), ios::out | ios::trunc | ios::binary); + if (!out_file.good()) { + err << "Failed to open '" << getOutputFile() << "'"; + throwCommandException(err); + } + out = &out_file; + } + /* FIXME: No good idea to have a fixed buffer size. * Read in chunks and fill a buffer instead. */ + data.password = 0; data.offset = 0; data.buffer_size = 0x8800; data.buffer = new uint8_t[data.buffer_size]; strncpy(data.file_name, args[0].c_str(), sizeof(data.file_name) - 1); + data.file_name[sizeof(data.file_name)-1] = 0; + if (args.size() >= 2) { + stringstream strPassword; + strPassword << args[1]; + strPassword + >> resetiosflags(ios::basefield) // guess base from prefix + >> data.password; + if (strPassword.fail()) { + err << "Invalid password '" << args[1] << "'!"; + throwInvalidUsageException(err); + } + } try { m.readFoe(&data); @@ -126,12 +151,7 @@ void CommandFoeRead::execute(const StringVector &args) } } - // TODO --output-file - for (i = 0; i < data.data_size; i++) { - uint8_t *w = data.buffer + i; - cout << *(uint8_t *) w ; - } - + out->write((const char*) data.buffer, data.data_size); delete [] data.buffer; } diff --git a/tool/CommandFoeWrite.cpp b/tool/CommandFoeWrite.cpp index 58a12117..c24ba8e5 100644 --- a/tool/CommandFoeWrite.cpp +++ b/tool/CommandFoeWrite.cpp @@ -53,7 +53,7 @@ string CommandFoeWrite::helpString(const string &binaryBaseName) const stringstream str; str << binaryBaseName << " " << getName() - << " [OPTIONS] " << endl + << " [OPTIONS] []" << endl << endl << getBriefDescription() << endl << endl @@ -63,6 +63,7 @@ string CommandFoeWrite::helpString(const string &binaryBaseName) const << " FILENAME can either be a path to a file, or '-'. In" << endl << " the latter case, data are read from stdin and" << endl << " the --output-file option has to be specified." << endl + << " PASSWORD is the numeric password defined by the vendor." << endl << endl << "Command-specific options:" << endl << " --output-file -o Target filename on the slave." << endl @@ -89,8 +90,8 @@ void CommandFoeWrite::execute(const StringVector &args) SlaveList slaves; string storeFileName; - if (args.size() != 1) { - err << "'" << getName() << "' takes exactly one argument!"; + if (args.size() < 1 || args.size() > 2) { + err << "'" << getName() << "' takes one or two arguments!"; throwInvalidUsageException(err); } @@ -140,8 +141,21 @@ void CommandFoeWrite::execute(const StringVector &args) // write data via foe to the slave data.offset = 0; + data.password = 0; strncpy(data.file_name, storeFileName.c_str(), sizeof(data.file_name) - 1); + data.file_name[sizeof(data.file_name)-1] = 0; + if (args.size() >= 2) { + stringstream strPassword; + strPassword << args[1]; + strPassword + >> resetiosflags(ios::basefield) // guess base from prefix + >> data.password; + if (strPassword.fail()) { + err << "Invalid password '" << args[1] << "'!"; + throwInvalidUsageException(err); + } + } try { m.writeFoe(&data);