Subversion Repositories HomeAutomation

Rev

Rev 986 | Rev 997 | 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.  *   canidtranslator.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 "canidtranslator.h"
  23.  
  24. CanIdTranslator* CanIdTranslator::myInstance = NULL;
  25.  
  26. CanIdTranslator& CanIdTranslator::getInstance()
  27. {
  28.     if (myInstance == NULL)
  29.     {
  30.         myInstance = new CanIdTranslator();
  31.     }
  32.  
  33.     return *myInstance;
  34. }
  35.  
  36. void CanIdTranslator::deleteInstance()
  37. {
  38.     delete myInstance;
  39.     myInstance = NULL;
  40. }
  41.  
  42. CanIdTranslator::CanIdTranslator()
  43. {
  44.     SyslogStream &slog = SyslogStream::getInstance();
  45.  
  46.     string filename = Settings::get("CanIdXMLFile");
  47.  
  48.     if (file_exists(filename))
  49.     {
  50.         xmlNode.load(filename.c_str());
  51.  
  52.         slog << "Loading definitions from " + filename + ".\n";
  53.     }
  54.     else
  55.     {
  56.         slog << "CanIdXMLFile is not defined in the config file, this will probably not work at all.\n";
  57.     }
  58. }
  59.  
  60. string CanIdTranslator::lookupClassName(int classId)
  61. {
  62.     XmlNode classesNode = xmlNode.findChild("classes");
  63.     vector<XmlNode> classNodes = classesNode.getChildren();
  64.  
  65.     for (int n = 0; n < classNodes.size(); n++)
  66.     {
  67.         map<string, string> attributes = classNodes[n].getAttributes();
  68.  
  69.         if (stoi(attributes["id"]) == classId)
  70.         {
  71.             return attributes["name"];
  72.         }
  73.     }
  74.  
  75.     return "";
  76. }
  77.  
  78. int CanIdTranslator::resolveClassId(string className)
  79. {
  80.     XmlNode classesNode = xmlNode.findChild("classes");
  81.     vector<XmlNode> classNodes = classesNode.getChildren();
  82.  
  83.     for (int n = 0; n < classNodes.size(); n++)
  84.     {
  85.         map<string, string> attributes = classNodes[n].getAttributes();
  86.  
  87.         if (attributes["name"].compare(className) == 0)
  88.         {
  89.             return stoi(attributes["id"]);
  90.         }
  91.     }
  92.  
  93.     return -1;
  94. }
  95.  
  96. string CanIdTranslator::lookupCommandName(int commandId, string moduleName)
  97. {
  98.     XmlNode commandsNode = xmlNode.findChild("commands");
  99.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  100.  
  101.     for (int n = 0; n < commandNodes.size(); n++)
  102.     {
  103.         map<string, string> attributes = commandNodes[n].getAttributes();
  104.  
  105.         if (commandId >= 128)
  106.         {
  107.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  108.             {
  109.                 return attributes["name"];
  110.             }
  111.         }
  112.         else if (stoi(attributes["id"]) == commandId)
  113.         {
  114.             return attributes["name"];
  115.         }
  116.     }
  117.  
  118.     return "";
  119. }
  120.  
  121. int CanIdTranslator::resolveCommandId(string commandName, string moduleName)
  122. {
  123.     XmlNode commandsNode = xmlNode.findChild("commands");
  124.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  125.  
  126.     for (int n = 0; n < commandNodes.size(); n++)
  127.     {
  128.         map<string, string> attributes = commandNodes[n].getAttributes();
  129.  
  130.         if (attributes["name"].compare(commandName) == 0)
  131.         {
  132.             int commandId = stoi(attributes["id"]);
  133.  
  134.             if (commandId >= 128)
  135.             {
  136.                 if (attributes["module"] == moduleName)
  137.                 {
  138.                     return commandId;
  139.                 }
  140.             }
  141.             else
  142.             {
  143.                 return commandId;
  144.             }
  145.         }
  146.     }
  147.  
  148.     return -1;
  149. }
  150.  
  151. string CanIdTranslator::lookupNMTCommandName(int commandId)
  152. {
  153.     XmlNode commandsNode = xmlNode.findChild("nmt_messages");
  154.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  155.  
  156.     for (int n = 0; n < commandNodes.size(); n++)
  157.     {
  158.         map<string, string> attributes = commandNodes[n].getAttributes();
  159.  
  160.         if (stoi(attributes["id"]) == commandId)
  161.         {
  162.             return attributes["name"];
  163.         }
  164.     }
  165.  
  166.     return "";
  167. }
  168.  
  169. int CanIdTranslator::resolveNMTCommandId(string commandName)
  170. {
  171.     XmlNode commandsNode = xmlNode.findChild("nmt_messages");
  172.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  173.  
  174.     for (int n = 0; n < commandNodes.size(); n++)
  175.     {
  176.         map<string, string> attributes = commandNodes[n].getAttributes();
  177.  
  178.         if (attributes["name"].compare(commandName) == 0)
  179.         {
  180.             return stoi(attributes["id"]);
  181.         }
  182.     }
  183.  
  184.     return -1;
  185. }
  186.  
  187. string CanIdTranslator::getDefineId(string name, string group)
  188. {
  189.     XmlNode definesNode = xmlNode.findChild("defines");
  190.     vector<XmlNode> defineNodes = definesNode.getChildren();
  191.  
  192.     for (int n = 0; n < defineNodes.size(); n++)
  193.     {
  194.         map<string, string> attributes = defineNodes[n].getAttributes();
  195.  
  196.         if (attributes["group"] == group && attributes["name"] == name)
  197.         {
  198.             return attributes["id"];
  199.         }
  200.     }
  201.  
  202.     return "";
  203. }
  204.  
  205. string CanIdTranslator::lookupDirectionFlag(int directionFlag)
  206. {
  207.     XmlNode definesNode = xmlNode.findChild("defines");
  208.     vector<XmlNode> defineNodes = definesNode.getChildren();
  209.  
  210.     for (int n = 0; n < defineNodes.size(); n++)
  211.     {
  212.         map<string, string> attributes = defineNodes[n].getAttributes();
  213.  
  214.         if (attributes["group"].compare("DirectionFlag") == 0 && stoi(attributes["id"]) == directionFlag)
  215.         {
  216.             return attributes["name"];
  217.         }
  218.     }
  219.  
  220.     return "";
  221. }
  222.  
  223. int CanIdTranslator::resolveDirectionFlag(string directionName)
  224. {
  225.     XmlNode definesNode = xmlNode.findChild("defines");
  226.     vector<XmlNode> defineNodes = definesNode.getChildren();
  227.  
  228.     for (int n = 0; n < defineNodes.size(); n++)
  229.     {
  230.         map<string, string> attributes = defineNodes[n].getAttributes();
  231.  
  232.         if (attributes["group"].compare("DirectionFlag") == 0 && attributes["name"].compare(directionName) == 0)
  233.         {
  234.             return stoi(attributes["id"]);
  235.         }
  236.     }
  237.  
  238.     return -1;
  239. }
  240.  
  241. string CanIdTranslator::lookupModuleName(int moduleId)
  242. {
  243.     XmlNode modulesNode = xmlNode.findChild("modules");
  244.     vector<XmlNode> moduleNodes = modulesNode.getChildren();
  245.  
  246.     for (int n = 0; n < moduleNodes.size(); n++)
  247.     {
  248.         map<string, string> attributes = moduleNodes[n].getAttributes();
  249.  
  250.         if (stoi(attributes["id"]) == moduleId)
  251.         {
  252.             return attributes["name"];
  253.         }
  254.     }
  255.  
  256.     return "";
  257. }
  258.  
  259. int CanIdTranslator::resolveModuleId(string moduleName)
  260. {
  261.     XmlNode modulesNode = xmlNode.findChild("modules");
  262.     vector<XmlNode> moduleNodes = modulesNode.getChildren();
  263.  
  264.     for (int n = 0; n < moduleNodes.size(); n++)
  265.     {
  266.         map<string, string> attributes = moduleNodes[n].getAttributes();
  267.  
  268.         if (attributes["name"].compare(moduleName) == 0)
  269.         {
  270.             return stoi(attributes["id"]);
  271.         }
  272.     }
  273.  
  274.     return -1;
  275. }
  276.  
  277. void CanIdTranslator::makeNMTDataValid(int commandId, map<string, CanVariable> &data)
  278. {
  279.     vector<XmlNode> commandNodes = xmlNode.findChild("nmt_messages").getChildren();
  280.  
  281.     for (int n = 0; n < commandNodes.size(); n++)
  282.     {
  283.         map<string, string> attributes = commandNodes[n].getAttributes();
  284.  
  285.         if (stoi(attributes["id"]) == commandId)
  286.         {
  287.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  288.  
  289.             makeDataValid(varablesNode.getChildren(), data);
  290.  
  291.             return;
  292.         }
  293.     }
  294. }
  295.  
  296. void CanIdTranslator::makeDataValid(int commandId, string moduleName, map<string, CanVariable> &data)
  297. {
  298.     vector<XmlNode> commandNodes = xmlNode.findChild("commands").getChildren();
  299.  
  300.     for (int n = 0; n < commandNodes.size(); n++)
  301.     {
  302.         map<string, string> attributes = commandNodes[n].getAttributes();
  303.  
  304.         if ((stoi(attributes["id"]) == commandId) || (commandId >= 128 && (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)))
  305.         {
  306.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  307.  
  308.             makeDataValid(varablesNode.getChildren(), data);
  309.  
  310.             return;
  311.         }
  312.     }
  313. }
  314.  
  315. void CanIdTranslator::makeDataValid(vector<XmlNode> variableNodes, map<string, CanVariable> &data)
  316. {
  317.     ///FIXME: Remove variables that do not exist in the xmlfile
  318.     for (int c = 0; c < variableNodes.size(); c++)
  319.     {
  320.         map<string, string> attributes = variableNodes[c].getAttributes();
  321.  
  322.         if (data.find(attributes["name"]) != data.end())
  323.         {
  324.             data[attributes["name"]].setType(attributes["type"]);
  325.             data[attributes["name"]].setUnit(attributes["unit"]);
  326.             data[attributes["name"]].setBitLength(stoi(attributes["bit_length"]));
  327.             data[attributes["name"]].setStartBit(stoi(attributes["start_bit"]));
  328.         }
  329.     }
  330. }
  331.  
  332. string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> &data)
  333. {
  334.     makeDataValid(commandId, moduleName, data);
  335.  
  336.     return translateValidDataToHex(data);
  337. }
  338.  
  339.  
  340. map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
  341. {
  342.     vector<XmlNode> commandNodes = xmlNode.findChild("commands").getChildren();
  343.  
  344.     for (int n = 0; n < commandNodes.size(); n++)
  345.     {
  346.         map<string, string> attributes = commandNodes[n].getAttributes();
  347.  
  348.         if ((stoi(attributes["id"]) == commandId) || (commandId >= 128 && (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)))
  349.         {
  350.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  351.  
  352.             return translateData(varablesNode.getChildren(), dataHex);
  353.         }
  354.     }
  355.  
  356.     map<string, CanVariable> variables;
  357.     return variables;
  358. }
  359.  
  360. map<string, CanVariable> CanIdTranslator::translateNMTData(int commandId, string dataHex)
  361. {
  362.     vector<XmlNode> commandNodes = xmlNode.findChild("nmt_messages").getChildren();
  363.  
  364.     for (int n = 0; n < commandNodes.size(); n++)
  365.     {
  366.         map<string, string> attributes = commandNodes[n].getAttributes();
  367.  
  368.         if (stoi(attributes["id"]) == commandId)
  369.         {
  370.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  371.  
  372.             return translateData(varablesNode.getChildren(), dataHex);
  373.         }
  374.     }
  375.  
  376.     map<string, CanVariable> variables;
  377.     return variables;
  378. }
  379.  
  380. string CanIdTranslator::translateNMTDataToHex(int commandId, map<string, CanVariable> &data)
  381. {
  382.     makeNMTDataValid(commandId, data);
  383.  
  384.     return translateValidDataToHex(data);
  385. }
  386.  
  387. string CanIdTranslator::translateValidDataToHex(map<string, CanVariable> &data)
  388. {
  389.     string bin = "0000000000000000000000000000000000000000000000000000000000000000";
  390.     int highestBit = 0;
  391.  
  392.     for (map<string, CanVariable>::iterator iter = data.begin(); iter != data.end(); iter++)
  393.     {
  394.         if (iter->second.getType() == "uint")
  395.         {
  396.             if (iter->second.getStartBit() + iter->second.getBitLength() > highestBit)
  397.                 highestBit = iter->second.getStartBit() + iter->second.getBitLength();
  398.  
  399.             unsigned int a = stoi(iter->second.getValue());
  400.  
  401.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
  402.         }
  403.         else if (iter->second.getType() == "float")
  404.         {
  405.             if (iter->second.getStartBit() + iter->second.getBitLength() > highestBit)
  406.                 highestBit = iter->second.getStartBit() + iter->second.getBitLength();
  407.  
  408.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
  409.         }
  410.         else if (iter->second.getType() == "ascii")
  411.         {
  412.             for (int n = 0; n < iter->second.getValue().length(); n++)
  413.             {
  414.                 if (iter->second.getStartBit()+n*8 + 8 > highestBit)
  415.                     highestBit = iter->second.getStartBit()+n*8 + 8;
  416.  
  417.                 bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
  418.             }
  419.         }
  420.         else if (iter->second.getType() == "hexstring")
  421.         {
  422.             for (int n = 0; n < iter->second.getValue().length(); n++)
  423.             {
  424.                 if (iter->second.getStartBit()+n*4 + 4 > highestBit)
  425.                     highestBit = iter->second.getStartBit()+n*4 + 4;
  426.  
  427.                 string character;
  428.                 character += iter->second.getValue()[n];
  429.  
  430.                 bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
  431.             }
  432.         }
  433.     }
  434.  
  435.     bin = bin.substr(0, highestBit);
  436.  
  437.     return bin2hex(bin);
  438. }
  439.  
  440. map<string, CanVariable> CanIdTranslator::translateData(vector<XmlNode> variableNodes, string dataHex)
  441. {
  442.     map<string, CanVariable> variables;
  443.     string dataBin = hex2bin(dataHex);
  444.  
  445.     for (int c = 0; c < variableNodes.size(); c++)
  446.     {
  447.         map<string, string> attributes = variableNodes[c].getAttributes();
  448.  
  449.         int bitStart = stoi(attributes["start_bit"]);
  450.         int bitLength = stoi(attributes["bit_length"]);
  451.  
  452.         string bits = dataBin.substr(bitStart, bitLength);
  453.  
  454.         CanVariable variable;
  455.  
  456.         variable.setName(attributes["name"]);
  457.         variable.setType(attributes["type"]);
  458.         variable.setUnit(attributes["unit"]);
  459.         variable.setStartBit(bitStart);
  460.         variable.setBitLength(bitLength);
  461.  
  462.         if (attributes["type"] == "uint")
  463.         {
  464.             variable.setValue(itos(bin2uint(bits)));
  465.         }
  466.         else if (attributes["type"] == "float")
  467.         {
  468.             variable.setValue(ftos(bin2float(bits)));
  469.         }
  470.         else if (attributes["type"] == "ascii")
  471.         {
  472.             string str;
  473.  
  474.             for (int k = 0; k < bits.length(); k += 8)
  475.             {
  476.                 str += (char)bin2uint(bits.substr(k, 8));
  477.             }
  478.  
  479.             variable.setValue(str);
  480.         }
  481.         else if (attributes["type"] == "hexstring")
  482.         {
  483.             string str;
  484.  
  485.             for (int k = 0; k < bits.length(); k += 4)
  486.             {
  487.                 str += bin2hex(bits.substr(k, 4));
  488.             }
  489.  
  490.             variable.setValue(str);
  491.         }
  492.  
  493.         variables[attributes["name"]] = variable;
  494.     }
  495.  
  496.     return variables;
  497. }
  498.  
  499.  
  500.