Subversion Repositories HomeAutomation

Rev

Rev 1606 | Rev 1642 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1606 Rev 1627
1
/*
1
/*
2
 *
2
 *
3
 *  Copyright (C) 2010  Mattias Runge
3
 *  Copyright (C) 2010  Mattias Runge
4
 *
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
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
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
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
8
 *  (at your option) any later version.
9
 *
9
 *
10
 *  This program is distributed in the hope that it will be useful,
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
13
 *  GNU General Public License for more details.
14
 *
14
 *
15
 *  You should have received a copy of the GNU General Public License along
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.,
16
 *  with this program; if not, write to the Free Software Foundation, Inc.,
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
18
 *
19
 */
19
 */
20
 
20
 
21
#include "Manager.h"
21
#include "Manager.h"
22
 
22
 
23
#include <iostream>
23
#include <iostream>
24
 
24
 
25
#include <boost/lexical_cast.hpp>
25
#include <boost/lexical_cast.hpp>
26
#include <boost/bind.hpp>
26
#include <boost/bind.hpp>
27
#include <boost/cast.hpp>
27
#include <boost/cast.hpp>
28
 
28
 
29
namespace atom {
29
namespace atom {
30
namespace net {
30
namespace net {
31
 
31
 
32
Manager::Pointer Manager::instance_;
32
Manager::Pointer Manager::instance_;
33
   
33
   
34
Manager::Manager()
34
Manager::Manager()
35
{
35
{
-
 
36
 
36
}
37
}
37
 
38
 
38
Manager::~Manager()
39
Manager::~Manager()
39
{
40
{
40
    this->clients_.clear();
41
    this->clients_.clear();
41
}
42
}
42
 
43
 
43
Manager::Pointer Manager::Instance()
44
Manager::Pointer Manager::Instance()
44
{
45
{
45
    return Manager::instance_;
46
    return Manager::instance_;
46
}
47
}
47
 
48
 
48
void Manager::Create()
49
void Manager::Create()
49
{
50
{
50
    Manager::instance_ = Manager::Pointer(new Manager());
51
    Manager::instance_ = Manager::Pointer(new Manager());
51
}
52
}
52
 
53
 
53
void Manager::Delete()
54
void Manager::Delete()
54
{
55
{
55
    Manager::instance_.reset();
56
    Manager::instance_.reset();
56
}
57
}
57
 
58
 
58
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
59
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
59
{
60
{
60
    this->signal_on_new_state_.connect(slot_on_new_state);
61
    this->signal_on_new_state_.connect(slot_on_new_state);
61
    this->signal_on_new_data_.connect(slot_on_new_data);
62
    this->signal_on_new_data_.connect(slot_on_new_data);
62
}
63
}
63
 
64
 
64
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
65
void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
65
{
66
{
66
    if (client_state == CLIENT_STATE_DISCONNECTED)
67
    if (client_state == CLIENT_STATE_DISCONNECTED)
67
    {
68
    {
68
        this->clients_.erase(client_id);
69
        this->clients_.erase(client_id);
69
    }
70
    }
70
    else if (client_state == CLIENT_STATE_ACCEPTED)
71
    else if (client_state == CLIENT_STATE_ACCEPTED)
71
    {
72
    {
72
        ClientList::iterator it = this->clients_.find(client_id);
73
        ClientList::iterator it = this->clients_.find(client_id);
73
       
74
       
74
        if (it != this->clients_.end())
75
        if (it != this->clients_.end())
75
        {
76
        {
76
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
77
            TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
77
           
78
           
78
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
79
            client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
79
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
80
                                 Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
80
           
81
           
81
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
82
            client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
82
           
83
           
83
            this->clients_[client->GetId()] = client;
84
            this->clients_[client->GetId()] = client;
84
           
85
           
85
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
86
            this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
86
            return;
87
            return;
87
        }
88
        }
88
        else
89
        else
89
        {
90
        {
90
            throw std::runtime_error("Accepted unknown client!");
91
            throw std::runtime_error("Accepted unknown client!");
91
        }
92
        }
92
    }
93
    }
93
   
94
   
94
    this->signal_on_new_state_(client_id, server_id, client_state);
95
    this->signal_on_new_state_(client_id, server_id, client_state);
95
}
96
}
96
 
97
 
97
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, type::Byteset data)
98
void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, type::Byteset data)
98
{
99
{
99
    this->signal_on_new_data_(client_id, server_id, data);
100
    this->signal_on_new_data_(client_id, server_id, data);
100
}
101
}
101
 
102
 
102
ServerId Manager::GetFreeServerId()
103
ServerId Manager::GetFreeServerId()
103
{
104
{
104
    ServerId server_id = 1;
105
    ServerId server_id = 1;
105
   
106
   
106
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
107
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
107
    {
108
    {
108
        if (it->second->GetServerId() != server_id)
109
        if (it->second->GetServerId() != server_id)
109
        {
110
        {
110
            return server_id;
111
            return server_id;
111
        }
112
        }
112
       
113
       
113
        server_id++;
114
        server_id++;
114
    }
115
    }
115
   
116
   
116
    return server_id;
117
    return server_id;
117
}
118
}
118
 
119
 
119
ClientId Manager::GetFreeClientId()
120
ClientId Manager::GetFreeClientId()
120
{
121
{
121
    ClientId client_id = 1;
122
    ClientId client_id = 1;
122
   
123
   
123
    while (this->clients_.find(client_id) != this->clients_.end())
124
    while (this->clients_.find(client_id) != this->clients_.end())
124
    {
125
    {
125
        client_id++;
126
        client_id++;
126
    }
127
    }
127
   
128
   
128
    return client_id;
129
    return client_id;
129
}
130
}
130
 
131
 
131
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
132
ServerId Manager::StartServer(Protocol protocol, unsigned int port)
132
{
133
{
133
    if (protocol != PROTOCOL_TCP)
134
    if (protocol != PROTOCOL_TCP)
134
    {
135
    {
135
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
136
        throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
136
        return 0;
137
        return 0;
137
    }
138
    }
138
   
139
   
139
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
140
    TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
140
   
141
   
141
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
142
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
142
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
143
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
143
   
144
   
144
    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)));    
145
    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)));    
145
 
146
 
146
    client->Accept(acceptor);
147
    client->Accept(acceptor);
147
   
148
   
148
    this->clients_[client->GetId()] = client;
149
    this->clients_[client->GetId()] = client;
149
   
150
   
150
    return client->GetServerId();
151
    return client->GetServerId();
151
}
152
}
152
 
153
 
153
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
154
ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
154
{
155
{
155
    Client::Pointer client;
156
    Client::Pointer client;
156
   
157
   
157
    switch (protocol)
158
    switch (protocol)
158
    {
159
    {
159
        case PROTOCOL_TCP:
160
        case PROTOCOL_TCP:
160
        {
161
        {
161
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
162
            client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
162
            break;
163
            break;
163
        }
164
        }
164
        case PROTOCOL_UDP:
165
        case PROTOCOL_UDP:
165
        {
166
        {
166
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
167
            client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
167
            break;
168
            break;
168
        }
169
        }
169
        case PROTOCOL_SERIAL:
170
        case PROTOCOL_SERIAL:
170
        {
171
        {
171
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
172
            client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
172
            break;
173
            break;
173
        }
174
        }
174
        default:
175
        default:
175
        {
176
        {
176
            throw std::runtime_error("Invalid protocol specified!");
177
            throw std::runtime_error("Invalid protocol specified!");
177
            return 0;
178
            return 0;
178
        }
179
        }
179
    }
180
    }
180
   
181
   
181
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
182
    client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
182
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
183
                         Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
183
   
184
   
184
    client->Connect(address, port_or_baud);
185
    client->Connect(address, port_or_baud);
185
   
186
   
186
    this->clients_[client->GetId()] = client;
187
    this->clients_[client->GetId()] = client;
187
   
188
   
188
    return client->GetId();
189
    return client->GetId();
189
}
190
}
190
 
191
 
191
void Manager::SendToAll(ServerId server_id, type::Byteset data)
192
void Manager::SendToAll(ServerId server_id, type::Byteset data)
192
{
193
{
193
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
194
    this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
194
}
195
}
195
 
196
 
196
void Manager::SendTo(ClientId client_id, type::Byteset data)
197
void Manager::SendTo(ClientId client_id, type::Byteset data)
197
{
198
{
198
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
199
    this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
199
}
200
}
200
 
201
 
201
void Manager::StopServer(ServerId server_id)
202
void Manager::StopServer(ServerId server_id)
202
{
203
{
203
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
204
    this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
204
}
205
}
205
 
206
 
206
void Manager::Disconnect(ClientId client_id)
207
void Manager::Disconnect(ClientId client_id)
207
{
208
{
208
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
209
    this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
209
}
210
}
210
 
211
 
211
void Manager::SendToAllHandler(ServerId server_id, type::Byteset data)
212
void Manager::SendToAllHandler(ServerId server_id, type::Byteset data)
212
{
213
{
213
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
214
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
214
    {
215
    {
215
        if (it->second->GetServerId() == server_id)
216
        if (it->second->GetServerId() == server_id)
216
        {
217
        {
217
            it->second->Send(data);
218
            it->second->Send(data);
218
        }
219
        }
219
    }
220
    }
220
}
221
}
221
 
222
 
222
void Manager::SendToHandler(ClientId client_id, type::Byteset data)
223
void Manager::SendToHandler(ClientId client_id, type::Byteset data)
223
{
224
{
224
    ClientList::iterator it = this->clients_.find(client_id);
225
    ClientList::iterator it = this->clients_.find(client_id);
225
 
226
 
226
    if (it != this->clients_.end())
227
    if (it != this->clients_.end())
227
    {
228
    {
228
        it->second->Send(data);
229
        it->second->Send(data);
229
    }
230
    }
230
}
231
}
231
 
232
 
232
void Manager::StopServerHandler(ServerId server_id)
233
void Manager::StopServerHandler(ServerId server_id)
233
{
234
{
234
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
235
    for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
235
    {
236
    {
236
        if (it->second->GetServerId() == server_id)
237
        if (it->second->GetServerId() == server_id)
237
        {
238
        {
238
            it->second->Stop();
239
            it->second->Stop();
239
        }
240
        }
240
    }
241
    }
241
}
242
}
242
 
243
 
243
void Manager::DisconnectHandler(ClientId client_id)
244
void Manager::DisconnectHandler(ClientId client_id)
244
{
245
{
245
    ClientList::iterator it = this->clients_.find(client_id);
246
    ClientList::iterator it = this->clients_.find(client_id);
246
   
247
   
247
    if (it != this->clients_.end())
248
    if (it != this->clients_.end())
248
    {
249
    {
249
        it->second->Disconnect();
250
        it->second->Disconnect();
250
    }
251
    }
251
}
252
}
252
 
253
 
253
}; // namespace net
254
}; // namespace net
254
}; // namespace atom
255
}; // namespace atom
255
 
256