Subversion Repositories HomeAutomation

Rev

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

  1. /*
  2.  * CanNet.cpp
  3.  *
  4.  *  Created on: Apr 27, 2009
  5.  *      Author: Mattias Runge
  6.  */
  7.  
  8. #include "CanNet.h"
  9. #include <iostream>
  10.  
  11. using namespace std;
  12.  
  13. namespace atom {
  14. namespace subscribers {
  15.  
  16. // TODO Fix input on the form of a URL:
  17. // ex. udp://192.168.1.250:1100
  18. // ex. dev://dev/ttyUSB0:57000
  19. CanNet::CanNet(Broker::pointer broker, string address, unsigned int port) : Subscriber(broker, false)
  20. {
  21.     LOG.setName("CanNetSubscriber");
  22.  
  23.     this->myUdpServer = UdpServer::getInstance(port);
  24.     (*this->myUdpServer).connect(boost::bind(&CanNet::onNewData, this, _1, _2));
  25.  
  26.     this->myEndpoint = (*this->myUdpServer).getEndpoint(address);
  27.  
  28.     this->sendPing();
  29.  
  30.     this->start();
  31. }
  32.  
  33. CanNet::~CanNet()
  34. {
  35. }
  36.  
  37. byte_list CanNet::buildPacket(unsigned int id, byte_list data)
  38. {
  39.     byte_list packet;
  40.  
  41.     packet.push_back((unsigned char) PACKET_START);
  42.  
  43.     packet.push_back((unsigned char) (id & 0xFF));
  44.     packet.push_back((unsigned char) ((id >> 8) & 0xFF));
  45.     packet.push_back((unsigned char) ((id >> 16) & 0xFF));
  46.     packet.push_back((unsigned char) ((id >> 24) & 0xFF));
  47.  
  48.     packet.push_back((unsigned char) 1); // Ext
  49.     packet.push_back((char) 0); // Rtr
  50.  
  51.     packet.push_back((unsigned char) data.size());
  52.  
  53.     for (unsigned char n = 0; n < 8; n++)
  54.     {
  55.         if (n < data.size())
  56.         {
  57.             packet.push_back(data[n]);
  58.         }
  59.         else
  60.         {
  61.             packet.push_back(' ');
  62.         }
  63.     }
  64.  
  65.     packet.push_back((unsigned char) PACKET_END);
  66.  
  67.     return packet;
  68. }
  69.  
  70. void CanNet::processBuffer()
  71. {
  72.     if (this->myBuffer.size() != 15)
  73.     {
  74.         LOG.warn("Received packet of length " + itos(this->myBuffer.size() + 2) + ", should be 17.");
  75.         this->myBuffer.clear();
  76.         return;
  77.     }
  78.  
  79.     byte_list data;
  80.  
  81.     /*unsigned long id = 0;
  82.  
  83.     id = id | this->myBuffer[0];
  84.     id = id | this->myBuffer[1] << 8;
  85.     id = id | this->myBuffer[2] << 16;
  86.     id = id | this->myBuffer[3] << 24;*/
  87.  
  88.     data.push_back(this->myBuffer[0]);
  89.     data.push_back(this->myBuffer[1]);
  90.     data.push_back(this->myBuffer[2]);
  91.     data.push_back(this->myBuffer[3]);
  92.  
  93.     unsigned char length = this->myBuffer[4];
  94.  
  95.     for (unsigned char n = 0; n < length; n++)
  96.     {
  97.         data.push_back(this->myBuffer[5 + n]);
  98.     }
  99.  
  100.  
  101.     BitBuffer buffer(data);
  102.  
  103.     Header header;
  104.  
  105.     header.readBits(buffer);
  106.  
  107.  
  108.  
  109.  
  110.     Message::pointer message = boost::make_shared<Message>("", 0, "");
  111.     // TODO Get moduletype-bits, lookup moduletype-name
  112.  
  113.     // TODO Get moduleid-bits
  114.  
  115.     // TODO Get messagetype-bits, lookup messagetype-name
  116.  
  117.     // TODO Get variables for message
  118.  
  119.     // TODO Read in variable values
  120.  
  121.     // TODO Convert bitbuffer to message
  122.  
  123.  
  124.  
  125.     this->put(message);
  126.  
  127.     this->myBuffer.clear();
  128. }
  129.  
  130. void CanNet::sendPing()
  131. {
  132.     byte_list data(1, (unsigned char) PACKET_PING);
  133.  
  134.     LOG.info("Sending ping packet...");
  135.     (*this->myUdpServer).sendTo(this->myEndpoint, data);
  136. }
  137.  
  138. void CanNet::onNewMessage(Message::pointer message)
  139. {
  140.     LOG.debug("update called");
  141.  
  142.     BitBuffer buffer;
  143.     // TODO Convert message-variables to bitbuffer then to byte_list
  144.     byte_list data;
  145.  
  146.     // TODO Convert message-id to long
  147.     unsigned long id;
  148.  
  149.     (*this->myUdpServer).sendTo(this->myEndpoint, buildPacket(id, data));
  150. }
  151.  
  152. void CanNet::onNewData(const udp::endpoint & sender, const byte_list & bytes)
  153. {
  154.     //LOG.debug(udp::endpoint(sender).address().to_string() + "==" + this->myEndpoint.address().to_string());
  155.     //LOG.debug(itos(udp::endpoint(sender).port()) + "==" + itos(this->myEndpoint.port()));
  156.     if (sender.address() == this->myEndpoint.address()) // Port is wrong sometimes, therefor we only compare address
  157.     {
  158.         LOG.debug("Got data.");
  159.  
  160.         for (unsigned int n = 0; n < bytes.size(); n++)
  161.         {
  162.             if (bytes[n] == PACKET_START)
  163.             {
  164.                 this->myBuffer.clear();
  165.             }
  166.             else if (bytes[n] == PACKET_END)
  167.             {
  168.                 this->processBuffer();
  169.             }
  170.             else if (bytes[n] == PACKET_PING)
  171.             {
  172.                 LOG.info("Received pong.");
  173.             }
  174.             else
  175.             {
  176.                 //LOG.info("Received byte. " + itos(bytes[n]));
  177.                 this->myBuffer.push_back(bytes[n]);
  178.             }
  179.         }
  180.     }
  181.     else
  182.     {
  183.         LOG.debug("This message was not for me.");
  184.     }
  185. }
  186.  
  187. }
  188. }
  189.