Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1309 runge 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
}