# HG changeset patch # User Florian Pose # Date 1217250919 0 # Node ID d1324ac71232828c5e9d215ae17fea8e49cf324a # Parent f02ff486b31303123ba6993a73b45b6f69ebdb38 Accept '-' as filename to read from stdin. diff -r f02ff486b313 -r d1324ac71232 TODO --- a/TODO Mon Jul 28 12:15:25 2008 +0000 +++ b/TODO Mon Jul 28 13:15:19 2008 +0000 @@ -14,8 +14,6 @@ * Get original driver for r8169. * Race in jiffies frame timeout? * ethercat tool: - - Show Pdos in 'ethercat slave -v'. - - Accept files from stdin. - Display attached device's MAC address instead of ff's. - Data type abbreviations. - Add a -n (numeric) switch. diff -r f02ff486b313 -r d1324ac71232 tool/CommandSiiWrite.cpp --- a/tool/CommandSiiWrite.cpp Mon Jul 28 12:15:25 2008 +0000 +++ b/tool/CommandSiiWrite.cpp Mon Jul 28 13:15:19 2008 +0000 @@ -37,7 +37,8 @@ << endl << "Arguments:" << endl << " FILENAME must be a path to a file that contains a" << endl - << " positive number of words." << endl + << " positive number of words. If it is '-'," << endl + << " data are read from stdin." << endl << endl << "Command-specific options:" << endl << " --alias -a " << endl @@ -54,89 +55,141 @@ void CommandSiiWrite::execute(MasterDevice &m, const StringVector &args) { - SlaveList slaves; stringstream err; ec_ioctl_slave_sii_t data; ifstream file; - unsigned int byte_size; - const uint16_t *categoryHeader; - uint16_t categoryType, categorySize; - uint8_t crc; + SlaveList slaves; if (args.size() != 1) { err << "'" << getName() << "' takes exactly one argument!"; throwInvalidUsageException(err); } - file.open(args[0].c_str(), ifstream::in | ifstream::binary); - if (file.fail()) { - err << "Failed to open '" << args[0] << "'!"; - throwCommandException(err); + if (args[0] == "-") { + loadSiiData(&data, cin); + } else { + file.open(args[0].c_str(), ifstream::in | ifstream::binary); + if (file.fail()) { + err << "Failed to open '" << args[0] << "'!"; + throwCommandException(err); + } + loadSiiData(&data, file); + file.close(); } - // get length of file - file.seekg(0, ios::end); - byte_size = file.tellg(); - file.seekg(0, ios::beg); - - if (!byte_size || byte_size % 2) { - err << "Invalid file size! Must be non-zero and even."; - throwCommandException(err); - } - - data.nwords = byte_size / 2; - if (data.nwords < 0x0041 && !force) { - err << "SII data too short (" << data.nwords << " words)! Mimimum is" - " 40 fixed words + 1 delimiter. Use --force to write anyway."; - throwCommandException(err); - } - - // allocate buffer and read file into buffer - data.words = new uint16_t[data.nwords]; - file.read((char *) data.words, byte_size); - file.close(); - if (!force) { - // calculate checksum over words 0 to 6 - crc = calcSiiCrc((const uint8_t *) data.words, 14); - if (crc != ((const uint8_t *) data.words)[14]) { - err << "CRC incorrect. Must be 0x" - << hex << setfill('0') << setw(2) << (unsigned int) crc - << ". Use --force to write anyway."; - throwCommandException(err); - } - - // cycle through categories to detect corruption - categoryHeader = data.words + 0x0040U; - categoryType = le16tocpu(*categoryHeader); - while (categoryType != 0xffff) { - if (categoryHeader + 1 > data.words + data.nwords) { - err << "SII data seem to be corrupted! " - << "Use --force to write anyway."; - throwCommandException(err); - } - categorySize = le16tocpu(*(categoryHeader + 1)); - if (categoryHeader + 2 + categorySize + 1 - > data.words + data.nwords) { - err << "SII data seem to be corrupted! " - "Use --force to write anyway."; - throwCommandException(err); - } - categoryHeader += 2 + categorySize; - categoryType = le16tocpu(*categoryHeader); + try { + checkSiiData(&data); + } catch (CommandException &e) { + delete [] data.words; + throw e; } } - m.open(MasterDevice::ReadWrite); + try { + m.open(MasterDevice::ReadWrite); + } catch (MasterDeviceException &e) { + delete [] data.words; + throw e; + } + slaves = selectedSlaves(m); if (slaves.size() != 1) { + delete [] data.words; throwSingleSlaveRequired(slaves.size()); } data.slave_position = slaves.front().position; // send data to master data.offset = 0; - m.writeSii(&data); + try { + m.writeSii(&data); + } catch (MasterDeviceException &e) { + delete [] data.words; + throw e; + } + + if (getVerbosity() == Verbose) { + cerr << "SII writing finished." << endl; + } + + delete [] data.words; } /*****************************************************************************/ + +void CommandSiiWrite::loadSiiData( + ec_ioctl_slave_sii_t *data, + const istream &in + ) +{ + stringstream err; + ostringstream tmp; + + tmp << in.rdbuf(); + string const &contents = tmp.str(); + + if (getVerbosity() == Verbose) { + cerr << "Read " << contents.size() << " bytes of SII data." << endl; + } + + if (!contents.size() || contents.size() % 2) { + err << "Invalid data size " << contents.size() << "! " + << "Must be non-zero and even."; + throwCommandException(err); + } + data->nwords = contents.size() / 2; + + // allocate buffer and read file into buffer + data->words = new uint16_t[data->nwords]; + contents.copy((char *) data->words, contents.size()); +} + +/*****************************************************************************/ + +void CommandSiiWrite::checkSiiData( + const ec_ioctl_slave_sii_t *data + ) +{ + stringstream err; + const uint16_t *categoryHeader; + uint16_t categoryType, categorySize; + uint8_t crc; + + if (data->nwords < 0x0041) { + err << "SII data too short (" << data->nwords << " words)! Mimimum is" + " 40 fixed words + 1 delimiter. Use --force to write anyway."; + throwCommandException(err); + } + + // calculate checksum over words 0 to 6 + crc = calcSiiCrc((const uint8_t *) data->words, 14); + if (crc != ((const uint8_t *) data->words)[14]) { + err << "CRC incorrect. Must be 0x" + << hex << setfill('0') << setw(2) << (unsigned int) crc + << ". Use --force to write anyway."; + throwCommandException(err); + } + + // cycle through categories to detect corruption + categoryHeader = data->words + 0x0040U; + categoryType = le16tocpu(*categoryHeader); + while (categoryType != 0xffff) { + if (categoryHeader + 1 > data->words + data->nwords) { + err << "SII data seem to be corrupted! " + << "Use --force to write anyway."; + throwCommandException(err); + } + categorySize = le16tocpu(*(categoryHeader + 1)); + if (categoryHeader + 2 + categorySize + 1 + > data->words + data->nwords) { + err << "SII data seem to be corrupted! " + "Use --force to write anyway."; + throwCommandException(err); + } + categoryHeader += 2 + categorySize; + categoryType = le16tocpu(*categoryHeader); + } +} + +/*****************************************************************************/ diff -r f02ff486b313 -r d1324ac71232 tool/CommandSiiWrite.h --- a/tool/CommandSiiWrite.h Mon Jul 28 12:15:25 2008 +0000 +++ b/tool/CommandSiiWrite.h Mon Jul 28 13:15:19 2008 +0000 @@ -19,6 +19,10 @@ string helpString() const; void execute(MasterDevice &, const StringVector &); + + protected: + void loadSiiData(ec_ioctl_slave_sii_t *, const istream &); + void checkSiiData(const ec_ioctl_slave_sii_t *data); }; /****************************************************************************/