tool/cmd_sii_write.cpp
changeset 1126 b09fd81894cb
child 1130 bb1c11adb2db
equal deleted inserted replaced
1125:9976f7b9fe66 1126:b09fd81894cb
       
     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]\n"
       
    19     "\n"
       
    20     "\n"
       
    21     "Command-specific options:\n";
       
    22 
       
    23 /****************************************************************************/
       
    24 
       
    25 void command_sii_write(void)
       
    26 {
       
    27     stringstream err;
       
    28     ec_ioctl_slave_sii_t data;
       
    29     ifstream file;
       
    30     unsigned int byte_size;
       
    31     const uint16_t *categoryHeader;
       
    32     uint16_t categoryType, categorySize;
       
    33     uint8_t crc;
       
    34 
       
    35     if (slavePosition < 0) {
       
    36         err << "'sii_write' requires a slave! Please specify --slave.";
       
    37         throw MasterDeviceException(err.str());
       
    38     }
       
    39     data.slave_position = slavePosition;
       
    40 
       
    41     if (commandArgs.size() != 1) {
       
    42         err << "'ssi_write' takes exactly one argument!";
       
    43         throw MasterDeviceException(err.str());
       
    44     }
       
    45 
       
    46     file.open(commandArgs[0].c_str(), ifstream::in | ifstream::binary);
       
    47     if (file.fail()) {
       
    48         err << "Failed to open '" << commandArgs[0] << "'!";
       
    49         throw MasterDeviceException(err.str());
       
    50     }
       
    51 
       
    52     // get length of file
       
    53     file.seekg(0, ios::end);
       
    54     byte_size = file.tellg();
       
    55     file.seekg(0, ios::beg);
       
    56 
       
    57     if (!byte_size || byte_size % 2) {
       
    58         stringstream err;
       
    59         err << "Invalid file size! Must be non-zero and even.";
       
    60         throw MasterDeviceException(err.str());
       
    61     }
       
    62 
       
    63     data.nwords = byte_size / 2;
       
    64     if (data.nwords < 0x0041 && !force) {
       
    65         err << "SII data too short (" << data.nwords << " words)! Mimimum is"
       
    66                 " 40 fixed words + 1 delimiter. Use --force to write anyway.";
       
    67         throw MasterDeviceException(err.str());
       
    68     }
       
    69 
       
    70     // allocate buffer and read file into buffer
       
    71     data.words = new uint16_t[data.nwords];
       
    72     file.read((char *) data.words, byte_size);
       
    73     file.close();
       
    74 
       
    75     if (!force) {
       
    76         // calculate checksum over words 0 to 6
       
    77         crc = calcSiiCrc((const uint8_t *) data.words, 14);
       
    78         if (crc != ((const uint8_t *) data.words)[14]) {
       
    79             err << "CRC incorrect. Must be 0x"
       
    80                 << hex << setfill('0') << setw(2) << (unsigned int) crc
       
    81                 << ". Use --force to write anyway.";
       
    82             throw MasterDeviceException(err.str());
       
    83         }
       
    84 
       
    85         // cycle through categories to detect corruption
       
    86         categoryHeader = data.words + 0x0040U;
       
    87         categoryType = le16tocpu(*categoryHeader);
       
    88         while (categoryType != 0xffff) {
       
    89             if (categoryHeader + 1 > data.words + data.nwords) {
       
    90                 err << "SII data seem to be corrupted! "
       
    91                     << "Use --force to write anyway.";
       
    92                 throw MasterDeviceException(err.str());
       
    93             }
       
    94             categorySize = le16tocpu(*(categoryHeader + 1));
       
    95             if (categoryHeader + 2 + categorySize + 1
       
    96                     > data.words + data.nwords) {
       
    97                 err << "SII data seem to be corrupted! "
       
    98                     "Use --force to write anyway.";
       
    99                 throw MasterDeviceException(err.str());
       
   100             }
       
   101             categoryHeader += 2 + categorySize;
       
   102             categoryType = le16tocpu(*categoryHeader);
       
   103         }
       
   104     }
       
   105 
       
   106     // send data to master
       
   107     masterDev.open(MasterDevice::ReadWrite);
       
   108     data.offset = 0;
       
   109 	masterDev.writeSii(&data);
       
   110 }
       
   111 
       
   112 /*****************************************************************************/