Subversion Repositories HomeAutomation

Rev

Rev 1962 | 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 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.   log::Debug(log_module_, "SlotOnNewState, client_id %d, server_id %d, client_state %d", client_id, server_id, client_state);
  98.  
  99.   if (client_state == CLIENT_STATE_DISCONNECTED)
  100.   {
  101.     this->clients_.erase(client_id);
  102.   }
  103.  
  104.   this->signal_on_new_state_(client_id, server_id, client_state);
  105.  
  106.   LOG_DEBUG_EXIT;
  107. }
  108.  
  109. void Manager::SlotOnNewClient(SocketId server_id, TcpSocketPointer socket)
  110. {
  111.   LOG_DEBUG_ENTER;
  112.  
  113.   TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, socket, this->GetFreeSocketId(), server_id));
  114.  
  115.   client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
  116.                        Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
  117.  
  118.   this->clients_[client->GetId()] = client;
  119.  
  120.   log::Debug(log_module_, "Client connected on server id %d with client id %d!", server_id, client->GetId());
  121.  
  122.   this->signal_on_new_state_(client->GetId(), server_id, CLIENT_STATE_CONNECTED);
  123.  
  124.   LOG_DEBUG_EXIT;
  125. }
  126.  
  127. void Manager::SlotOnNewData(SocketId client_id, SocketId server_id, common::Byteset data)
  128. {
  129.   LOG_DEBUG_ENTER;
  130.  
  131.   this->signal_on_new_data_(client_id, server_id, data);
  132.  
  133.   LOG_DEBUG_EXIT;
  134. }
  135.  
  136. SocketId Manager::GetFreeSocketId()
  137. {
  138.   LOG_DEBUG_ENTER;
  139.  
  140.   SocketId id = 1;
  141.  
  142.   while (this->clients_.find(id) != this->clients_.end() || this->servers_.find(id) != this->servers_.end())
  143.   {
  144.     id++;
  145.   }
  146.  
  147.   LOG_DEBUG_EXIT;
  148.  
  149.   return id;
  150. }
  151.  
  152. SocketId Manager::StartServer(Protocol protocol, unsigned int port)
  153. {
  154.   LOG_DEBUG_ENTER;
  155.  
  156.   if (protocol != PROTOCOL_TCP)
  157.   {
  158.     throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
  159.   }
  160.  
  161.   TcpServer::Pointer server = TcpServer::Pointer(new TcpServer(this->io_service_, port, this->GetFreeSocketId()));
  162.  
  163.   server->ConnectSlots(TcpServer::SignalOnNewClient::slot_type(&Manager::SlotOnNewClient, this, _1, _2).track(Manager::instance_));
  164.  
  165.   server->Accept();
  166.  
  167.   this->servers_[server->GetId()] = server;
  168.  
  169.   log::Debug(log_module_, "Started server with id %d!", server->GetId());
  170.  
  171.   LOG_DEBUG_EXIT;
  172.  
  173.   return server->GetId();
  174. }
  175.  
  176. SocketId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
  177. {
  178.   LOG_DEBUG_ENTER;
  179.  
  180.   Client::Pointer client;
  181.  
  182.   switch (protocol)
  183.   {
  184.     case PROTOCOL_TCP:
  185.     {
  186.       client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeSocketId(), 0));
  187.       break;
  188.     }
  189.     case PROTOCOL_UDP:
  190.     {
  191.       client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeSocketId(), 0));
  192.       break;
  193.     }
  194.     case PROTOCOL_SERIAL:
  195.     {
  196.       client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeSocketId(), 0));
  197.       break;
  198.     }
  199.     default:
  200.     {
  201.       throw std::runtime_error("Invalid protocol specified!");
  202.     }
  203.   }
  204.  
  205.   client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
  206.                        Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
  207.  
  208.   client->Connect(address, port_or_baud);
  209.  
  210.   this->clients_[client->GetId()] = client;
  211.  
  212.   LOG_DEBUG_EXIT;
  213.  
  214.   return client->GetId();
  215. }
  216.  
  217. void Manager::SendToAll(SocketId server_id, common::Byteset data)
  218. {
  219.   LOG_DEBUG_ENTER;
  220.  
  221.   this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
  222.  
  223.   LOG_DEBUG_EXIT;
  224. }
  225.  
  226. void Manager::SendTo(SocketId client_id, common::Byteset data)
  227. {
  228.   LOG_DEBUG_ENTER;
  229.  
  230.   log::Debug(log_module_, "SendTo, client_id %d", client_id);
  231.  
  232.   this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
  233.  
  234.   LOG_DEBUG_EXIT;
  235. }
  236.  
  237. void Manager::StopServer(SocketId server_id)
  238. {
  239.   LOG_DEBUG_ENTER;
  240.  
  241.   this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
  242.  
  243.   LOG_DEBUG_EXIT;
  244. }
  245.  
  246. void Manager::Disconnect(SocketId client_id)
  247. {
  248.   LOG_DEBUG_ENTER;
  249.  
  250.   log::Debug(log_module_, "Disconnect, client_id %d", client_id);
  251.  
  252.   this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
  253.  
  254.   LOG_DEBUG_EXIT;
  255. }
  256.  
  257. void Manager::SendToAllHandler(SocketId server_id, common::Byteset data)
  258. {
  259.   LOG_DEBUG_ENTER;
  260.  
  261.   for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
  262.   {
  263.     if (it->second->GetServerId() == server_id)
  264.     {
  265.       it->second->Send(data);
  266.     }
  267.   }
  268.  
  269.   LOG_DEBUG_EXIT;
  270. }
  271.  
  272. void Manager::SendToHandler(SocketId client_id, common::Byteset data)
  273. {
  274.   LOG_DEBUG_ENTER;
  275.  
  276.   log::Debug(log_module_, "SendToHandler, client_id %d, data %s", client_id, data.ToCharString().c_str());
  277.  
  278.   ClientList::iterator it = this->clients_.find(client_id);
  279.  
  280.   if (it != this->clients_.end())
  281.   {
  282.     it->second->Send(data);
  283.   }
  284.  
  285.   LOG_DEBUG_EXIT;
  286. }
  287.  
  288. void Manager::StopServerHandler(SocketId server_id)
  289. {
  290.   LOG_DEBUG_ENTER;
  291.  
  292.   this->clients_.erase(server_id);
  293.  
  294.   LOG_DEBUG_EXIT;
  295. }
  296.  
  297. void Manager::DisconnectHandler(SocketId client_id)
  298. {
  299.   LOG_DEBUG_ENTER;
  300.  
  301.   log::Debug(log_module_, "DisconnectHandler, client_id %d", client_id);
  302.  
  303.   ClientList::iterator it = this->clients_.find(client_id);
  304.  
  305.   if (it != this->clients_.end())
  306.   {
  307.     it->second->Disconnect();
  308.   }
  309.  
  310.   LOG_DEBUG_EXIT;
  311. }
  312.  
  313.  
  314. }; // namespace net
  315. }; // namespace atom
  316.