Subversion Repositories HomeAutomation

Rev

Rev 2107 | Blame | Compare with Previous | 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 "JsPipe.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.  
  32. namespace atom {
  33. namespace vm {
  34. namespace plugin {
  35.  
  36. static const std::string log_module_ = "vm::plugin::jspipe";
  37.  
  38. JsPipe::JsPipe(boost::asio::io_service& io_service, unsigned int port) : Plugin(io_service)
  39. {
  40.   this->name_ = "jspipe";
  41.  
  42.   net::Manager::Instance()->ConnectSlots(net::Manager::SignalOnNewState::slot_type(&JsPipe::SlotOnNewState, this, _1, _2).track(this->tracker_),
  43.                                          net::Manager::SignalOnNewClient::slot_type(&JsPipe::SlotOnNewClient, this, _1, _2).track(this->tracker_),
  44.                                          net::Manager::SignalOnNewData::slot_type(&JsPipe::SlotOnNewData, this, _1, _2).track(this->tracker_));
  45.  
  46.   this->ExportFunction("JsPipeExport_DisconnectClient", JsPipe::Export_DisconnectClient);
  47.  
  48.   try
  49.   {
  50.     this->server_id_ = net::Manager::Instance()->StartServer(net::TRANSPORT_PROTOCOL_TCP, port);
  51.     log::Info(log_module_, "Started JsPipe TCP server on port %u.", port);
  52.     log::Debug(log_module_, "Server id is %u.", this->server_id_);
  53.   }
  54.   catch (std::runtime_error& e)
  55.   {
  56.     log::Exception(log_module_, e);
  57.   }
  58. }
  59.  
  60. JsPipe::~JsPipe()
  61. {
  62.   net::Manager::Instance()->StopServer(this->server_id_);
  63.   this->server_id_ = 0;
  64. }
  65.  
  66. void JsPipe::InitializeDone()
  67. {
  68.   Plugin::InitializeDone();
  69. }
  70.  
  71. void JsPipe::CallResult(unsigned int request_id, std::string output)
  72. {
  73.   output += "\n";
  74.  
  75.   net::Manager::Instance()->SendTo(request_id, common::Byteset(output.begin(), output.end()));
  76. }
  77.  
  78. void JsPipe::SlotOnNewData(net::SocketId id, common::Byteset data)
  79. {
  80.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewDataHandler, this, id, data));
  81. }
  82.  
  83. void JsPipe::SlotOnNewClient(net::SocketId id, net::SocketId server_id)
  84. {
  85.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewClientHandler, this, id, server_id));
  86. }
  87.  
  88. void JsPipe::SlotOnNewState(net::SocketId id, net::ClientState client_state)
  89. {
  90.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewStateHandler, this, id, client_state));
  91. }
  92.  
  93. void JsPipe::SlotOnNewDataHandler(net::SocketId id, common::Byteset data)
  94. {
  95.   v8::Locker lock;
  96.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  97.   v8::HandleScope handle_scope;
  98.  
  99.   if (std::find(this->clients_.begin(), this->clients_.end(), id) == this->clients_.end())
  100.   {
  101.     return;
  102.   }
  103.  
  104.  
  105.   //log::Debug(log_module_, "%s called!", __FUNCTION__);
  106.  
  107.   if (data.size() == 0)
  108.   {
  109.     log::Error("%s got empty data!", __FUNCTION__);
  110.     return;
  111.   }
  112.  
  113.   std::string s(data.begin(), data.end());
  114.  
  115.   this->Execute(id, s);
  116. }
  117.  
  118. void JsPipe::SlotOnNewClientHandler(net::SocketId id, net::SocketId server_id)
  119. {
  120.   if (server_id == this->server_id_)
  121.   {
  122.     this->clients_.insert(id);
  123.   }
  124. }
  125.  
  126. void JsPipe::SlotOnNewStateHandler(net::SocketId id, net::ClientState client_state)
  127. {
  128.   v8::Locker lock;
  129.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  130.   v8::HandleScope handle_scope;
  131.  
  132.   if (std::find(this->clients_.begin(), this->clients_.end(), id) == this->clients_.end())
  133.   {
  134.     return;
  135.   }
  136.  
  137.   //log::Debug(log_module_, "%s called!", __FUNCTION__);
  138.  
  139.   if (client_state == net::CLIENT_STATE_DISCONNECTED)
  140.   {
  141.     log::Info(log_module_, "Client %u has disconnected from JsPipe.", id);
  142.     this->clients_.erase(id);
  143.   }
  144.   else if (client_state == net::CLIENT_STATE_CONNECTED)
  145.   {
  146.     log::Info(log_module_, "Client %u has connected to JsPipe.", id);
  147.   }
  148.   else
  149.   {
  150.     log::Debug(log_module_, "Got state: %u", client_state);
  151.   }
  152. }
  153.  
  154. Value JsPipe::Export_DisconnectClient(const v8::Arguments& args)
  155. {
  156.   v8::Locker lock;
  157.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  158.   v8::HandleScope handle_scope;
  159.  
  160.   //log::Debug(log_module_, "%s called!", __FUNCTION__);
  161.  
  162.   if (args.Length() < 1)
  163.   {
  164.     log::Error(log_module_, "%s: To few arguments.", __FUNCTION__);
  165.     return handle_scope.Close(v8::Boolean::New(false));
  166.   }
  167.  
  168.   net::Manager::Instance()->Disconnect(args[0]->Uint32Value());
  169.   return handle_scope.Close(v8::Boolean::New(true));
  170. }
  171.  
  172. }; // namespace plugin
  173. }; // namespace vm
  174. }; // namespace atom
  175.