Esempio n. 1
0
void ObjectEndPoint::newPackageReady()
{
    //client and service side
#ifdef QT_SFW_ENDPOINT_DEBUG
    qDebug() << "ObjectEndPoint::newPackageReady: Start ..." ;
#endif 
    
    // The monitor keeps track of this ObjectEndPoint so that it doesn't get deleted while in progress.    
#ifdef Q_OS_SYMBIAN
    ObjectEndPointMonitor aOem(this);
#endif //End Q_OS_SYMBIAN
    while(dispatch->packageAvailable())
    {
        QServicePackage p = dispatch->nextPackage();
        if (!p.isValid())
            continue;

        switch(p.d->packageType) {
            case QServicePackage::ObjectCreation:
                objectRequest(p);
                break;
            case QServicePackage::MethodCall:
                methodCall(p);
                break;
            case QServicePackage::PropertyCall:
                propertyCall(p);
                break;
            default:
                qWarning() << "Unknown package type received.";
        }
    }
#ifdef QT_SFW_ENDPOINT_DEBUG
	qDebug() << "ObjectEndPoint::newPackageReady: End" ;
#endif 
}
/*!
    Received a new package from the DBus client-server controller.
    Once an object request is handled there is only direct communication to the DBus object so
    no other package types should be received on this layer.
*/
void ObjectEndPoint::newPackageReady()
{
    // Client and service side
    while(dispatch->packageAvailable())
    {
        QServicePackage p = dispatch->nextPackage();
        if (!p.isValid())
            continue;

        if (p.d->packageType == QServicePackage::ObjectCreation) {
            objectRequest(p);
        } else {
            qWarning() << "Unknown package type received.";
        }
    }
}
Esempio n. 3
0
/*!
    Received a new package from the DBus client-server controller.
    Once an object request is handled there is only direct communication to the DBus object so
    no other package types should be received on this layer.
*/
void ObjectEndPoint::newPackageReady()
{
    // Client and service side
    while (dispatch->packageAvailable())
    {
        // must call get getSecurityCredentials everytime you call nextPackage
        QServiceClientCredentials creds;
        dispatch->getSecurityCredentials(creds);
        QServicePackage p = dispatch->nextPackage();
        if (!p.isValid())
            continue;

        if (p.d->packageType == QServicePackage::ObjectCreation) {
            objectRequest(p, creds);
        } else {
            qWarning() << "Unknown package type received.";
        }
    }
}
Esempio n. 4
0
void ObjectEndPoint::propertyCall(const QServicePackage& p)
{
    if(p.d->responseType == QServicePackage::NotAResponse) {
        //service side
        Q_ASSERT(d->endPointType == ObjectEndPoint::Service);

        QByteArray data = p.d->payload.toByteArray();
        QDataStream stream(&data, QIODevice::ReadOnly);
        int metaIndex = -1;
        QVariant arg;
        int callType;
        stream >> metaIndex;
        stream >> arg;
        stream >> callType;
        const QMetaObject::Call c = (QMetaObject::Call) callType;

        QVariant result;
        QMetaProperty property = service->metaObject()->property(metaIndex);
        if (property.isValid()) {
            switch(c) {
                case QMetaObject::ReadProperty:
                    result = property.read(service);
                    break;
                case QMetaObject::WriteProperty:
                    property.write(service, arg);
                    break;
                case QMetaObject::ResetProperty:
                    property.reset(service);
                    break;
                default:
                    break;

            }
        } 

        if (c == QMetaObject::ReadProperty) {
            QServicePackage response = p.createResponse();
            if (property.isValid()) {
                response.d->responseType = QServicePackage::Success;
                response.d->payload = result;
            } else {
                response.d->responseType = QServicePackage::Failed;
            }
            dispatch->writePackage(response);
        }
    } else {
Esempio n. 5
0
/*!
    Service finds existing objects or spawns new object instances and registers them on DBus using a
    hash of the unique instance ID. This registered object has a special metaobject representation
    of the service that is compatible with the QDBus type system.

    Client receives a package containing the information to connect an interface to the registered
    DBus object.
*/
void ObjectEndPoint::objectRequest(const QServicePackage& p, QServiceClientCredentials& creds)
{
    if (p.d->responseType != QServicePackage::NotAResponse ) {
        // Client side
        Q_ASSERT(d->endPointType == ObjectEndPoint::Client);

        d->serviceInstanceId = p.d->instanceId;
        d->entry = p.d->entry;

        Response* response = openRequests()->value(p.d->messageId);
        if (p.d->responseType == QServicePackage::Failed) {
            response->result = 0;
            response->isFinished = true;
            QTimer::singleShot(0, this, SIGNAL(pendingRequestFinished()));
            qWarning() << "Service instantiation failed";
            return;
        }

        // Deserialize meta object and create proxy object
        QServiceProxy* proxy = new QServiceProxy(p.d->payload.toByteArray(), this);
        response->result = reinterpret_cast<void *>(proxy);
        response->isFinished = true;

        // Create DBUS interface by using a hash of the service instance ID
        QString serviceName = QStringLiteral("com.nokia.qtmobility.sfw.") + p.d->entry.serviceName();
        uint hash = qHash(d->serviceInstanceId.toString());
        QString objPath = QLatin1Char('/') + p.d->entry.interfaceName() + QLatin1Char('/') + p.d->entry.version() + QLatin1Char('/') + QString::number(hash);
        objPath.replace(QLatin1Char('.'), QLatin1Char('/'));

#ifdef DEBUG
        qDebug() << "Client Interface ObjectPath:" << objPath;
#endif
        // Instantiate our DBus interface and its corresponding signals object
        if (!iface)
            iface = new QDBusInterface(serviceName, objPath, QString(), QDBusConnection::sessionBus(), this);
        signalsObject = new QServiceMetaObjectDBus(iface, true);

        // Wake up waiting proxy construction code
        QTimer::singleShot(0, this, SIGNAL(pendingRequestFinished()));

    } else {
        // Service side
        Q_ASSERT(d->endPointType == ObjectEndPoint::Service);

        QServicePackage response = p.createResponse();
        InstanceManager* iManager = InstanceManager::instance();

        if (!creds.isValid()) {
            qWarning() << "SFW Unable to get socket credentials client asking for" << p.d->entry.interfaceName() << p.d->entry.serviceName() << "this may fail in the future";
        }

        // Instantiate service object from type register
        service = iManager->createObjectInstance(p.d->entry, d->serviceInstanceId, creds);
        if (!service) {
            qWarning() << "Cannot instantiate service object";
            dispatch->writePackage(response);
            return;
        }

        if (!creds.isClientAccepted()) {
            qWarning() << "SFW Security failure by" <<
                          creds.getProcessIdentifier() <<
                          creds.getUserIdentifier() <<
                          creds.getGroupIdentifier() <<
                          "requesting" << p.d->entry.interfaceName() << p.d->entry.serviceName();
            iManager->removeObjectInstance(p.d->entry, d->serviceInstanceId);
            dispatch->writePackage(response);
            return;
        }

        // Start DBus connection and register proxy service
        if (!QDBusConnection::sessionBus().isConnected()) {
            qWarning() << "Cannot connect to DBus";
        }

        // DBus registration path uses a hash of the service instance ID
        QString serviceName = QStringLiteral("com.nokia.qtmobility.sfw.") + p.d->entry.serviceName();
        uint hash = qHash(d->serviceInstanceId.toString());
        QString objPath = QLatin1Char('/') + p.d->entry.interfaceName() + QLatin1Char('/') + p.d->entry.version() + QLatin1Char('/') + QString::number(hash);
        objPath.replace(QLatin1Char('.'), QLatin1Char('/'));

        QServiceMetaObjectDBus *serviceDBus = new QServiceMetaObjectDBus(service);
        QDBusConnection::sessionBus().registerObject(objPath, serviceDBus, QDBusConnection::ExportAllContents);

        QString clientId = p.d->payload.toString();

        int exists = 0;
        for (int i=d->clientList.size()-1; i>=0; i--) {
            // Find right client process
            if (d->clientList[i].clientId == clientId) {
                d->clientList[i].ref++;
                exists = 1;
                break;
            }
        }

        if (!exists) {
            // Add new instance to client ownership list
            ClientInstance c;
            c.clientId = clientId;
            c.entry = p.d->entry;
            c.instanceId = d->serviceInstanceId;
            c.ref = 1;
            d->clientList << c;
        }



#ifdef DEBUG
        qDebug() << "Service Interface ObjectPath:" << objPath;

        const QMetaObject *s_meta = service->metaObject();
        qDebug() << "+++++++++++++++++++++SERVICE+++++++++++++++++++++++";
        qDebug() << s_meta->className();
        qDebug() << "METHOD COUNT: " << s_meta->methodCount();
        for (int i=0; i<s_meta->methodCount(); i++) {
            QMetaMethod mm = s_meta->method(i);

            QString type;
            switch (mm.methodType()) {
                case QMetaMethod::Method:
                    type = "Q_INVOKABLE";
                    break;
                case QMetaMethod::Signal:
                    type = "SIGNAL";
                    break;
                case QMetaMethod::Slot:
                    type = "SLOT";
                    break;
                default:
                    break;
            }

            QString returnType = mm.typeName();
            if (returnType == "") returnType = "void";

            qDebug() << "METHOD" << type << ":" << returnType << mm.methodSignature();
        }
        qDebug() << "++++++++++++++++++++++++++++++++++++++++++++++++++++";
        if (!iface)
            iface = new QDBusInterface(serviceName, objPath, "", QDBusConnection::sessionBus(), this);
        const QMetaObject *i_meta = iface->metaObject();
        qDebug() << "++++++++++++++++++++DBUS SERVICE++++++++++++++++++++";
        qDebug() << i_meta->className();
        qDebug() << "METHOD COUNT: " << i_meta->methodCount();
        for (int i=0; i<i_meta->methodCount(); i++) {
            QMetaMethod mm = i_meta->method(i);

            QString type;
            switch (mm.methodType()) {
                case QMetaMethod::Method:
                    type = "Q_INVOKABLE";
                    break;
                case QMetaMethod::Signal:
                    type = "SIGNAL";
                    break;
                case QMetaMethod::Slot:
                    type = "SLOT";
                    break;
                default:
                    break;
            }

            QString returnType = mm.typeName();
            if (returnType == "") returnType = "void";

            qDebug() << "METHOD" << type << ":" << returnType << mm.methodSignature();
        }
        qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++";
#endif

        // Get meta object from type register
        const QMetaObject* meta = iManager->metaObject(p.d->entry);
        if (!meta) {
            qDebug() << "Unknown type" << p.d->entry;
            dispatch->writePackage(response);
            return;
        }

        // Serialize meta object
        QByteArray data;
        QDataStream stream( &data, QIODevice::WriteOnly | QIODevice::Append );
        QMetaObjectBuilder builder(meta);
        builder.serialize(stream);

        // Send meta object and instance ID to the client for processing
        d->entry = p.d->entry;
        response.d->instanceId = d->serviceInstanceId;
        response.d->entry = p.d->entry;
        response.d->responseType = QServicePackage::Success;
        response.d->payload = QVariant(data);
        dispatch->writePackage(response);
    }
}