Subversion Repositories HomeAutomation

Rev

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