Subversion Repositories HomeAutomation

Rev

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

  1. /*
  2.  * UdpServer.cpp
  3.  *
  4.  *  Created on: Jul 20, 2009
  5.  *      Author: Mattias Runge
  6.  */
  7.  
  8. #include "UdpServer.h"
  9.  
  10. namespace atom {
  11. namespace utils {
  12.  
  13. UdpServer::UdpServer(unsigned int port) :
  14.     mySocket(this->myIoService, udp::endpoint(udp::v4(), port))
  15. {
  16.     LOG.setName("UdpServer");
  17.  
  18.     this->receiveFrom();
  19.  
  20.     this->start();
  21. }
  22.  
  23. UdpServer::~UdpServer()
  24. {
  25.     this->stop();
  26.     this->mySocket.cancel();
  27.     this->mySocket.close();
  28. }
  29.  
  30. UdpServer::pointer UdpServer::getInstance(unsigned int port)
  31. {
  32.     static map<unsigned int, UdpServer::pointer> servers; // FIXME Make thread-safe
  33.  
  34.     map<unsigned int, UdpServer::pointer>::iterator iter = servers.find(port);
  35.  
  36.     if (iter != servers.end())
  37.     {
  38.         return iter->second;
  39.     }
  40.  
  41.     UdpServer::pointer udpServer(new UdpServer(port));
  42.  
  43.     servers[port] = udpServer;
  44.  
  45.     return udpServer;
  46. }
  47.  
  48. udp::endpoint UdpServer::getEndpoint(string address)
  49. {
  50.     LOG.info("Resolving " + address + ":" + convert::int2string(this->getPort()) + "...");
  51.     udp::resolver resolver(this->myIoService);
  52.     udp::resolver::query query(udp::v4(), address, convert::int2string(this->getPort()));
  53.     return *resolver.resolve(query);
  54. }
  55.  
  56. unsigned int UdpServer::getPort()
  57. {
  58.     return this->mySocket.local_endpoint().port();
  59. }
  60.  
  61. void UdpServer::sendTo(udp::endpoint receiver, byte_list bytes)
  62. {
  63.     try
  64.     {
  65.         LOG.info("Sending packet, length " + convert::int2string(bytes.size()) + ", to " + receiver.address().to_string() + ":" + convert::int2string(this->getPort()) + "...");
  66.         this->mySocket.send_to(boost::asio::buffer(bytes), receiver);
  67.     }
  68.     catch (std::exception& e)
  69.     {
  70.         LOG.error(e.what());
  71.     }
  72. }
  73.  
  74. void UdpServer::receiveFrom()
  75. {
  76.     LOG.info("Listening for incoming data on port " + convert::int2string(this->getPort()) + "...");
  77.     this->mySocket.async_receive_from(boost::asio::buffer(this->myDataBuffer, MAX_LENGTH), this->mySender, boost::bind(&UdpServer::handleReceiveFrom, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
  78. }
  79.  
  80. void UdpServer::handleReceiveFrom(const boost::system::error_code& error, size_t bytesReceived)
  81. {
  82.     if (error)
  83.     {
  84.         LOG.error("handleReceiveFrom got the error code " + convert::int2string(error.value()) + " and the message " + error.message());
  85.     }
  86.     else if (bytesReceived == 0)
  87.     {
  88.         LOG.info("handleReceiveFrom got 0 bytes.");
  89.     }
  90.     else
  91.     {
  92.         LOG.info("Got " + convert::int2string(bytesReceived) + " bytes from " + this->mySender.address().to_string());
  93.  
  94.         byte_list bytes(this->myDataBuffer, this->myDataBuffer + bytesReceived);
  95.  
  96.         this->onNewData(this->mySender, bytes);
  97.     }
  98.  
  99.     this->receiveFrom();
  100. }
  101.  
  102. void UdpServer::connect(const OnDataSignal::slot_type & slot)
  103. {
  104.     LOG.info("New listener connected.");
  105.     this->onNewData.connect(slot);
  106. }
  107.  
  108. void UdpServer::run()
  109. {
  110.     LOG.info("Starting thread...");
  111.     this->myIoService.run();
  112.     LOG.info("Thread completed.");
  113. }
  114.  
  115. }
  116. }
  117.