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