tool/cmd_sii_write.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 <fstream>
       
    10 using namespace std;
       
    11 
       
    12 #include "globals.h"
       
    13 #include "sii_crc.h"
       
    14 
       
    15 /****************************************************************************/
       
    16 
       
    17 const char *help_sii_write =
       
    18     "[OPTIONS] <FILENAME>\n"
       
    19     "\n"
       
    20     "Writes SII contents from a local file to a slave.\n"
       
    21     "\n"
       
    22     "The file contents are checked for validity and integrity. These checks\n"
       
    23     "can be overridden with the --force option.\n"
       
    24     "\n"
       
    25     "Arguments:\n"
       
    26     "  FILENAME must be a path to a file that contains a positive number\n"
       
    27     "           of words.\n"
       
    28     "\n"
       
    29     "Command-specific options:\n"
       
    30     "  --slave -s <index>  Positive numerical ring position (mandatory).\n"
       
    31     "  --force             Override validity checks.\n"
       
    32     "\n"
       
    33     "Numerical values can be specified either with decimal (no prefix),\n"
       
    34     "octal (prefix '0') or hexadecimal (prefix '0x') base.\n";
       
    35 
       
    36 /****************************************************************************/
       
    37 
       
    38 void command_sii_write(void)
       
    39 {
       
    40     stringstream err;
       
    41     ec_ioctl_slave_sii_t data;
       
    42     ifstream file;
       
    43     unsigned int byte_size;
       
    44     const uint16_t *categoryHeader;
       
    45     uint16_t categoryType, categorySize;
       
    46     uint8_t crc;
       
    47 
       
    48     if (slavePosition < 0) {
       
    49         err << "'" << commandName << "' requires a slave! "
       
    50             << "Please specify --slave.";
       
    51         throw InvalidUsageException(err);
       
    52     }
       
    53     data.slave_position = slavePosition;
       
    54 
       
    55     if (commandArgs.size() != 1) {
       
    56         err << "'" << commandName << "' takes exactly one argument!";
       
    57         throw InvalidUsageException(err);
       
    58     }
       
    59 
       
    60     file.open(commandArgs[0].c_str(), ifstream::in | ifstream::binary);
       
    61     if (file.fail()) {
       
    62         err << "Failed to open '" << commandArgs[0] << "'!";
       
    63         throw CommandException(err);
       
    64     }
       
    65 
       
    66     // get length of file
       
    67     file.seekg(0, ios::end);
       
    68     byte_size = file.tellg();
       
    69     file.seekg(0, ios::beg);
       
    70 
       
    71     if (!byte_size || byte_size % 2) {
       
    72         err << "Invalid file size! Must be non-zero and even.";
       
    73         throw CommandException(err);
       
    74     }
       
    75 
       
    76     data.nwords = byte_size / 2;
       
    77     if (data.nwords < 0x0041 && !force) {
       
    78         err << "SII data too short (" << data.nwords << " words)! Mimimum is"
       
    79                 " 40 fixed words + 1 delimiter. Use --force to write anyway.";
       
    80         throw CommandException(err);
       
    81     }
       
    82 
       
    83     // allocate buffer and read file into buffer
       
    84     data.words = new uint16_t[data.nwords];
       
    85     file.read((char *) data.words, byte_size);
       
    86     file.close();
       
    87 
       
    88     if (!force) {
       
    89         // calculate checksum over words 0 to 6
       
    90         crc = calcSiiCrc((const uint8_t *) data.words, 14);
       
    91         if (crc != ((const uint8_t *) data.words)[14]) {
       
    92             err << "CRC incorrect. Must be 0x"
       
    93                 << hex << setfill('0') << setw(2) << (unsigned int) crc
       
    94                 << ". Use --force to write anyway.";
       
    95             throw CommandException(err);
       
    96         }
       
    97 
       
    98         // cycle through categories to detect corruption
       
    99         categoryHeader = data.words + 0x0040U;
       
   100         categoryType = le16tocpu(*categoryHeader);
       
   101         while (categoryType != 0xffff) {
       
   102             if (categoryHeader + 1 > data.words + data.nwords) {
       
   103                 err << "SII data seem to be corrupted! "
       
   104                     << "Use --force to write anyway.";
       
   105                 throw CommandException(err);
       
   106             }
       
   107             categorySize = le16tocpu(*(categoryHeader + 1));
       
   108             if (categoryHeader + 2 + categorySize + 1
       
   109                     > data.words + data.nwords) {
       
   110                 err << "SII data seem to be corrupted! "
       
   111                     "Use --force to write anyway.";
       
   112                 throw CommandException(err);
       
   113             }
       
   114             categoryHeader += 2 + categorySize;
       
   115             categoryType = le16tocpu(*categoryHeader);
       
   116         }
       
   117     }
       
   118 
       
   119     // send data to master
       
   120     masterDev.open(MasterDevice::ReadWrite);
       
   121     data.offset = 0;
       
   122 	masterDev.writeSii(&data);
       
   123 }
       
   124 
       
   125 /*****************************************************************************/