Subversion Repositories HomeAutomation

Rev

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