summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--radio/RadioClient.cpp142
-rw-r--r--radio/RadioClient.h (renamed from radio/radio.h)61
-rw-r--r--radio/RadioGrpcClient.cpp213
-rw-r--r--radio/RadioGrpcClient.h67
-rw-r--r--radio/meson.build43
-rw-r--r--radio/protos/radio.proto205
-rw-r--r--radio/radio.cpp294
7 files changed, 695 insertions, 330 deletions
diff --git a/radio/RadioClient.cpp b/radio/RadioClient.cpp
new file mode 100644
index 0000000..a142d22
--- /dev/null
+++ b/radio/RadioClient.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018-2020,2022 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <QDebug>
+#include "RadioClient.h"
+#include "RadioGrpcClient.h"
+
+RadioClient::RadioClient(QQmlContext *context, QObject * parent) :
+ QObject(parent),
+ m_band(1),
+ m_frequency(0),
+ m_minFrequency(0),
+ m_maxFrequency(0),
+ m_playing(false),
+ m_scanning(false)
+{
+ m_radio = new RadioGrpcClient(this);
+
+ if (m_radio) {
+ m_radio->GetBandParameters(m_band, m_minFrequency, m_maxFrequency, m_frequencyStep);
+ emit minFrequencyChanged(m_minFrequency);
+ emit maxFrequencyChanged(m_maxFrequency);
+ emit frequencyStepChanged(m_frequencyStep);
+
+ // Handle start up
+ if (!m_frequency) {
+ m_frequency = m_minFrequency;
+ emit frequencyChanged(m_frequency);
+ }
+ }
+}
+
+RadioClient::~RadioClient()
+{
+ delete m_radio;
+}
+
+void RadioClient::setBand(int band)
+{
+ if (m_radio)
+ m_radio->SetBand(band);
+}
+
+void RadioClient::setFrequency(int frequency)
+{
+ if (!m_radio)
+ return;
+
+ m_radio->SetFrequency(frequency);
+
+ // To improve UI responsiveness, signal the change here immediately
+ // This fixes visual glitchiness in the slider caused by the frequency
+ // update event taking long enough that the QML engine gets a chance
+ // to update the slider with the current value before the event with
+ // the new value comes.
+ m_frequency = frequency;
+ emit frequencyChanged(m_frequency);
+}
+
+// control related methods
+
+void RadioClient::start()
+{
+ if (m_radio)
+ m_radio->Start();
+}
+
+void RadioClient::stop()
+{
+ if (m_radio)
+ m_radio->Stop();
+}
+
+void RadioClient::scanForward()
+{
+ if (!m_radio || m_scanning)
+ return;
+
+ m_radio->ScanForward();
+
+ m_scanning = true;
+ emit scanningChanged(m_scanning);
+}
+
+void RadioClient::scanBackward()
+{
+ if (!m_radio || m_scanning)
+ return;
+
+ m_radio->ScanBackward();
+
+ m_scanning = true;
+ emit scanningChanged(m_scanning);
+}
+
+void RadioClient::scanStop()
+{
+ if (m_radio)
+ m_radio->ScanStop();
+
+ m_scanning = false;
+ emit scanningChanged(m_scanning);
+}
+
+void RadioClient::updateBand(int band)
+{
+ m_band = band;
+ emit bandChanged(m_band);
+}
+
+void RadioClient::updateFrequency(int frequency)
+{
+ m_frequency = frequency;
+ emit frequencyChanged(m_frequency);
+}
+
+void RadioClient::updatePlaying(bool status)
+{
+ m_playing = status;
+ emit playingChanged(m_playing);
+}
+
+void RadioClient::updateScanning(int station_found)
+{
+ if (station_found && m_scanning) {
+ m_scanning = false;
+ emit scanningChanged(m_scanning);
+ }
+}
diff --git a/radio/radio.h b/radio/RadioClient.h
index cfd314c..5920442 100644
--- a/radio/radio.h
+++ b/radio/RadioClient.h
@@ -14,28 +14,30 @@
* limitations under the License.
*/
-#ifndef RADIO_H
-#define RADIO_H
+#ifndef RADIO_CLIENT_H
+#define RADIO_CLIENT_H
#include <QObject>
#include <QtQml/QQmlContext>
-class Radio : public QObject
+class RadioGrpcClient;
+
+class RadioClient : public QObject
{
- Q_OBJECT
- Q_PROPERTY(unsigned int band READ band WRITE setBand NOTIFY bandChanged)
- Q_PROPERTY(unsigned int amBand READ amBand CONSTANT)
- Q_PROPERTY(unsigned int fmBand READ fmBand CONSTANT)
- Q_PROPERTY(unsigned int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged)
- Q_PROPERTY(bool playing READ playing NOTIFY playingChanged)
- Q_PROPERTY(bool scanning READ scanning NOTIFY scanningChanged)
- Q_PROPERTY(unsigned int minFrequency READ minFrequency NOTIFY minFrequencyChanged)
- Q_PROPERTY(unsigned int maxFrequency READ maxFrequency NOTIFY maxFrequencyChanged)
- Q_PROPERTY(unsigned int frequencyStep READ frequencyStep NOTIFY frequencyStepChanged)
-
- public:
- explicit Radio(QQmlContext *context, QObject * parent = Q_NULLPTR);
- virtual ~Radio();
+ Q_OBJECT
+ Q_PROPERTY(unsigned int band READ band WRITE setBand NOTIFY bandChanged)
+ Q_PROPERTY(unsigned int amBand READ amBand CONSTANT)
+ Q_PROPERTY(unsigned int fmBand READ fmBand CONSTANT)
+ Q_PROPERTY(unsigned int frequency READ frequency WRITE setFrequency NOTIFY frequencyChanged)
+ Q_PROPERTY(bool playing READ playing NOTIFY playingChanged)
+ Q_PROPERTY(bool scanning READ scanning NOTIFY scanningChanged)
+ Q_PROPERTY(unsigned int minFrequency READ minFrequency NOTIFY minFrequencyChanged)
+ Q_PROPERTY(unsigned int maxFrequency READ maxFrequency NOTIFY maxFrequencyChanged)
+ Q_PROPERTY(unsigned int frequencyStep READ frequencyStep NOTIFY frequencyStepChanged)
+
+public:
+ explicit RadioClient(QQmlContext *context, QObject * parent = Q_NULLPTR);
+ virtual ~RadioClient();
unsigned int band() const { return m_band; }
void setBand(int band);
@@ -61,7 +63,13 @@ class Radio : public QObject
Q_INVOKABLE void scanBackward();
Q_INVOKABLE void scanStop();
- signals:
+public slots:
+ void updateBand(int band);
+ void updateFrequency(int frequency);
+ void updatePlaying(bool status);
+ void updateScanning(int station_found);
+
+signals:
void bandChanged(int band);
void frequencyChanged(int frequency);
void playingChanged(bool status);
@@ -70,9 +78,11 @@ class Radio : public QObject
void maxFrequencyChanged(int maxFrequency);
void frequencyStepChanged(int frequencyStep);
- private:
+private:
QQmlContext *m_context;
+ RadioGrpcClient *m_radio;
+
unsigned int m_band;
unsigned int m_frequency;
unsigned int m_minFrequency;
@@ -80,19 +90,6 @@ class Radio : public QObject
unsigned int m_frequencyStep;
bool m_playing;
bool m_scanning;
-
- void updateFrequencyBandParameters();
-#if 0
- void onConnected();
- void onDisconnected();
- void onMessageReceived(std::shared_ptr<Message> msg);
-
- const QStringList events {
- "frequency",
- "station_found",
- "status",
- };
-#endif
};
#endif // RADIO_H
diff --git a/radio/RadioGrpcClient.cpp b/radio/RadioGrpcClient.cpp
new file mode 100644
index 0000000..3795d1d
--- /dev/null
+++ b/radio/RadioGrpcClient.cpp
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+ * Copyright (C) 2023 Konsulko Group
+ */
+
+#include <QDebug>
+#include "RadioGrpcClient.h"
+#include "RadioClient.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::ClientReader;
+using grpc::Status;
+
+using automotivegradelinux::Radio;
+using automotivegradelinux::SetBandRequest;
+using automotivegradelinux::SetBandResponse;
+using automotivegradelinux::SetFrequencyRequest;
+using automotivegradelinux::SetFrequencyResponse;
+using automotivegradelinux::StartRequest;
+using automotivegradelinux::StartResponse;
+using automotivegradelinux::StopRequest;
+using automotivegradelinux::StopResponse;
+using automotivegradelinux::ScanStartRequest;
+using automotivegradelinux::ScanStartResponse;
+using automotivegradelinux::ScanStopRequest;
+using automotivegradelinux::ScanStopResponse;
+using automotivegradelinux::GetBandParametersRequest;
+using automotivegradelinux::GetBandParametersResponse;
+using automotivegradelinux::StatusRequest;
+using automotivegradelinux::StatusResponse;
+using automotivegradelinux::BandStatus;
+using automotivegradelinux::FrequencyStatus;
+using automotivegradelinux::PlayStatus;
+using automotivegradelinux::ScanStatus;
+
+// Enum values used
+using automotivegradelinux::BAND_AM;
+using automotivegradelinux::BAND_FM;
+using automotivegradelinux::SCAN_DIRECTION_FORWARD;
+using automotivegradelinux::SCAN_DIRECTION_BACKWARD;
+
+void RadioStatusEventReader::GetStatusEvents()
+{
+ ClientContext context;
+ StatusRequest request;
+ StatusResponse response;
+
+ std::unique_ptr<ClientReader<StatusResponse> > reader(stub_->GetStatusEvents(&context, request));
+ while (reader->Read(&response)) {
+ if (response.has_band()) {
+ BandStatus band_status = response.band();
+ unsigned int band;
+ if (band_status.band() == BAND_AM)
+ band = 0;
+ else if (band_status.band() == BAND_FM)
+ band = 1;
+ else
+ continue;
+ emit bandUpdate(band);
+ } else if (response.has_frequency()) {
+ FrequencyStatus frequency_status = response.frequency();
+ emit frequencyUpdate(frequency_status.frequency());
+ } else if (response.has_play()) {
+ PlayStatus play_status = response.play();
+ emit playingUpdate(play_status.playing());
+ } else if (response.has_scan()) {
+ ScanStatus scan_status = response.scan();
+ emit scanningUpdate(scan_status.station_found());
+ }
+ }
+ Status status = reader->Finish();
+ if (!status.ok()) {
+ qWarning() << "GetStatusEvents RPC failed";
+ }
+
+ emit finished();
+}
+
+
+RadioGrpcClient::RadioGrpcClient(QObject *parent) : QObject(parent)
+{
+ stub_ = Radio::NewStub(grpc::CreateChannel("localhost:50053", grpc::InsecureChannelCredentials()));
+
+ // Create thread to read status events
+ RadioStatusEventReader *reader = new RadioStatusEventReader(stub_);
+ reader->moveToThread(&m_event_thread);
+ connect(&m_event_thread, &QThread::started, reader, &RadioStatusEventReader::GetStatusEvents);
+ connect(reader, &RadioStatusEventReader::finished, &m_event_thread, &QThread::quit);
+ // FIXME: Normally the thread finishing would be connected per the below
+ // to trigger cleaning up the object. That seems to trigger a crash
+ // for not entirely obvious reasons. It seems unrelated to the signal
+ // connection to AppLauncherClient, as not connecting does not prevent
+ // the crash; further investigation is required.
+ //connect(reader, &RadioStatusEventReader::finished, reader, &RadioStatusEventReader::deleteLater);
+ //connect(&m_event_thread, &QThread::finished, &m_event_thread, &QThread::deleteLater);
+
+ // To avoid having intermediary slot+signal's in this class, try
+ // casting parent to Radio and connect directly to its slot.
+ // Callers should set parent to ensure this works as required.
+ if (parent) {
+ RadioClient *radio = qobject_cast<RadioClient*>(parent);
+ if (radio) {
+ connect(reader,
+ &RadioStatusEventReader::bandUpdate,
+ radio,
+ &RadioClient::updateBand);
+ connect(reader,
+ &RadioStatusEventReader::frequencyUpdate,
+ radio,
+ &RadioClient::updateFrequency);
+ connect(reader,
+ &RadioStatusEventReader::playingUpdate,
+ radio,
+ &RadioClient::updatePlaying);
+ connect(reader,
+ &RadioStatusEventReader::scanningUpdate,
+ radio,
+ &RadioClient::updateScanning);
+ }
+ }
+
+ // Start status event handling
+ m_event_thread.start();
+}
+
+void RadioGrpcClient::SetBand(unsigned int band)
+{
+ SetBandRequest request;
+
+ ClientContext context;
+ SetBandResponse response;
+ if (band)
+ request.set_band(BAND_FM);
+ else
+ request.set_band(BAND_AM);
+ Status status = stub_->SetBand(&context, request, &response);
+}
+
+void RadioGrpcClient::SetFrequency(unsigned int frequency)
+{
+ SetFrequencyRequest request;
+
+ ClientContext context;
+ SetFrequencyResponse response;
+ request.set_frequency(frequency);
+ Status status = stub_->SetFrequency(&context, request, &response);
+}
+
+void RadioGrpcClient::Start()
+{
+ StartRequest request;
+
+ ClientContext context;
+ StartResponse response;
+ Status status = stub_->Start(&context, request, &response);
+}
+
+void RadioGrpcClient::Stop()
+{
+ StopRequest request;
+
+ ClientContext context;
+ StopResponse response;
+ Status status = stub_->Stop(&context, request, &response);
+}
+
+void RadioGrpcClient::ScanForward()
+{
+ ScanStartRequest request;
+
+ ClientContext context;
+ ScanStartResponse response;
+ request.set_direction(SCAN_DIRECTION_FORWARD);
+ Status status = stub_->ScanStart(&context, request, &response);
+}
+
+void RadioGrpcClient::ScanBackward()
+{
+ ScanStartRequest request;
+
+ ClientContext context;
+ ScanStartResponse response;
+ request.set_direction(SCAN_DIRECTION_BACKWARD);
+ Status status = stub_->ScanStart(&context, request, &response);
+}
+
+void RadioGrpcClient::ScanStop()
+{
+ ScanStopRequest request;
+
+ ClientContext context;
+ ScanStopResponse response;
+ Status status = stub_->ScanStop(&context, request, &response);
+}
+
+void RadioGrpcClient::GetBandParameters(unsigned int band, unsigned int &min, unsigned int &max, unsigned int &step)
+{
+ GetBandParametersRequest request;
+
+ ClientContext context;
+ GetBandParametersResponse response;
+ if (band)
+ request.set_band(BAND_FM);
+ else
+ request.set_band(BAND_AM);
+ Status status = stub_->GetBandParameters(&context, request, &response);
+ if (status.ok()) {
+ min = response.min();
+ max = response.max();
+ step = response.step();
+ }
+}
diff --git a/radio/RadioGrpcClient.h b/radio/RadioGrpcClient.h
new file mode 100644
index 0000000..603253a
--- /dev/null
+++ b/radio/RadioGrpcClient.h
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+ * Copyright (C) 2023 Konsulko Group
+ */
+
+#ifndef RADIO_GRPC_CLIENT_H
+#define RADIO_GRPC_CLIENT_H
+
+#include <QObject>
+#include <QList>
+#include <QMap>
+#include <QThread>
+#include <grpcpp/grpcpp.h>
+
+#include "radio.grpc.pb.h"
+
+using grpc::Channel;
+
+class RadioStatusEventReader : public QObject
+{
+ Q_OBJECT
+public:
+ RadioStatusEventReader(std::shared_ptr<automotivegradelinux::Radio::Stub> &stub,
+ QObject *parent = Q_NULLPTR) : QObject(parent), stub_(stub) {}
+
+public slots:
+ void GetStatusEvents();
+
+signals:
+ void bandUpdate(int band);
+ void frequencyUpdate(int frequency);
+ void playingUpdate(bool status);
+ void scanningUpdate(bool scanning);
+
+ void finished();
+
+private:
+ std::shared_ptr<automotivegradelinux::Radio::Stub> stub_;
+};
+
+class RadioGrpcClient : public QObject
+{
+ Q_OBJECT
+
+public:
+ RadioGrpcClient(QObject *parent = Q_NULLPTR);
+
+ void SetBand(unsigned int band);
+ void SetFrequency(unsigned int frequency);
+ void Start();
+ void Stop();
+ void ScanForward();
+ void ScanBackward();
+ void ScanStop();
+ void GetBandParameters(unsigned int band,
+ unsigned int &min,
+ unsigned int &max,
+ unsigned int &step);
+
+private:
+ std::shared_ptr<automotivegradelinux::Radio::Stub> stub_;
+
+ QThread m_event_thread;
+
+};
+
+#endif // RADIO_GRPC_CLIENT_H
diff --git a/radio/meson.build b/radio/meson.build
index c8218a3..7ae1bac 100644
--- a/radio/meson.build
+++ b/radio/meson.build
@@ -1,17 +1,52 @@
+cpp = meson.get_compiler('cpp')
+grpcpp_reflection_dep = cpp.find_library('grpc++_reflection')
+
qt5_dep = dependency('qt5', modules: ['Qml'])
+radio_dep = [
+ qt5_dep,
+ dependency('protobuf'),
+ dependency('grpc'),
+ dependency('grpc++'),
+ grpcpp_reflection_dep,
+]
+
+protoc = find_program('protoc')
+grpc_cpp = find_program('grpc_cpp_plugin')
+
+protoc_gen = generator(protoc, \
+ output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'],
+ arguments : ['--proto_path=@CURRENT_SOURCE_DIR@/protos',
+ '--cpp_out=@BUILD_DIR@',
+ '@INPUT@'])
+generated_protoc_sources = protoc_gen.process('protos/radio.proto')
-moc_files = qt5.compile_moc(headers: 'radio.h',
+grpc_gen = generator(protoc, \
+ output : ['@BASENAME@.grpc.pb.cc', '@BASENAME@.grpc.pb.h'],
+ arguments : ['--proto_path=@CURRENT_SOURCE_DIR@/protos',
+ '--grpc_out=@BUILD_DIR@',
+ '--plugin=protoc-gen-grpc=' + grpc_cpp.path(),
+ '@INPUT@'])
+generated_grpc_sources = grpc_gen.process('protos/radio.proto')
+
+moc_files = qt5.compile_moc(headers: ['RadioClient.h', 'RadioGrpcClient.h'],
dependencies: qt5_dep)
-src = ['radio.cpp', moc_files]
+src = [
+ 'RadioClient.cpp',
+ 'RadioGrpcClient.cpp',
+ generated_protoc_sources,
+ generated_grpc_sources,
+ moc_files
+]
+
lib = shared_library('qtappfw-radio',
sources: src,
version: '1.0.0',
soversion: '0',
- dependencies: qt5_dep,
+ dependencies: radio_dep,
install: true)
-install_headers('radio.h')
+install_headers('RadioClient.h')
pkg_mod = import('pkgconfig')
pkg_mod.generate(libraries : lib,
diff --git a/radio/protos/radio.proto b/radio/protos/radio.proto
new file mode 100644
index 0000000..60afc45
--- /dev/null
+++ b/radio/protos/radio.proto
@@ -0,0 +1,205 @@
+syntax = "proto3";
+
+package automotivegradelinux;
+
+service Radio {
+ rpc GetFrequency(GetFrequencyRequest) returns (GetFrequencyResponse) {}
+ rpc SetFrequency(SetFrequencyRequest) returns (SetFrequencyResponse) {}
+
+ rpc GetBand(GetBandRequest) returns (GetBandResponse) {}
+ rpc SetBand(SetBandRequest) returns (SetBandResponse) {}
+
+ rpc GetBandSupported(GetBandSupportedRequest) returns (GetBandSupportedResponse) {}
+ rpc GetBandParameters(GetBandParametersRequest) returns (GetBandParametersResponse) {}
+
+ rpc GetStereoMode(GetStereoModeRequest) returns (GetStereoModeResponse) {}
+ rpc SetStereoMode(SetStereoModeRequest) returns (SetStereoModeResponse) {}
+
+ rpc Start(StartRequest) returns (StartResponse) {}
+ rpc Stop(StopRequest) returns (StopResponse) {}
+
+ rpc ScanStart(ScanStartRequest) returns (ScanStartResponse) {}
+ rpc ScanStop(ScanStopRequest) returns (ScanStopResponse) {}
+
+ rpc GetRDS(GetRDSRequest) returns (GetRDSResponse) {}
+
+ rpc GetQuality(GetQualityRequest) returns (GetQualityResponse) {}
+
+ rpc SetAlternativeFrequency(SetAlternativeFrequencyRequest) returns (SetAlternativeFrequencyResponse) {}
+
+ rpc GetStatusEvents(StatusRequest) returns (stream StatusResponse) {}
+}
+
+message GetFrequencyRequest {
+}
+
+message GetFrequencyResponse {
+ uint32 frequency = 1;
+}
+
+message SetFrequencyRequest {
+ uint32 frequency = 1;
+}
+
+message SetFrequencyResponse {
+ uint32 frequency = 1;
+}
+
+message GetBandRequest {
+}
+
+enum Band {
+ BAND_UNSPECIFIED = 0;
+ BAND_AM = 1;
+ BAND_FM = 2;
+ BAND_DBS = 3;
+}
+
+message GetBandResponse {
+ Band band = 1;
+}
+
+message SetBandRequest {
+ Band band = 1;
+}
+
+message SetBandResponse {
+ Band band = 1;
+}
+
+message GetBandSupportedRequest {
+ Band band = 1;
+}
+
+message GetBandSupportedResponse {
+ bool supported = 1;
+}
+
+message GetBandParametersRequest {
+ Band band = 1;
+}
+
+message GetBandParametersResponse {
+ uint32 min = 1;
+ uint32 max = 2;
+ uint32 step = 3;
+}
+
+enum StereoMode {
+ STEREO_MODE_UNSPECIFIED = 0;
+ STEREO_MODE_MONO = 1;
+ STEREO_MODE_STEREO = 2;
+}
+
+message GetStereoModeRequest {
+}
+
+message GetStereoModeResponse {
+ StereoMode mode = 1;
+}
+
+message SetStereoModeRequest {
+ StereoMode mode = 1;
+}
+
+message SetStereoModeResponse {
+ StereoMode mode = 1;
+}
+
+message StartRequest {
+}
+
+message StartResponse {
+}
+
+message StopRequest {
+}
+
+message StopResponse {
+}
+
+enum ScanDirection {
+ SCAN_DIRECTION_UNSPECIFIED = 0;
+ SCAN_DIRECTION_FORWARD = 1;
+ SCAN_DIRECTION_BACKWARD = 2;
+}
+
+message ScanStartRequest {
+ ScanDirection direction = 1;
+}
+
+message ScanStartResponse {
+}
+
+message ScanStopRequest {
+}
+
+message ScanStopResponse {
+}
+
+message GetRDSRequest {
+}
+
+// NOTE: This is a placeholder and will be revised!
+message GetRDSResponse {
+ string name = 1;
+ string radio_text = 2;
+ string alternatives = 3;
+ string minute = 4;
+ string hour = 5;
+ string day = 6;
+ string month = 7;
+ string year = 8;
+ string pi = 9;
+ string pty = 10;
+ string ta = 11;
+ string tp = 12;
+ string ms = 13;
+}
+
+message GetQualityRequest {
+}
+
+message GetQualityResponse {
+}
+
+message SetAlternativeFrequencyRequest {
+ uint32 frequency = 1;
+}
+
+message SetAlternativeFrequencyResponse {
+ uint32 frequency = 1;
+}
+
+message StatusRequest {
+}
+
+message BandStatus {
+ Band band = 1;
+}
+
+message FrequencyStatus {
+ uint32 frequency = 1;
+}
+
+message PlayStatus {
+ bool playing = 1;
+}
+
+message ScanStatus {
+ bool station_found = 1;
+}
+
+message StereoStatus {
+ StereoMode mode = 1;
+}
+
+message StatusResponse {
+ oneof status {
+ BandStatus band = 1;
+ FrequencyStatus frequency = 2;
+ PlayStatus play = 3;
+ StereoStatus stereo = 4;
+ ScanStatus scan = 5;
+ }
+}
diff --git a/radio/radio.cpp b/radio/radio.cpp
deleted file mode 100644
index efe8e78..0000000
--- a/radio/radio.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2018-2020,2022 Konsulko Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <QDebug>
-#include "radio.h"
-
-
-Radio::Radio(QQmlContext *context, QObject * parent) :
- QObject(parent),
- m_band(1),
- m_frequency(0),
- m_minFrequency(0),
- m_maxFrequency(0),
- m_playing(false),
- m_scanning(false)
-{
-#if 0
- m_mloop = MessageEngineFactory::getInstance().getMessageEngine(url);
- m_context = context;
-
- QObject::connect(m_mloop.get(), &MessageEngine::connected, this, &Radio::onConnected);
- QObject::connect(m_mloop.get(), &MessageEngine::disconnected, this, &Radio::onDisconnected);
- QObject::connect(m_mloop.get(), &MessageEngine::messageReceived, this, &Radio::onMessageReceived);
-#endif
-}
-
-Radio::~Radio()
-{
-}
-
-void Radio::setBand(int band)
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
-
- parameter.insert("band", band ? "FM": "AM");
- rmsg->createRequest("radio", "band", parameter);
- m_mloop->sendMessage(std::move(msg));
-#endif
-}
-
-void Radio::setFrequency(int frequency)
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
-
- if (m_scanning)
- scanStop();
-
- if (frequency == m_frequency)
- return;
-
- parameter.insert("value", QString::number(frequency));
- rmsg->createRequest("radio", "frequency", parameter);
- m_mloop->sendMessage(std::move(msg));
-
- // To improve UI responsiveness, signal the change here immediately
- // This fixes visual glitchiness in the slider caused by the frequency
- // update event taking long enough that the QML engine gets a chance
- // to update the slider with the current value before the event with
- // the new value comes.
- m_frequency = frequency;
- emit frequencyChanged(m_frequency);
-#endif
-}
-
-// control related methods
-
-void Radio::start()
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
-
- rmsg->createRequest("radio", "start", parameter);
- m_mloop->sendMessage(std::move(msg));
-#endif
-}
-
-void Radio::stop()
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- rmsg->createRequest("radio", "stop", parameter);
- m_mloop->sendMessage(std::move(msg));
-#endif
-}
-
-void Radio::scanForward()
-{
- if (m_scanning)
- return;
-
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- parameter.insert("direction", "forward");
- rmsg->createRequest("radio", "scan_start", parameter);
- m_mloop->sendMessage(std::move(msg));
-
- m_scanning = true;
- emit scanningChanged(m_scanning);
-#endif
-}
-
-void Radio::scanBackward()
-{
- if (m_scanning)
- return;
-
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- parameter.insert("direction", "backward");
- rmsg->createRequest("radio", "scan_start", parameter);
- m_mloop->sendMessage(std::move(msg));
-
- m_scanning = true;
- emit scanningChanged(m_scanning);
-#endif
-}
-
-void Radio::scanStop()
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- rmsg->createRequest("radio", "scan_stop", parameter);
- m_mloop->sendMessage(std::move(msg));
-
- m_scanning = false;
- emit scanningChanged(m_scanning);
-#endif
-}
-
-void Radio::updateFrequencyBandParameters()
-{
-#if 0
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- parameter.insert("band", m_band ? "FM" : "AM");
- rmsg->createRequest("radio", "frequency_range", parameter);
- m_mloop->sendMessage(std::move(msg));
-
- std::unique_ptr<Message> msg2 = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg2)
- return;
-
- rmsg = static_cast<CallMessage*>(msg2.get());
- rmsg->createRequest("radio", "frequency_step", parameter);
- m_mloop->sendMessage(std::move(msg2));
-#endif
-}
-
-#if 0
-void Radio::onConnected()
-{
- QStringListIterator eventIterator(events);
-
- while (eventIterator.hasNext()) {
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- parameter.insert("value", eventIterator.next());
- rmsg->createRequest("radio", "subscribe", parameter);
- m_mloop->sendMessage(std::move(msg));
- }
-
- // Trigger initial update of frequency band parameters (min/max/step)
- updateFrequencyBandParameters();
-}
-
-void Radio::onDisconnected()
-{
- QStringListIterator eventIterator(events);
-
- while (eventIterator.hasNext()) {
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* rmsg = static_cast<CallMessage*>(msg.get());
- QJsonObject parameter;
- parameter.insert("value", eventIterator.next());
- rmsg->createRequest("radio", "unsubscribe", parameter);
- m_mloop->sendMessage(std::move(msg));
- }
-}
-
-void Radio::onMessageReceived(std::shared_ptr<Message> msg)
-{
- if (!msg)
- return;
-
- if (msg->isEvent()) {
- std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
- QString ename = emsg->eventName();
- QString eapi = emsg->eventApi();
- QJsonObject data = emsg->eventData();
- if (ename == "frequency") {
- unsigned int frequency = data.value("value").toInt();
- m_frequency = frequency;
- if (!m_scanning && (m_frequency != frequency)) {
- emit frequencyChanged(m_frequency);
- }
- } else if (ename == "station_found") {
- m_scanning = false;
- emit scanningChanged(m_scanning);
-
- m_frequency = data.value("value").toInt();
- emit frequencyChanged(m_frequency);
- } else if (ename == "status") {
- if (data.value("value") == QString("playing")) {
- m_playing = true;
- emit playingChanged(m_playing);
- } else if (data.value("value") == QString("stopped")) {
- m_playing = false;
- emit playingChanged(m_playing);
- }
- }
- } else if (msg->isReply()) {
- std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
- QString api = rmsg->requestApi();
- if (api != "radio")
- return;
-
- QString verb = rmsg->requestVerb();
- QJsonObject data = rmsg->replyData();
- if (verb == "frequency_range") {
- m_minFrequency = data.value("min").toInt();
- emit minFrequencyChanged(m_minFrequency);
- m_maxFrequency = data.value("max").toInt();
- emit maxFrequencyChanged(m_maxFrequency);
-
- // Handle start up
- if (!m_frequency) {
- m_frequency = m_minFrequency;
- emit frequencyChanged(m_frequency);
- }
- } else if (verb == "frequency_step") {
- m_frequencyStep = data.value("step").toInt();
- emit frequencyStepChanged(m_frequencyStep);
- }
- }
-}
-#endif