Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
1947 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 "Mbb.h"
22
 
23
#include <boost/lexical_cast.hpp>
24
#include <boost/algorithm/string/trim.hpp>
25
#include <boost/algorithm/string/split.hpp>
1950 runge 26
#include <time.h>
1947 runge 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__);
1950 runge 109
  //clock_t tStart = clock();
1947 runge 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
  }
1950 runge 135
 
136
  //atom::log::Info(log_module_, "Time taken: %.2fs", (double)(clock() - tStart)/CLOCKS_PER_SEC);
1947 runge 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