tool/CommandAlias.cpp
changeset 1142 59be91dfcbe1
child 1144 7dbfdd61812c
equal deleted inserted replaced
1141:7ffbca63fc72 1142:59be91dfcbe1
       
     1 /*****************************************************************************
       
     2  *
       
     3  * $Id$
       
     4  *
       
     5  ****************************************************************************/
       
     6 
       
     7 #include <iostream>
       
     8 #include <iomanip>
       
     9 #include <sstream>
       
    10 using namespace std;
       
    11 
       
    12 #include "CommandAlias.h"
       
    13 #include "sii_crc.h"
       
    14 #include "byteorder.h"
       
    15 
       
    16 /*****************************************************************************/
       
    17 
       
    18 CommandAlias::CommandAlias():
       
    19     Command("alias", "Write alias addresses.")
       
    20 {
       
    21 }
       
    22 
       
    23 /*****************************************************************************/
       
    24 
       
    25 string CommandAlias::helpString() const
       
    26 {
       
    27     stringstream str;
       
    28 
       
    29     str << getName() << " [OPTIONS] <ALIAS>" << endl
       
    30         << endl
       
    31         << getBriefDescription() << endl
       
    32         << endl
       
    33         << "Arguments:" << endl
       
    34         << "  ALIAS must be an unsigned 16 bit number. Zero means no alias."
       
    35         << endl << endl
       
    36         << "Command-specific options:" << endl
       
    37         << "  --slave -s <index>  Positive numerical ring position, or 'all'"
       
    38         << endl
       
    39         << "                      for all slaves (default). The --force"
       
    40         << endl
       
    41         << "                      option is required in this case." << endl
       
    42         << "  --force -f          Acknowledge writing aliases of all" << endl
       
    43         << "                      slaves." << endl
       
    44         << endl
       
    45         << numericInfo();
       
    46 
       
    47     return str.str();
       
    48 }
       
    49 
       
    50 /*****************************************************************************/
       
    51 
       
    52 /** Writes the Secondary slave address (alias) to the slave's SII.
       
    53  */
       
    54 void CommandAlias::execute(MasterDevice &m, const StringVector &args)
       
    55 {
       
    56     uint16_t alias;
       
    57     stringstream err, strAlias;
       
    58     int number;
       
    59     unsigned int numSlaves, i;
       
    60 
       
    61     if (args.size() != 1) {
       
    62         err << "'" << getName() << "' takes exactly one argument!";
       
    63         throwInvalidUsageException(err);
       
    64     }
       
    65 
       
    66     strAlias << args[0];
       
    67     strAlias
       
    68         >> resetiosflags(ios::basefield) // guess base from prefix
       
    69         >> number;
       
    70     if (strAlias.fail() || number < 0x0000 || number > 0xffff) {
       
    71         err << "Invalid alias '" << args[0] << "'!";
       
    72         throwInvalidUsageException(err);
       
    73     }
       
    74     alias = number;
       
    75 
       
    76     if (slavePosition == -1) {
       
    77         if (!force) {
       
    78             err << "This will write the alias addresses of all slaves to "
       
    79                 << alias << "! Please specify --force to proceed.";
       
    80             throwCommandException(err);
       
    81         }
       
    82 
       
    83         m.open(MasterDevice::ReadWrite);
       
    84         numSlaves = m.slaveCount();
       
    85 
       
    86         for (i = 0; i < numSlaves; i++) {
       
    87             writeSlaveAlias(m, i, alias);
       
    88         }
       
    89     } else {
       
    90         m.open(MasterDevice::ReadWrite);
       
    91         writeSlaveAlias(m, slavePosition, alias);
       
    92     }
       
    93 }
       
    94 
       
    95 /*****************************************************************************/
       
    96 
       
    97 /** Writes the Secondary slave address (alias) to the slave's SII.
       
    98  */
       
    99 void CommandAlias::writeSlaveAlias(
       
   100         MasterDevice &m,
       
   101         uint16_t slavePosition,
       
   102         uint16_t alias
       
   103         )
       
   104 {
       
   105     ec_ioctl_slave_sii_t data;
       
   106     ec_ioctl_slave_t slave;
       
   107     stringstream err;
       
   108     uint8_t crc;
       
   109 
       
   110     m.getSlave(&slave, slavePosition);
       
   111 
       
   112     if (slave.sii_nwords < 8) {
       
   113         err << "Current SII contents are too small to set an alias "
       
   114             << "(" << slave.sii_nwords << " words)!";
       
   115         throwCommandException(err);
       
   116     }
       
   117 
       
   118     // read first 8 SII words
       
   119     data.slave_position = slavePosition;
       
   120     data.offset = 0;
       
   121     data.nwords = 8;
       
   122     data.words = new uint16_t[data.nwords];
       
   123 
       
   124     try {
       
   125         m.readSii(&data);
       
   126     } catch (MasterDeviceException &e) {
       
   127         delete [] data.words;
       
   128         err << "Failed to read SII: " << e.what();
       
   129         throwCommandException(err);
       
   130     }
       
   131 
       
   132     // write new alias address in word 4
       
   133     data.words[4] = cputole16(alias);
       
   134 
       
   135     // calculate checksum over words 0 to 6
       
   136     crc = calcSiiCrc((const uint8_t *) data.words, 14);
       
   137 
       
   138     // write new checksum into first byte of word 7
       
   139     *(uint8_t *) (data.words + 7) = crc;
       
   140 
       
   141     // write first 8 words with new alias and checksum
       
   142     try {
       
   143         m.writeSii(&data);
       
   144     } catch (MasterDeviceException &e) {
       
   145         delete [] data.words;
       
   146         err << "Failed to read SII: " << e.what();
       
   147         throwCommandException(err);
       
   148     }
       
   149 
       
   150     delete [] data.words;
       
   151 }
       
   152 
       
   153 /*****************************************************************************/