Subversion Repositories HomeAutomation

Rev

Rev 1642 | Rev 1939 | 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. namespace atom {
  30. namespace net {
  31.  
  32. Manager::Pointer Manager::instance_;
  33.    
  34. logging::Logger Manager::LOG("net::Manager");
  35.  
  36. Manager::Manager()
  37. {
  38.  
  39. }
  40.  
  41. Manager::~Manager()
  42. {
  43.     this->clients_.clear();
  44. }
  45.  
  46. Manager::Pointer Manager::Instance()
  47. {
  48.     return Manager::instance_;
  49. }
  50.  
  51. void Manager::Create()
  52. {
  53.     Manager::instance_ = Manager::Pointer(new Manager());
  54. }
  55.  
  56. void Manager::Delete()
  57. {
  58.     Manager::instance_.reset();
  59. }
  60.  
  61. void Manager::ConnectSlots(const SignalOnNewState::slot_type& slot_on_new_state, const SignalOnNewData::slot_type& slot_on_new_data)
  62. {
  63.     this->signal_on_new_state_.connect(slot_on_new_state);
  64.     this->signal_on_new_data_.connect(slot_on_new_data);
  65. }
  66.  
  67. void Manager::SlotOnNewState(ClientId client_id, ServerId server_id, ClientState client_state)
  68. {
  69.     if (client_state == CLIENT_STATE_DISCONNECTED)
  70.     {
  71.         this->clients_.erase(client_id);
  72.     }
  73.     else if (client_state == CLIENT_STATE_ACCEPTED)
  74.     {
  75.         ClientList::iterator it = this->clients_.find(client_id);
  76.        
  77.         if (it != this->clients_.end())
  78.         {
  79.             TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), it->second->GetServerId()));
  80.            
  81.             client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
  82.                                  Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
  83.            
  84.             client->Accept(boost::polymorphic_downcast<TcpClient*>(it->second.get())->ReleaseAcceptor());
  85.            
  86.             this->clients_[client->GetId()] = client;
  87.            
  88.             this->signal_on_new_state_(client_id, server_id, CLIENT_STATE_CONNECTED);
  89.             return;
  90.         }
  91.         else
  92.         {
  93.             throw std::runtime_error("Accepted unknown client!");
  94.         }
  95.     }
  96.    
  97.     this->signal_on_new_state_(client_id, server_id, client_state);
  98. }
  99.  
  100. void Manager::SlotOnNewData(ClientId client_id, ServerId server_id, common::Byteset data)
  101. {
  102.     this->signal_on_new_data_(client_id, server_id, data);
  103. }
  104.  
  105. ServerId Manager::GetFreeServerId()
  106. {
  107.     ServerId server_id = 1;
  108.    
  109.     for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
  110.     {
  111.         if (it->second->GetServerId() != server_id)
  112.         {
  113.             return server_id;
  114.         }
  115.        
  116.         server_id++;
  117.     }
  118.    
  119.     return server_id;
  120. }
  121.  
  122. ClientId Manager::GetFreeClientId()
  123. {
  124.     ClientId client_id = 1;
  125.    
  126.     while (this->clients_.find(client_id) != this->clients_.end())
  127.     {
  128.         client_id++;
  129.     }
  130.    
  131.     return client_id;
  132. }
  133.  
  134. ServerId Manager::StartServer(Protocol protocol, unsigned int port)
  135. {
  136.     if (protocol != PROTOCOL_TCP)
  137.     {
  138.         throw std::runtime_error("Can not start server for the Serial or UDP protocol!");
  139.         return 0;
  140.     }
  141.    
  142.     TcpClient::Pointer client = TcpClient::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), this->GetFreeServerId()));
  143.    
  144.     client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
  145.                          Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
  146.    
  147.     TcpClient::AcceptorPointer acceptor = TcpClient::AcceptorPointer(new boost::asio::ip::tcp::acceptor(this->io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)));    
  148.  
  149.     client->Accept(acceptor);
  150.    
  151.     this->clients_[client->GetId()] = client;
  152.    
  153.     return client->GetServerId();
  154. }
  155.  
  156. ClientId Manager::Connect(Protocol protocol, std::string address, unsigned int port_or_baud)
  157. {
  158.     Client::Pointer client;
  159.    
  160.     switch (protocol)
  161.     {
  162.         case PROTOCOL_TCP:
  163.         {
  164.             client = Client::Pointer(new TcpClient(this->io_service_, this->GetFreeClientId(), 0));
  165.             break;
  166.         }
  167.         case PROTOCOL_UDP:
  168.         {
  169.             client = Client::Pointer(new UdpClient(this->io_service_, this->GetFreeClientId(), 0));
  170.             break;
  171.         }
  172.         case PROTOCOL_SERIAL:
  173.         {
  174.             client = Client::Pointer(new SerialClient(this->io_service_, this->GetFreeClientId(), 0));
  175.             break;
  176.         }
  177.         default:
  178.         {
  179.             throw std::runtime_error("Invalid protocol specified!");
  180.             return 0;
  181.         }
  182.     }
  183.    
  184.     client->ConnectSlots(Client::SignalOnNewState::slot_type(&Manager::SlotOnNewState, this, _1, _2, _3).track(Manager::instance_),
  185.                          Client::SignalOnNewData::slot_type(&Manager::SlotOnNewData, this, _1, _2, _3).track(Manager::instance_));
  186.    
  187.     client->Connect(address, port_or_baud);
  188.    
  189.     this->clients_[client->GetId()] = client;
  190.    
  191.     return client->GetId();
  192. }
  193.  
  194. void Manager::SendToAll(ServerId server_id, common::Byteset data)
  195. {
  196.     this->io_service_.post(boost::bind(&Manager::SendToAllHandler, this, server_id, data));
  197. }
  198.  
  199. void Manager::SendTo(ClientId client_id, common::Byteset data)
  200. {
  201.     this->io_service_.post(boost::bind(&Manager::SendToHandler, this, client_id, data));
  202. }
  203.  
  204. void Manager::StopServer(ServerId server_id)
  205. {
  206.     this->io_service_.post(boost::bind(&Manager::StopServerHandler, this, server_id));
  207. }
  208.  
  209. void Manager::Disconnect(ClientId client_id)
  210. {
  211.     this->io_service_.post(boost::bind(&Manager::DisconnectHandler, this, client_id));
  212. }
  213.  
  214. void Manager::SendToAllHandler(ServerId server_id, common::Byteset data)
  215. {
  216.     for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
  217.     {
  218.         if (it->second->GetServerId() == server_id)
  219.         {
  220.             it->second->Send(data);
  221.         }
  222.     }
  223. }
  224.  
  225. void Manager::SendToHandler(ClientId client_id, common::Byteset data)
  226. {
  227.     ClientList::iterator it = this->clients_.find(client_id);
  228.  
  229.     if (it != this->clients_.end())
  230.     {
  231.         it->second->Send(data);
  232.     }
  233. }
  234.  
  235. void Manager::StopServerHandler(ServerId server_id)
  236. {
  237.     for (ClientList::iterator it = this->clients_.begin(); it != this->clients_.end(); it++)
  238.     {
  239.         if (it->second->GetServerId() == server_id)
  240.         {
  241.             it->second->Stop();
  242.         }
  243.     }
  244. }
  245.  
  246. void Manager::DisconnectHandler(ClientId client_id)
  247. {
  248.     ClientList::iterator it = this->clients_.find(client_id);
  249.    
  250.     if (it != this->clients_.end())
  251.     {
  252.         it->second->Disconnect();
  253.     }
  254. }
  255.  
  256. }; // namespace net
  257. }; // namespace atom
  258.