Subversion Repositories HomeAutomation

Rev

Rev 1939 | Rev 1962 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1592 runge 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 "Manager.h"
22
 
1596 runge 23
#include <iostream>
24
 
1592 runge 25
#include <boost/lexical_cast.hpp>
26
#include <boost/bind.hpp>
1594 runge 27
#include <boost/cast.hpp>
1592 runge 28
 
29
namespace atom {
30
namespace net {
1593 runge 31
 
1599 runge 32
Manager::Pointer Manager::instance_;
1898 runge 33
 
34
logging::Logger Manager::LOG("net::Manager");
35
 
1601 runge 36
Manager::Manager()
1592 runge 37
{
1627 runge 38
 
1592 runge 39
}
40
 
41
Manager::~Manager()
42
{
1939 runge 43
    this->Stop();
44
 
1592 runge 45
    this->clients_.clear();
46
}
47
 
48
Manager::Pointer Manager::Instance()
49
{
50
    return Manager::instance_;
51
}
52
 
1599 runge 53
void Manager::Create()
54
{
55
    Manager::instance_ = Manager::Pointer(new Manager());
56
}
57
 
1592 runge 58
void Manager::Delete()
59
{
60
    Manager::instance_.reset();
61
}
62
 
63
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
64
{
65
    this->signal_on_new_state_.connect(slot_on_new_state);
66
    this->signal_on_new_data_.connect(slot_on_new_data);
67
}
68
 
1959 runge 69
void Manager::SlotOnNewState(SocketId client_id, SocketId server_id, ClientState client_state)
1592 runge 70
{
71
    if (client_state == CLIENT_STATE_DISCONNECTED)
72
    {
73
        this->clients_.erase(client_id);
74
    }
75
    else if (client_state == CLIENT_STATE_ACCEPTED)
76
    {
77
        ClientList::iterator it = this->clients_.find(client_id);
78
 
79
        if (it != this->clients_.end())
80
        {
1959 runge 81
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), it->second->GetServerId()));
1592 runge 82
 
1593 runge 83
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
84
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
1592 runge 85
 
1594 runge 86
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
1592 runge 87
 
88
            this->clients_[client->GetId()] = client;
89
 
1593 runge 90
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
1592 runge 91
            return;
92
        }
93
        else
94
        {
95
            throw std::runtime_error("Accepted unknown client!");
96
        }
97
    }
98
 
1593 runge 99
    this->signal_on_new_state_(client_id, server_id, client_state);
1592 runge 100
}
101
 
1959 runge 102
void Manager::SlotOnNewData(SocketId client_id, SocketId server_id, common::Byteset data)
1592 runge 103
{
1593 runge 104
    this->signal_on_new_data_(client_id, server_id, data);
1592 runge 105
}
106
 
1959 runge 107
SocketId Manager::GetFreeSocketId()
1592 runge 108
{
1959 runge 109
    SocketId id = 1;
1592 runge 110
 
111
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
112
    {
1959 runge 113
        if (it->second->GetServerId() != id && this->clients_.find(id) == this->clients_.end())
1592 runge 114
        {
1959 runge 115
            return id;
1592 runge 116
        }
117
 
1959 runge 118
        id++;
1592 runge 119
    }
120
 
1959 runge 121
    return id;
1592 runge 122
}
123
 
1959 runge 124
SocketId Manager::StartServer(Protocol protocol, unsigned int port)
1592 runge 125
{
126
    if (protocol != PROTOCOL_TCP)
127
    {
128
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
129
        return 0;
130
    }
131
 
1959 runge 132
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), this->GetFreeSocketId()));
1592 runge 133
 
1593 runge 134
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
135
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
1592 runge 136
 
137
    TcpClient::AcceptorPointer acceptor = TcpClient::AcceptorPointer(new boost::asio::ip::tcp::acceptor(this->io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)));    
138
 
139
    client->Accept(acceptor);
140
 
141
    this->clients_[client->GetId()] = client;
142
 
143
    return client->GetServerId();
144
}
145
 
1959 runge 146
SocketId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
1592 runge 147
{
148
    Client::Pointer client;
149
 
150
    switch (protocol)
151
    {
152
        case PROTOCOL_TCP:
153
        {
1959 runge 154
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), 0));
1592 runge 155
            break;
156
        }
157
        case PROTOCOL_UDP:
158
        {
1959 runge 159
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeSocketId(), 0));
1592 runge 160
            break;
161
        }
162
        case PROTOCOL_SERIAL:
163
        {
1959 runge 164
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeSocketId(), 0));
1592 runge 165
            break;
166
        }
167
        default:
168
        {
169
            throw std::runtime_error("Invalid protocol specified!");
170
            return 0;
171
        }
172
    }
173
 
1593 runge 174
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
175
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
1592 runge 176
 
1606 runge 177
    client->Connect(address, port_or_baud);
1592 runge 178
 
179
    this->clients_[client->GetId()] = client;
180
 
181
    return client->GetId();
182
}
183
 
1959 runge 184
void Manager::SendToAll(SocketId server_id, common::Byteset data)
1592 runge 185
{
186
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
187
}
188
 
1959 runge 189
void Manager::SendTo(SocketId client_id, common::Byteset data)
1592 runge 190
{
191
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
192
}
193
 
1959 runge 194
void Manager::StopServer(SocketId server_id)
1592 runge 195
{
196
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
197
}
198
 
1959 runge 199
void Manager::Disconnect(SocketId client_id)
1592 runge 200
{
201
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
202
}
203
 
1959 runge 204
void Manager::SendToAllHandler(SocketId server_id, common::Byteset data)
1592 runge 205
{
206
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
207
    {
208
        if (it->second->GetServerId() == server_id)
209
        {
210
            it->second->Send(data);
211
        }
212
    }
213
}
214
 
1959 runge 215
void Manager::SendToHandler(SocketId client_id, common::Byteset data)
1592 runge 216
{
217
    ClientList::iterator it = this->clients_.find(client_id);
1599 runge 218
 
1592 runge 219
    if (it != this->clients_.end())
220
    {
221
        it->second->Send(data);
222
    }
223
}
224
 
1959 runge 225
void Manager::StopServerHandler(SocketId server_id)
1592 runge 226
{
227
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
228
    {
229
        if (it->second->GetServerId() == server_id)
230
        {
1599 runge 231
            it->second->Stop();
1592 runge 232
        }
233
    }
234
}
235
 
1959 runge 236
void Manager::DisconnectHandler(SocketId client_id)
1592 runge 237
{
238
    ClientList::iterator it = this->clients_.find(client_id);
239
 
240
    if (it != this->clients_.end())
241
    {
242
        it->second->Disconnect();
243
    }
244
}
245
 
246
}; // namespace net
247
}; // namespace atom