Subversion Repositories HomeAutomation

Rev

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