2 Copyright (C) 2012 Intel Corporation
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.
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.
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
20 #include "bluemonkey.h"
21 #include "abstractroutingengine.h"
25 #include <QJsonDocument>
26 #include <QScriptEngine>
31 extern "C" AbstractSinkManager * create(AbstractRoutingEngine* routingengine, map<string, string> config)
33 return new BluemonkeySinkManager(routingengine, config);
36 QVariant gvariantToQVariant(GVariant *value)
38 switch (g_variant_classify(value)) {
39 case G_VARIANT_CLASS_BOOLEAN:
40 return QVariant((bool) g_variant_get_boolean(value));
42 case G_VARIANT_CLASS_BYTE:
43 return QVariant((char) g_variant_get_byte(value));
45 case G_VARIANT_CLASS_INT16:
46 return QVariant((int) g_variant_get_int16(value));
48 case G_VARIANT_CLASS_UINT16:
49 return QVariant((unsigned int) g_variant_get_uint16(value));
51 case G_VARIANT_CLASS_INT32:
52 return QVariant((int) g_variant_get_int32(value));
54 case G_VARIANT_CLASS_UINT32:
55 return QVariant((unsigned int) g_variant_get_uint32(value));
57 case G_VARIANT_CLASS_INT64:
58 return QVariant((long long) g_variant_get_int64(value));
60 case G_VARIANT_CLASS_UINT64:
61 return QVariant((unsigned long long) g_variant_get_uint64(value));
63 case G_VARIANT_CLASS_DOUBLE:
64 return QVariant(g_variant_get_double(value));
66 case G_VARIANT_CLASS_STRING:
67 return QVariant(g_variant_get_string(value, NULL));
70 return QVariant::Invalid;
74 BluemonkeySink::BluemonkeySink(AbstractRoutingEngine* e, map<string, string> config): QObject(0), AbstractSink(e, config), engine(nullptr)
76 irc = new IrcCommunication(config, this);
80 auth = new Authenticate(config, this);
82 connect(irc, &IrcCommunication::message, [&](QString sender, QString prefix, QString codes ) {
84 if(codes.contains("authenticate"))
87 int i = codes.indexOf("authenticate");
88 QString pin = codes.mid(i+13);
92 if(!auth->authorize(prefix, pin))
93 irc->respond(sender,"failed");
97 else if(codes.startsWith("bluemonkey"))
99 if(!auth->isAuthorized(prefix))
101 irc->respond(sender, "denied");
105 QString bm("bluemonkey");
107 codes = codes.mid(bm.length()+1);
109 irc->respond(sender, engine->evaluate(codes).toString());
118 PropertyList BluemonkeySink::subscriptions()
123 void BluemonkeySink::supportedChanged(PropertyList supportedProperties)
128 void BluemonkeySink::propertyChanged(VehicleProperty::Property property, AbstractPropertyType* value, std::string uuid)
133 std::string BluemonkeySink::uuid()
138 QObject *BluemonkeySink::subscribeTo(QString str)
140 return new Property(str.toStdString(), routingEngine, this);
143 bool BluemonkeySink::authenticate(QString pass)
148 void BluemonkeySink::loadConfig(QString str)
150 configsToLoad.append(str);
151 QTimer::singleShot(1,this,SLOT(loadConfigPriv()));
154 void BluemonkeySink::loadConfigPriv()
156 if(!configsToLoad.count()) return;
158 QString str = configsToLoad.first();
159 configsToLoad.pop_front();
162 if(!file.open(QIODevice::ReadOnly))
164 qDebug()<<"failed to open config file: "<<str;
168 QString script = file.readAll();
172 QScriptValue val = engine->evaluate(script);
174 qDebug()<<val.toString();
177 void BluemonkeySink::reloadEngine()
180 engine->deleteLater();
182 engine = new QScriptEngine(this);
184 QScriptValue value = engine->newQObject(this);
185 engine->globalObject().setProperty("bluemonkey", value);
189 loadConfig(configuration["config"].c_str());
192 void BluemonkeySink::writeProgram(QString program)
194 QFile file(configuration["customPrograms"].c_str());
196 file.open(QIODevice::ReadWrite | QIODevice::Append);
198 file.write(program.toUtf8());
205 QVariant Property::value()
207 return gvariantToQVariant(mValue->toVariant());
210 void Property::setValue(QVariant v)
212 if(v.type() == QVariant::List || v.type() == QVariant::Map)
215 QJsonDocument doc = QJsonDocument::fromVariant(v);
217 QString json = doc.toJson();
219 mValue->fromString(json.toStdString());
223 mValue->fromString(v.toString().toStdString());
225 AsyncSetPropertyRequest request;
226 request.property = mValue->name;
227 request.value = mValue;
228 request.completed = [](AsyncPropertyReply* reply) { delete reply; };
229 routingEngine->setProperty(request);
232 Property::Property(VehicleProperty::Property prop, AbstractRoutingEngine* re, QObject *parent)
233 :QObject(parent), AbstractSink(re, std::map<std::string,std::string>()),mValue(nullptr)
235 setType(prop.c_str());
238 QString Property::type()
240 return mValue->name.c_str();
243 void Property::setType(QString t)
245 if(mValue && type() != "")
246 routingEngine->unsubscribeToProperty(type().toStdString(),this);
248 routingEngine->subscribeToProperty(t.toStdString(),this);
250 mValue = VehicleProperty::getPropertyTypeForPropertyNameValue(t.toStdString());
252 AsyncPropertyRequest request;
253 request.property = mValue->name;
254 request.completed = [this](AsyncPropertyReply* reply)
256 propertyChanged(reply->property, reply->value,uuid());
260 routingEngine->getPropertyAsync(request);
263 void Property::propertyChanged(VehicleProperty::Property property, AbstractPropertyType *value, string uuid)
265 mValue = value->copy();
267 changed(gvariantToQVariant(mValue->toVariant()));