Subversion Repositories HomeAutomation

Rev

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

  1. /*
  2.  *
  3.  *  Copyright (C) 2010  Mattias Runge
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License along
  16.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  17.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18.  *
  19.  */
  20.  
  21. #include "Protocol.h"
  22.  
  23. #include <stdexcept>
  24. #include <string.h>
  25.  
  26. #include <boost/lexical_cast.hpp>
  27.  
  28. namespace atom {
  29. namespace can {
  30.  
  31. Protocol::Pointer Protocol::instance_;
  32.  
  33. Protocol::Protocol() : LOG("can::Protocol")
  34. {
  35. }
  36.  
  37. Protocol::~Protocol()
  38. {
  39. }
  40.  
  41. void Protocol::Create()
  42. {
  43.     Protocol::instance_ = Protocol::Pointer(new Protocol());
  44. }
  45.  
  46. Protocol::Pointer Protocol::Instance()
  47. {
  48.     return Protocol::instance_;
  49. }
  50.  
  51. void Protocol::Delete()
  52. {
  53.     Protocol::instance_.reset();
  54. }
  55.    
  56. bool Protocol::Load(std::string filename)
  57. {
  58.     try
  59.     {
  60.         this->root_node_.LoadFile(filename);
  61.     }
  62.     catch (std::runtime_error& e)
  63.     {
  64.         LOG.Error(e.what());
  65.         return false;
  66.     }
  67.    
  68.     LOG.Info("Protocol loaded successfully.");
  69.     return true;
  70. }
  71.  
  72. std::string Protocol::LookupClassName(unsigned int class_id)
  73. {
  74.     try
  75.     {
  76.         return this->root_node_.FindChild("classes").SelectChild("id", boost::lexical_cast<std::string>(class_id)).GetAttributeValue("name");
  77.     }
  78.     catch (std::runtime_error& e)
  79.     {
  80.         LOG.Error(e.what());
  81.         throw std::runtime_error("No such class_id found, " + boost::lexical_cast<std::string>(class_id));
  82.     }
  83. }
  84.  
  85. unsigned int Protocol::ResolveClassId(std::string class_name)
  86. {
  87.     try
  88.     {
  89.         return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("classes").SelectChild("name", class_name).GetAttributeValue("id"));
  90.     }
  91.     catch (std::runtime_error& e)
  92.     {
  93.         LOG.Error(e.what());
  94.         throw std::runtime_error("No such class_name found, " + class_name);
  95.     }
  96. }
  97.  
  98. std::string Protocol::LookupCommandName(unsigned int command_id, std::string module_name)
  99. {
  100.     try
  101.     {
  102.         if (command_id >= 128)
  103.         {
  104.             return this->root_node_.FindChild("commands").SelectChild("id", boost::lexical_cast<std::string>(command_id), "module", module_name).GetAttributeValue("name");
  105.         }
  106.    
  107.         return this->root_node_.FindChild("commands").SelectChild("id", boost::lexical_cast<std::string>(command_id)).GetAttributeValue("name");
  108.     }
  109.     catch (std::runtime_error& e)
  110.     {
  111.         LOG.Error(e.what());
  112.         throw std::runtime_error("No such command found, id = " + boost::lexical_cast<std::string>(command_id) + ", module = " + module_name);
  113.     }
  114. }
  115.  
  116. unsigned int Protocol::ResolveCommandId(std::string command_name, std::string module_name)
  117. {
  118.     try
  119.     {
  120.         return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("commands").SelectChild("name", command_name, "module", module_name).GetAttributeValue("id"));
  121.     }
  122.     catch (std::runtime_error& e)
  123.     {
  124.     }
  125.    
  126.     try
  127.     {
  128.         return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("commands").SelectChild("name", command_name).GetAttributeValue("id"));
  129.     }
  130.     catch (std::runtime_error& e)
  131.     {
  132.         LOG.Error(e.what());
  133.         throw std::runtime_error("No such command found, name = " + command_name + ", module = " + module_name);
  134.     }
  135. }
  136.  
  137. std::string Protocol::LookupNMTCommandName(unsigned int command_id)
  138. {
  139.     try
  140.     {
  141.         return this->root_node_.FindChild("nmt_messages").SelectChild("id", boost::lexical_cast<std::string>(command_id)).GetAttributeValue("name");
  142.     }
  143.     catch (std::runtime_error& e)
  144.     {
  145.         LOG.Error(e.what());
  146.         throw std::runtime_error("No such nmt command found, id = " + boost::lexical_cast<std::string>(command_id));
  147.     }
  148. }
  149.  
  150. unsigned int Protocol::ResolveNMTCommandId(std::string command_name)
  151. {
  152.     try
  153.     {
  154.         return boost::lexical_cast<unsigned int >(this->root_node_.FindChild("nmt_messages").SelectChild("name", command_name).GetAttributeValue("id"));
  155.     }
  156.     catch (std::runtime_error& e)
  157.     {
  158.         LOG.Error(e.what());
  159.         throw std::runtime_error("No such nmt command found, name = " + command_name);
  160.     }
  161. }
  162.  
  163. std::string Protocol::GetDefineId(std::string name, std::string group)
  164. {
  165.     try
  166.     {
  167.         return this->root_node_.FindChild("defines").SelectChild("name", name, "group", group).GetAttributeValue("id");
  168.     }
  169.     catch (std::runtime_error& e)
  170.     {
  171.         LOG.Error(e.what());
  172.         throw std::runtime_error("No such define found, name = " + name + ", group = " + group);
  173.     }
  174. }
  175.  
  176. std::string Protocol::LookupDirectionFlag(unsigned int direction_flag)
  177. {
  178.     try
  179.     {
  180.         return this->root_node_.FindChild("defines").SelectChild("id", boost::lexical_cast<std::string>(direction_flag), "group", "DirectionFlag").GetAttributeValue("name");
  181.     }
  182.     catch (std::runtime_error& e)
  183.     {
  184.         LOG.Error(e.what());
  185.         throw std::runtime_error("No such direction flag found, direction_flag = " + boost::lexical_cast<std::string>(direction_flag));
  186.     }
  187. }
  188.  
  189. unsigned int Protocol::ResolveDirectionFlag(std::string direction_name)
  190. {
  191.     try
  192.     {
  193.         return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("defines").SelectChild("name", direction_name, "group", "DirectionFlag").GetAttributeValue("id"));
  194.     }
  195.     catch (std::runtime_error& e)
  196.     {
  197.         LOG.Error(e.what());
  198.         throw std::runtime_error("No such direction flag found, direction_name = " + direction_name);
  199.     }
  200. }
  201.  
  202. std::string Protocol::LookupModuleName(unsigned int module_id)
  203. {
  204.     try
  205.     {
  206.         return this->root_node_.FindChild("modules").SelectChild("id", boost::lexical_cast<std::string>(module_id)).GetAttributeValue("name");
  207.     }
  208.     catch (std::runtime_error& e)
  209.     {
  210.         LOG.Error(e.what());
  211.         throw std::runtime_error("No such module id found, " + boost::lexical_cast<std::string>(module_id));
  212.     }
  213. }
  214.  
  215. unsigned int Protocol::ResolveModuleId(std::string module_name)
  216. {
  217.     if (module_name == "")
  218.     {
  219.         return 0;
  220.     }
  221.    
  222.     try
  223.     {
  224.         return boost::lexical_cast<unsigned int>(this->root_node_.FindChild("modules").SelectChild("name", module_name).GetAttributeValue("id"));
  225.     }
  226.     catch (std::runtime_error& e)
  227.     {
  228.         LOG.Error(e.what());
  229.         throw std::runtime_error("No such module name found, " + module_name);
  230.     }
  231. }
  232.  
  233. xml::Node::NodeList Protocol::GetCommandVariables(std::string command_name, std::string module_name)
  234. {
  235.     xml::Node node;
  236.    
  237.     try
  238.     {
  239.         node = this->root_node_.FindChild("commands").SelectChild("name", command_name, "module", module_name);
  240.        
  241.         try
  242.         {
  243.             return node.FindChild("variables").GetChildren();
  244.         }
  245.         catch (std::runtime_error& e)
  246.         {
  247.             return xml::Node::NodeList();
  248.         }
  249.     }
  250.     catch (std::runtime_error& e)
  251.     {
  252.     }
  253.  
  254.    
  255.     try
  256.     {
  257.         node = this->root_node_.FindChild("commands").SelectChild("name", command_name);
  258.        
  259.         try
  260.         {
  261.             return node.FindChild("variables").GetChildren();
  262.         }
  263.         catch (std::runtime_error& e)
  264.         {
  265.             return xml::Node::NodeList();
  266.         }
  267.     }
  268.     catch (std::runtime_error& e)
  269.     {
  270.         LOG.Error(e.what());
  271.         throw std::runtime_error("Could not find variables for command, name = " + command_name + ", module = " + module_name);
  272.     }
  273.    
  274.     return xml::Node::NodeList();
  275. }
  276.  
  277. xml::Node::NodeList Protocol::GetNMTCommandVariables(std::string command_name)
  278. {
  279.     xml::Node node;
  280.    
  281.     try
  282.     {
  283.         node = this->root_node_.FindChild("nmt_messages").SelectChild("name", command_name);
  284.        
  285.         try
  286.         {
  287.             return node.FindChild("variables").GetChildren();
  288.         }
  289.         catch (std::runtime_error& e)
  290.         {
  291.             return xml::Node::NodeList();
  292.         }
  293.     }
  294.     catch (std::runtime_error& e)
  295.     {
  296.         LOG.Error(e.what());
  297.         throw std::runtime_error("Could not find variables for nmt command, name = " + command_name);
  298.     }
  299.    
  300.     return xml::Node::NodeList();
  301. }
  302.  
  303. std::string Protocol::DecodeInt(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
  304. {
  305.     bool sign = bitset.Get(start_bit) == 1;
  306.    
  307.     unsigned long raw_bit_value = bitset.Read(start_bit, bit_length);
  308.  
  309.     int raw_value = raw_bit_value;
  310.    
  311.     if (sign)
  312.     {
  313.         long mask = 0;
  314.        
  315.         for (unsigned int n = 0; n < bit_length; n++)
  316.         {
  317.             mask += (1 << n);
  318.         }
  319.        
  320.         raw_value = -((~raw_bit_value) & mask);
  321.     }
  322.  
  323.     return boost::lexical_cast<std::string>(raw_value);
  324. }
  325.  
  326. void Protocol::EncodeInt(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
  327. {
  328.     unsigned long raw_bit_value = 0;
  329.     int raw_value = boost::lexical_cast<int>(value);
  330.     //LOG.Info("Float as int: " + raw_value);
  331.  
  332.     raw_bit_value = raw_value;
  333.    
  334.     if (raw_value < 0)
  335.     {
  336.         long mask = 0;
  337.        
  338.         for (unsigned int n = 0; n < bit_length; n++)
  339.         {
  340.             mask += (1 << n);
  341.         }
  342.        
  343.         raw_bit_value = (~(-raw_value)) & mask;
  344.     }
  345.    
  346.     bitset.Write(start_bit, bit_length, raw_bit_value);
  347. }
  348.  
  349. std::string Protocol::DecodeUint(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
  350. {
  351.     unsigned long raw_bit_value = bitset.Read(start_bit, bit_length);
  352.    
  353.     //LOG.Debug("DecodeUint: raw_bit_value=" + boost::lexical_cast<std::string>(raw_bit_value));
  354.    
  355.     return boost::lexical_cast<std::string>((unsigned int)raw_bit_value);
  356. }
  357.  
  358. void Protocol::EncodeUint(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
  359. {
  360.     unsigned long raw_bit_value = boost::lexical_cast<unsigned int>(value);
  361.    
  362.     bitset.Write(start_bit, bit_length, raw_bit_value);
  363. }
  364.  
  365. std::string Protocol::DecodeFloat(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
  366. {
  367.     float float_value = boost::lexical_cast<float>(this->DecodeInt(bitset, start_bit, bit_length));
  368.     //LOG.Debug("DecodeFloat::float_value1=" + boost::lexical_cast<std::string>(float_value));
  369.    
  370.    
  371.     float_value = float_value / 64.0f;
  372.    
  373.     //LOG.Debug("DecodeFloat::float_value2=" + boost::lexical_cast<std::string>(float_value));
  374.    
  375.     return boost::lexical_cast<std::string>(float_value);
  376. }
  377.  
  378. void Protocol::EncodeFloat(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
  379. {
  380.     int int_value = boost::lexical_cast<float>(value) * 64.0f;
  381.     //LOG.Info("Float: " + int_value);
  382.  
  383.     this->EncodeInt(bitset, start_bit, bit_length, boost::lexical_cast<std::string>(int_value));
  384. }
  385.  
  386. std::string Protocol::DecodeAscii(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
  387. {
  388.     std::string value;
  389.    
  390.     for (unsigned int n = 0; n < bit_length; n += 8)
  391.     {
  392.         unsigned long raw_value = bitset.Read(start_bit + n, 8);
  393.         value += (char)raw_value;
  394.     }
  395.    
  396.     return value;
  397. }
  398.  
  399. void Protocol::EncodeAscii(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
  400. {
  401.     //LOG.Debug("EncodeAscii: " + value + ", length=" + boost::lexical_cast<std::string>(value.length()) + ", bit_length=" + boost::lexical_cast<std::string>(bit_length));
  402.    
  403.     for (unsigned int n = 0; n < bit_length; n += 8)
  404.     {
  405.         if (n / 8 >= value.length())
  406.         {
  407.             break;
  408.         }
  409.        
  410.         //LOG.Debug(boost::lexical_cast<std::string>((unsigned int)value[n / 8]));
  411.        
  412.         bitset.Write(start_bit + n, 8, value[n / 8]);
  413.     }
  414. }
  415.  
  416. std::string Protocol::DecodeHexstring(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length)
  417. {
  418.     std::string value;
  419.     char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  420.    
  421.     for (unsigned int n = 0; n < bit_length; n += 4)
  422.     {
  423.         unsigned long raw_bit_value = bitset.Read(start_bit + n, 4);
  424.        
  425.         if (raw_bit_value >= sizeof(hex))
  426.         {
  427.             value += '-';
  428.         }
  429.         else
  430.         {
  431.             value += hex[raw_bit_value];
  432.         }
  433.     }
  434.    
  435.     return value;
  436. }
  437.  
  438. void Protocol::EncodeHexstring(common::Bitset& bitset, unsigned int start_bit, unsigned int bit_length, std::string value)
  439. {
  440.     int ascii_value;
  441.    
  442.     for (unsigned int n = 0; n < bit_length; n += 4)
  443.     {
  444.         ascii_value = boost::lexical_cast<int>((int)std::toupper(value[n / 4]));
  445.        
  446.         if (48 <= ascii_value && ascii_value <= 57)
  447.         {
  448.             bitset.Write(start_bit + n, 4, ascii_value - 48);
  449.         }
  450.         else if (65 <= ascii_value && ascii_value <= 70)
  451.         {
  452.             bitset.Write(start_bit + n, 4, ascii_value - 65);
  453.         }
  454.         else
  455.         {
  456.             throw std::runtime_error("This is not an hex string, " + value);
  457.         }
  458.     }
  459. }
  460.  
  461. }; // namespace can
  462. }; // namespace atom
  463.