summaryrefslogtreecommitdiff
path: root/fmrxproxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fmrxproxy.cpp')
-rw-r--r--fmrxproxy.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/fmrxproxy.cpp b/fmrxproxy.cpp
new file mode 100644
index 0000000..77fcfb1
--- /dev/null
+++ b/fmrxproxy.cpp
@@ -0,0 +1,148 @@
+#include "fmrxproxy.h"
+
+#include <QtDebug>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+// Cannot really use QtDbus because lack of support for FD passing, pity.
+
+#define BUS_NAME "com.javispedro.fmrxd"
+#define BUS_PATH "/com/javispedro/fmrxd"
+#define BUS_INTERFACE BUS_NAME
+
+#define BUS_MATCH_RULE "type='signal',sender='" BUS_NAME "',interface='" BUS_INTERFACE "'"
+
+FmRxProxy::FmRxProxy(QObject *parent) :
+ QObject(parent)
+{
+ GError *gerr = NULL;
+ DBusGConnection *gconn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &gerr);
+ if (!gconn) {
+ qWarning("Failed to connect to D-Bus: %s", gerr->message);
+ g_error_free(gerr);
+ }
+
+ // From dbus-glib all we want is main loop integration,
+ // the rest we use plain D-Bus.
+
+ m_conn = dbus_g_connection_get_connection(gconn);
+ dbus_bus_add_match(m_conn, BUS_MATCH_RULE, NULL);
+ dbus_connection_add_filter(m_conn, bus_message_filter, this, NULL);
+}
+
+FmRxProxy::~FmRxProxy()
+{
+ dbus_bus_remove_match(m_conn, BUS_MATCH_RULE, NULL);
+ dbus_connection_remove_filter(m_conn, bus_message_filter, this);
+}
+
+int FmRxProxy::Connect()
+{
+ DBusError err;
+ dbus_bool_t ret;
+ int fd;
+ DBusMessage *reply;
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "Connect");
+ Q_ASSERT(msg != NULL);
+
+ dbus_error_init(&err);
+
+ reply = dbus_connection_send_with_reply_and_block(m_conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ qWarning("Failed to Connect(): %s", err.message);
+ dbus_error_free(&err);
+ return -1;
+ }
+
+ ret = dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_INVALID);
+ dbus_message_unref(reply);
+
+ if (!ret) {
+ qWarning("Failed to parse Connect() reply: %s", err.message);
+ dbus_error_free(&err);
+ return -1;
+ }
+
+
+ return fd;
+}
+
+void FmRxProxy::Tune(double f)
+{
+ DBusError err;
+ DBusMessage *reply;
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "Tune");
+ Q_ASSERT(msg != NULL);
+
+ dbus_error_init(&err);
+
+ dbus_message_append_args(msg, DBUS_TYPE_DOUBLE, &f, DBUS_TYPE_INVALID);
+
+ reply = dbus_connection_send_with_reply_and_block(m_conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ qWarning("Failed to Tune(): %s", err.message);
+ dbus_error_free(&err);
+ return;
+ }
+
+ dbus_message_unref(reply);
+}
+
+void FmRxProxy::SearchForward()
+{
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "SearchForward");
+ Q_ASSERT(msg != NULL);
+
+ dbus_connection_send(m_conn, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+void FmRxProxy::SearchBackward()
+{
+ DBusMessage *msg = dbus_message_new_method_call(BUS_NAME, BUS_PATH,
+ BUS_INTERFACE, "SearchBackward");
+ Q_ASSERT(msg != NULL);
+
+ dbus_connection_send(m_conn, msg, NULL);
+ dbus_message_unref(msg);
+}
+
+DBusHandlerResult FmRxProxy::bus_message_filter(DBusConnection *,
+ DBusMessage *m, void *user_data)
+{
+ FmRxProxy *self = reinterpret_cast<FmRxProxy*>(user_data);
+ if (dbus_message_has_interface(m, BUS_INTERFACE)) {
+ if (dbus_message_is_signal(m, BUS_INTERFACE, "Tuned")) {
+ double freq;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID)) {
+ emit self->Tuned(freq);
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "Stopped")) {
+ emit self->Stopped();
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "PiReceived")) {
+ quint16 pi;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_UINT16, &pi, DBUS_TYPE_INVALID)) {
+ emit self->PiReceived(pi);
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "PsReceived")) {
+ char * s;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
+ emit self->PsReceived(QString::fromUtf8(s));
+ }
+ } else if (dbus_message_is_signal(m, BUS_INTERFACE, "RtReceived")) {
+ char * s;
+ if (dbus_message_get_args(m, NULL, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
+ emit self->RtReceived(QString::fromUtf8(s));
+ }
+ }
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}