Merge branch 'foe_with_passwd' into 'master'

Add support for FoE with password.

See merge request etherlab.org/ethercat!45
This commit is contained in:
Florian Pose 2022-04-19 10:11:49 +00:00
commit de6a8987b7
7 changed files with 55 additions and 16 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)) {

View File

@ -426,6 +426,7 @@ typedef struct {
typedef struct {
// inputs
uint32_t password;
uint16_t slave_position;
uint16_t offset;
size_t buffer_size;

View File

@ -31,6 +31,7 @@
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
#include "CommandFoeRead.h"
@ -51,7 +52,7 @@ string CommandFoeRead::helpString(const string &binaryBaseName) const
stringstream str;
str << binaryBaseName << " " << getName()
<< " [OPTIONS] <SOURCEFILE>" << endl
<< " [OPTIONS] <SOURCEFILE> [<PASSWORD>]" << 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 <file> 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;
}

View File

@ -53,7 +53,7 @@ string CommandFoeWrite::helpString(const string &binaryBaseName) const
stringstream str;
str << binaryBaseName << " " << getName()
<< " [OPTIONS] <FILENAME>" << endl
<< " [OPTIONS] <FILENAME> [<PASSWORD>]" << 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 <file> 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);