Subversion Repositories HomeAutomation

Rev

Rev 1010 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1010 Rev 1011
1
/***************************************************************************
1
/***************************************************************************
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
3
 *   mattias@runge.se                                                      *
4
 *   virtualmachine.cpp                                            *
4
 *   virtualmachine.cpp                                            *
5
 *                                                                         *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
20
 ***************************************************************************/
21
 
21
 
22
#include "virtualmachine.h"
22
#include "virtualmachine.h"
23
 
23
 
24
VirtualMachine* VirtualMachine::myInstance = NULL;
24
VirtualMachine* VirtualMachine::myInstance = NULL;
25
 
25
 
26
VirtualMachine& VirtualMachine::getInstance()
26
VirtualMachine& VirtualMachine::getInstance()
27
{
27
{
28
    if (myInstance == NULL)
28
    if (myInstance == NULL)
29
    {
29
    {
30
        myInstance = new VirtualMachine();
30
        myInstance = new VirtualMachine();
31
    }
31
    }
32
 
32
 
33
    return *myInstance;
33
    return *myInstance;
34
}
34
}
35
 
35
 
36
void VirtualMachine::deleteInstance()
36
void VirtualMachine::deleteInstance()
37
{
37
{
38
    if (myInstance != NULL)
38
    if (myInstance != NULL)
39
    {
39
    {
40
        delete myInstance;
40
        delete myInstance;
41
        myInstance = NULL;
41
        myInstance = NULL;
42
    }
42
    }
43
}
43
}
44
 
44
 
45
VirtualMachine::VirtualMachine()
45
VirtualMachine::VirtualMachine()
46
{
46
{
47
}
47
}
48
 
48
 
49
VirtualMachine::~VirtualMachine()
49
VirtualMachine::~VirtualMachine()
50
{
50
{
51
    stop();
51
    stop();
52
 
52
 
53
    myCommandThread.stop();
53
    myCommandThread.stop();
54
 
54
 
55
    ///FIXME: Verify that this works and does not cause segfaults
55
    ///FIXME: Verify that this works and does not cause segfaults
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
57
    {
57
    {
58
        iter->second->stop();
58
        iter->second->stop();
59
        delete iter->second;
59
        delete iter->second;
60
        //mySocketThreads.erase(iter);
60
        //mySocketThreads.erase(iter);
61
    }
61
    }
62
 
62
 
63
    mySocketThreads.clear();
63
    mySocketThreads.clear();
64
 
64
 
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
66
    {
66
    {
67
        iter->second->stop();
67
        iter->second->stop();
68
        delete iter->second;
68
        delete iter->second;
69
        //myIntervalThreads.erase(iter);
69
        //myIntervalThreads.erase(iter);
70
    }
70
    }
71
 
71
 
72
    myIntervalThreads.clear();
72
    myIntervalThreads.clear();
73
}
73
}
74
 
74
 
75
void VirtualMachine::run()
75
void VirtualMachine::run()
76
{
76
{
77
    myGlobal = ObjectTemplate::New();
77
    myGlobal = ObjectTemplate::New();
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
86
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
86
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
87
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
87
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
88
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
88
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
89
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
-
 
90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
89
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
90
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
-
 
91
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
-
 
92
    myGlobal->Set(String::New("hex2bin"), FunctionTemplate::New(VirtualMachine::_hex2bin));
-
 
93
    myGlobal->Set(String::New("bin2hex"), FunctionTemplate::New(VirtualMachine::_bin2hex));
-
 
94
    myGlobal->Set(String::New("bin2float"), FunctionTemplate::New(VirtualMachine::_bin2float));
-
 
95
    myGlobal->Set(String::New("float2bin"), FunctionTemplate::New(VirtualMachine::_float2bin));
-
 
96
    myGlobal->Set(String::New("bin2uint"), FunctionTemplate::New(VirtualMachine::_bin2uint));
-
 
97
    myGlobal->Set(String::New("uint2bin"), FunctionTemplate::New(VirtualMachine::_uint2bin));
-
 
98
    myGlobal->Set(String::New("hex2uint"), FunctionTemplate::New(VirtualMachine::_hex2uint));
92
    myContext = Context::New(NULL, myGlobal);
99
    myContext = Context::New(NULL, myGlobal);
93
 
100
 
94
 
101
 
95
    if (loadScript("System/Base.js"))
102
    if (loadScript("System/Base.js"))
96
    {
103
    {
97
        loadScript("System/Startup.js");
104
        loadScript("System/Startup.js");
98
 
105
 
99
        loadScript("Autostart.js");
106
        loadScript("Autostart.js");
100
 
107
 
101
        Context::Scope contextScope(myContext);
108
        Context::Scope contextScope(myContext);
102
 
109
 
103
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
110
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
104
    }
111
    }
105
    else
112
    else
106
    {
113
    {
107
        ///FIXME: We should probably exit the application here
114
        ///FIXME: We should probably exit the application here
108
        return;
115
        return;
109
    }
116
    }
110
 
117
 
111
    const int argc = 0;
118
    const int argc = 0;
112
    Handle<Value> argv[argc] = { };
119
    Handle<Value> argv[argc] = { };
113
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
120
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
114
 
121
 
115
 
122
 
116
    string commandPort = Settings::get("CommandPort");
123
    string commandPort = Settings::get("CommandPort");
117
    if (commandPort != "")
124
    if (commandPort != "")
118
    {
125
    {
119
        myCommandThread.setSettings(stoi(commandPort), "Command console");
126
        myCommandThread.setSettings(stoi(commandPort), "Command console");
120
        myCommandThread.start();
127
        myCommandThread.start();
121
    }
128
    }
122
    else
129
    else
123
    {
130
    {
124
        SyslogStream &slog = SyslogStream::getInstance();
131
        SyslogStream &slog = SyslogStream::getInstance();
125
        slog << "CommandPort is not defined, can not start Command console socket\n";
132
        slog << "CommandPort is not defined, can not start Command console socket\n";
126
    }
133
    }
127
 
134
 
128
 
135
 
129
    mySemaphore.lock();
136
    mySemaphore.lock();
130
 
137
 
131
    while (true)
138
    while (true)
132
    {
139
    {
133
        while (myExpressions.size() > 0)
140
        while (myExpressions.size() > 0)
134
        {
141
        {
135
            runExpression(myExpressions.pop());
142
            runExpression(myExpressions.pop());
136
        }
143
        }
137
 
144
 
138
        mySemaphore.wait();
145
        mySemaphore.wait();
139
    }
146
    }
140
 
147
 
141
    mySemaphore.unlock();
148
    mySemaphore.unlock();
142
}
149
}
143
 
150
 
144
void VirtualMachine::queueExpression(Expression expression)
151
void VirtualMachine::queueExpression(Expression expression)
145
{
152
{
146
    myExpressions.push(expression);
153
    myExpressions.push(expression);
147
    mySemaphore.broadcast();
154
    mySemaphore.broadcast();
148
}
155
}
149
 
156
 
150
string VirtualMachine::formatException(TryCatch* tryCatch)
157
string VirtualMachine::formatException(TryCatch* tryCatch)
151
{
158
{
152
    string result;
159
    string result;
153
 
160
 
154
    HandleScope handleScope;
161
    HandleScope handleScope;
155
    String::Utf8Value exception(tryCatch->Exception());
162
    String::Utf8Value exception(tryCatch->Exception());
156
    Handle<v8::Message> message = tryCatch->Message();
163
    Handle<v8::Message> message = tryCatch->Message();
157
 
164
 
158
    string strException = *exception;
165
    string strException = *exception;
159
 
166
 
160
    if (message.IsEmpty())
167
    if (message.IsEmpty())
161
    {
168
    {
162
        result += strException + "\n";
169
        result += strException + "\n";
163
    }
170
    }
164
    else
171
    else
165
    {
172
    {
166
        String::Utf8Value filename(message->GetScriptResourceName());
173
        String::Utf8Value filename(message->GetScriptResourceName());
167
        string strFilename = *filename;
174
        string strFilename = *filename;
168
 
175
 
169
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
176
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
170
 
177
 
171
        String::Utf8Value sourceline(message->GetSourceLine());
178
        String::Utf8Value sourceline(message->GetSourceLine());
172
        string strSourceline = *sourceline;
179
        string strSourceline = *sourceline;
173
 
180
 
174
        result += strSourceline + "\n";
181
        result += strSourceline + "\n";
175
 
182
 
176
        string underline = rpad("", message->GetStartColumn(), ' ');
183
        string underline = rpad("", message->GetStartColumn(), ' ');
177
        underline = rpad(underline, message->GetEndColumn(), '^');
184
        underline = rpad(underline, message->GetEndColumn(), '^');
178
 
185
 
179
        result += underline + "\n";
186
        result += underline + "\n";
180
    }
187
    }
181
 
188
 
182
    return result;
189
    return result;
183
}
190
}
184
 
191
 
185
bool VirtualMachine::loadDataStore(string storeName)
192
bool VirtualMachine::loadDataStore(string storeName)
186
{
193
{
187
    SyslogStream &slog = SyslogStream::getInstance();
194
    SyslogStream &slog = SyslogStream::getInstance();
188
 
195
 
189
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
196
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
190
    string scriptFileName = basePath + storeName + ".js";
197
    string scriptFileName = basePath + storeName + ".js";
191
 
198
 
192
    if (!file_exists(scriptFileName))
199
    if (!file_exists(scriptFileName))
193
    {
200
    {
194
        slog << "Failed to load datastore " + scriptFileName + ", file does not exist.\n";
201
        slog << "Failed to load datastore " + scriptFileName + ", file does not exist.\n";
195
        return false;
202
        return false;
196
    }
203
    }
197
 
204
 
198
    string scriptSource = file_get_contents(scriptFileName);
205
    string scriptSource = file_get_contents(scriptFileName);
199
 
206
 
200
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
207
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
201
 
208
 
202
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
209
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
203
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
210
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
204
 
211
 
205
    Context::Scope contextScope(myContext);
212
    Context::Scope contextScope(myContext);
206
 
213
 
207
    TryCatch tryCatch;
214
    TryCatch tryCatch;
208
 
215
 
209
    Handle<Script> script = Script::Compile(source, name);
216
    Handle<Script> script = Script::Compile(source, name);
210
 
217
 
211
    if (script.IsEmpty())
218
    if (script.IsEmpty())
212
    {
219
    {
213
        slog << formatException(&tryCatch);
220
        slog << formatException(&tryCatch);
214
        return false;
221
        return false;
215
    }
222
    }
216
    else
223
    else
217
    {
224
    {
218
        Handle<Value> result = script->Run();
225
        Handle<Value> result = script->Run();
219
 
226
 
220
        if (result.IsEmpty())
227
        if (result.IsEmpty())
221
        {
228
        {
222
            slog << formatException(&tryCatch);
229
            slog << formatException(&tryCatch);
223
            return false;
230
            return false;
224
        }
231
        }
225
 
232
 
226
        slog << "Loaded datastore " + storeName + "\n";
233
        slog << "Loaded datastore " + storeName + "\n";
227
    }
234
    }
228
 
235
 
229
    return true;
236
    return true;
230
}
237
}
231
 
238
 
232
bool VirtualMachine::loadScript(string scriptName)
239
bool VirtualMachine::loadScript(string scriptName)
233
{
240
{
234
    SyslogStream &slog = SyslogStream::getInstance();
241
    SyslogStream &slog = SyslogStream::getInstance();
235
 
242
 
236
    string basePath = Settings::get("BasePath") + "Services/";
243
    string basePath = Settings::get("BasePath") + "Services/";
237
    string scriptFileName = basePath + scriptName;
244
    string scriptFileName = basePath + scriptName;
238
 
245
 
239
    if (!file_exists(scriptFileName))
246
    if (!file_exists(scriptFileName))
240
    {
247
    {
241
        slog << "Failed to load " + scriptFileName + ", file does not exist.\n";
248
        slog << "Failed to load " + scriptFileName + ", file does not exist.\n";
242
        return false;
249
        return false;
243
    }
250
    }
244
 
251
 
245
    string scriptSource = file_get_contents(scriptFileName);
252
    string scriptSource = file_get_contents(scriptFileName);
246
 
253
 
247
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
254
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
248
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
255
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
249
 
256
 
250
    Context::Scope contextScope(myContext);
257
    Context::Scope contextScope(myContext);
251
 
258
 
252
    TryCatch tryCatch;
259
    TryCatch tryCatch;
253
 
260
 
254
    Handle<Script> script = Script::Compile(source, name);
261
    Handle<Script> script = Script::Compile(source, name);
255
 
262
 
256
    if (script.IsEmpty())
263
    if (script.IsEmpty())
257
    {
264
    {
258
        slog << formatException(&tryCatch);
265
        slog << formatException(&tryCatch);
259
        return false;
266
        return false;
260
    }
267
    }
261
    else
268
    else
262
    {
269
    {
263
        Handle<Value> result = script->Run();
270
        Handle<Value> result = script->Run();
264
 
271
 
265
        if (result.IsEmpty())
272
        if (result.IsEmpty())
266
        {
273
        {
267
            slog << formatException(&tryCatch);
274
            slog << formatException(&tryCatch);
268
            return false;
275
            return false;
269
        }
276
        }
270
 
277
 
271
        slog << "Loaded " + scriptName + "\n";
278
        slog << "Loaded " + scriptName + "\n";
272
    }
279
    }
273
 
280
 
274
    return true;
281
    return true;
275
}
282
}
276
 
283
 
277
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
284
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
278
{
285
{
279
    IntervalThread *intervalThread = new IntervalThread(timeout);
286
    IntervalThread *intervalThread = new IntervalThread(timeout);
280
 
287
 
281
    myIntervalThreads[intervalThread->getId()] = intervalThread;
288
    myIntervalThreads[intervalThread->getId()] = intervalThread;
282
    myIntervalThreads[intervalThread->getId()]->start();
289
    myIntervalThreads[intervalThread->getId()]->start();
283
 
290
 
284
    return intervalThread->getId();
291
    return intervalThread->getId();
285
}
292
}
286
 
293
 
287
bool VirtualMachine::stopIntervalThread(unsigned int id)
294
bool VirtualMachine::stopIntervalThread(unsigned int id)
288
{
295
{
289
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
296
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
290
    {
297
    {
291
        delete myIntervalThreads[id];
298
        delete myIntervalThreads[id];
292
        myIntervalThreads.erase(id);
299
        myIntervalThreads.erase(id);
293
        return true;
300
        return true;
294
    }
301
    }
295
 
302
 
296
    return false;
303
    return false;
297
}
304
}
298
 
305
 
299
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
306
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
300
{
307
{
301
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
308
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
302
    mySocketThreads[socketThread->getId()] = socketThread;
309
    mySocketThreads[socketThread->getId()] = socketThread;
303
    mySocketThreads[socketThread->getId()]->start();
310
    mySocketThreads[socketThread->getId()]->start();
304
 
311
 
305
    return socketThread->getId();
312
    return socketThread->getId();
306
}
313
}
307
 
314
 
308
bool VirtualMachine::stopSocketThread(unsigned int id)
315
bool VirtualMachine::stopSocketThread(unsigned int id)
309
{
316
{
310
    if (mySocketThreads.find(id) != mySocketThreads.end())
317
    if (mySocketThreads.find(id) != mySocketThreads.end())
311
    {
318
    {
312
        delete mySocketThreads[id];
319
        delete mySocketThreads[id];
313
        mySocketThreads.erase(id);
320
        mySocketThreads.erase(id);
314
        return true;
321
        return true;
315
    }
322
    }
316
 
323
 
317
    return false;
324
    return false;
318
}
325
}
319
 
326
 
320
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
327
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
321
{
328
{
322
    if (mySocketThreads.find(id) != mySocketThreads.end())
329
    if (mySocketThreads.find(id) != mySocketThreads.end())
323
    {
330
    {
324
        mySocketThreads[id]->send(data);
331
        mySocketThreads[id]->send(data);
325
    }
332
    }
326
}
333
}
327
 
334
 
328
void VirtualMachine::disconnectCommandClient(unsigned int id)
335
void VirtualMachine::disconnectCommandClient(unsigned int id)
329
{
336
{
330
    myCommandThread.disconnectClient(id);
337
    myCommandThread.disconnectClient(id);
331
}
338
}
332
 
339
 
333
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
340
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
334
{
341
{
335
    myCommandThread.sendTo(id, data);
342
    myCommandThread.sendTo(id, data);
336
}
343
}
337
 
344
 
338
void VirtualMachine::print(unsigned int id, string data)
345
void VirtualMachine::print(unsigned int id, string data)
339
{
346
{
340
    if (id == 0)
347
    if (id == 0)
341
    {
348
    {
342
        SyslogStream &slog = SyslogStream::getInstance();
349
        SyslogStream &slog = SyslogStream::getInstance();
343
        slog << data;
350
        slog << data;
344
    }
351
    }
345
    else
352
    else
346
    {
353
    {
347
        VirtualMachine &vm = VirtualMachine::getInstance();
354
        VirtualMachine &vm = VirtualMachine::getInstance();
348
        vm.sendToCommandClient(id, data);
355
        vm.sendToCommandClient(id, data);
349
    }
356
    }
350
}
357
}
351
 
358
 
352
bool VirtualMachine::runExpression(Expression expression)
359
bool VirtualMachine::runExpression(Expression expression)
353
{
360
{
354
    string scriptName = "runExpression";
361
    string scriptName = "runExpression";
355
 
362
 
356
    string scriptData = expression.getScript();
363
    string scriptData = expression.getScript();
357
 
364
 
358
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
365
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
359
 
366
 
360
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
367
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
361
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
368
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
362
 
369
 
363
    Context::Scope contextScope(myContext);
370
    Context::Scope contextScope(myContext);
364
 
371
 
365
    TryCatch tryCatch;
372
    TryCatch tryCatch;
366
 
373
 
367
    Handle<Script> script = Script::Compile(source, name);
374
    Handle<Script> script = Script::Compile(source, name);
368
 
375
 
369
    if (script.IsEmpty())
376
    if (script.IsEmpty())
370
    {
377
    {
371
        print(expression.getTargetId(), formatException(&tryCatch));
378
        print(expression.getTargetId(), formatException(&tryCatch));
372
        return false;
379
        return false;
373
    }
380
    }
374
    else
381
    else
375
    {
382
    {
376
        Handle<Value> result = script->Run();
383
        Handle<Value> result = script->Run();
377
 
384
 
378
        if (result.IsEmpty())
385
        if (result.IsEmpty())
379
        {
386
        {
380
            print(expression.getTargetId(), formatException(&tryCatch));
387
            print(expression.getTargetId(), formatException(&tryCatch));
381
            return false;
388
            return false;
382
        }
389
        }
383
        else if (expression.getTargetId() != 0)
390
        else if (expression.getTargetId() != 0)
384
        {
391
        {
385
             String::AsciiValue ascii(result);
392
             String::AsciiValue ascii(result);
386
             string resultString = *ascii;
393
             string resultString = *ascii;
387
 
394
 
388
             if (resultString != "undefined")
395
             if (resultString != "undefined")
389
             {
396
             {
390
                print(expression.getTargetId(), resultString + "\n");
397
                print(expression.getTargetId(), resultString + "\n");
391
             }
398
             }
392
        }
399
        }
393
    }
400
    }
394
 
401
 
395
    return true;
402
    return true;
396
}
403
}
397
 
404
 
398
 
405
 
399
Handle<Value> VirtualMachine::_quit(const Arguments& args)
406
Handle<Value> VirtualMachine::_quit(const Arguments& args)
400
{
407
{
401
    VirtualMachine &vm = VirtualMachine::getInstance();
408
    VirtualMachine &vm = VirtualMachine::getInstance();
402
 
409
 
403
    vm.disconnectCommandClient(args[0]->Uint32Value());
410
    vm.disconnectCommandClient(args[0]->Uint32Value());
404
 
411
 
405
    return Undefined();
412
    return Undefined();
406
}
413
}
407
 
414
 
408
Handle<Value> VirtualMachine::_log(const Arguments& args)
415
Handle<Value> VirtualMachine::_log(const Arguments& args)
409
{
416
{
410
    SyslogStream &slog = SyslogStream::getInstance();
417
    SyslogStream &slog = SyslogStream::getInstance();
411
 
418
 
412
    String::AsciiValue str(args[0]);
419
    String::AsciiValue str(args[0]);
413
 
420
 
414
    slog << *str;
421
    slog << *str;
415
 
422
 
416
    return Undefined();
423
    return Undefined();
417
}
424
}
418
 
425
 
419
Handle<Value> VirtualMachine::_print(const Arguments& args)
426
Handle<Value> VirtualMachine::_print(const Arguments& args)
420
{
427
{
421
    VirtualMachine &vm = VirtualMachine::getInstance();
428
    VirtualMachine &vm = VirtualMachine::getInstance();
422
 
429
 
423
    String::AsciiValue str(args[1]);
430
    String::AsciiValue str(args[1]);
424
 
431
 
425
    vm.print(args[0]->Uint32Value(), *str);
432
    vm.print(args[0]->Uint32Value(), *str);
426
 
433
 
427
    return Undefined();
434
    return Undefined();
428
}
435
}
429
 
436
 
430
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
437
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
431
{
438
{
432
    CanNetManager &canMan = CanNetManager::getInstance();
439
    CanNetManager &canMan = CanNetManager::getInstance();
433
 
440
 
434
    CanMessage canMessage;
441
    CanMessage canMessage;
435
 
442
 
436
    String::AsciiValue className(args[0]);
443
    String::AsciiValue className(args[0]);
437
    canMessage.setClassName(*className);
444
    canMessage.setClassName(*className);
438
    String::AsciiValue directionFlag(args[1]);
445
    String::AsciiValue directionFlag(args[1]);
439
    canMessage.setDirectionFlag(*directionFlag);
446
    canMessage.setDirectionFlag(*directionFlag);
440
    String::AsciiValue moduleName(args[2]);
447
    String::AsciiValue moduleName(args[2]);
441
    canMessage.setModuleName(*moduleName);
448
    canMessage.setModuleName(*moduleName);
442
    canMessage.setModuleId(args[3]->Uint32Value());
449
    canMessage.setModuleId(args[3]->Uint32Value());
443
    String::AsciiValue commandName(args[4]);
450
    String::AsciiValue commandName(args[4]);
444
    canMessage.setCommandName(*commandName);
451
    canMessage.setCommandName(*commandName);
445
 
452
 
446
    String::AsciiValue dataString(args[5]);
453
    String::AsciiValue dataString(args[5]);
447
 
454
 
448
    vector<string> parts = explode(",", trim(*dataString, ','));
455
    vector<string> parts = explode(",", trim(*dataString, ','));
449
    map<string, CanVariable> data;
456
    map<string, CanVariable> data;
450
 
457
 
451
    for (int n = 0; n < parts.size(); n++)
458
    for (int n = 0; n < parts.size(); n++)
452
    {
459
    {
453
        vector<string> keyAndValue = explode(":", parts[n]);
460
        vector<string> keyAndValue = explode(":", parts[n]);
454
 
461
 
455
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
462
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
456
    }
463
    }
457
 
464
 
458
    canMessage.setData(data);
465
    canMessage.setData(data);
459
   
466
   
460
    canMan.sendMessage(canMessage);
467
    canMan.sendMessage(canMessage);
461
 
468
 
462
    return Undefined();
469
    return Undefined();
463
}
470
}
464
 
471
 
465
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
472
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
466
{
473
{
467
    CanNetManager &canMan = CanNetManager::getInstance();
474
    CanNetManager &canMan = CanNetManager::getInstance();
468
 
475
 
469
    CanMessage canMessage;
476
    CanMessage canMessage;
470
 
477
 
471
    String::AsciiValue className(args[0]);
478
    String::AsciiValue className(args[0]);
472
    canMessage.setClassName(*className);
479
    canMessage.setClassName(*className);
473
    String::AsciiValue commandName(args[1]);
480
    String::AsciiValue commandName(args[1]);
474
    canMessage.setCommandName(*commandName);
481
    canMessage.setCommandName(*commandName);
475
 
482
 
476
    String::AsciiValue dataString(args[2]);
483
    String::AsciiValue dataString(args[2]);
477
 
484
 
478
    vector<string> parts = explode(",", trim(*dataString, ','));
485
    vector<string> parts = explode(",", trim(*dataString, ','));
479
    map<string, CanVariable> data;
486
    map<string, CanVariable> data;
480
 
487
 
481
    for (int n = 0; n < parts.size(); n++)
488
    for (int n = 0; n < parts.size(); n++)
482
    {
489
    {
483
        vector<string> keyAndValue = explode(":", parts[n]);
490
        vector<string> keyAndValue = explode(":", parts[n]);
484
 
491
 
485
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
492
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
486
    }
493
    }
487
 
494
 
488
    canMessage.setData(data);
495
    canMessage.setData(data);
489
 
496
 
490
    canMan.sendMessage(canMessage);
497
    canMan.sendMessage(canMessage);
491
 
498
 
492
    return Undefined();
499
    return Undefined();
493
}
500
}
494
 
501
 
495
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
502
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
496
{
503
{
497
    VirtualMachine &vm = VirtualMachine::getInstance();
504
    VirtualMachine &vm = VirtualMachine::getInstance();
498
 
505
 
499
    String::AsciiValue str(args[0]);
506
    String::AsciiValue str(args[0]);
500
 
507
 
501
    return Boolean::New(vm.loadScript(*str));
508
    return Boolean::New(vm.loadScript(*str));
502
}
509
}
503
 
510
 
504
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
511
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
505
{
512
{
506
    VirtualMachine &vm = VirtualMachine::getInstance();
513
    VirtualMachine &vm = VirtualMachine::getInstance();
507
 
514
 
508
    String::AsciiValue str(args[0]);
515
    String::AsciiValue str(args[0]);
509
 
516
 
510
    return Boolean::New(vm.loadDataStore(*str));
517
    return Boolean::New(vm.loadDataStore(*str));
511
}
518
}
512
 
519
 
513
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
520
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
514
{
521
{
515
    VirtualMachine &vm = VirtualMachine::getInstance();
522
    VirtualMachine &vm = VirtualMachine::getInstance();
516
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
523
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
517
}
524
}
518
 
525
 
519
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
526
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
520
{
527
{
521
    VirtualMachine &vm = VirtualMachine::getInstance();
528
    VirtualMachine &vm = VirtualMachine::getInstance();
522
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
529
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
523
}
530
}
524
 
531
 
525
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
532
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
526
{
533
{
527
    VirtualMachine &vm = VirtualMachine::getInstance();
534
    VirtualMachine &vm = VirtualMachine::getInstance();
528
 
535
 
529
    String::AsciiValue address(args[0]);
536
    String::AsciiValue address(args[0]);
530
 
537
 
531
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
538
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
532
}
539
}
533
 
540
 
534
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
541
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
535
{
542
{
536
    VirtualMachine &vm = VirtualMachine::getInstance();
543
    VirtualMachine &vm = VirtualMachine::getInstance();
537
 
544
 
538
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
545
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
539
}
546
}
540
 
547
 
541
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
548
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
542
{
549
{
543
    VirtualMachine &vm = VirtualMachine::getInstance();
550
    VirtualMachine &vm = VirtualMachine::getInstance();
544
 
551
 
545
    String::AsciiValue data(args[1]);
552
    String::AsciiValue data(args[1]);
546
 
553
 
547
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
554
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
548
 
555
 
549
    return Undefined();
556
    return Undefined();
550
}
557
}
551
 
558
 
552
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
559
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
553
{
560
{
554
    String::AsciiValue filename(args[0]);
561
    String::AsciiValue filename(args[0]);
555
 
562
 
556
    if (!file_exists(*filename))
563
    if (!file_exists(*filename))
557
    {
564
    {
558
        return Undefined();
565
        return Undefined();
559
    }
566
    }
560
 
567
 
561
    string content = file_get_contents(*filename);
568
    string content = file_get_contents(*filename);
562
 
569
 
563
    return String::New(content.c_str());
570
    return String::New(content.c_str());
564
}
571
}
565
 
572
 
566
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
573
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
567
{
574
{
568
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
575
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
569
    return String::New(hex.c_str());
576
    return String::New(hex.c_str());
570
}
577
}
571
 
578
 
572
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
579
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
573
{
580
{
574
    String::AsciiValue hex(args[0]);
581
    String::AsciiValue hex(args[0]);
575
    string bin = hex2bin(*hex);
582
    string bin = hex2bin(*hex);
576
    return String::New(bin.c_str());
583
    return String::New(bin.c_str());
577
}
584
}
578
 
585
 
579
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
586
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
580
{
587
{
581
    String::AsciiValue bin(args[0]);
588
    String::AsciiValue bin(args[0]);
582
    string hex = bin2hex(*bin);
589
    string hex = bin2hex(*bin);
583
    return String::New(hex.c_str());
590
    return String::New(hex.c_str());
584
}
591
}
585
 
592
 
586
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
593
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
587
{
594
{
588
    String::AsciiValue bin(args[0]);
595
    String::AsciiValue bin(args[0]);
589
    float f = bin2float(*bin);
596
    float f = bin2float(*bin);
590
    return Number::New(f);
597
    return Number::New(f);
591
}
598
}
592
 
599
 
593
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
600
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
594
{
601
{
595
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
602
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
596
    return String::New(bin.c_str());
603
    return String::New(bin.c_str());
597
}
604
}
598
 
605
 
599
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
606
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
600
{
607
{
601
    String::AsciiValue bin(args[0]);
608
    String::AsciiValue bin(args[0]);
602
    unsigned int num = bin2uint(*bin);
609
    unsigned int num = bin2uint(*bin);
603
    return Uint32::New(num);
610
    return Uint32::New(num);
604
}
611
}
605
 
612
 
606
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
613
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
607
{
614
{
608
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
615
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
609
    return String::New(bin.c_str());
616
    return String::New(bin.c_str());
610
}
617
}
611
 
618
 
-
 
619
Handle<Value> VirtualMachine::_hex2uint(const Arguments& args)
612
 
620
{
-
 
621
    String::AsciiValue hex(args[0]);
-
 
622
    unsigned int num = hex2uint(*hex);
-
 
623
    return Uint32::New(num);
-
 
624
}
613
 
625