Subversion Repositories HomeAutomation

Rev

Go to most recent revision | 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.   net::Manager::Instance()->SendTo(request_id, common::Byteset(output.begin(), output.end()));
  74. }
  75.  
  76. void JsPipe::SlotOnNewData(net::SocketId id, common::Byteset data)
  77. {
  78.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewDataHandler, this, id, data));
  79. }
  80.  
  81. void JsPipe::SlotOnNewClient(net::SocketId id, net::SocketId server_id)
  82. {
  83.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewClientHandler, this, id, server_id));
  84. }
  85.  
  86. void JsPipe::SlotOnNewState(net::SocketId id, net::ClientState client_state)
  87. {
  88.   this->io_service_.post(boost::bind(&JsPipe::SlotOnNewStateHandler, this, id, client_state));
  89. }
  90.  
  91. void JsPipe::SlotOnNewDataHandler(net::SocketId id, common::Byteset data)
  92. {
  93.   v8::Locker lock;
  94.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  95.   v8::HandleScope handle_scope;
  96.  
  97.   if (std::find(this->clients_.begin(), this->clients_.end(), id) == this->clients_.end())
  98.   {
  99.     return;
  100.   }
  101.      
  102.    
  103.   //log::Debug(log_module_, "%s called!", __FUNCTION__);
  104.  
  105.   if (data.size() == 0)
  106.   {
  107.     log::Error("%s got empty data!", __FUNCTION__);
  108.     return;
  109.   }
  110.    
  111.   std::string s(data.begin(), data.end());
  112.  
  113.   this->Execute(id, s);
  114. }
  115.  
  116. void JsPipe::SlotOnNewClientHandler(net::SocketId id, net::SocketId server_id)
  117. {
  118.   if (server_id == this->server_id_)
  119.   {
  120.     this->clients_.insert(id);
  121.   }
  122. }
  123.  
  124. void JsPipe::SlotOnNewStateHandler(net::SocketId id, net::ClientState client_state)
  125. {
  126.   v8::Locker lock;
  127.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  128.   v8::HandleScope handle_scope;
  129.  
  130.   if (std::find(this->clients_.begin(), this->clients_.end(), id) == this->clients_.end())
  131.   {
  132.     return;
  133.   }
  134.    
  135.   //log::Debug(log_module_, "%s called!", __FUNCTION__);  
  136.  
  137.   if (client_state == net::CLIENT_STATE_DISCONNECTED)
  138.   {
  139.     log::Info(log_module_, "Client %u has disconnected from JsPipe.", id);
  140.     this->clients_.erase(id);
  141.   }
  142.   else if (client_state == net::CLIENT_STATE_CONNECTED)
  143.   {
  144.     log::Info(log_module_, "Client %u has connected to JsPipe.", id);
  145.   }
  146.   else
  147.   {
  148.     log::Debug(log_module_, "Got state: %u", client_state);
  149.   }
  150. }
  151.  
  152. Value JsPipe::Export_DisconnectClient(const v8::Arguments& args)
  153. {
  154.   v8::Locker lock;
  155.   v8::Context::Scope context_scope(vm::Manager::Instance()->GetContext());
  156.   v8::HandleScope handle_scope;
  157.  
  158.   //log::Debug(log_module_, "%s called!", __FUNCTION__);  
  159.    
  160.   if (args.Length() < 1)
  161.   {
  162.     log::Error(log_module_, "%s: To few arguments.", __FUNCTION__);
  163.     return handle_scope.Close(v8::Boolean::New(false));
  164.   }
  165.  
  166.   net::Manager::Instance()->Disconnect(args[0]->Uint32Value());
  167.   return handle_scope.Close(v8::Boolean::New(true));
  168. }
  169.  
  170. }; // namespace plugin
  171. }; // namespace vm
  172. }; // namespace atom
  173.