Moved conection logic from Qcma/ListenerWorker to CmaServer/CmaClient.
Added tray icon. Quit now really quits the application.
This commit is contained in:
@@ -1,70 +1,60 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -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