Subversion Repositories HomeAutomation

Rev

Rev 1229 | Rev 1405 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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