Subversion Repositories HomeAutomation

Rev

Rev 1971 | Rev 1987 | 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 SignalOnNewClient::slot_type& slot_on_new_client, 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_client_.connect(slot_on_new_client);
  89.   this->signal_on_new_data_.connect(slot_on_new_data);
  90.  
  91.   LOG_DEBUG_EXIT;
  92. }
  93.  
  94. void Manager::SlotOnNewState(SocketId client_id, SocketId server_id, ClientState client_state)
  95. {
  96.   LOG_DEBUG_ENTER;
  97.  
  98.   log::Debug(log_module_, "SlotOnNewState, client_id %d, server_id %d, client_state %d", client_id, server_id, client_state);
  99.  
  100.   if (client_state == CLIENT_STATE_DISCONNECTED)
  101.   {
  102.     this->clients_.erase(client_id);
  103.   }
  104.  
  105.   this->signal_on_new_state_(client_id, client_state);
  106.  
  107.   LOG_DEBUG_EXIT;
  108. }
  109.  
  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.  
  121.   log::Info(log_module_, "Client connected on server id %d with client id %d!", server_id, client->GetId());
  122.  
  123.   this->signal_on_new_client_(client->GetId(), server_id);
  124.  
  125.   this->signal_on_new_state_(client->GetId(), CLIENT_STATE_CONNECTED);
  126.  
  127.   LOG_DEBUG_EXIT;
  128. }
  129.  
  130. void Manager::SlotOnNewData(SocketId client_id, SocketId server_id, common::Byteset data)
  131. {
  132.   LOG_DEBUG_ENTER;
  133.  
  134.   this->signal_on_new_data_(client_id, data);
  135.  
  136.   LOG_DEBUG_EXIT;
  137. }
  138.  
  139. SocketId Manager::GetFreeSocketId()
  140. {
  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;
  153. }
  154.  
  155. SocketId Manager::StartServer(Protocol protocol, unsigned int port)
  156. {
  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_));
  167.  
  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();
  177. }
  178.  
  179. SocketId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
  180. {
  181.   LOG_DEBUG_ENTER;
  182.  
  183.   Client::Pointer client;
  184.  
  185.   switch (protocol)
  186.   {
  187.     case PROTOCOL_TCP:
  188.     {
  189.       client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), 0));
  190.       break;
  191.     }
  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();
  218. }
  219.  
  220. void Manager::SendToAll(SocketId server_id, common::Byteset data)
  221. {
  222.   LOG_DEBUG_ENTER;
  223.  
  224.   this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
  225.  
  226.   LOG_DEBUG_EXIT;
  227. }
  228.  
  229. void Manager::SendTo(SocketId client_id, common::Byteset data)
  230. {
  231.   LOG_DEBUG_ENTER;
  232.  
  233.   log::Debug(log_module_, "SendTo, client_id %d", client_id);
  234.  
  235.   this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
  236.  
  237.   LOG_DEBUG_EXIT;
  238. }
  239.  
  240. void Manager::StopServer(SocketId server_id)
  241. {
  242.   LOG_DEBUG_ENTER;
  243.  
  244.   this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
  245.  
  246.   LOG_DEBUG_EXIT;
  247. }
  248.  
  249. void Manager::Disconnect(SocketId client_id)
  250. {
  251.   LOG_DEBUG_ENTER;
  252.  
  253.   log::Debug(log_module_, "Disconnect, client_id %d", client_id);
  254.  
  255.   this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
  256.  
  257.   LOG_DEBUG_EXIT;
  258. }
  259.  
  260. void Manager::SendToAllHandler(SocketId server_id, common::Byteset data)
  261. {
  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)
  267.     {
  268.       it->second->Send(data);
  269.     }
  270.   }
  271.  
  272.   LOG_DEBUG_EXIT;
  273. }
  274.  
  275. void Manager::SendToHandler(SocketId client_id, common::Byteset data)
  276. {
  277.   LOG_DEBUG_ENTER;
  278.  
  279.   log::Debug(log_module_, "SendToHandler, client_id %d, data %s", client_id, data.ToCharString().c_str());
  280.  
  281.   ClientList::iterator it = this->clients_.find(client_id);
  282.  
  283.   if (it != this->clients_.end())
  284.   {
  285.     it->second->Send(data);
  286.   }
  287.   else
  288.   {
  289.     log::Error(log_module_, "Failed to find client %d to send data to!", client_id);
  290.   }
  291.  
  292.   LOG_DEBUG_EXIT;
  293. }
  294.  
  295. void Manager::StopServerHandler(SocketId server_id)
  296. {
  297.   LOG_DEBUG_ENTER;
  298.  
  299.   this->clients_.erase(server_id);
  300.  
  301.   LOG_DEBUG_EXIT;
  302. }
  303.  
  304. void Manager::DisconnectHandler(SocketId client_id)
  305. {
  306.   LOG_DEBUG_ENTER;
  307.  
  308.   log::Debug(log_module_, "DisconnectHandler, client_id %d", client_id);
  309.  
  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;
  318. }
  319.  
  320.  
  321. }; // namespace net
  322. }; // namespace atom
  323.