Subversion Repositories HomeAutomation

Rev

Rev 991 | Rev 999 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /***************************************************************************
  2.  *   Copyright (C) November 28, 2008 by Mattias Runge                             *
  3.  *   mattias@runge.se                                                      *
  4.  *   canmessage.cpp                                            *
  5.  *                                                                         *
  6.  *   This program is free software; you can redistribute it and/or modify  *
  7.  *   it under the terms of the GNU General Public License as published by  *
  8.  *   the Free Software Foundation; either version 2 of the License, or     *
  9.  *   (at your option) any later version.                                   *
  10.  *                                                                         *
  11.  *   This program is distributed in the hope that it will be useful,       *
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  14.  *   GNU General Public License for more details.                          *
  15.  *                                                                         *
  16.  *   You should have received a copy of the GNU General Public License     *
  17.  *   along with this program; if not, write to the                         *
  18.  *   Free Software Foundation, Inc.,                                       *
  19.  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  20.  ***************************************************************************/
  21.  
  22. #include <string>
  23. #include <iostream>
  24. #include "canidtranslator.h"
  25. #include "canmessage.h"
  26.  
  27. void CanMessage::setRaw(string rawHex)
  28. {
  29.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  30.     //SyslogStream &slog = SyslogStream::getInstance();
  31.  
  32.     //PKT 00060102 1 0 00 00 c4
  33.  
  34.     rawHex = trim(rawHex, '\n');
  35.     rawHex = trim(rawHex);
  36.  
  37.     vector<string> parts = explode(" ", rawHex);
  38.  
  39.     if (parts.size() < 2 || parts[0].compare("PKT") != 0)
  40.     {
  41.         //slog << "Malformed can message received from canDaemon: \"" << rawHex << "\"\n";
  42.         throw new CanMessageException("Malformed can message received from canDaemon");
  43.     }
  44.  
  45.     string rawHeaderBin = hex2bin(parts[1]);
  46.    
  47.     try
  48.     {
  49.         myClassName = translator.lookupClassName(bin2uint(rawHeaderBin.substr(3, 4)));
  50.     }
  51.     catch (std::out_of_range& e)
  52.     {
  53.         cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  54.         cout << "DEBUG: A rawHeaderBin=" << rawHeaderBin << endl;
  55.     }
  56.  
  57.  
  58.     if (myClassName == "")
  59.     {
  60.         myIsUnknown = true;
  61.         return;
  62.     }
  63.     else
  64.     {
  65.         myIsUnknown = false;
  66.     }
  67.  
  68.     string rawHexData = "";
  69.     for (int n = 4; n < parts.size(); n++)
  70.     {
  71.         rawHexData += parts[n];
  72.     }
  73.  
  74.     if (myClassName == "nmt")
  75.     {
  76.         int commandId;
  77.  
  78.         try
  79.         {
  80.             commandId = bin2uint(rawHeaderBin.substr(8, 8));
  81.         }
  82.         catch (std::out_of_range& e)
  83.         {
  84.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  85.             cout << "DEBUG: B rawHeaderBin=" << rawHeaderBin << endl;
  86.         }
  87.  
  88.         myCommandName = translator.lookupNMTCommandName(commandId);
  89.  
  90.         myData = translator.translateNMTData(commandId, rawHexData);
  91.     }
  92.     else
  93.     {
  94.         try
  95.         {
  96.             myDirectionFlag = translator.lookupDirectionFlag(bin2uint(rawHeaderBin.substr(7, 1)));
  97.         }
  98.         catch (std::out_of_range& e)
  99.         {
  100.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  101.             cout << "DEBUG: C rawHeaderBin=" << rawHeaderBin << endl;
  102.         }
  103.  
  104.         try
  105.         {
  106.             myModuleName = translator.lookupModuleName(bin2uint(rawHeaderBin.substr(8, 8)));
  107.         }
  108.         catch (std::out_of_range& e)
  109.         {
  110.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  111.             cout << "DEBUG: D rawHeaderBin=" << rawHeaderBin << endl;
  112.         }
  113.  
  114.         try
  115.         {
  116.             myModuleId = bin2uint(rawHeaderBin.substr(16, 8));
  117.         }
  118.         catch (std::out_of_range& e)
  119.         {
  120.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  121.             cout << "DEBUG: E rawHeaderBin=" << rawHeaderBin << endl;
  122.         }
  123.  
  124.         int commandId;
  125.  
  126.         try
  127.         {
  128.             commandId = bin2uint(rawHeaderBin.substr(24, 8));
  129.         }
  130.         catch (std::out_of_range& e)
  131.         {
  132.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  133.             cout << "DEBUG: F rawHeaderBin=" << rawHeaderBin << endl;
  134.         }
  135.        
  136.         myCommandName = translator.lookupCommandName(commandId, myModuleName);
  137.  
  138.         myData = translator.translateData(commandId, myModuleName, rawHexData);
  139.     }
  140. }
  141.  
  142. string CanMessage::getRaw()
  143. {
  144.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  145.  
  146.     string dataHex;
  147.  
  148.     string rawHex = "PKT ";
  149.  
  150.     string bin = "000";
  151.  
  152.     int classId = translator.resolveClassId(myClassName);
  153.     if (classId == -1)
  154.         bin += "0000";
  155.     else
  156.         bin += uint2bin(classId, 4);
  157.  
  158.     if (myClassName == "nmt")
  159.     {
  160.         bin +="0";
  161.  
  162.         int commandNameId = translator.resolveNMTCommandId(myCommandName);
  163.         if (commandNameId == -1)
  164.             bin += "00000000";
  165.         else
  166.             bin += uint2bin(commandNameId, 8);
  167.  
  168.         bin += "0000000000000000";
  169.  
  170.         dataHex = translator.translateNMTDataToHex(commandNameId, myData);
  171.     }
  172.     else
  173.     {
  174.         bin += uint2bin(translator.resolveDirectionFlag(myDirectionFlag), 1);
  175.  
  176.  
  177.         int moduleTypeId = translator.resolveModuleId(myModuleName);
  178.         if (moduleTypeId == -1)
  179.             bin += "00000000";
  180.         else
  181.             bin += uint2bin(moduleTypeId, 8);
  182.  
  183.  
  184.         int moduleId = myModuleId;
  185.         bin += uint2bin(moduleId, 8);
  186.  
  187.  
  188.         int commandNameId = translator.resolveCommandId(myCommandName, myModuleName);
  189.         if (commandNameId == -1)
  190.             bin += "00000000";
  191.         else
  192.             bin += uint2bin(commandNameId, 8);
  193.  
  194.         dataHex = translator.translateDataToHex(commandNameId, myModuleName, myData);
  195.     }
  196.  
  197.     rawHex += bin2hex(bin);
  198.  
  199.     rawHex += " 1 0";
  200.  
  201.     while (dataHex.size() > 0)
  202.     {
  203.         string hex;
  204.  
  205.         try
  206.         {
  207.             hex = dataHex.substr(0, 2);
  208.         }
  209.         catch (std::out_of_range& e)
  210.         {
  211.             cout << "DEBUG: getRaw exception: " << e.what() << "\n";
  212.             cout << "DEBUG: A dataHex=" << dataHex << endl;
  213.             continue;
  214.         }
  215.  
  216.        
  217.         dataHex.erase(0, 2);
  218.         rawHex += " " + hex;
  219.     }
  220.  
  221.     rawHex += "\n";
  222.  
  223.     return rawHex;
  224. }
  225.  
  226. void CanMessage::setData(map<string, CanVariable> data)
  227. {
  228.     myData = data;
  229.  
  230.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  231.  
  232.     int commandNameId = translator.resolveNMTCommandId(myCommandName);
  233.  
  234.     if (myClassName == "nmt")
  235.     {
  236.         translator.makeNMTDataValid(commandNameId, data);
  237.     }
  238.     else
  239.     {
  240.         translator.makeDataValid(commandNameId, myModuleName, data);
  241.     }
  242. }
  243.  
  244. string CanMessage::getJSONData()
  245. {
  246.     string json = "{";
  247.  
  248.     map<string, CanVariable>::iterator iter;
  249.  
  250.     for (iter = myData.begin(); iter != myData.end(); iter++)
  251.     {
  252.         json += " " + iter->first + " : ";
  253.  
  254.         if (iter->second.getType() == "uint")
  255.         {
  256.             json += iter->second.getValue();
  257.         }
  258.         else if (iter->second.getType() == "float")
  259.         {
  260.             json += iter->second.getValue();
  261.         }
  262.         else if (iter->second.getType() == "ascii" || iter->second.getType() == "hexstring")
  263.         {
  264.             json += "'" + escape(iter->second.getValue()) + "'";
  265.         }
  266.  
  267.         json += ",";
  268.     }
  269.  
  270.     json = trim(json, ',');
  271.  
  272.     return json + " }";
  273. }
  274.  
  275. string CanMessage::toString()
  276. {
  277.     string result = "[CanMessage] ClassName: " + myClassName + "\n";
  278.     result += "             DirectionFlag: " + myDirectionFlag + "\n";
  279.     result += "             ModuleName: " + myModuleName + "\n";
  280.     result += "             ModuleId: " + itos(myModuleId) + "\n";
  281.     result += "             CommandName: " + myCommandName + "\n";
  282.     result += "             Data: " + getJSONData() + "\n";
  283.  
  284.     return result;
  285. }
  286.