Moved conection logic from Qcma/ListenerWorker to CmaServer/CmaClient.
Added tray icon. Quit now really quits the application.
This commit is contained in:
		@@ -1,74 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2013  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "listenerworker.h"
 | 
			
		||||
 | 
			
		||||
#include <locale.h>
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "capability.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QUrl>
 | 
			
		||||
#include <QMutexLocker>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
const metadata_t CmaClient::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{18, 144, 80, 0, 1, 1.0f, 2}}, NULL};
 | 
			
		||||
 | 
			
		||||
#define CALL_MEMBER_FUNC(obj,memberptr)  ((obj).*(memberptr))
 | 
			
		||||
 | 
			
		||||
const metadata_t ListenerWorker::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{18, 144, 80, 0, 1, 1.0f, 2}}, NULL};
 | 
			
		||||
 | 
			
		||||
ListenerWorker::ListenerWorker(QObject *parent) :
 | 
			
		||||
CmaClient::CmaClient(QObject *parent) :
 | 
			
		||||
    BaseWorker(parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CmaClient::CmaClient(Database *database, vita_device_t *device, QObject *parent) :
 | 
			
		||||
    BaseWorker(parent), db(database), device(device)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CmaClient::~CmaClient()
 | 
			
		||||
{
 | 
			
		||||
    if(device) {
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaClient::close()
 | 
			
		||||
{
 | 
			
		||||
    VitaMTP_SendHostStatus(device, VITA_HOST_STATUS_EndConnection);
 | 
			
		||||
    VitaMTP_Release_Device(device);
 | 
			
		||||
    device = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaClient::process()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Vita connected: id %s", VitaMTP_Get_Identification(device));
 | 
			
		||||
 | 
			
		||||
    DeviceCapability *vita_info = new DeviceCapability();
 | 
			
		||||
 | 
			
		||||
    if(!vita_info->exchangeInfo(device)) {
 | 
			
		||||
        qCritical("Error while exchanging info with the vita");
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Conection successful, inform the user
 | 
			
		||||
    emit deviceConnected(QString(tr("Connected to ")) + vita_info->getOnlineId());
 | 
			
		||||
    connected = true;
 | 
			
		||||
    enterEventLoop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ListenerWorker::rebuildDatabase()
 | 
			
		||||
{
 | 
			
		||||
    db.destroy();
 | 
			
		||||
    return db.create();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::setDevice(vita_device_t *device)
 | 
			
		||||
{
 | 
			
		||||
    this->device = device;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ListenerWorker::isConnected()
 | 
			
		||||
{
 | 
			
		||||
    return connected;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::disconnect()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Stopping event listener");
 | 
			
		||||
    connected = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::process()
 | 
			
		||||
void CmaClient::enterEventLoop()
 | 
			
		||||
{
 | 
			
		||||
    vita_event_t event;
 | 
			
		||||
 | 
			
		||||
    qDebug() << "From listener: "<< QThread::currentThreadId();
 | 
			
		||||
    qDebug() << "From listener:"<< QThread::currentThreadId();
 | 
			
		||||
 | 
			
		||||
    while(connected) {
 | 
			
		||||
        if(VitaMTP_Read_Event(device, &event) < 0) {
 | 
			
		||||
@@ -147,10 +137,11 @@ void ListenerWorker::process()
 | 
			
		||||
            vitaEventUnimplementated(&event, event.Param1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    qDebug() << "Finished event thread for:" << QThread::currentThreadId();
 | 
			
		||||
    emit finished();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
quint16 ListenerWorker::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
quint16 CmaClient::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
{
 | 
			
		||||
    union {
 | 
			
		||||
        unsigned char *fileData;
 | 
			
		||||
@@ -165,13 +156,12 @@ quint16 ListenerWorker::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
        return PTP_RC_VITA_Invalid_Data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    CMAObject *object =  db.pathToObject(remote_meta.name, parent->metadata.ohfi);
 | 
			
		||||
    CMAObject *object =  db->pathToObject(remote_meta.name, parent->metadata.ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object) {
 | 
			
		||||
        qDebug("Deleting %s", object->path.toStdString().c_str());
 | 
			
		||||
        removeRecursively(object->path);
 | 
			
		||||
        db.remove(object);
 | 
			
		||||
        db->remove(object);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QDir dir(parent->path);
 | 
			
		||||
@@ -200,7 +190,7 @@ quint16 ListenerWorker::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
    object = new CMAObject(parent);
 | 
			
		||||
    object->initObject(info);
 | 
			
		||||
    object->metadata.handle = remote_meta.handle;
 | 
			
		||||
    db.append(parent->metadata.ohfi, object);
 | 
			
		||||
    db->append(parent->metadata.ohfi, object);
 | 
			
		||||
    free(remote_meta.name);
 | 
			
		||||
 | 
			
		||||
    qDebug("Added object %s with OHFI %i to database", object->metadata.path, object->metadata.ohfi);
 | 
			
		||||
@@ -211,7 +201,7 @@ quint16 ListenerWorker::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
 | 
			
		||||
            if(ret != PTP_RC_OK) {
 | 
			
		||||
                qDebug("Deleteting object with OHFI %d", object->metadata.ohfi);
 | 
			
		||||
                db.remove(object);
 | 
			
		||||
                db->remove(object);
 | 
			
		||||
                free(data.fileData);
 | 
			
		||||
                return ret;
 | 
			
		||||
            }
 | 
			
		||||
@@ -222,7 +212,7 @@ quint16 ListenerWorker::processAllObjects(CMAObject *parent, quint32 handle)
 | 
			
		||||
    return PTP_RC_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventGetTreatObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventGetTreatObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -233,9 +223,9 @@ void ListenerWorker::vitaEventGetTreatObject(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *parent = db.ohfiToObject(treatObject.ohfiParent);
 | 
			
		||||
    CMAObject *parent = db->ohfiToObject(treatObject.ohfiParent);
 | 
			
		||||
 | 
			
		||||
    if(parent == NULL) {
 | 
			
		||||
        qWarning("Cannot find parent OHFI %d", treatObject.ohfiParent);
 | 
			
		||||
@@ -246,7 +236,7 @@ void ListenerWorker::vitaEventGetTreatObject(vita_event_t *event, int eventId)
 | 
			
		||||
    VitaMTP_ReportResult(device, eventId, processAllObjects(parent, treatObject.handle));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -256,14 +246,14 @@ void ListenerWorker::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    quint64 size = 0;
 | 
			
		||||
 | 
			
		||||
    for(quint32 i = 0; i < info->count; i++) {
 | 
			
		||||
        CMAObject *object;
 | 
			
		||||
 | 
			
		||||
        if((object = db.ohfiToObject(info->ohfi[i])) == NULL) {
 | 
			
		||||
        if((object = db->ohfiToObject(info->ohfi[i])) == NULL) {
 | 
			
		||||
            qWarning("Cannot find OHFI %d", info->ohfi[i]);
 | 
			
		||||
            free(info);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -281,7 +271,7 @@ void ListenerWorker::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int
 | 
			
		||||
    free(info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -291,9 +281,9 @@ void ListenerWorker::vitaEventSendObjectMetadataItems(vita_event_t *event, int e
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(ohfi);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("Cannot find OHFI %d in database", ohfi);
 | 
			
		||||
@@ -312,33 +302,34 @@ void ListenerWorker::vitaEventSendObjectMetadataItems(vita_event_t *event, int e
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendNPAccountInfo(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendNPAccountInfo(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
    // AFAIK, Sony hasn't even implemented this in their CMA
 | 
			
		||||
    qWarning("Event 0x%x unimplemented!", event->Code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventRequestTerminate(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventRequestTerminate(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
    qWarning("Event 0x%x unimplemented!", event->Code);
 | 
			
		||||
    //qWarning("Event 0x%x unimplemented!", event->Code);
 | 
			
		||||
    connected = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventUnimplementated(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventUnimplementated(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qWarning("Unknown event not handled, code: 0x%x, id: %d", event->Code, eventId);
 | 
			
		||||
    qWarning("Param1: 0x%08X, Param2: 0x%08X, Param3: 0x%08X", event->Param1, event->Param2, event->Param3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendNumOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendNumOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    uint ohfi = event->Param2;
 | 
			
		||||
    int items = db.filterObjects(ohfi, NULL);
 | 
			
		||||
    int items = db->filterObjects(ohfi, NULL);
 | 
			
		||||
 | 
			
		||||
    if(VitaMTP_SendNumOfObject(device, eventId, items) != PTP_RC_OK) {
 | 
			
		||||
        qWarning("Error occured receiving object count for OHFI parent %d", ohfi);
 | 
			
		||||
@@ -348,7 +339,7 @@ void ListenerWorker::vitaEventSendNumOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -358,10 +349,10 @@ void ListenerWorker::vitaEventSendObjectMetadata(vita_event_t *event, int eventI
 | 
			
		||||
        qWarning("GetBrowseInfo failed");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    metadata_t *meta;
 | 
			
		||||
    int count = db.filterObjects(browse.ohfiParent, &meta);  // if meta is null, will return empty XML
 | 
			
		||||
    int count = db->filterObjects(browse.ohfiParent, &meta);  // if meta is null, will return empty XML
 | 
			
		||||
    qDebug("Sending %i metadata filtered objects for OHFI %id", count, browse.ohfiParent);
 | 
			
		||||
 | 
			
		||||
    if(VitaMTP_SendObjectMetadata(device, eventId, meta) != PTP_RC_OK) {  // send all objects with OHFI parent
 | 
			
		||||
@@ -371,16 +362,16 @@ void ListenerWorker::vitaEventSendObjectMetadata(vita_event_t *event, int eventI
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
    int ohfi = event->Param2;
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    Database::find_data iters;
 | 
			
		||||
    if(!db.find(ohfi, iters)) {
 | 
			
		||||
    if(!db->find(ohfi, iters)) {
 | 
			
		||||
        qWarning("Failed to find OHFI %d", ohfi);
 | 
			
		||||
        VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
 | 
			
		||||
        return;
 | 
			
		||||
@@ -435,7 +426,7 @@ void ListenerWorker::vitaEventSendObject(vita_event_t *event, int eventId)
 | 
			
		||||
    VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Data);  // TODO: Send thumbnail
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventCancelTask(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventCancelTask(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -444,7 +435,7 @@ void ListenerWorker::vitaEventCancelTask(vita_event_t *event, int eventId)
 | 
			
		||||
    qWarning("Event CancelTask (0x%x) unimplemented!", event->Code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendHttpObjectFromURL(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendHttpObjectFromURL(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -487,7 +478,7 @@ void ListenerWorker::vitaEventSendHttpObjectFromURL(vita_event_t *event, int eve
 | 
			
		||||
    free(url);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -498,9 +489,9 @@ void ListenerWorker::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *object = db.pathToObject(objectstatus.title, objectstatus.ohfiRoot);
 | 
			
		||||
    CMAObject *object = db->pathToObject(objectstatus.title, objectstatus.ohfiRoot);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) { // not in database, don't return metadata
 | 
			
		||||
        qDebug("Object %s not in database (OHFI: %i). Sending OK response for non-existence", objectstatus.title, objectstatus.ohfiRoot);
 | 
			
		||||
@@ -520,14 +511,14 @@ void ListenerWorker::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
 | 
			
		||||
    free(objectstatus.title);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendObjectThumb(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendObjectThumb(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    int ohfi = event->Param2;
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(ohfi);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("Cannot find OHFI %d in database.", ohfi);
 | 
			
		||||
@@ -579,14 +570,14 @@ void ListenerWorker::vitaEventSendObjectThumb(vita_event_t *event, int eventId)
 | 
			
		||||
    free(locale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventDeleteObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventDeleteObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    int ohfi = event->Param2;
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(ohfi);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("OHFI %d not found", ohfi);
 | 
			
		||||
@@ -596,12 +587,12 @@ void ListenerWorker::vitaEventDeleteObject(vita_event_t *event, int eventId)
 | 
			
		||||
 | 
			
		||||
    qDebug("Deleting %s, OHFI: %i", object->metadata.path, object->metadata.ohfi);
 | 
			
		||||
    removeRecursively(object->path);
 | 
			
		||||
    db.remove(object);
 | 
			
		||||
    db->remove(object);
 | 
			
		||||
 | 
			
		||||
    VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventGetSettingInfo(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventGetSettingInfo(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -613,7 +604,7 @@ void ListenerWorker::vitaEventGetSettingInfo(vita_event_t *event, int eventId)
 | 
			
		||||
 | 
			
		||||
    qDebug("Current account id: %s", settingsinfo->current_account.accountId);
 | 
			
		||||
 | 
			
		||||
    db.setUUID(settingsinfo->current_account.accountId);
 | 
			
		||||
    db->setUUID(settingsinfo->current_account.accountId);
 | 
			
		||||
 | 
			
		||||
    // set the database to be updated ASAP
 | 
			
		||||
    emit refreshDatabase();
 | 
			
		||||
@@ -623,7 +614,7 @@ void ListenerWorker::vitaEventGetSettingInfo(vita_event_t *event, int eventId)
 | 
			
		||||
    VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendHttpObjectPropFromURL(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendHttpObjectPropFromURL(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -659,7 +650,7 @@ void ListenerWorker::vitaEventSendHttpObjectPropFromURL(vita_event_t *event, int
 | 
			
		||||
    free(url);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -670,9 +661,9 @@ void ListenerWorker::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(part_init.ohfi);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(part_init.ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("Cannot find object for OHFI %d", part_init.ohfi);
 | 
			
		||||
@@ -699,7 +690,7 @@ void ListenerWorker::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -710,9 +701,9 @@ void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *root = db.ohfiToObject(operateobject.ohfi);
 | 
			
		||||
    CMAObject *root = db->ohfiToObject(operateobject.ohfi);
 | 
			
		||||
 | 
			
		||||
    // end for renaming only
 | 
			
		||||
    if(root == NULL) {
 | 
			
		||||
@@ -731,7 +722,7 @@ void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
        } else {
 | 
			
		||||
            CMAObject *newobj = new CMAObject(root);
 | 
			
		||||
            newobj->initObject(QFileInfo(dir, operateobject.title));
 | 
			
		||||
            db.append(operateobject.ohfi, newobj);
 | 
			
		||||
            db->append(operateobject.ohfi, newobj);
 | 
			
		||||
            qDebug("Created folder %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path);
 | 
			
		||||
            VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi);
 | 
			
		||||
        }
 | 
			
		||||
@@ -747,7 +738,7 @@ void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
        } else {
 | 
			
		||||
            CMAObject *newobj = new CMAObject(root);
 | 
			
		||||
            newobj->initObject(file);
 | 
			
		||||
            db.append(root->metadata.ohfi, newobj);
 | 
			
		||||
            db->append(root->metadata.ohfi, newobj);
 | 
			
		||||
            qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path);
 | 
			
		||||
            VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi);
 | 
			
		||||
        }
 | 
			
		||||
@@ -762,7 +753,7 @@ void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
        //rename the current object
 | 
			
		||||
        root->rename(operateobject.title);
 | 
			
		||||
        Database::find_data iters;
 | 
			
		||||
        db.find(root->metadata.ohfi, iters);
 | 
			
		||||
        db->find(root->metadata.ohfi, iters);
 | 
			
		||||
 | 
			
		||||
        // rename the rest of the list only if has the renamed parent in some part of the chain
 | 
			
		||||
        while(iters.it != iters.end) {
 | 
			
		||||
@@ -794,7 +785,7 @@ void ListenerWorker::vitaEventOperateObject(vita_event_t *event, int eventId)
 | 
			
		||||
    free(operateobject.title);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -806,8 +797,8 @@ void ListenerWorker::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(part_init.ohfi);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(part_init.ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("Cannot find OHFI %d", part_init.ohfi);
 | 
			
		||||
@@ -834,14 +825,14 @@ void ListenerWorker::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
 | 
			
		||||
    free(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventSendStorageSize(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventSendStorageSize(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    int ohfi = event->Param2;
 | 
			
		||||
    CMAObject *object = db.ohfiToObject(ohfi);
 | 
			
		||||
    CMAObject *object = db->ohfiToObject(ohfi);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        qWarning("Error: Cannot find OHFI %d", ohfi);
 | 
			
		||||
@@ -880,7 +871,7 @@ void ListenerWorker::vitaEventSendStorageSize(vita_event_t *event, int eventId)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ListenerWorker::vitaEventCheckExistance(vita_event_t *event, int eventId)
 | 
			
		||||
void CmaClient::vitaEventCheckExistance(vita_event_t *event, int eventId)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
 | 
			
		||||
 | 
			
		||||
@@ -892,9 +883,9 @@ void ListenerWorker::vitaEventCheckExistance(vita_event_t *event, int eventId)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QMutexLocker locker(&db.mutex);
 | 
			
		||||
    QMutexLocker locker(&db->mutex);
 | 
			
		||||
 | 
			
		||||
    CMAObject *object = db.pathToObject(existance.name, 0);
 | 
			
		||||
    CMAObject *object = db->pathToObject(existance.name, 0);
 | 
			
		||||
 | 
			
		||||
    if(object == NULL) {
 | 
			
		||||
        VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Different_Object);
 | 
			
		||||
@@ -1,50 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2013  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CMACLIENT_H
 | 
			
		||||
#define CMACLIENT_H
 | 
			
		||||
 | 
			
		||||
#ifndef LISTENERWORKER_H
 | 
			
		||||
#define LISTENERWORKER_H
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "baseworker.h"
 | 
			
		||||
#include "cmaobject.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ListenerWorker : public BaseWorker
 | 
			
		||||
class CmaClient : public BaseWorker
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit ListenerWorker(QObject *parent = 0);
 | 
			
		||||
 | 
			
		||||
    void setDevice(vita_device_t *device);
 | 
			
		||||
    bool isConnected();
 | 
			
		||||
    void disconnect();
 | 
			
		||||
    int rebuildDatabase();
 | 
			
		||||
 | 
			
		||||
    Database db;
 | 
			
		||||
    explicit CmaClient(QObject *parent = 0);
 | 
			
		||||
    explicit CmaClient(Database *database, vita_device_t *device, QObject *parent = 0);
 | 
			
		||||
    ~CmaClient();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void enterEventLoop();
 | 
			
		||||
 | 
			
		||||
    uint16_t processAllObjects(CMAObject *parent, uint32_t handle);
 | 
			
		||||
    void vitaEventSendObject(vita_event_t *event, int eventId);
 | 
			
		||||
    void vitaEventSendObjectMetadata(vita_event_t *event, int eventId);
 | 
			
		||||
@@ -68,15 +46,21 @@ private:
 | 
			
		||||
    void vitaEventSendNPAccountInfo(vita_event_t *event, int eventId);
 | 
			
		||||
    void vitaEventRequestTerminate(vita_event_t *event, int eventId);
 | 
			
		||||
 | 
			
		||||
    Database *db;
 | 
			
		||||
    vita_device_t *device;
 | 
			
		||||
    volatile bool connected;
 | 
			
		||||
    static const metadata_t g_thumbmeta;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void deviceConnected(QString);
 | 
			
		||||
    void refreshDatabase();
 | 
			
		||||
    void terminate();
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void close();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void process();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // LISTENERWORKER_H
 | 
			
		||||
#endif // CMACLIENT_H
 | 
			
		||||
							
								
								
									
										72
									
								
								cmaserver.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								cmaserver.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
#include "cmaserver.h"
 | 
			
		||||
#include "wirelessworker.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QHostInfo>
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
CmaServer::CmaServer(QObject *parent) :
 | 
			
		||||
    QObject(parent), num_retries(0)
 | 
			
		||||
{
 | 
			
		||||
    strcpy(hostname, QHostInfo::localHostName().toStdString().c_str());
 | 
			
		||||
    BroadcastSignal::info.name = hostname;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaServer::listen()
 | 
			
		||||
{
 | 
			
		||||
    QThread *thread = new QThread();
 | 
			
		||||
    if(QSettings().value("wireless", false).toBool()) {
 | 
			
		||||
        connect(&timer, SIGNAL(timeout()), this, SLOT(connectWireless()));
 | 
			
		||||
        broadcast.start();
 | 
			
		||||
        timer.setSingleShot(true);
 | 
			
		||||
    } else {
 | 
			
		||||
        timer.setSingleShot(false);
 | 
			
		||||
        connect(&timer, SIGNAL(timeout()), this, SLOT(connectUsb()));
 | 
			
		||||
    }
 | 
			
		||||
    moveToThread(thread);
 | 
			
		||||
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
 | 
			
		||||
    timer.start(2000);
 | 
			
		||||
    thread->start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaServer::connectUsb()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() << "From connectUsb: "<< QThread::currentThreadId();
 | 
			
		||||
 | 
			
		||||
    vita_device_t *vita = VitaMTP_Get_First_USB_Vita();
 | 
			
		||||
    if(vita) {
 | 
			
		||||
        qDebug("Detected PS Vita via USB");
 | 
			
		||||
        timer.stop();
 | 
			
		||||
        emit newConnection(vita);
 | 
			
		||||
    } else {
 | 
			
		||||
        qDebug("No PS Vita found. Attempt %d", ++num_retries);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaServer::connectWireless()
 | 
			
		||||
{
 | 
			
		||||
    typedef BroadcastSignal BS;
 | 
			
		||||
 | 
			
		||||
    qDebug() << "From connectWireless: "<< QThread::currentThreadId();
 | 
			
		||||
 | 
			
		||||
    vita_device_t *vita = VitaMTP_Get_First_Wireless_Vita(&BS::info, 0, 0, BS::deviceRegistered, BS::generatePin);
 | 
			
		||||
    if(vita) {
 | 
			
		||||
        qDebug("Detected PS Vita in wireless mode");
 | 
			
		||||
        emit newConnection(vita);
 | 
			
		||||
    } else {
 | 
			
		||||
        qDebug("PS Vita couldn't be detected. Attempt %d", ++num_retries);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaServer::continueProcess()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Restarting CmaServer thread");
 | 
			
		||||
    num_retries = 0;
 | 
			
		||||
    timer.start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CmaServer::stopProcess()
 | 
			
		||||
{
 | 
			
		||||
    timer.stop();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								cmaserver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								cmaserver.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
#ifndef CMASERVER_H
 | 
			
		||||
#define CMASERVER_H
 | 
			
		||||
 | 
			
		||||
#include "wirelessworker.h"
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
 | 
			
		||||
class CmaServer : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit CmaServer(QObject *parent = 0);
 | 
			
		||||
    void listen();
 | 
			
		||||
    void close();
 | 
			
		||||
 | 
			
		||||
    int num_retries;
 | 
			
		||||
    QTimer timer;
 | 
			
		||||
    QThread *thread;
 | 
			
		||||
    char hostname[256];
 | 
			
		||||
    BroadcastSignal broadcast;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void newConnection(vita_device_t *);
 | 
			
		||||
    void createdPin(int);
 | 
			
		||||
    void finished();
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void continueProcess();
 | 
			
		||||
    void stopProcess();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void connectWireless();
 | 
			
		||||
    void connectUsb();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // CMASERVER_H
 | 
			
		||||
							
								
								
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							@@ -18,6 +18,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#include "singleapplication.h"
 | 
			
		||||
#include "mainwidget.h"
 | 
			
		||||
@@ -42,12 +43,17 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    SingleApplication app(argc, argv);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if(!app.arguments().contains("--with-debug")) {
 | 
			
		||||
        VitaMTP_Set_Logging(VitaMTP_NONE);
 | 
			
		||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
 | 
			
		||||
        qInstallMessageHandler(noMessageOutput);
 | 
			
		||||
#else
 | 
			
		||||
        qInstallMsgHandler(noMessageOutput);
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        VitaMTP_Set_Logging(VitaMTP_DEBUG);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qDebug()<<"From main thread: "<<QThread::currentThreadId();
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,12 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "mainwidget.h"
 | 
			
		||||
#include "qcma.h"
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#include <QAction>
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QMenu>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
@@ -45,7 +47,7 @@ void MainWidget::checkSettings()
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    CmaWorker.start();
 | 
			
		||||
    startServer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::dialogResult(int result)
 | 
			
		||||
@@ -53,13 +55,44 @@ void MainWidget::dialogResult(int result)
 | 
			
		||||
    if(result == QDialog::Accepted) {
 | 
			
		||||
        if(first_run) {
 | 
			
		||||
            first_run = false;
 | 
			
		||||
            CmaWorker.start();
 | 
			
		||||
            startServer();
 | 
			
		||||
        }
 | 
			
		||||
    } else if(first_run) {
 | 
			
		||||
        qApp->quit();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::startServer()
 | 
			
		||||
{
 | 
			
		||||
    connect(&server, SIGNAL(newConnection(vita_device_t *)), this, SLOT(startClient(vita_device_t*)));
 | 
			
		||||
    connect(&server, SIGNAL(createdPin(int)), this, SLOT(showPin(int)));
 | 
			
		||||
    //connect(&server, SIGNAL(finished()), qApp, SLOT(quit()));
 | 
			
		||||
 | 
			
		||||
    qDebug("Starting cma server");
 | 
			
		||||
    server.listen();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::refreshDatabase()
 | 
			
		||||
{
 | 
			
		||||
    db.mutex.lock();
 | 
			
		||||
    db.destroy();
 | 
			
		||||
    db.create();
 | 
			
		||||
    db.mutex.unlock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::startClient(vita_device_t *device)
 | 
			
		||||
{
 | 
			
		||||
    server.stopProcess();
 | 
			
		||||
    qDebug() << "From startClient: "<< QThread::currentThreadId();
 | 
			
		||||
    qDebug("Starting new client connection");
 | 
			
		||||
    CmaClient *client = new CmaClient(&db, device);
 | 
			
		||||
    connect(client, SIGNAL(deviceConnected(QString)), this, SLOT(receiveMessage(QString)));
 | 
			
		||||
    connect(client, SIGNAL(deviceConnected(QString)), this, SLOT(setTrayTooltip(QString)));
 | 
			
		||||
    connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase()));
 | 
			
		||||
    connect(client, SIGNAL(finished()), &server, SLOT(continueProcess()));
 | 
			
		||||
    client->start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::deviceDisconnect()
 | 
			
		||||
{
 | 
			
		||||
    setTrayTooltip(tr("Disconnected"));
 | 
			
		||||
@@ -69,12 +102,6 @@ void MainWidget::deviceDisconnect()
 | 
			
		||||
void MainWidget::connectSignals()
 | 
			
		||||
{
 | 
			
		||||
    connect(&dialog, SIGNAL(finished(int)), this, SLOT(dialogResult(int)));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(createdPin(int)), this, SLOT(showPin(int)));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(deviceConnected(QString)), this, SLOT(receiveMessage(QString)));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(deviceConnected(QString)), this, SLOT(setTrayTooltip(QString)));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(statusUpdated(QString)), this, SLOT(receiveMessage(QString)));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect()));
 | 
			
		||||
    connect(&CmaWorker, SIGNAL(finished()), qApp, SLOT(quit()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::showPin(int pin)
 | 
			
		||||
@@ -86,7 +113,6 @@ void MainWidget::prepareApplication()
 | 
			
		||||
{
 | 
			
		||||
    connectSignals();
 | 
			
		||||
    createTrayIcon();
 | 
			
		||||
    trayIcon->show();
 | 
			
		||||
    checkSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +131,6 @@ void MainWidget::toggleWireless()
 | 
			
		||||
        wireless->setText(tr("&Wireless disabled"));
 | 
			
		||||
        settings.setValue("wireless", false);
 | 
			
		||||
    }
 | 
			
		||||
    CmaWorker.reload();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::createTrayIcon()
 | 
			
		||||
@@ -126,8 +151,8 @@ void MainWidget::createTrayIcon()
 | 
			
		||||
    quit = new QAction(tr("&Quit"), this);
 | 
			
		||||
 | 
			
		||||
    connect(options, SIGNAL(triggered()), &dialog, SLOT(open()));
 | 
			
		||||
    connect(reload, SIGNAL(triggered()), &CmaWorker, SLOT(allowRefresh()), Qt::DirectConnection);
 | 
			
		||||
    connect(quit, SIGNAL(triggered()), &CmaWorker, SLOT(stop()), Qt::DirectConnection);
 | 
			
		||||
    //connect(reload, SIGNAL(triggered()), &CmaWorker, SLOT(allowRefresh()), Qt::DirectConnection);
 | 
			
		||||
    connect(quit, SIGNAL(triggered()), qApp, SLOT(quit()));
 | 
			
		||||
    connect(wireless, SIGNAL(triggered()), this, SLOT(toggleWireless()));
 | 
			
		||||
 | 
			
		||||
    QMenu *trayIconMenu = new QMenu(this);
 | 
			
		||||
@@ -139,7 +164,10 @@ void MainWidget::createTrayIcon()
 | 
			
		||||
 | 
			
		||||
    trayIcon = new QSystemTrayIcon(this);
 | 
			
		||||
    trayIcon->setContextMenu(trayIconMenu);
 | 
			
		||||
    trayIcon->setIcon(QIcon::fromTheme("image-loading"));
 | 
			
		||||
    trayIcon->setIcon(QIcon(":/main/resources/psv_icon.png"));
 | 
			
		||||
    trayIcon->show();
 | 
			
		||||
    // try to avoid the iconTray Qt bug
 | 
			
		||||
    //Sleeper::sleep(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWidget::receiveMessage(QString message)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								mainwidget.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								mainwidget.h
									
									
									
									
									
								
							@@ -21,19 +21,20 @@
 | 
			
		||||
#define MAINWIDGET_H
 | 
			
		||||
 | 
			
		||||
#include "configwidget.h"
 | 
			
		||||
#include "qcma.h"
 | 
			
		||||
#include "cmaserver.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
 | 
			
		||||
#include <QAction>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <QSystemTrayIcon>
 | 
			
		||||
 | 
			
		||||
class QMenu;
 | 
			
		||||
 | 
			
		||||
namespace Ui
 | 
			
		||||
{
 | 
			
		||||
class MainWidget;
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QMenu;
 | 
			
		||||
 | 
			
		||||
class MainWidget : public QWidget
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
@@ -49,13 +50,14 @@ private:
 | 
			
		||||
    void connectSignals();
 | 
			
		||||
 | 
			
		||||
    bool first_run;
 | 
			
		||||
    QCMA CmaWorker;
 | 
			
		||||
    ConfigWidget dialog;
 | 
			
		||||
    QSystemTrayIcon *trayIcon;
 | 
			
		||||
    QAction *quit;
 | 
			
		||||
    QAction *reload;
 | 
			
		||||
    QAction *options;
 | 
			
		||||
    QAction *wireless;
 | 
			
		||||
    Database db;
 | 
			
		||||
    CmaServer server;
 | 
			
		||||
    const static QStringList path_list;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
@@ -65,6 +67,9 @@ private slots:
 | 
			
		||||
    void setTrayTooltip(QString message);
 | 
			
		||||
    void toggleWireless();
 | 
			
		||||
    void showPin(int pin);
 | 
			
		||||
    void startClient(vita_device_t *device);
 | 
			
		||||
    void refreshDatabase();
 | 
			
		||||
    void startServer();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // MAINWIDGET_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										174
									
								
								qcma.cpp
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								qcma.cpp
									
									
									
									
									
								
							@@ -1,174 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2013  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qcma.h"
 | 
			
		||||
 | 
			
		||||
#include "capability.h"
 | 
			
		||||
#include "listenerworker.h"
 | 
			
		||||
#include "wirelessworker.h"
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
#include <QElapsedTimer>
 | 
			
		||||
#include <QHostInfo>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#define RETRY_TIMEOUT 2000
 | 
			
		||||
 | 
			
		||||
QCMA::QCMA(QObject *parent) :
 | 
			
		||||
    BaseWorker(parent)
 | 
			
		||||
{
 | 
			
		||||
    exit_thread = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vita_device_t *QCMA::connectWireless()
 | 
			
		||||
{
 | 
			
		||||
    int num_tries = 0;
 | 
			
		||||
    vita_device_t *vita = NULL;
 | 
			
		||||
    WirelessWorker *broadcast = new WirelessWorker();
 | 
			
		||||
 | 
			
		||||
    // bubble up the pin received signal
 | 
			
		||||
    connect(broadcast, SIGNAL(createdPin(int)), this, SIGNAL(createdPin(int)));
 | 
			
		||||
 | 
			
		||||
    qDebug("Starting broadcast");
 | 
			
		||||
    broadcast->start();
 | 
			
		||||
 | 
			
		||||
    QMutex mutex;
 | 
			
		||||
    QString hostname = QHostInfo::localHostName();
 | 
			
		||||
    WirelessWorker::info.name = hostname.toUtf8().data();
 | 
			
		||||
 | 
			
		||||
    while(!break_loop && (vita = VitaMTP_Get_First_Wireless_Vita(
 | 
			
		||||
                                      &WirelessWorker::info, 0, 10,
 | 
			
		||||
                                      WirelessWorker::deviceRegistered,
 | 
			
		||||
                                      WirelessWorker::generatePin)) == NULL) {
 | 
			
		||||
        qDebug("Error connecting to device. Attempt %d", ++num_tries);
 | 
			
		||||
        //FIXME: use a proper sleep function
 | 
			
		||||
        mutex.lock();
 | 
			
		||||
        waitCondition.wait(&mutex, RETRY_TIMEOUT);
 | 
			
		||||
        mutex.unlock();
 | 
			
		||||
    }
 | 
			
		||||
    qDebug("Stopping broadcast");
 | 
			
		||||
    broadcast->stopBroadcast();
 | 
			
		||||
    return vita;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vita_device_t *QCMA::connectUsb()
 | 
			
		||||
{
 | 
			
		||||
    int num_tries = 0;
 | 
			
		||||
    vita_device_t *vita = NULL;
 | 
			
		||||
    QMutex mutex;
 | 
			
		||||
    while(!break_loop && (vita = VitaMTP_Get_First_USB_Vita()) == NULL) {
 | 
			
		||||
        qDebug("No Vita found. Attempt %d", ++num_tries);
 | 
			
		||||
        //FIXME: use a proper sleep function
 | 
			
		||||
        mutex.lock();
 | 
			
		||||
        waitCondition.wait(&mutex, RETRY_TIMEOUT);
 | 
			
		||||
        mutex.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return vita;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QCMA::process()
 | 
			
		||||
{    
 | 
			
		||||
    QSettings settings;
 | 
			
		||||
 | 
			
		||||
    qDebug() << "From QCMA: "<< QThread::currentThreadId();
 | 
			
		||||
 | 
			
		||||
    while(!exit_thread) {
 | 
			
		||||
        break_loop = false;
 | 
			
		||||
        VitaMTP_Set_Logging(VitaMTP_NONE);
 | 
			
		||||
        bool wireless = settings.value("wireless", false).toBool();
 | 
			
		||||
        emit statusUpdated("Searching for device...");
 | 
			
		||||
        vita_device_t *device = wireless ? connectWireless() : connectUsb();
 | 
			
		||||
        if(!device) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qDebug("Vita connected: id %s", VitaMTP_Get_Identification(device));
 | 
			
		||||
 | 
			
		||||
        // create a listener thread to receive the vita events
 | 
			
		||||
        ListenerWorker *listener = new ListenerWorker();
 | 
			
		||||
        listener->setDevice(device);
 | 
			
		||||
        connect(listener, SIGNAL(refreshDatabase()), this, SLOT(allowRefresh()), Qt::DirectConnection);
 | 
			
		||||
        connect(listener, SIGNAL(finished()), this, SIGNAL(deviceDisconnected()), Qt::DirectConnection);
 | 
			
		||||
        connect(listener, SIGNAL(finished()), this, SLOT(reload()), Qt::DirectConnection);
 | 
			
		||||
        listener->start();
 | 
			
		||||
        qDebug("Exchanging info with vita");
 | 
			
		||||
        DeviceCapability *vita_info = new DeviceCapability();
 | 
			
		||||
 | 
			
		||||
        if(!vita_info->exchangeInfo(device)) {
 | 
			
		||||
            qCritical("Error while exchanging info with the vita");
 | 
			
		||||
            VitaMTP_SendHostStatus(device, VITA_HOST_STATUS_EndConnection);
 | 
			
		||||
            VitaMTP_Release_Device(device);
 | 
			
		||||
            sleep(RETRY_TIMEOUT);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Conection successful, inform the user
 | 
			
		||||
        emit deviceConnected(QString(tr("Connected to ")) + vita_info->getOnlineId());
 | 
			
		||||
 | 
			
		||||
        delete vita_info;
 | 
			
		||||
        QElapsedTimer timer;
 | 
			
		||||
        qint64 sec;
 | 
			
		||||
 | 
			
		||||
        while(listener->isConnected()) {
 | 
			
		||||
            sema.acquire();
 | 
			
		||||
            if(break_loop) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            qDebug("Updating database");
 | 
			
		||||
            timer.start();
 | 
			
		||||
            int scanned_objects = listener->rebuildDatabase();
 | 
			
		||||
            sec = timer.elapsed();
 | 
			
		||||
            qDebug("Scanned %i objects in %lli milliseconds", scanned_objects, sec);
 | 
			
		||||
            emit statusUpdated(QString("Scanned %1 objects in %2 milliseconds").arg(scanned_objects, sec));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qDebug("Ending device connection...");
 | 
			
		||||
        VitaMTP_SendHostStatus(device, VITA_HOST_STATUS_EndConnection);
 | 
			
		||||
        VitaMTP_Release_Device(device);
 | 
			
		||||
    }
 | 
			
		||||
    qDebug("QCMA thread end");
 | 
			
		||||
    emit finished();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QCMA::allowRefresh()
 | 
			
		||||
{
 | 
			
		||||
    sema.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QCMA::reload()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Stopping QCMA workers...");
 | 
			
		||||
    break_loop = true;
 | 
			
		||||
    waitCondition.wakeAll();
 | 
			
		||||
    sema.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QCMA::stop()
 | 
			
		||||
{    
 | 
			
		||||
    exit_thread = true;
 | 
			
		||||
    reload();
 | 
			
		||||
    qDebug("Stopping QCMA thread...");
 | 
			
		||||
    emit stopCMA();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								qcma.h
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								qcma.h
									
									
									
									
									
								
							@@ -1,70 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  QCMA: Cross-platform content manager assistant for the PS Vita
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2013  Codestation
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef QCMA_H
 | 
			
		||||
#define QCMA_H
 | 
			
		||||
 | 
			
		||||
#include "baseworker.h"
 | 
			
		||||
 | 
			
		||||
#include <QSystemTrayIcon>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <QMenu>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
#include <QSemaphore>
 | 
			
		||||
 | 
			
		||||
class QMenu;
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define QCMA_VERSION_STRING "QCMA 0.1"
 | 
			
		||||
 | 
			
		||||
class QCMA : public BaseWorker
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit QCMA(QObject *parent = 0);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QSemaphore sema;
 | 
			
		||||
    QWaitCondition waitCondition;
 | 
			
		||||
    volatile bool break_loop;
 | 
			
		||||
    volatile bool exit_thread;
 | 
			
		||||
    vita_device_t *connectUsb();
 | 
			
		||||
    vita_device_t *connectWireless();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void createdPin(int);
 | 
			
		||||
    void deviceConnected(QString);
 | 
			
		||||
    void statusUpdated(QString);
 | 
			
		||||
    void deviceDisconnected();
 | 
			
		||||
    void stopCMA();
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void stop();
 | 
			
		||||
    void reload();
 | 
			
		||||
 | 
			
		||||
protected slots:
 | 
			
		||||
    void allowRefresh();
 | 
			
		||||
    virtual void process();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QCMA_H
 | 
			
		||||
							
								
								
									
										15
									
								
								qcma.pro
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								qcma.pro
									
									
									
									
									
								
							@@ -14,9 +14,7 @@ TARGET = qcma
 | 
			
		||||
TEMPLATE = app
 | 
			
		||||
 | 
			
		||||
SOURCES += main.cpp \
 | 
			
		||||
    qcma.cpp \
 | 
			
		||||
    wirelessworker.cpp \
 | 
			
		||||
    listenerworker.cpp \
 | 
			
		||||
    capability.cpp \
 | 
			
		||||
    database.cpp \
 | 
			
		||||
    cmaobject.cpp \
 | 
			
		||||
@@ -26,12 +24,12 @@ SOURCES += main.cpp \
 | 
			
		||||
    configwidget.cpp \
 | 
			
		||||
    singleapplication.cpp \
 | 
			
		||||
    baseworker.cpp \
 | 
			
		||||
    sforeader.cpp
 | 
			
		||||
    sforeader.cpp \
 | 
			
		||||
    cmaserver.cpp \
 | 
			
		||||
    cmaclient.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    qcma.h \
 | 
			
		||||
    wirelessworker.h \
 | 
			
		||||
    listenerworker.h \
 | 
			
		||||
    capability.h \
 | 
			
		||||
    database.h \
 | 
			
		||||
    cmaobject.h \
 | 
			
		||||
@@ -41,7 +39,9 @@ HEADERS += \
 | 
			
		||||
    configwidget.h \
 | 
			
		||||
    singleapplication.h \
 | 
			
		||||
    baseworker.h \
 | 
			
		||||
    sforeader.h
 | 
			
		||||
    sforeader.h \
 | 
			
		||||
    cmaserver.h \
 | 
			
		||||
    cmaclient.h
 | 
			
		||||
 | 
			
		||||
CONFIG += link_pkgconfig
 | 
			
		||||
PKGCONFIG += libvitamtp libmediainfo
 | 
			
		||||
@@ -52,7 +52,8 @@ RESOURCES += \
 | 
			
		||||
    qcmares.qrc
 | 
			
		||||
 | 
			
		||||
OTHER_FILES += \
 | 
			
		||||
    psp2-updatelist.xml
 | 
			
		||||
    resources/psp2-updatelist.xml \
 | 
			
		||||
    resources/psv_icon.png
 | 
			
		||||
 | 
			
		||||
FORMS += \
 | 
			
		||||
    configwidget.ui
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
<RCC>
 | 
			
		||||
    <qresource prefix="/main">
 | 
			
		||||
        <file>psp2-updatelist.xml</file>
 | 
			
		||||
        <file>resources/psp2-updatelist.xml</file>
 | 
			
		||||
        <file>resources/psv_icon.png</file>
 | 
			
		||||
    </qresource>
 | 
			
		||||
</RCC>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								resources/psv_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/psv_icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 387 B  | 
@@ -20,7 +20,6 @@
 | 
			
		||||
#include "singleapplication.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
 | 
			
		||||
const int SingleApplication::timeout = 500;
 | 
			
		||||
const QString SingleApplication::SHARED_KEY = "QCMA_KEY";
 | 
			
		||||
@@ -30,15 +29,7 @@ SingleApplication::SingleApplication(int &argc, char **argv) :
 | 
			
		||||
{
 | 
			
		||||
    server = new QLocalServer(this);
 | 
			
		||||
    connect(server, SIGNAL(newConnection()), this, SLOT(receiveMessage()));
 | 
			
		||||
#ifdef Q_OS_UNIX
 | 
			
		||||
    // Make sure that the socket file is deleted
 | 
			
		||||
    QFile address(QString("/tmp/" +  SHARED_KEY));
 | 
			
		||||
 | 
			
		||||
    if(address.exists()) {
 | 
			
		||||
        address.remove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
    QLocalServer::removeServer(SHARED_KEY);
 | 
			
		||||
    server->listen(SHARED_KEY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								utils.h
									
									
									
									
									
								
							@@ -21,6 +21,20 @@
 | 
			
		||||
#define UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
// Qt4 doesn't have public methods for Thread::*sleep
 | 
			
		||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
 | 
			
		||||
    typedef QThread Sleeper;
 | 
			
		||||
#else
 | 
			
		||||
    class Sleeper : QThread
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        static void sleep(unsigned long secs) { QThread::sleep(secs); }
 | 
			
		||||
        static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
 | 
			
		||||
        static void usleep(unsigned long usecs) { QThread::usleep(usecs); }
 | 
			
		||||
    };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool removeRecursively(const QString &dirName);
 | 
			
		||||
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,32 +17,38 @@
 | 
			
		||||
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qcma.h"
 | 
			
		||||
#include "wirelessworker.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QHostInfo>
 | 
			
		||||
 | 
			
		||||
#define QCMA_REQUEST_PORT 9309
 | 
			
		||||
 | 
			
		||||
wireless_host_info_t WirelessWorker::info = {"00000000-0000-0000-0000-000000000000", "win", NULL, QCMA_REQUEST_PORT};
 | 
			
		||||
wireless_host_info_t BroadcastSignal::info = {"00000000-0000-0000-0000-000000000000", "win", NULL, QCMA_REQUEST_PORT};
 | 
			
		||||
 | 
			
		||||
WirelessWorker *WirelessWorker::this_object = NULL;
 | 
			
		||||
BroadcastSignal *BroadcastSignal::this_object = NULL;
 | 
			
		||||
 | 
			
		||||
WirelessWorker::WirelessWorker(QObject *parent) :
 | 
			
		||||
BroadcastSignal::BroadcastSignal(QObject *parent) :
 | 
			
		||||
    BaseWorker(parent)
 | 
			
		||||
{
 | 
			
		||||
    qsrand(QTime::currentTime().msec());
 | 
			
		||||
    this_object = this;
 | 
			
		||||
    started = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WirelessWorker::deviceRegistered(const char *deviceid)
 | 
			
		||||
BroadcastSignal::~BroadcastSignal()
 | 
			
		||||
{
 | 
			
		||||
    VitaMTP_Stop_Broadcast();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BroadcastSignal::deviceRegistered(const char *deviceid)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Got connection request from %s", deviceid);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int WirelessWorker::generatePin(wireless_vita_info_t *info, int *p_err)
 | 
			
		||||
int BroadcastSignal::generatePin(wireless_vita_info_t *info, int *p_err)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Registration request from %s (MAC: %s)", info->name, info->mac_addr);
 | 
			
		||||
    int pin = qrand() % 100000000;
 | 
			
		||||
@@ -52,25 +58,24 @@ int WirelessWorker::generatePin(wireless_vita_info_t *info, int *p_err)
 | 
			
		||||
    return pin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WirelessWorker::process()
 | 
			
		||||
void BroadcastSignal::process()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() <<" Wireless thread ID: "<< QThread::currentThreadId();
 | 
			
		||||
 | 
			
		||||
    wireless_host_info_t broadcast_info = info;
 | 
			
		||||
    QString hostname = QHostInfo::localHostName();
 | 
			
		||||
    broadcast_info.name = hostname.toUtf8().data();
 | 
			
		||||
 | 
			
		||||
    qDebug() <<"Broadcast thread ID: "<< QThread::currentThreadId();
 | 
			
		||||
    qDebug("Starting CMA wireless broadcast...");
 | 
			
		||||
    if(VitaMTP_Broadcast_Host(&broadcast_info, 0) < 0) {
 | 
			
		||||
 | 
			
		||||
    started = true;
 | 
			
		||||
    if(VitaMTP_Broadcast_Host(&info, 0) < 0) {
 | 
			
		||||
        qCritical( "An error occured during broadcast. Exiting.");
 | 
			
		||||
    } else {
 | 
			
		||||
        qDebug("Broadcast ended.");
 | 
			
		||||
    }
 | 
			
		||||
    qDebug("WirelessrWorker thread end.");
 | 
			
		||||
    qDebug("Broadcast thread end.");
 | 
			
		||||
    emit finished();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WirelessWorker::stopBroadcast()
 | 
			
		||||
void BroadcastSignal::stopBroadcast()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("Stopping broadcast");
 | 
			
		||||
    VitaMTP_Stop_Broadcast();
 | 
			
		||||
    started = false;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,21 +29,24 @@ extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class WirelessWorker : public BaseWorker
 | 
			
		||||
class BroadcastSignal : public BaseWorker
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit WirelessWorker(QObject *parent = 0);
 | 
			
		||||
    explicit BroadcastSignal(QObject *parent = 0);
 | 
			
		||||
    ~BroadcastSignal();
 | 
			
		||||
 | 
			
		||||
    static int deviceRegistered(const char *deviceid);
 | 
			
		||||
    static int generatePin(wireless_vita_info_t *info, int *p_err);
 | 
			
		||||
    bool isRunning() { return started; }
 | 
			
		||||
 | 
			
		||||
    static wireless_host_info_t info;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    volatile bool started;
 | 
			
		||||
    //used to emit a signal from a static method
 | 
			
		||||
    static WirelessWorker *this_object;
 | 
			
		||||
    static BroadcastSignal *this_object;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void createdPin(int);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user