tool/cmd_alias.cpp
changeset 1142 59be91dfcbe1
parent 1141 7ffbca63fc72
child 1143 09ee878d7214
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 "globals.h"
       
    13 #include "sii_crc.h"
       
    14 
       
    15 /*****************************************************************************/
       
    16 
       
    17 const char *help_alias =
       
    18     "[OPTIONS] <ALIAS>\n"
       
    19     "\n"
       
    20     "Write the secondary slave address (alias) for either\n"
       
    21     "one or for multiple slaves.\n"
       
    22     "\n"
       
    23     "Arguments:\n"
       
    24     "  ALIAS must be an unsigned 16 bit number. Zero means no alias.\n"
       
    25     "\n"
       
    26     "Command-specific options:\n"
       
    27     "  --slave -s <index>  Positive numerical ring position, or 'all' for\n"
       
    28     "                      all slaves (default). The --force option is\n"
       
    29     "                      required in this case.\n"
       
    30     "  --force             Acknowledge writing aliases of all slaves.\n"
       
    31     "\n"
       
    32     "Numerical values can be specified either with decimal (no prefix),\n"
       
    33     "octal (prefix '0') or hexadecimal (prefix '0x') base.\n";
       
    34 
       
    35 /*****************************************************************************/
       
    36 
       
    37 void writeSlaveAlias(uint16_t, uint16_t);
       
    38 
       
    39 /*****************************************************************************/
       
    40 
       
    41 /** Writes the Secondary slave address (alias) to the slave's SII.
       
    42  */
       
    43 void command_alias(void)
       
    44 {
       
    45     uint16_t alias;
       
    46     stringstream err, strAlias;
       
    47     int number;
       
    48     unsigned int numSlaves, i;
       
    49 
       
    50     if (commandArgs.size() != 1) {
       
    51         err << "'" << commandName << "' takes exactly one argument!";
       
    52         throw InvalidUsageException(err);
       
    53     }
       
    54 
       
    55     strAlias << commandArgs[0];
       
    56     strAlias
       
    57         >> resetiosflags(ios::basefield) // guess base from prefix
       
    58         >> number;
       
    59     if (strAlias.fail() || number < 0x0000 || number > 0xffff) {
       
    60         err << "Invalid alias '" << commandArgs[0] << "'!";
       
    61         throw InvalidUsageException(err);
       
    62     }
       
    63     alias = number;
       
    64 
       
    65     if (slavePosition == -1) {
       
    66         if (!force) {
       
    67             err << "This will write the alias addresses of all slaves to "
       
    68                 << alias << "! Please specify --force to proceed.";
       
    69             throw CommandException(err);
       
    70         }
       
    71 
       
    72         masterDev.open(MasterDevice::ReadWrite);
       
    73         numSlaves = masterDev.slaveCount();
       
    74 
       
    75         for (i = 0; i < numSlaves; i++) {
       
    76             writeSlaveAlias(i, alias);
       
    77         }
       
    78     } else {
       
    79         masterDev.open(MasterDevice::ReadWrite);
       
    80         writeSlaveAlias(slavePosition, alias);
       
    81     }
       
    82 }
       
    83 
       
    84 /*****************************************************************************/
       
    85 
       
    86 /** Writes the Secondary slave address (alias) to the slave's SII.
       
    87  */
       
    88 void writeSlaveAlias(
       
    89         uint16_t slavePosition,
       
    90         uint16_t alias
       
    91         )
       
    92 {
       
    93     ec_ioctl_slave_sii_t data;
       
    94     ec_ioctl_slave_t slave;
       
    95     stringstream err;
       
    96     uint8_t crc;
       
    97 
       
    98     masterDev.getSlave(&slave, slavePosition);
       
    99 
       
   100     if (slave.sii_nwords < 8) {
       
   101         err << "Current SII contents are too small to set an alias "
       
   102             << "(" << slave.sii_nwords << " words)!";
       
   103         throw CommandException(err);
       
   104     }
       
   105 
       
   106     // read first 8 SII words
       
   107     data.slave_position = slavePosition;
       
   108     data.offset = 0;
       
   109     data.nwords = 8;
       
   110     data.words = new uint16_t[data.nwords];
       
   111 
       
   112     try {
       
   113         masterDev.readSii(&data);
       
   114     } catch (MasterDeviceException &e) {
       
   115         delete [] data.words;
       
   116         err << "Failed to read SII: " << e.what();
       
   117         throw CommandException(err);
       
   118     }
       
   119 
       
   120     // write new alias address in word 4
       
   121     data.words[4] = cputole16(alias);
       
   122 
       
   123     // calculate checksum over words 0 to 6
       
   124     crc = calcSiiCrc((const uint8_t *) data.words, 14);
       
   125 
       
   126     // write new checksum into first byte of word 7
       
   127     *(uint8_t *) (data.words + 7) = crc;
       
   128 
       
   129     // write first 8 words with new alias and checksum
       
   130     try {
       
   131         masterDev.writeSii(&data);
       
   132     } catch (MasterDeviceException &e) {
       
   133         delete [] data.words;
       
   134         err << "Failed to read SII: " << e.what();
       
   135         throw CommandException(err);
       
   136     }
       
   137 
       
   138     delete [] data.words;
       
   139 }
       
   140 
       
   141 /*****************************************************************************/