[bluemonkey] declare qtimer script meta type
[profile/ivi/automotive-message-broker.git] / plugins / bluemonkey / bluemonkey.cpp
1 /*
2     Copyright (C) 2012  Intel Corporation
3
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Lesser General Public
6     License as published by the Free Software Foundation; either
7     version 2.1 of the License, or (at your option) any later version.
8
9     This library is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12     Lesser General Public License for more details.
13
14     You should have received a copy of the GNU Lesser General Public
15     License along with this library; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19
20 #include "bluemonkey.h"
21 #include "abstractroutingengine.h"
22 #include "debugout.h"
23 #include "irccoms.h"
24
25 #include <QJsonDocument>
26 #include <QScriptEngine>
27 #include <QString>
28 #include <QFile>
29 #include <QTimer>
30
31 Q_SCRIPT_DECLARE_QMETAOBJECT(QTimer, QObject*)
32
33 extern "C" AbstractSinkManager * create(AbstractRoutingEngine* routingengine, map<string, string> config)
34 {
35         return new BluemonkeySinkManager(routingengine, config);
36 }
37
38 QVariant gvariantToQVariant(GVariant *value)
39 {
40         GVariantClass c = g_variant_classify(value);
41         if(c == G_VARIANT_CLASS_BOOLEAN)
42                 return QVariant((bool) g_variant_get_boolean(value));
43
44         else if(c == G_VARIANT_CLASS_BYTE)
45                 return QVariant((char) g_variant_get_byte(value));
46
47         else if(c == G_VARIANT_CLASS_INT16)
48                 return QVariant((int) g_variant_get_int16(value));
49
50         else if(c == G_VARIANT_CLASS_UINT16)
51                 return QVariant((unsigned int) g_variant_get_uint16(value));
52
53         else if(c == G_VARIANT_CLASS_INT32)
54                 return QVariant((int) g_variant_get_int32(value));
55
56         else if(c ==  G_VARIANT_CLASS_UINT32)
57                 return QVariant((unsigned int) g_variant_get_uint32(value));
58
59         else if(c == G_VARIANT_CLASS_INT64)
60                 return QVariant((long long) g_variant_get_int64(value));
61
62         else if(c == G_VARIANT_CLASS_UINT64)
63                 return QVariant((unsigned long long) g_variant_get_uint64(value));
64
65         else if(c == G_VARIANT_CLASS_DOUBLE)
66                 return QVariant(g_variant_get_double(value));
67
68         else if(c == G_VARIANT_CLASS_STRING)
69                 return QVariant(g_variant_get_string(value, NULL));
70
71         else if(c == G_VARIANT_CLASS_ARRAY)
72         {
73                 gsize dictsize = g_variant_n_children(value);
74                 QVariantList list;
75                 for (int i=0;i<dictsize;i++)
76                 {
77                         GVariant *childvariant = g_variant_get_child_value(value,i);
78                         GVariant *innervariant = g_variant_get_variant(childvariant);
79                         list.append(gvariantToQVariant(innervariant));
80                 }
81                 return list;
82         }
83
84         else
85                 return QVariant::Invalid;
86
87 }
88
89 BluemonkeySink::BluemonkeySink(AbstractRoutingEngine* e, map<string, string> config): QObject(0), AbstractSink(e, config), engine(nullptr)
90 {
91         irc = new IrcCommunication(config, this);
92
93         reloadEngine();
94
95         auth = new Authenticate(config, this);
96
97         connect(irc, &IrcCommunication::message, [&](QString sender, QString prefix, QString codes ) {
98
99                 if(codes.contains("authenticate"))
100                 {
101
102                         int i = codes.indexOf("authenticate");
103                         QString pin = codes.mid(i+13);
104                         pin = pin.trimmed();
105
106
107                         if(!auth->authorize(prefix, pin))
108                                 irc->respond(sender,"failed");
109                         qDebug()<<sender;
110
111                 }
112                 else if(codes.startsWith("bluemonkey"))
113                 {
114                         if(!auth->isAuthorized(prefix))
115                         {
116                                 irc->respond(sender, "denied");
117                                 return;
118                         }
119
120                         QString bm("bluemonkey");
121
122                         codes = codes.mid(bm.length()+1);
123
124                         irc->respond(sender, engine->evaluate(codes).toString());
125                 }
126         });
127
128
129
130 }
131
132
133 PropertyList BluemonkeySink::subscriptions()
134 {
135
136 }
137
138 void BluemonkeySink::supportedChanged(PropertyList supportedProperties)
139 {
140
141 }
142
143 void BluemonkeySink::propertyChanged(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
144 {
145
146 }
147
148 std::string BluemonkeySink::uuid()
149 {
150         return "bluemonkey";
151 }
152
153 QObject *BluemonkeySink::subscribeTo(QString str)
154 {
155         return new Property(str.toStdString(), routingEngine, this);
156 }
157
158 bool BluemonkeySink::authenticate(QString pass)
159 {
160
161 }
162
163 void BluemonkeySink::loadConfig(QString str)
164 {
165         configsToLoad.append(str);
166         QTimer::singleShot(1,this,SLOT(loadConfigPriv()));
167 }
168
169 void BluemonkeySink::loadConfigPriv()
170 {
171         if(!configsToLoad.count()) return;
172
173         QString str = configsToLoad.first();
174         configsToLoad.pop_front();
175
176         QFile file(str);
177         if(!file.open(QIODevice::ReadOnly))
178         {
179                 qDebug()<<"failed to open config file: "<<str;
180                 return;
181         }
182
183         QString script = file.readAll();
184
185         file.close();
186
187         QScriptValue val = engine->evaluate(script);
188
189         qDebug()<<val.toString();
190 }
191
192 void BluemonkeySink::reloadEngine()
193 {
194         if(engine)
195                 engine->deleteLater();
196
197         engine = new QScriptEngine(this);
198
199         QScriptValue value = engine->newQObject(this);
200         engine->globalObject().setProperty("bluemonkey", value);
201
202         QScriptValue qtimerClass = engine->scriptValueFromQMetaObject<QTimer>();
203         engine->globalObject().setProperty("QTimer", qtimerClass);
204
205
206
207         loadConfig(configuration["config"].c_str());
208 }
209
210 void BluemonkeySink::writeProgram(QString program)
211 {
212         QFile file(configuration["customPrograms"].c_str());
213
214         file.open(QIODevice::ReadWrite | QIODevice::Append);
215
216         file.write(program.toUtf8());
217         file.write("\n");
218
219         file.close();
220 }
221
222
223 QVariant Property::value()
224 {
225         return gvariantToQVariant(mValue->toVariant());
226 }
227
228 void Property::setValue(QVariant v)
229 {
230         if(v.type() == QVariant::List || v.type() == QVariant::Map)
231         {
232
233                 QJsonDocument doc = QJsonDocument::fromVariant(v);
234
235                 QString json = doc.toJson();
236
237                 mValue->fromString(json.toStdString());
238         }
239
240
241
242         else
243         {
244                 QString tempVal = v.toString();
245                 mValue->fromString(tempVal.toStdString());
246         }
247
248         AsyncSetPropertyRequest request;
249         request.property = mValue->name;
250         request.value = mValue;
251         request.completed = [&](AsyncPropertyReply* reply)
252         {
253                 if(reply->success)
254                 {
255                         propertyChanged(reply->property,reply->value,reply->value->sourceUuid);
256                 }
257                 delete reply;
258         };
259         routingEngine->setProperty(request);
260 }
261
262 Property::Property(VehicleProperty::Property prop, AbstractRoutingEngine* re, QObject *parent)
263         :QObject(parent), AbstractSink(re, std::map<std::string,std::string>()),mValue(nullptr)
264 {
265         setType(prop.c_str());
266 }
267
268 QString Property::type()
269 {
270         return mValue->name.c_str();
271 }
272
273 void Property::setType(QString t)
274 {
275         if(mValue && type() != "")
276                 routingEngine->unsubscribeToProperty(type().toStdString(),this);
277
278         routingEngine->subscribeToProperty(t.toStdString(),this);
279
280         mValue = VehicleProperty::getPropertyTypeForPropertyNameValue(t.toStdString());
281
282         AsyncPropertyRequest request;
283         request.property = mValue->name;
284         request.completed = [this](AsyncPropertyReply* reply)
285         {
286                 propertyChanged(reply->property, reply->value,uuid());
287                 delete reply;
288         };
289
290         routingEngine->getPropertyAsync(request);
291 }
292
293 void Property::propertyChanged(VehicleProperty::Property property, AbstractPropertyType *value, string uuid)
294 {
295         mValue = value->copy();
296
297         changed(gvariantToQVariant(mValue->toVariant()));
298 }