tool/CommandSoeWrite.cpp
changeset 1968 4f682084c643
parent 1966 23c638a81fe7
equal deleted inserted replaced
1967:c41b4f4af645 1968:4f682084c643
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    27  *
    27  *
    28  ****************************************************************************/
    28  ****************************************************************************/
    29 
    29 
    30 #include <iostream>
    30 #include <iostream>
       
    31 #include <iomanip>
    31 using namespace std;
    32 using namespace std;
    32 
    33 
    33 #include "CommandSoeWrite.h"
    34 #include "CommandSoeWrite.h"
    34 #include "MasterDevice.h"
    35 #include "MasterDevice.h"
    35 
    36 
    40 {
    41 {
    41 }
    42 }
    42 
    43 
    43 /*****************************************************************************/
    44 /*****************************************************************************/
    44 
    45 
    45 string CommandSoeWrite::helpString() const
    46 string CommandSoeWrite::helpString(const string &binaryBaseName) const
    46 {
    47 {
    47     stringstream str;
    48     stringstream str;
    48 
    49 
    49     str << getName() << " [OPTIONS] <IDN> <VALUE>" << endl
    50     str << binaryBaseName << " " << getName()
       
    51         << " [OPTIONS] <IDN> <VALUE>" << endl
       
    52         << binaryBaseName << " " << getName()
       
    53         << " [OPTIONS] <DRIVE> <IDN> <VALUE>" << endl
    50         << endl
    54         << endl
    51         << getBriefDescription() << endl
    55         << getBriefDescription() << endl
    52         << endl
    56         << endl
    53         << "This command requires a single slave to be selected." << endl
    57         << "This command requires a single slave to be selected." << endl
    54         << endl
    58         << endl
    55         << "Arguments:" << endl
    59         << "Arguments:" << endl
       
    60         << "  DRIVE    is the drive number (0 - 7). If omitted, 0 is assumed."
       
    61         << endl
    56         << "  IDN      is the IDN and must be either an unsigned" << endl
    62         << "  IDN      is the IDN and must be either an unsigned" << endl
    57         << "           16 bit number acc. to IEC 61800-7-204:" << endl
    63         << "           16 bit number acc. to IEC 61800-7-204:" << endl
    58         << "             Bit 15: (0) Standard data, (1) Product data" << endl
    64         << "             Bit 15: (0) Standard data, (1) Product data" << endl
    59         << "             Bit 14 - 12: Parameter set (0 - 7)" << endl
    65         << "             Bit 14 - 12: Parameter set (0 - 7)" << endl
    60         << "             Bit 11 - 0: Data block number" << endl
    66         << "             Bit 11 - 0: Data block number" << endl
    79 
    85 
    80 /****************************************************************************/
    86 /****************************************************************************/
    81 
    87 
    82 void CommandSoeWrite::execute(const StringVector &args)
    88 void CommandSoeWrite::execute(const StringVector &args)
    83 {
    89 {
    84     stringstream strIdn, err;
    90     stringstream err;
    85     const DataType *dataType = NULL;
    91     const DataType *dataType = NULL;
    86     ec_ioctl_slave_soe_write_t ioctl;
    92     ec_ioctl_slave_soe_write_t ioctl;
    87     SlaveList slaves;
    93     SlaveList slaves;
    88     size_t memSize;
    94     size_t memSize;
       
    95     int driveArgIndex = -1, idnArgIndex = -1, valueArgIndex = -1;
    89 
    96 
    90     if (args.size() != 2) {
    97     if (args.size() == 2) {
    91         err << "'" << getName() << "' takes 2 arguments!";
    98         idnArgIndex = 0;
       
    99         valueArgIndex = 1;
       
   100     } else if (args.size() == 3) {
       
   101         driveArgIndex = 0;
       
   102         idnArgIndex = 1;
       
   103         valueArgIndex = 2;
       
   104     } else {
       
   105         err << "'" << getName() << "' takes eiter 2 or 3 arguments!";
    92         throwInvalidUsageException(err);
   106         throwInvalidUsageException(err);
    93     }
   107     }
    94 
   108 
    95     ioctl.drive_no = 0; // FIXME
   109     if (driveArgIndex >= 0) {
       
   110         stringstream str;
       
   111         unsigned int number;
       
   112         str << args[driveArgIndex];
       
   113         str
       
   114             >> resetiosflags(ios::basefield) // guess base from prefix
       
   115             >> number;
       
   116         if (str.fail() || number > 7) {
       
   117             err << "Invalid drive number '" << args[driveArgIndex] << "'!";
       
   118             throwInvalidUsageException(err);
       
   119         }
       
   120         ioctl.drive_no = number;
       
   121     } else {
       
   122         ioctl.drive_no = 0;
       
   123     }
    96 
   124 
    97     try {
   125     try {
    98         ioctl.idn = parseIdn(args[0]);
   126         ioctl.idn = parseIdn(args[idnArgIndex]);
    99     } catch (runtime_error &e) {
   127     } catch (runtime_error &e) {
   100         err << "Invalid IDN '" << args[0] << "': " << e.what();
   128         err << "Invalid IDN '" << args[idnArgIndex] << "': " << e.what();
   101         throwInvalidUsageException(err);
   129         throwInvalidUsageException(err);
   102     }
   130     }
   103 
   131 
   104     MasterDevice m(getSingleMasterIndex());
   132     MasterDevice m(getSingleMasterIndex());
   105     m.open(MasterDevice::ReadWrite);
   133     m.open(MasterDevice::ReadWrite);
   121 
   149 
   122     if (dataType->byteSize) {
   150     if (dataType->byteSize) {
   123         memSize = dataType->byteSize;
   151         memSize = dataType->byteSize;
   124     } else {
   152     } else {
   125         // guess string type size
   153         // guess string type size
   126         memSize = args[1].size() + 1;
   154         memSize = args[valueArgIndex].size() + 1;
   127         if (!memSize) {
   155         if (!memSize) {
   128             err << "Empty argument not allowed.";
   156             err << "Empty argument not allowed.";
   129             throwInvalidUsageException(err);
   157             throwInvalidUsageException(err);
   130         }
   158         }
   131     }
   159     }
   132 
   160 
   133     ioctl.data = new uint8_t[memSize];
   161     ioctl.data = new uint8_t[memSize];
   134 
   162 
   135     try {
   163     try {
   136         ioctl.data_size = interpretAsType(
   164         ioctl.data_size = interpretAsType(
   137                 dataType, args[1], ioctl.data, memSize);
   165                 dataType, args[valueArgIndex], ioctl.data, memSize);
   138     } catch (SizeException &e) {
   166     } catch (SizeException &e) {
   139         delete [] ioctl.data;
   167         delete [] ioctl.data;
   140         throwCommandException(e.what());
   168         throwCommandException(e.what());
   141     } catch (ios::failure &e) {
   169     } catch (ios::failure &e) {
   142         delete [] ioctl.data;
   170         delete [] ioctl.data;
   143         err << "Invalid value argument '" << args[1]
   171         err << "Invalid value argument '" << args[valueArgIndex]
   144             << "' for type '" << dataType->name << "'!";
   172             << "' for type '" << dataType->name << "'!";
   145         throwInvalidUsageException(err);
   173         throwInvalidUsageException(err);
   146     }
   174     }
   147 
   175 
   148     try {
   176     try {