Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /*
  2.  *
  3.  *  Copyright (C) 2012  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 "Mbb.h"
  22.  
  23. #include <boost/lexical_cast.hpp>
  24. #include <boost/algorithm/string/trim.hpp>
  25. #include <boost/algorithm/string/split.hpp>
  26.  
  27. #include "net/Manager.h"
  28. #include "vm/Manager.h"
  29. #include "common/common.h"
  30. #include "common/log.h"
  31. #include "common/exception.h"
  32.  
  33. namespace atom {
  34. namespace vm {
  35. namespace plugin {
  36.    
  37. static const std::string log_module_ = "vm::plugin::mbb";
  38.  
  39. net::ClientId Mbb::current_client_id_;
  40.    
  41. Mbb::Mbb(boost::asio::io_service& io_service, unsigned int port) : Plugin(io_service)
  42. {
  43.   this->name_ = "mbb";
  44.   Mbb::current_client_id_ = 0;
  45.  
  46.   net::Manager::Instance()->ConnectSlots(net::Manager::SignalOnNewState::slot_type(&Mbb::SlotOnNewState, this, _1, _2, _3).track(this->tracker_),
  47.                                          net::Manager::SignalOnNewData::slot_type(&Mbb::SlotOnNewData, this, _1, _2, _3).track(this->tracker_));
  48.  
  49.   this->ExportFunction("MbbExport_SendData", Mbb::Export_SendData);
  50.  
  51.   try
  52.   {
  53.     this->server_id_ = net::Manager::Instance()->StartServer(net::PROTOCOL_TCP, port);
  54.     atom::log::Info(log_module_, "Started TCP server on port %u.", port);
  55.     atom::log::Debug(log_module_, "Server id is %u", this->server_id_);
  56.   }
  57.   catch (std::runtime_error& e)
  58.   {
  59.     atom::log::Exception(log_module_, e);
  60.   }
  61. }
  62.  
  63. Mbb::~Mbb()
  64. {
  65.   net::Manager::Instance()->StopServer(this->server_id_);
  66.   this->server_id_ = 0;
  67. }
  68.  
  69. void Mbb::InitializeDone()
  70. {
  71.   Plugin::InitializeDone();
  72.  
  73.   this->ImportFunction("Mbb_Connected");
  74.   this->ImportFunction("Mbb_Disconnected");
  75.   this->ImportFunction("Mbb_ReceivedData");
  76. }
  77.  
  78. void Mbb::CallOutput(unsigned int request_id, std::string output)
  79. {
  80.   atom::log::Info(log_module_, output);
  81. }
  82.  
  83. void Mbb::SlotOnNewData(net::ClientId client_id, net::ServerId server_id, common::Byteset data)
  84. {
  85.   if (server_id != this->server_id_)
  86.   {
  87.     return;
  88.   }
  89.  
  90.   this->io_service_.post(boost::bind(&Mbb::SlotOnNewDataHandler, this, client_id, server_id, data));
  91. }
  92.  
  93. void Mbb::SlotOnNewState(net::ClientId client_id, net::ServerId server_id, net::ClientState client_state)
  94. {
  95.   if (server_id != this->server_id_)
  96.   {
  97.     return;
  98.   }
  99.  
  100.   this->io_service_.post(boost::bind(&Mbb::SlotOnNewStateHandler, this, client_id, server_id, client_state));
  101. }
  102.  
  103. void Mbb::SlotOnNewDataHandler(net::ClientId client_id, net::ServerId server_id, common::Byteset data)
  104. {
  105.   ATOM_VM_PLUGIN_SCOPE;
  106.  
  107.   //atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
  108.  
  109.   try
  110.   {
  111.     ArgumentListPointer call_arguments = ArgumentListPointer(new ArgumentList);
  112.    
  113.     if (data.GetSize() == 0)
  114.     {
  115.         atom::log::Error(log_module_, "Got empty data!");
  116.         return;
  117.     }
  118.    
  119.     call_arguments->push_back(v8::Integer::New(boost::lexical_cast<unsigned int>(client_id)));
  120.     call_arguments->push_back(v8::String::New(data.ToCharString().c_str()));
  121.        
  122.     if (!this->Call(client_id, "Mbb_ReceivedData", call_arguments))
  123.     {
  124.         atom::log::Error(log_module_, "Mbb_ReceivedData failed!");
  125.     }
  126.    
  127.     Mbb::current_client_id_ = 0;
  128.   }
  129.   catch (std::exception& exception)
  130.   {
  131.     atom::log::Exception(log_module_, exception);
  132.   }
  133. }
  134.  
  135. void Mbb::SlotOnNewStateHandler(net::ClientId client_id, net::ServerId server_id, net::ClientState client_state)
  136. {
  137.   ATOM_VM_PLUGIN_SCOPE;
  138.  
  139.   //atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
  140.  
  141.   try
  142.   {
  143.     ArgumentListPointer call_arguments = ArgumentListPointer(new ArgumentList);
  144.    
  145.     Mbb::current_client_id_ = client_id;
  146.    
  147.     call_arguments->push_back(v8::Integer::New(boost::lexical_cast<unsigned int>(client_id)));
  148.    
  149.     if (client_state == net::CLIENT_STATE_DISCONNECTED)
  150.     {
  151.       atom::log::Info(log_module_, "Client %u has disconnected.", client_id);
  152.        
  153.       if (!this->Call(client_id, "Mbb_Disconnected", call_arguments))
  154.       {
  155.           atom::log::Error(log_module_, "Mbb_Connected failed!");
  156.       }
  157.     }
  158.     else if (client_state == net::CLIENT_STATE_CONNECTED)
  159.     {
  160.       atom::log::Info(log_module_, "Client %u has connected.", client_id);
  161.        
  162.       if (!this->Call(client_id, "Mbb_Connected", call_arguments))
  163.       {
  164.           atom::log::Error(log_module_, "Mbb_Connected failed!");
  165.       }
  166.     }
  167.     else
  168.     {
  169.       atom::log::Error(log_module_, "Client %u reported state %u.", client_id, client_state);
  170.       throw atom::exception::unknown_state();
  171.     }
  172.    
  173.     Mbb::current_client_id_ = 0;
  174.   }
  175.   catch (std::exception& exception)
  176.   {
  177.     atom::log::Exception(log_module_, exception);
  178.   }
  179. }
  180.  
  181. Value Mbb::Export_SendData(const v8::Arguments& args)
  182. {
  183.   ATOM_VM_PLUGIN_SCOPE;
  184.  
  185.   //atom::log::Debug(log_module_, "%s called!", __FUNCTION__);
  186.  
  187.   try
  188.   {
  189.     ATOM_VM_PLUGIN_NUM_PARAMS(2);
  190.  
  191.     v8::String::AsciiValue data(args[1]);
  192.    
  193.     net::Manager::Instance()->SendTo(args[0]->Uint32Value(), std::string(*data));
  194.    
  195.     return handle_scope.Close(v8::Boolean::New(true));
  196.   }
  197.   catch (std::exception& exception)
  198.   {
  199.     atom::log::Exception(log_module_, exception);
  200.    
  201.     return handle_scope.Close(v8::Boolean::New(false));
  202.   }
  203. }
  204.  
  205. }; // namespace plugin
  206. }; // namespace vm
  207. }; // namespace atom
  208.