Subversion Repositories HomeAutomation

Rev

Rev 1987 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1987 Rev 1989
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
#include "common/log.h"
29
#include "common/log.h"
30
 
30
 
31
static const std::string log_module_ = "net::manager";
31
static const std::string log_module_ = "net::manager";
32
 
32
 
33
namespace atom {
33
namespace atom {
34
namespace net {
34
namespace net {
35
 
35
 
36
Manager::Pointer Manager::instance_;
36
Manager::Pointer Manager::instance_;
37
 
37
 
38
 
38
 
39
Manager::Manager()
39
Manager::Manager()
40
{
40
{
41
  LOG_DEBUG_ENTER;
41
  LOG_DEBUG_ENTER;
42
  LOG_DEBUG_EXIT;
42
  LOG_DEBUG_EXIT;
43
}
43
}
44
 
44
 
45
Manager::~Manager()
45
Manager::~Manager()
46
{
46
{
47
  LOG_DEBUG_ENTER;
47
  LOG_DEBUG_ENTER;
48
 
48
 
49
  this->Stop();
49
  this->Stop();
50
 
50
 
51
  this->clients_.clear();
51
  this->clients_.clear();
52
 
52
 
53
  LOG_DEBUG_EXIT;
53
  LOG_DEBUG_EXIT;
54
}
54
}
55
 
55
 
56
Manager::Pointer Manager::Instance()
56
Manager::Pointer Manager::Instance()
57
{
57
{
58
  LOG_DEBUG_ENTER;
58
  LOG_DEBUG_ENTER;
59
 
59
 
60
  return Manager::instance_;
60
  return Manager::instance_;
61
 
61
 
62
  LOG_DEBUG_EXIT;
62
  LOG_DEBUG_EXIT;
63
}
63
}
64
 
64
 
65
void Manager::Create()
65
void Manager::Create()
66
{
66
{
67
  LOG_DEBUG_ENTER;
67
  LOG_DEBUG_ENTER;
68
 
68
 
69
  Manager::instance_ = Manager::Pointer(new Manager());
69
  Manager::instance_ = Manager::Pointer(new Manager());
70
 
70
 
71
  LOG_DEBUG_EXIT;
71
  LOG_DEBUG_EXIT;
72
}
72
}
73
 
73
 
74
void Manager::Delete()
74
void Manager::Delete()
75
{
75
{
76
  LOG_DEBUG_ENTER;
76
  LOG_DEBUG_ENTER;
77
 
77
 
78
  Manager::instance_.reset();
78
  Manager::instance_.reset();
79
 
79
 
80
  LOG_DEBUG_EXIT;
80
  LOG_DEBUG_EXIT;
81
}
81
}
82
 
82
 
83
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewClient::slot_type& slot_on_new_client, const SignalOnNewData::slot_type& slot_on_new_data)
83
void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewClient::slot_type& slot_on_new_client, const SignalOnNewData::slot_type& slot_on_new_data)
84
{
84
{
85
  LOG_DEBUG_ENTER;
85
  LOG_DEBUG_ENTER;
86
 
86
 
87
  this->signal_on_new_state_.connect(slot_on_new_state);
87
  this->signal_on_new_state_.connect(slot_on_new_state);
88
  this->signal_on_new_client_.connect(slot_on_new_client);
88
  this->signal_on_new_client_.connect(slot_on_new_client);
89
  this->signal_on_new_data_.connect(slot_on_new_data);
89
  this->signal_on_new_data_.connect(slot_on_new_data);
90
 
90
 
91
  LOG_DEBUG_EXIT;
91
  LOG_DEBUG_EXIT;
92
}
92
}
93
 
93
 
94
void Manager::SlotOnNewState(SocketId client_id, SocketId server_id, ClientState client_state)
94
void Manager::SlotOnNewState(SocketId client_id, SocketId server_id, ClientState client_state)
95
{
95
{
96
  LOG_DEBUG_ENTER;
96
  LOG_DEBUG_ENTER;
97
 
97
 
98
  log::Debug(log_module_, "SlotOnNewState, client_id %d, server_id %d, client_state %d", client_id, server_id, client_state);
98
  log::Debug(log_module_, "SlotOnNewState, client_id %d, server_id %d, client_state %d", client_id, server_id, client_state);
99
 
99
 
100
  if (client_state == CLIENT_STATE_DISCONNECTED)
100
  if (client_state == CLIENT_STATE_DISCONNECTED)
101
  {
101
  {
102
    this->clients_.erase(client_id);
102
    this->clients_.erase(client_id);
103
  }
103
  }
104
 
104
 
105
  this->signal_on_new_state_(client_id, client_state);
105
  this->signal_on_new_state_(client_id, client_state);
106
 
106
 
107
  LOG_DEBUG_EXIT;
107
  LOG_DEBUG_EXIT;
108
}
108
}
109
 
109
 
110
void Manager::SlotOnNewClient(SocketId server_id, TcpSocketPointer socket)
110
void Manager::SlotOnNewClient(SocketId server_id, TcpSocketPointer socket)
111
{
111
{
112
  LOG_DEBUG_ENTER;
112
  LOG_DEBUG_ENTER;
113
 
113
 
114
  TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, socket, this->GetFreeSocketId(), server_id));
114
  TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, socket, this->GetFreeSocketId(), server_id));
115
 
115
 
116
  client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
116
  client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
117
                       Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
117
                       Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
118
 
118
 
119
  this->clients_[client->GetId()] = client;
119
  this->clients_[client->GetId()] = client;
120
 
120
 
121
  log::Info(log_module_, "Client connected on server id %d with client id %d!", server_id, client->GetId());
121
  log::Info(log_module_, "Client connected on server id %d with client id %d!", server_id, client->GetId());
122
 
122
 
123
  this->signal_on_new_client_(client->GetId(), server_id);
123
  this->signal_on_new_client_(client->GetId(), server_id);
124
 
124
 
125
  this->signal_on_new_state_(client->GetId(), CLIENT_STATE_CONNECTED);
125
  this->signal_on_new_state_(client->GetId(), CLIENT_STATE_CONNECTED);
126
 
126
 
127
  LOG_DEBUG_EXIT;
127
  LOG_DEBUG_EXIT;
128
}
128
}
129
 
129
 
130
void Manager::SlotOnNewData(SocketId client_id, SocketId server_id, common::Byteset data)
130
void Manager::SlotOnNewData(SocketId client_id, SocketId server_id, common::Byteset data)
131
{
131
{
132
  LOG_DEBUG_ENTER;
132
  LOG_DEBUG_ENTER;
133
 
133
 
134
  log::Debug(log_module_, "data=\"%s\"", std::string(data.begin(), data.end()).data());
134
  //log::Debug(log_module_, "data=\"%s\"", std::string(data.begin(), data.end()).data());
135
 
135
 
136
  this->signal_on_new_data_(client_id, data);
136
  this->signal_on_new_data_(client_id, data);
137
 
137
 
138
  LOG_DEBUG_EXIT;
138
  LOG_DEBUG_EXIT;
139
}
139
}
140
 
140
 
141
SocketId Manager::GetFreeSocketId()
141
SocketId Manager::GetFreeSocketId()
142
{
142
{
143
  LOG_DEBUG_ENTER;
143
  LOG_DEBUG_ENTER;
144
 
144
 
145
  SocketId id = 1;
145
  SocketId id = 1;
146
 
146
 
147
  while (this->clients_.find(id) != this->clients_.end() || this->servers_.find(id) != this->servers_.end())
147
  while (this->clients_.find(id) != this->clients_.end() || this->servers_.find(id) != this->servers_.end())
148
  {
148
  {
149
    id++;
149
    id++;
150
  }
150
  }
151
 
151
 
152
  LOG_DEBUG_EXIT;
152
  LOG_DEBUG_EXIT;
153
 
153
 
154
  return id;
154
  return id;
155
}
155
}
156
 
156
 
157
SocketId Manager::StartServer(Protocol protocol, unsigned int port)
157
SocketId Manager::StartServer(TransportProtocol protocol, unsigned int port)
158
{
158
{
159
  LOG_DEBUG_ENTER;
159
  LOG_DEBUG_ENTER;
160
 
160
 
161
  if (protocol != PROTOCOL_TCP)
161
  if (protocol != TRANSPORT_PROTOCOL_TCP)
162
  {
162
  {
163
    throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
163
    throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
164
  }
164
  }
165
 
165
 
166
  TcpServer::Pointer server = TcpServer::Pointer(new TcpServer(this->io_service_, port, this->GetFreeSocketId()));
166
  TcpServer::Pointer server = TcpServer::Pointer(new TcpServer(this->io_service_, port, this->GetFreeSocketId()));
167
 
167
 
168
  server->ConnectSlots(TcpServer::SignalOnNewClient::slot_type(&Manager::SlotOnNewClient, this, _1, _2).track(Manager::instance_));
168
  server->ConnectSlots(TcpServer::SignalOnNewClient::slot_type(&Manager::SlotOnNewClient, this, _1, _2).track(Manager::instance_));
169
 
169
 
170
  server->Accept();
170
  server->Accept();
171
 
171
 
172
  this->servers_[server->GetId()] = server;
172
  this->servers_[server->GetId()] = server;
173
 
173
 
174
  log::Debug(log_module_, "Started server with id %d!", server->GetId());
174
  log::Debug(log_module_, "Started server with id %d!", server->GetId());
175
 
175
 
176
  LOG_DEBUG_EXIT;
176
  LOG_DEBUG_EXIT;
177
 
177
 
178
  return server->GetId();
178
  return server->GetId();
179
}
179
}
180
 
180
 
181
SocketId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
181
SocketId Manager::Connect(TransportProtocol protocol, std::string address, unsigned int port_or_baud)
182
{
182
{
183
  LOG_DEBUG_ENTER;
183
  LOG_DEBUG_ENTER;
184
 
184
 
185
  Client::Pointer client;
185
  Client::Pointer client;
186
 
186
 
187
  switch (protocol)
187
  switch (protocol)
188
  {
188
  {
189
    case PROTOCOL_TCP:
189
    case TRANSPORT_PROTOCOL_TCP:
190
    {
190
    {
191
      client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), 0));
191
      client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), 0));
192
      break;
192
      break;
193
    }
193
    }
194
    case PROTOCOL_UDP:
194
    case TRANSPORT_PROTOCOL_UDP:
195
    {
195
    {
196
      client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeSocketId(), 0));
196
      client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeSocketId(), 0));
197
      break;
197
      break;
198
    }
198
    }
199
    case PROTOCOL_SERIAL:
199
    case TRANSPORT_PROTOCOL_SERIAL:
200
    {
200
    {
201
      client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeSocketId(), 0));
201
      client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeSocketId(), 0));
202
      break;
202
      break;
203
    }
203
    }
204
    default:
204
    default:
205
    {
205
    {
206
      throw std::runtime_error("Invalid protocol specified!");
206
      throw std::runtime_error("Invalid protocol specified!");
207
    }
207
    }
208
  }
208
  }
209
 
209
 
210
  client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
210
  client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
211
                       Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
211
                       Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
212
 
212
 
213
  client->Connect(address, port_or_baud);
213
  client->Connect(address, port_or_baud);
214
 
214
 
215
  this->clients_[client->GetId()] = client;
215
  this->clients_[client->GetId()] = client;
216
 
216
 
217
  LOG_DEBUG_EXIT;
217
  LOG_DEBUG_EXIT;
218
 
218
 
219
  return client->GetId();
219
  return client->GetId();
220
}
220
}
221
 
221
 
222
void Manager::SendToAll(SocketId server_id, common::Byteset data)
222
void Manager::SendToAll(SocketId server_id, common::Byteset data)
223
{
223
{
224
  LOG_DEBUG_ENTER;
224
  LOG_DEBUG_ENTER;
225
 
225
 
226
  this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
226
  this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
227
 
227
 
228
  LOG_DEBUG_EXIT;
228
  LOG_DEBUG_EXIT;
229
}
229
}
230
 
230
 
231
void Manager::SendTo(SocketId client_id, common::Byteset data)
231
void Manager::SendTo(SocketId client_id, common::Byteset data)
232
{
232
{
233
  LOG_DEBUG_ENTER;
233
  LOG_DEBUG_ENTER;
234
 
234
 
235
  log::Debug(log_module_, "SendTo, client_id %d", client_id);
235
  log::Debug(log_module_, "SendTo, client_id %d", client_id);
236
 
236
 
237
  this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
237
  this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
238
 
238
 
239
  LOG_DEBUG_EXIT;
239
  LOG_DEBUG_EXIT;
240
}
240
}
241
 
241
 
242
void Manager::StopServer(SocketId server_id)
242
void Manager::StopServer(SocketId server_id)
243
{
243
{
244
  LOG_DEBUG_ENTER;
244
  LOG_DEBUG_ENTER;
245
 
245
 
246
  this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
246
  this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
247
 
247
 
248
  LOG_DEBUG_EXIT;
248
  LOG_DEBUG_EXIT;
249
}
249
}
250
 
250
 
251
void Manager::Disconnect(SocketId client_id)
251
void Manager::Disconnect(SocketId client_id)
252
{
252
{
253
  LOG_DEBUG_ENTER;
253
  LOG_DEBUG_ENTER;
254
 
254
 
255
  log::Debug(log_module_, "Disconnect, client_id %d", client_id);
255
  log::Debug(log_module_, "Disconnect, client_id %d", client_id);
256
 
256
 
257
  this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
257
  this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
258
 
258
 
259
  LOG_DEBUG_EXIT;
259
  LOG_DEBUG_EXIT;
260
}
260
}
261
 
261
 
262
void Manager::SendToAllHandler(SocketId server_id, common::Byteset data)
262
void Manager::SendToAllHandler(SocketId server_id, common::Byteset data)
263
{
263
{
264
  LOG_DEBUG_ENTER;
264
  LOG_DEBUG_ENTER;
265
 
265
 
266
  for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
266
  for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
267
  {
267
  {
268
    if (it->second->GetServerId() == server_id)
268
    if (it->second->GetServerId() == server_id)
269
    {
269
    {
270
      it->second->Send(data);
270
      it->second->Send(data);
271
    }
271
    }
272
  }
272
  }
273
 
273
 
274
  LOG_DEBUG_EXIT;
274
  LOG_DEBUG_EXIT;
275
}
275
}
276
 
276
 
277
void Manager::SendToHandler(SocketId client_id, common::Byteset data)
277
void Manager::SendToHandler(SocketId client_id, common::Byteset data)
278
{
278
{
279
  LOG_DEBUG_ENTER;
279
  LOG_DEBUG_ENTER;
280
 
280
 
281
  log::Debug(log_module_, "SendToHandler, client_id %d, data %s", client_id, std::string(data.begin(), data.end()).data());
281
  log::Debug(log_module_, "SendToHandler, client_id %d, data %s", client_id, std::string(data.begin(), data.end()).data());
282
 
282
 
283
  ClientList::iterator it = this->clients_.find(client_id);
283
  ClientList::iterator it = this->clients_.find(client_id);
284
 
284
 
285
  if (it != this->clients_.end())
285
  if (it != this->clients_.end())
286
  {
286
  {
287
    it->second->Send(data);
287
    it->second->Send(data);
288
  }
288
  }
289
  else
289
  else
290
  {
290
  {
291
    log::Error(log_module_, "Failed to find client %d to send data to!", client_id);
291
    log::Error(log_module_, "Failed to find client %d to send data to!", client_id);
292
  }
292
  }
293
 
293
 
294
  LOG_DEBUG_EXIT;
294
  LOG_DEBUG_EXIT;
295
}
295
}
296
 
296
 
297
void Manager::StopServerHandler(SocketId server_id)
297
void Manager::StopServerHandler(SocketId server_id)
298
{
298
{
299
  LOG_DEBUG_ENTER;
299
  LOG_DEBUG_ENTER;
300
 
300
 
301
  this->clients_.erase(server_id);
301
  this->clients_.erase(server_id);
302
 
302
 
303
  LOG_DEBUG_EXIT;
303
  LOG_DEBUG_EXIT;
304
}
304
}
305
 
305
 
306
void Manager::DisconnectHandler(SocketId client_id)
306
void Manager::DisconnectHandler(SocketId client_id)
307
{
307
{
308
  LOG_DEBUG_ENTER;
308
  LOG_DEBUG_ENTER;
309
 
309
 
310
  log::Debug(log_module_, "DisconnectHandler, client_id %d", client_id);
310
  log::Debug(log_module_, "DisconnectHandler, client_id %d", client_id);
311
 
311
 
312
  ClientList::iterator it = this->clients_.find(client_id);
312
  ClientList::iterator it = this->clients_.find(client_id);
313
 
313
 
314
  if (it != this->clients_.end())
314
  if (it != this->clients_.end())
315
  {
315
  {
316
    it->second->Disconnect();
316
    it->second->Disconnect();
317
  }
317
  }
318
 
318
 
319
  LOG_DEBUG_EXIT;
319
  LOG_DEBUG_EXIT;
320
}
320
}
321
 
321
 
322
 
322
 
323
}; // namespace net
323
}; // namespace net
324
}; // namespace atom
324
}; // namespace atom
325
 
325