Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Blame | 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.insert(make_pair(port, udpServer));
  44.  
  45.     return udpServer;
  46.  
  47. }
  48.  
  49. udp::endpoint UdpServer::getEndpoint(string address)
  50. {
  51.     LOG.info("Resolving " + address + ":" + itos(this->getPort()) + "...");
  52.     udp::resolver resolver(this->myIoService);
  53.     udp::resolver::query query(udp::v4(), address, itos(this->getPort()));
  54.     return *resolver.resolve(query);
  55. }
  56.  
  57. unsigned int UdpServer::getPort()
  58. {
  59.     return this->mySocket.local_endpoint().port();
  60. }
  61.  
  62. void UdpServer::sendTo(udp::endpoint receiver, byte_list bytes)
  63. {
  64.     try
  65.     {
  66.         LOG.info("Sending packet, length " + itos(bytes.size()) + ", to " + receiver.address().to_string() + ":" + itos(this->getPort()) + "...");
  67.         this->mySocket.send_to(boost::asio::buffer(bytes), receiver);
  68.     }
  69.     catch (std::exception& e)
  70.     {
  71.         LOG.error(e.what());
  72.     }
  73. }
  74.  
  75. void UdpServer::receiveFrom()
  76. {
  77.     LOG.info("Listening for incoming data on port " + itos(this->getPort()) + "...");
  78.     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));
  79. }
  80.  
  81. void UdpServer::handleReceiveFrom(const boost::system::error_code& error, size_t bytesReceived)
  82. {
  83.     if (error)
  84.     {
  85.         LOG.error("handleReceiveFrom got the error code " + itos(error.value()) + " and the message " + error.message());
  86.     }
  87.     else if (bytesReceived == 0)
  88.     {
  89.         LOG.info("handleReceiveFrom got 0 bytes.");
  90.     }
  91.     else
  92.     {
  93.         LOG.info("Got " + itos(bytesReceived) + " bytes from " + this->mySender.address().to_string());
  94.  
  95.         byte_list bytes(this->myDataBuffer, this->myDataBuffer + bytesReceived);
  96.  
  97.         this->onNewData(this->mySender, bytes);
  98.     }
  99.  
  100.     this->receiveFrom();
  101. }
  102.  
  103. void UdpServer::connect(const OnDataSignal::slot_type & slot)
  104. {
  105.     LOG.info("New listener connected.");
  106.     this->onNewData.connect(slot);
  107. }
  108.  
  109. void UdpServer::run()
  110. {
  111.     LOG.info("Starting thread...");
  112.     this->myIoService.run();
  113.     LOG.info("Thread completed.");
  114. }
  115.  
  116. }
  117. }
  118.