Subversion Repositories HomeAutomation

Rev

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

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