brimtrans.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       brimtrans.cc
00003 ///             Translates log files generated by RIM's USB driver
00004 ///             into something more or less readable.
00005 ///
00006 
00007 /*
00008     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00009     Copyright (C) 2009, Josh Kropf
00010 
00011     This program is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     This program is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00019 
00020     See the GNU General Public License in the COPYING file at the
00021     root directory of this project for more details.
00022 */
00023 
00024 #include <iostream>
00025 #include <iomanip>
00026 #include <sstream>
00027 #include <string>
00028 #include <vector>
00029 #include <list>
00030 #include <cctype>
00031 #include <stdint.h>
00032 #include "i18n.h"
00033 
00034 using namespace std;
00035 
00036 string trim_right(const string& source , const string& t = " ");
00037 string trim_data_line(const string& line);
00038 void dump(const list<string>& event);
00039 void parse_hex(const string& source, vector<uint16_t>& data);
00040 void print_hex(const vector<uint16_t>& data);
00041 
00042 int main(int argc, char* argv[])
00043 {
00044         list<string>* event = NULL;
00045         string line;
00046 
00047         INIT_I18N(PACKAGE);
00048 
00049         while( !getline(cin, line).eof() ) {
00050                 size_t pos = line.find_first_of(':');
00051 
00052                 // skip lines missing colon
00053                 if( pos == string::npos )
00054                         continue;
00055 
00056                 line = trim_right(line.substr(pos + 2), "\n\r ");
00057 
00058                 // each sequence of write/read packets begins with this line
00059                 if( line == "BbUsbDevice: WriteToDevice" ) {
00060                         if( event != NULL ) {
00061                                 dump(*event);
00062                                 delete event;
00063                         }
00064 
00065                         event = new list<string>;
00066                 }
00067                 else if( line.substr(0, 3) == "<-:" ) { // send to device
00068                         event->push_front(trim_data_line(line.erase(0, 3)));
00069                 }
00070                 else if( line.substr(0, 3) == "->:" ) { // receive from device
00071                         event->push_back(trim_data_line(line.erase(0, 3)));
00072                 }
00073         }
00074 
00075         if( event != NULL ) {
00076                 dump(*event);
00077                 delete event;
00078         }
00079 
00080         return 0;
00081 }
00082 
00083 string trim_right(const string& source , const string& t)
00084 {
00085         string str = source;
00086         return str.erase(str.find_last_not_of(t) + 1);
00087 }
00088 
00089 string trim_data_line(const string& line)
00090 {
00091         size_t pos = line.find_first_of(':');
00092         return line.substr(pos + 2);
00093 }
00094 
00095 void dump(const list<string>& event)
00096 {
00097         vector<uint16_t> data;
00098         list<string>::const_iterator i, begin = event.begin(), end = event.end();
00099         for( i=begin; i != end; ++i ) {
00100                 data.clear();
00101                 parse_hex(*i, data);
00102                 cout << (i == begin? "Send" : "Receive") << endl;
00103                 print_hex(data);
00104         }
00105         cout << endl;
00106 }
00107 
00108 void parse_hex(const string& source, vector<uint16_t>& data)
00109 {
00110         istringstream ss(source);
00111         uint16_t byte;
00112 
00113         while( !ss.eof() ) {
00114                 ss >> hex >> byte;
00115                 data.push_back(byte);
00116         }
00117 }
00118 
00119 void print_hex(const vector<uint16_t>& data)
00120 {
00121         int remaining = data.size(), offset = 0;
00122         do {
00123                 cout << "    " << hex << setfill('0') << setw(8) << offset;
00124                 int margin = 13;
00125 
00126                 for( int i=0, stop=min(16, remaining); i<stop; i++ ) {
00127                         cout << ' ' << hex << setfill('0') << setw(2) << data[offset + i];
00128                         margin += 3;
00129                 }
00130 
00131                 cout << string(62-margin, ' ');
00132 
00133                 for( int i=0, stop=min(16, remaining); i<stop; i++) {
00134                         char c = data[offset + i];
00135                         cout << (isprint(c)? c : '.');
00136                 }
00137 
00138                 offset += 16;
00139                 remaining -= 16;
00140 
00141                 cout << endl;
00142         } while( remaining > 0 );
00143 }