Subversion Repositories HomeAutomation

Rev

Rev 985 | Rev 991 | 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. string CanIdTranslator::translateDataToHex(int commandId, string moduleName, map<string, CanVariable> data)
  278. {
  279.     XmlNode commandsNode = xmlNode.findChild("commands");
  280.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  281.  
  282.     map<string, CanVariable> sortedData;
  283.  
  284.     for (int n = 0; n < commandNodes.size(); n++)
  285.     {
  286.         map<string, string> attributes = commandNodes[n].getAttributes();
  287.  
  288.         bool correct = false;
  289.  
  290.         if (commandId >= 128)
  291.         {
  292.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  293.             {
  294.                 correct = true;
  295.             }
  296.         }
  297.         else if (stoi(attributes["id"]) == commandId)
  298.         {
  299.             correct = true;
  300.         }
  301.  
  302.         if (correct)
  303.         {
  304.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  305.  
  306.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  307.  
  308.             for (int c = 0; c < variableNodes.size(); c++)
  309.             {
  310.                 map<string, string> attributes = variableNodes[c].getAttributes();
  311.  
  312.                 if (data.find(attributes["name"]) != data.end())
  313.                 {
  314.                     int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
  315.                     int bitLength = stoi(attributes["bit_length"]);
  316.  
  317.                     sortedData[attributes["name"]].setType(attributes["type"]);
  318.                     sortedData[attributes["name"]].setUnit(attributes["unit"]);
  319.                     sortedData[attributes["name"]].setBitLength(bitLength);
  320.                     sortedData[attributes["name"]].setBitLength(bitLength);
  321.                     sortedData[attributes["name"]].setStartBit(bitStart);
  322.                     sortedData[attributes["name"]].setName(attributes["name"]);
  323.                     sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
  324.                 }
  325.             }
  326.         }
  327.     }
  328.  
  329.     string bin = "0000000000000000000000000000000000000000000000000000000000000000";
  330.     int heighestBit = 0;
  331.  
  332.     map<string, CanVariable>::iterator iter;
  333.  
  334.     for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
  335.     {
  336.         if (iter->second.getType() == "uint")
  337.         {
  338.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  339.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  340.  
  341.             //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
  342.             unsigned int a = stoi(iter->second.getValue());
  343.            
  344.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
  345.         }
  346.         else if (iter->second.getType() == "float")
  347.         {
  348.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  349.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  350.  
  351.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
  352.         }
  353.         else if (iter->second.getType() == "ascii")
  354.         {
  355.             //cout << iter->second.getValue() << endl;
  356.             for (int n = 0; n < iter->second.getValue().length(); n++)
  357.             {
  358.                 if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
  359.                     heighestBit = iter->second.getStartBit()+n*8 + 8;
  360.  
  361.                 //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
  362.                 bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
  363.             }
  364.         }
  365.         else if (iter->second.getType() == "hexstring")
  366.         {
  367.             for (int n = 0; n < iter->second.getValue().length(); n++)
  368.             {
  369.                 if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
  370.                     heighestBit = iter->second.getStartBit()+n*4 + 4;
  371.  
  372.                 string character;
  373.                 character += iter->second.getValue()[n];
  374.  
  375.                 bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
  376.             }
  377.         }
  378.     }
  379.  
  380.     bin = bin.substr(0, heighestBit);
  381.  
  382.     //cout << bin2hex(bin) << endl;
  383.  
  384.     return bin2hex(bin);
  385. }
  386.  
  387. map<string, CanVariable> CanIdTranslator::translateData(int commandId, string moduleName, string dataHex)
  388. {
  389.     map<string, CanVariable> variables;
  390.     XmlNode commandsNode = xmlNode.findChild("commands");
  391.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  392.  
  393.     string dataBin = hex2bin(dataHex);
  394.  
  395.     for (int n = 0; n < commandNodes.size(); n++)
  396.     {
  397.         map<string, string> attributes = commandNodes[n].getAttributes();
  398.  
  399.         bool correct = false;
  400.  
  401.         if (commandId >= 128)
  402.         {
  403.             if (stoi(attributes["id"]) == commandId && attributes["module"] == moduleName)
  404.             {
  405.                 correct = true;
  406.             }
  407.         }
  408.         else if (stoi(attributes["id"]) == commandId)
  409.         {
  410.             correct = true;
  411.         }
  412.  
  413.         if (correct)
  414.         {
  415.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  416.  
  417.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  418.  
  419.             for (int c = 0; c < variableNodes.size(); c++)
  420.             {
  421.                 map<string, string> attributes = variableNodes[c].getAttributes();
  422.  
  423.                 int bitStart = stoi(attributes["start_bit"]);
  424.                 int bitLength = stoi(attributes["bit_length"]);
  425.  
  426.                 string bits = dataBin.substr(bitStart, bitLength);
  427.                
  428.                 CanVariable variable;
  429.                
  430.                 variable.setName(attributes["name"]);
  431.                 variable.setType(attributes["type"]);
  432.                 variable.setUnit(attributes["unit"]);
  433.                 variable.setBitLength(bitLength);
  434.  
  435.                 if (attributes["type"] == "uint")
  436.                 {
  437.                     variable.setValue(itos(bin2uint(bits)));
  438.                 }
  439.                 else if (attributes["type"] == "float")
  440.                 {
  441.                     variable.setValue(ftos(bin2float(bits)));
  442.                 }
  443.                 else if (attributes["type"] == "ascii")
  444.                 {
  445.                     string str;
  446.  
  447.                     for (int k = 0; k < bits.length(); k += 8)
  448.                     {
  449.                         str += (char)bin2uint(bits.substr(k, 8));
  450.                     }
  451.  
  452.                     variable.setValue(str);
  453.                 }
  454.                 else if (attributes["type"] == "hexstring")
  455.                 {
  456.                     string str;
  457.  
  458.                     for (int k = 0; k < bits.length(); k += 4)
  459.                     {
  460.                         str += bin2hex(bits.substr(k, 4));
  461.                     }
  462.  
  463.                     variable.setValue(str);
  464.                 }
  465.  
  466.                 variables[attributes["name"]] = variable;
  467.             }
  468.  
  469.             return variables;
  470.         }
  471.     }
  472.  
  473.     return variables;
  474. }
  475.  
  476. map<string, CanVariable> CanIdTranslator::translateNMTData(int commandId, string dataHex)
  477. {
  478.     map<string, CanVariable> variables;
  479.     XmlNode commandsNode = xmlNode.findChild("nmt_messages");
  480.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  481.  
  482.     string dataBin = hex2bin(dataHex);
  483.  
  484.     for (int n = 0; n < commandNodes.size(); n++)
  485.     {
  486.         map<string, string> attributes = commandNodes[n].getAttributes();
  487.  
  488.         if (stoi(attributes["id"]) == commandId)
  489.         {
  490.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  491.  
  492.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  493.  
  494.             for (int c = 0; c < variableNodes.size(); c++)
  495.             {
  496.                 map<string, string> attributes = variableNodes[c].getAttributes();
  497.  
  498.                 int bitStart = stoi(attributes["start_bit"]);
  499.                 int bitLength = stoi(attributes["bit_length"]);
  500.  
  501.                 string bits = dataBin.substr(bitStart, bitLength);
  502.  
  503.                 CanVariable variable;
  504.  
  505.                 variable.setName(attributes["name"]);
  506.                 variable.setType(attributes["type"]);
  507.                 variable.setUnit(attributes["unit"]);
  508.                 variable.setBitLength(bitLength);
  509.  
  510.                 if (attributes["type"] == "uint")
  511.                 {
  512.                     variable.setValue(itos(bin2uint(bits)));
  513.                 }
  514.                 else if (attributes["type"] == "float")
  515.                 {
  516.                     variable.setValue(ftos(bin2float(bits)));
  517.                 }
  518.                 else if (attributes["type"] == "ascii")
  519.                 {
  520.                     string str;
  521.  
  522.                     for (int k = 0; k < bits.length(); k += 8)
  523.                     {
  524.                         str += (char)bin2uint(bits.substr(k, 8));
  525.                     }
  526.  
  527.                     variable.setValue(str);
  528.                 }
  529.                 else if (attributes["type"] == "hexstring")
  530.                 {
  531.                     string str;
  532.  
  533.                     for (int k = 0; k < bits.length(); k += 4)
  534.                     {
  535.                         str += bin2hex(bits.substr(k, 4));
  536.                     }
  537.  
  538.                     variable.setValue(str);
  539.                 }
  540.  
  541.                 variables[attributes["name"]] = variable;
  542.             }
  543.  
  544.             return variables;
  545.         }
  546.     }
  547.  
  548.     //return dataString + " ]";
  549.     return variables;
  550. }
  551.  
  552. string CanIdTranslator::translateNMTDataToHex(int commandId, map<string, CanVariable> data)
  553. {
  554.     XmlNode commandsNode = xmlNode.findChild("nmt_messages");
  555.     vector<XmlNode> commandNodes = commandsNode.getChildren();
  556.  
  557.     map<string, CanVariable> sortedData;
  558.  
  559.     for (int n = 0; n < commandNodes.size(); n++)
  560.     {
  561.         map<string, string> attributes = commandNodes[n].getAttributes();
  562.  
  563.         if (stoi(attributes["id"]) == commandId)
  564.         {
  565.             XmlNode varablesNode = commandNodes[n].findChild("variables");
  566.  
  567.             vector<XmlNode> variableNodes = varablesNode.getChildren();
  568.  
  569.             for (int c = 0; c < variableNodes.size(); c++)
  570.             {
  571.                 map<string, string> attributes = variableNodes[c].getAttributes();
  572.  
  573.                 if (data.find(attributes["name"]) != data.end())
  574.                 {
  575.                     int bitStart = stoi(attributes["start_bit"]);///FIXME: This is not a good way
  576.                     int bitLength = stoi(attributes["bit_length"]);
  577.  
  578.                     sortedData[attributes["name"]].setType(attributes["type"]);
  579.                     sortedData[attributes["name"]].setUnit(attributes["unit"]);
  580.                     sortedData[attributes["name"]].setBitLength(bitLength);
  581.                     sortedData[attributes["name"]].setBitLength(bitLength);
  582.                     sortedData[attributes["name"]].setStartBit(bitStart);
  583.                     sortedData[attributes["name"]].setName(attributes["name"]);
  584.                     sortedData[attributes["name"]].setValue(data[attributes["name"]].getValue());
  585.                 }
  586.             }
  587.         }
  588.     }
  589.  
  590.     string bin = "0000000000000000000000000000000000000000000000000000000000000000";
  591.     int heighestBit = 0;
  592.  
  593.     map<string, CanVariable>::iterator iter;
  594.  
  595.     for (iter = sortedData.begin(); iter != sortedData.end(); iter++)///FIXME: We should check order and length
  596.     {
  597.         if (iter->second.getType() == "uint")
  598.         {
  599.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  600.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  601.  
  602.             //cout << iter->first << ":" <<  stoi(iter->second.getValue()) << endl;
  603.             unsigned int a = stoi(iter->second.getValue());
  604.  
  605.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
  606.         }
  607.         else if (iter->second.getType() == "float")
  608.         {
  609.             if (iter->second.getStartBit() + iter->second.getBitLength() > heighestBit)
  610.                 heighestBit = iter->second.getStartBit() + iter->second.getBitLength();
  611.  
  612.             bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
  613.         }
  614.         else if (iter->second.getType() == "ascii")
  615.         {
  616.             //cout << iter->second.getValue() << endl;
  617.             for (int n = 0; n < iter->second.getValue().length(); n++)
  618.             {
  619.                 if (iter->second.getStartBit()+n*8 + 8 > heighestBit)
  620.                     heighestBit = iter->second.getStartBit()+n*8 + 8;
  621.  
  622.                 //cout << iter->second.getValue()[n] << ":" << (unsigned int)iter->second.getValue()[n] << endl;
  623.                 bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
  624.             }
  625.         }
  626.         else if (iter->second.getType() == "hexstring")
  627.         {
  628.             for (int n = 0; n < iter->second.getValue().length(); n++)
  629.             {
  630.                 if (iter->second.getStartBit()+n*4 + 4 > heighestBit)
  631.                     heighestBit = iter->second.getStartBit()+n*4 + 4;
  632.  
  633.                 string character;
  634.                 character += iter->second.getValue()[n];
  635.  
  636.                 bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
  637.             }
  638.         }
  639.     }
  640.  
  641.     bin = bin.substr(0, heighestBit);
  642.  
  643.     //cout << bin2hex(bin) << endl;
  644.  
  645.     return bin2hex(bin);
  646. }
  647.  
  648.