Subversion Repositories HomeAutomation

Rev

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

Rev 977 Rev 981
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
 
-
 
22
#include <map>
-
 
23
 
-
 
24
 
21
 
25
#include "virtualmachine.h"
22
#include "virtualmachine.h"
26
 
23
 
27
VirtualMachine* VirtualMachine::myInstance = NULL;
24
VirtualMachine* VirtualMachine::myInstance = NULL;
28
 
25
 
29
VirtualMachine& VirtualMachine::getInstance()
26
VirtualMachine& VirtualMachine::getInstance()
30
{
27
{
31
    if (myInstance == NULL)
28
    if (myInstance == NULL)
32
    {
29
    {
33
        myInstance = new VirtualMachine();
30
        myInstance = new VirtualMachine();
34
    }
31
    }
35
 
32
 
36
    return *myInstance;
33
    return *myInstance;
37
}
34
}
38
 
35
 
39
void VirtualMachine::deleteInstance()
36
void VirtualMachine::deleteInstance()
40
{
37
{
41
    if (myInstance != NULL)
38
    if (myInstance != NULL)
42
    {
39
    {
43
        delete myInstance;
40
        delete myInstance;
44
        myInstance = NULL;
41
        myInstance = NULL;
45
    }
42
    }
46
}
43
}
47
 
44
 
48
VirtualMachine::VirtualMachine()
45
VirtualMachine::VirtualMachine()
49
{
46
{
50
   
-
 
-
 
47
    Thread<VirtualMachine>();
51
}
48
}
52
 
49
 
53
VirtualMachine::~VirtualMachine()
50
VirtualMachine::~VirtualMachine()
54
{
51
{
55
   
52
    stop();
56
}
53
}
57
 
54
 
58
void VirtualMachine::run()
55
void VirtualMachine::run()
59
{
56
{
60
    SyslogStream &slog = SyslogStream::getInstance();
57
    SyslogStream &slog = SyslogStream::getInstance();
61
 
58
 
62
    string basePath = Settings::get("BasePath") + "Services/";
59
    string basePath = Settings::get("BasePath") + "Services/";
63
    string scriptName = "Base.js";
60
    string scriptName = "Base.js";
64
    string scriptFileName = basePath + "System/" + scriptName;
61
    string scriptFileName = basePath + "System/" + scriptName;
65
 
62
 
66
    if (!file_exists(scriptFileName))
63
    if (!file_exists(scriptFileName))
67
    {
64
    {
68
        slog << "Failed to load :" + scriptFileName + "\n";
65
        slog << "Failed to load :" + scriptFileName + "\n";
69
    }
66
    }
70
 
67
 
71
    string scriptSource = file_get_contents(scriptFileName);
68
    string scriptSource = file_get_contents(scriptFileName);
72
 
69
 
73
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
70
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
74
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
71
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
75
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
72
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
76
 
73
 
77
    // Create a template for the global object.
74
    // Create a template for the global object.
78
    myGlobal = ObjectTemplate::New();
75
    myGlobal = ObjectTemplate::New();
79
 
76
 
80
    //associates "print" on script to the Print function
77
    //associates "print" on script to the Print function
81
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine_log));
78
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine_log));
82
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine_sendCanMessage));
79
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine_sendCanMessage));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine_loadScript));
80
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine_loadScript));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine_startIntervalThread));
81
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine_startIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine_stopIntervalThread));
82
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine_stopIntervalThread));
86
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine_startSocketThread));
83
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine_startSocketThread));
87
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine_stopSocketThread));
84
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine_stopSocketThread));
88
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine_sendToSocketThread));
85
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine_sendToSocketThread));
-
 
86
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine_uint2hex));
89
 
87
 
90
    //create context for the script
88
    //create context for the script
91
    myContext = Context::New(NULL, myGlobal);
89
    myContext = Context::New(NULL, myGlobal);
92
 
90
 
93
 
91
 
94
    //access global context within this scope
92
    //access global context within this scope
95
    Context::Scope context_scope(myContext);
93
    Context::Scope context_scope(myContext);
96
    //exception handler
94
    //exception handler
97
    TryCatch try_catch;
95
    TryCatch try_catch;
98
    //compile script to binary code - JIT
96
    //compile script to binary code - JIT
99
    Handle<Script> script = Script::Compile(source, name);
97
    Handle<Script> script = Script::Compile(source, name);
100
 
98
 
101
    //check if we got problems on compilation
99
    //check if we got problems on compilation
102
    if (script.IsEmpty())
100
    if (script.IsEmpty())
103
    {
101
    {
104
 
102
 
105
        // Print errors that happened during compilation.
103
        // Print errors that happened during compilation.
106
        String::AsciiValue error(try_catch.Exception());
104
        String::AsciiValue error(try_catch.Exception());
107
        string sError = *error;
105
        string sError = *error;
108
        slog << "Failed to compile script: " + sError + "\n";
106
        slog << "Failed to compile script: " + sError + "\n";
109
    }
107
    }
110
    else
108
    else
111
    {
109
    {
112
        //no errors , let's continue
110
        //no errors , let's continue
113
        Handle<Value> result = script->Run();
111
        Handle<Value> result = script->Run();
114
 
112
 
115
        //check if execution ended with errors
113
        //check if execution ended with errors
116
        if (result.IsEmpty())
114
        if (result.IsEmpty())
117
        {
115
        {
118
            // Print errors that happened during execution.
116
            // Print errors that happened during execution.
119
            String::AsciiValue error(try_catch.Exception());
117
            String::AsciiValue error(try_catch.Exception());
120
            string sError = *error;
118
            string sError = *error;
121
            slog << "Constructor: Failed to run script: " << sError << "\n";
119
            slog << "Constructor: Failed to run script: " << sError << "\n";
122
        }
120
        }
123
        else
121
        else
124
        {
122
        {
125
            loadScript("System/Startup.js");
123
            loadScript("System/Startup.js");
126
 
124
 
127
            if (file_exists(basePath + "Autostart.js"))
125
            if (file_exists(basePath + "Autostart.js"))
128
            {
126
            {
129
                loadScript("Autostart.js");
127
                loadScript("Autostart.js");
130
            }
128
            }
131
           
129
           
132
            myFunctionHandleHeartbeat = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleHeartbeat")));
130
            myFunctionHandleHeartbeat = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleHeartbeat")));
133
            myFunctionOfflineCheck = Handle<Function>::Cast(myContext->Global()->Get(String::New("offlineCheck")));
131
            myFunctionOfflineCheck = Handle<Function>::Cast(myContext->Global()->Get(String::New("offlineCheck")));
134
            myFunctionHandleMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleMessage")));
132
            myFunctionHandleMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleMessage")));
135
            myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
133
            myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
136
        }
134
        }
137
    }
135
    }
138
 
136
 
139
    const int argc = 0;
137
    const int argc = 0;
140
    Handle<Value> argv[argc] = { };
138
    Handle<Value> argv[argc] = { };
141
 
139
 
142
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv); // argc and argv are your standard arguments to a function
140
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv); // argc and argv are your standard arguments to a function
143
 
141
 
144
    mySemaphore.lock();
142
    mySemaphore.lock();
145
 
143
 
146
    while (1)
144
    while (1)
147
    {
145
    {
148
        string expression;
146
        string expression;
149
 
147
 
150
        while (myExpressions.size() > 0)
148
        while (myExpressions.size() > 0)
151
        {
149
        {
152
            expression = myExpressions.pop();
150
            expression = myExpressions.pop();
153
 
151
 
154
            runExpression(expression);
152
            runExpression(expression);
155
        }
153
        }
156
 
154
 
157
        CanMessage canMessage;
155
        CanMessage canMessage;
158
 
156
 
159
        while (myCanMessages.size() > 0)
157
        while (myCanMessages.size() > 0)
160
        {
158
        {
161
            canMessage = myCanMessages.pop();
159
            canMessage = myCanMessages.pop();
162
 
160
 
163
            if (canMessage.isHeartbeat())
161
            if (canMessage.isHeartbeat())
164
            {
162
            {
165
                callHandleHeartbeat(stoi(canMessage.getData()["HardwareId"].getValue()));
163
                callHandleHeartbeat(stoi(canMessage.getData()["HardwareId"].getValue()));
166
            }
164
            }
167
            else
165
            else
168
            {
166
            {
169
                callHandleMessage(canMessage);
167
                callHandleMessage(canMessage);
170
            }
168
            }
171
        }
169
        }
172
 
170
 
173
        mySemaphore.wait();
171
        mySemaphore.wait();
174
    }
172
    }
175
 
173
 
176
    mySemaphore.unlock();
174
    mySemaphore.unlock();
177
}
175
}
178
 
176
 
179
void VirtualMachine::queueCanMessage(CanMessage canMessage)
177
void VirtualMachine::queueCanMessage(CanMessage canMessage)
180
{
178
{
181
    myCanMessages.push(canMessage);
179
    myCanMessages.push(canMessage);
182
    mySemaphore.broadcast();
180
    mySemaphore.broadcast();
183
}
181
}
184
 
182
 
185
void VirtualMachine::queueExpression(string expression)
183
void VirtualMachine::queueExpression(string expression)
186
{
184
{
187
    myExpressions.push(expression);
185
    myExpressions.push(expression);
188
    mySemaphore.broadcast();
186
    mySemaphore.broadcast();
189
}
187
}
190
 
188
 
191
bool VirtualMachine::loadScript(string scriptName)
189
bool VirtualMachine::loadScript(string scriptName)
192
{
190
{
193
    SyslogStream &slog = SyslogStream::getInstance();
191
    SyslogStream &slog = SyslogStream::getInstance();
194
 
192
 
195
    string basePath = Settings::get("BasePath") + "/Services/";
193
    string basePath = Settings::get("BasePath") + "Services/";
196
    string scriptFileName = basePath + scriptName;
194
    string scriptFileName = basePath + scriptName;
197
 
195
 
198
    if (!file_exists(scriptFileName))
196
    if (!file_exists(scriptFileName))
199
    {
197
    {
200
        slog << "Failed to load :" + scriptFileName + "\n";
198
        slog << "Failed to load " + scriptFileName + "\n";
201
        return false;
199
        return false;
202
    }
200
    }
203
 
201
 
204
    string scriptSource = file_get_contents(scriptFileName);
202
    string scriptSource = file_get_contents(scriptFileName);
205
 
203
 
206
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
204
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
207
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
205
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
208
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
206
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
209
 
207
 
210
    //access global context within this scope
208
    //access global context within this scope
211
    Context::Scope context_scope(myContext);
209
    Context::Scope context_scope(myContext);
212
    //exception handler
210
    //exception handler
213
    TryCatch try_catch;
211
    TryCatch try_catch;
214
    //compile script to binary code - JIT
212
    //compile script to binary code - JIT
215
    Handle<Script> script = Script::Compile(source, name);
213
    Handle<Script> script = Script::Compile(source, name);
216
 
214
 
217
    //check if we got problems on compilation
215
    //check if we got problems on compilation
218
    if (script.IsEmpty())
216
    if (script.IsEmpty())
219
    {
217
    {
220
        // Print errors that happened during compilation.
218
        // Print errors that happened during compilation.
221
        String::AsciiValue error(try_catch.Exception());
219
        String::AsciiValue error(try_catch.Exception());
222
        string sError = *error;
220
        string sError = *error;
223
        slog << "loadScript: Failed to compile script: " + sError + "\n";
221
        slog << "loadScript: Failed to compile script: " + sError + "\n";
224
        return false;
222
        return false;
225
    }
223
    }
226
    else
224
    else
227
    {
225
    {
228
        //no errors , let's continue
226
        //no errors , let's continue
229
        Handle<Value> result = script->Run();
227
        Handle<Value> result = script->Run();
230
 
228
 
231
        //check if execution ended with errors
229
        //check if execution ended with errors
232
        if (result.IsEmpty())
230
        if (result.IsEmpty())
233
        {
231
        {
234
            // Print errors that happened during execution.
232
            // Print errors that happened during execution.
235
            String::AsciiValue error(try_catch.Exception());
233
            String::AsciiValue error(try_catch.Exception());
236
            string sError = *error;
234
            string sError = *error;
237
            slog << "loadScript: Failed to run script: " + sError + "\n";
235
            slog << "loadScript: Failed to run script: " + sError + "\n";
238
            return false;
236
            return false;
239
        }
237
        }
240
 
238
 
241
        slog << "Loaded " + scriptName + "\n";
239
        slog << "Loaded " + scriptName + "\n";
242
    }
240
    }
243
 
241
 
244
    return true;
242
    return true;
245
}
243
}
246
 
244
 
247
void VirtualMachine::callHandleHeartbeat(int hardwareId)
245
void VirtualMachine::callHandleHeartbeat(int hardwareId)
248
{
246
{
249
    const int argc = 1;
247
    const int argc = 1;
250
    Handle<Value> argv[argc] = { Integer::New(hardwareId) };
248
    Handle<Value> argv[argc] = { Integer::New(hardwareId) };
251
 
249
 
252
    Handle<Value> result = myFunctionHandleHeartbeat->Call(myFunctionHandleHeartbeat, argc, argv); // argc and argv are your standard arguments to a function
250
    Handle<Value> result = myFunctionHandleHeartbeat->Call(myFunctionHandleHeartbeat, argc, argv); // argc and argv are your standard arguments to a function
253
}
251
}
254
 
252
 
255
void VirtualMachine::callHandleMessage(CanMessage canMessage)
253
void VirtualMachine::callHandleMessage(CanMessage canMessage)
256
{
254
{
257
    const int argc = 6;
255
    const int argc = 6;
-
 
256
 
-
 
257
    string jsonData = canMessage.getJSONData();
-
 
258
 
258
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
259
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
259
                                String::New(canMessage.getDirectionFlag().c_str()),
260
                                String::New(canMessage.getDirectionFlag().c_str()),
260
                                String::New(canMessage.getModuleName().c_str()),
261
                                String::New(canMessage.getModuleName().c_str()),
261
                                Integer::New(canMessage.getModuleId()),
262
                                Integer::New(canMessage.getModuleId()),
262
                                String::New(canMessage.getCommandName().c_str()),
263
                                String::New(canMessage.getCommandName().c_str()),
263
                                String::New(canMessage.getJSONData().c_str()) };
264
                                String::New(jsonData.c_str()) };
264
 
265
 
265
    Handle<Value> result = myFunctionHandleMessage->Call(myFunctionHandleMessage, argc, argv); // argc and argv are your standard arguments to a function
266
    Handle<Value> result = myFunctionHandleMessage->Call(myFunctionHandleMessage, argc, argv); // argc and argv are your standard arguments to a function
266
}
267
}
267
 
268
 
268
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
269
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
269
{
270
{
270
    IntervalThread intervalThread(timeout);
271
    IntervalThread intervalThread(timeout);
271
 
272
 
272
    myIntervalThreads[intervalThread.getId()] = intervalThread;
273
    myIntervalThreads[intervalThread.getId()] = intervalThread;
273
    myIntervalThreads[intervalThread.getId()].start();
274
    myIntervalThreads[intervalThread.getId()].start();
274
 
275
 
275
    return intervalThread.getId();
276
    return intervalThread.getId();
276
}
277
}
277
 
278
 
278
bool VirtualMachine::stopIntervalThread(unsigned int id)
279
bool VirtualMachine::stopIntervalThread(unsigned int id)
279
{
280
{
280
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
281
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
281
    {
282
    {
282
        myIntervalThreads.erase(id);
283
        myIntervalThreads.erase(id);
283
        return true;
284
        return true;
284
    }
285
    }
285
 
286
 
286
    return false;
287
    return false;
287
}
288
}
288
 
289
 
289
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
290
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
290
{
291
{
291
    SocketThread socketThread(address, port, reconnectTimeout);
292
    SocketThread socketThread(address, port, reconnectTimeout);
292
    mySocketThreads[socketThread.getId()] = socketThread;
293
    mySocketThreads[socketThread.getId()] = socketThread;
293
    mySocketThreads[socketThread.getId()].start();
294
    mySocketThreads[socketThread.getId()].start();
294
 
295
 
295
    return socketThread.getId();
296
    return socketThread.getId();
296
}
297
}
297
 
298
 
298
bool VirtualMachine::stopSocketThread(unsigned int id)
299
bool VirtualMachine::stopSocketThread(unsigned int id)
299
{
300
{
300
    if (mySocketThreads.find(id) != mySocketThreads.end())
301
    if (mySocketThreads.find(id) != mySocketThreads.end())
301
    {
302
    {
302
        mySocketThreads.erase(id);
303
        mySocketThreads.erase(id);
303
        return true;
304
        return true;
304
    }
305
    }
305
 
306
 
306
    return false;
307
    return false;
307
}
308
}
308
 
309
 
309
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
310
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
310
{
311
{
311
    if (mySocketThreads.find(id) != mySocketThreads.end())
312
    if (mySocketThreads.find(id) != mySocketThreads.end())
312
    {
313
    {
313
        mySocketThreads[id].send(data);
314
        mySocketThreads[id].send(data);
314
    }
315
    }
315
}
316
}
316
 
317
 
317
bool VirtualMachine::runExpression(string expression)
318
bool VirtualMachine::runExpression(string expression)
318
{
319
{
319
    SyslogStream &slog = SyslogStream::getInstance();
320
    SyslogStream &slog = SyslogStream::getInstance();
320
 
321
 
321
    string scriptName = "runExpression";
322
    string scriptName = "runExpression";
322
 
323
 
323
    Handle<String> source =  String::New(expression.c_str(), expression.length());
324
    Handle<String> source =  String::New(expression.c_str(), expression.length());
324
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
325
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
325
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
326
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
326
 
327
 
327
    //access global context within this scope
328
    //access global context within this scope
328
    Context::Scope context_scope(myContext);
329
    Context::Scope context_scope(myContext);
329
    //exception handler
330
    //exception handler
330
    TryCatch try_catch;
331
    TryCatch try_catch;
331
    //compile script to binary code - JIT
332
    //compile script to binary code - JIT
332
    Handle<Script> script = Script::Compile(source, name);
333
    Handle<Script> script = Script::Compile(source, name);
333
 
334
 
334
    //check if we got problems on compilation
335
    //check if we got problems on compilation
335
    if (script.IsEmpty())
336
    if (script.IsEmpty())
336
    {
337
    {
337
        // Print errors that happened during compilation.
338
        // Print errors that happened during compilation.
338
        String::AsciiValue error(try_catch.Exception());
339
        String::AsciiValue error(try_catch.Exception());
339
        string sError = *error;
340
        string sError = *error;
340
        slog << "runExpression: Failed to compile script: " + sError + "\n";
341
        slog << "runExpression: Failed to compile script: " + sError + "\n";
341
        slog << expression << "\n\n";
342
        slog << expression << "\n\n";
342
        return false;
343
        return false;
343
    }
344
    }
344
    else
345
    else
345
    {
346
    {
346
        //no errors , let's continue
347
        //no errors , let's continue
347
        Handle<Value> result = script->Run();
348
        Handle<Value> result = script->Run();
348
 
349
 
349
        //check if execution ended with errors
350
        //check if execution ended with errors
350
        if (result.IsEmpty())
351
        if (result.IsEmpty())
351
        {
352
        {
352
            // Print errors that happened during execution.
353
            // Print errors that happened during execution.
353
            String::AsciiValue error(try_catch.Exception());
354
            String::AsciiValue error(try_catch.Exception());
354
            string sError = *error;
355
            string sError = *error;
355
            slog << "runExpression: Failed to run script: " + sError + "\n";
356
            slog << "runExpression: Failed to run script: " + sError + "\n";
356
            return false;
357
            return false;
357
        }
358
        }
358
    }
359
    }
359
 
360
 
360
    return true;
361
    return true;
361
}
362
}
362
 
363
 
363
Handle<Value> VirtualMachine_log(const Arguments& args)
364
Handle<Value> VirtualMachine_log(const Arguments& args)
364
{
365
{
365
    SyslogStream &slog = SyslogStream::getInstance();
366
    SyslogStream &slog = SyslogStream::getInstance();
366
 
367
 
367
    String::AsciiValue str(args[0]);
368
    String::AsciiValue str(args[0]);
368
 
369
 
369
    slog << *str;
370
    slog << *str;
370
 
371
 
371
    return Undefined();
372
    return Undefined();
372
}
373
}
373
 
374
 
374
Handle<Value> VirtualMachine_sendCanMessage(const Arguments& args)
375
Handle<Value> VirtualMachine_sendCanMessage(const Arguments& args)
375
{
376
{
376
    //SyslogStream &slog = SyslogStream::getInstance();
377
    //SyslogStream &slog = SyslogStream::getInstance();
377
    CanNetManager &canMan = CanNetManager::getInstance();
378
    CanNetManager &canMan = CanNetManager::getInstance();
378
 
379
 
379
    CanMessage canMessage;
380
    CanMessage canMessage;
380
 
381
 
381
    String::AsciiValue className(args[0]);
382
    String::AsciiValue className(args[0]);
382
    canMessage.setClassName(*className);
383
    canMessage.setClassName(*className);
383
    String::AsciiValue directionFlag(args[1]);
384
    String::AsciiValue directionFlag(args[1]);
384
    canMessage.setDirectionFlag(*directionFlag);
385
    canMessage.setDirectionFlag(*directionFlag);
385
    String::AsciiValue moduleName(args[2]);
386
    String::AsciiValue moduleName(args[2]);
386
    canMessage.setModuleName(*moduleName);
387
    canMessage.setModuleName(*moduleName);
387
    canMessage.setModuleId(args[3]->Uint32Value());
388
    canMessage.setModuleId(args[3]->Uint32Value());
388
    String::AsciiValue commandName(args[4]);
389
    String::AsciiValue commandName(args[4]);
389
    canMessage.setCommandName(*commandName);
390
    canMessage.setCommandName(*commandName);
390
 
391
 
391
    String::AsciiValue dataString(args[5]);
392
    String::AsciiValue dataString(args[5]);
392
 
393
 
393
    vector<string> parts = explode(",", trim(*dataString, ','));
394
    vector<string> parts = explode(",", trim(*dataString, ','));
394
    map<string, CanVariable> data;
395
    map<string, CanVariable> data;
395
 
396
 
396
    for (int n = 0; n < parts.size(); n++)
397
    for (int n = 0; n < parts.size(); n++)
397
    {
398
    {
398
        vector<string> keyAndValue = explode(":", parts[n]);
399
        vector<string> keyAndValue = explode(":", parts[n]);
399
 
400
 
400
        //string key = trim(keyAndValue[0], ' ');
401
        //string key = trim(keyAndValue[0], ' ');
401
        //string value = trim(keyAndValue[1], ' ');
402
        //string value = trim(keyAndValue[1], ' ');
402
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
403
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
403
    }
404
    }
404
 
405
 
405
    canMessage.setData(data);
406
    canMessage.setData(data);
406
   
407
   
407
    canMan.sendMessage(canMessage);
408
    canMan.sendMessage(canMessage);
408
 
409
 
409
    return Undefined();
410
    return Undefined();
410
}
411
}
411
 
412
 
412
Handle<Value> VirtualMachine_loadScript(const Arguments& args)
413
Handle<Value> VirtualMachine_loadScript(const Arguments& args)
413
{
414
{
414
    VirtualMachine &vm = VirtualMachine::getInstance();
415
    VirtualMachine &vm = VirtualMachine::getInstance();
415
 
416
 
416
    String::AsciiValue str(args[0]);
417
    String::AsciiValue str(args[0]);
417
 
418
 
418
    return Boolean::New(vm.loadScript(*str));
419
    return Boolean::New(vm.loadScript(*str));
419
}
420
}
420
 
421
 
421
Handle<Value> VirtualMachine_startIntervalThread(const Arguments& args)
422
Handle<Value> VirtualMachine_startIntervalThread(const Arguments& args)
422
{
423
{
423
    VirtualMachine &vm = VirtualMachine::getInstance();
424
    VirtualMachine &vm = VirtualMachine::getInstance();
424
 
425
 
425
    unsigned int timeout = args[0]->Uint32Value();
426
    unsigned int timeout = args[0]->Uint32Value();
426
 
427
 
427
    return Integer::New(vm.startIntervalThread(timeout));
428
    return Integer::New(vm.startIntervalThread(timeout));
428
}
429
}
429
 
430
 
430
Handle<Value> VirtualMachine_stopIntervalThread(const Arguments& args)
431
Handle<Value> VirtualMachine_stopIntervalThread(const Arguments& args)
431
{
432
{
432
    VirtualMachine &vm = VirtualMachine::getInstance();
433
    VirtualMachine &vm = VirtualMachine::getInstance();
433
 
434
 
434
    unsigned int id = args[0]->Uint32Value();
435
    unsigned int id = args[0]->Uint32Value();
435
 
436
 
436
    return Boolean::New(vm.stopIntervalThread(id));
437
    return Boolean::New(vm.stopIntervalThread(id));
437
}
438
}
438
 
439
 
439
Handle<Value> VirtualMachine_startSocketThread(const Arguments& args)
440
Handle<Value> VirtualMachine_startSocketThread(const Arguments& args)
440
{
441
{
441
    VirtualMachine &vm = VirtualMachine::getInstance();
442
    VirtualMachine &vm = VirtualMachine::getInstance();
442
 
443
 
443
    String::AsciiValue address(args[0]);
444
    String::AsciiValue address(args[0]);
444
    int port = args[1]->Uint32Value();
445
    int port = args[1]->Uint32Value();
445
    unsigned int reconnectTimeout = args[2]->Uint32Value();
446
    unsigned int reconnectTimeout = args[2]->Uint32Value();
446
 
447
 
447
    return Integer::New(vm.startSocketThread(*address, port, reconnectTimeout));
448
    return Integer::New(vm.startSocketThread(*address, port, reconnectTimeout));
448
}
449
}
449
 
450
 
450
Handle<Value> VirtualMachine_stopSocketThread(const Arguments& args)
451
Handle<Value> VirtualMachine_stopSocketThread(const Arguments& args)
451
{
452
{
452
    VirtualMachine &vm = VirtualMachine::getInstance();
453
    VirtualMachine &vm = VirtualMachine::getInstance();
453
 
454
 
454
    unsigned int id = args[0]->Uint32Value();
455
    unsigned int id = args[0]->Uint32Value();
455
 
456
 
456
    return Boolean::New(vm.stopSocketThread(id));
457
    return Boolean::New(vm.stopSocketThread(id));
457
}
458
}
458
 
459
 
459
Handle<Value> VirtualMachine_sendToSocketThread(const Arguments& args)
460
Handle<Value> VirtualMachine_sendToSocketThread(const Arguments& args)
-
 
461
{
-
 
462
    VirtualMachine &vm = VirtualMachine::getInstance();
-
 
463
 
-
 
464
    unsigned int id = args[0]->Uint32Value();
-
 
465
    String::AsciiValue data(args[1]);
-
 
466
 
-
 
467
    vm.sendToSocketThread(id, *data);
-
 
468
 
-
 
469
    return Undefined();
-
 
470
}
-
 
471
 
-
 
472
Handle<Value> VirtualMachine_uint2hex(const Arguments& args)
460
{
473
{
461
    VirtualMachine &vm = VirtualMachine::getInstance();
474
    VirtualMachine &vm = VirtualMachine::getInstance();
462
 
475
 
463
    unsigned int id = args[0]->Uint32Value();
476
    unsigned int id = args[0]->Uint32Value();
464
    String::AsciiValue data(args[1]);
477
    unsigned int length = args[1]->Uint32Value();
465
 
-
 
466
    vm.sendToSocketThread(id, *data);
478
    string hexId = uint2hex(id, length);
467
 
479
 
468
    return Undefined();
480
    return String::New(hexId.c_str());
469
}
481
}
470
 
482
 
471
 
483