Subversion Repositories HomeAutomation

Rev

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