diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt
index e2108b0..3d1e131 100644
--- a/res/CMakeLists.txt
+++ b/res/CMakeLists.txt
@@ -2,10 +2,11 @@
########### install files ###############
execute_process(
- COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=session_bus_services_dir dbus-1
- OUTPUT_VARIABLE DBUS_SESSION_SERVICES_DIR
+ COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=system_bus_services_dir dbus-1
+ OUTPUT_VARIABLE DBUS_SYSTEM_SERVICES_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
+
execute_process(
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=systemdsystemunitdir systemd
OUTPUT_VARIABLE SYSTEMD_SYSTEM_UNIT_DIR
diff --git a/res/org.freedesktop.miracle.conf b/res/org.freedesktop.miracle.conf
index dee41ad..5337aa8 100644
--- a/res/org.freedesktop.miracle.conf
+++ b/res/org.freedesktop.miracle.conf
@@ -11,10 +11,13 @@
+
+
+
diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt
index 082c246..87f561a 100644
--- a/src/ctl/CMakeLists.txt
+++ b/src/ctl/CMakeLists.txt
@@ -1,3 +1,4 @@
+# vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab :
find_package(Readline)
########### next target ###############
@@ -78,6 +79,33 @@ target_link_libraries(miracle-srcctl miracle-shared
sender-iface
${GIO_LIBRARIES})
+########### next target ###############
+set(miracle-wfdctl_SRCS ctl.h
+ ctl-cli.c
+ ctl-src.h
+ ctl-src.c
+ ctl-wifi.c
+ wfdctl.c
+ wfd.c)
+
+include_directories(${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/src
+ ${CMAKE_SOURCE_DIR}/src/shared)
+
+add_executable(miracle-wfdctl ${miracle-wfdctl_SRCS})
+
+install(TARGETS miracle-wfdctl DESTINATION bin)
+
+if(READLINE_FOUND)
+ message(STATUS "Compiling with Readline support")
+ set_property(TARGET miracle-wfdctl
+ APPEND
+ PROPERTY COMPILE_DEFINITIONS HAVE_READLINE)
+ target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY})
+endif(READLINE_FOUND)
+
+target_link_libraries(miracle-wfdctl miracle-shared)
+
########### install files ###############
@@ -116,3 +144,4 @@ target_link_libraries(miracle-srcctl miracle-shared
# $(DEPS_LIBS)
#
#
+
diff --git a/src/ctl/wfdctl.c b/src/ctl/wfdctl.c
new file mode 100644
index 0000000..8c2f866
--- /dev/null
+++ b/src/ctl/wfdctl.c
@@ -0,0 +1,424 @@
+/*
+ * MiracleCast - Wifi-Display/Miracast Implementation
+ *
+ * Copyright (c) 2013-2014 David Herrmann
+ *
+ * MiracleCast is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * MiracleCast 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with MiracleCast; If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ctl.h"
+#include "wfd.h"
+#include "shl_macro.h"
+#include "shl_util.h"
+#include "config.h"
+
+struct ctl_wfd
+{
+ sd_event *loop;
+ sd_bus *bus;
+ struct ctl_wifi *wifi;
+ struct ctl_src *src;
+};
+
+static struct ctl_wfd *ctl_wfd;
+
+void ctl_wfd_free(struct ctl_wfd *wfd);
+
+int ctl_wfd_new(struct ctl_wfd **out)
+{
+ int r;
+ struct ctl_wfd *wfd = calloc(1, sizeof(struct ctl_wfd));
+ if(!wfd) {
+ r = -ENOMEM;
+ goto end;
+ }
+
+ r = sd_event_default(&wfd->loop);
+ if(0 > r) {
+ goto free_wfd;
+ }
+
+ r = sd_bus_default_system(&wfd->bus);
+ if (r < 0) {
+ goto free_wfd;
+ }
+
+ *out = wfd;
+
+ r = 0;
+
+ goto end;
+
+free_wfd:
+ ctl_wfd_free(wfd);
+end:
+ return r;
+}
+
+void ctl_wfd_free(struct ctl_wfd *wfd)
+{
+ if(wfd->bus) {
+ sd_bus_unref(wfd->bus);
+ }
+
+ free(wfd);
+}
+
+int ctl_wfd_run(struct ctl_wfd *wfd)
+{
+ return sd_event_loop(wfd->loop);
+}
+
+/* Callbacks from ctl-src */
+void ctl_fn_src_connected(struct ctl_src *s)
+{
+}
+
+void ctl_fn_src_disconnected(struct ctl_src *s)
+{
+}
+
+void ctl_fn_src_setup(struct ctl_src *s)
+{
+}
+
+void ctl_fn_src_playing(struct ctl_src *s)
+{
+}
+
+void ctl_fn_peer_new(struct ctl_peer *p)
+{
+}
+
+void ctl_fn_peer_free(struct ctl_peer *p)
+{
+}
+
+void ctl_fn_peer_provision_discovery(struct ctl_peer *p,
+ const char *prov,
+ const char *pin)
+{
+}
+
+void ctl_fn_peer_go_neg_request(struct ctl_peer *p,
+ const char *prov,
+ const char *pin)
+{
+}
+
+void ctl_fn_peer_formation_failure(struct ctl_peer *p, const char *reason)
+{
+}
+
+void ctl_fn_peer_connected(struct ctl_peer *p)
+{
+}
+
+void ctl_fn_peer_disconnected(struct ctl_peer *p)
+{
+}
+
+void ctl_fn_link_new(struct ctl_link *l)
+{
+}
+
+void ctl_fn_link_free(struct ctl_link *l)
+{
+}
+
+void cli_fn_help()
+{
+}
+
+static int ctl_wfd_enum(sd_bus *bus,
+ const char *path,
+ void *userdata,
+ char ***out,
+ sd_bus_error *out_error)
+{
+ int r = 0, i = 0;
+ char **nodes;
+
+ if(strcmp("/org/freedesktop/miracle/wfd", path)) {
+ return 0;
+ }
+
+ nodes = malloc(sizeof(char *) * 3);
+ if(!nodes) {
+ r = -ENOMEM;
+ goto end;
+ }
+
+ nodes[i] = strdup("/org/freedesktop/miracle/wfd/sink");
+ if(!nodes[i ++]) {
+ r = -ENOMEM;
+ goto end;
+ }
+
+ nodes[i] = strdup("/org/freedesktop/miracle/wfd/session");
+ if(!nodes[i ++]) {
+ r = -ENOMEM;
+ goto end;
+ }
+
+ nodes[i ++] = NULL;
+ *out = nodes;
+
+ return 0;
+
+free_nodes:
+ while(i --) {
+ free(nodes[i]);
+ }
+ free(nodes);
+end:
+ return r;
+}
+
+static int ctl_wfd_find_sink(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ void *userdata,
+ void **ret_found,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_find_session(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ void *userdata,
+ void **ret_found,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_start_session(sd_bus_message *m,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_get_audio_formats(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_get_video_formats(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_has_video(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_get_peer(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_sink_has_audio(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_session_end(sd_bus_message *m,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_session_get_sink(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static int ctl_wfd_session_get_state(sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *ret_error)
+{
+ return 0;
+}
+
+static const sd_bus_vtable ctl_wfd_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_VTABLE_END,
+};
+
+static const sd_bus_vtable ctl_wfd_sink_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("StartSession", NULL, "o", ctl_wfd_sink_start_session, 0),
+ SD_BUS_PROPERTY("AudioFormats", "a{sv}", ctl_wfd_sink_get_audio_formats, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("VideoFormats", "a{sv}", ctl_wfd_sink_get_video_formats, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HasAudio", "b", ctl_wfd_sink_has_audio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("HasVideo", "b", ctl_wfd_sink_has_video, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Peer", "o", ctl_wfd_sink_get_peer, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_VTABLE_END,
+};
+
+static const sd_bus_vtable ctl_wfd_session_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("End", NULL, NULL, ctl_wfd_session_end, 0),
+ SD_BUS_PROPERTY("Sink", "o", ctl_wfd_session_get_sink, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("State", "i", ctl_wfd_session_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_VTABLE_END,
+};
+
+int ctl_wfd_expose(struct ctl_wfd *wfd)
+{
+ int r;
+
+ r = sd_bus_add_object_vtable(wfd->bus,
+ NULL,
+ "/org/freedesktop/miracle/wfd",
+ "org.freedesktop.miracle.wfd.Display",
+ ctl_wfd_vtable,
+ NULL);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_add_fallback_vtable(wfd->bus,
+ NULL,
+ "/org/freedesktop/miracle/wfd/sink",
+ "org.freedesktop.miracle.wfd.Sink",
+ ctl_wfd_sink_vtable,
+ ctl_wfd_find_sink,
+ NULL);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_add_fallback_vtable(wfd->bus,
+ NULL,
+ "/org/freedesktop/miracle/wfd/session",
+ "org.freedesktop.miracle.wfd.Session",
+ ctl_wfd_session_vtable,
+ ctl_wfd_find_session,
+ NULL);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_add_node_enumerator(wfd->bus,
+ NULL,
+ "/org/freedesktop/miracle/wfd",
+ ctl_wfd_enum,
+ NULL);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_add_object_manager(wfd->bus, NULL, "/org/freedesktop/miracle/wfd");
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_attach_event(wfd->bus, wfd->loop, SD_EVENT_PRIORITY_NORMAL);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = sd_bus_request_name(wfd->bus, "org.freedesktop.miracle.wfd", 0);
+
+end:
+ return r;
+}
+
+int main(int argc, char **argv)
+{
+ int r;
+
+ setlocale(LC_ALL, "");
+
+ r = ctl_wfd_new(&ctl_wfd);
+ if(0 > r) {
+ goto end;
+ }
+
+ r = ctl_wfd_expose(ctl_wfd);
+ if(0 > r) {
+ goto free_wfd;
+ }
+
+ r = ctl_wfd_run(ctl_wfd);
+
+free_wfd:
+ ctl_wfd_free(ctl_wfd);
+end:
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+/* vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab : */