Subversion Repositories HomeAutomation

Rev

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