Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
2107 runge 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