Subversion Repositories HomeAutomation

Rev

Rev 1959 | Rev 1986 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

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