tool/CommandSiiRead.cpp
changeset 1142 59be91dfcbe1
child 1151 1fc1535dec29
equal deleted inserted replaced
1141:7ffbca63fc72 1142:59be91dfcbe1
       
     1 /*****************************************************************************
       
     2  *
       
     3  * $Id$
       
     4  *
       
     5  ****************************************************************************/
       
     6 
       
     7 #include <iostream>
       
     8 #include <iomanip>
       
     9 using namespace std;
       
    10 
       
    11 #include "CommandSiiRead.h"
       
    12 #include "byteorder.h"
       
    13 
       
    14 /*****************************************************************************/
       
    15 
       
    16 CommandSiiRead::CommandSiiRead():
       
    17     Command("sii_read", "Output a slave's SII contents.")
       
    18 {
       
    19 }
       
    20 
       
    21 /*****************************************************************************/
       
    22 
       
    23 string CommandSiiRead::helpString() const
       
    24 {
       
    25     stringstream str;
       
    26 
       
    27     str << getName() << " [OPTIONS]" << endl
       
    28     	<< endl
       
    29     	<< getBriefDescription() << endl
       
    30     	<< endl
       
    31     	<< "Without the --verbose option, binary SII contents are" << endl
       
    32 		<< "output." << endl
       
    33     	<< endl
       
    34     	<< "With the --verbose option given, a textual representation" << endl
       
    35 		<< "of the data is output, that is separated by SII category" << endl
       
    36 		<< "names." << endl
       
    37     	<< endl
       
    38     	<< "Command-specific options:" << endl
       
    39     	<< "  --slave   -s <index>  Positive numerical ring position" << endl
       
    40 		<< "                        (mandatory)." << endl
       
    41     	<< "  --verbose -v          Output textual data with" << endl
       
    42 		<< "                        category names." << endl
       
    43     	<< endl
       
    44 		<< numericInfo();
       
    45 
       
    46 	return str.str();
       
    47 }
       
    48 
       
    49 /****************************************************************************/
       
    50 
       
    51 void CommandSiiRead::execute(MasterDevice &m, const StringVector &args)
       
    52 {
       
    53     ec_ioctl_slave_sii_t data;
       
    54     ec_ioctl_slave_t slave;
       
    55     unsigned int i;
       
    56     const uint16_t *categoryHeader;
       
    57     uint16_t categoryType, categorySize;
       
    58     stringstream err;
       
    59 
       
    60     if (slavePosition < 0) {
       
    61         err << "'" << getName() << "' requires a slave! "
       
    62             << "Please specify --slave.";
       
    63         throwInvalidUsageException(err);
       
    64     }
       
    65     data.slave_position = slavePosition;
       
    66 
       
    67     m.open(MasterDevice::Read);
       
    68 
       
    69     m.getSlave(&slave, slavePosition);
       
    70 
       
    71     if (!slave.sii_nwords)
       
    72         return;
       
    73 
       
    74     data.offset = 0;
       
    75     data.nwords = slave.sii_nwords;
       
    76     data.words = new uint16_t[data.nwords];
       
    77 
       
    78 	try {
       
    79 		m.readSii(&data);
       
    80 	} catch (MasterDeviceException &e) {
       
    81         delete [] data.words;
       
    82 		throw e;
       
    83 	}
       
    84 
       
    85     if (getVerbosity() == Verbose) {
       
    86         cout << "SII Area:" << hex << setfill('0');
       
    87         for (i = 0; i < min(data.nwords, 0x0040U) * 2; i++) {
       
    88             if (i % BreakAfterBytes) {
       
    89                 cout << " ";
       
    90             } else {
       
    91                 cout << endl << "  ";
       
    92             }
       
    93             cout << setw(2) << (unsigned int) *((uint8_t *) data.words + i);
       
    94         }
       
    95         cout << endl;
       
    96 
       
    97         if (data.nwords > 0x0040U) {
       
    98             // cycle through categories
       
    99             categoryHeader = data.words + 0x0040U;
       
   100             categoryType = le16tocpu(*categoryHeader);
       
   101             while (categoryType != 0xffff) {
       
   102                 cout << "SII Category 0x" << hex
       
   103                     << setw(4) << categoryType
       
   104                     << " (" << getCategoryName(categoryType) << ")" << flush;
       
   105 
       
   106                 if (categoryHeader + 1 > data.words + data.nwords) {
       
   107                     err << "SII data seem to be corrupted!";
       
   108                     throwCommandException(err);
       
   109                 }
       
   110                 categorySize = le16tocpu(*(categoryHeader + 1));
       
   111                 cout << ", " << dec << categorySize << " words" << flush;
       
   112 
       
   113                 if (categoryHeader + 2 + categorySize
       
   114                         > data.words + data.nwords) {
       
   115                     err << "SII data seem to be corrupted!";
       
   116                     throwCommandException(err);
       
   117                 }
       
   118 
       
   119                 cout << hex;
       
   120                 for (i = 0; i < categorySize * 2U; i++) {
       
   121                     if (i % BreakAfterBytes) {
       
   122                         cout << " ";
       
   123                     } else {
       
   124                         cout << endl << "  ";
       
   125                     }
       
   126                     cout << setw(2) << (unsigned int)
       
   127                         *((uint8_t *) (categoryHeader + 2) + i);
       
   128                 }
       
   129                 cout << endl;
       
   130 
       
   131                 if (categoryHeader + 2 + categorySize + 1
       
   132                         > data.words + data.nwords) {
       
   133                     err << "SII data seem to be corrupted!"; 
       
   134                     throwCommandException(err);
       
   135                 }
       
   136                 categoryHeader += 2 + categorySize;
       
   137                 categoryType = le16tocpu(*categoryHeader);
       
   138             }
       
   139         }
       
   140     } else {
       
   141         for (i = 0; i < data.nwords; i++) {
       
   142             uint16_t *w = data.words + i;
       
   143             cout << *(uint8_t *) w << *((uint8_t *) w + 1);
       
   144         }
       
   145     }
       
   146 
       
   147     delete [] data.words;
       
   148 }
       
   149 
       
   150 /****************************************************************************/
       
   151 
       
   152 const CommandSiiRead::CategoryName CommandSiiRead::categoryNames[] = {
       
   153     {0x000a, "STRINGS"},
       
   154     {0x0014, "DataTypes"},
       
   155     {0x001e, "General"},
       
   156     {0x0028, "FMMU"},
       
   157     {0x0029, "SyncM"},
       
   158     {0x0032, "TXPDO"},
       
   159     {0x0033, "RXPDO"},
       
   160     {0x003c, "DC"},
       
   161     {}
       
   162 };
       
   163 
       
   164 /****************************************************************************/
       
   165 
       
   166 const char *CommandSiiRead::getCategoryName(uint16_t type)
       
   167 {
       
   168     const CategoryName *cn = categoryNames;
       
   169 
       
   170     while (cn->type) {
       
   171         if (cn->type == type) {
       
   172             return cn->name;
       
   173         }
       
   174         cn++;
       
   175     }
       
   176 
       
   177     return "unknown";
       
   178 }
       
   179 
       
   180 /*****************************************************************************/