Subversion Repositories HomeAutomation

Rev

Rev 1046 | 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.  
  31.     //PKT 00060102 1 0 00 00 c4
  32.  
  33.     rawHex = trim(rawHex, '\n');
  34.     rawHex = trim(rawHex);
  35.  
  36.     myRawHex = rawHex;
  37.  
  38.     vector<string> parts = explode(" ", rawHex);
  39.  
  40.     if (parts.size() < 2 || parts[0].compare("PKT") != 0)
  41.     {
  42.         cout << "Malformed can message received from canDaemon: \"" << rawHex << "\"\n";
  43.         throw new CanMessageException("Malformed can message received from canDaemon");
  44.     }
  45.  
  46.     string rawHeaderBin = hex2bin(parts[1]);
  47.    
  48.     try
  49.     {
  50.         myClassName = translator.lookupClassName(bin2uint(rawHeaderBin.substr(3, 4)));
  51.     }
  52.     catch (std::out_of_range& e)
  53.     {
  54.         cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  55.         cout << "DEBUG: A rawHeaderBin=" << rawHeaderBin << endl;
  56.     }
  57.  
  58.  
  59.     if (myClassName == "")
  60.     {
  61.         myIsUnknown = true;
  62.         return;
  63.     }
  64.     else
  65.     {
  66.         myIsUnknown = false;
  67.     }
  68.  
  69.     string rawHexData = "";
  70.     for (int n = 4; n < parts.size(); n++)
  71.     {
  72.         rawHexData += parts[n];
  73.     }
  74.  
  75.     if (myClassName == "nmt")
  76.     {
  77.         int commandId;
  78.  
  79.         try
  80.         {
  81.             commandId = bin2uint(rawHeaderBin.substr(8, 8));
  82.         }
  83.         catch (std::out_of_range& e)
  84.         {
  85.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  86.             cout << "DEBUG: B rawHeaderBin=" << rawHeaderBin << endl;
  87.         }
  88.  
  89.         myCommandName = translator.lookupNMTCommandName(commandId);
  90.  
  91.         myData = translator.translateNMTData(commandId, rawHexData);
  92.  
  93.         myDirectionFlag = "";
  94.         myModuleName = "";
  95.         myModuleId = 0;
  96.     }
  97.     else
  98.     {
  99.         try
  100.         {
  101.             myDirectionFlag = translator.lookupDirectionFlag(bin2uint(rawHeaderBin.substr(7, 1)));
  102.         }
  103.         catch (std::out_of_range& e)
  104.         {
  105.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  106.             cout << "DEBUG: C rawHeaderBin=" << rawHeaderBin << endl;
  107.         }
  108.  
  109.         try
  110.         {
  111.             myModuleName = translator.lookupModuleName(bin2uint(rawHeaderBin.substr(8, 8)));
  112.         }
  113.         catch (std::out_of_range& e)
  114.         {
  115.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  116.             cout << "DEBUG: D rawHeaderBin=" << rawHeaderBin << endl;
  117.         }
  118.  
  119.         try
  120.         {
  121.             myModuleId = bin2uint(rawHeaderBin.substr(16, 8));
  122.         }
  123.         catch (std::out_of_range& e)
  124.         {
  125.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  126.             cout << "DEBUG: E rawHeaderBin=" << rawHeaderBin << endl;
  127.         }
  128.  
  129.         int commandId;
  130.  
  131.         try
  132.         {
  133.             commandId = bin2uint(rawHeaderBin.substr(24, 8));
  134.         }
  135.         catch (std::out_of_range& e)
  136.         {
  137.             cout << "DEBUG: setRaw exception: " << e.what() << "\n";
  138.             cout << "DEBUG: F rawHeaderBin=" << rawHeaderBin << endl;
  139.         }
  140.        
  141.         myCommandName = translator.lookupCommandName(commandId, myModuleName);
  142.  
  143.         myData = translator.translateData(commandId, myModuleName, rawHexData);
  144.     }
  145. }
  146.  
  147. string CanMessage::getRaw()
  148. {
  149.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  150.  
  151.     string dataHex;
  152.  
  153.     string rawHex = "PKT ";
  154.  
  155.     string bin = "000";
  156.  
  157.     int classId = translator.resolveClassId(myClassName);
  158.     if (classId == -1)
  159.         bin += "0000";
  160.     else
  161.         bin += uint2bin(classId, 4);
  162.  
  163.     if (myClassName == "nmt")
  164.     {
  165.         bin +="0";
  166.  
  167.         int commandNameId = translator.resolveNMTCommandId(myCommandName);
  168.         if (commandNameId == -1)
  169.             bin += "00000000";
  170.         else
  171.             bin += uint2bin(commandNameId, 8);
  172.  
  173.         bin += "0000000000000000";
  174.  
  175.         dataHex = translator.translateNMTDataToHex(myCommandName, myData);
  176.     }
  177.     else
  178.     {
  179.         bin += uint2bin(translator.resolveDirectionFlag(myDirectionFlag), 1);
  180.  
  181.  
  182.         int moduleTypeId = translator.resolveModuleId(myModuleName);
  183.         if (moduleTypeId == -1)
  184.             bin += "00000000";
  185.         else
  186.             bin += uint2bin(moduleTypeId, 8);
  187.  
  188.  
  189.         int moduleId = myModuleId;
  190.         bin += uint2bin(moduleId, 8);
  191.  
  192.  
  193.         int commandNameId = translator.resolveCommandId(myCommandName, myModuleName);
  194.         if (commandNameId == -1)
  195.             bin += "00000000";
  196.         else
  197.             bin += uint2bin(commandNameId, 8);
  198.  
  199.         dataHex = translator.translateDataToHex(commandNameId, myModuleName, myData);
  200.     }
  201.  
  202.     rawHex += bin2hex(bin);
  203.  
  204.     rawHex += " 1 0";
  205.  
  206.     while (dataHex.size() > 0)
  207.     {
  208.         string hex;
  209.  
  210.         try
  211.         {
  212.             hex = dataHex.substr(0, 2);
  213.         }
  214.         catch (std::out_of_range& e)
  215.         {
  216.             cout << "DEBUG: getRaw exception: " << e.what() << "\n";
  217.             cout << "DEBUG: A dataHex=" << dataHex << endl;
  218.             continue;
  219.         }
  220.  
  221.        
  222.         dataHex.erase(0, 2);
  223.         rawHex += " " + hex;
  224.     }
  225.  
  226.     rawHex += "\n";
  227.  
  228.     return rawHex;
  229. }
  230.  
  231. void CanMessage::setData(map<string, CanVariable> data)
  232. {
  233.     myData = data;
  234.  
  235.     CanIdTranslator &translator = CanIdTranslator::getInstance();
  236.  
  237.     int commandNameId = translator.resolveNMTCommandId(myCommandName);
  238.  
  239.     if (myClassName == "nmt")
  240.     {
  241.         translator.makeNMTDataValid(myCommandName, data);
  242.     }
  243.     else
  244.     {
  245.         translator.makeDataValid(commandNameId, myModuleName, data);
  246.     }
  247. }
  248.  
  249. string CanMessage::getJSONData()
  250. {
  251.     string json = "{";
  252.  
  253.     map<string, CanVariable>::iterator iter;
  254.  
  255.     for (iter = myData.begin(); iter != myData.end(); iter++)
  256.     {
  257.         json += " " + iter->first + " : ";
  258.  
  259.         if (iter->second.getType() == "uint")
  260.         {
  261.             json += iter->second.getValue();
  262.         }
  263.         else if (iter->second.getType() == "int")
  264.         {
  265.             json += iter->second.getValue();
  266.         }
  267.         else if (iter->second.getType() == "float")
  268.         {
  269.             json += iter->second.getValue();
  270.         }
  271.         else if (iter->second.getType() == "ascii" ||
  272.                 iter->second.getType() == "hexstring" ||
  273.                 iter->second.getType() == "enum")
  274.         {
  275.             json += "'" + escape(iter->second.getValue()) + "'";
  276.         }
  277.  
  278.         json += ",";
  279.     }
  280.  
  281.     json = trim(json, ',');
  282.  
  283.     return json + " }";
  284. }
  285.  
  286. string CanMessage::toString()
  287. {
  288.     string result = "[CanMessage] ClassName: " + myClassName + "\n";
  289.     result += "             DirectionFlag: " + myDirectionFlag + "\n";
  290.     result += "             ModuleName: " + myModuleName + "\n";
  291.     result += "             ModuleId: " + itos(myModuleId) + "\n";
  292.     result += "             CommandName: " + myCommandName + "\n";
  293.     result += "             Data: " + getJSONData() + "\n";
  294.     result += "             RawHex: " + myRawHex + "\n";
  295.  
  296.     return result;
  297. }
  298.