Skip to content

Commit

Permalink
Merge pull request #320 from jmlich/asteroidos
Browse files Browse the repository at this point in the history
AsteroidOS support
  • Loading branch information
piggz authored Jan 21, 2024
2 parents 09a550d + e0b559a commit d5e3fe6
Show file tree
Hide file tree
Showing 18 changed files with 762 additions and 10 deletions.
10 changes: 10 additions & 0 deletions daemon/daemon.pro
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ include(libwatchfish/libwatchfish.pri)
include(../qble/qble.pri)

SOURCES += \
src/devices/asteroidosdevice.cpp \
src/devices/banglejsdevice.cpp \
src/devices/bipdevice.cpp \
src/devices/bipsdevice.cpp \
Expand Down Expand Up @@ -131,6 +132,10 @@ SOURCES += \
src/operations/huamiupdatefirmwareoperation2020.cpp \
src/qaesencryption.cpp \
src/services/adafruitblefsservice.cpp \
src/services/asteroidtimeservice.cpp \
src/services/asteroidweatherservice.cpp \
src/services/asteroidnotificationservice.cpp \
src/services/asteroidmediaservice.cpp \
src/services/currenttimeservice.cpp \
src/services/dfuservice.cpp \
src/services/infinitimemotionservice.cpp \
Expand Down Expand Up @@ -181,6 +186,7 @@ SAILFISHAPP_ICONS = 86x86 108x108 128x128 172x172

HEADERS += \
src/codec.h \
src/devices/asteroidosdevice.h \
src/devices/banglejsdevice.h \
src/devices/bipdevice.h \
src/devices/bipsdevice.h \
Expand Down Expand Up @@ -208,6 +214,10 @@ HEADERS += \
src/operations/huamiupdatefirmwareoperation2020.h \
src/qaesencryption.h \
src/services/adafruitblefsservice.h \
src/services/asteroidtimeservice.h \
src/services/asteroidweatherservice.h \
src/services/asteroidnotificationservice.h \
src/services/asteroidmediaservice.h \
src/services/currenttimeservice.h \
src/services/dfuservice.h \
src/services/infinitimemotionservice.h \
Expand Down
16 changes: 16 additions & 0 deletions daemon/src/devicefactory.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "devicefactory.h"
#include "asteroidosdevice.h"
#include "huamidevice.h"
#include "gtsdevice.h"
#include "biplitedevice.h"
Expand Down Expand Up @@ -56,6 +57,21 @@ AbstractDevice* DeviceFactory::createDevice(const QString &deviceName)
return new BangleJSDevice(deviceName);
}

QList<QString> asteroidDevices = {
"AsteroidOS",
"bass", "sturgeon", "narwhal", "sparrow", "dory",
"lenok", "catfish", "carp", "smelt", "anthias",
"pike", "sawfish", "ray", "firefish", "beluga", "skipjack",
"koi", "mooneye", "swift", "nemo", "hoki",
"minnow", "tetra", "sprat", "kingyo", "medaka"
};

for (auto iterator = asteroidDevices.begin(); iterator != asteroidDevices.end(); ++iterator) {
if (deviceName == *iterator) {
return new AsteroidOSDevice(deviceName);
}
}

qDebug() << "DeviceFactory::createDevice: no suitable devices found, creating a Bip device as default";
return new BipDevice(deviceName);

Expand Down
1 change: 1 addition & 0 deletions daemon/src/devices/abstractdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void AbstractDevice::pair()
QBLEDevice::pair();
}


void AbstractDevice::connectToDevice()
{
qDebug() << "AbstractDevice::connectToDevice";
Expand Down
281 changes: 281 additions & 0 deletions daemon/src/devices/asteroidosdevice.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
#include "asteroidosdevice.h"

#include "batteryservice.h"
#include "asteroidtimeservice.h"
#include "asteroidweatherservice.h"
#include "asteroidnotificationservice.h"
#include "asteroidmediaservice.h"

#include <QtXml/QtXml>


AsteroidOSDevice::AsteroidOSDevice(const QString &pairedName, QObject *parent) : AbstractDevice(pairedName, parent)
{
qDebug() << Q_FUNC_INFO << pairedName;
connect(this, &QBLEDevice::propertiesChanged, this, &AsteroidOSDevice::onPropertiesChanged, Qt::UniqueConnection);
}

int AsteroidOSDevice::supportedFeatures() const
{
return FEATURE_WEATHER | FEATURE_WEATHER | FEATURE_ALERT ;
//FEATURE_HRM | FEATURE_STEPS;
}

QString AsteroidOSDevice::deviceType() const
{
return "asteroidos";
}

AbstractFirmwareInfo *AsteroidOSDevice::firmwareInfo(const QByteArray &bytes)
{
qDebug() << Q_FUNC_INFO;
return nullptr;
}

void AsteroidOSDevice::sendAlert(const QString &sender, const QString &subject, const QString &message)
{
qDebug() << Q_FUNC_INFO << sender << subject << message;

AsteroidNotificationService *notification = qobject_cast<AsteroidNotificationService*>(service(AsteroidNotificationService::UUID_SERVICE_NOTIFICATION));
if (notification) {
notification->sendAlert(sender, subject, message);
}

}

void AsteroidOSDevice::incomingCall(const QString &caller)
{
qDebug() << Q_FUNC_INFO << caller;

AsteroidNotificationService *notification = qobject_cast<AsteroidNotificationService*>(service(AsteroidNotificationService::UUID_SERVICE_NOTIFICATION));
if (notification) {
notification->incomingCall(caller);
}

}


void AsteroidOSDevice::pair()
{
qDebug() << Q_FUNC_INFO;

m_needsAuth = true;
m_pairing = true;
m_autoreconnect = true;
//disconnectFromDevice();
setConnectionState("pairing");
emit connectionStateChanged();

QBLEDevice::connectToDevice();
}


/*
//Firmware handling
AbstractFirmwareInfo * AsteroidOSDevice::firmwareInfo(const QByteArray &bytes) = 0; //Caller owns the pointer and should delete it
void AsteroidOSDevice::prepareFirmwareDownload(const AbstractFirmwareInfo* info);
void AsteroidOSDevice::startDownload();
void AsteroidOSDevice::downloadSportsData();
void AsteroidOSDevice::refreshInformation();
QString AsteroidOSDevice::information(Info i) const;
void AsteroidOSDevice::applyDeviceSetting(Settings s);
void AsteroidOSDevice::rebootWatch();
void AsteroidOSDevice::sendEventReminder(int id, const QDateTime &dt, const QString &event);
void AsteroidOSDevice::enableFeature(AbstractDevice::Feature feature);
void AsteroidOSDevice::setMusicStatus(bool playing, const QString &title, const QString &artist, const QString &album, int duration = 0, int position = 0);
void AsteroidOSDevice::navigationRunning(bool running);
void AsteroidOSDevice::navigationNarrative(const QString &flag, const QString &narrative, const QString &manDist, int progress);
QStringList AsteroidOSDevice::supportedDisplayItems() const;
*/


void AsteroidOSDevice::onPropertiesChanged(QString interface, QVariantMap map, QStringList list)
{
qDebug() << Q_FUNC_INFO << interface << map << list;

if (interface == "org.bluez.Device1") {
m_reconnectTimer->start();
if (deviceProperty("ServicesResolved").toBool() ) {
initialise();
}
if (map.contains("Connected")) {
bool value = map["Connected"].toBool();

if (!value) {
qDebug() << "DisConnected!";
setConnectionState("disconnected");
} else {
setConnectionState("connected");
}
}
}

}


void AsteroidOSDevice::parseServices()
{
qDebug() << Q_FUNC_INFO;

QDBusInterface adapterIntro("org.bluez", devicePath(), "org.freedesktop.DBus.Introspectable", QDBusConnection::systemBus(), 0);
QDBusReply<QString> xml = adapterIntro.call("Introspect");

qDebug() << "Resolved services...";

qDebug().noquote() << xml.value();

QDomDocument doc;
doc.setContent(xml.value());

QDomNodeList nodes = doc.elementsByTagName("node");

qDebug() << nodes.count() << "nodes";

for (int x = 0; x < nodes.count(); x++)
{
QDomElement node = nodes.at(x).toElement();
QString nodeName = node.attribute("name");

if (nodeName.startsWith("service")) {
QString path = devicePath() + "/" + nodeName;

QDBusInterface devInterface("org.bluez", path, "org.bluez.GattService1", QDBusConnection::systemBus(), 0);
QString uuid = devInterface.property("UUID").toString();

qDebug() << "Creating service for: " << uuid;

if (uuid == BatteryService::UUID_SERVICE_BATTERY && !service(BatteryService::UUID_SERVICE_BATTERY)) {
addService(BatteryService::UUID_SERVICE_BATTERY, new BatteryService(path, this));
} else if (uuid == AsteroidTimeService::UUID_SERVICE_ASTEROID_TIME && !service(AsteroidTimeService::UUID_SERVICE_ASTEROID_TIME)) {
addService(AsteroidTimeService::UUID_SERVICE_ASTEROID_TIME, new AsteroidTimeService(path, this));
} else if (uuid == AsteroidWeatherService::UUID_SERVICE_WEATHER && !service(AsteroidWeatherService::UUID_SERVICE_WEATHER)) {
addService(AsteroidWeatherService::UUID_SERVICE_WEATHER, new AsteroidWeatherService(path, this));
} else if (uuid == AsteroidNotificationService::UUID_SERVICE_NOTIFICATION && !service(AsteroidNotificationService::UUID_SERVICE_NOTIFICATION)) {
addService(AsteroidNotificationService::UUID_SERVICE_NOTIFICATION, new AsteroidNotificationService(path, this));
} else if (uuid == AsteroidMediaService::UUID_SERVICE_MEDIA && !service(AsteroidMediaService::UUID_SERVICE_MEDIA )) {
addService(AsteroidMediaService::UUID_SERVICE_MEDIA , new AsteroidMediaService(path, this));
} else if ( !service(uuid)) {
addService(uuid, new QBLEService(uuid, path, this));
}
}
}
setConnectionState("authenticated");
}

void AsteroidOSDevice::initialise()
{
qDebug() << Q_FUNC_INFO;
setConnectionState("connected");
parseServices();

AsteroidNotificationService *notification = qobject_cast<AsteroidNotificationService*>(service(AsteroidNotificationService::UUID_SERVICE_NOTIFICATION));
if (notification) {
// notification->enableNotification(AsteroidNotificationService::UUID_CHARACTERISTIC_ALERT_NOTIFICATION_EVENT);
// connect(alert, &AlertNotificationService::serviceEvent, this, &PinetimeJFDevice::serviceEvent, Qt::UniqueConnection);
}


BatteryService *battery = qobject_cast<BatteryService*>(service(BatteryService::UUID_SERVICE_BATTERY));
if (battery) {
connect(battery, &BatteryService::informationChanged, this, &AsteroidOSDevice::informationChanged, Qt::UniqueConnection);
}


AsteroidTimeService *ats = qobject_cast<AsteroidTimeService*>(service(AsteroidTimeService::UUID_SERVICE_ASTEROID_TIME));
if (ats) {
ats->setCurrentTime();
}


AsteroidMediaService *ms = qobject_cast<AsteroidMediaService*>(service(AsteroidMediaService::UUID_SERVICE_MEDIA));
if (ms) {
ms->enableNotification(AsteroidMediaService::UUID_CHARACTERISTIC_MEDIA_COMMAND);
ms->enableNotification(AsteroidMediaService::UUID_CHARACTERISTIC_MEDIA_VOLUME);
connect(ms, &AsteroidMediaService::serviceEvent, this, &AsteroidOSDevice::serviceEvent, Qt::UniqueConnection);
}

}


void AsteroidOSDevice::authenticated(bool ready)
{
qDebug() << Q_FUNC_INFO << ready;

if (ready) {
setConnectionState("authenticated");
} else {
setConnectionState("authfailed");
}
}

void AsteroidOSDevice::refreshInformation()
{

BatteryService *bat = qobject_cast<BatteryService*>(service(BatteryService::UUID_SERVICE_BATTERY));
if (bat) {
bat->refreshInformation();
}

}

void AsteroidOSDevice::sendWeather(CurrentWeather *weather)
{
AsteroidWeatherService *w = qobject_cast<AsteroidWeatherService*>(service(AsteroidWeatherService::UUID_SERVICE_WEATHER));
if (w){
w->sendWeather(weather);
}
}

void AsteroidOSDevice::setMusicStatus(bool playing, const QString &title, const QString &artist, const QString &album, int duration, int position)
{
Q_UNUSED(duration)
Q_UNUSED(position)

AsteroidMediaService *media = qobject_cast<AsteroidMediaService*>(service(AsteroidMediaService::UUID_SERVICE_MEDIA));
if (media) {
media->setStatus(playing);
media->setAlbum(album);
media->setTrack(title);
media->setArtist(artist);
}
}

void AsteroidOSDevice::serviceEvent(const QString &characteristic, uint8_t event, uint8_t data)
{
if (characteristic == AsteroidMediaService::UUID_CHARACTERISTIC_MEDIA_COMMAND) {
switch(event) {
case AsteroidMediaService::EVENT_MEDIA_PREV:
emit deviceEvent(AbstractDevice::EVENT_MUSIC_PREV);
break;
case AsteroidMediaService::EVENT_MEDIA_NEXT:
emit deviceEvent(AbstractDevice::EVENT_MUSIC_NEXT);
break;
case AsteroidMediaService::EVENT_MEDIA_PLAY:
emit deviceEvent(AbstractDevice::EVENT_MUSIC_PLAY);
break;
case AsteroidMediaService::EVENT_MEDIA_PAUSE:
emit deviceEvent(AbstractDevice::EVENT_MUSIC_PAUSE);
break;
case AsteroidMediaService::EVENT_MEDIA_VOL:
qDebug() << Q_FUNC_INFO << "Command volume" << characteristic << event << data;
if (data < m_prevVolume) {
emit deviceEvent(AbstractDevice::EVENT_MUSIC_VOLDOWN);
} else {
emit deviceEvent(AbstractDevice::EVENT_MUSIC_VOLUP);
}
m_prevVolume = data;
AsteroidMediaService *media = qobject_cast<AsteroidMediaService*>(service(AsteroidMediaService::UUID_SERVICE_MEDIA));
if (media) {
media->setVolume(data);
}

break;


}
} else {
qDebug() << Q_FUNC_INFO << characteristic << event << data;
}

}
Loading

0 comments on commit d5e3fe6

Please sign in to comment.