# shbase.cpp

Go to the documentation of this file.

    00001 /*
    00002  * SmartHome server: Base of the system
    00003  *
    00004  * Copyright (C) 2010 Daniel Pisi <dan.pisi@gmail.com>
    00005  *
    00006  * This program is free software; you can redistribute it and/or modify it
    00007  * under the terms of version 2 of the GNU General Public License
    00008  * as published by the Free Software Foundation.
    00009  *
    00010  */
    00011
    00018 #include <QtSql>
    00019 #include "shbase.h"
    00020
    00021 // -----------------------------------------------------------------------------
    00022
    00027 ShBase::ShBase(QObject *parent) : QObject(parent)
    00028 {
    00029     reload();
    00030 }
    00031 // -----------------------------------------------------------------------------
    00032
    00036 void ShBase::reload()
    00037 {
    00038     int id;
    00039     QPluginLoader pluginLoader;
    00040     QString path;
    00041     QObject *plugin;
    00042     ShObject *shObject;
    00043
    00044     qDebug("Updating system structure");
    00045
    00046     QDir pluginsDir(qApp->applicationDirPath());
    00047     pluginsDir.cd("plugins");
    00048
    00049     QSqlQuery query;
    00050     query.exec("SELECT id,class,params FROM smarthome_objects");
    00051
    00052     QList<int> oldIds = mObjects.keys();
    00053     QList<int> newItems;
    00054
    00055     // Find out differences between old and new objects
    00056     while (query.next())
    00057     {
    00058         if (!oldIds.removeOne(query.value(0).toInt()))
    00059             newItems.append(query.at());
    00060     }
    00061
    00062     // Delete no longer needed objects
    00063     foreach (int id, oldIds)
    00064     {
    00065         delete mObjects[id];
    00066         mObjects.remove(id);
    00067     }
    00068
    00069     // Load and initialize new objects
    00070     foreach (int idx, newItems)
    00071     {
    00072         query.seek(idx);
    00073         path = pluginsDir.absoluteFilePath(QString("lib%1.so").arg(query.value(1).toString()));
    00074
    00075         pluginLoader.setFileName(path);
    00076         plugin = pluginLoader.instance();
    00077
    00078         shObject = NULL;
    00079         if (plugin)
    00080         {
    00081             shObject = qobject_cast<ShObject*>(plugin);
    00082             if (shObject)
    00083             {
    00084                 qDebug(QString("Plugin %1 loaded").arg(query.value(1).toString()).toLatin1());
    00085
    00086                 id = query.value(0).toInt();
    00087                 mObjects[id] = shObject;
    00088
    00089                 connect(plugin, SIGNAL(newMessage(ShMessagePtr)), this, SLOT(routeMessage(ShMessagePtr)));
    00090
    00091                 shObject->setObjectId(id);
    00092                 shObject->init(query.value(2).toString());
    00093             }
    00094             else
    00095                 delete plugin;
    00096         }
    00097         if (!shObject)
    00098             qDebug(QString("Failed to load plugin %1: %2").arg(query.value(1).toString(), pluginLoader.errorString()).toLatin1());
    00099     }
    00100
    00101     // Update all pins
    00102     QMapIterator<int,ShObject*> objectsI(mObjects);
    00103     while (objectsI.hasNext())
    00104     {
    00105         objectsI.next();
    00106         objectsI.value()->updatePins(queryPins(objectsI.key()));
    00107     }
    00108 }
    00109 // -----------------------------------------------------------------------------
    00110
    00117 int ShBase::queryPinId(int object, QString signal)
    00118 {
    00119     QSqlQuery query;
    00120
    00121     query.prepare("SELECT id FROM smarthome_pins WHERE object=? AND signal=?");
    00122     query.addBindValue(object);
    00123     query.addBindValue(signal);
    00124     query.exec();
    00125
    00126     return query.next() ? query.value(0).toInt() : 0;
    00127 }
    00128 // -----------------------------------------------------------------------------
    00129
    00135 QList<ShPin> ShBase::queryPins(int objectId)
    00136 {
    00137     QList<ShPin> ret;
    00138     QSqlQuery query;
    00139
    00140     query.prepare("SELECT signal,direction,type FROM smarthome_pins WHERE object=?");
    00141     query.addBindValue(objectId);
    00142     query.exec();
    00143
    00144     ShPin pin;
    00145     pin.setObjectId(objectId);
    00146
    00147     while (query.next())
    00148     {
    00149         pin.setSignal(query.value(0).toString());
    00150         pin.setDirection(query.value(1).toString());
    00151         pin.setType(query.value(2).toString());
    00152         ret.append(pin);
    00153     }
    00154
    00155     return ret;
    00156 }
    00157 // -----------------------------------------------------------------------------
    00158
    00165 bool ShBase::pinBelongsTo(int pin, int object)
    00166 {
    00167     QSqlQuery query;
    00168
    00169     query.prepare("SELECT * FROM smarthome_pins WHERE id=? AND object=?");
    00170     query.addBindValue(pin);
    00171     query.addBindValue(object);
    00172     query.exec();
    00173
    00174     return query.next();
    00175 }
    00176 // -----------------------------------------------------------------------------
    00177
    00183 ShPin ShBase::queryPin(int pinId)
    00184 {
    00185     ShPin pin;
    00186     QSqlQuery query;
    00187
    00188     query.prepare("SELECT object,signal,direction,type FROM smarthome_pins WHERE id=?");
    00189     query.addBindValue(pinId);
    00190     query.exec();
    00191
    00192     if (query.next())
    00193     {
    00194         pin.setObjectId(query.value(0).toInt());
    00195         pin.setSignal(query.value(1).toString());
    00196         pin.setDirection(query.value(2).toString());
    00197         pin.setType(query.value(3).toString());
    00198     }
    00199     return pin;
    00200 }
    00201 // -----------------------------------------------------------------------------
    00202
    00207 void ShBase::routeMessage(ShMessagePtr message)
    00208 {
    00209     QSqlQuery destinations;
    00210     int pin, id;
    00211
    00212     qDebug(QString("Routing message: sender = %1, signal = %2, value = %3, type = %4").arg(message->senderId()).arg(message->signal()).arg(message->value().toString()).arg(message->msgTypeStr()).toLatin1());
    00213
    00214     if (!mObjects.contains(message->senderId()))
    00215         return;
    00216
    00217     if (message->msgType() == ShMessage::mtReload)
    00218     {
    00219         reload();
    00220         return;
    00221     }
    00222
    00223     pin = (mObjects[message->senderId()]->idApi()) ? message->signal().toInt()
    00224                                                    : queryPinId(message->senderId(), message->signal());
    00225
    00226     if (pin <= 0 || !pinBelongsTo(pin, message->senderId()))
    00227         return;
    00228
    00229
    00230     QString sqlCmd;
    00231
    00232     if (( message->msgType() == ShMessage::mtValue) ||
    00233         ((message->msgType() == ShMessage::mtError) && (message->pin().isOutput())) )
    00234     {
    00235         sqlCmd = "SELECT destination FROM smarthome_links WHERE source=%1";
    00236     }
    00237     else if (( message->msgType() == ShMessage::mtGet) ||
    00238              ( message->msgType() == ShMessage::mtAck) ||
    00239              ((message->msgType() == ShMessage::mtError) && (message->pin().isInput())) )
    00240     {
    00241         sqlCmd = "SELECT source FROM smarthome_links WHERE destination=%1";
    00242     }
    00243
    00244     ShMessagePtr destMsg;
    00245
    00246     destinations.exec(sqlCmd.arg(pin));
    00247
    00248     if (!destinations.next())
    00249     {
    00250         qDebug("Destination not found, pin = %d", pin);
    00251     }
    00252
    00253     do
    00254     {
    00255         pin = destinations.value(0).toInt();
    00256
    00257         ShPin destPin = queryPin(pin);
    00258         id = destPin.objectId();
    00259
    00260         if (mObjects.contains(id))
    00261         {
    00262             destMsg = ShMessagePtr(new ShMessage);
    00263
    00264             destMsg->setSenderId(message->senderId());
    00265             destMsg->setMsgType(message->msgType());
    00266             destMsg->setPin(destPin);
    00267             destMsg->setSignal(mObjects[id]->idApi() ? QString::number(pin) : destPin.signal());
    00268             destMsg->setValue(message->value());
    00269
    00270             mObjects[id]->processMessage(destMsg);
    00271         }
    00272     } while (destinations.next());
    00273 }
    00274 // -----------------------------------------------------------------------------
    00275
    00276

All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends