From 72fee8ea0e247333dba78f6a4a88b20856cd667d Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 24 Jan 2016 20:56:06 +0100 Subject: [PATCH 001/142] Debug hardware tester --- res/test-hardware-capabilities.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/res/test-hardware-capabilities.sh b/res/test-hardware-capabilities.sh index 15a0cbf..f3bab45 100755 --- a/res/test-hardware-capabilities.sh +++ b/res/test-hardware-capabilities.sh @@ -1,5 +1,17 @@ #!/bin/bash +eval SCRIPT_DEBUG="\$$(basename $0 .sh | tr - _)_DEBUG" +SCRIPT_DEBUG=${SCRIPT_DEBUG:--1} + +if [ "$SCRIPT_DEBUG" -ge 1 ] +then + set -x +fi +if [ "$SCRIPT_DEBUG" -ge 10 ] +then + set -v +fi + . miracle-utils.sh WIFI_NAMES=$(find_wireless_network_interfaces) From ce1cbba7d588d6023da3d7c9ea833982dde8e089 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 24 Jan 2016 23:33:09 +0100 Subject: [PATCH 002/142] Add continuous integration --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7b1448..99941cd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # MiracleCast - Wifi-Display/Miracast Implementation [![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://semaphoreci.com/api/v1/projects/5ece4a7a-365b-4f7c-bfcc-6dcdece7002f/671892/badge.svg)](https://semaphoreci.com/albfan/miraclecast) The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. From 1cbfa5b42a9dcdce04e8c7b5267367f82611b327 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 20 Feb 2016 11:06:45 +0100 Subject: [PATCH 003/142] Fix hardware tester when no devices available --- res/miracle-utils.sh | 8 +++++++- res/test-hardware-capabilities.sh | 10 +++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index e77fff0..12186c5 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -52,7 +52,7 @@ function find_wireless_connected_network_interfaces { # function find_physical_for_network_interface { PHY_INDEX=$(iw dev $1 info | grep wiphy | awk '{print $2}') - if [ -n $PHY_INDEX ] + if [ -n "$PHY_INDEX" ] then echo phy$PHY_INDEX fi @@ -65,6 +65,12 @@ function search_p2p_capabilities { WI_DEVICE=$1 PHY_DEVICE=$(find_physical_for_network_interface $WI_DEVICE) + if [ -z "$PHY_DEVICE" ] + then + echo "cannot find physical device for $WI_DEVICE" + return + fi + if iw phy $PHY_DEVICE info | grep -Pzo "(?s)Supported interface modes.*Supported commands" | grep "P2P" &> /dev/null then echo $WI_DEVICE supports P2P diff --git a/res/test-hardware-capabilities.sh b/res/test-hardware-capabilities.sh index f3bab45..1e227f5 100755 --- a/res/test-hardware-capabilities.sh +++ b/res/test-hardware-capabilities.sh @@ -14,12 +14,16 @@ fi . miracle-utils.sh -WIFI_NAMES=$(find_wireless_network_interfaces) -WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l) +WIFI_COUNT=0 +WIFI_NAMES="$(find_wireless_network_interfaces)" +if [ -n "$WIFI_NAMES" ] +then + WIFI_COUNT=$(echo "$WIFI_NAMES" | wc -l) +fi if [ 0 = $WIFI_COUNT ] then - echo There is no wireless devices avaliable + echo There is no wireless devices available exit 1 elif [ 1 = $WIFI_COUNT ] then From c94be167c85c6ec8badd7ac79e3dea2e0b73225c Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 2 Apr 2016 13:15:38 +0200 Subject: [PATCH 004/142] open UIBC connection relates to #57 --- src/ctl/ctl-sink.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index c4ba423..3a5cf5d 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -43,6 +43,7 @@ struct ctl_sink { char *target; char *session; char *url; + char *uibc_setting; struct sockaddr_storage addr; size_t addr_size; int fd; @@ -60,7 +61,8 @@ struct ctl_sink { int hres; int vres; }; - +static const int DEFAULT_UIBC_PORT = 7239; +static const int DEFAULT_RSTP_PORT = 1991; /* * RTSP Session */ @@ -154,12 +156,26 @@ static void sink_handle_get_parameter(struct ctl_sink *s, } /* wfd_client_rtp_ports */ if (rtsp_message_read(m, "{<>}", "wfd_client_rtp_ports") >= 0) { + char wfd_client_rtp_ports[128]; + sprintf(wfd_client_rtp_ports, + "wfd_client_rtp_ports: RTP/AVP/UDP;unicast %d 0 mode=play", DEFAULT_RSTP_PORT); r = rtsp_message_append(rep, "{&}", - "wfd_client_rtp_ports: RTP/AVP/UDP;unicast 1991 0 mode=play"); + wfd_client_rtp_ports); if (r < 0) return cli_vERR(r); } + /* wfd_uibc_capability */ + if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0) { + char wfd_uibc_capability[512]; + sprintf(wfd_uibc_capability, + "wfd_uibc_capability: input_category_list=GENERIC;" + "generic_cap_list=Mouse,SingleTouch,Keyboard,Camera;" + "hidc_cap_list=none;port=%d", DEFAULT_UIBC_PORT); + r = rtsp_message_append(rep, "{&}", wfd_uibc_capability); + if (r < 0) + return cli_vERR(r); + } rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); @@ -241,6 +257,7 @@ static void sink_handle_set_parameter(struct ctl_sink *s, _rtsp_message_unref_ struct rtsp_message *rep = NULL; const char *trigger; const char *url; + const char *uibc_setting; char *nu; unsigned int cea_res, vesa_res, hh_res; int r; @@ -273,6 +290,19 @@ static void sink_handle_set_parameter(struct ctl_sink *s, } } + /* M4 (or any other) can pass presentation URLs */ + r = rtsp_message_read(m, "{}", "wfd_uibc_setting", &uibc_setting); + if (r >= 0) { + if (!s->uibc_setting || strcmp(s->uibc_setting, uibc_setting)) { + nu = strdup(uibc_setting); + if (!nu) + return cli_vENOMEM(); + + free(s->uibc_setting); + s->uibc_setting = nu; + cli_debug("uibc setting: %s\n", s->uibc_setting); + } + } /* M4 again */ r = rtsp_message_read(m, "{<****hhh>}", "wfd_video_formats", &cea_res, &vesa_res, &hh_res); From a95de6395eb8c9d5b8d9f81c109b5d04b08ef16f Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 26 Jun 2016 12:28:32 +0200 Subject: [PATCH 005/142] kdbus is avaliable by default relates to #41 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99941cd..5a24dd3 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ On the other hand, the Display-Sink side allows you to create wifi-capable exter The MiracleCast projects requires the following software to be installed: - **systemd**: A system management daemon. It is used for device-management (udev), dbus management (sd-bus) and service management. - Systemd must be compiled with --enable-kdbus, even though kdbus isn't used, but only the independent, experimental sd-libraries. + Systemd >= 221 will work out of the box. For earlier versions systemd must be compiled with --enable-kdbus, even though kdbus isn't used, but only the independent, experimental sd-libraries. *required*: >=systemd-213 - **glib**: A utility library. Used by the current DHCP implementation. Will be removed once sd-dns gains DHCP-server capabilities. From 442103a333847a322298aeb7ba8bacc197d05db3 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Thu, 30 Jun 2016 11:59:45 +0200 Subject: [PATCH 006/142] Details for ubuntu distributions General details for systemd prerequisite. relates to #83 --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a24dd3..a829c2f 100644 --- a/README.md +++ b/README.md @@ -70,11 +70,17 @@ You can also choose the interface with `--interface` option for miracle-wifid. ### Ubuntu -This specific linux flavour is so hard to get miraclecast dependencies that an alternative repo was created to install systemd with dbus +Check your systemd version with: + + $ systemctl --version + +If you are on 221 or above your systemd has kdbus enabled. + +If you are below 221, an alternative repo was created to install systemd with dbus https://github.com/albfan/systemd-ubuntu-with-dbus -At this time, ubuntu is on version 15.04 and systemd is stick on 219 version, use branch [systemd-219](https://github.com/albfan/miraclecast/tree/systemd-219) to compile miraclecast +See there was interface changes on systemd 219, if you are below that version, use branch [systemd-219](https://github.com/albfan/miraclecast/tree/systemd-219) to compile miraclecast > See specific instructions on that repo From c6d645d720b411d0ea3f35585b334d3cbc6bcaca Mon Sep 17 00:00:00 2001 From: albfan Date: Thu, 30 Jun 2016 21:16:32 +0200 Subject: [PATCH 007/142] Fix test suite on cmake --- .gitignore | 4 ++++ test/CMakeLists.txt | 23 ++++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 9802ce6..1bef527 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,7 @@ test_valgrind test_wpas wpa_cli wpa_supplicant +CMakeFiles/ +cmake_install.cmake +CMakeCache.txt +libmiracle-shared.a diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6d4c2eb..01bf9bf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,21 +4,22 @@ find_package(PkgConfig) pkg_check_modules (CHECK check) +set(test_rtsp_SOURCES test_common.h test_rtsp.c) +add_executable(test_rtsp ${test_rtsp_SOURCES}) +target_link_libraries(test_rtsp miracle-shared) +target_link_libraries(test_rtsp ${UDEV_LIBRARIES}) +target_link_libraries(test_rtsp ${GLIB2_LIBRARIES}) + +set(test_wpas_SOURCES test_common.h test_wpas.c) +add_executable(test_wpas ${test_wpas_SOURCES}) +target_link_libraries(test_wpas miracle-shared) +target_link_libraries(test_wpas ${UDEV_LIBRARIES}) +target_link_libraries(test_wpas ${GLIB2_LIBRARIES}) + if(CHECK_FOUND) - - set(test_rtsp_SOURCES test_common.h test_rtsp.c) - add_executable(test_rtsp ${test_rtsp_SOURCES}) - target_link_libraries(test_rtsp miracle-shared) target_link_libraries(test_rtsp ${CHECK_LIBRARIES}) - target_link_libraries(test_rtsp ${UDEV_LIBRARIES}) - target_link_libraries(test_rtsp ${GLIB2_LIBRARIES}) - set(test_wpas_SOURCES test_common.h test_wpas.c) - add_executable(test_wpas ${test_wpas_SOURCES}) - target_link_libraries(test_wpas miracle-shared) target_link_libraries(test_wpas ${CHECK_LIBRARIES}) - target_link_libraries(test_wpas ${UDEV_LIBRARIES}) - target_link_libraries(test_wpas ${GLIB2_LIBRARIES}) set(test_valgrind_SOURCES test_common.h test_valgrind.c) add_executable(test_valgrind ${test_valgrind_SOURCES}) From 4637409d0b82b3e4a25f8c96077f29f3efed9c5c Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 2 Jul 2016 15:22:13 +0200 Subject: [PATCH 008/142] relay on PATH to find executables --- .gitignore | 1 + CMakeLists.txt | 33 ++++++++++++++++----------------- common.am | 3 +-- src/ctl/ctl.h | 1 + src/ctl/sinkctl.c | 2 +- src/wifi/wifid-supplicant.c | 12 ++++++++---- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 1bef527..5e1f1b3 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ CMakeFiles/ cmake_install.cmake CMakeCache.txt libmiracle-shared.a +install_manifest.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index ffbe32c..60e2969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,27 @@ -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake - ${CMAKE_MODULE_PATH}) - -set(CMAKE_C_FLAGS "-std=gnu11") -add_definitions(-D_GNU_SOURCE) - -project(Miraclecast) cmake_minimum_required(VERSION 3.0) - -add_subdirectory(src) -add_subdirectory(res) -add_subdirectory(test) - -SET(BUILD_BINDIR "${CMAKE_INSTALL_PREFIX}/bin") -OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) -OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) -OPTION(BUILD_TESTS "Enable TEST" ON ) +project(Miraclecast) SET(PACKAGE_NAME miraclecast) SET(PACKAGE_VERSION 1) SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake + ${CMAKE_MODULE_PATH}) + +set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}") +add_definitions(-D_GNU_SOURCE) + +OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) +OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) +OPTION(BUILD_TESTS "Enable TEST" ON ) + find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) -CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) + +add_subdirectory(src) +add_subdirectory(res) +add_subdirectory(test) diff --git a/common.am b/common.am index 89b0ff1..1bd9b78 100644 --- a/common.am +++ b/common.am @@ -10,8 +10,7 @@ AM_CFLAGS = -Wall \ AM_CPPFLAGS = -include $(top_builddir)/config.h \ -I $(top_srcdir)/src \ - -I $(top_srcdir)/src/shared \ - '-DBUILD_BINDIR="$(bindir)"' + -I $(top_srcdir)/src/shared AM_LDFLAGS = -Wl,--as-needed \ -Wl,--gc-sections \ diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 40e49ec..8062f0c 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -186,6 +186,7 @@ void cli_printf(const char *fmt, ...); #define CLI_BLUE "\x1B[0;94m" #define CLI_BOLDGRAY "\x1B[1;30m" #define CLI_BOLDWHITE "\x1B[1;37m" + #define CLI_PROMPT CLI_BLUE "[miraclectl] # " CLI_DEFAULT struct cli_cmd { diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 24d461e..e71ea7c 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -369,7 +369,7 @@ static void spawn_gst(int hres, int vres) } i = 0; - argv[i++] = (char*) BUILD_BINDIR "/miracle-gst.sh"; + argv[i++] = (char*) "/miracle-gst.sh"; if (cli_max_sev >= 7) argv[i++] = "-d 3"; if (gst_audio_en) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index f467b47..e05a0cc 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -386,7 +386,7 @@ static int supplicant_group_spawn_dhcp_server(struct supplicant_group *g, } i = 0; - argv[i++] = (char*) BUILD_BINDIR "/miracle-dhcp"; + argv[i++] = (char*) "miracle-dhcp"; argv[i++] = "--server"; argv[i++] = "--prefix"; argv[i++] = prefix; @@ -398,7 +398,9 @@ static int supplicant_group_spawn_dhcp_server(struct supplicant_group *g, argv[i++] = commfd; argv[i] = NULL; - execve(argv[0], argv, environ); + if (execvpe(argv[0], argv, environ)< 0) { + log_error("dhcp failed (%d): %m", errno); + } _exit(1); } @@ -448,7 +450,7 @@ static int supplicant_group_spawn_dhcp_client(struct supplicant_group *g) } i = 0; - argv[i++] = (char*) BUILD_BINDIR "/miracle-dhcp"; + argv[i++] = (char*) "miracle-dhcp"; argv[i++] = "--log-level"; argv[i++] = loglevel; argv[i++] = "--netdev"; @@ -457,7 +459,9 @@ static int supplicant_group_spawn_dhcp_client(struct supplicant_group *g) argv[i++] = commfd; argv[i] = NULL; - execve(argv[0], argv, environ); + if (execvpe(argv[0], argv, environ) < 0) { + log_error("dhcp failed (%d): %m", errno); + } _exit(1); } From 1e69dd6dae5f2332face744b247dbeb72036e0cf Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 2 Jul 2016 15:35:58 +0200 Subject: [PATCH 009/142] UIBC support Basic support for UIBC (single mouse events and key events) - Option --uibc on miracle-sinkctl to enable it - Option --log-journal-level to see player execution on journalctl - Controller for uibc miracle-uibcctl - Player based on PyGtk to receive and communicate mouse and keyevents closes #57 --- .gitignore | 1 + README.md | 10 +- configure.ac | 2 + res/CMakeLists.txt | 2 +- res/Makefile.am | 2 +- res/gstplayer | 219 +++++++++++++ res/miracle-gst | 100 ++++++ res/test-viewer.sh | 2 +- res/uibc-viewer | 8 + src/CMakeLists.txt | 3 +- src/Makefile.am | 2 +- src/ctl/CMakeLists.txt | 2 +- src/ctl/Makefile.am | 1 + src/ctl/ctl-sink.c | 87 ++---- src/ctl/ctl-sink.h | 72 +++++ src/ctl/ctl.h | 2 +- src/ctl/sinkctl.c | 124 +++++++- src/uibc/CMakeLists.txt | 10 + src/uibc/Makefile.am | 16 + src/uibc/miracle-uibcctl.c | 624 +++++++++++++++++++++++++++++++++++++ src/uibc/miracle-uibcctl.h | 48 +++ 21 files changed, 1258 insertions(+), 79 deletions(-) create mode 100755 res/gstplayer create mode 100755 res/miracle-gst create mode 100755 res/uibc-viewer create mode 100644 src/ctl/ctl-sink.h create mode 100644 src/uibc/CMakeLists.txt create mode 100644 src/uibc/Makefile.am create mode 100644 src/uibc/miracle-uibcctl.c create mode 100644 src/uibc/miracle-uibcctl.h diff --git a/.gitignore b/.gitignore index 5e1f1b3..089ec5d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ miracle-dhcp miracle-sinkctl miracle-wifictl miracle-wifid +miracle-uibcctl miraclectl miracled stamp-h1 diff --git a/README.md b/README.md index a829c2f..9f91f59 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ See there was interface changes on systemd 219, if you are below that version, u ### Arch linux -Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast/). Remember to enable kdus to systemd-git dependency +Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast/). Remember to enable kdus to systemd-git dependency if you are below 221 systemd. $ export _systemd_git_kdbus=--enable-kdbus @@ -142,7 +142,13 @@ Steps to use it as peer: > psp-scan - 5. Apart from list, or show info with peer <mac> there's nothing useful here by now. + 5. Apart from list, or show info with peer <mac> there's nothing useful here by now. For a Q&D see [Using as peer](https://github.com/albfan/miraclecast/issues/4) + +## UIBC + +> The User Input Back Channel (UIBC) is an optional WFD feature that when implemented facilitates communication of user inputs to a User Interface, present at the WFD Sink, to the WFD Source. + +To use it just add `--uibc` on `miracle-sinkctl` startup. Single mouse events and key events are implemented. ## Autocompletion diff --git a/configure.ac b/configure.ac index 97ba376..a2f3738 100644 --- a/configure.ac +++ b/configure.ac @@ -35,6 +35,7 @@ AC_PROG_AWK LT_PREREQ(2.2) LT_INIT +LT_LIB_M AC_ARG_ENABLE([rely-udev], AS_HELP_STRING([--enable-rely-udev], [Use tagged device with miraclecast]), AC_DEFINE([RELY_UDEV], [], [Rely on udev to find miraclecast device])) @@ -70,6 +71,7 @@ AC_CONFIG_FILES([Makefile src/dhcp/Makefile src/shared/Makefile src/wifi/Makefile + src/uibc/Makefile test/Makefile]) AC_OUTPUT diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 2065690..da37a71 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -1,7 +1,7 @@ ########### install files ############### -install(FILES miracle-gst.sh DESTINATION bin) +install(FILES miracle-gst gstplayer DESTINATION bin) diff --git a/res/Makefile.am b/res/Makefile.am index 51f71fb..56eea69 100644 --- a/res/Makefile.am +++ b/res/Makefile.am @@ -1,2 +1,2 @@ -bin_SCRIPTS = miracle-gst.sh +bin_SCRIPTS = miracle-gst gstplayer uibc-viewer EXTRA_DIST = wpa.conf diff --git a/res/gstplayer b/res/gstplayer new file mode 100755 index 0000000..b1d3c08 --- /dev/null +++ b/res/gstplayer @@ -0,0 +1,219 @@ +#!/usr/bin/python3 -u + +import gi +import sys +import argparse + +gi.require_version('Gst', '1.0') +gi.require_version('Gtk', '3.0') +gi.require_version('GstVideo', '1.0') + +from gi.repository import GObject, Gst, Gtk, Gdk, GLib + +# Needed for window.get_xid(), xvimagesink.set_window_handle(), respectively: +from gi.repository import GdkX11, GstVideo + +GObject.threads_init() +Gst.init(None) + +class Player(object): + def __init__(self, **kwargs): + + scale = kwargs.get("scale") + #scale = "1080x1920" + if not scale: + self.width = 800 + self.height = 600 + else: + split = scale.split("x") + self.width = int(split[0]) + self.height = int(split[1]) + + port = kwargs.get("port") + + uri = kwargs.get("uri") + + self.window = Gtk.Window() + self.window.set_name('eco') + self.window.connect('destroy', self.quit) + + title = kwargs.get("title") + if title: + self.window.set_title(title) + + self.window.set_default_size(self.width, self.height) + + self.drawingarea = Gtk.DrawingArea() + self.window.add(self.drawingarea) + + self.drawingarea.set_size_request(self.width,self.height) + self.drawingarea.add_events(Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.BUTTON_RELEASE_MASK) + self.drawingarea.connect('button-press-event', self.on_mouse_pressed) + self.drawingarea.connect('button-release-event', self.on_mouse_pressed) + self.drawingarea.add_events(Gdk.EventMask.KEY_PRESS_MASK) + self.window.connect('key-press-event', self.on_key_pressed) + + audio = kwargs.get("audio") + + self.playbin = None + + #Create GStreamer pipeline + if uri is not None: + self.pipeline = Gst.Pipeline() + + # Create GStreamer elements + self.playbin = Gst.ElementFactory.make('playbin', "source") + + if not uri.startswith("http://") or not uri.startswith("http://") or not uri.startswith("file://"): + if not uri.startswith("/"): + import os + uri = os.path.abspath(uri) + uri = "file://"+uri + + # Set properties + self.playbin.set_property('uri', uri) + + + # Add playbin to the pipeline + self.pipeline.add(self.playbin) + else: + gstcommand = "udpsrc port="+str(port)+" caps=\"application/x-rtp, media=video\" ! rtpjitterbuffer latency=100 ! rtpmp2tdepay ! tsdemux " + + if audio: + gstcommand += "name=demuxer demuxer. " + + gstcommand += "! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! " + + if scale: + gstcommand += "videoscale method=1 ! video/x-raw,width="+str(self.width)+",height="+str(self.height)+" ! " + + gstcommand += "autovideosink " + + if audio: + gstcommand += "demuxer. ! queue max-size-buffers=0 max-size-time=0 ! aacparse ! avdec_aac ! audioconvert ! audioresample ! autoaudiosink " + + self.pipeline = Gst.parse_launch(gstcommand) + + + # Create bus to get events from GStreamer pipeline + self.bus = self.pipeline.get_bus() + self.bus.add_signal_watch() + self.bus.connect('message::eos', self.on_eos) + self.bus.connect('message::error', self.on_error) + + # This is needed to make the video output in our DrawingArea: + self.bus.enable_sync_message_emission() + self.bus.connect('sync-message::element', self.on_sync_message) + self.bus.connect('message', self.on_message) + + self.success = False + + def on_message(self, bus, message): + if self.playbin: + videoPad = self.playbin.emit("get-video-pad", 0) + if videoPad and not self.success: + videoPadCapabilities = videoPad.get_current_caps() + if videoPadCapabilities: + (self.success, self.videoWidth) = \ + videoPadCapabilities.get_structure(0).get_int("width") + (self.success, self.videoHeight) = \ + videoPadCapabilities.get_structure(0).get_int("height") + if self.success: + print("{0} {1}".format(self.videoWidth, self.videoHeight)) + self.drawingarea.set_size_request(self.videoWidth, self.videoHeight) + + def on_mouse_pressed(self, widget, event): + #,,,, + if event.type == Gdk.EventType.BUTTON_PRESS: + type = 0 + else: + type = 1 + + width = self.drawingarea.get_allocation().width + height = self.drawingarea.get_allocation().height + half_area_width = width / 2 + half_area_height = height / 2 + + half_def_width = self.width / 2 + half_def_height = self.height / 2 + + min_hor_pos = half_area_width - half_def_width + max_hor_pos = half_area_width + half_def_width + min_ver_pos = half_area_height - half_def_height + max_ver_pos = half_area_height + half_def_height + + pos_event_x = event.x + pos_event_y = event.y + + + #print('{0} {1} {2} {3} {4} {5}'.format(min_hor_pos, pos_event_x, max_hor_pos, min_ver_pos, pos_event_y,max_ver_pos)) + if min_hor_pos <= pos_event_x <= max_hor_pos and min_ver_pos <= pos_event_y <= max_ver_pos: + uibc_x = int(pos_event_x - (half_area_width - half_def_width)) + #print ('{0} {1} {2} {3}'.format(uibc_x, pos_event_x, half_area_width,half_def_width)) + uibc_y = int(pos_event_y - (half_area_height - half_def_height)) + #print ('{0} {1} {2} {3}'.format(uibc_y, pos_event_y, half_area_height,half_def_height)) + print('{0},1,0,{1},{2}'.format(type, uibc_x , uibc_y)) + + def on_key_pressed(self, widget, event): + #print(Gdk.keyval_name(event.keyval)) + print("3,0x%04X,0x0000" % event.keyval) + # print(event.state) + # if event.state & Gdk.ModifierType.LOCK_MASK == Gdk.ModifierType.LOCK_MASK: + # print("caps lock") + # print(Gtk.accelerator_get_label(event.keyval, event.state)) + + def run(self): + self.window.show_all() + # You need to get the XID after window.show_all(). You shouldn't get it + # in the on_sync_message() handler because threading issues will cause + # segfaults there. + self.xid = self.drawingarea.get_property('window').get_xid() + self.pipeline.set_state(Gst.State.PLAYING) + Gtk.main() + + + def quit(self, window): + self.pipeline.set_state(Gst.State.NULL) + Gtk.main_quit() + + def on_sync_message(self, bus, msg): + if msg.get_structure().get_name() == 'prepare-window-handle': + print(self.drawingarea.get_allocation()) + #msg.src.set_property("force-aspect-radio", True) + msg.src.set_window_handle(self.xid) + + def on_eos(self, bus, msg): + print('on_eos(): seeking to start of video') + self.pipeline.seek_simple( + Gst.Format.TIME, + Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, + 0 + ) + + def on_error(self, bus, msg): + print('on_error():', msg.parse_error()) + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser() + parser.add_argument("uri", nargs="?", help="Uri to play") + parser.add_argument("-v", "--version", help="Show package version") + parser.add_argument("--log-level", metavar="lvl", help="Maximum level for log messages") + parser.add_argument("-p", "--port", type=int, default=1991, help="Port for rtsp") + parser.add_argument("-a", "--audio", dest="audio", action="store_true", help="Enable audio support") + parser.add_argument("-s", "--scale", metavar="WxH", help="Scale to resolution") + parser.add_argument("-d", "--debug", help="Debug") + parser.add_argument("--uibc", help="Enable UIBC") + parser.add_argument("--title", help="set player title") + parser.add_argument("--res", metavar="n,n,n", help="Supported resolutions masks (CEA, VESA, HH)") + # res + # " default CEA %08X\n" + # " default VESA %08X\n" + # " default HH %08X\n" + parser.add_argument("-r", "--resolution", help="Resolution") + parser.set_defaults(audio=True) + args = parser.parse_args() + + p = Player(**vars(args)) + p.run() diff --git a/res/miracle-gst b/res/miracle-gst new file mode 100755 index 0000000..9a2a4db --- /dev/null +++ b/res/miracle-gst @@ -0,0 +1,100 @@ +#!/bin/bash + +function help { + local scriptname="$(basename $0)" + cat >&2 <x Scale + -d Log level for gst + -p Port for stream + -a Enables audio + -h Show this help + +Examples: + + # play stream on port 7236 + $ $scriptname -p 7236 + # play stream with resolution 800x600 + $ $scriptname -s 800x600 + # play stream with audio + $ $scriptname -a + # play stream with debug level 3 + $ $scriptname -d 3 + +EOF +} + +DEBUG='0' +AUDIO='0' +SCALE='0' + +while getopts "r:d:as:p:h" optname + do + case "$optname" in + "h") + help + exit 0 + ;; + "d") + DEBUG=`echo ${OPTARG} | tr -d ' '` + ;; + "r") + RESOLUTION=`echo ${OPTARG} | tr -d ' '` + ;; + "a") + AUDIO='1' + ;; + "p") + PORT=`echo ${OPTARG} | tr -d ' '` + ;; + "s") + SCALE='1' + WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1` + HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2` + ;; + "?") + echo "Unknown option $OPTARG" + ;; + *) + echo "Unknown parameter $OPTARG" + help + exit 1 + ;; + esac + done + +RUN="/usr/bin/gst-launch-1.0 -v " +if [ $DEBUG != '0' ] +then + RUN+="--gst-debug=${DEBUG} " +fi + +RUN+="udpsrc port=$PORT caps=\"application/x-rtp, media=video\" ! rtpjitterbuffer latency=100 ! rtpmp2tdepay ! tsdemux " + +if [ $AUDIO == '1' ] +then + RUN+="name=demuxer demuxer. " +fi + +RUN+="! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! " + +if [ $SCALE == '1' ] +then + RUN+="videoscale method=1 ! video/x-raw,width=${WIDTH},height=${HEIGHT} ! " +fi + +RUN+="autovideosink " + +if [ $AUDIO == '1' ] +then + RUN+="demuxer. ! queue max-size-buffers=0 max-size-time=0 ! aacparse ! avdec_aac ! audioconvert ! audioresample ! autoaudiosink " +fi + +echo "running: $RUN" +exec ${RUN} diff --git a/res/test-viewer.sh b/res/test-viewer.sh index ab1fa99..38bd83a 100755 --- a/res/test-viewer.sh +++ b/res/test-viewer.sh @@ -35,7 +35,7 @@ Try installing packages "gst-plugins-bad, gst-plugins-base, gst-plugins-base-lib If that fails too, try: -$ vlc rtp://@1991 +$ vlc rtp://@:1991 EOF else diff --git a/res/uibc-viewer b/res/uibc-viewer new file mode 100755 index 0000000..40365c9 --- /dev/null +++ b/res/uibc-viewer @@ -0,0 +1,8 @@ +#!/bin/bash + +IP=$1 +shift +UIBC_PORT=$1 +shift + +gstplayer $@ | miracle-uibcctl $IP $UIBC_PORT --daemon diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5b8363c..96fe570 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,10 @@ -set(CMAKE_C_FLAGS "-std=gnu11") +set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}") add_subdirectory(shared) add_subdirectory(wifi) add_subdirectory(dhcp) add_subdirectory(ctl) +add_subdirectory(uibc) set(miracled_SRCS miracled.h miracled.c) add_executable(miracled ${miracled_SRCS}) diff --git a/src/Makefile.am b/src/Makefile.am index f10e22b..3a3ead6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ include $(top_srcdir)/common.am -SUBDIRS = shared wifi dhcp ctl +SUBDIRS = shared wifi dhcp ctl uibc bin_PROGRAMS = miracled diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt index 727a2d6..d6d98e4 100644 --- a/src/ctl/CMakeLists.txt +++ b/src/ctl/CMakeLists.txt @@ -24,11 +24,11 @@ target_link_libraries(miracle-wifictl miracle-shared) set(miracle-sinkctl_SRCS ctl.h ctl-cli.c + ctl-sink.h ctl-sink.c ctl-wifi.c sinkctl.c wfd.c) - add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS}) diff --git a/src/ctl/Makefile.am b/src/ctl/Makefile.am index 9f88336..f02d052 100644 --- a/src/ctl/Makefile.am +++ b/src/ctl/Makefile.am @@ -17,6 +17,7 @@ miracle_wifictl_LDADD = \ miracle_sinkctl_SOURCES = \ ctl.h \ ctl-cli.c \ + ctl-sink.h \ ctl-sink.c \ ctl-wifi.c \ wfd.c \ diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 3a5cf5d..e771f52 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -17,52 +17,8 @@ * along with MiracleCast; If not, see . */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ctl.h" -#include "rtsp.h" -#include "shl_macro.h" -#include "shl_util.h" -#include "wfd.h" +#include "ctl-sink.h" -struct ctl_sink { - sd_event *event; - - char *target; - char *session; - char *url; - char *uibc_setting; - struct sockaddr_storage addr; - size_t addr_size; - int fd; - sd_event_source *fd_source; - - struct rtsp *rtsp; - - bool connected : 1; - bool hup : 1; - - uint32_t resolutions_cea; - uint32_t resolutions_vesa; - uint32_t resolutions_hh; - - int hres; - int vres; -}; -static const int DEFAULT_UIBC_PORT = 7239; -static const int DEFAULT_RSTP_PORT = 1991; /* * RTSP Session */ @@ -158,7 +114,7 @@ static void sink_handle_get_parameter(struct ctl_sink *s, if (rtsp_message_read(m, "{<>}", "wfd_client_rtp_ports") >= 0) { char wfd_client_rtp_ports[128]; sprintf(wfd_client_rtp_ports, - "wfd_client_rtp_ports: RTP/AVP/UDP;unicast %d 0 mode=play", DEFAULT_RSTP_PORT); + "wfd_client_rtp_ports: RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); r = rtsp_message_append(rep, "{&}", wfd_client_rtp_ports); if (r < 0) @@ -166,12 +122,12 @@ static void sink_handle_get_parameter(struct ctl_sink *s, } /* wfd_uibc_capability */ - if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0) { + if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0 && uibc) { char wfd_uibc_capability[512]; sprintf(wfd_uibc_capability, "wfd_uibc_capability: input_category_list=GENERIC;" - "generic_cap_list=Mouse,SingleTouch,Keyboard,Camera;" - "hidc_cap_list=none;port=%d", DEFAULT_UIBC_PORT); + "generic_cap_list=Mouse,SingleTouch;" + "hidc_cap_list=none;port=none"); r = rtsp_message_append(rep, "{&}", wfd_uibc_capability); if (r < 0) return cli_vERR(r); @@ -243,7 +199,7 @@ static int sink_set_format(struct ctl_sink *s, if (hres && vres) { s->hres = hres; s->vres = vres; - ctl_fn_sink_resolution_set(s, hres, vres); + ctl_fn_sink_resolution_set(s); return 0; } } @@ -257,6 +213,7 @@ static void sink_handle_set_parameter(struct ctl_sink *s, _rtsp_message_unref_ struct rtsp_message *rep = NULL; const char *trigger; const char *url; + const char *uibc_config; const char *uibc_setting; char *nu; unsigned int cea_res, vesa_res, hh_res; @@ -290,6 +247,30 @@ static void sink_handle_set_parameter(struct ctl_sink *s, } } + /* M4 (or any other) can pass presentation URLs */ + r = rtsp_message_read(m, "{}", "wfd_uibc_capability", &uibc_config); + if (r >= 0) { + if (!s->uibc_config || strcmp(s->uibc_config, uibc_config)) { + nu = strdup(uibc_config); + if (!nu) + return cli_vENOMEM(); + + free(s->uibc_config); + s->uibc_config = nu; + + char* token = strtok(uibc_config, ";"); + + while (token) { + if (sscanf(token, "port=%d", &uibc_port)) { + break; + } + token = strtok(0, ";"); + } + + cli_debug("Got URL: %s\n", s->url); + } + } + /* M4 (or any other) can pass presentation URLs */ r = rtsp_message_read(m, "{}", "wfd_uibc_setting", &uibc_setting); if (r >= 0) { @@ -330,9 +311,9 @@ static void sink_handle_set_parameter(struct ctl_sink *s, if (r < 0) return cli_vERR(r); - r = rtsp_message_append(rep, "", - "Transport", - "RTP/AVP/UDP;unicast;client_port=1991"); + char rtsp_setup[128]; + sprintf(rtsp_setup, "RTP/AVP/UDP;unicast;client_port=%d", rstp_port); + r = rtsp_message_append(rep, "", "Transport", rtsp_setup); if (r < 0) return cli_vERR(r); diff --git a/src/ctl/ctl-sink.h b/src/ctl/ctl-sink.h new file mode 100644 index 0000000..69d0532 --- /dev/null +++ b/src/ctl/ctl-sink.h @@ -0,0 +1,72 @@ +/* + * MiracleCast - Wifi-Display/Miracast Implementation + * + * 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 . + */ + +#ifndef CTL_SINK_H +#define CTL_SINK_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ctl.h" + +#include "rtsp.h" +#include "shl_macro.h" +#include "shl_util.h" +#include "wfd.h" + +extern int rstp_port; +extern bool uibc; +extern int uibc_port; + +struct ctl_sink { + sd_event *event; + + char *target; + char *session; + char *url; + char *uibc_config; + char *uibc_setting; + struct sockaddr_storage addr; + size_t addr_size; + int fd; + sd_event_source *fd_source; + + struct rtsp *rtsp; + + bool connected : 1; + bool hup : 1; + + uint32_t resolutions_cea; + uint32_t resolutions_vesa; + uint32_t resolutions_hh; + + int hres; + int vres; +}; + +#endif /* CTL_SINK_H */ diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 8062f0c..077cc49 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -241,7 +241,7 @@ void ctl_fn_link_free(struct ctl_link *l); void ctl_fn_sink_connected(struct ctl_sink *s); void ctl_fn_sink_disconnected(struct ctl_sink *s); -void ctl_fn_sink_resolution_set(struct ctl_sink *s, int hres, int vres); +void ctl_fn_sink_resolution_set(struct ctl_sink *s); void cli_fn_help(void); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e71ea7c..e594a50 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -34,6 +34,7 @@ #include #include #include "ctl.h" +#include "ctl-sink.h" #include "wfd.h" #include "shl_macro.h" #include "shl_util.h" @@ -53,8 +54,15 @@ static struct ctl_link *running_link; static struct ctl_peer *running_peer; static struct ctl_peer *pending_peer; +void launch_player(struct ctl_sink *s); + char *gst_scale_res; int gst_audio_en = 1; +static const int DEFAULT_RSTP_PORT = 1991; +bool uibc; +int rstp_port; +int uibc_port; + unsigned int wfd_supported_res_cea = 0x0000001f; /* up to 720x576 */ unsigned int wfd_supported_res_vesa = 0x00000003; /* up to 800x600 */ unsigned int wfd_supported_res_hh = 0x00000000; /* not supported */ @@ -335,12 +343,10 @@ static const struct cli_cmd cli_cmds[] = { { }, }; -static void spawn_gst(int hres, int vres) +static void spawn_gst(struct ctl_sink *s) { - char *argv[64]; - char resolution[64]; pid_t pid; - int fd_journal, i; + int fd_journal; sigset_t mask; if (sink_pid > 0) @@ -357,7 +363,7 @@ static void spawn_gst(int hres, int vres) /* redirect stdout/stderr to journal */ fd_journal = sd_journal_stream_fd("miracle-sinkctl-gst", - LOG_INFO, + LOG_DEBUG, false); if (fd_journal >= 0) { /* dup journal-fd to stdout and stderr */ @@ -368,8 +374,34 @@ static void spawn_gst(int hres, int vres) dup2(2, 1); } - i = 0; - argv[i++] = (char*) "/miracle-gst.sh"; + launch_player(s); + _exit(1); + } else { + sink_pid = pid; + } +} + +void launch_player(struct ctl_sink *s) { + char *argv[64]; + char resolution[64]; + char port[64]; + char uibc_portStr[64]; + int i = 0; + char* player; + if (uibc) { +// player = "gstplayer"; + player = "uibc-viewer"; + } else { + player = "miracle-gst"; + } + + argv[i++] = player; + if (uibc) { + argv[i++] = s->target; + sprintf(uibc_portStr, "%d", uibc_port); + argv[i++] = uibc_portStr; +// argv[i++] = "--daemon"; + } if (cli_max_sev >= 7) argv[i++] = "-d 3"; if (gst_audio_en) @@ -378,18 +410,55 @@ static void spawn_gst(int hres, int vres) argv[i++] = "-s"; argv[i++] = gst_scale_res; } - if (hres && vres) { - sprintf(resolution, "%dx%d", hres, vres); + argv[i++] = "-p"; + sprintf(port, "%d", rstp_port); + argv[i++] = port; + + if (s->hres && s->vres) { + sprintf(resolution, "%dx%d", s->hres, s->vres); argv[i++] = "-r"; argv[i++] = resolution; } + argv[i] = NULL; - execve(argv[0], argv, environ); - _exit(1); - } else { - sink_pid = pid; + i = 0; + int size = 0; + while (argv[i]) { + size += strlen(argv[i++] + 1); } + + char* player_command = malloc(size); + i = 0; + strcpy(player_command, argv[i++]); + while (argv[i]) { + strcat(player_command, " "); + strcat(player_command, argv[i++]); + } + log_debug("player command: %s", player_command); + //free(player_command); + if (execvpe(argv[0], argv, environ) < 0) { + cli_debug("stream player failed (%d): %m", errno); + int i = 0; + cli_debug("printing environment: "); + while (environ[i]) { + cli_debug("%s", environ[i++]); + } + } +} + +void launch_uibc_daemon(int port) { + char *argv[64]; + char portStr[64]; + int i = 0; + argv[i++] = "miracle-uibcctl"; + argv[i++] = "localhost"; + sprintf(portStr, "%d", port); + argv[i++] = portStr; + argv[i] = NULL; + + cli_debug("uibc daemon: %s", argv[0]); + execvpe(argv[0], argv, environ); } static void kill_gst(void) @@ -418,11 +487,11 @@ void ctl_fn_sink_disconnected(struct ctl_sink *s) } } -void ctl_fn_sink_resolution_set(struct ctl_sink *s, int hres, int vres) +void ctl_fn_sink_resolution_set(struct ctl_sink *s) { - cli_printf("SINK set resolution %dx%d\n", hres, vres); + cli_printf("SINK set resolution %dx%d\n", s->hres, s->vres); if (sink_connected) - spawn_gst(hres, vres); + spawn_gst(s); } void ctl_fn_peer_new(struct ctl_peer *p) @@ -604,14 +673,17 @@ void cli_fn_help() " -h --help Show this help\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" + " --log-journal-level Maximum level for journal log messages\n" " --audio <0/1> Enable audio support (default %d)\n" " --scale WxH Scale to resolution\n" + " --port Port for rtsp (default %d)\n" + " --uibc Enables UIBC\n" " --res Supported resolutions masks (CEA, VESA, HH)\n" " default CEA %08X\n" " default VESA %08X\n" " default HH %08X\n" "\n" - , program_invocation_short_name, gst_audio_en, + , program_invocation_short_name, gst_audio_en, DEFAULT_RSTP_PORT, wfd_supported_res_cea, wfd_supported_res_vesa, wfd_supported_res_hh ); wfd_print_resolutions(); @@ -680,21 +752,30 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_JOURNAL_LEVEL, ARG_AUDIO, ARG_SCALE, ARG_RES, + ARG_PORT, + ARG_UIBC, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, { "audio", required_argument, NULL, ARG_AUDIO }, { "scale", required_argument, NULL, ARG_SCALE }, { "res", required_argument, NULL, ARG_RES }, + { "port", required_argument, NULL, ARG_PORT }, + { "uibc", no_argument, NULL, ARG_UIBC }, {} }; int c; + uibc = false; + rstp_port = DEFAULT_RSTP_PORT; + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { switch (c) { case 'h': @@ -705,6 +786,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_LEVEL: cli_max_sev = log_parse_arg(optarg); break; + case ARG_JOURNAL_LEVEL: + log_max_sev = log_parse_arg(optarg); + break; case ARG_AUDIO: gst_audio_en = atoi(optarg); break; @@ -717,6 +801,12 @@ static int parse_argv(int argc, char *argv[]) &wfd_supported_res_vesa, &wfd_supported_res_hh); break; + case ARG_PORT: + rstp_port = atoi(optarg); + break; + case ARG_UIBC: + uibc = true; + break; case '?': return -EINVAL; } diff --git a/src/uibc/CMakeLists.txt b/src/uibc/CMakeLists.txt new file mode 100644 index 0000000..ac81904 --- /dev/null +++ b/src/uibc/CMakeLists.txt @@ -0,0 +1,10 @@ +set(miracle-uibcctl_SRCS miracle-uibcctl.h + miracle-uibcctl.c) + +add_executable(miracle-uibcctl ${miracle-uibcctl_SRCS}) +target_link_libraries(miracle-uibcctl PRIVATE miracle-shared) +target_link_libraries(miracle-uibcctl PUBLIC m) + +install(TARGETS miracle-uibcctl DESTINATION bin) + +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) diff --git a/src/uibc/Makefile.am b/src/uibc/Makefile.am new file mode 100644 index 0000000..7829d8c --- /dev/null +++ b/src/uibc/Makefile.am @@ -0,0 +1,16 @@ +include $(top_srcdir)/common.am + +bin_PROGRAMS = miracle-uibcctl + +miracle_uibcctl_SOURCES = \ + miracle-uibcctl.h \ + miracle-uibcctl.c + +miracle_uibctcl_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(DEPS_CFLAGS) + +miracle_uibcctl_LDADD = \ + ../shared/libmiracle-shared.la \ + $(LIBM) + diff --git a/src/uibc/miracle-uibcctl.c b/src/uibc/miracle-uibcctl.c new file mode 100644 index 0000000..39bc42c --- /dev/null +++ b/src/uibc/miracle-uibcctl.c @@ -0,0 +1,624 @@ + +#include "miracle-uibcctl.h" + +int main(int argc, char *argv[]) { + //TODO: Add miracle TUI interface + //TODO: Add parsearg + //--daemon (read stdin) + + int portno; + struct hostent *server; + int sockfd; + struct sockaddr_in serv_addr; + char buffer[256]; + int r; + + log_max_sev = LOG_INFO; + + if (argc < 3) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s \n", argv[0]); + return EXIT_FAILURE; + } + + server = gethostbyname(argv[1]); + portno = atoi(argv[2]); + + log_info("server %s port %d", argv[1], portno); + + if (server == NULL) { + fprintf(stderr,"ERROR, no such host\n"); + exit(0); + } + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) { + perror("ERROR opening socket"); + return EXIT_FAILURE; + } + + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + bcopy(server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); + serv_addr.sin_port = htons(portno); + + if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + perror("ERROR connecting"); + return EXIT_FAILURE; + } + + bool daemon = true; + while(1) { + if (!daemon) { + printf("enter event ,,,,: "); + } + bzero(buffer, 256); + fgets(buffer, 255, stdin); + if (buffer == NULL) { + break; + } + if (daemon) { + printf("input: %s", buffer); + } + char type = buffer[0]; + UibcMessage uibcmessage; + if (type == '0' || type == '1') { + uibcmessage = buildUibcMessage(GENERIC_TOUCH_DOWN, buffer, 1, 1); + } else if (type == '3' || type == '4') { + uibcmessage = buildUibcMessage(GENERIC_KEY_DOWN, buffer, 1, 1); + } else { + printf("unknow event type: %s", buffer); + continue; + } + + r = sendUibcMessage(&uibcmessage, sockfd); + if (r) { + return r; + } + } + + close(sockfd); + return EXIT_SUCCESS; +} + +const char *int2binary(int x, int padding) +{ + char *b; + int min_padding = x > 0 ? floor(log2(x)) : 0; + if (padding < min_padding) + { + padding = min_padding; + } + + b = (char *)malloc (sizeof (char *) * padding + 1); + strcpy(b, ""); + + int z; + for (z = pow(2,padding); z > 0; z >>= 1) + { + strcat(b, ((x & z) == z) ? "1" : "0"); + } + + return b; +} + +int sendUibcMessage(UibcMessage* uibcmessage, int sockfd) { + ssize_t n; + + printf("sending %d bytes\n", uibcmessage->m_PacketDataLen); + + n = write(sockfd, uibcmessage->m_PacketData , uibcmessage->m_PacketDataLen); + + if (n < 0) { + perror("ERROR writing to socket"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +UibcMessage buildUibcMessage(MessageType type, + const char* inEventDesc, + double widthRatio, + double heightRatio) { + UibcMessage uibcmessage; + uibcmessage.m_PacketData = NULL; + uibcmessage.m_PacketDataLen = 0; + uibcmessage.m_DataValid = false; + + switch (type) { + case GENERIC_TOUCH_DOWN: + case GENERIC_TOUCH_UP: + case GENERIC_TOUCH_MOVE: + getUIBCGenericTouchPacket(inEventDesc, + &uibcmessage, + widthRatio, + heightRatio); + break; + + case GENERIC_KEY_DOWN: + case GENERIC_KEY_UP: + getUIBCGenericKeyPacket(inEventDesc, &uibcmessage); + break; + + case GENERIC_ZOOM: + getUIBCGenericZoomPacket(inEventDesc, &uibcmessage); + break; + + case GENERIC_VERTICAL_SCROLL: + case GENERIC_HORIZONTAL_SCROLL: + getUIBCGenericScalePacket(inEventDesc, &uibcmessage); + break; + + case GENERIC_ROTATE: + getUIBCGenericRotatePacket(inEventDesc, &uibcmessage); + break; + }; + return uibcmessage; +} + + +// format: "typeId, number of pointers, pointer Id1, X coordnate, Y coordinate, pointer Id2, X coordnate, Y coordnate,..." +void getUIBCGenericTouchPacket(const char *inEventDesc, + UibcMessage* uibcmessage, + double widthRatio, + double heightRatio) { + log_info("getUIBCGenericTouchPacket (%s)", inEventDesc); + char* outData; + int32_t typeId = 0; + int32_t numberOfPointers = 0; + size_t uibcBodyLen = 0; + int32_t genericPacketLen = 0; + int32_t temp; + size_t size; + + char** splitedStr = str_split((char*)inEventDesc, ",", &size); + + if ((int)size - 5 < 0 || ((int)size - 5) % 3 != 0) { + log_error("getUIBCGenericTouchPacket (%s)", "bad input event"); + return; + } + int offset_split = 0; + typeId = atoi(*(splitedStr + offset_split++)); + numberOfPointers = atoi(*(splitedStr + offset_split++)); + + genericPacketLen = numberOfPointers * 5 + 1; + uibcBodyLen = genericPacketLen + 7; // Generic header length = 7 + //Padding to even number + uibcBodyLen = (uibcBodyLen % 2 == 0) ? uibcBodyLen : (uibcBodyLen + 1); + + outData = (char*)malloc(uibcBodyLen); + // UIBC header Octets + int offset_header = 0; + //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[offset_header++] = 0x00; // 000 0 0000 + outData[offset_header++] = 0x00; // 0000 0000 + + //Length(16 bits) + outData[offset_header++] = (uibcBodyLen >> 8) & 0xFF; // first 8 bytes + outData[offset_header++] = uibcBodyLen & 0xFF; // last 8 bytes + + //Generic Input Body Format + outData[offset_header++] = typeId & 0xFF; // Tyoe ID, 1 octet + + // Length, 2 octets + outData[offset_header++] = (genericPacketLen >> 8) & 0xFF; // first 8 bytes + outData[offset_header++] = genericPacketLen & 0xFF; //last 8 bytes + + // Number of pointers, 1 octet + outData[offset_header++] = numberOfPointers & 0xFF; + + int offset = 0; + log_info("getUIBCGenericTouchPacket numberOfPointers=[%d]\n", numberOfPointers); + for (int i = 0; i < numberOfPointers; i++) { + int splitoffset = offset_split + (i * 3); + temp = atoi(*(splitedStr + splitoffset++)); + offset = offset_header + ( i * 5); + outData[offset++] = temp & 0xFF; + log_info("getUIBCGenericTouchPacket PointerId=[%d]\n", temp); + + temp = atoi(*(splitedStr + splitoffset++)); + temp = (int32_t)((double)temp / widthRatio); + log_info("getUIBCGenericTouchPacket X-coordinate=[%d]\n", temp); + outData[offset++] = (temp >> 8) & 0xFF; + outData[offset++] = temp & 0xFF; + + temp = atoi(*(splitedStr + splitoffset++)); + temp = (int32_t)((double)temp / heightRatio); + log_info("getUIBCGenericTouchPacket Y-coordinate=[%d]\n", temp); + outData[offset++] = (temp >> 8) & 0xFF; + outData[offset++] = temp & 0xFF; + } + + while (offset <= uibcBodyLen) { + outData[offset++] = 0x00; + } + + for (int i = 0; i < size; i++) { + free(*(splitedStr + i)); + } + free(splitedStr); + + binarydump(outData, uibcBodyLen); + uibcmessage->m_DataValid = true; + uibcmessage->m_PacketData = outData; + uibcmessage->m_PacketDataLen = uibcBodyLen; +} + +void hexdump(void *_data, size_t len) +{ + unsigned char *data = _data; + int count; + + int line = 15; + for (count = 0; count < len; count++) { + if ((count & line) == 0) { + fprintf(stderr,"%04zu: ", count); + } + fprintf(stderr,"%02x ", *data); + data++; + if ((count & line) == line) { + fprintf(stderr,"\n"); + } + } + if ((count & line) != 0) { + fprintf(stderr,"\n"); + } +} + +void binarydump(void *_data, size_t len) +{ + unsigned char *data = _data; + int count; + + int line = 7; + for (count = 0; count < len; count++) { + if ((count & line) == 0) { + fprintf(stderr,"%04zu: ", count); + } + fprintf(stderr,"%s ", int2binary(*data, 8)); + data++; + if ((count & line) == line) { + fprintf(stderr,"\n"); + } + } + if ((count & line) != 0) { + fprintf(stderr,"\n"); + } +} +// format: "typeId, Key code 1(0x00), Key code 2(0x00)" +void getUIBCGenericKeyPacket(const char *inEventDesc, + UibcMessage* uibcmessage) { + log_info("getUIBCGenericKeyPacket (%s)", inEventDesc); + char* outData = uibcmessage->m_PacketData; + int32_t typeId = 0; + int32_t uibcBodyLen = 0; + int32_t genericPacketLen = 0; + int32_t temp = 0; + size_t size; + char** splitedStr = str_split((char*)inEventDesc, ",", &size); + + if (size > 0) { + + if (((int)size) % 3 != 0) { + log_error("getUIBCGenericKeyPacket (%s)", "bad input event"); + return; + } + int i; + for (i = 0; i < size; i++) { + log_info("getUIBCGenericKeyPacket splitedStr tokens=[%s]\n", *(splitedStr + i)); + + switch (i) { + case 0: { + typeId = atoi(*(splitedStr + i)); + log_info("getUIBCGenericKeyPacket typeId=[%d]\n", typeId); + genericPacketLen = 5; + uibcBodyLen = genericPacketLen + 7; // Generic header legth = 7 + outData = (char*)malloc(uibcBodyLen + 1); + // UIBC header + outData[0] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[1] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[2] = (uibcBodyLen >> 8) & 0xFF; //Length(16 bits) + outData[3] = uibcBodyLen & 0xFF; //Length(16 bits) + //Generic Input Body Format + outData[4] = typeId & 0xFF; // Tyoe ID, 1 octet + outData[5] = (genericPacketLen >> 8) & 0xFF; // Length, 2 octets + outData[6] = genericPacketLen & 0xFF; // Length, 2 octets + outData[7] = 0x00; // reserved + break; + } + case 1: { + sscanf(*(splitedStr + i), " 0x%04X", &temp); + if (temp == 0) { + outData[8] = 0x00; + outData[9] = 0x00; + } + log_info("getUIBCGenericKeyPacket key code 1=[%d]\n", temp); + outData[8] = (temp >> 8) & 0xFF; + outData[9] = temp & 0xFF; + + break; + } + case 2: { + sscanf(*(splitedStr + i), " 0x%04X", &temp); + if (temp == 0) { + outData[10] = 0x00; + outData[11] = 0x00; + } + log_info("getUIBCGenericKeyPacket key code 2=[%d]\n", temp); + outData[10] = (temp >> 8) & 0xFF; + outData[11] = temp & 0xFF; + + break; + } + default: { + } + break; + } + free(*(splitedStr + i)); + } + } + free(splitedStr); + + binarydump(outData, uibcBodyLen); + uibcmessage->m_DataValid = true; + uibcmessage->m_PacketData = outData; + uibcmessage->m_PacketDataLen = uibcBodyLen; +} + +// format: "typeId, X coordnate, Y coordnate, integer part, fraction part" +void getUIBCGenericZoomPacket(const char *inEventDesc, UibcMessage* uibcmessage) { + log_info("getUIBCGenericZoomPacket (%s)", inEventDesc); + char* outData = uibcmessage->m_PacketData; + int32_t typeId; + int32_t uibcBodyLen, genericPacketLen; + int32_t xCoord, yCoord, integerPart, FractionPart; + size_t size; + + char** splitedStr = str_split((char*)inEventDesc, ",", &size); + + if (splitedStr) { + int i; + for (i = 0; * (splitedStr + i); i++) { + //log_info("getUIBCGenericZoomPacket splitedStr tokens=[%s]\n", *(splitedStr + i)); + + switch (i) { + case 0: { + typeId = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericZoomPacket typeId=[%d]\n", typeId); + + genericPacketLen = 6; + uibcBodyLen = genericPacketLen + 7; // Generic herder leh = 7 + outData = (char*)malloc(uibcBodyLen + 1); + // UIBC header + outData[0] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[1] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[2] = (uibcBodyLen >> 8) & 0xFF; //Length(16 bits) + outData[3] = uibcBodyLen & 0xFF; //Length(16 bits) + //Generic Input Body Format + outData[4] = typeId & 0xFF; // Tyoe ID, 1 octet + outData[5] = (genericPacketLen >> 8) & 0xFF; // Length, 2 octets + outData[6] = genericPacketLen & 0xFF; // Length, 2 octets + break; + } + + case 1: { + xCoord = atoi(*(splitedStr + i)); + outData[7] = (xCoord >> 8) & 0xFF; + outData[8] = xCoord & 0xFF; + log_info("getUIBCGenericZoomPacket xCoord=[%d]\n", xCoord); + break; + } + case 2: { + yCoord = atoi(*(splitedStr + i)); + log_info("getUIBCGenericZoomPacket yCoord=[%d]\n", yCoord); + break; + } + case 3: { + integerPart = atoi(*(splitedStr + i)); + outData[11] = integerPart & 0xFF; + //log_info("getUIBCGenericZoomPacket integerPart=[%d]\n", integerPart); + break; + } + case 4: { + FractionPart = atoi(*(splitedStr + i)); + outData[12] = FractionPart & 0xFF; + //log_info("getUIBCGenericZoomPacket FractionPart=[%d]\n", FractionPart); + + break; + } + default: { + break; + } + } + + free(*(splitedStr + i)); + } + free(splitedStr); + } + //hexdump(outData, uibcBodyLen); + uibcmessage->m_DataValid = true; + uibcmessage->m_PacketDataLen = uibcBodyLen; +} + +// format: "typeId, unit, direction, amount to scroll" +void getUIBCGenericScalePacket(const char *inEventDesc, UibcMessage* uibcmessage) { + log_info("getUIBCGenericScalePacket (%s)", inEventDesc); + char* outData = uibcmessage->m_PacketData; + int32_t typeId; + int32_t uibcBodyLen, genericPacketLen; + int32_t temp; + size_t size; + char** splitedStr = str_split((char*)inEventDesc, ",", &size); + + if (splitedStr) { + int i; + for (i = 0; * (splitedStr + i); i++) { + //log_info("getUIBCGenericScalePacket splitedStr tokens=[%s]\n", *(splitedStr + i)); + + switch (i) { + case 0: { + typeId = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericScalePacket typeId=[%d]\n", typeId); + genericPacketLen = 2; + uibcBodyLen = genericPacketLen + 7; // Generic herder leh = 7 + outData = (char*)malloc(uibcBodyLen + 1); + // UIBC header + outData[0] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[1] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[2] = (uibcBodyLen >> 8) & 0xFF; //Length(16 bits) + outData[3] = uibcBodyLen & 0xFF; //Length(16 bits) + //Generic Input Body Format + outData[4] = typeId & 0xFF; // Tyoe ID, 1 octet + outData[5] = (genericPacketLen >> 8) & 0xFF; // Length, 2 octets + outData[6] = genericPacketLen & 0xFF; // Length, 2 octets + outData[7] = 0x00; // Clear the byte + outData[8] = 0x00; // Clear the byte + /* + B15B14; Scroll Unit Indication bits. + 0b00; the unit is a pixel (normalized with respect to the WFD Source display resolution that is conveyed in an RTSP M4 request message). + 0b01; the unit is a mouse notch (where the application is responsible for representing the number of pixels per notch). + 0b10-0b11; Reserved. + + B13; Scroll Direction Indication bit. + 0b0; Scrolling to the right. Scrolling to the right means the displayed content being shifted to the left from a user perspective. + 0b1; Scrolling to the left. Scrolling to the left means the displayed content being shifted to the right from a user perspective. + +B12:B0; Number of Scroll bits. +Number of units for a Horizontal scroll. +*/ + break; + } + case 1: { + temp = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericScalePacket unit=[%d]\n", temp); + outData[7] = (temp >> 8) & 0xFF; + break; + } + case 2: { + temp = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericScalePacket direction=[%d]\n", temp); + outData[7] |= ((temp >> 10) & 0xFF); + break; + + } + case 3: { + temp = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericScalePacket amount to scroll=[%d]\n", temp); + outData[7] |= ((temp >> 12) & 0xFF); + outData[8] = temp & 0xFF; + + break; + } + default: { + break; + } + } + + free(*(splitedStr + i)); + } + + free(splitedStr); + } + //hexdump(outData, uibcBodyLen); + uibcmessage->m_DataValid = true; + uibcmessage->m_PacketDataLen = uibcBodyLen; +} + +// format: "typeId, integer part, fraction part" +void getUIBCGenericRotatePacket(const char * inEventDesc, UibcMessage* uibcmessage) { + log_info("getUIBCGenericRotatePacket (%s)", inEventDesc); + char* outData = uibcmessage->m_PacketData; + int32_t typeId; + int32_t uibcBodyLen, genericPacketLen; + int32_t integerPart, FractionPart; + size_t size; + + char** splitedStr = str_split((char*)inEventDesc, ",", &size); + + if (splitedStr) { + int i; + for (i = 0; * (splitedStr + i); i++) { + //log_info("getUIBCGenericRotatePacket splitedStr tokens=[%s]\n", *(splitedStr + i)); + + switch (i) { + case 0: { + typeId = atoi(*(splitedStr + i)); + //log_info("getUIBCGenericRotatePacket typeId=[%d]\n", typeId); + genericPacketLen = 2; + uibcBodyLen = genericPacketLen + 7; // Generic herder leh = 7 + outData = (char*)malloc(uibcBodyLen + 1); + // UIBC header + outData[0] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[1] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) + outData[2] = (uibcBodyLen >> 8) & 0xFF; //Length(16 bits) + outData[3] = uibcBodyLen & 0xFF; //Length(16 bits) + //Generic Input Body Format + outData[4] = typeId & 0xFF; // Tyoe ID, 1 octet + outData[5] = (genericPacketLen >> 8) & 0xFF; // Length, 2 octets + outData[6] = genericPacketLen & 0xFF; // Length, 2 octets + break; + } + case 1: { + integerPart = atoi(*(splitedStr + i)); + outData[7] = integerPart & 0xFF; + //log_info("getUIBCGenericRotatePacket integerPart=[%d]\n", integerPart); + break; + } + case 2: { + FractionPart = atoi(*(splitedStr + i)); + outData[8] = FractionPart & 0xFF; + //log_info("getUIBCGenericRotatePacket FractionPart=[%d]\n", FractionPart); + + break; + } + default: { + break; + } + } + free(*(splitedStr + i)); + } + + free(splitedStr); + } + //hexdump(outData, uibcBodyLen); + uibcmessage->m_DataValid = true; + uibcmessage->m_PacketDataLen = uibcBodyLen; +} + + +char** str_split(char* pStr, const char* pDelim, size_t* size) { + char** result = 0; + size_t count = 0; + char* tmp = pStr; + char* tmpStr = NULL; + char* last_comma = 0; + + asprintf(&tmpStr, "%s", pStr); + + /* Count how many elements will be extracted. */ + while (*tmp) { + if (*pDelim == *tmp) { + count++; + last_comma = tmp; + } + tmp++; + } + + /* Add space for trailing token. */ + count += last_comma < (pStr + strlen(pStr) - 1) ? 1 : 0; + + result = (char**)malloc(sizeof(char*) * count); + + *size = count; + + tmp = tmpStr = strdup(pStr); + size_t idx = 0; + char* token; + while ((token = strsep(&tmp, pDelim)) != NULL) { + * (result + idx++) = strdup(token); + } + free(tmpStr); + return result; +} diff --git a/src/uibc/miracle-uibcctl.h b/src/uibc/miracle-uibcctl.h new file mode 100644 index 0000000..1398011 --- /dev/null +++ b/src/uibc/miracle-uibcctl.h @@ -0,0 +1,48 @@ + +#ifndef MIRACLE_UIBCCTL_H +#define MIRACLE_UIBCCTL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shl_log.h" + +typedef enum { + GENERIC_TOUCH_DOWN = 0, + GENERIC_TOUCH_UP, + GENERIC_TOUCH_MOVE, + GENERIC_KEY_DOWN, + GENERIC_KEY_UP, + GENERIC_ZOOM, + GENERIC_VERTICAL_SCROLL, + GENERIC_HORIZONTAL_SCROLL, + GENERIC_ROTATE +} MessageType; + +typedef struct { + char* m_PacketData; + size_t m_PacketDataLen; + bool m_DataValid; +} UibcMessage; + +UibcMessage buildUibcMessage(MessageType type, const char* inEventDesc, double widthRatio, double heightRatio); + +static char** str_split(char* pStr, const char* pDelim, size_t* size); + +void getUIBCGenericTouchPacket(const char *inEventDesc, UibcMessage* uibcmessage, double widthRatio, double heightRatio); +void getUIBCGenericKeyPacket(const char *inEventDesc, UibcMessage* uibcmessage); +void getUIBCGenericZoomPacket(const char *inEventDesc,UibcMessage* uibcmessage); +void getUIBCGenericScalePacket(const char *inEventDesc, UibcMessage* uibcmessage); +void getUIBCGenericRotatePacket(const char *inEventDesc, UibcMessage* uibcmessage); + +void hexdump(void *_data, size_t len); +void binarydump(void *_data, size_t len); + +int sendUibcMessage(UibcMessage* uibcmessage, int sockfd); +#endif From 0ac755a7655448a3579919a6cf86c854f0792320 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 2 Jul 2016 16:06:02 +0200 Subject: [PATCH 010/142] Add technical specs relates #38 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f91f59..5a4dfb8 100644 --- a/README.md +++ b/README.md @@ -171,4 +171,4 @@ If you have any questions, do not hesitate to contact one of the maintainers. - Website: http://www.freedesktop.org/wiki/Software/miracle - Original repo: git://people.freedesktop.org/~dvdhrm/miracle - Fork repo: https://github.com/albfan/miraclecast - +- Technical spec: https://www.wi-fi.org/file/wi-fi-display-technical-specification-v11 (free registration required) From 349db0f04a26c09a63711414f6a16857c15398c2 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 2 Jul 2016 16:15:09 +0200 Subject: [PATCH 011/142] help functions for arch linux --- res/miracle-gst.sh | 62 -------------------------------------------- res/miracle-utils.sh | 28 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 62 deletions(-) delete mode 100755 res/miracle-gst.sh diff --git a/res/miracle-gst.sh b/res/miracle-gst.sh deleted file mode 100755 index 99749d5..0000000 --- a/res/miracle-gst.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -DEBUG='0' -AUDIO='0' -SCALE='0' - -while getopts "r:d:as:" optname - do - case "$optname" in - "d") - DEBUG=`echo ${OPTARG} | tr -d ' '` - ;; - "r") - RESOLUTION=`echo ${OPTARG} | tr -d ' '` - ;; - "a") - AUDIO='1' - ;; - "s") - SCALE='1' - WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1` - HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2` - ;; - "?") - echo "Unknown option $OPTARG" - ;; - *) - # Should not occur - echo "Unknown error while processing options" - ;; - esac - done - -RUN="/usr/bin/gst-launch-1.0 -v " -if [ $DEBUG != '0' ] -then - RUN+="--gst-debug=${DEBUG} " -fi - -RUN+="udpsrc port=1991 caps=\"application/x-rtp, media=video\" ! rtpjitterbuffer latency=100 ! rtpmp2tdepay ! tsdemux " - -if [ $AUDIO == '1' ] -then - RUN+="name=demuxer demuxer. " -fi - -RUN+="! queue max-size-buffers=0 max-size-time=0 ! h264parse ! avdec_h264 ! videoconvert ! " - -if [ $SCALE == '1' ] -then - RUN+="videoscale method=1 ! video/x-raw,width=${WIDTH},height=${HEIGHT} ! " -fi - -RUN+="autovideosink " - -if [ $AUDIO == '1' ] -then - RUN+="demuxer. ! queue max-size-buffers=0 max-size-time=0 ! aacparse ! avdec_aac ! audioconvert ! audioresample ! autoaudiosink " -fi - -echo "running: $RUN" -exec ${RUN} diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index 12186c5..577fe41 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -101,6 +101,12 @@ function find_wpa_supplicant_pid { show_wpa_supplicant_process | awk '{print $2}' } +# +# checking if distro is archlinux +# +function check_archlinux_distro { + test -f "/etc/arch-release" +} # # checking if distro is ubuntu # @@ -119,6 +125,17 @@ function kill_ubuntu_network_manager { fi } +# +# arch linux manager restarts automatically wpa_supplicant +# +function kill_archlinux_network_manager { + if check_ubuntu_distro + then + echo stopping NetworkManager + sudo systemctl stop Network.service + fi +} + # # start ubuntu manager # @@ -129,3 +146,14 @@ function start_ubuntu_network_manager { sudo service NetworkManager start fi } + +# +# start arch linux manager +# +function start_archlinux_network_manager { + if check_archlinux_distro + then + echo starting NetworkManager + sudo systemctl start Network.service + fi +} From 42820c00baba22821a22fb945efe1d7d6c97e6a9 Mon Sep 17 00:00:00 2001 From: albfan Date: Tue, 5 Jul 2016 23:13:54 +0200 Subject: [PATCH 012/142] Add check cflags on cmake closes #82 closes #85 --- test/CMakeLists.txt | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 01bf9bf..bb99d34 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,32 +1,33 @@ ########### next target ############### -find_package(PkgConfig) -pkg_check_modules (CHECK check) - -set(test_rtsp_SOURCES test_common.h test_rtsp.c) -add_executable(test_rtsp ${test_rtsp_SOURCES}) -target_link_libraries(test_rtsp miracle-shared) -target_link_libraries(test_rtsp ${UDEV_LIBRARIES}) -target_link_libraries(test_rtsp ${GLIB2_LIBRARIES}) - -set(test_wpas_SOURCES test_common.h test_wpas.c) -add_executable(test_wpas ${test_wpas_SOURCES}) -target_link_libraries(test_wpas miracle-shared) -target_link_libraries(test_wpas ${UDEV_LIBRARIES}) -target_link_libraries(test_wpas ${GLIB2_LIBRARIES}) - if(CHECK_FOUND) + find_package(PkgConfig) + pkg_check_modules (CHECK check) + + set(test_rtsp_SOURCES test_common.h test_rtsp.c) + add_executable(test_rtsp ${test_rtsp_SOURCES}) + target_link_libraries(test_rtsp miracle-shared) + target_link_libraries(test_rtsp ${UDEV_LIBRARIES}) + target_link_libraries(test_rtsp ${GLIB2_LIBRARIES}) target_link_libraries(test_rtsp ${CHECK_LIBRARIES}) - + target_link_libraries(test_rtsp ${CHECK_CFLAGS}) + + set(test_wpas_SOURCES test_common.h test_wpas.c) + add_executable(test_wpas ${test_wpas_SOURCES}) + target_link_libraries(test_wpas miracle-shared) + target_link_libraries(test_wpas ${UDEV_LIBRARIES}) + target_link_libraries(test_wpas ${GLIB2_LIBRARIES}) target_link_libraries(test_wpas ${CHECK_LIBRARIES}) + target_link_libraries(test_wpas ${CHECK_CFLAGS}) set(test_valgrind_SOURCES test_common.h test_valgrind.c) add_executable(test_valgrind ${test_valgrind_SOURCES}) target_link_libraries(test_valgrind miracle-shared) - target_link_libraries(test_valgrind ${CHECK_LIBRARIES}) target_link_libraries(test_valgrind ${UDEV_LIBRARIES}) target_link_libraries(test_valgrind ${GLIB2_LIBRARIES}) + target_link_libraries(test_valgrind ${CHECK_LIBRARIES}) + target_link_libraries(test_valgrind ${CHECK_CFLAGS}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/shared) From 3f2266e2540f6b767d2a260aca13ba29e0cb9cd2 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 16 Jul 2016 12:26:40 +0200 Subject: [PATCH 013/142] Kill uibc viewer subprocess closes #93 --- res/uibc-viewer | 13 ++++++++++++- src/uibc/miracle-uibcctl.c | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/res/uibc-viewer b/res/uibc-viewer index 40365c9..90c623e 100755 --- a/res/uibc-viewer +++ b/res/uibc-viewer @@ -1,8 +1,19 @@ #!/bin/bash +function kill_child() { + CHILDREN="$(ps -o pid= --ppid $$)" + echo killing $CHILDREN + kill $CHILDREN +} + IP=$1 shift UIBC_PORT=$1 shift -gstplayer $@ | miracle-uibcctl $IP $UIBC_PORT --daemon +echo $$ + +trap 'kill_child' SIGTERM + +gstplayer $@ | miracle-uibcctl $IP $UIBC_PORT --daemon & +wait diff --git a/src/uibc/miracle-uibcctl.c b/src/uibc/miracle-uibcctl.c index 39bc42c..79b92e0 100644 --- a/src/uibc/miracle-uibcctl.c +++ b/src/uibc/miracle-uibcctl.c @@ -56,20 +56,22 @@ int main(int argc, char *argv[]) { bzero(buffer, 256); fgets(buffer, 255, stdin); if (buffer == NULL) { - break; + break; } - if (daemon) { - printf("input: %s", buffer); + if (!daemon) { + printf("input: %s", buffer); } char type = buffer[0]; UibcMessage uibcmessage; if (type == '0' || type == '1') { - uibcmessage = buildUibcMessage(GENERIC_TOUCH_DOWN, buffer, 1, 1); + uibcmessage = buildUibcMessage(GENERIC_TOUCH_DOWN, buffer, 1, 1); } else if (type == '3' || type == '4') { - uibcmessage = buildUibcMessage(GENERIC_KEY_DOWN, buffer, 1, 1); + uibcmessage = buildUibcMessage(GENERIC_KEY_DOWN, buffer, 1, 1); } else { + if (!daemon) { printf("unknow event type: %s", buffer); - continue; + } + continue; } r = sendUibcMessage(&uibcmessage, sockfd); @@ -86,8 +88,7 @@ const char *int2binary(int x, int padding) { char *b; int min_padding = x > 0 ? floor(log2(x)) : 0; - if (padding < min_padding) - { + if (padding < min_padding) { padding = min_padding; } @@ -95,8 +96,7 @@ const char *int2binary(int x, int padding) strcpy(b, ""); int z; - for (z = pow(2,padding); z > 0; z >>= 1) - { + for (z = pow(2,padding); z > 0; z >>= 1) { strcat(b, ((x & z) == z) ? "1" : "0"); } @@ -176,8 +176,8 @@ void getUIBCGenericTouchPacket(const char *inEventDesc, char** splitedStr = str_split((char*)inEventDesc, ",", &size); if ((int)size - 5 < 0 || ((int)size - 5) % 3 != 0) { - log_error("getUIBCGenericTouchPacket (%s)", "bad input event"); - return; + log_error("getUIBCGenericTouchPacket (%s)", "bad input event"); + return; } int offset_split = 0; typeId = atoi(*(splitedStr + offset_split++)); From 412ce067b613cdbc8e269242a6436e5fc90bb585 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 23 Jul 2016 19:15:38 +0200 Subject: [PATCH 014/142] Use resolution provided to resize viewer --- res/gstplayer | 12 +++++++----- src/ctl/sinkctl.c | 26 ++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/res/gstplayer b/res/gstplayer index b1d3c08..d20d53f 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -19,12 +19,14 @@ Gst.init(None) class Player(object): def __init__(self, **kwargs): + resolution = kwargs.get("resolution") + if resolution: + split = resolution.split("x") + self.width = int(split[0]) + self.height = int(split[1]) + scale = kwargs.get("scale") - #scale = "1080x1920" - if not scale: - self.width = 800 - self.height = 600 - else: + if scale: split = scale.split("x") self.width = int(split[0]) self.height = int(split[1]) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e594a50..5c335f2 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -389,7 +389,6 @@ void launch_player(struct ctl_sink *s) { int i = 0; char* player; if (uibc) { -// player = "gstplayer"; player = "uibc-viewer"; } else { player = "miracle-gst"; @@ -400,27 +399,26 @@ void launch_player(struct ctl_sink *s) { argv[i++] = s->target; sprintf(uibc_portStr, "%d", uibc_port); argv[i++] = uibc_portStr; -// argv[i++] = "--daemon"; } - if (cli_max_sev >= 7) - argv[i++] = "-d 3"; - if (gst_audio_en) - argv[i++] = "-a"; - if (gst_scale_res) { - argv[i++] = "-s"; - argv[i++] = gst_scale_res; - } + if (cli_max_sev >= 7) + argv[i++] = "-d 3"; + if (gst_audio_en) + argv[i++] = "-a"; + if (gst_scale_res) { + argv[i++] = "-s"; + argv[i++] = gst_scale_res; + } argv[i++] = "-p"; sprintf(port, "%d", rstp_port); argv[i++] = port; if (s->hres && s->vres) { sprintf(resolution, "%dx%d", s->hres, s->vres); - argv[i++] = "-r"; - argv[i++] = resolution; - } + argv[i++] = "-r"; + argv[i++] = resolution; + } - argv[i] = NULL; + argv[i] = NULL; i = 0; int size = 0; From 7228c3e63d6f5bd847b92bd1a86bf2ac2af39a6f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Thu, 30 Jun 2016 13:31:31 +0200 Subject: [PATCH 015/142] Change to support CI environment --- CMakeLists.txt | 3 ++- src/wifi/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60e2969..0877bed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 2.8) project(Miraclecast) SET(PACKAGE_NAME miraclecast) @@ -11,6 +11,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}") add_definitions(-D_GNU_SOURCE) +SET(BUILD_BINDIR "${CMAKE_INSTALL_PREFIX}/bin") OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) OPTION(BUILD_TESTS "Enable TEST" ON ) diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index 566df22..c041e34 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(miracle-wifid ${miracle-wifid_SRCS}) target_link_libraries(miracle-wifid ${KDE4_KDECORE_LIBS}) +cmake_policy(SET CMP0015 NEW) include_directories(shared) link_directories(shared) target_link_libraries(miracle-wifid miracle-shared) From 44625ff4fcf3b2b5aca22dbb037c9692bc6d822a Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 10 Aug 2016 16:42:35 +0800 Subject: [PATCH 016/142] specify GdkX11 version before import it --- res/gstplayer | 1 + 1 file changed, 1 insertion(+) diff --git a/res/gstplayer b/res/gstplayer index d20d53f..c777366 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -7,6 +7,7 @@ import argparse gi.require_version('Gst', '1.0') gi.require_version('Gtk', '3.0') gi.require_version('GstVideo', '1.0') +gi.require_version('GdkX11', '3.0') from gi.repository import GObject, Gst, Gtk, Gdk, GLib From e863a4498d0c5fd585b21669d94dabcb14ff8b2e Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 10 Aug 2016 16:43:33 +0800 Subject: [PATCH 017/142] add dependency to libsystemd to the root CMakeLists.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0877bed..a04350f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ OPTION(BUILD_TESTS "Enable TEST" ON ) find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) +pkg_check_modules (SYSTEMD REQUIRED libsystemd) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) From fc6f19d1328ec2cf4d582395da9ef1ae40f8f959 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 10 Aug 2016 16:44:38 +0800 Subject: [PATCH 018/142] pkg_check_modules() before if(CHECK_FOUND) --- test/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bb99d34..a6e3b44 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,10 +1,10 @@ ########### next target ############### -if(CHECK_FOUND) - find_package(PkgConfig) - pkg_check_modules (CHECK check) +find_package(PkgConfig) +pkg_check_modules (CHECK check) +if(CHECK_FOUND) set(test_rtsp_SOURCES test_common.h test_rtsp.c) add_executable(test_rtsp ${test_rtsp_SOURCES}) target_link_libraries(test_rtsp miracle-shared) From 99ed3efd8801f638772d6e1c05f120a80f2551b7 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 10 Aug 2016 17:11:01 +0800 Subject: [PATCH 019/142] fix typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a4dfb8..0e03657 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Steps to use it as peer: 4. Locate them using scanning - > psp-scan + > p2p-scan 5. Apart from list, or show info with peer <mac> there's nothing useful here by now. For a Q&D see [Using as peer](https://github.com/albfan/miraclecast/issues/4) From 6dd107a2fdf8093ba9fa8b22d4e3c32e620a962b Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Thu, 11 Aug 2016 17:37:59 +0800 Subject: [PATCH 020/142] since shl_log.h does not include config.h, define BUILD_ENABLE_DEBUG through add_definitions() instead of config.h.cmake --- CMakeLists.txt | 4 ++++ config.h.cmake | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a04350f..6aea926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) OPTION(BUILD_TESTS "Enable TEST" ON ) +if(BUILD_ENABLE_DEBUG) + add_definitions(-DBUILD_ENABLE_DEBUG) +endif() + find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) diff --git a/config.h.cmake b/config.h.cmake index dd6b763..ddc0cd1 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,8 +1,6 @@ #ifndef CONFIG_H #define CONFIG_H -#cmakedefine BUILD_ENABLE_DEBUG - #cmakedefine BUILD_BINDIR "@BUILD_BINDIR@" #cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" From 7fc8d0884c86eb76efecbc6e96a5ba4287dbc0e8 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Mon, 15 Aug 2016 11:15:12 +0800 Subject: [PATCH 021/142] add debian support to miracle-utils.sh and normal-wifi.sh --- README.md | 2 +- res/miracle-utils.sh | 10 ++++++++-- res/normal-wifi.sh | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0e03657..06678d7 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ If you feel confidence enough (since systemd is the entrypoint for an OS) extrac Steps to use it as sink: - 1. shutdown wpa_supplicant + 1. shutdown wpa_supplicant and NetworkManager $ sudo kill -9 $(ps -ef | grep wpa_supplican[t] | awk '{print $2}') # now you can use `res/kill-wpa.sh` diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index 577fe41..e938055 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -113,12 +113,18 @@ function check_archlinux_distro { function check_ubuntu_distro { cat /proc/version | grep -i ubuntu } +# +# checking if distro is debian +# +function check_debian_distro { + cat /proc/version | grep -i debian +} # # ubuntu manager restarts automatically wpa_supplicant # function kill_ubuntu_network_manager { - if check_ubuntu_distro + if check_ubuntu_distro || check_debian_distro then echo stopping NetworkManager sudo service NetworkManager stop @@ -140,7 +146,7 @@ function kill_archlinux_network_manager { # start ubuntu manager # function start_ubuntu_network_manager { - if check_ubuntu_distro + if check_ubuntu_distro || check_debian_distro then echo starting NetworkManager sudo service NetworkManager start diff --git a/res/normal-wifi.sh b/res/normal-wifi.sh index 230f4db..1e03201 100755 --- a/res/normal-wifi.sh +++ b/res/normal-wifi.sh @@ -47,7 +47,7 @@ CONFIG_FILE=${1:-/run/network/wpa_supplicant_${ETHERNAME}.conf} echo starting wpa_supplicant for normal connection -if check_ubuntu_distro +if check_ubuntu_distro || check_debian_distro then start_ubuntu_network_manager sudo wpa_supplicant -B -u -s -O /var/run/wpa_supplicant From 4601514799e4b1e017d5c723e69a4fbbefd693e7 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Mon, 15 Aug 2016 17:35:38 +0800 Subject: [PATCH 022/142] find wpa_supplicant through PATH instead of option --wpa-bindir --- src/wifi/wifid-supplicant.c | 56 ++++++++++++++++++++++++++++++++----- src/wifi/wifid.c | 7 ----- src/wifi/wifid.h | 1 - 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index e05a0cc..305b4bd 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -2401,6 +2402,49 @@ static void supplicant_run(struct supplicant *s, const char *binary) execve(argv[0], argv, environ); } +static int supplicant_find(char **binary) +{ + _shl_free_ char *path = getenv("PATH"); + if(!path) { + return -EINVAL; + } + + path = strdup(path); + if(!path) { + return log_ENOMEM(); + } + + struct stat bin_stat; + char *curr = path, *next; + while(1) { + curr = strtok_r(curr, ":", &next); + if(!curr) { + break; + } + + _shl_free_ char *bin = shl_strcat(curr, "/wpa_supplicant"); + if (!bin) + return log_ENOMEM(); + + if(stat(bin, &bin_stat) < 0) { + if(ENOENT == errno) { + goto end; + } + return log_ERRNO(); + } + + if (!access(bin, X_OK)) { + *binary = strdup(bin); + return 0; + } + +end: + curr = NULL; + } + + return -EINVAL; +} + static int supplicant_spawn(struct supplicant *s) { _shl_free_ char *binary = NULL; @@ -2414,14 +2458,12 @@ static int supplicant_spawn(struct supplicant *s) log_debug("spawn supplicant of %s", s->l->ifname); - binary = shl_strcat(arg_wpa_bindir, "/wpa_supplicant"); - if (!binary) - return log_ENOMEM(); + if (supplicant_find(&binary) < 0) { + log_error("execution of wpas (%s) not possible: %m", binary); + return -EINVAL; + } - if (access(binary, X_OK) < 0) { - log_error("execution of wpas (%s) not possible: %m", binary); - return -EINVAL; - } + log_info("wpa_supplicant found: %s", binary); pid = fork(); if (pid < 0) { diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 9bfd2a8..9533206 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -40,7 +40,6 @@ #include "wifid.h" #include "config.h" -const char *arg_wpa_bindir = "/usr/bin"; const char *interface_name = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; @@ -457,7 +456,6 @@ static int help(void) "\n" " -i --interface Choose the interface to use\n" "\n" - " --wpa-bindir wpa_supplicant binary dir [/usr/bin]\n" " --wpa-loglevel Date: Tue, 16 Aug 2016 14:05:24 -0700 Subject: [PATCH 023/142] Add uibc-viewer to CMake install list --- res/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index da37a71..2f265e7 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -1,7 +1,7 @@ ########### install files ############### -install(FILES miracle-gst gstplayer DESTINATION bin) +install(FILES miracle-gst gstplayer uibc-viewer DESTINATION bin) From b6400aa14a94da660d8f77f2f8049bee5bf44ddf Mon Sep 17 00:00:00 2001 From: Tony Y Date: Tue, 16 Aug 2016 17:09:39 -0700 Subject: [PATCH 024/142] CMake: correctly set file permissions When building using CMake, the display would not appear because the files did not have execute permissions. --- res/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 2f265e7..c295067 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -1,7 +1,11 @@ ########### install files ############### -install(FILES miracle-gst gstplayer uibc-viewer DESTINATION bin) +install( + FILES miracle-gst gstplayer uibc-viewer + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + DESTINATION bin + ) From 59ea55c28c4a439e1465986536f6a16d37649197 Mon Sep 17 00:00:00 2001 From: Tony Y Date: Thu, 18 Aug 2016 09:19:47 -0700 Subject: [PATCH 025/142] CMake: use PROGRAMS during install During install, PROGRAMS (instead of FILES) will set execute permissions for all targets. --- res/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index c295067..05db87f 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -2,8 +2,7 @@ ########### install files ############### install( - FILES miracle-gst gstplayer uibc-viewer - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + PROGRAMS miracle-gst gstplayer uibc-viewer DESTINATION bin ) From 28252707a2689ae0ec3a9a239f7f06675ba94d92 Mon Sep 17 00:00:00 2001 From: albfan Date: Mon, 22 Aug 2016 03:08:40 +0200 Subject: [PATCH 026/142] Install dbus policy closes #107 --- autogen.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++- res/CMakeLists.txt | 10 +++----- res/Makefile.am | 3 +++ 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/autogen.sh b/autogen.sh index 3c5fdcb..60be64e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,2 +1,62 @@ #!/bin/sh -autoreconf -f --install + +set -e + +oldpwd=$(pwd) +topdir=$(dirname $0) +cd $topdir + +#intltoolize --force --automake +autoreconf --force --install --symlink + +libdir() { + echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd) +} + +args="\ +--sysconfdir=/etc \ +--localstatedir=/var \ +--libdir=$(libdir /usr/lib) \ +" + +if [ -f "$topdir/.config.args" ]; then + args="$args $(cat $topdir/.config.args)" +fi + +cd $oldpwd + +if [ "x$1" = "xc" ]; then + $topdir/configure CFLAGS='-g -O0 -ftrapv' $args + make clean +elif [ "x$1" = "xg" ]; then + $topdir/configure CFLAGS='-g -Og -ftrapv' $args + make clean +elif [ "x$1" = "xa" ]; then + $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args + make clean +elif [ "x$1" = "xl" ]; then + $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args + make clean +elif [ "x$1" = "xs" ]; then + scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' $args + scan-build make +else + cat < Date: Fri, 26 Aug 2016 06:29:34 +0200 Subject: [PATCH 027/142] Fix wpa_supplicant search when path did not exists --- src/wifi/wifid-supplicant.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 305b4bd..6a49fa4 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2427,7 +2427,7 @@ static int supplicant_find(char **binary) return log_ENOMEM(); if(stat(bin, &bin_stat) < 0) { - if(ENOENT == errno) { + if(ENOENT == errno || ENOTDIR == errno) { goto end; } return log_ERRNO(); From 1cc667a00caa830b90e71d2f5c4e3a321cf2e73e Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 14 Sep 2016 10:57:46 +0800 Subject: [PATCH 028/142] don't modify raw message --- src/shared/wpas.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/shared/wpas.c b/src/shared/wpas.c index 4b2adea..171a472 100644 --- a/src/shared/wpas.c +++ b/src/shared/wpas.c @@ -742,6 +742,7 @@ static int wpas__parse_message(struct wpas *w, const char *ifname = NULL; unsigned int level; char *pos; + char *orig_raw = raw; int r, num; bool is_event = false; @@ -751,7 +752,7 @@ static int wpas__parse_message(struct wpas *w, ifname = pos; pos = strchrnul(pos, ' '); if (*pos) - *pos++ = 0; + pos++; len -= pos - raw; raw = pos; @@ -811,15 +812,12 @@ static int wpas__parse_message(struct wpas *w, m->sealed = true; m->rawlen = len; - m->raw = malloc(len + 1); + m->raw = strdup(orig_raw); if (!m->raw) return -ENOMEM; - /* copy with 0-terminator */ - memcpy(m->raw, raw, len + 1); - if (ifname) { - m->ifname = strdup(ifname); + m->ifname = strndup(ifname, strchrnul(ifname, ' ') - ifname); if (!m->ifname) return -ENOMEM; } From a9266e5055d2c332080785e24bbaa82b101b1d11 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 14 Sep 2016 11:29:55 +0800 Subject: [PATCH 029/142] re-dispatch wpa_message with ifname!=NULL from supplicant_global_fn() to supplicant_dev_fn() --- src/wifi/wifid-supplicant.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 6a49fa4..26d981c 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2147,6 +2147,9 @@ static int supplicant_global_fn(struct wpas *w, } /* ignore events on the global-iface, we only listen on dev-iface */ + if(wpas_message_get_ifname(m)) { + supplicant_event(s, m); + } return 0; From 3886dcb7c791442a2012c8d0678a1c828403a8b5 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Wed, 14 Sep 2016 16:01:54 +0800 Subject: [PATCH 030/142] add option --use-dev to miracle-wifid to workaround the 'no ifname' issue --- src/wifi/wifid-link.c | 10 ++++++++++ src/wifi/wifid-supplicant.c | 2 +- src/wifi/wifid.c | 11 +++++++++++ src/wifi/wifid.h | 5 +++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index ff9eb62..b2de058 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -132,6 +132,16 @@ void link_free(struct link *l) free(l); } +void link_use_dev(struct link *l) +{ + l->use_dev = true; +} + +bool link_is_using_dev(struct link *l) +{ + return l->use_dev; +} + void link_set_managed(struct link *l, bool set) { int r; diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 26d981c..d3e4dbe 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2147,7 +2147,7 @@ static int supplicant_global_fn(struct wpas *w, } /* ignore events on the global-iface, we only listen on dev-iface */ - if(wpas_message_get_ifname(m)) { + if(link_is_using_dev(s->l) && wpas_message_get_ifname(m)) { supplicant_event(s, m); } diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 9533206..d2e8108 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -42,6 +42,7 @@ const char *interface_name = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; +bool use_dev = false; /* * Manager Handling @@ -102,6 +103,9 @@ static void manager_add_udev_link(struct manager *m, link_set_friendly_name(l, m->friendly_name); + if(use_dev) + link_use_dev(l); + #ifdef RELY_UDEV if (udev_device_has_tag(d, "miracle")) { #else @@ -457,6 +461,7 @@ static int help(void) " -i --interface Choose the interface to use\n" "\n" " --wpa-loglevel Date: Sat, 1 Oct 2016 12:25:32 +0200 Subject: [PATCH 031/142] Fix finding subnet --- src/wifi/wifid-supplicant.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index d3e4dbe..4cb4ae7 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -509,7 +509,7 @@ static int supplicant_group_new(struct supplicant *s, j = shl_dlist_entry(i, struct supplicant_group, list); - if (j->subnet == j->subnet) + if (j->subnet == subnet) break; } From 5e93ad063827016229dc5660b93075ccf42f254f Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 23 Oct 2016 03:58:47 +0200 Subject: [PATCH 032/142] Fix compilation warnings --- src/ctl/ctl-cli.c | 2 +- src/ctl/ctl-sink.c | 2 +- src/ctl/ctl.h | 2 +- src/shared/shl_log.c | 23 ++++++++++++++++++++--- src/shared/shl_log.h | 2 +- src/uibc/miracle-uibcctl.c | 6 +++--- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 72d1eba..dd61ff0 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -47,7 +47,7 @@ static sd_event_source *cli_sigs[_NSIG]; static sd_event_source *cli_stdin; static bool cli_rl; static const struct cli_cmd *cli_cmds; -int cli_max_sev = LOG_NOTICE; +unsigned int cli_max_sev = LOG_NOTICE; static bool is_cli(void) { diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index e771f52..2d72e18 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -213,7 +213,7 @@ static void sink_handle_set_parameter(struct ctl_sink *s, _rtsp_message_unref_ struct rtsp_message *rep = NULL; const char *trigger; const char *url; - const char *uibc_config; + char *uibc_config; const char *uibc_setting; char *nu; unsigned int cea_res, vesa_res, hh_res; diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 077cc49..75cc0a3 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -120,7 +120,7 @@ bool ctl_sink_is_closed(struct ctl_sink *s); /* CLI handling */ -extern int cli_max_sev; +extern unsigned int cli_max_sev; void cli_printv(const char *fmt, va_list args); void cli_printf(const char *fmt, ...); diff --git a/src/shared/shl_log.c b/src/shared/shl_log.c index dc7ef55..2e983cf 100644 --- a/src/shared/shl_log.c +++ b/src/shared/shl_log.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "shl_log.h" /* @@ -239,9 +240,9 @@ void log_llog(void *data, log_submit(file, line, func, subs, sev, format, args); } -int log_parse_arg(char *optarg) +unsigned int log_parse_arg(char *optarg) { - int log_max_sev; + unsigned int log_max_sev; if(!strcasecmp(optarg, "fatal")) { log_max_sev = LOG_FATAL; } else if(!strcasecmp(optarg, "alert")) { @@ -261,7 +262,23 @@ int log_parse_arg(char *optarg) } else if(!strcasecmp(optarg, "trace")) { log_max_sev = LOG_TRACE; } else { - log_max_sev = atoi(optarg); + errno = 0; + char *temp; + long val = strtoul(optarg, &temp, 0); + + if (temp == optarg || *temp != '\0' + || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)) { + log_error("Could not convert '%s' to long and leftover string is: '%s'\n", optarg, temp); + } + if (val > INT_MAX) { + errno = ERANGE; + return INT_MAX; + } + if (val < INT_MIN) { + errno = ERANGE; + return INT_MIN; + } + log_max_sev = (unsigned int) val; } return log_max_sev; } diff --git a/src/shared/shl_log.h b/src/shared/shl_log.h index e645948..ed9afa1 100644 --- a/src/shared/shl_log.h +++ b/src/shared/shl_log.h @@ -116,7 +116,7 @@ void log_llog(void *data, const char *format, va_list args); -int log_parse_arg(char *optarg); +unsigned int log_parse_arg(char *optarg); static inline __attribute__((format(printf, 2, 3))) void log_dummyf(unsigned int sev, const char *format, ...) diff --git a/src/uibc/miracle-uibcctl.c b/src/uibc/miracle-uibcctl.c index 79b92e0..2c8835b 100644 --- a/src/uibc/miracle-uibcctl.c +++ b/src/uibc/miracle-uibcctl.c @@ -106,7 +106,7 @@ const char *int2binary(int x, int padding) int sendUibcMessage(UibcMessage* uibcmessage, int sockfd) { ssize_t n; - printf("sending %d bytes\n", uibcmessage->m_PacketDataLen); + printf("sending %zu bytes\n", uibcmessage->m_PacketDataLen); n = write(sockfd, uibcmessage->m_PacketData , uibcmessage->m_PacketDataLen); @@ -249,7 +249,7 @@ void getUIBCGenericTouchPacket(const char *inEventDesc, void hexdump(void *_data, size_t len) { unsigned char *data = _data; - int count; + size_t count; int line = 15; for (count = 0; count < len; count++) { @@ -270,7 +270,7 @@ void hexdump(void *_data, size_t len) void binarydump(void *_data, size_t len) { unsigned char *data = _data; - int count; + size_t count; int line = 7; for (count = 0; count < len; count++) { From 472fbf4a246c95594143ae3a91f538748abcdb82 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 23 Oct 2016 00:30:19 +0200 Subject: [PATCH 033/142] Check source UIBC capability If source has no UIBC capability don't try to connect UIBC controller, and listen UIBC setting to disable UIBC relates to #115 --- src/ctl/ctl-sink.c | 26 ++++++++++++++++---------- src/ctl/ctl-sink.h | 3 ++- src/ctl/sinkctl.c | 41 +++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 2d72e18..486456c 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -122,7 +122,7 @@ static void sink_handle_get_parameter(struct ctl_sink *s, } /* wfd_uibc_capability */ - if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0 && uibc) { + if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0 && uibc_option) { char wfd_uibc_capability[512]; sprintf(wfd_uibc_capability, "wfd_uibc_capability: input_category_list=GENERIC;" @@ -258,16 +258,22 @@ static void sink_handle_set_parameter(struct ctl_sink *s, free(s->uibc_config); s->uibc_config = nu; - char* token = strtok(uibc_config, ";"); + if (!strcasecmp(uibc_config, "none")) { + uibc_enabled = false; + } else { + char* token = strtok(uibc_config, ";"); - while (token) { - if (sscanf(token, "port=%d", &uibc_port)) { - break; - } - token = strtok(0, ";"); - } - - cli_debug("Got URL: %s\n", s->url); + while (token) { + if (sscanf(token, "port=%d", &uibc_port)) { + log_debug("UIBC port: %d\n", uibc_port); + if (uibc_option) { + uibc_enabled = true; + } + break; + } + token = strtok(0, ";"); + } + } } } diff --git a/src/ctl/ctl-sink.h b/src/ctl/ctl-sink.h index 69d0532..7218583 100644 --- a/src/ctl/ctl-sink.h +++ b/src/ctl/ctl-sink.h @@ -40,7 +40,8 @@ #include "wfd.h" extern int rstp_port; -extern bool uibc; +extern bool uibc_option; +extern bool uibc_enabled; extern int uibc_port; struct ctl_sink { diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 5c335f2..f1f6af8 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -59,7 +59,8 @@ void launch_player(struct ctl_sink *s); char *gst_scale_res; int gst_audio_en = 1; static const int DEFAULT_RSTP_PORT = 1991; -bool uibc; +bool uibc_option; +bool uibc_enabled; int rstp_port; int uibc_port; @@ -388,14 +389,14 @@ void launch_player(struct ctl_sink *s) { char uibc_portStr[64]; int i = 0; char* player; - if (uibc) { + if (uibc_enabled) { player = "uibc-viewer"; } else { player = "miracle-gst"; } argv[i++] = player; - if (uibc) { + if (uibc_enabled) { argv[i++] = s->target; sprintf(uibc_portStr, "%d", uibc_port); argv[i++] = uibc_portStr; @@ -420,29 +421,28 @@ void launch_player(struct ctl_sink *s) { argv[i] = NULL; - i = 0; + i = 0; int size = 0; - while (argv[i]) { + while (argv[i]) { size += strlen(argv[i++] + 1); - } + } char* player_command = malloc(size); - i = 0; + i = 0; strcpy(player_command, argv[i++]); - while (argv[i]) { + while (argv[i]) { strcat(player_command, " "); strcat(player_command, argv[i++]); - } + } log_debug("player command: %s", player_command); - //free(player_command); - if (execvpe(argv[0], argv, environ) < 0) { - cli_debug("stream player failed (%d): %m", errno); - int i = 0; - cli_debug("printing environment: "); - while (environ[i]) { - cli_debug("%s", environ[i++]); - } - } + if (execvpe(argv[0], argv, environ) < 0) { + cli_debug("stream player failed (%d): %m", errno); + int i = 0; + cli_debug("printing environment: "); + while (environ[i]) { + cli_debug("%s", environ[i++]); + } + } } void launch_uibc_daemon(int port) { @@ -771,7 +771,8 @@ static int parse_argv(int argc, char *argv[]) }; int c; - uibc = false; + uibc_option = false; + uibc_enabled = false; rstp_port = DEFAULT_RSTP_PORT; while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { @@ -803,7 +804,7 @@ static int parse_argv(int argc, char *argv[]) rstp_port = atoi(optarg); break; case ARG_UIBC: - uibc = true; + uibc_option = true; break; case '?': return -EINVAL; From cedfeeebe10c4006492d70a9a47aecb5d2e67176 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 23 Oct 2016 09:47:56 +0200 Subject: [PATCH 034/142] Debug GStreamer execution Allow to config gstreamer log level --- res/gstplayer | 6 +++++- src/ctl/sinkctl.c | 43 +++++++++++++++++++++++++++---------------- src/shared/shl_log.c | 2 ++ src/shared/shl_log.h | 5 +++++ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/res/gstplayer b/res/gstplayer index c777366..b284bda 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -1,7 +1,6 @@ #!/usr/bin/python3 -u import gi -import sys import argparse gi.require_version('Gst', '1.0') @@ -32,6 +31,11 @@ class Player(object): self.width = int(split[0]) self.height = int(split[1]) + debug = kwargs.get("debug") + if debug: + Gst.debug_set_active(True) + Gst.debug_set_threshold_from_string(debug, True) + port = kwargs.get("port") uri = kwargs.get("uri") diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index f1f6af8..c30e342 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -401,8 +401,13 @@ void launch_player(struct ctl_sink *s) { sprintf(uibc_portStr, "%d", uibc_port); argv[i++] = uibc_portStr; } - if (cli_max_sev >= 7) - argv[i++] = "-d 3"; + if (gst_debug) { + argv[i++] = "-d"; + argv[i++] = gst_debug; + } else if (cli_max_sev >= LOG_DEBUG) { + argv[i++] = "-d"; + argv[i++] = "3"; + } if (gst_audio_en) argv[i++] = "-a"; if (gst_scale_res) { @@ -422,9 +427,9 @@ void launch_player(struct ctl_sink *s) { argv[i] = NULL; i = 0; - int size = 0; + size_t size = 0; while (argv[i]) { - size += strlen(argv[i++] + 1); + size += strlen(argv[i++]) + 1; } char* player_command = malloc(size); @@ -668,18 +673,19 @@ void cli_fn_help() */ printf("%s [OPTIONS...] ...\n\n" "Control a dedicated local sink via MiracleCast.\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --log-level Maximum level for log messages\n" - " --log-journal-level Maximum level for journal log messages\n" - " --audio <0/1> Enable audio support (default %d)\n" - " --scale WxH Scale to resolution\n" - " --port Port for rtsp (default %d)\n" - " --uibc Enables UIBC\n" - " --res Supported resolutions masks (CEA, VESA, HH)\n" - " default CEA %08X\n" - " default VESA %08X\n" - " default HH %08X\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --log-level Maximum level for log messages\n" + " --log-journal-level Maximum level for journal log messages\n" + " --gst-debug [cat:]lvl[,...] List of categories an level of debug\n" + " --audio <0/1> Enable audio support (default %d)\n" + " --scale WxH Scale to resolution\n" + " --port Port for rtsp (default %d)\n" + " --uibc Enables UIBC\n" + " --res Supported resolutions masks (CEA, VESA, HH)\n" + " default CEA %08X\n" + " default VESA %08X\n" + " default HH %08X\n" "\n" , program_invocation_short_name, gst_audio_en, DEFAULT_RSTP_PORT, wfd_supported_res_cea, wfd_supported_res_vesa, wfd_supported_res_hh @@ -751,6 +757,7 @@ static int parse_argv(int argc, char *argv[]) ARG_VERSION = 0x100, ARG_LOG_LEVEL, ARG_JOURNAL_LEVEL, + ARG_GST_DEBUG, ARG_AUDIO, ARG_SCALE, ARG_RES, @@ -762,6 +769,7 @@ static int parse_argv(int argc, char *argv[]) { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, + { "gst-debug", required_argument, NULL, ARG_GST_DEBUG }, { "audio", required_argument, NULL, ARG_AUDIO }, { "scale", required_argument, NULL, ARG_SCALE }, { "res", required_argument, NULL, ARG_RES }, @@ -785,6 +793,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_LEVEL: cli_max_sev = log_parse_arg(optarg); break; + case ARG_GST_DEBUG: + gst_debug = optarg; + break; case ARG_JOURNAL_LEVEL: log_max_sev = log_parse_arg(optarg); break; diff --git a/src/shared/shl_log.c b/src/shared/shl_log.c index 2e983cf..9b311be 100644 --- a/src/shared/shl_log.c +++ b/src/shared/shl_log.c @@ -85,6 +85,8 @@ const char *LOG_SUBSYSTEM = NULL; unsigned int log_max_sev = LOG_NOTICE; +char *gst_debug = NULL; + /* * Forward declaration so we can use the locked-versions in other functions * here. Be careful to avoid deadlocks, though. diff --git a/src/shared/shl_log.h b/src/shared/shl_log.h index ed9afa1..bd08601 100644 --- a/src/shared/shl_log.h +++ b/src/shared/shl_log.h @@ -61,6 +61,11 @@ enum log_severity { extern unsigned int log_max_sev; +/* + * Defines the debug configuration for gstreamer + */ +extern char* gst_debug; + /* * Timestamping * Call this to initialize timestamps and cause all log-messages to be prefixed From e5795edd0459ea13a409c93f8e7b0ea1e263819d Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 28 Oct 2016 11:37:16 +0200 Subject: [PATCH 035/142] Read UIBC capability in raw mode Some devices send its UIBC capabilities with spaces. Read in raw mode to parse port correctly --- src/ctl/ctl-sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 486456c..4580ecb 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -248,7 +248,7 @@ static void sink_handle_set_parameter(struct ctl_sink *s, } /* M4 (or any other) can pass presentation URLs */ - r = rtsp_message_read(m, "{}", "wfd_uibc_capability", &uibc_config); + r = rtsp_message_read(m, "{<&>}", "wfd_uibc_capability", &uibc_config); if (r >= 0) { if (!s->uibc_config || strcmp(s->uibc_config, uibc_config)) { nu = strdup(uibc_config); From 2757c4f5e64838f52683d0e3ff0f0d4825efe323 Mon Sep 17 00:00:00 2001 From: Joseph Nix Date: Thu, 9 Feb 2017 21:38:50 -0600 Subject: [PATCH 036/142] Fixed small grammar error in README: this -> these. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06678d7..38e60ce 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The MiracleCast projects requires the following software to be installed: - **gstreamer**: MiracleCast relay on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh) - - **P2P Wi-Fi device** Although widespread this days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh) + - **P2P Wi-Fi device** Although widespread these days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh) - copy the dbus policy **res/org.freedesktop.miracle.conf** to `/etc/dbus-1/system.d/` From 016159bb1ee83fee084c2ce35d48b5b473edf763 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 25 Mar 2017 11:54:35 +0100 Subject: [PATCH 037/142] Check running as root Detect running with elevated privileges to access dbus fixes #89 --- src/ctl/sinkctl.c | 6 ++++++ src/wifi/wifid.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index c30e342..49eac82 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -733,6 +733,12 @@ static int ctl_main(int argc, char *argv[]) struct ctl_link *l; int r, left; + if (getuid() != 0) { + r = EACCES; + log_notice("Must run as root"); + return r; + } + r = ctl_wifi_new(&wifi, bus); if (r < 0) return r; diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index d2e8108..026a0ae 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -541,6 +541,12 @@ int main(int argc, char **argv) struct manager *m = NULL; int r; + if (getuid() != 0) { + r = EACCES; + log_notice("Must run as root"); + goto finish; + } + srand(time(NULL)); r = parse_argv(argc, argv); From 3628f789b4912a9c7936e6f4d0e77e99ffebdc6b Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 25 Mar 2017 12:48:04 +0100 Subject: [PATCH 038/142] Add external player config Allow to run custom player. It will be run within a wrapper that respect -p/--port, option at least fixes #87 --- res/Makefile.am | 2 +- res/miracle-omxplayer | 69 +++++++++++++++++++++++++++++++++++++++++++ src/ctl/sinkctl.c | 31 ++++++++++++------- 3 files changed, 90 insertions(+), 12 deletions(-) create mode 100755 res/miracle-omxplayer diff --git a/res/Makefile.am b/res/Makefile.am index b51bdbc..e4d879e 100644 --- a/res/Makefile.am +++ b/res/Makefile.am @@ -1,4 +1,4 @@ -bin_SCRIPTS = miracle-gst gstplayer uibc-viewer +bin_SCRIPTS = miracle-gst gstplayer uibc-viewer miracle-omxplayer EXTRA_DIST = wpa.conf dbuspolicydir=$(sysconfdir)/dbus-1/system.d diff --git a/res/miracle-omxplayer b/res/miracle-omxplayer new file mode 100755 index 0000000..dfa9152 --- /dev/null +++ b/res/miracle-omxplayer @@ -0,0 +1,69 @@ +#!/bin/bash + +function help { + local scriptname="$(basename $0)" + cat >&2 <x Scale + -d Log level for gst + -p Port for stream + -a Enables audio + -h Show this help + +Examples: + + # play stream on port 7236 + $ $scriptname -p 7236 + +EOF +} + +DEBUG='0' +AUDIO='0' +SCALE='0' + +while getopts "r:d:as:p:h" optname + do + case "$optname" in + "h") + help + exit 0 + ;; + "d") + DEBUG=`echo ${OPTARG} | tr -d ' '` + ;; + "r") + RESOLUTION=`echo ${OPTARG} | tr -d ' '` + ;; + "a") + AUDIO='1' + ;; + "p") + PORT=`echo ${OPTARG} | tr -d ' '` + ;; + "s") + SCALE='1' + WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1` + HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2` + ;; + "?") + echo "Unknown option $OPTARG" + ;; + *) + echo "Unknown parameter $OPTARG" + help + exit 1 + ;; + esac + done + +RUN="omxplayer -live -b - o hdmi rtp://localhost:$PORT" + +echo "running: $RUN" +exec ${RUN} diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 49eac82..c1b8b68 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -61,8 +61,10 @@ int gst_audio_en = 1; static const int DEFAULT_RSTP_PORT = 1991; bool uibc_option; bool uibc_enabled; +bool external_player; int rstp_port; int uibc_port; +char* player; unsigned int wfd_supported_res_cea = 0x0000001f; /* up to 720x576 */ unsigned int wfd_supported_res_vesa = 0x00000003; /* up to 800x600 */ @@ -388,12 +390,13 @@ void launch_player(struct ctl_sink *s) { char port[64]; char uibc_portStr[64]; int i = 0; - char* player; - if (uibc_enabled) { - player = "uibc-viewer"; - } else { - player = "miracle-gst"; - } + if (!external_player) { + if (uibc_enabled) { + player = "uibc-viewer"; + } else { + player = "miracle-gst"; + } + } argv[i++] = player; if (uibc_enabled) { @@ -680,8 +683,9 @@ void cli_fn_help() " --gst-debug [cat:]lvl[,...] List of categories an level of debug\n" " --audio <0/1> Enable audio support (default %d)\n" " --scale WxH Scale to resolution\n" - " --port Port for rtsp (default %d)\n" + " -p --port Port for rtsp (default %d)\n" " --uibc Enables UIBC\n" + " -e --external-player Configure player to use\n" " --res Supported resolutions masks (CEA, VESA, HH)\n" " default CEA %08X\n" " default VESA %08X\n" @@ -767,7 +771,6 @@ static int parse_argv(int argc, char *argv[]) ARG_AUDIO, ARG_SCALE, ARG_RES, - ARG_PORT, ARG_UIBC, }; static const struct option options[] = { @@ -779,17 +782,19 @@ static int parse_argv(int argc, char *argv[]) { "audio", required_argument, NULL, ARG_AUDIO }, { "scale", required_argument, NULL, ARG_SCALE }, { "res", required_argument, NULL, ARG_RES }, - { "port", required_argument, NULL, ARG_PORT }, + { "port", required_argument, NULL, 'p' }, { "uibc", no_argument, NULL, ARG_UIBC }, + { "external-player", required_argument, NULL, 'e' }, {} }; int c; uibc_option = false; uibc_enabled = false; + external_player = false; rstp_port = DEFAULT_RSTP_PORT; - while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "he:p", options, NULL)) >= 0) { switch (c) { case 'h': return cli_help(cli_cmds); @@ -817,9 +822,13 @@ static int parse_argv(int argc, char *argv[]) &wfd_supported_res_vesa, &wfd_supported_res_hh); break; - case ARG_PORT: + case 'p': rstp_port = atoi(optarg); break; + case 'e': + external_player = true; + player = optarg; + break; case ARG_UIBC: uibc_option = true; break; From 2aeec41290d5009261c4bddbaf7bf380ab9f16c0 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 25 Mar 2017 12:53:13 +0100 Subject: [PATCH 039/142] Provide wrapper for vlc external player wrapper for vlc --- res/miracle-vlc | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 res/miracle-vlc diff --git a/res/miracle-vlc b/res/miracle-vlc new file mode 100755 index 0000000..a4e61c7 --- /dev/null +++ b/res/miracle-vlc @@ -0,0 +1,69 @@ +#!/bin/bash + +function help { + local scriptname="$(basename $0)" + cat >&2 <x Scale + -d Log level for gst + -p Port for stream + -a Enables audio + -h Show this help + +Examples: + + # play stream on port 7236 + $ $scriptname -p 7236 + +EOF +} + +DEBUG='0' +AUDIO='0' +SCALE='0' + +while getopts "r:d:as:p:h" optname + do + case "$optname" in + "h") + help + exit 0 + ;; + "d") + DEBUG=`echo ${OPTARG} | tr -d ' '` + ;; + "r") + RESOLUTION=`echo ${OPTARG} | tr -d ' '` + ;; + "a") + AUDIO='1' + ;; + "p") + PORT=`echo ${OPTARG} | tr -d ' '` + ;; + "s") + SCALE='1' + WIDTH=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 1` + HEIGHT=`echo ${OPTARG} | tr -d ' ' | cut -dx -f 2` + ;; + "?") + echo "Unknown option $OPTARG" + ;; + *) + echo "Unknown parameter $OPTARG" + help + exit 1 + ;; + esac + done + +RUN="vlc rtp://@:$PORT" + +echo "running: $RUN" +exec ${RUN} From a9da0067e3bec03f4cfd6eda907b006234f59842 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 26 Mar 2017 09:31:32 +0200 Subject: [PATCH 040/142] Improve autocompletion Standardize help commands Add autocompletion for short arguments Install autocompletion --- res/Makefile.am | 4 ++ res/miraclecast-completion | 75 ++++++++++++++++++++++++++++++++++++-- src/ctl/ctl-cli.c | 9 ++--- src/ctl/ctl.h | 2 +- src/ctl/sinkctl.c | 17 +++++++-- src/ctl/wfd.c | 14 +++---- src/ctl/wfd.h | 2 +- src/ctl/wifictl.c | 8 +++- src/wifi/wifid.c | 12 +++--- 9 files changed, 115 insertions(+), 28 deletions(-) diff --git a/res/Makefile.am b/res/Makefile.am index e4d879e..9e73673 100644 --- a/res/Makefile.am +++ b/res/Makefile.am @@ -3,3 +3,7 @@ EXTRA_DIST = wpa.conf dbuspolicydir=$(sysconfdir)/dbus-1/system.d dbuspolicy_DATA = org.freedesktop.miracle.conf + +bashcompletiondir=${datadir}/bash-completion/completions +bashcompletion_DATA=miraclecast-completion + diff --git a/res/miraclecast-completion b/res/miraclecast-completion index 707ccad..1d82b32 100755 --- a/res/miraclecast-completion +++ b/res/miraclecast-completion @@ -1,3 +1,11 @@ +#!/bin/bash + +# +# Autocompletion for miraclecast commands +# +# Maintainer: Alberto Fanjul +# + function _miracle-wifid() { local cur prev @@ -15,7 +23,7 @@ function _miracle-wifid() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid) $(_parse_short_help miracle-wifid)" -- "$cur")) } complete -F _miracle-wifid miracle-wifid @@ -33,7 +41,7 @@ function _miracle-sinkctl() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl) $(_parse_short_help miracle-sinkctl)" -- "$cur")) } complete -F _miracle-sinkctl miracle-sinkctl @@ -51,7 +59,68 @@ function _miracle-wifictl() { ;; esac - COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl)" -- "$cur")) + COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl) $(_parse_short_help miracle-wifictl)" -- "$cur")) } complete -F _miracle-wifictl miracle-wifictl + +_parse_short_help () +{ + eval local cmd=$( quote "$1" ); + local line; + { + case $cmd in + -) + cat + ;; + *) + LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 + ;; + esac + } | while read -r line; do + [[ $line == *([[:blank:]])-* ]] || continue; + while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do + line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}; + done; + __parse_short_options "${line// or /, }"; + done +} + +__parse_short_options () +{ + local option option2 i IFS=' +,/|'; + option=; + local -a array; + read -a array <<< "$1"; + for i in "${array[@]}"; + do + case "$i" in + ---*) + break + ;; + --?*) + break + ;; + -?*) + option=$i; + break + ;; + *) + break + ;; + esac; + done; + [[ -n $option ]] || return; + IFS=' +'; + if [[ $option =~ (\[((no|dont)-?)\]). ]]; then + option2=${option/"${BASH_REMATCH[1]}"/}; + option2=${option2%%[<{().[]*}; + printf '%s\n' "${option2/=*/=}"; + option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}; + fi; + option=${option%%[<{().[]*}; + printf '%s\n' "${option/=*/=}" +} + diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index dd61ff0..c1e5855 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -93,13 +93,10 @@ void cli_printf(const char *fmt, ...) va_end(args); } -int cli_help(const struct cli_cmd *cmds) +int cli_help(const struct cli_cmd *cmds, int whitespace) { unsigned int i; - if (!is_cli()) { - cli_fn_help(); - } cli_printf("Available commands:\n"); for (i = 0; cmds[i].cmd; ++i) { @@ -112,7 +109,7 @@ int cli_help(const struct cli_cmd *cmds) cli_printf(" %s %-*s %s\n", cmds[i].cmd, - (int)(40 - strlen(cmds[i].cmd)), + (int)(whitespace - strlen(cmds[i].cmd)), cmds[i].args ? : "", cmds[i].desc ? : ""); } @@ -173,7 +170,7 @@ int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n) } if (!strcmp(cmd, "help")) - return cli_help(cmds); + return cli_help(cmds, 40); return -EAGAIN; } diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 75cc0a3..1d0bd9a 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -220,7 +220,7 @@ int cli_run(void); void cli_exit(void); bool cli_running(void); -int cli_help(const struct cli_cmd *cmds); +int cli_help(const struct cli_cmd *cmds, int whitespace); int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n); /* callback functions */ diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index c1b8b68..5514a86 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -677,6 +677,7 @@ void cli_fn_help() printf("%s [OPTIONS...] ...\n\n" "Control a dedicated local sink via MiracleCast.\n" " -h --help Show this help\n" + " --help-commands Show avaliable commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-journal-level Maximum level for journal log messages\n" @@ -690,11 +691,11 @@ void cli_fn_help() " default CEA %08X\n" " default VESA %08X\n" " default HH %08X\n" + " --help-res Shows avaliable values for res\n" "\n" , program_invocation_short_name, gst_audio_en, DEFAULT_RSTP_PORT, wfd_supported_res_cea, wfd_supported_res_vesa, wfd_supported_res_hh ); - wfd_print_resolutions(); /* * 80-char barrier: * 01234567890123456789012345678901234567890123456789012345678901234567890123456789 @@ -771,10 +772,13 @@ static int parse_argv(int argc, char *argv[]) ARG_AUDIO, ARG_SCALE, ARG_RES, + ARG_HELP_RES, ARG_UIBC, + ARG_HELP_COMMANDS, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, + { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, @@ -782,6 +786,7 @@ static int parse_argv(int argc, char *argv[]) { "audio", required_argument, NULL, ARG_AUDIO }, { "scale", required_argument, NULL, ARG_SCALE }, { "res", required_argument, NULL, ARG_RES }, + { "help-res", no_argument, NULL, ARG_HELP_RES }, { "port", required_argument, NULL, 'p' }, { "uibc", no_argument, NULL, ARG_UIBC }, { "external-player", required_argument, NULL, 'e' }, @@ -794,10 +799,16 @@ static int parse_argv(int argc, char *argv[]) external_player = false; rstp_port = DEFAULT_RSTP_PORT; - while ((c = getopt_long(argc, argv, "he:p", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "he:p:", options, NULL)) >= 0) { switch (c) { case 'h': - return cli_help(cli_cmds); + cli_fn_help(); + return 0; + case ARG_HELP_COMMANDS: + return cli_help(cli_cmds, 20); + case ARG_HELP_RES: + wfd_print_resolutions(""); + return 0; case ARG_VERSION: puts(PACKAGE_STRING); return 0; diff --git a/src/ctl/wfd.c b/src/ctl/wfd.c index 87c3922..49ee5d3 100644 --- a/src/ctl/wfd.c +++ b/src/ctl/wfd.c @@ -103,27 +103,27 @@ struct resolution_bitmap resolutions_hh[] = { {0, 0, 0, 0}, }; -void wfd_print_resolutions(void) +void wfd_print_resolutions(char * prefix) { int i; - printf("CEA resolutions:\n"); + printf("%sCEA resolutions:\n", prefix); for (i = 0; resolutions_cea[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_cea[i].index, 1 << resolutions_cea[i].index, resolutions_cea[i].hres, resolutions_cea[i].vres, resolutions_cea[i].fps); } - printf("VESA resolutions:\n"); + printf("%sVESA resolutions:\n", prefix); for (i = 0; resolutions_vesa[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_vesa[i].index, 1 << resolutions_vesa[i].index, resolutions_vesa[i].hres, resolutions_vesa[i].vres, resolutions_vesa[i].fps); } - printf("HH resolutions:\n"); + printf("%sHH resolutions:\n", prefix); for (i = 0; resolutions_hh[i].hres != 0; i++) { - printf("\t%2d %08x %4dx%4d@%d\n", + printf("%s\t%2d %08x %4dx%4d@%d\n", prefix, resolutions_hh[i].index, 1 << resolutions_hh[i].index, resolutions_hh[i].hres, resolutions_hh[i].vres, resolutions_hh[i].fps); diff --git a/src/ctl/wfd.h b/src/ctl/wfd.h index 2d85111..d9a5831 100644 --- a/src/ctl/wfd.h +++ b/src/ctl/wfd.h @@ -21,7 +21,7 @@ #ifndef WFD_H #define WFD_H -void wfd_print_resolutions(void); +void wfd_print_resolutions(char * prefix); int vfd_get_cea_resolution(uint32_t mask, int *hres, int *vres); int vfd_get_vesa_resolution(uint32_t mask, int *hres, int *vres); int vfd_get_hh_resolution(uint32_t mask, int *hres, int *vres); diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index f8bf7e5..7058d2c 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -420,6 +420,7 @@ void cli_fn_help() "Send control command to or query the MiracleCast Wifi-Manager. If no arguments\n" "are given, an interactive command-line tool is provided.\n\n" " -h --help Show this help\n" + " --help-commands Show avaliable commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" "\n" @@ -497,9 +498,11 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_HELP_COMMANDS, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, + { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, {} @@ -509,7 +512,10 @@ static int parse_argv(int argc, char *argv[]) while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { switch (c) { case 'h': - return cli_help(cli_cmds); + cli_fn_help(); + return 0; + case ARG_HELP_COMMANDS: + return cli_help(cli_cmds, 20); case ARG_VERSION: puts(PACKAGE_STRING); return 0; diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 026a0ae..ca7e461 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -541,12 +541,6 @@ int main(int argc, char **argv) struct manager *m = NULL; int r; - if (getuid() != 0) { - r = EACCES; - log_notice("Must run as root"); - goto finish; - } - srand(time(NULL)); r = parse_argv(argc, argv); @@ -555,6 +549,12 @@ int main(int argc, char **argv) if (!r) return EXIT_SUCCESS; + if (getuid() != 0) { + r = EACCES; + log_notice("Must run as root"); + goto finish; + } + r = manager_new(&m); if (r < 0) goto finish; From 52cd3f0f28d37da55d1ae6d649e49ab9561e812b Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 26 Mar 2017 13:12:33 +0200 Subject: [PATCH 041/142] cleanup for gstplayer --- res/gstplayer | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/res/gstplayer b/res/gstplayer index b284bda..0501715 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -41,19 +41,21 @@ class Player(object): uri = kwargs.get("uri") self.window = Gtk.Window() - self.window.set_name('eco') + self.window.set_name('gstplayer') self.window.connect('destroy', self.quit) title = kwargs.get("title") if title: self.window.set_title(title) - self.window.set_default_size(self.width, self.height) + if hasattr(self,'width') and hasattr(self,'height'): + self.window.set_default_size(self.width, self.height) self.drawingarea = Gtk.DrawingArea() self.window.add(self.drawingarea) - self.drawingarea.set_size_request(self.width,self.height) + if hasattr(self,'width') and hasattr(self,'height'): + self.drawingarea.set_size_request(self.width,self.height) self.drawingarea.add_events(Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.BUTTON_RELEASE_MASK) self.drawingarea.connect('button-press-event', self.on_mouse_pressed) self.drawingarea.connect('button-release-event', self.on_mouse_pressed) @@ -153,21 +155,13 @@ class Player(object): pos_event_y = event.y - #print('{0} {1} {2} {3} {4} {5}'.format(min_hor_pos, pos_event_x, max_hor_pos, min_ver_pos, pos_event_y,max_ver_pos)) if min_hor_pos <= pos_event_x <= max_hor_pos and min_ver_pos <= pos_event_y <= max_ver_pos: uibc_x = int(pos_event_x - (half_area_width - half_def_width)) - #print ('{0} {1} {2} {3}'.format(uibc_x, pos_event_x, half_area_width,half_def_width)) uibc_y = int(pos_event_y - (half_area_height - half_def_height)) - #print ('{0} {1} {2} {3}'.format(uibc_y, pos_event_y, half_area_height,half_def_height)) print('{0},1,0,{1},{2}'.format(type, uibc_x , uibc_y)) def on_key_pressed(self, widget, event): - #print(Gdk.keyval_name(event.keyval)) print("3,0x%04X,0x0000" % event.keyval) - # print(event.state) - # if event.state & Gdk.ModifierType.LOCK_MASK == Gdk.ModifierType.LOCK_MASK: - # print("caps lock") - # print(Gtk.accelerator_get_label(event.keyval, event.state)) def run(self): self.window.show_all() @@ -186,8 +180,8 @@ class Player(object): def on_sync_message(self, bus, msg): if msg.get_structure().get_name() == 'prepare-window-handle': print(self.drawingarea.get_allocation()) - #msg.src.set_property("force-aspect-radio", True) - msg.src.set_window_handle(self.xid) + if hasattr(self,'xid'): + msg.src.set_window_handle(self.xid) def on_eos(self, bus, msg): print('on_eos(): seeking to start of video') From dec8ee0c0799238515e94955127508b6b4bd65b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=8D=9A=E4=BB=81=28Buo-Ren=20Lin=29?= Date: Sun, 26 Mar 2017 19:38:26 +0800 Subject: [PATCH 042/142] Fix minor typo in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-Off-By: 林博仁 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38e60ce..84bb4b8 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The MiracleCast projects requires the following software to be installed: - **check**: Test-suite for C programs. Used for optional tests of the MiracleCast code base. *optional*: ~=check-0.9.11 (might work with older releases, untested..) - - **gstreamer**: MiracleCast relay on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh) + - **gstreamer**: MiracleCast rely on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh) - **P2P Wi-Fi device** Although widespread these days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh) From a2735d9b4d4712bad8f3b5130397c10c2f1fd995 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 26 Mar 2017 13:12:33 +0200 Subject: [PATCH 043/142] find pci bus slot for wireless adapter helper function to find number to pass to run command of miracle-sinkctl --- res/miracle-utils.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index e938055..e9c7f4a 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -27,6 +27,13 @@ function find_wireless_network_interfaces { done } +# +# show pci slot +# +function show_pci_slot { + basename $(readlink /sys/class/net/$1/device) | cut -d: -f2 | sed 's/^0*//' +} + # # test if interface is connected # @@ -34,6 +41,15 @@ function is_interface_connected { test x$( cat /sys/class/net/$1/carrier 2>/dev/null) = x1 } +# +# find wireless pci slot +# +function find_wireless_pci_slot { + for i in $( find_wireless_network_interfaces ) + do + show_pci_slot $i + done +} # # find wireless connected interfaces # From 3dfa75d90b5bd0a02791a9f79b29d83260a74953 Mon Sep 17 00:00:00 2001 From: albfan Date: Mon, 27 Mar 2017 00:10:30 +0200 Subject: [PATCH 044/142] Find interface index for wireless interfaces helper function to find number to pass to run command of miracle-sinkctl --- res/miracle-utils.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index e9c7f4a..303ec0a 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -50,6 +50,17 @@ function find_wireless_pci_slot { show_pci_slot $i done } + +# +# find wireless pci slot +# +function find_wireless_ifindex { + for i in $( find_wireless_network_interfaces ) + do + show_ifindex $i + done +} + # # find wireless connected interfaces # @@ -74,6 +85,17 @@ function find_physical_for_network_interface { fi } +# +# find interface index for interface +# +function show_ifindex { + IF_INDEX=$(iw dev $1 info | grep ifindex | awk '{print $2}') + if [ -n "$IF_INDEX" ] + then + echo $IF_INDEX + fi +} + # # Check interface for P2P capabilities # From 1bc0648f4b2db9f7f7e469b9f6cce0c1399d8588 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 2 Apr 2017 22:25:48 +0200 Subject: [PATCH 045/142] Workaround for Wayland GDK backend --- res/gstplayer | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/res/gstplayer b/res/gstplayer index 0501715..2cbbb9b 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -168,7 +168,10 @@ class Player(object): # You need to get the XID after window.show_all(). You shouldn't get it # in the on_sync_message() handler because threading issues will cause # segfaults there. - self.xid = self.drawingarea.get_property('window').get_xid() + window = self.drawingarea.get_property('window') + if hasattr(window,'get_xid'): + self.xid = self.drawingarea.get_property('window').get_xid() + self.pipeline.set_state(Gst.State.PLAYING) Gtk.main() From 04a1ec8aa3f791dc276dab827df8968cf87e0c47 Mon Sep 17 00:00:00 2001 From: albfan Date: Mon, 27 Mar 2017 03:13:47 +0200 Subject: [PATCH 046/142] Ini files for miracle-wifid Honor ~/.miraclecast or ~/.config/miraclecastrc Properties avaliable: - wifid: log-level - sinkctl: external-player, rstp-port, log-level, log-journal-level, autocmd - wifictl: log-level, journal-log-level Command line has always higher priority over ini files fixes #113 --- configure.ac | 2 +- src/ctl/Makefile.am | 9 ++++--- src/ctl/sinkctl.c | 60 +++++++++++++++++++++++++++++++++++++++-- src/ctl/wifictl.c | 32 +++++++++++++++++++--- src/dhcp/Makefile.am | 4 +-- src/shared/Makefile.am | 6 ++--- src/shared/util.h | 20 ++++++++++++++ src/wifi/CMakeLists.txt | 4 +-- src/wifi/Makefile.am | 6 +++-- src/wifi/wifid.c | 12 +++++++++ 10 files changed, 136 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index a2f3738..1f0aa64 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ AC_ARG_ENABLE([log-debug], # PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219]) -PKG_CHECK_MODULES([GDHCP], [glib-2.0]) +PKG_CHECK_MODULES([GLIB], [glib-2.0]) AC_CHECK_HEADERS(readline/readline.h,, AC_MSG_ERROR(GNU readline not found)) diff --git a/src/ctl/Makefile.am b/src/ctl/Makefile.am index f02d052..ded5b45 100644 --- a/src/ctl/Makefile.am +++ b/src/ctl/Makefile.am @@ -8,7 +8,8 @@ miracle_wifictl_SOURCES = \ wifictl.c miracle_wifictl_CPPFLAGS = \ $(AM_CPPFLAGS) \ - $(DEPS_CFLAGS) + $(DEPS_CFLAGS) \ + $(GLIB_CFLAGS) miracle_wifictl_LDADD = \ ../shared/libmiracle-shared.la \ -lreadline \ @@ -24,10 +25,12 @@ miracle_sinkctl_SOURCES = \ sinkctl.c miracle_sinkctl_CPPFLAGS = \ $(AM_CPPFLAGS) \ - $(DEPS_CFLAGS) + $(DEPS_CFLAGS) \ + $(GLIB_CFLAGS) miracle_sinkctl_LDADD = \ ../shared/libmiracle-shared.la \ -lreadline \ - $(DEPS_LIBS) + $(DEPS_LIBS) \ + $(GLIB_LIBS) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 5514a86..844dd9c 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -38,6 +38,7 @@ #include "wfd.h" #include "shl_macro.h" #include "shl_util.h" +#include "util.h" #include "config.h" static sd_bus *bus; @@ -748,8 +749,9 @@ static int ctl_main(int argc, char *argv[]) if (r < 0) return r; - left = argc - optind; - r = ctl_interactive(argv + optind, left <= 0 ? 0 : left); + left = argc - optind; + left = left <= 0 ? 0 : left; + r = ctl_interactive(argv + optind, left); /* stop all scans */ shl_dlist_for_each(i, &wifi->links) { @@ -854,9 +856,59 @@ static int parse_argv(int argc, char *argv[]) int main(int argc, char **argv) { int r; + bool free_argv = false; setlocale(LC_ALL, ""); + GKeyFile* gkf = load_ini_file(); + + gchar** autocmds_free = NULL; + if (gkf) { + player = g_key_file_get_string (gkf, "sinkctl", "external-player", NULL); + if (player) { + external_player = true; + } + gchar* log_level; + log_level = g_key_file_get_string (gkf, "sinkctl", "log-journal-level", NULL); + if (log_level) { + log_max_sev = log_parse_arg(log_level); + g_free(log_level); + } + log_level = g_key_file_get_string (gkf, "sinkctl", "log-level", NULL); + if (log_level) { + cli_max_sev = log_parse_arg(log_level); + g_free(log_level); + } + gchar* rstp_port_str = g_key_file_get_string (gkf, "sinkctl", "rstp-port", NULL); + if (rstp_port_str) { + rstp_port = atoi(rstp_port_str); + g_free(rstp_port_str); + } + gchar* autocmd; + autocmd = g_key_file_get_string (gkf, "sinkctl", "autocmd", NULL); + if (autocmd && argc == 1) { + gchar** autocmds = g_strsplit(autocmd, " ", -1); + autocmds_free = autocmds; + while (*autocmds) { + if (strcmp(*autocmds, "") != 0) { + gchar **newv = malloc((argc + 2) * sizeof(gchar*)); + memmove(newv, argv, sizeof(gchar*) * argc); + newv[argc] = *autocmds; + newv[argc+1] = NULL; + argc++; + if (free_argv) { + free(argv); + } + argv = newv; + free_argv = true; + } + autocmds++; + } + g_free(autocmd); + } + g_key_file_free(gkf); + } + r = parse_argv(argc, argv); if (r < 0) return EXIT_FAILURE; @@ -870,6 +922,10 @@ int main(int argc, char **argv) } r = ctl_main(argc, argv); + g_strfreev(autocmds_free); + if (free_argv) { + free(argv); + } sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 7058d2c..d3ad7f3 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -31,6 +31,7 @@ #include "ctl.h" #include "shl_macro.h" #include "shl_util.h" +#include "util.h" #include "config.h" static sd_bus *bus; @@ -419,10 +420,11 @@ void cli_fn_help() printf("%s [OPTIONS...] {COMMAND} ...\n\n" "Send control command to or query the MiracleCast Wifi-Manager. If no arguments\n" "are given, an interactive command-line tool is provided.\n\n" - " -h --help Show this help\n" - " --help-commands Show avaliable commands\n" - " --version Show package version\n" - " --log-level Maximum level for log messages\n" + " -h --help Show this help\n" + " --help-commands Show avaliable commands\n" + " --version Show package version\n" + " --log-level Maximum level for log messages\n" + " --log-journal-level Maximum level for journal log messages\n" "\n" "Commands:\n" , program_invocation_short_name); @@ -498,6 +500,7 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_JOURNAL_LEVEL, ARG_HELP_COMMANDS, }; static const struct option options[] = { @@ -505,6 +508,7 @@ static int parse_argv(int argc, char *argv[]) { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, { "version", no_argument, NULL, ARG_VERSION }, { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, {} }; int c; @@ -522,6 +526,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_LEVEL: cli_max_sev = log_parse_arg(optarg); break; + case ARG_JOURNAL_LEVEL: + log_max_sev = log_parse_arg(optarg); + break; case '?': return -EINVAL; } @@ -536,6 +543,23 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); + GKeyFile* gkf = load_ini_file(); + + if (gkf) { + gchar* log_level; + log_level = g_key_file_get_string (gkf, "wifictl", "log-journal-level", NULL); + if (log_level) { + log_max_sev = log_parse_arg(log_level); + g_free(log_level); + } + log_level = g_key_file_get_string (gkf, "wifictl", "log-level", NULL); + if (log_level) { + cli_max_sev = log_parse_arg(log_level); + g_free(log_level); + } + g_key_file_free(gkf); + } + r = parse_argv(argc, argv); if (r < 0) return EXIT_FAILURE; diff --git a/src/dhcp/Makefile.am b/src/dhcp/Makefile.am index 2703f48..fb01fff 100644 --- a/src/dhcp/Makefile.am +++ b/src/dhcp/Makefile.am @@ -14,11 +14,11 @@ miracle_dhcp_SOURCES = \ miracle_dhcp_CPPFLAGS = \ $(AM_CPPFLAGS) \ $(DEPS_CFLAGS) \ - $(GDHCP_CFLAGS) + $(GLIB_CFLAGS) miracle_dhcp_LDADD = \ ../shared/libmiracle-shared.la \ $(DEPS_LIBS) \ - $(GDHCP_LIBS) + $(GLIB_LIBS) diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am index e79c8ff..b98dd81 100644 --- a/src/shared/Makefile.am +++ b/src/shared/Makefile.am @@ -17,7 +17,7 @@ libmiracle_shared_la_SOURCES = \ util.h \ wpas.h \ wpas.c -libmiracle_shared_la_LIBADD = -lsystemd - - +libmiracle_shared_la_LIBADD = -lsystemd \ + $(DEPS_LIBS) \ + $(GLIB_LIBS) diff --git a/src/shared/util.h b/src/shared/util.h index 5b85742..0e0ba3c 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -31,6 +31,26 @@ #include #include #include "shl_macro.h" +#include + +static inline GKeyFile* load_ini_file() { + GKeyFile* gkf = NULL; + gchar* config_file; + + gkf = g_key_file_new(); + + config_file = g_build_filename(g_get_home_dir(), ".config", "miraclecastrc", NULL); + if (!g_key_file_load_from_file(gkf, config_file, G_KEY_FILE_NONE, NULL)) { + g_free(config_file); + config_file = g_build_filename(g_get_home_dir(), ".miraclecast", NULL); + if (!g_key_file_load_from_file(gkf, config_file, G_KEY_FILE_NONE, NULL)) { + g_key_file_free(gkf); + gkf = NULL; + } + } + g_free(config_file); + return gkf; +} static inline void cleanup_sd_bus_message(sd_bus_message **ptr) { diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index c041e34..0dd7585 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -23,8 +23,8 @@ pkg_check_modules (UDEV REQUIRED libudev) #link_directories( ${UDEV_LIBRARY_DIRS}) #include_directories( ${UDEV_INCLUDE_DIRS}) target_link_libraries(miracle-wifid ${UDEV_LIBRARIES}) -#link_directories( ${GLIB2_LIBRARY_DIRS}) -#include_directories( ${GLIB2_INCLUDE_DIRS}) +link_directories( ${GLIB2_LIBRARY_DIRS}) +include_directories( ${GLIB2_INCLUDE_DIRS}) target_link_libraries(miracle-wifid ${GLIB2_LIBRARIES}) install(TARGETS miracle-wifid DESTINATION bin) diff --git a/src/wifi/Makefile.am b/src/wifi/Makefile.am index 179d4cc..463ac17 100644 --- a/src/wifi/Makefile.am +++ b/src/wifi/Makefile.am @@ -10,8 +10,10 @@ miracle_wifid_SOURCES = \ wifid-supplicant.c miracle_wifid_CPPFLAGS = \ $(AM_CPPFLAGS) \ - $(DEPS_CFLAGS) + $(DEPS_CFLAGS) \ + $(GLIB_CFLAGS) miracle_wifid_LDADD = \ ../shared/libmiracle-shared.la \ - $(DEPS_LIBS) + $(DEPS_LIBS) \ + $(GLIB_LIBS) diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index ca7e461..09e7195 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -543,6 +543,18 @@ int main(int argc, char **argv) srand(time(NULL)); + GKeyFile* gkf = load_ini_file(); + + if (gkf) { + gchar* log_level; + log_level = g_key_file_get_string (gkf, "wifid", "log-level", NULL); + if (log_level) { + log_max_sev = log_parse_arg(log_level); + g_free(log_level); + } + g_key_file_free(gkf); + } + r = parse_argv(argc, argv); if (r < 0) return EXIT_FAILURE; From b8de12cab38da3eeefc71c16b940a7b50f888c8f Mon Sep 17 00:00:00 2001 From: albfan Date: Wed, 5 Apr 2017 07:51:04 +0200 Subject: [PATCH 047/142] Avoid config stdin if not a tty Allow to run miracle-sinkctl as a service relates to #98 --- src/ctl/ctl-cli.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index c1e5855..6e8182a 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -317,16 +317,18 @@ int cli_init(sd_bus *bus, const struct cli_cmd *cmds) } } - r = sd_event_add_io(cli_event, - &cli_stdin, - fileno(stdin), - EPOLLHUP | EPOLLERR | EPOLLIN, - cli_stdin_fn, - NULL); - if (r < 0) { - cli_vERR(r); - goto error; - } + if (isatty(fileno(stdin))) { + r = sd_event_add_io(cli_event, + &cli_stdin, + fileno(stdin), + EPOLLHUP | EPOLLERR | EPOLLIN, + cli_stdin_fn, + NULL); + if (r < 0) { + cli_vERR(r); + goto error; + } + } cli_rl = true; From c3f6b7f68345e43ad3817b734aa173bc04556720 Mon Sep 17 00:00:00 2001 From: albfan Date: Fri, 7 Apr 2017 21:49:43 +0200 Subject: [PATCH 048/142] Fix cmake compilation for ini files --- src/ctl/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt index d6d98e4..7d41b54 100644 --- a/src/ctl/CMakeLists.txt +++ b/src/ctl/CMakeLists.txt @@ -1,5 +1,9 @@ - +find_package(PkgConfig) +pkg_check_modules (GLIB2 REQUIRED glib-2.0) +link_directories( ${GLIB2_LIBRARY_DIRS}) +include_directories( ${GLIB2_INCLUDE_DIRS}) find_package(Readline) +pkg_check_modules (GLIB2 REQUIRED glib-2.0) ########### next target ############### set(miracle-wifictl_SRCS ctl.h @@ -20,6 +24,7 @@ if(READLINE_FOUND) endif(READLINE_FOUND) target_link_libraries(miracle-wifictl miracle-shared) +target_link_libraries(miracle-wifictl ${GLIB2_LIBRARIES}) ########### next target ############### set(miracle-sinkctl_SRCS ctl.h @@ -31,6 +36,7 @@ set(miracle-sinkctl_SRCS ctl.h wfd.c) add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS}) +target_link_libraries(miracle-sinkctl ${GLIB2_LIBRARIES}) install(TARGETS miracle-sinkctl DESTINATION bin) From fe9a39bee8b5fc05cca48b50a98426942826f5cb Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Fri, 7 Apr 2017 18:26:19 -0700 Subject: [PATCH 049/142] miracle-sinkctl: don't use readline if no stdin Signed-off-by: Eric Nelson --- src/ctl/ctl-cli.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 6e8182a..0897aa7 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -317,28 +317,27 @@ int cli_init(sd_bus *bus, const struct cli_cmd *cmds) } } - if (isatty(fileno(stdin))) { - r = sd_event_add_io(cli_event, - &cli_stdin, - fileno(stdin), - EPOLLHUP | EPOLLERR | EPOLLIN, - cli_stdin_fn, - NULL); - if (r < 0) { - cli_vERR(r); - goto error; - } - } + if (isatty(fileno(stdin))) { + r = sd_event_add_io(cli_event, + &cli_stdin, + fileno(stdin), + EPOLLHUP | EPOLLERR | EPOLLIN, + cli_stdin_fn, + NULL); + if (r < 0) { + cli_vERR(r); + goto error; + } + cli_rl = true; - cli_rl = true; + rl_erase_empty_line = 1; + rl_callback_handler_install(NULL, cli_handler_fn); - rl_erase_empty_line = 1; - rl_callback_handler_install(NULL, cli_handler_fn); - - rl_set_prompt(CLI_PROMPT); - printf("\r"); - rl_on_new_line(); - rl_redisplay(); + rl_set_prompt(CLI_PROMPT); + printf("\r"); + rl_on_new_line(); + rl_redisplay(); + } return 0; From 6b5907ad458d410cea53c799056c81f36a2c8cd7 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Mon, 3 Apr 2017 12:12:50 +0800 Subject: [PATCH 050/142] Add meson build system Use it as: $ meson build $ cd build $ ninja build $ ninja test $ sudo ninja install --- .gitignore | 1 + meson.build | 45 ++++++++++++++++++++++++++++++++++++++++++ meson_options.txt | 12 +++++++++++ res/meson.build | 8 ++++++++ src/ctl/meson.build | 24 ++++++++++++++++++++++ src/dhcp/meson.build | 11 +++++++++++ src/meson.build | 11 +++++++++++ src/shared/meson.build | 22 +++++++++++++++++++++ src/uibc/meson.build | 5 +++++ src/wifi/meson.build | 14 +++++++++++++ test/meson.build | 37 ++++++++++++++++++++++++++++++++++ 11 files changed, 190 insertions(+) create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 res/meson.build create mode 100644 src/ctl/meson.build create mode 100644 src/dhcp/meson.build create mode 100644 src/meson.build create mode 100644 src/shared/meson.build create mode 100644 src/uibc/meson.build create mode 100644 src/wifi/meson.build create mode 100644 test/meson.build diff --git a/.gitignore b/.gitignore index 089ec5d..dd6862d 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ cmake_install.cmake CMakeCache.txt libmiracle-shared.a install_manifest.txt +/build/ diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..1e88906 --- /dev/null +++ b/meson.build @@ -0,0 +1,45 @@ +project('Miraclecast', + 'c', + version: '1', + meson_version: '>=0.39', + default_options: ['buildtype=debugoptimized', 'c_std=gnu11'] +) + +add_project_arguments('-D_GNU_SOURCE', language: 'c') + +conf_data = configuration_data() +conf_data.set_quoted('BUILD_BINDIR', + join_paths(get_option('prefix'), get_option('bindir')) +) +conf_data.set_quoted('PACKAGE_STRING', + '@0@ @1@'.format(meson.project_name(), meson.project_version()) +) +configure_file(output: 'config.h', + configuration: conf_data +) + +c_compiler = meson.get_compiler('c') +readline = c_compiler.find_library('readline', required: false) +if readline.found() + add_project_arguments('-DHAVE_READLINE', language: 'c') +endif + +if get_option('build-enable-debug') + add_project_arguments('-DBUILD_ENABLE_DEBUG', language: 'c') +endif + +if get_option('rely-udev') + add_project_arguments('-DRELY_UDEV', language: 'c') +endif + +glib2 = dependency('glib-2.0') +udev = dependency('libudev') +libsystemd = dependency('libsystemd') + +subdir('src') +subdir('res') + +if get_option('build-tests') + subdir('test') +endif + diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..34002ff --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,12 @@ +option('build-enable-debug', + type: 'boolean', + value: true, + description: 'Enable Debug') +option('rely-udev', + type: 'boolean', + value: false, + description: 'Rely in udev tag to select device') +option('build-tests', + type: 'boolean', + value: true, + description: 'Enable TEST') diff --git a/res/meson.build b/res/meson.build new file mode 100644 index 0000000..1b331ad --- /dev/null +++ b/res/meson.build @@ -0,0 +1,8 @@ +install_data( + 'org.freedesktop.miracle.conf', + install_dir: join_paths(get_option('sysconfdir'), 'dbus-1', 'system.d') +) + +install_data('miracle-gst', 'gstplayer', 'uibc-viewer', + install_dir: get_option('bindir'), + install_mode: 'rwxr-xr-x') diff --git a/src/ctl/meson.build b/src/ctl/meson.build new file mode 100644 index 0000000..d2ba182 --- /dev/null +++ b/src/ctl/meson.build @@ -0,0 +1,24 @@ +inc = include_directories('../..') +deps = [libsystemd, libmiracle_shared_dep, glib2] +if readline.found() + deps += readline +endif + +miracle_wifictl_srcs = ['ctl-cli.c', 'ctl-wifi.c', 'wifictl.c'] +executable('miracle-wifictl', miracle_wifictl_srcs, + install: true, + include_directories: inc, + dependencies: deps +) + +miracle_sinkctl_srcs = ['ctl-cli.c', + 'ctl-sink.c', + 'ctl-wifi.c', + 'sinkctl.c', + 'wfd.c' +] +executable('miracle-sinkctl', miracle_sinkctl_srcs, + install: true, + include_directories: inc, + dependencies: deps +) diff --git a/src/dhcp/meson.build b/src/dhcp/meson.build new file mode 100644 index 0000000..1dce905 --- /dev/null +++ b/src/dhcp/meson.build @@ -0,0 +1,11 @@ +miracle_dhcp_srcs = ['dhcp.c', + 'common.c', + 'ipv4ll.c', + 'client.c', + 'server.c' +] +executable('miracle-dhcp', miracle_dhcp_srcs, + install: true, + include_directories: include_directories('../..'), + dependencies: [glib2, udev, libmiracle_shared_dep] +) diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..1179ab3 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,11 @@ +subdir('shared') +subdir('wifi') +subdir('dhcp') +subdir('ctl') +subdir('uibc') + +executable('miracled', 'miracled.c', + dependencies: libmiracle_shared_dep, + include_directories: include_directories('..'), + install: true +) diff --git a/src/shared/meson.build b/src/shared/meson.build new file mode 100644 index 0000000..4af9e34 --- /dev/null +++ b/src/shared/meson.build @@ -0,0 +1,22 @@ +libmiracle_shared = static_library('miracle-shared', + 'rtsp.h', + 'rtsp.c', + 'shl_dlist.h', + 'shl_htable.h', + 'shl_htable.c', + 'shl_log.h', + 'shl_log.c', + 'shl_macro.h', + 'shl_ring.h', + 'shl_ring.c', + 'shl_util.h', + 'shl_util.c', + 'util.h', + 'wpas.h', + 'wpas.c', + dependencies: [libsystemd] +) +libmiracle_shared_dep = declare_dependency( + include_directories: include_directories('.'), + link_with: libmiracle_shared +) diff --git a/src/uibc/meson.build b/src/uibc/meson.build new file mode 100644 index 0000000..17a06db --- /dev/null +++ b/src/uibc/meson.build @@ -0,0 +1,5 @@ +m = c_compiler.find_library('m', required: false) +executable('miracle-uibcctl', 'miracle-uibcctl.h', 'miracle-uibcctl.c', + install: true, + dependencies: [m, libmiracle_shared_dep] +) diff --git a/src/wifi/meson.build b/src/wifi/meson.build new file mode 100644 index 0000000..e0176f4 --- /dev/null +++ b/src/wifi/meson.build @@ -0,0 +1,14 @@ +inc = include_directories('../..') +miracle_wifid_src = ['wifid.h', + 'wifid.c', + 'wifid-dbus.c', + 'wifid-link.c', + 'wifid-peer.c', + 'wifid-supplicant.c' +] +executable('miracle-wifid', miracle_wifid_src, + include_directories: inc, + install: true, + dependencies: [udev, glib2, libsystemd, libmiracle_shared_dep] +) + diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000..68e7ef3 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,37 @@ +check = dependency('check', required: false) +deps = [udev, glib2, check, libsystemd, libmiracle_shared_dep] + +if check.found() + test_rtsp = executable('test_rtsp', 'test_rtsp.c', dependencies: deps) + + test_wpas = executable('test_wpas', 'test_wpas.c', dependencies: deps) + + test_valgrind = executable('test_valgrind', + 'test_valgrind.c', + dependencies: deps + ) + + valgrind = find_program('valgrind') + + test('rtsp test', test_rtsp) + test('wpas test', test_wpas) + test('valgrind test', test_valgrind) + +# set(VALGRIND CK_FORK=no valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --leak-resolution=high --error-exitcode=1 --suppressions=${CMAKE_SOURCE_DIR}/test.supp) +# +# add_custom_target(memcheck-verify +# DEPENDS test_rtsp test_wpas test_valgrind +# COMMAND ${VALGRIND} --log-file=/dev/null ./test_valgrind >/dev/null | +# test 1 = $$? +# COMMENT "verify memcheck") +# +# add_custom_target(memcheck +# DEPENDS memcheck-verify +# COMMAND for i in $(MEMTESTS) | +# do | +# ${VALGRIND} --log-file=${CMAKE_SOURCE_DIR}/$$i.memlog | +# ${CMAKE_SOURCE_DIR}/$$i >/dev/null || (echo "memcheck failed on: $$i" ; exit 1) ; | +# done +# SOURCES test_rtsp test_valgrind test_wpas +# COMMENT "verify memcheck") +endif From a6f672311edaddb18d5c294d9328b77df77b15db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Derek=20=E5=91=86?= Date: Sat, 15 Apr 2017 21:59:46 +0800 Subject: [PATCH 051/142] Logging Formation failure miracle-sinkctl: Fix signal emotion of FormationFailure miracle-wifid: Log formation failure --- src/wifi/wifid-dbus.c | 1 + src/wifi/wifid-supplicant.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/wifi/wifid-dbus.c b/src/wifi/wifid-dbus.c index f462cf4..e7f73ec 100644 --- a/src/wifi/wifid-dbus.c +++ b/src/wifi/wifid-dbus.c @@ -309,6 +309,7 @@ static const sd_bus_vtable peer_dbus_vtable[] = { SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_SIGNAL("ProvisionDiscovery", "ss", 0), SD_BUS_SIGNAL("GoNegRequest", "ss", 0), + SD_BUS_SIGNAL("FormationFailure", "s", 0), SD_BUS_VTABLE_END }; diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 4cb4ae7..13951bf 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -1292,6 +1292,20 @@ static void supplicant_event_p2p_group_removed(struct supplicant *s, supplicant_group_free(g); } +static void supplicant_event_p2p_go_neg_failure(struct supplicant *s, + struct wpas_message *ev) +{ + struct peer *p; + + if (s->pending) { + log_debug("peer %s group owner negotiation failed", + s->pending->friendly_name); + p = s->pending->p; + s->pending = NULL; + peer_supplicant_formation_failure(p, "group owner negotiation failed"); + } +} + static void supplicant_event_p2p_group_formation_failure(struct supplicant *s, struct wpas_message *ev) { @@ -1472,6 +1486,8 @@ static void supplicant_event(struct supplicant *s, struct wpas_message *m) supplicant_event_p2p_group_started(s, m); else if (!strcmp(name, "P2P-GROUP-REMOVED")) supplicant_event_p2p_group_removed(s, m); + else if (!strcmp(name, "P2P-GO-NEG-FAILURE")) + supplicant_event_p2p_go_neg_failure(s, m); else if (!strcmp(name, "P2P-GROUP-FORMATION-FAILURE")) supplicant_event_p2p_group_formation_failure(s, m); else if (!strcmp(name, "AP-STA-CONNECTED")) From 68802bb592addd363be50596917e0bf9b72d043a Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 15 Apr 2017 22:35:43 +0200 Subject: [PATCH 052/142] Customizable sysconfdir on cmake --- CMakeLists.txt | 2 ++ res/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6aea926..75f21f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ if(BUILD_ENABLE_DEBUG) add_definitions(-DBUILD_ENABLE_DEBUG) endif() +set(SYSCONFDIR "/etc" CACHE STRING "system config dir") + find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 4cb3f19..b28fa2b 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -8,5 +8,5 @@ install( INSTALL( FILES org.freedesktop.miracle.conf - DESTINATION /etc/dbus-1/system.d + DESTINATION ${SYSCONFDIR}/dbus-1/system.d ) From 033690b7fb20ca053e22968d0fc62f6d98dd74a1 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 15 Apr 2017 23:00:51 +0200 Subject: [PATCH 053/142] Fix omxplayer execution --- res/miracle-omxplayer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/miracle-omxplayer b/res/miracle-omxplayer index dfa9152..961e2ec 100755 --- a/res/miracle-omxplayer +++ b/res/miracle-omxplayer @@ -63,7 +63,7 @@ while getopts "r:d:as:p:h" optname esac done -RUN="omxplayer -live -b - o hdmi rtp://localhost:$PORT" +RUN="omxplayer -live -b -o hdmi rtp://@:$PORT" echo "running: $RUN" exec ${RUN} From 92ab7eb2d34fdfb27219a1cd7d55154c00ed64d2 Mon Sep 17 00:00:00 2001 From: albfan Date: Sat, 15 Apr 2017 23:09:22 +0200 Subject: [PATCH 054/142] Move info from README to wiki --- README.md | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 84bb4b8..93c9666 100644 --- a/README.md +++ b/README.md @@ -29,34 +29,15 @@ The MiracleCast projects requires the following software to be installed: - copy the dbus policy **res/org.freedesktop.miracle.conf** to `/etc/dbus-1/system.d/` -## Install +## Build and install -To compile MiracleCast, you can choose from [autotools](http://en.wikipedia.org/wiki/GNU_build_system) or [cmake](http://en.wikipedia.org/wiki/CMake): +To compile MiracleCast, you can choose from: -Autotools: + - [autotools](http://en.wikipedia.org/wiki/GNU_build_system) + - [cmake](http://en.wikipedia.org/wiki/CMake) + - [meson](http://mesonbuild.com/) - $ ./autogen.sh - $ mkdir build - $ cd build - $ ../configure --prefix=/usr/local #avoid --prefix for a standard install - -Cmake: - - $ mkdir build - $ cd build - $ cmake .. - -Compile - - $ make - -Test - - $ make check #only with autotools by now - -Install - - $ sudo make install +See more info on wiki [Building](https://github.com/albfan/miraclecast/wiki/Building) ## Automatic interface selection with udev From 20036e77dc52a050b4aa6658355a73eef35f8843 Mon Sep 17 00:00:00 2001 From: albfan Date: Tue, 18 Apr 2017 04:50:13 +0200 Subject: [PATCH 055/142] Accept configure params on autogen.sh --- autogen.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/autogen.sh b/autogen.sh index 60be64e..7912a7c 100755 --- a/autogen.sh +++ b/autogen.sh @@ -26,18 +26,28 @@ fi cd $oldpwd if [ "x$1" = "xc" ]; then + shift + args="$args $@" $topdir/configure CFLAGS='-g -O0 -ftrapv' $args make clean elif [ "x$1" = "xg" ]; then - $topdir/configure CFLAGS='-g -Og -ftrapv' $args + shift + args="$args $@" + $topdir/configure CFLAGS='-g -O0 -ftrapv' $args make clean elif [ "x$1" = "xa" ]; then + shift + args="$args $@" $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args make clean elif [ "x$1" = "xl" ]; then + shift + args="$args $@" $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args make clean elif [ "x$1" = "xs" ]; then + shift + args="$args $@" scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' $args scan-build make else From eceb252ec7d7926174cc9ec290eef5b7144bcadb Mon Sep 17 00:00:00 2001 From: albfan Date: Tue, 18 Apr 2017 04:51:11 +0200 Subject: [PATCH 056/142] Adding code coverage --- Makefile.am | 18 +++++++++++++ README.md | 1 + configure.ac | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/Makefile.am b/Makefile.am index ef42db4..5a62abe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,3 +4,21 @@ EXTRA_DIST = README.md \ NEWS ACLOCAL_AMFLAGS = -I m4 + +.PHONY: lcov genlcov lcov-clean + +lcov: + -$(MAKE) $(AM_MAKEFLAGS) -k check + $(MAKE) $(AM_MAKEFLAGS) genlcov + +# we have to massage the lcov.info file slightly to hide the effect of libtool +# placing the objects files in the .libs/ directory separate from the *.c +genlcov: + $(LTP) --directory $(top_builddir) --capture --output-file miraclecast-lcov.info --test-name GLIB_PERF --no-checksum + LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory miraclecast-lcov --title "Miraclecast Code Coverage" --legend --show-details miraclecast-lcov.info + +lcov-clean: + -$(LTP) --directory $(top_builddir) -z + -rm -rf miraclecast-lcov.info miraclecast-lcov + -find -name '*.gcda' -print | xargs -Ix rm x + diff --git a/README.md b/README.md index 93c9666..13b6254 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://semaphoreci.com/api/v1/projects/5ece4a7a-365b-4f7c-bfcc-6dcdece7002f/671892/badge.svg)](https://semaphoreci.com/albfan/miraclecast) +[![Coverage Status](https://coveralls.io/repos/github/albfan/miraclecast/badge.svg?branch=master)](https://coveralls.io/github/albfan/miraclecast?branch=master) The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. diff --git a/configure.ac b/configure.ac index 1f0aa64..991b969 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,78 @@ PKG_CHECK_MODULES([CHECK], [check], [have_check=yes], [have_check=no]) AM_CONDITIONAL([BUILD_HAVE_CHECK], [test "x$have_check" = "xyes"]) +if test "x$have_check" = "xyes" +then + + dnl ************************************ + dnl *** Enable lcov coverage reports *** + dnl ************************************ + + AC_ARG_ENABLE(gcov, + AS_HELP_STRING([--enable-gcov], + [Enable gcov]), + [use_gcov=$enableval], [use_gcov=no]) + + if test "x$use_gcov" = "xyes"; then + dnl we need gcc: + if test "$GCC" != "yes"; then + AC_MSG_ERROR([GCC is required for --enable-gcov]) + fi + + dnl Check if ccache is being used + AC_CHECK_PROG(SHTOOL, shtool, shtool) + case `$SHTOOL path $CC` in + *ccache*[)] gcc_ccache=yes;; + *[)] gcc_ccache=no;; + esac + + if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then + AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) + fi + + ltp_version_list="1.6 1.7 1.8 1.11 1.12" + AC_CHECK_PROG(LTP, lcov, lcov) + AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) + + if test "$LTP"; then + AC_CACHE_CHECK([for ltp version], glib_cv_ltp_version, [ + glib_cv_ltp_version=invalid + ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'` + for ltp_check_version in $ltp_version_list; do + if test "$ltp_version" = "$ltp_check_version"; then + glib_cv_ltp_version="$ltp_check_version (ok)" + fi + done + ]) + else + ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list" + AC_MSG_ERROR([$ltp_msg]) + fi + + case $glib_cv_ltp_version in + ""|invalid[)] + ltp_msg="You must have one of the following versions of LTP: $ltp_version_list (found: $ltp_version)." + AC_MSG_ERROR([$ltp_msg]) + LTP="exit 0;" + ;; + esac + + if test -z "$LTP_GENHTML"; then + AC_MSG_ERROR([Could not find genhtml from the LTP package]) + fi + + AC_DEFINE(HAVE_GCOV, 1, [Whether you have gcov]) + + dnl Remove all optimization flags from CFLAGS + changequote({,}) + CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` + changequote([,]) + + dnl Add the special gcc flags + CFLAGS="$CFLAGS -O0 -fprofile-arcs -ftest-coverage" + LDFLAGS="$LDFLAGS -lgcov" + fi +fi # # Makefile vars # After everything is configured, we create all makefiles. @@ -92,6 +164,7 @@ AC_MSG_NOTICE([Build configuration: Miscellaneous Options: building tests: $have_check + code coverage: $use_gcov Compilation mkdir build && cd build From 3dec3e9b837dd4c8aece23507c7eb9fd9190b358 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 18 Apr 2017 10:42:36 +0200 Subject: [PATCH 057/142] Fixing CI for Code Coverage --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 991b969..5c1e1ef 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,7 @@ then AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) fi - ltp_version_list="1.6 1.7 1.8 1.11 1.12" + ltp_version_list="1.6 1.7 1.8 1.10 1.11 1.12" AC_CHECK_PROG(LTP, lcov, lcov) AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) From a395c3c7afc39a958ae8ab805dea0f5d22118f0c Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Sat, 22 Apr 2017 16:16:59 +0800 Subject: [PATCH 058/142] remove valgrind checking since now it is optional Change-Id: I39dc6b3e23307fd039775983b6d68878547523ba --- test/meson.build | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/meson.build b/test/meson.build index 68e7ef3..1514773 100644 --- a/test/meson.build +++ b/test/meson.build @@ -11,8 +11,6 @@ if check.found() dependencies: deps ) - valgrind = find_program('valgrind') - test('rtsp test', test_rtsp) test('wpas test', test_wpas) test('valgrind test', test_valgrind) From 0c3f02e97bce0cea8c332800a55c265c1b3c4a79 Mon Sep 17 00:00:00 2001 From: albfan Date: Wed, 31 Jan 2018 22:14:26 +0100 Subject: [PATCH 059/142] fix info to stop normal wifi --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 13b6254..f234d07 100644 --- a/README.md +++ b/README.md @@ -83,15 +83,12 @@ If you feel confidence enough (since systemd is the entrypoint for an OS) extrac ## Documentation -Steps to use it as sink: +- Steps to use it as sink: 1. shutdown wpa_supplicant and NetworkManager - $ sudo kill -9 $(ps -ef | grep wpa_supplican[t] | awk '{print $2}') - # now you can use `res/kill-wpa.sh` - - >Remember to save your config to use with `res/normal-wifi.sh` - >it will be easily located with `ps -ef | grep wpa_supplicant` on `-c` option. + $ systemctl stop NetworkManager.service + $ systemctl stop wpa_supplicant.service 2. launch wifi daemon @@ -110,7 +107,7 @@ Steps to use it as sink: 6. See your screen device on this machine -Steps to use it as peer: +- Steps to use it as peer: 1. Repeat steps 1 and 2 from "use as sink" From 76f01898292e8a014e5a460b41666b84e784b214 Mon Sep 17 00:00:00 2001 From: Arsh Singh Date: Tue, 13 Feb 2018 10:30:20 -0800 Subject: [PATCH 060/142] Fix Arch Linux AUR package link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f234d07..476b465 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ See there was interface changes on systemd 219, if you are below that version, u ### Arch linux -Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast/). Remember to enable kdus to systemd-git dependency if you are below 221 systemd. +Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast-git/). Remember to enable kdus to systemd-git dependency if you are below 221 systemd. $ export _systemd_git_kdbus=--enable-kdbus From 1d01ae2117b8e2a3dc24b21761a02d5b8dd46b70 Mon Sep 17 00:00:00 2001 From: albfan Date: Thu, 22 Feb 2018 22:30:09 +0100 Subject: [PATCH 061/142] sink: Enable all resolutions by default --- src/ctl/sinkctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 844dd9c..029407c 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -67,9 +67,9 @@ int rstp_port; int uibc_port; char* player; -unsigned int wfd_supported_res_cea = 0x0000001f; /* up to 720x576 */ -unsigned int wfd_supported_res_vesa = 0x00000003; /* up to 800x600 */ -unsigned int wfd_supported_res_hh = 0x00000000; /* not supported */ +unsigned int wfd_supported_res_cea = 0x0001ffff; +unsigned int wfd_supported_res_vesa = 0x1fffffff; +unsigned int wfd_supported_res_hh = 0x00001fff; /* * cmd list From 34595f035e5b02b60c2569ea8ed7ef1a131fbb1c Mon Sep 17 00:00:00 2001 From: Julian Kornberger Date: Mon, 19 Mar 2018 18:10:41 +0100 Subject: [PATCH 062/142] Update README.md Use ### for sub-sub-titles --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 476b465..3b04545 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ If you feel confidence enough (since systemd is the entrypoint for an OS) extrac ## Documentation -- Steps to use it as sink: +### Steps to use it as sink 1. shutdown wpa_supplicant and NetworkManager @@ -107,7 +107,7 @@ If you feel confidence enough (since systemd is the entrypoint for an OS) extrac 6. See your screen device on this machine -- Steps to use it as peer: +### Steps to use it as peer 1. Repeat steps 1 and 2 from "use as sink" From 5bfc97a72cc6252f307526bd1a2581ef1a3d292b Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 21 Sep 2018 13:02:57 +0200 Subject: [PATCH 063/142] Customizable config_methods --- src/wifi/wifid-link.c | 17 +++++++++++++++++ src/wifi/wifid-supplicant.c | 5 ++--- src/wifi/wifid.c | 22 ++++++++++++++++++++-- src/wifi/wifid.h | 3 +++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index b2de058..bc69557 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -129,6 +129,7 @@ void link_free(struct link *l) free(l->wfd_subelements); free(l->friendly_name); free(l->ifname); + free(l->config_methods); free(l); } @@ -142,6 +143,22 @@ bool link_is_using_dev(struct link *l) return l->use_dev; } +int link_set_config_methods(struct link *l, char *config_methods) +{ + char *cm; + + if (!config_methods) + return log_EINVAL(); + + cm = strdup(config_methods); + if (!cm) + return log_ENOMEM(); + + free(l->config_methods); + l->config_methods = config_methods; + return 0; +} + void link_set_managed(struct link *l, bool set) { int r; diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 13951bf..a2a3a43 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2597,10 +2597,9 @@ static int supplicant_write_config(struct supplicant *s) "driver_param=%s\n" "ap_scan=%s\n" "# End of configuration\n", - s->l->friendly_name ? : "unknown", + s->l->friendly_name ?: "unknown", "1-0050F204-1", - "pbc", - //"pbc keypad pin display", + s->l->config_methods ?: "pbc", "p2p_device=1", "1"); if (r < 0) { diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 09e7195..4c0f02c 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -41,6 +41,7 @@ #include "config.h" const char *interface_name = NULL; +const char *config_methods = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; bool use_dev = false; @@ -102,6 +103,7 @@ static void manager_add_udev_link(struct manager *m, return; link_set_friendly_name(l, m->friendly_name); + link_set_config_methods(l, m->config_methods); if(use_dev) link_use_dev(l); @@ -215,6 +217,7 @@ static void manager_free(struct manager *m) sd_event_unref(m->event); free(m->friendly_name); + free(m->config_methods); free(m); } @@ -227,6 +230,7 @@ static int manager_new(struct manager **out) unsigned int i; sigset_t mask; int r; + char *cm; m = calloc(1, sizeof(*m)); if (!m) @@ -234,6 +238,16 @@ static int manager_new(struct manager **out) shl_htable_init_uint(&m->links); + + if (config_methods) { + cm = strdup(config_methods); + if (!cm) + return log_ENOMEM(); + + free(m->config_methods); + m->config_methods = cm; + } + r = sd_event_default(&m->event); if (r < 0) { log_vERR(r); @@ -459,6 +473,7 @@ static int help(void) " --log-time Prefix log-messages with timestamp\n" "\n" " -i --interface Choose the interface to use\n" + " --config-methods Define config methods for pairing, default 'pbc'\n" "\n" " --wpa-loglevel Date: Fri, 21 Sep 2018 12:39:17 +0200 Subject: [PATCH 064/142] bash completion with lazy load --- CMakeLists.txt | 1 + res/CMakeLists.txt | 10 ++- res/Makefile.am | 2 +- res/meson.build | 5 ++ res/miracle-sinkctl | 85 +++++++++++++++++++ res/miracle-wifictl | 85 +++++++++++++++++++ res/{miraclecast-completion => miracle-wifid} | 49 ++--------- 7 files changed, 192 insertions(+), 45 deletions(-) create mode 100755 res/miracle-sinkctl create mode 100755 res/miracle-wifictl rename res/{miraclecast-completion => miracle-wifid} (69%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75f21f6..a073be0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ if(BUILD_ENABLE_DEBUG) endif() set(SYSCONFDIR "/etc" CACHE STRING "system config dir") +set(DATADIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "shared data dir") find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index b28fa2b..e67277e 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -1,7 +1,4 @@ - -########### install files ############### - -install( +INSTALL( PROGRAMS miracle-gst gstplayer uibc-viewer DESTINATION bin ) @@ -10,3 +7,8 @@ INSTALL( FILES org.freedesktop.miracle.conf DESTINATION ${SYSCONFDIR}/dbus-1/system.d ) + +INSTALL( + FILES miracle-wifid miracle-sinkctl miracle-wifictl + DESTINATION ${DATADIR}/bash-completion/completions + ) diff --git a/res/Makefile.am b/res/Makefile.am index 9e73673..b11d0b3 100644 --- a/res/Makefile.am +++ b/res/Makefile.am @@ -5,5 +5,5 @@ dbuspolicydir=$(sysconfdir)/dbus-1/system.d dbuspolicy_DATA = org.freedesktop.miracle.conf bashcompletiondir=${datadir}/bash-completion/completions -bashcompletion_DATA=miraclecast-completion +bashcompletion_DATA=miracle-wifid miracle-sinkctl miracle-wifictl diff --git a/res/meson.build b/res/meson.build index 1b331ad..037a759 100644 --- a/res/meson.build +++ b/res/meson.build @@ -6,3 +6,8 @@ install_data( install_data('miracle-gst', 'gstplayer', 'uibc-viewer', install_dir: get_option('bindir'), install_mode: 'rwxr-xr-x') + +install_data( + 'miracle-wifid', 'miracle-sinkctl', 'miracle-wifictl', + install_dir: join_paths(get_option('datadir'), 'bash-completions', 'completions') +) diff --git a/res/miracle-sinkctl b/res/miracle-sinkctl new file mode 100755 index 0000000..a14c0bb --- /dev/null +++ b/res/miracle-sinkctl @@ -0,0 +1,85 @@ +# +# Autocompletion for miraclecast commands +# +# Maintainer: Alberto Fanjul +# + +function _miracle-sinkctl() { + local cur prev + + _get_comp_words_by_ref cur + prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + --log-level) + COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur")) + return 0 + ;; + esac + + COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl) $(_parse_short_help miracle-sinkctl)" -- "$cur")) +} + +_parse_short_help () +{ + eval local cmd=$( quote "$1" ); + local line; + { + case $cmd in + -) + cat + ;; + *) + LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 + ;; + esac + } | while read -r line; do + [[ $line == *([[:blank:]])-* ]] || continue; + while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do + line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}; + done; + __parse_short_options "${line// or /, }"; + done +} + +__parse_short_options () +{ + local option option2 i IFS=' +,/|'; + option=; + local -a array; + read -a array <<< "$1"; + for i in "${array[@]}"; + do + case "$i" in + ---*) + break + ;; + --?*) + break + ;; + -?*) + option=$i; + break + ;; + *) + break + ;; + esac; + done; + [[ -n $option ]] || return; + IFS=' +'; + if [[ $option =~ (\[((no|dont)-?)\]). ]]; then + option2=${option/"${BASH_REMATCH[1]}"/}; + option2=${option2%%[<{().[]*}; + printf '%s\n' "${option2/=*/=}"; + option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}; + fi; + option=${option%%[<{().[]*}; + printf '%s\n' "${option/=*/=}" +} + +complete -F _miracle-sinkctl miracle-sinkctl + +# ex: filetype=sh diff --git a/res/miracle-wifictl b/res/miracle-wifictl new file mode 100755 index 0000000..07fc4ae --- /dev/null +++ b/res/miracle-wifictl @@ -0,0 +1,85 @@ +# +# Autocompletion for miracle-wifictl +# +# Maintainer: Alberto Fanjul +# + +function _miracle-wifictl() { + local cur prev + + _get_comp_words_by_ref cur + prev=${COMP_WORDS[COMP_CWORD-1]} + + case "$prev" in + --log-level) + COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur")) + return 0 + ;; + esac + + COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl) $(_parse_short_help miracle-wifictl)" -- "$cur")) +} + +_parse_short_help () +{ + eval local cmd=$( quote "$1" ); + local line; + { + case $cmd in + -) + cat + ;; + *) + LC_ALL=C "$( dequote "$cmd" )" ${2:---help} 2>&1 + ;; + esac + } | while read -r line; do + [[ $line == *([[:blank:]])-* ]] || continue; + while [[ $line =~ ((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do + line=${line/"${BASH_REMATCH[0]}"/"${BASH_REMATCH[1]}"}; + done; + __parse_short_options "${line// or /, }"; + done +} + +__parse_short_options () +{ + local option option2 i IFS=' +,/|'; + option=; + local -a array; + read -a array <<< "$1"; + for i in "${array[@]}"; + do + case "$i" in + ---*) + break + ;; + --?*) + break + ;; + -?*) + option=$i; + break + ;; + *) + break + ;; + esac; + done; + [[ -n $option ]] || return; + IFS=' +'; + if [[ $option =~ (\[((no|dont)-?)\]). ]]; then + option2=${option/"${BASH_REMATCH[1]}"/}; + option2=${option2%%[<{().[]*}; + printf '%s\n' "${option2/=*/=}"; + option=${option/"${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]}"}; + fi; + option=${option%%[<{().[]*}; + printf '%s\n' "${option/=*/=}" +} + +complete -F _miracle-wifictl miracle-wifictl + +# ex: filetype=sh diff --git a/res/miraclecast-completion b/res/miracle-wifid similarity index 69% rename from res/miraclecast-completion rename to res/miracle-wifid index 1d82b32..1f320bd 100755 --- a/res/miraclecast-completion +++ b/res/miracle-wifid @@ -1,7 +1,5 @@ -#!/bin/bash - # -# Autocompletion for miraclecast commands +# Autocompletion for miracle-wifid # # Maintainer: Alberto Fanjul # @@ -13,6 +11,10 @@ function _miracle-wifid() { prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in + --config-methods) + COMPREPLY=($(compgen -W 'pbc pin usba ethernet label display ext_nfc_token int_nfc_token nfc_interface push_button keypad virtual_display physical_display virtual_push_button physical_push_button' -- "$cur")) + return 0 + ;; --log-level) COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur")) return 0 @@ -26,43 +28,6 @@ function _miracle-wifid() { COMPREPLY=($(compgen -W "$(_parse_help miracle-wifid) $(_parse_short_help miracle-wifid)" -- "$cur")) } -complete -F _miracle-wifid miracle-wifid - -function _miracle-sinkctl() { - local cur prev - - _get_comp_words_by_ref cur - prev=${COMP_WORDS[COMP_CWORD-1]} - - case "$prev" in - --log-level) - COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur")) - return 0 - ;; - esac - - COMPREPLY=($(compgen -W "$(_parse_help miracle-sinkctl) $(_parse_short_help miracle-sinkctl)" -- "$cur")) -} - -complete -F _miracle-sinkctl miracle-sinkctl - -function _miracle-wifictl() { - local cur prev - - _get_comp_words_by_ref cur - prev=${COMP_WORDS[COMP_CWORD-1]} - - case "$prev" in - --log-level) - COMPREPLY=($(compgen -W 'fatal alert critical error warning notice info debug trace 1 2 3 4 5 6 7 8' -- "$cur")) - return 0 - ;; - esac - - COMPREPLY=($(compgen -W "$(_parse_help miracle-wifictl) $(_parse_short_help miracle-wifictl)" -- "$cur")) -} - -complete -F _miracle-wifictl miracle-wifictl _parse_short_help () { @@ -124,3 +89,7 @@ __parse_short_options () printf '%s\n' "${option/=*/=}" } +complete -F _miracle-wifid miracle-wifid + + +# ex: filetype=sh From 8b76e3c212eac5a7caaf3a695db862215cf5303b Mon Sep 17 00:00:00 2001 From: Xu Fasheng Date: Fri, 21 Oct 2016 00:43:03 +0800 Subject: [PATCH 065/142] Make miracle-wifid conexists with other network tools The new option --lazy-managed will let miracle-wifid don't managed the links automatically. Instead, the link will be managed only when the new DBus property Managed was set to true. So this will be possible that miracle-wifid could be coexists with other network tools like networkmanager. For example, unmanage the device in networkmanager with setting the DBus property org.freedesktop.NetworkManager.Device.Managed to false and manage it in miracle-wifid with setting org.freedesktop.miracle.wifi.Link.Managed to true, then both them could works and don't need to kill each other. Besides, there is new command named make-managed in miracle-wifictl and miracle-sinkctl. closes #135, #75 --- src/ctl/ctl-wifi.c | 69 ++++++++++++++++++++++++++++++++++++++++++ src/ctl/ctl.h | 2 ++ src/ctl/sinkctl.c | 42 +++++++++++++++++++++++--- src/ctl/wifictl.c | 70 ++++++++++++++++++++++++++++++++++++++++--- src/shared/shl_log.h | 5 ++++ src/wifi/wifid-dbus.c | 42 ++++++++++++++++++++++++++ src/wifi/wifid-link.c | 48 ++++++++++++++++++++++------- src/wifi/wifid.c | 16 ++++++---- src/wifi/wifid.h | 3 +- 9 files changed, 272 insertions(+), 25 deletions(-) diff --git a/src/ctl/ctl-wifi.c b/src/ctl/ctl-wifi.c index 6efca2c..130c031 100644 --- a/src/ctl/ctl-wifi.c +++ b/src/ctl/ctl-wifi.c @@ -414,6 +414,8 @@ static int ctl_link_parse_properties(struct ctl_link *l, bool p2p_scanning_set = false; char *tmp; int p2p_scanning, r; + bool managed_set = false; + int managed; if (!l || !m) return cli_EINVAL(); @@ -444,6 +446,13 @@ static int ctl_link_parse_properties(struct ctl_link *l, &friendly_name); if (r < 0) return cli_log_parser(r); + } else if (!strcmp(t, "Managed")) { + r = bus_message_read_basic_variant(m, "b", + &managed); + if (r < 0) + return cli_log_parser(r); + + managed_set = true; } else if (!strcmp(t, "P2PScanning")) { r = bus_message_read_basic_variant(m, "b", &p2p_scanning); @@ -494,6 +503,9 @@ static int ctl_link_parse_properties(struct ctl_link *l, } } + if (managed_set) + l->managed = managed; + if (p2p_scanning_set) l->p2p_scanning = p2p_scanning; @@ -620,6 +632,63 @@ int ctl_link_set_wfd_subelements(struct ctl_link *l, const char *val) return 0; } +int ctl_link_set_managed(struct ctl_link *l, bool val) +{ + _sd_bus_message_unref_ sd_bus_message *m = NULL; + _sd_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL; + _shl_free_ char *node = NULL; + int r; + + if (!l) + return cli_EINVAL(); + if (l->managed == val) + return 0; + + r = sd_bus_path_encode("/org/freedesktop/miracle/wifi/link", + l->label, + &node); + if (r < 0) + return cli_ERR(r); + + r = sd_bus_message_new_method_call(l->w->bus, + &m, + "org.freedesktop.miracle.wifi", + node, + "org.freedesktop.DBus.Properties", + "Set"); + if (r < 0) + return cli_log_create(r); + + r = sd_bus_message_append(m, "ss", + "org.freedesktop.miracle.wifi.Link", + "Managed"); + if (r < 0) + return cli_log_create(r); + + r = sd_bus_message_open_container(m, 'v', "b"); + if (r < 0) + return cli_log_create(r); + + r = sd_bus_message_append(m, "b", val); + if (r < 0) + return cli_log_create(r); + + r = sd_bus_message_close_container(m); + if (r < 0) + return cli_log_create(r); + + r = sd_bus_call(l->w->bus, m, 0, &err, NULL); + if (r < 0) { + cli_error("cannot change managed state on link %s to %d: %s", + l->label, val, bus_error_message(&err, r)); + return r; + } + + l->managed = val; + + return 0; +} + int ctl_link_set_p2p_scanning(struct ctl_link *l, bool val) { _sd_bus_message_unref_ sd_bus_message *m = NULL; diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 1d0bd9a..02220bc 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -71,6 +71,7 @@ struct ctl_link { unsigned int ifindex; char *ifname; char *friendly_name; + bool managed; char *wfd_subelements; bool p2p_scanning; }; @@ -78,6 +79,7 @@ struct ctl_link { #define link_from_dlist(_l) shl_dlist_entry((_l), struct ctl_link, list); int ctl_link_set_friendly_name(struct ctl_link *l, const char *name); +int ctl_link_set_managed(struct ctl_link *l, bool val); int ctl_link_set_wfd_subelements(struct ctl_link *l, const char *val); int ctl_link_set_p2p_scanning(struct ctl_link *l, bool val); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 029407c..9a6489d 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -84,19 +84,20 @@ static int cmd_list(char **args, unsigned int n) /* list links */ - cli_printf("%6s %-24s %-30s\n", - "LINK", "INTERFACE", "FRIENDLY-NAME"); + cli_printf("%6s %-24s %-30s %-10s\n", + "LINK", "INTERFACE", "FRIENDLY-NAME", "MANAGED"); shl_dlist_for_each(i, &wifi->links) { l = link_from_dlist(i); ++link_cnt; - cli_printf("%6s %-24s %-30s\n", + cli_printf("%6s %-24s %-30s %-10s\n", l->label, shl_isempty(l->ifname) ? "" : l->ifname, shl_isempty(l->friendly_name) ? - "" : l->friendly_name); + "" : l->friendly_name, + l->managed ? "yes": "no"); } cli_printf("\n"); @@ -157,6 +158,7 @@ static int cmd_show(char **args, unsigned int n) cli_printf("P2PScanning=%d\n", l->p2p_scanning); if (l->wfd_subelements && *l->wfd_subelements) cli_printf("WfdSubelements=%s\n", l->wfd_subelements); + cli_printf("Managed=%d\n", l->managed); } else if (p) { cli_printf("Peer=%s\n", p->label); if (p->p2p_mac && *p->p2p_mac) @@ -210,6 +212,11 @@ static int cmd_run(char **args, unsigned int n) return 0; } + if (!l->managed) { + cli_printf("link %s not managed\n", l->label); + return 0; + } + run_on(l); return 0; @@ -240,11 +247,37 @@ static int cmd_bind(char **args, unsigned int n) if (!l) return 0; + if (!l->managed) { + cli_printf("link %s not managed\n", l->label); + return 0; + } + run_on(l); return 0; } +/* + * cmd: set-managed + */ + +static int cmd_set_managed(char **args, unsigned int n) +{ + struct ctl_link *l = NULL; + bool managed = true; + + l = ctl_wifi_search_link(wifi, args[0]); + if (!l) { + cli_error("unknown link %s", args[0]); + return 0; + } + + if (!strcmp(args[1], "no")) { + managed = false; + } + return ctl_link_set_managed(l, managed); +} + /* * cmd: quit/exit */ @@ -341,6 +374,7 @@ static const struct cli_cmd cli_cmds[] = { { "show", "", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information" }, { "run", "", CLI_M, CLI_EQUAL, 1, cmd_run, "Run sink on given link" }, { "bind", "", CLI_M, CLI_EQUAL, 1, cmd_bind, "Like 'run' but bind the link name to run when it is hotplugged" }, + { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link" }, { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program" }, { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL }, { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help" }, diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index d3ad7f3..8823f73 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -52,19 +52,20 @@ static int cmd_list(char **args, unsigned int n) /* list links */ - cli_printf("%6s %-24s %-30s\n", - "LINK", "INTERFACE", "FRIENDLY-NAME"); + cli_printf("%6s %-24s %-30s %-10s\n", + "LINK", "INTERFACE", "FRIENDLY-NAME", "MANAGED"); shl_dlist_for_each(i, &wifi->links) { l = link_from_dlist(i); ++link_cnt; - cli_printf("%6s %-24s %-30s\n", + cli_printf("%6s %-24s %-30s %-10s\n", l->label, shl_isempty(l->ifname) ? "" : l->ifname, shl_isempty(l->friendly_name) ? - "" : l->friendly_name); + "" : l->friendly_name, + l->managed ? "yes": "no"); } cli_printf("\n"); @@ -157,6 +158,7 @@ static int cmd_show(char **args, unsigned int n) cli_printf("P2PScanning=%d\n", l->p2p_scanning); if (l->wfd_subelements && *l->wfd_subelements) cli_printf("WfdSubelements=%s\n", l->wfd_subelements); + cli_printf("Managed=%d\n", l->managed); } else if (p) { cli_printf("Peer=%s\n", p->label); if (p->p2p_mac && *p->p2p_mac) @@ -212,9 +214,53 @@ static int cmd_set_friendly_name(char **args, unsigned int n) return 0; } + if (!l->managed) { + cli_printf("link %s not managed\n", l->label); + return 0; + } + return ctl_link_set_friendly_name(l, name); } +/* + * cmd: set-managed + */ + +static int cmd_set_managed(char **args, unsigned int n) +{ + struct ctl_link *l = NULL; + const char *value; + bool managed = true; + + if (n < 1) { + cli_printf("To what?\n"); + return 0; + } + + if (n > 1) { + l = ctl_wifi_search_link(wifi, args[0]); + if (!l) { + cli_error("unknown link %s", args[0]); + return 0; + } + + value = args[1]; + } else { + value = args[0]; + } + + l = l ? : selected_link; + if (!l) { + cli_error("no link selected"); + return 0; + } + + if (!strcmp(value, "no")) { + managed = false; + } + return ctl_link_set_managed(l, managed); +} + /* * cmd: p2p-scan */ @@ -243,6 +289,11 @@ static int cmd_p2p_scan(char **args, unsigned int n) return 0; } + if (!l->managed) { + cli_printf("link %s not managed\n", l->label); + return 0; + } + return ctl_link_set_p2p_scanning(l, !stop); } @@ -290,6 +341,11 @@ static int cmd_connect(char **args, unsigned int n) pin = ""; } + if (!p->l->managed) { + cli_printf("link %s not managed\n", p->l->label); + return 0; + } + return ctl_peer_connect(p, prov, pin); } @@ -312,6 +368,11 @@ static int cmd_disconnect(char **args, unsigned int n) return 0; } + if (!p->l->managed) { + cli_printf("link %s not managed\n", p->l->label); + return 0; + } + return ctl_peer_disconnect(p); } @@ -334,6 +395,7 @@ static const struct cli_cmd cli_cmds[] = { { "select", "[link]", CLI_Y, CLI_LESS, 1, cmd_select, "Select default link" }, { "show", "[link|peer]", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information" }, { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object" }, + { "set-managed", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_managed, "Manage or unmnage a link" }, { "p2p-scan", "[link] [stop]", CLI_Y, CLI_LESS, 2, cmd_p2p_scan, "Control neighborhood P2P scanning" }, { "connect", " [provision] [pin]", CLI_M, CLI_LESS, 3, cmd_connect, "Connect to peer" }, { "disconnect", "", CLI_M, CLI_EQUAL, 1, cmd_disconnect, "Disconnect from peer" }, diff --git a/src/shared/shl_log.h b/src/shared/shl_log.h index bd08601..43e972b 100644 --- a/src/shared/shl_log.h +++ b/src/shared/shl_log.h @@ -231,4 +231,9 @@ extern const char *LOG_SUBSYSTEM; #define log_vERR(_r) \ ((void)log_ERR(_r)) +#define log_EUNMANAGED() \ + (log_error("interface unmanaged"), -EFAULT) +#define log_vEUNMANAGED() \ + ((void)log_EUNMANAGED()) + #endif /* SHL_LOG_H */ diff --git a/src/wifi/wifid-dbus.c b/src/wifi/wifid-dbus.c index e7f73ec..c45dc89 100644 --- a/src/wifi/wifid-dbus.c +++ b/src/wifi/wifid-dbus.c @@ -571,6 +571,42 @@ static int link_dbus_set_friendly_name(sd_bus *bus, return link_set_friendly_name(l, name); } +static int link_dbus_get_managed(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *data, + sd_bus_error *err) +{ + struct link *l = data; + int r; + + r = sd_bus_message_append(reply, "b", link_get_managed(l)); + if (r < 0) + return r; + + return 1; +} + +static int link_dbus_set_managed(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *value, + void *data, + sd_bus_error *err) +{ + struct link *l = data; + int val, r; + + r = sd_bus_message_read(value, "b", &val); + if (r < 0) + return r; + + return link_set_managed(l, val); +} + static int link_dbus_get_p2p_scanning(sd_bus *bus, const char *path, const char *interface, @@ -662,6 +698,12 @@ static const sd_bus_vtable link_dbus_vtable[] = { link_dbus_set_friendly_name, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + SD_BUS_WRITABLE_PROPERTY("Managed", + "b", + link_dbus_get_managed, + link_dbus_set_managed, + 0, + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_WRITABLE_PROPERTY("P2PScanning", "b", link_dbus_get_p2p_scanning, diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index bc69557..81cef73 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -100,6 +100,8 @@ int link_new(struct manager *m, if (out) *out = l; + l->public = true; + link_dbus_added(l); return 0; error: @@ -116,6 +118,9 @@ void link_free(struct link *l) link_set_managed(l, false); + link_dbus_removed(l); + l->public = false; + if (shl_htable_remove_uint(&l->m->links, l->ifindex, NULL)) { log_info("remove link: %s", l->ifname); --l->m->link_cnt; @@ -159,14 +164,19 @@ int link_set_config_methods(struct link *l, char *config_methods) return 0; } -void link_set_managed(struct link *l, bool set) +bool link_get_managed(struct link *l) +{ + return l->managed; +} + +int link_set_managed(struct link *l, bool set) { int r; if (!l) - return log_vEINVAL(); + return log_EINVAL(); if (l->managed == set) - return; + return 0; if (set) { log_info("manage link %s", l->ifname); @@ -174,7 +184,7 @@ void link_set_managed(struct link *l, bool set) r = supplicant_start(l->s); if (r < 0) { log_error("cannot start supplicant on %s", l->ifname); - return; + return -EFAULT; } } else { log_info("link %s no longer managed", l->ifname); @@ -182,6 +192,7 @@ void link_set_managed(struct link *l, bool set) } l->managed = set; + return 0; } int link_renamed(struct link *l, const char *ifname) @@ -216,6 +227,9 @@ int link_set_friendly_name(struct link *l, const char *name) if (!l || !name || !*name) return log_EINVAL(); + if (!l->managed) + return log_EUNMANAGED(); + t = strdup(name); if (!t) return log_ENOMEM(); @@ -251,6 +265,9 @@ int link_set_wfd_subelements(struct link *l, const char *val) if (!l || !val) return log_EINVAL(); + if (!l->managed) + return log_EUNMANAGED(); + t = strdup(val); if (!t) return log_ENOMEM(); @@ -283,6 +300,9 @@ int link_set_p2p_scanning(struct link *l, bool set) if (!l) return log_EINVAL(); + if (!l->managed) + return log_EUNMANAGED(); + if (set) { return supplicant_p2p_start_scan(l->s); } else { @@ -293,7 +313,16 @@ int link_set_p2p_scanning(struct link *l, bool set) bool link_get_p2p_scanning(struct link *l) { - return l && supplicant_p2p_scanning(l->s); + if (!l) { + log_vEINVAL(); + return false; + } + + if (!l->managed) { + return false; + } + + return supplicant_p2p_scanning(l->s); } void link_supplicant_started(struct link *l) @@ -301,9 +330,8 @@ void link_supplicant_started(struct link *l) if (!l || l->public) return; - log_debug("link %s started", l->ifname); - l->public = true; - link_dbus_added(l); + link_set_friendly_name(l, l->m->friendly_name); + log_info("link %s managed", l->ifname); } void link_supplicant_stopped(struct link *l) @@ -311,9 +339,7 @@ void link_supplicant_stopped(struct link *l) if (!l || !l->public) return; - log_debug("link %s stopped", l->ifname); - link_dbus_removed(l); - l->public = false; + log_info("link %s unmanaged", l->ifname); } void link_supplicant_p2p_scan_changed(struct link *l, bool new_value) diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 4c0f02c..72209f4 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -44,6 +44,7 @@ const char *interface_name = NULL; const char *config_methods = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; bool use_dev = false; +bool lazy_managed = false; /* * Manager Handling @@ -109,9 +110,9 @@ static void manager_add_udev_link(struct manager *m, link_use_dev(l); #ifdef RELY_UDEV - if (udev_device_has_tag(d, "miracle")) { + if (udev_device_has_tag(d, "miracle") && !lazy_managed) { #else - if (!interface_name || !strcmp(interface_name, ifname)) { + if ((!interface_name || !strcmp(interface_name, ifname)) && !lazy_managed) { #endif link_set_managed(l, true); } else { @@ -152,12 +153,12 @@ static int manager_udev_fn(sd_event_source *source, } #ifdef RELY_UDEV - if (udev_device_has_tag(d, "miracle")) + if (udev_device_has_tag(d, "miracle") && !lazy_managed) link_set_managed(l, true); else link_set_managed(l, false); #else - if (!interface_name || !strcmp(interface_name, ifname)) { + if ((!interface_name || !strcmp(interface_name, ifname)) && !lazy_managed) { link_set_managed(l, true); } else { log_debug("ignored device: %s", ifname); @@ -230,7 +231,7 @@ static int manager_new(struct manager **out) unsigned int i; sigset_t mask; int r; - char *cm; + char *cm; m = calloc(1, sizeof(*m)); if (!m) @@ -477,6 +478,7 @@ static int help(void) "\n" " --wpa-loglevel Date: Sat, 22 Sep 2018 08:44:06 +0200 Subject: [PATCH 066/142] Avoid log errors Do not output error settings null values or configuring unmanaged links --- src/wifi/wifid-link.c | 3 ++- src/wifi/wifid.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index 81cef73..01bf744 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -330,7 +330,8 @@ void link_supplicant_started(struct link *l) if (!l || l->public) return; - link_set_friendly_name(l, l->m->friendly_name); + if (l->m->friendly_name && l->managed) + link_set_friendly_name(l, l->m->friendly_name); log_info("link %s managed", l->ifname); } diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 72209f4..d5b2336 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -103,8 +103,10 @@ static void manager_add_udev_link(struct manager *m, if (r < 0) return; - link_set_friendly_name(l, m->friendly_name); - link_set_config_methods(l, m->config_methods); + if (m->friendly_name && l->managed) + link_set_friendly_name(l, m->friendly_name); + if (m->config_methods) + link_set_config_methods(l, m->config_methods); if(use_dev) link_use_dev(l); From 8151bb8cbd651597be5d35b35714ffe1eb2783b6 Mon Sep 17 00:00:00 2001 From: albfan Date: Sun, 23 Oct 2016 12:15:55 +0200 Subject: [PATCH 067/142] whitespace --- src/ctl/ctl-sink.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 4580ecb..fe652cc 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -251,29 +251,29 @@ static void sink_handle_set_parameter(struct ctl_sink *s, r = rtsp_message_read(m, "{<&>}", "wfd_uibc_capability", &uibc_config); if (r >= 0) { if (!s->uibc_config || strcmp(s->uibc_config, uibc_config)) { - nu = strdup(uibc_config); - if (!nu) - return cli_vENOMEM(); + nu = strdup(uibc_config); + if (!nu) + return cli_vENOMEM(); - free(s->uibc_config); - s->uibc_config = nu; + free(s->uibc_config); + s->uibc_config = nu; - if (!strcasecmp(uibc_config, "none")) { - uibc_enabled = false; - } else { - char* token = strtok(uibc_config, ";"); + if (!strcasecmp(uibc_config, "none")) { + uibc_enabled = false; + } else { + char* token = strtok(uibc_config, ";"); - while (token) { - if (sscanf(token, "port=%d", &uibc_port)) { - log_debug("UIBC port: %d\n", uibc_port); - if (uibc_option) { - uibc_enabled = true; - } - break; - } - token = strtok(0, ";"); - } - } + while (token) { + if (sscanf(token, "port=%d", &uibc_port)) { + log_debug("UIBC port: %d\n", uibc_port); + if (uibc_option) { + uibc_enabled = true; + } + break; + } + token = strtok(0, ";"); + } + } } } From c3c868e523f450ad4f0d77f5484a3b61f08120b7 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 6 Oct 2018 15:25:39 +0200 Subject: [PATCH 068/142] refactor to fix clang AST parsing --- src/wifi/wifid.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index d5b2336..def3043 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -108,14 +108,15 @@ static void manager_add_udev_link(struct manager *m, if (m->config_methods) link_set_config_methods(l, m->config_methods); - if(use_dev) + if(use_dev) link_use_dev(l); #ifdef RELY_UDEV - if (udev_device_has_tag(d, "miracle") && !lazy_managed) { + bool managed = udev_device_has_tag(d, "miracle") && !lazy_managed; #else - if ((!interface_name || !strcmp(interface_name, ifname)) && !lazy_managed) { + bool managed = (!interface_name || !strcmp(interface_name, ifname)) && !lazy_managed; #endif + if (managed) { link_set_managed(l, true); } else { log_debug("ignored device: %s", ifname); From 46089b18f0b223f700ee8cedbf2d3b51792da55c Mon Sep 17 00:00:00 2001 From: Graham White Date: Tue, 25 Dec 2018 08:32:31 +0100 Subject: [PATCH 069/142] Add spec file for building rpm files --- res/miraclecast.spec | 60 ++++++++++++++++++++++++++++++++++ res/miraclecast.spec-README.md | 24 ++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 res/miraclecast.spec create mode 100644 res/miraclecast.spec-README.md diff --git a/res/miraclecast.spec b/res/miraclecast.spec new file mode 100644 index 0000000..e199155 --- /dev/null +++ b/res/miraclecast.spec @@ -0,0 +1,60 @@ +%global commit c3c868e523f450ad4f0d77f5484a3b61f08120b7 +%global shortcommit %(c=%{commit}; echo ${c:0:7}) + +Name: miraclecast +Version: 1.0 +Release: 1.git%{shortcommit}%{?dist} +Summary: Connect external monitors to your system via Wifi-Display +License: LGPL +URL: https://github.com/albfan/miraclecast +Source0: https://github.com/albfan/miraclecast/archive/%{commit}/%{name}-%{shortcommit}.tar.gz +BuildRequires: autoconf, automake, libtool +BuildRequires: readline-devel, glib2-devel, systemd-devel + +%description +The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. + +The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. + +On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display. + + +%prep +%autosetup -n %{name}-%{shortcommit} + + +%build +mkdir build +cd build +../autogen.sh g --prefix=%{_prefix} +%make_build + + +%install +rm -rf $RPM_BUILD_ROOT +cd build +%make_install + + +%files +%license COPYING LICENSE_gdhcp LICENSE_htable LICENSE_lgpl +%doc README.md +%{_sysconfdir}/dbus-1/system.d/org.freedesktop.miracle.conf +%{_bindir}/miracle-wifictl +%{_bindir}/miracle-omxplayer +%{_bindir}/miracle-gst +%{_bindir}/miracle-sinkctl +%{_bindir}/miracled +%{_bindir}/miracle-dhcp +%{_bindir}/miracle-uibcctl +%{_bindir}/miracle-wifid +%{_bindir}/gstplayer +%{_bindir}/uibc-viewer +%{_datadir}/bash-completion/completions/miracle-wifictl +%{_datadir}/bash-completion/completions/miracle-sinkctl +%{_datadir}/bash-completion/completions/miracle-wifid + + +%changelog +* Wed Nov 21 2018 Graham White +- first build diff --git a/res/miraclecast.spec-README.md b/res/miraclecast.spec-README.md new file mode 100644 index 0000000..4fc60b6 --- /dev/null +++ b/res/miraclecast.spec-README.md @@ -0,0 +1,24 @@ +This file can be used with the rpmbuild or mock commands to create a binary RPM. Tested and working on Fedora 28 x86\_64. + +Example usage (for Fedora 28 systems): +1. Create a tar.gz file of the source code and add the short name of the commit to the tar file, for the most recent commit at the time of writing this would be: + * `git clone https://github.com/albfan/miraclecast.git miraclecast-c3c868e` + * `tar -zcf miraclecast-c3c868e.tar.gz miraclecast-c3c868e` + +2. Create a Source RPM + * `rpmbuild -bs miraclecast.spec --define "_sourcedir $PWD"` + +Then build the RPM with one of the following: + +* Using mock (assuming you're in the dir where the .src.rpm file is): + * `mock --arch=x86_64 -r fedora-28-x86_64 --resultdir=results miraclecast-1.0-1.gitc3c868e.fc28.src.rpm` + +OR + +* Using rpmbuild (assuming you're in the dir where the .src.rpm file is): + * `rpmbuild -ra miraclecast-1.0-1.gitc3c868e.fc28.src.rpm` + +OR + +* Using rpmbuild (assuming you're in the dir where the .spec and .tar.gz files are): + * `rpmbuild -bs miraclecast.spec --define "_sourcedir $PWD"`` From 3a459e5316b0791ce931886c191080c2ef33a8c3 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 25 Dec 2018 09:52:06 +0100 Subject: [PATCH 070/142] Add docker for CI --- Dockerfile | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1618f44 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:buster-slim + +RUN dpkg --add-architecture i386 + +RUN apt-get update && apt-get install -y \ + build-essential \ + systemd \ + libglib2.0-dev \ + libreadline-dev \ + libudev-dev \ + libsystemd-dev \ + libusb-dev \ + automake \ + autoconf \ + libtool \ + cmake \ + meson + +COPY . ./ + +RUN rm -rf build-autotools ; \ + mkdir build-autotools; \ + cd build-autotools; \ + ../autogen.sh; \ + ../configure; \ + make; \ + make check + +RUN rm -rf build-cmake; \ + mkdir build-cmake; \ + cd build-cmake; \ + cmake ..; \ + make + +RUN rm -rf build-meson; \ + meson build-meson; \ + ninja -C build-meson From 59df9a4a3fef40271a5de3b3ff7362dd1bcdcb7c Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 25 Dec 2018 11:42:35 +0100 Subject: [PATCH 071/142] Add CI badge status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b04545..7be9547 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MiracleCast - Wifi-Display/Miracast Implementation [![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://semaphoreci.com/api/v1/projects/5ece4a7a-365b-4f7c-bfcc-6dcdece7002f/671892/badge.svg)](https://semaphoreci.com/albfan/miraclecast) +[![Build Status](https://semaphoreci.com/api/v1/albfan/miraclecast-2/branches/master/badge.svg)](https://semaphoreci.com/albfan/miraclecast-2) [![Coverage Status](https://coveralls.io/repos/github/albfan/miraclecast/badge.svg?branch=master)](https://coveralls.io/github/albfan/miraclecast?branch=master) The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. From 960a785e10523cc525885380dd03aa2c5ba11bc7 Mon Sep 17 00:00:00 2001 From: Martin Kennedy Date: Wed, 3 Apr 2019 17:01:42 -0400 Subject: [PATCH 072/142] Use a guard to prevent dependency on pkg-config when it is not available I picked the methodology off of https://github.com/curl/curl/issues/972. The benefit here is that if someone does not have pkg-config (we know this is unlikely anyways), their configuration script just won't end up with the checks. This provides a patch similar to the one requested in issue #120. --- configure.ac | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 5c1e1ef..aeff177 100644 --- a/configure.ac +++ b/configure.ac @@ -45,8 +45,10 @@ AC_ARG_ENABLE([log-debug], # Mandatory dependencies # -PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219]) -PKG_CHECK_MODULES([GLIB], [glib-2.0]) +m4_ifdef([PKG_CHECK_MODULES], [ + PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219]) + PKG_CHECK_MODULES([GLIB], [glib-2.0]) +]) AC_CHECK_HEADERS(readline/readline.h,, AC_MSG_ERROR(GNU readline not found)) @@ -55,8 +57,10 @@ AC_CHECK_HEADERS(readline/readline.h,, AC_MSG_ERROR(GNU readline not found)) # all tests. # -PKG_CHECK_MODULES([CHECK], [check], - [have_check=yes], [have_check=no]) +m4_ifdef([PKG_CHECK_MODULES], [ + PKG_CHECK_MODULES([CHECK], [check], + [have_check=yes], [have_check=no]) +]) AM_CONDITIONAL([BUILD_HAVE_CHECK], [test "x$have_check" = "xyes"]) if test "x$have_check" = "xyes" From 58dd6c411e182265a69dd81ff6fb994a5ada02ed Mon Sep 17 00:00:00 2001 From: Warren Crossing Date: Thu, 22 Aug 2019 06:50:32 +1000 Subject: [PATCH 073/142] Add --syslog flag to see wpa logs in syslog --- src/wifi/wifid-supplicant.c | 5 +++++ src/wifi/wifid.c | 10 ++++++++-- src/wifi/wifid.h | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index a2a3a43..081e79e 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2415,6 +2415,11 @@ static void supplicant_run(struct supplicant *s, const char *binary) argv[i++] = s->l->ifname; argv[i++] = "-g"; argv[i++] = s->global_ctrl; + + if (arg_wpa_syslog) { + argv[i++] = "-s"; + } + argv[i] = NULL; /* execute wpa_supplicant; if it fails, the caller issues exit(1) */ diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index def3043..9417fe4 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -43,6 +43,7 @@ const char *interface_name = NULL; const char *config_methods = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; +bool arg_wpa_syslog = false; bool use_dev = false; bool lazy_managed = false; @@ -479,7 +480,8 @@ static int help(void) " -i --interface Choose the interface to use\n" " --config-methods Define config methods for pairing, default 'pbc'\n" "\n" - " --wpa-loglevel wpa_supplicant log-level\n" + " --wpa-syslog wpa_supplicant use syslog\n" " --use-dev enable workaround for 'no ifname' issue\n" " --lazy-managed manage interface only when user decide to do\n" , program_invocation_short_name); @@ -498,6 +500,7 @@ static int parse_argv(int argc, char *argv[]) ARG_LOG_LEVEL, ARG_LOG_TIME, ARG_WPA_LOGLEVEL, + ARG_WPA_SYSLOG, ARG_USE_DEV, ARG_CONFIG_METHODS, ARG_LAZY_MANAGED, @@ -509,6 +512,7 @@ static int parse_argv(int argc, char *argv[]) { "log-time", no_argument, NULL, ARG_LOG_TIME }, { "wpa-loglevel", required_argument, NULL, ARG_WPA_LOGLEVEL }, + { "wpa-syslog", no_argument, NULL, ARG_WPA_SYSLOG }, { "interface", required_argument, NULL, 'i' }, { "use-dev", no_argument, NULL, ARG_USE_DEV }, { "config-methods", required_argument, NULL, ARG_CONFIG_METHODS }, @@ -541,10 +545,12 @@ static int parse_argv(int argc, char *argv[]) case ARG_LAZY_MANAGED: lazy_managed = true; break; - case ARG_WPA_LOGLEVEL: arg_wpa_loglevel = log_parse_arg(optarg); break; + case ARG_WPA_SYSLOG: + arg_wpa_syslog = true; + break; case '?': return -EINVAL; } diff --git a/src/wifi/wifid.h b/src/wifi/wifid.h index 817b685..d07c29f 100644 --- a/src/wifi/wifid.h +++ b/src/wifi/wifid.h @@ -213,5 +213,6 @@ void manager_dbus_disconnect(struct manager *m); /* cli arguments */ extern unsigned int arg_wpa_loglevel; +extern bool arg_wpa_syslog; #endif /* WIFID_H */ From 41113335211463e122f7e5f782274c84752703c9 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 27 Aug 2019 11:01:22 +0200 Subject: [PATCH 074/142] Set readline as required package autotools already set it, but cmake and meson no. --- meson.build | 2 +- src/ctl/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 1e88906..c74b9ba 100644 --- a/meson.build +++ b/meson.build @@ -19,7 +19,7 @@ configure_file(output: 'config.h', ) c_compiler = meson.get_compiler('c') -readline = c_compiler.find_library('readline', required: false) +readline = c_compiler.find_library('readline', required: true) if readline.found() add_project_arguments('-DHAVE_READLINE', language: 'c') endif diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt index 7d41b54..837109f 100644 --- a/src/ctl/CMakeLists.txt +++ b/src/ctl/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) link_directories( ${GLIB2_LIBRARY_DIRS}) include_directories( ${GLIB2_INCLUDE_DIRS}) -find_package(Readline) +find_package(Readline REQUIRED) pkg_check_modules (GLIB2 REQUIRED glib-2.0) ########### next target ############### From 2ef4c1f40feaca06173b34d2301315f4772f6e79 Mon Sep 17 00:00:00 2001 From: Andrey Alekseenko Date: Fri, 21 Feb 2020 21:21:38 -0500 Subject: [PATCH 075/142] Random static analysis fixes --- src/dhcp/client.c | 2 +- src/wifi/wifid-supplicant.c | 1 - src/wifi/wifid.c | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dhcp/client.c b/src/dhcp/client.c index 3d04cd1..7f818ba 100644 --- a/src/dhcp/client.c +++ b/src/dhcp/client.c @@ -2785,7 +2785,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address) addr = ntohl(inet_addr(last_address)); if (addr == 0xFFFFFFFF) { addr = 0; - } else { + } else if (dhcp_client->last_address != last_address) { // Avoiding use-after-free g_free(dhcp_client->last_address); dhcp_client->last_address = g_strdup(last_address); } diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 081e79e..644f077 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -1451,7 +1451,6 @@ static void supplicant_event(struct supplicant *s, struct wpas_message *m) !strcmp(name, "WPS-AP-AVAILABLE-PIN") || !strcmp(name, "CTRL-EVENT-EAP-STATUS") || !strcmp(name, "CTRL-EVENT-EAP-METHOD") || - !strcmp(name, "CTRL-EVENT-EAP-STATUS") || !strcmp(name, "WPS-CRED-RECEIVED") || !strcmp(name, "WPS-AP-AVAILABLE") || !strcmp(name, "WPS-REG-SUCCESS") || diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 9417fe4..4b46f64 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -542,6 +542,7 @@ static int parse_argv(int argc, char *argv[]) break; case ARG_CONFIG_METHODS: config_methods = optarg; + break; case ARG_LAZY_MANAGED: lazy_managed = true; break; From 9edb225905d1a0e7e0195750a24263e2d06a39b5 Mon Sep 17 00:00:00 2001 From: Andrey Alekseenko Date: Fri, 21 Feb 2020 21:59:48 -0500 Subject: [PATCH 076/142] Add option to use cppcheck in CMake --- CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a073be0..a94c904 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ SET(BUILD_BINDIR "${CMAKE_INSTALL_PREFIX}/bin") OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) OPTION(BUILD_TESTS "Enable TEST" ON ) +OPTION(BUILD_ENABLE_CPPCHECK "Enable CPPCheck static analysis" OFF ) if(BUILD_ENABLE_DEBUG) add_definitions(-DBUILD_ENABLE_DEBUG) @@ -30,6 +31,20 @@ pkg_check_modules (SYSTEMD REQUIRED libsystemd) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) +if(BUILD_ENABLE_CPPCHECK) + find_program(CMAKE_C_CPPCHECK NAMES cppcheck) + if (CMAKE_C_CPPCHECK) + list( + APPEND CMAKE_C_CPPCHECK + "--enable=warning" + "--inline-suppr" + "--std=c11" + "-D__SIZEOF_POINTER__=8" + ) + endif() +endif() + + add_subdirectory(src) add_subdirectory(res) add_subdirectory(test) From 57d05a18082d3d06a94dff1d83898237b7d28540 Mon Sep 17 00:00:00 2001 From: Andrey Alekseenko Date: Fri, 21 Feb 2020 22:06:16 -0500 Subject: [PATCH 077/142] Remove double free The function parser_submit_data is only called from parser_feed_char_data_body, which frees the buffer pointer anyway. --- src/shared/rtsp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/rtsp.c b/src/shared/rtsp.c index 9ecf5a5..1df569d 100644 --- a/src/shared/rtsp.c +++ b/src/shared/rtsp.c @@ -2169,7 +2169,6 @@ static int parser_submit_data(struct rtsp *bus, uint8_t *p) p, dec->data_size); if (r < 0) { - free(p); return r; } From be548047687d3a02ff23f8cac05bf57803e343b1 Mon Sep 17 00:00:00 2001 From: Andrey Alekseenko Date: Fri, 21 Feb 2020 22:12:53 -0500 Subject: [PATCH 078/142] Remove access to freed memory If rtsp_unlink_waiting(m) is called and actually destroys m, it's not safe to pass it to rtsp_unlink_outgoing later. We make rtsp_unlink_waiting and rtsp_unlink_outgoing return true if they destroy the message, and in this case we make sure not to try freeing it again. --- src/shared/rtsp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/shared/rtsp.c b/src/shared/rtsp.c index 1df569d..60895cd 100644 --- a/src/shared/rtsp.c +++ b/src/shared/rtsp.c @@ -2716,7 +2716,7 @@ error: return r; } -static void rtsp_unlink_waiting(struct rtsp_message *m) +static bool rtsp_unlink_waiting(struct rtsp_message *m) { if (m->is_waiting) { sd_event_source_unref(m->timer_source); @@ -2725,7 +2725,9 @@ static void rtsp_unlink_waiting(struct rtsp_message *m) m->is_waiting = false; --m->bus->waiting_cnt; rtsp_message_unref(m); + return true; } + return false; } static void rtsp_link_outgoing(struct rtsp_message *m) @@ -2736,7 +2738,7 @@ static void rtsp_link_outgoing(struct rtsp_message *m) rtsp_message_ref(m); } -static void rtsp_unlink_outgoing(struct rtsp_message *m) +static bool rtsp_unlink_outgoing(struct rtsp_message *m) { if (m->is_outgoing) { shl_dlist_unlink(&m->list); @@ -2744,7 +2746,9 @@ static void rtsp_unlink_outgoing(struct rtsp_message *m) m->is_sending = false; --m->bus->outgoing_cnt; rtsp_message_unref(m); + return true; } + return false; } static int rtsp_incoming_message(struct rtsp_message *m) @@ -2822,10 +2826,11 @@ static int rtsp_write_message(struct rtsp_message *m) if (m->sent >= m->raw_size) { /* no need to wait for answer if no-body listens */ if (!m->cb_fn) - rtsp_unlink_waiting(m); - + if (rtsp_unlink_waiting(m)) + m = NULL; /* might destroy the message */ - rtsp_unlink_outgoing(m); + if (m) + rtsp_unlink_outgoing(m); } return 0; @@ -3245,10 +3250,12 @@ static void rtsp_drop_message(struct rtsp_message *m) /* never interrupt messages while being partly sent */ if (!m->is_sending) - rtsp_unlink_outgoing(m); + if (rtsp_unlink_outgoing(m)) + m = NULL; /* remove from waiting list so neither timeouts nor completions fire */ - rtsp_unlink_waiting(m); + if (m) + rtsp_unlink_waiting(m); } void rtsp_call_async_cancel(struct rtsp *bus, uint64_t cookie) From 4f37045eea9d5da1b3840144381160a905275244 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 13 Nov 2020 10:29:13 +0100 Subject: [PATCH 079/142] Use travis as CI --- .travis.yml | 16 +++++++++++++++ Dockerfile | 37 ----------------------------------- autotools.Dockerfile | 11 +++++++++++ cmake.Dockerfile | 9 +++++++++ meson.Dockerfile | 7 +++++++ res/miraclecast-ci.Dockerfile | 18 +++++++++++++++++ 6 files changed, 61 insertions(+), 37 deletions(-) create mode 100644 .travis.yml delete mode 100644 Dockerfile create mode 100644 autotools.Dockerfile create mode 100644 cmake.Dockerfile create mode 100644 meson.Dockerfile create mode 100644 res/miraclecast-ci.Dockerfile diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c2a4f7b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: c + +services: + - docker + +jobs: + include: + - stage: autotools + script: + docker build -t autotools -f autotools.Dockerfile . + - stage: cmake + script: + docker build -t cmake -f cmake.Dockerfile . + - stage: meson + script: + docker build -t meson -f meson.Dockerfile . diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 1618f44..0000000 --- a/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:buster-slim - -RUN dpkg --add-architecture i386 - -RUN apt-get update && apt-get install -y \ - build-essential \ - systemd \ - libglib2.0-dev \ - libreadline-dev \ - libudev-dev \ - libsystemd-dev \ - libusb-dev \ - automake \ - autoconf \ - libtool \ - cmake \ - meson - -COPY . ./ - -RUN rm -rf build-autotools ; \ - mkdir build-autotools; \ - cd build-autotools; \ - ../autogen.sh; \ - ../configure; \ - make; \ - make check - -RUN rm -rf build-cmake; \ - mkdir build-cmake; \ - cd build-cmake; \ - cmake ..; \ - make - -RUN rm -rf build-meson; \ - meson build-meson; \ - ninja -C build-meson diff --git a/autotools.Dockerfile b/autotools.Dockerfile new file mode 100644 index 0000000..e10e97a --- /dev/null +++ b/autotools.Dockerfile @@ -0,0 +1,11 @@ +FROM docker.io/albfan/miraclecast-ci + +COPY . ./ + +RUN rm -rf build-autotools ; \ + mkdir build-autotools; \ + cd build-autotools; \ + ../autogen.sh; \ + ../configure; \ + make; \ + make check diff --git a/cmake.Dockerfile b/cmake.Dockerfile new file mode 100644 index 0000000..4aebe91 --- /dev/null +++ b/cmake.Dockerfile @@ -0,0 +1,9 @@ +FROM docker.io/albfan/miraclecast-ci + +COPY . ./ + +RUN rm -rf build-cmake; \ + mkdir build-cmake; \ + cd build-cmake; \ + cmake ..; \ + make diff --git a/meson.Dockerfile b/meson.Dockerfile new file mode 100644 index 0000000..c57581b --- /dev/null +++ b/meson.Dockerfile @@ -0,0 +1,7 @@ +FROM docker.io/albfan/miraclecast-ci + +COPY . ./ + +RUN rm -rf build-meson; \ + meson build-meson; \ + ninja -C build-meson diff --git a/res/miraclecast-ci.Dockerfile b/res/miraclecast-ci.Dockerfile new file mode 100644 index 0000000..cb55da0 --- /dev/null +++ b/res/miraclecast-ci.Dockerfile @@ -0,0 +1,18 @@ +FROM debian:buster-slim + +RUN dpkg --add-architecture i386 + +RUN apt-get update && apt-get install -y \ + build-essential \ + systemd \ + libglib2.0-dev \ + libreadline-dev \ + libudev-dev \ + libsystemd-dev \ + libusb-dev \ + automake \ + autoconf \ + libtool \ + cmake \ + meson + From c864ff62461507d98cba93c335f21937e5ecab61 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 13 Nov 2020 10:53:38 +0100 Subject: [PATCH 080/142] Use new semaphore 2.0 CI --- .semaphore/semaphore.yml | 35 +++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 .semaphore/semaphore.yml diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml new file mode 100644 index 0000000..58a1fd0 --- /dev/null +++ b/.semaphore/semaphore.yml @@ -0,0 +1,35 @@ +version: v1.0 +name: Docker + +agent: + machine: + type: e1-standard-2 + os_image: ubuntu1804 + +global_job_config: + secrets: + - name: dockerhub + +blocks: + - name: Checkout + task: + jobs: + - name: Checkout + commands: + - checkout + - name: Build + task: + jobs: + - name: Autotools + commands: + - checkout + - docker build -t autotools -f autotools.Dockerfile . + - name: Cmake + commands: + - checkout + - docker build -t cmake -f cmake.Dockerfile . + - name: meson + commands: + - checkout + - docker build -t meson -f meson.Dockerfile . + diff --git a/README.md b/README.md index 7be9547..11e814c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # MiracleCast - Wifi-Display/Miracast Implementation [![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://semaphoreci.com/api/v1/albfan/miraclecast-2/branches/master/badge.svg)](https://semaphoreci.com/albfan/miraclecast-2) +[![Build Status](https://albfan.semaphoreci.com/badges/miraclecast/branches/master.svg?style=shields)](https://albfan.semaphoreci.com/projects/miraclecast) [![Coverage Status](https://coveralls.io/repos/github/albfan/miraclecast/badge.svg?branch=master)](https://coveralls.io/github/albfan/miraclecast?branch=master) The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. From 058c9cc3098e08f4beb58cc0a0665ccdffcd84fc Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 13 Nov 2020 16:50:57 +0100 Subject: [PATCH 081/142] Update travis build status --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 11e814c..056bf13 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # MiracleCast - Wifi-Display/Miracast Implementation [![Join the chat at https://gitter.im/albfan/miraclecast](https://badges.gitter.im/albfan/miraclecast.svg)](https://gitter.im/albfan/miraclecast?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://albfan.semaphoreci.com/badges/miraclecast/branches/master.svg?style=shields)](https://albfan.semaphoreci.com/projects/miraclecast) +[![Semaphore CI Build Status](https://albfan.semaphoreci.com/badges/miraclecast/branches/master.svg?style=shields)](https://albfan.semaphoreci.com/projects/miraclecast) +[![Travis CI Build Status](https://travis-ci.org/albfan/miraclecast.svg?branch=master)](https://travis-ci.org/albfan/miraclecast) [![Coverage Status](https://coveralls.io/repos/github/albfan/miraclecast/badge.svg?branch=master)](https://coveralls.io/github/albfan/miraclecast?branch=master) The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. From 92a8b0b2c6764deaf753b5f5f7861998e89975e5 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 1 Jan 2021 19:43:03 +0100 Subject: [PATCH 082/142] Detect miracle-wifid already running --- src/wifi/wifid-dbus.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wifi/wifid-dbus.c b/src/wifi/wifid-dbus.c index c45dc89..8aed6f4 100644 --- a/src/wifi/wifid-dbus.c +++ b/src/wifi/wifid-dbus.c @@ -937,8 +937,12 @@ int manager_dbus_connect(struct manager *m) r = sd_bus_request_name(m->bus, "org.freedesktop.miracle.wifi", 0); if (r < 0) { - log_error("cannot claim org.freedesktop.miracle.wifi bus-name: %d", + if (r == -EEXIST) { + log_info("cannot claim org.freedesktop.miracle.wifi bus-name: it is already being adquired"); + } else { + log_error("cannot claim org.freedesktop.miracle.wifi bus-name: %d", r); + } goto error_silent; } From 3b3531de5c6a7917024ba56cf919b1742b4db74b Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 3 Jan 2021 14:04:38 +0100 Subject: [PATCH 083/142] Allow to set friendly name even if unmanaged --- src/ctl/wifictl.c | 5 ----- src/wifi/wifid-link.c | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 8823f73..faf7880 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -214,11 +214,6 @@ static int cmd_set_friendly_name(char **args, unsigned int n) return 0; } - if (!l->managed) { - cli_printf("link %s not managed\n", l->label); - return 0; - } - return ctl_link_set_friendly_name(l, name); } diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index 01bf744..9b37571 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -227,9 +227,6 @@ int link_set_friendly_name(struct link *l, const char *name) if (!l || !name || !*name) return log_EINVAL(); - if (!l->managed) - return log_EUNMANAGED(); - t = strdup(name); if (!t) return log_ENOMEM(); From 8d6530ebc93a9e2657089d7cd261cd23a17c72d3 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 3 Jan 2021 14:07:44 +0100 Subject: [PATCH 084/142] protect from NULL binary path --- src/wifi/wifid-supplicant.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 644f077..fef362d 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -2482,7 +2482,11 @@ static int supplicant_spawn(struct supplicant *s) log_debug("spawn supplicant of %s", s->l->ifname); if (supplicant_find(&binary) < 0) { - log_error("execution of wpas (%s) not possible: %m", binary); + if (binary != NULL) { + log_error("execution of wpas (%s) not possible: %m", binary); + } else { + log_error("execution of wpas not possible: %m"); + } return -EINVAL; } From 62c5b8daa87bbb73bcb62cb2c62bdc22d020990a Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 3 Jan 2021 19:45:05 +0100 Subject: [PATCH 085/142] Do not fail if peers are found before links After discover peers, a miracle-sinkctl restart can lead to peers without links. Just ignore that --- src/ctl/ctl-wifi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/ctl-wifi.c b/src/ctl/ctl-wifi.c index 130c031..2e06e72 100644 --- a/src/ctl/ctl-wifi.c +++ b/src/ctl/ctl-wifi.c @@ -823,7 +823,7 @@ static int ctl_wifi_parse_peer(struct ctl_wifi *w, l = ctl_wifi_find_link_by_peer(w, label); if (!l) - return cli_EINVAL(); + return 0; r = ctl_peer_new(&p, l, label); if (r < 0) From a13c1b7c33d5e3b8b9d9c52643a3040ea8edbd89 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 3 Jan 2021 19:45:49 +0100 Subject: [PATCH 086/142] Do not fail stopping existing links --- src/ctl/sinkctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 9a6489d..3078f68 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -749,9 +749,7 @@ static int ctl_interactive(char **argv, int argc) if (r < 0) goto error; - r = ctl_wifi_fetch(wifi); - if (r < 0) - goto error; + ctl_wifi_fetch(wifi); if (argc > 0) { r = cli_do(cli_cmds, argv, argc); From 0481252438deff45d05bb389d4d1c4213c5eab15 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 9 Jul 2021 15:57:40 +0200 Subject: [PATCH 087/142] Specify path for miracle utils script --- res/test-hardware-capabilities.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/test-hardware-capabilities.sh b/res/test-hardware-capabilities.sh index 1e227f5..724943d 100755 --- a/res/test-hardware-capabilities.sh +++ b/res/test-hardware-capabilities.sh @@ -12,7 +12,7 @@ then set -v fi -. miracle-utils.sh +. ./miracle-utils.sh WIFI_COUNT=0 WIFI_NAMES="$(find_wireless_network_interfaces)" From a66b998883d81ee0fa89aa35445550bb4ceae0de Mon Sep 17 00:00:00 2001 From: dzink Date: Sun, 5 Sep 2021 17:32:33 -0400 Subject: [PATCH 088/142] Update README to indicate that source is not yet implemented. Prevent issue duplication and manage user expectations by indicating up front that source is not yet implemented (see issue #4). --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 056bf13..f2326a3 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,10 @@ The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. -The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. +The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. *Note: This is not implemented yet. Please see [#4](./issues/4)* On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display. - ## Requirements The MiracleCast projects requires the following software to be installed: From 7739a9cee0ce847db0fa0eed977e8e06839d3a08 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 26 Oct 2021 20:00:52 +0200 Subject: [PATCH 089/142] Fix completion path on meson buildsystem --- res/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/meson.build b/res/meson.build index 037a759..9a0992c 100644 --- a/res/meson.build +++ b/res/meson.build @@ -9,5 +9,5 @@ install_data('miracle-gst', 'gstplayer', 'uibc-viewer', install_data( 'miracle-wifid', 'miracle-sinkctl', 'miracle-wifictl', - install_dir: join_paths(get_option('datadir'), 'bash-completions', 'completions') + install_dir: join_paths(get_option('datadir'), 'bash-completion', 'completions') ) From 506f1e7b2821eca80617de54f3de358bdee9b83f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 27 Oct 2021 07:35:43 +0200 Subject: [PATCH 090/142] whitespace --- src/wifi/wifid-link.c | 8 ++++---- src/wifi/wifid.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index 9b37571..6dd7314 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -140,17 +140,17 @@ void link_free(struct link *l) void link_use_dev(struct link *l) { - l->use_dev = true; + l->use_dev = true; } bool link_is_using_dev(struct link *l) { - return l->use_dev; + return l->use_dev; } int link_set_config_methods(struct link *l, char *config_methods) { - char *cm; + char *cm; if (!config_methods) return log_EINVAL(); @@ -161,7 +161,7 @@ int link_set_config_methods(struct link *l, char *config_methods) free(l->config_methods); l->config_methods = config_methods; - return 0; + return 0; } bool link_get_managed(struct link *l) diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 4b46f64..c8c2b53 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -104,13 +104,13 @@ static void manager_add_udev_link(struct manager *m, if (r < 0) return; - if (m->friendly_name && l->managed) - link_set_friendly_name(l, m->friendly_name); - if (m->config_methods) - link_set_config_methods(l, m->config_methods); + if (m->friendly_name && l->managed) + link_set_friendly_name(l, m->friendly_name); + if (m->config_methods) + link_set_config_methods(l, m->config_methods); if(use_dev) - link_use_dev(l); + link_use_dev(l); #ifdef RELY_UDEV bool managed = udev_device_has_tag(d, "miracle") && !lazy_managed; From 3f5270ee7aeff677878f8b238370ed568a7277ea Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 27 Oct 2021 12:02:54 +0200 Subject: [PATCH 091/142] Avoid automatic make commands on autotools --- autogen.sh | 4 ---- configure.ac | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/autogen.sh b/autogen.sh index 7912a7c..48dc21e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -29,22 +29,18 @@ if [ "x$1" = "xc" ]; then shift args="$args $@" $topdir/configure CFLAGS='-g -O0 -ftrapv' $args - make clean elif [ "x$1" = "xg" ]; then shift args="$args $@" $topdir/configure CFLAGS='-g -O0 -ftrapv' $args - make clean elif [ "x$1" = "xa" ]; then shift args="$args $@" $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args - make clean elif [ "x$1" = "xl" ]; then shift args="$args $@" $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args - make clean elif [ "x$1" = "xs" ]; then shift args="$args $@" diff --git a/configure.ac b/configure.ac index aeff177..34a2eb0 100644 --- a/configure.ac +++ b/configure.ac @@ -165,13 +165,14 @@ AC_MSG_NOTICE([Build configuration: bindir: $bindir libdir: $libdir includedir: $includedir + sysconfdir: $sysconfdir Miscellaneous Options: building tests: $have_check code coverage: $use_gcov + rely udev: ${enable_rely_udev:-no} Compilation - mkdir build && cd build "${MAKE-make}" to start compilation process "${MAKE-make}" check to pass test]) else @@ -181,11 +182,12 @@ AC_MSG_NOTICE([Build configuration: bindir: $bindir libdir: $libdir includedir: $includedir + sysconfdir: $sysconfdir Miscellaneous Options: building tests: $have_check + rely udev: ${enable_rely_udev:-no} Compilation - mkdir build && cd build "${MAKE-make}" to start compilation process]) fi From 65a7a0aad1e4f0fd6af791a7990a1921cdce4530 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 27 Oct 2021 12:10:40 +0200 Subject: [PATCH 092/142] Assig dupped string --- src/wifi/wifid-link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index 6dd7314..1766e1a 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -160,7 +160,7 @@ int link_set_config_methods(struct link *l, char *config_methods) return log_ENOMEM(); free(l->config_methods); - l->config_methods = config_methods; + l->config_methods = cm; return 0; } From df12df656cfe6a3b7d65b80eaacc3736a5d12c18 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 27 Oct 2021 07:35:43 +0200 Subject: [PATCH 093/142] Configurable ip binary path Different OS have ip binary on different locations It can be configured at: - compile time `IP_BINARY` - execution time `--ip-binary` --- CMakeLists.txt | 1 + config.h.cmake | 2 ++ configure.ac | 8 ++++++++ meson.build | 2 ++ meson_options.txt | 4 ++++ src/dhcp/dhcp.c | 7 +++++-- src/wifi/wifid-link.c | 17 +++++++++++++++++ src/wifi/wifid-supplicant.c | 8 ++++++++ src/wifi/wifid.c | 12 ++++++++++++ src/wifi/wifid.h | 3 +++ 10 files changed, 62 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a94c904..38fce5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) OPTION(BUILD_TESTS "Enable TEST" ON ) OPTION(BUILD_ENABLE_CPPCHECK "Enable CPPCheck static analysis" OFF ) +SET(IP_BINARY "/bin/ip" CACHE STRING "Path to ip binary") if(BUILD_ENABLE_DEBUG) add_definitions(-DBUILD_ENABLE_DEBUG) diff --git a/config.h.cmake b/config.h.cmake index ddc0cd1..f4689e4 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -2,6 +2,8 @@ #define CONFIG_H #cmakedefine BUILD_BINDIR "@BUILD_BINDIR@" +#cmakedefine RELY_UDEV @RELY_UDEV@ +#cmakedefine IP_BINARY @IP_BINARY@ #cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" diff --git a/configure.ac b/configure.ac index 34a2eb0..bdbce1b 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,12 @@ AC_ARG_ENABLE([rely-udev], AS_HELP_STRING([--enable-rely-udev], [Use tagged device with miraclecast]), AC_DEFINE([RELY_UDEV], [], [Rely on udev to find miraclecast device])) AC_ARG_ENABLE([log-debug], AS_HELP_STRING([--disable-log-debug], [Disable log debug]), , AC_DEFINE([BUILD_ENABLE_DEBUG], [], [Enable debug log level])) +AC_ARG_VAR(IP_BINARY, [Path for ip binary]) +if test -z "$IP_BINARY"; then + IP_BINARY=/bin/ip +fi +AC_DEFINE_UNQUOTED([IP_BINARY], [$IP_BINARY], [Path for ip binary]) + # # Mandatory dependencies # @@ -166,6 +172,7 @@ AC_MSG_NOTICE([Build configuration: libdir: $libdir includedir: $includedir sysconfdir: $sysconfdir + ip-binary: $IP_BINARY Miscellaneous Options: building tests: $have_check @@ -183,6 +190,7 @@ AC_MSG_NOTICE([Build configuration: libdir: $libdir includedir: $includedir sysconfdir: $sysconfdir + ip-binary: $IP_BINARY Miscellaneous Options: building tests: $have_check diff --git a/meson.build b/meson.build index c74b9ba..32beeb7 100644 --- a/meson.build +++ b/meson.build @@ -32,6 +32,8 @@ if get_option('rely-udev') add_project_arguments('-DRELY_UDEV', language: 'c') endif +add_project_arguments('-DIP_BINARY='+get_option('ip-binary'), language: 'c') + glib2 = dependency('glib-2.0') udev = dependency('libudev') libsystemd = dependency('libsystemd') diff --git a/meson_options.txt b/meson_options.txt index 34002ff..86a6862 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,3 +10,7 @@ option('build-tests', type: 'boolean', value: true, description: 'Enable TEST') +option('ip-binary', + type: 'string', + value: '/bin/ip', + description: 'Path for ip binary') diff --git a/src/dhcp/dhcp.c b/src/dhcp/dhcp.c index 5457764..6838ae9 100644 --- a/src/dhcp/dhcp.c +++ b/src/dhcp/dhcp.c @@ -67,8 +67,11 @@ #include "shl_log.h" #include "config.h" +#define XSTR(x) STR(x) +#define STR(x) #x + static const char *arg_netdev; -static const char *arg_ip_binary = "/bin/ip"; +static const char *arg_ip_binary = XSTR(IP_BINARY); static bool arg_server; static char arg_local[INET_ADDRSTRLEN]; static char arg_gateway[INET_ADDRSTRLEN]; @@ -749,7 +752,7 @@ static int help(void) " --log-time Prefix log-messages with timestamp\n" "\n" " --netdev Network device to run on\n" - " --ip-binary Path to 'ip' binary [default: /bin/ip]\n" + " --ip-binary Path to 'ip' binary [default: "XSTR(IP_BINARY)"]\n" " --comm-fd Comm-socket FD passed through execve()\n" "\n" "Server Options:\n" diff --git a/src/wifi/wifid-link.c b/src/wifi/wifid-link.c index 1766e1a..1093fc4 100644 --- a/src/wifi/wifid-link.c +++ b/src/wifi/wifid-link.c @@ -135,6 +135,7 @@ void link_free(struct link *l) free(l->friendly_name); free(l->ifname); free(l->config_methods); + free(l->ip_binary); free(l); } @@ -164,6 +165,22 @@ int link_set_config_methods(struct link *l, char *config_methods) return 0; } +int link_set_ip_binary(struct link *l, const char *ip_binary) +{ + char *ipb; + + if (!ip_binary) + return log_EINVAL(); + + ipb = strdup(ip_binary); + if (!ipb) + return log_ENOMEM(); + + free(l->ip_binary); + l->ip_binary = ipb; + return 0; +} + bool link_get_managed(struct link *l) { return l->managed; diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index fef362d..0f8f728 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -397,6 +397,10 @@ static int supplicant_group_spawn_dhcp_server(struct supplicant_group *g, argv[i++] = g->ifname; argv[i++] = "--comm-fd"; argv[i++] = commfd; + if (g->s->l->ip_binary) { + argv[i++] = "--ip-binary"; + argv[i++] = g->s->l->ip_binary; + } argv[i] = NULL; if (execvpe(argv[0], argv, environ)< 0) { @@ -458,6 +462,10 @@ static int supplicant_group_spawn_dhcp_client(struct supplicant_group *g) argv[i++] = g->ifname; argv[i++] = "--comm-fd"; argv[i++] = commfd; + if (g->s->l->ip_binary) { + argv[i++] = "--ip-binary"; + argv[i++] = g->s->l->ip_binary; + } argv[i] = NULL; if (execvpe(argv[0], argv, environ) < 0) { diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index c8c2b53..7a45b94 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -40,12 +40,16 @@ #include "wifid.h" #include "config.h" +#define XSTR(x) STR(x) +#define STR(x) #x const char *interface_name = NULL; const char *config_methods = NULL; unsigned int arg_wpa_loglevel = LOG_NOTICE; bool arg_wpa_syslog = false; bool use_dev = false; bool lazy_managed = false; +const char *arg_ip_binary = NULL; + /* * Manager Handling @@ -111,6 +115,8 @@ static void manager_add_udev_link(struct manager *m, if(use_dev) link_use_dev(l); + if(arg_ip_binary) + link_set_ip_binary(l, arg_ip_binary); #ifdef RELY_UDEV bool managed = udev_device_has_tag(d, "miracle") && !lazy_managed; @@ -484,6 +490,7 @@ static int help(void) " --wpa-syslog wpa_supplicant use syslog\n" " --use-dev enable workaround for 'no ifname' issue\n" " --lazy-managed manage interface only when user decide to do\n" + " --ip-binary path to 'ip' binary [default: "XSTR(IP_BINARY)"]\n" , program_invocation_short_name); /* * 80-char barrier: @@ -504,6 +511,7 @@ static int parse_argv(int argc, char *argv[]) ARG_USE_DEV, ARG_CONFIG_METHODS, ARG_LAZY_MANAGED, + ARG_IP_BINARY, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, @@ -517,6 +525,7 @@ static int parse_argv(int argc, char *argv[]) { "use-dev", no_argument, NULL, ARG_USE_DEV }, { "config-methods", required_argument, NULL, ARG_CONFIG_METHODS }, { "lazy-managed", no_argument, NULL, ARG_LAZY_MANAGED }, + { "ip-binary", required_argument, NULL, ARG_IP_BINARY }, {} }; int c; @@ -552,6 +561,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_WPA_SYSLOG: arg_wpa_syslog = true; break; + case ARG_IP_BINARY: + arg_ip_binary = optarg; + break; case '?': return -EINVAL; } diff --git a/src/wifi/wifid.h b/src/wifi/wifid.h index d07c29f..db78f18 100644 --- a/src/wifi/wifid.h +++ b/src/wifi/wifid.h @@ -130,6 +130,7 @@ struct link { char *friendly_name; char *wfd_subelements; char *config_methods; + char *ip_binary; size_t peer_cnt; struct shl_htable peers; @@ -159,6 +160,8 @@ void link_free(struct link *l); void link_use_dev(struct link *l); bool link_is_using_dev(struct link *l); +int link_set_ip_binary(struct link *l, const char *ip_binary); + int link_set_managed(struct link *l, bool set); bool link_get_managed(struct link *l); int link_renamed(struct link *l, const char *ifname); From e25d8d5a0bac4231ee196784da6705ca5e9a58f2 Mon Sep 17 00:00:00 2001 From: mcp292 Date: Wed, 17 Nov 2021 12:44:20 -0700 Subject: [PATCH 094/142] Fix broken relative link to #4 in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2326a3..3cf79e1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. -The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. *Note: This is not implemented yet. Please see [#4](./issues/4)* +The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. *Note: This is not implemented yet. Please see [#4](../../issues/4)* On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display. From 5ac3e0593f1ccb8ab2cc89f5ba1c8107a59186f3 Mon Sep 17 00:00:00 2001 From: mcp292 Date: Thu, 18 Nov 2021 09:20:16 -0700 Subject: [PATCH 095/142] Add missing period --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cf79e1..31b230d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. -The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. *Note: This is not implemented yet. Please see [#4](../../issues/4)* +The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. *Note: This is not implemented yet. Please see [#4](../../issues/4).* On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display. From 4b229dc2825f5bda1bdc748d09d46c21527fdc9d Mon Sep 17 00:00:00 2001 From: Michael Partridge Date: Fri, 19 Nov 2021 17:40:28 -0700 Subject: [PATCH 096/142] Move optional packages towards the end --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 31b230d..2dfd9ab 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,13 @@ The MiracleCast projects requires the following software to be installed: - **glib**: A utility library. Used by the current DHCP implementation. Will be removed once sd-dns gains DHCP-server capabilities. *required*: ~=glib2-2.38 (might work with older releases, untested..) - - **check**: Test-suite for C programs. Used for optional tests of the MiracleCast code base. - *optional*: ~=check-0.9.11 (might work with older releases, untested..) - - **gstreamer**: MiracleCast rely on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh) - **P2P Wi-Fi device** Although widespread these days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh) + - **check**: Test-suite for C programs. Used for optional tests of the MiracleCast code base. + *optional*: ~=check-0.9.11 (might work with older releases, untested..) + - copy the dbus policy **res/org.freedesktop.miracle.conf** to `/etc/dbus-1/system.d/` ## Build and install From 264a222d242734da369ca287aa6cfc6ca4f1f7bf Mon Sep 17 00:00:00 2001 From: Michael Partridge Date: Fri, 19 Nov 2021 17:42:08 -0700 Subject: [PATCH 097/142] Add wpa_supplicant to requirements --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2dfd9ab..cd579f1 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ The MiracleCast projects requires the following software to be installed: - **gstreamer**: MiracleCast rely on gstreamer to show cast its output. You can test if all needed is installed launching [res/test-viewer.sh](https://github.com/albfan/miraclecast/blob/master/res/test-viewer.sh) + - **wpa_supplicant**: MiracleCast spawns wpa_supplicant with a custom config. + - **P2P Wi-Fi device** Although widespread these days, there are some devices not compatible with [Wi-Fi Direct](http://en.wikipedia.org/wiki/Wi-Fi_Direct) (prior know as Wi-Fi P2P). Test yours with [res/test-hardware-capabilities.sh](https://github.com/albfan/miraclecast/blob/master/res/test-hardware-capabilities.sh) - **check**: Test-suite for C programs. Used for optional tests of the MiracleCast code base. From 125f4a847f2c56363c46c0d36d5d524109b0a0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D1=80=D0=B5=D0=BD=D0=B1=D0=B5=D1=80=D0=B3=20?= =?UTF-8?q?=E2=98=A2=EF=B8=8F=20=20=D0=9C=D0=B0=D1=80=D0=BA?= Date: Wed, 5 Jan 2022 13:41:22 +0500 Subject: [PATCH 098/142] Fix .spec file --- res/miraclecast.spec | 76 ++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/res/miraclecast.spec b/res/miraclecast.spec index e199155..0ba2eab 100644 --- a/res/miraclecast.spec +++ b/res/miraclecast.spec @@ -1,60 +1,68 @@ -%global commit c3c868e523f450ad4f0d77f5484a3b61f08120b7 +%global commit 264a222d242734da369ca287aa6cfc6ca4f1f7bf %global shortcommit %(c=%{commit}; echo ${c:0:7}) Name: miraclecast Version: 1.0 -Release: 1.git%{shortcommit}%{?dist} -Summary: Connect external monitors to your system via Wifi-Display -License: LGPL +Release: 2.git%{shortcommit}%{?dist} +Summary: Connect external monitors to your system via Wi-Fi Display (miracast) +License: LGPLv2 URL: https://github.com/albfan/miraclecast Source0: https://github.com/albfan/miraclecast/archive/%{commit}/%{name}-%{shortcommit}.tar.gz -BuildRequires: autoconf, automake, libtool -BuildRequires: readline-devel, glib2-devel, systemd-devel + +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool + +BuildRequires: glib2-devel +BuildRequires: readline-devel +BuildRequires: systemd-devel + +# "Recommends" is stronger than "Suggests", and gets installed by default by DNF. + +# for gstplayer +Recommends: python3-gobject-base + +# for miracle-gst (/usr/bin/gst-launch-1.0) +Suggests: gstreamer + +# for miracle-omxplayer +Suggests: omxplayer %description -The MiracleCast project provides software to connect external monitors to your system via Wi-Fi. It is compatible to the Wifi-Display specification also known as Miracast. MiracleCast implements the Display-Source as well as Display-Sink side. +The MiracleCast project provides software to connect external monitors to your +system via Wi-Fi. It is compatible to the Wi-Fi Display specification also +known as Miracast. MiracleCast implements the Display-Source as well as +Display-Sink side. -The Display-Source side allows you to connect external displays to your system and stream local content to the device. A lot of effort is put into making this as easy as connecting external displays via HDMI. - -On the other hand, the Display-Sink side allows you to create wifi-capable external displays yourself. You can use it on your embedded devices or even on full desktops to allow other systems to use your device as external display. +The Display-Source side allows you to connect external displays to your system +and stream local content to the device. A lot of effort is put into making +this as easy as connecting external displays via HDMI. +On the other hand, the Display-Sink side allows you to create Wi-Fi capable +external displays yourself. You can use it on your embedded devices or even on +full desktops to allow other systems to use your device as external display. %prep -%autosetup -n %{name}-%{shortcommit} - +%autosetup -n %{name}-%{commit} %build -mkdir build -cd build -../autogen.sh g --prefix=%{_prefix} +autoreconf -fiv +%configure %make_build - %install -rm -rf $RPM_BUILD_ROOT -cd build %make_install - %files %license COPYING LICENSE_gdhcp LICENSE_htable LICENSE_lgpl %doc README.md -%{_sysconfdir}/dbus-1/system.d/org.freedesktop.miracle.conf -%{_bindir}/miracle-wifictl -%{_bindir}/miracle-omxplayer -%{_bindir}/miracle-gst -%{_bindir}/miracle-sinkctl -%{_bindir}/miracled -%{_bindir}/miracle-dhcp -%{_bindir}/miracle-uibcctl -%{_bindir}/miracle-wifid -%{_bindir}/gstplayer -%{_bindir}/uibc-viewer -%{_datadir}/bash-completion/completions/miracle-wifictl -%{_datadir}/bash-completion/completions/miracle-sinkctl -%{_datadir}/bash-completion/completions/miracle-wifid - +%config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freedesktop.miracle.conf +%{_bindir}/* +%{_datadir}/bash-completion/completions/* %changelog +* Wed Jan 05 2022 Korenberg Mark +- Fix .spec-file, bump version + * Wed Nov 21 2018 Graham White - first build From 0b72e0b4358b4908daf1932c8f77fbd11ad8d140 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 9 Mar 2022 17:45:30 +0100 Subject: [PATCH 099/142] cmake: fix build for Ninja generator --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a6e3b44..1363051 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,7 +41,7 @@ if(CHECK_FOUND) add_custom_target(memcheck DEPENDS memcheck-verify - COMMAND for i in $(MEMTESTS) | + COMMAND for i in $$(MEMTESTS) | do | ${VALGRIND} --log-file=${CMAKE_SOURCE_DIR}/$$i.memlog | ${CMAKE_SOURCE_DIR}/$$i >/dev/null || (echo "memcheck failed on: $$i" ; exit 1) ; | From 3ab7d5913fbe67d7588904adac4790bce4468116 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Tue, 12 Apr 2022 07:56:39 +0100 Subject: [PATCH 100/142] Correct spelling mistakes --- COPYING | 2 +- res/normal-wifi.sh | 2 +- res/write-udev-rule.sh | 2 +- src/ctl/sinkctl.c | 4 ++-- src/ctl/wifictl.c | 2 +- src/dhcp/dhcp.c | 2 +- src/shared/shl_util.c | 2 +- src/uibc/miracle-uibcctl.c | 2 +- src/wifi/wifid-dbus.c | 2 +- src/wifi/wifid-supplicant.c | 4 ++-- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/COPYING b/COPYING index 0dbad09..e6f33de 100644 --- a/COPYING +++ b/COPYING @@ -8,7 +8,7 @@ This software was written by: This software is licensed under the terms of the LGPL. Please see each source file for the related copyright notice and license. -If a file does not contain a copright notice, the following notice shall apply: +If a file does not contain a copyright notice, the following notice shall apply: MiracleCast - Wifi-Display/Miracast Implementation diff --git a/res/normal-wifi.sh b/res/normal-wifi.sh index 1e03201..30c5615 100755 --- a/res/normal-wifi.sh +++ b/res/normal-wifi.sh @@ -10,7 +10,7 @@ ETHER_COUNT=$(echo "$ETHER_NAMES" | wc -l) if [ 0 = $ETHER_COUNT ] then - echo There is no net devices avaliable + echo There is no net devices available exit 1 elif [ 1 = $ETHER_COUNT ] then diff --git a/res/write-udev-rule.sh b/res/write-udev-rule.sh index 6786dc9..73095da 100755 --- a/res/write-udev-rule.sh +++ b/res/write-udev-rule.sh @@ -8,7 +8,7 @@ ETHER_COUNT=$(echo "$ETHER_NAMES" | wc -l) if [ 0 = $ETHER_COUNT ] then - echo There is no net devices avaliable + echo There is no net devices available exit 1 elif [ 1 = $ETHER_COUNT ] then diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 3078f68..3edafee 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -712,7 +712,7 @@ void cli_fn_help() printf("%s [OPTIONS...] ...\n\n" "Control a dedicated local sink via MiracleCast.\n" " -h --help Show this help\n" - " --help-commands Show avaliable commands\n" + " --help-commands Show available commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-journal-level Maximum level for journal log messages\n" @@ -726,7 +726,7 @@ void cli_fn_help() " default CEA %08X\n" " default VESA %08X\n" " default HH %08X\n" - " --help-res Shows avaliable values for res\n" + " --help-res Shows available values for res\n" "\n" , program_invocation_short_name, gst_audio_en, DEFAULT_RSTP_PORT, wfd_supported_res_cea, wfd_supported_res_vesa, wfd_supported_res_hh diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index faf7880..d862b9c 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -478,7 +478,7 @@ void cli_fn_help() "Send control command to or query the MiracleCast Wifi-Manager. If no arguments\n" "are given, an interactive command-line tool is provided.\n\n" " -h --help Show this help\n" - " --help-commands Show avaliable commands\n" + " --help-commands Show available commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-journal-level Maximum level for journal log messages\n" diff --git a/src/dhcp/dhcp.c b/src/dhcp/dhcp.c index 6838ae9..83e7295 100644 --- a/src/dhcp/dhcp.c +++ b/src/dhcp/dhcp.c @@ -35,7 +35,7 @@ * of Wifi-P2P support in common network managers. Once they gain proper * support, we will drop this helper! * - * The "ip" invokation is quite fragile and ugly. However, performing these + * The "ip" invocation is quite fragile and ugly. However, performing these * steps directly involves netlink operations and more. As no-one came up with * patches, yet, we keep the hack. To anyone trying to fix it: Please, spend * this time hacking on NetworkManager, connman and friends instead! If they diff --git a/src/shared/shl_util.c b/src/shared/shl_util.c index 1d3f662..2417624 100644 --- a/src/shared/shl_util.c +++ b/src/shared/shl_util.c @@ -31,7 +31,7 @@ * variants to allow these. * Base-prefix parsing is only done if base=0 is requested. Otherwise, * base-prefixes are forbidden. - * The input string must be ASCII compatbile (which includes UTF8). + * The input string must be ASCII compatible (which includes UTF8). * * We also always check for overflows and return errors (but continue parsing!) * so callers can catch it correctly. diff --git a/src/uibc/miracle-uibcctl.c b/src/uibc/miracle-uibcctl.c index 2c8835b..3aee587 100644 --- a/src/uibc/miracle-uibcctl.c +++ b/src/uibc/miracle-uibcctl.c @@ -314,7 +314,7 @@ void getUIBCGenericKeyPacket(const char *inEventDesc, typeId = atoi(*(splitedStr + i)); log_info("getUIBCGenericKeyPacket typeId=[%d]\n", typeId); genericPacketLen = 5; - uibcBodyLen = genericPacketLen + 7; // Generic header legth = 7 + uibcBodyLen = genericPacketLen + 7; // Generic header length = 7 outData = (char*)malloc(uibcBodyLen + 1); // UIBC header outData[0] = 0x00; //Version (3 bits),T (1 bit),Reserved(8 bits),Input Category (4 bits) diff --git a/src/wifi/wifid-dbus.c b/src/wifi/wifid-dbus.c index 8aed6f4..a856cd2 100644 --- a/src/wifi/wifid-dbus.c +++ b/src/wifi/wifid-dbus.c @@ -938,7 +938,7 @@ int manager_dbus_connect(struct manager *m) r = sd_bus_request_name(m->bus, "org.freedesktop.miracle.wifi", 0); if (r < 0) { if (r == -EEXIST) { - log_info("cannot claim org.freedesktop.miracle.wifi bus-name: it is already being adquired"); + log_info("cannot claim org.freedesktop.miracle.wifi bus-name: it is already being acquired"); } else { log_error("cannot claim org.freedesktop.miracle.wifi bus-name: %d", r); diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 0f8f728..7679d7f 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -884,7 +884,7 @@ static void supplicant_parse_peer(struct supplicant *s, /* TODO: wfd_dev_info only contains the dev-info sub-elem, * while wfd_sublemens contains all. Fix that! The user has no * chance to distinguish both. - * We currently use it only as boolen (set/unset) but once we + * We currently use it only as boolean (set/unset) but once we * parse it we _definitely_ have to provide proper data. */ r = wpas_message_dict_read(m, "wfd_dev_info", 's', &val); if (r >= 0) { @@ -2219,7 +2219,7 @@ static int supplicant_global_attach_fn(struct wpas *w, * Devices with P2P_DEVICE support (instead of direct P2P_GO/CLIENT * support) are broken with a *lot* of wpa_supplicant versions on the * global interface. Therefore, try to open the p2p-dev-* interface - * after the global-ATTACH succeded (which means the iface is properly + * after the global-ATTACH succeeded (which means the iface is properly * set up). If this works, use the p2p-dev-* interface, otherwise, just * copy the global interface over to bus_dev. * Event-forwarding is broken on the global-interface in such cases, From c42624885bbc1e0bfc3fd0aba597140dbb6de5aa Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Thu, 26 May 2022 20:55:51 +0200 Subject: [PATCH 101/142] simplify pass request options --- src/ctl/ctl-sink.c | 58 +++++++++++++++------------------------------- src/ctl/ctl-sink.h | 12 ++++++++++ 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index fe652cc..bd0d967 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -87,50 +87,26 @@ static void sink_handle_get_parameter(struct ctl_sink *s, return cli_vERR(r); /* wfd_content_protection */ - if (rtsp_message_read(m, "{<>}", "wfd_content_protection") >= 0) { - r = rtsp_message_append(rep, "{&}", - "wfd_content_protection: none"); - if (r < 0) - return cli_vERR(r); - } + check_and_response_option("wfd_content_protection", "none"); /* wfd_video_formats */ - if (rtsp_message_read(m, "{<>}", "wfd_video_formats") >= 0) { - char wfd_video_formats[128]; - sprintf(wfd_video_formats, - "wfd_video_formats: 00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", - s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); - r = rtsp_message_append(rep, "{&}", wfd_video_formats); - if (r < 0) - return cli_vERR(r); - } + char wfd_video_formats[128]; + sprintf(wfd_video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", + s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); + check_and_response_option("wfd_video_formats", wfd_video_formats); /* wfd_audio_codecs */ - if (rtsp_message_read(m, "{<>}", "wfd_audio_codecs") >= 0) { - r = rtsp_message_append(rep, "{&}", - "wfd_audio_codecs: AAC 00000007 00"); - if (r < 0) - return cli_vERR(r); - } + check_and_response_option("wfd_audio_codecs", "AAC 00000007 00"); /* wfd_client_rtp_ports */ - if (rtsp_message_read(m, "{<>}", "wfd_client_rtp_ports") >= 0) { - char wfd_client_rtp_ports[128]; - sprintf(wfd_client_rtp_ports, - "wfd_client_rtp_ports: RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); - r = rtsp_message_append(rep, "{&}", - wfd_client_rtp_ports); - if (r < 0) - return cli_vERR(r); - } + char wfd_client_rtp_ports[128]; + sprintf(wfd_client_rtp_ports, "RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); + check_and_response_option("wfd_client_rtp_ports", wfd_client_rtp_ports); /* wfd_uibc_capability */ - if (rtsp_message_read(m, "{<>}", "wfd_uibc_capability") >= 0 && uibc_option) { - char wfd_uibc_capability[512]; - sprintf(wfd_uibc_capability, - "wfd_uibc_capability: input_category_list=GENERIC;" - "generic_cap_list=Mouse,SingleTouch;" - "hidc_cap_list=none;port=none"); - r = rtsp_message_append(rep, "{&}", wfd_uibc_capability); - if (r < 0) - return cli_vERR(r); + if (uibc_option) { + check_and_response_option("wfd_uibc_capability", + "input_category_list=GENERIC;" + "generic_cap_list=Mouse,SingleTouch;" + "hidc_cap_list=none;" + "port=none"); } rtsp_message_seal(rep); cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); @@ -140,6 +116,10 @@ static void sink_handle_get_parameter(struct ctl_sink *s, return cli_vERR(r); } +bool check_rtsp_option(struct rtsp_message *m, char *option) { + return rtsp_message_read(m, "{<>}", option) >= 0; +} + static int sink_setup_fn(struct rtsp *bus, struct rtsp_message *m, void *data) { _rtsp_message_unref_ struct rtsp_message *rep = NULL; diff --git a/src/ctl/ctl-sink.h b/src/ctl/ctl-sink.h index 7218583..996cba0 100644 --- a/src/ctl/ctl-sink.h +++ b/src/ctl/ctl-sink.h @@ -70,4 +70,16 @@ struct ctl_sink { int vres; }; +bool check_rtsp_option(struct rtsp_message *m, char *option); + +#define check_and_response_option(option, response) \ + if (check_rtsp_option(m, option)) { \ + char option_response[512]; \ + sprintf(option_response, "%s: %s", option, response); \ + r = rtsp_message_append(rep, "{&}", option_response); \ + if (r < 0) {\ + return cli_vERR(r); \ + } \ + } + #endif /* CTL_SINK_H */ From e816de93d3507584af5783403d520abd59051d5a Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 28 May 2022 10:37:53 +0200 Subject: [PATCH 102/142] Allow auto commands with any number of parameters --- src/ctl/sinkctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 3edafee..03941a6 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -918,7 +918,7 @@ int main(int argc, char **argv) } gchar* autocmd; autocmd = g_key_file_get_string (gkf, "sinkctl", "autocmd", NULL); - if (autocmd && argc == 1) { + if (autocmd) { gchar** autocmds = g_strsplit(autocmd, " ", -1); autocmds_free = autocmds; while (*autocmds) { From 43505ab3dd3911084331f7e9bdb562d1f5047190 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 27 May 2022 01:15:08 +0200 Subject: [PATCH 103/142] Allow to override/extend the request parameters --- res/sinkctl.protocol-extension.example | 18 ++++++++ src/ctl/ctl-sink.c | 62 +++++++++++++++++++++----- src/ctl/ctl-sink.h | 7 +++ src/ctl/sinkctl.c | 18 ++++++++ 4 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 res/sinkctl.protocol-extension.example diff --git a/res/sinkctl.protocol-extension.example b/res/sinkctl.protocol-extension.example new file mode 100644 index 0000000..a0205fe --- /dev/null +++ b/res/sinkctl.protocol-extension.example @@ -0,0 +1,18 @@ +#Example of extra parameters to extend sink request + +[sinkctl] +extends.wfd_video_formats=40 00 01 10 0001bdeb 051557ff 00000fff 10 0000 001f 11 0780 0438, 02 10 0001bdeb 155557ff 00000fff 10 0000 001f 11 0780 0438 +extends.wfd_audio_codecs=LPCM 00000003 00, AAC 0000000f 00, AC3 00000007 00 +extends.wfd_display_edid=0001 00ffffffffffff0051f38f50010000000e100104a51d10ff2f0000a057499b2610484f000000010101010101010101010101010101011a36809c70381f403020350025a510000018000000fc00496e7465726e616c204c43440a000000fd003c3c9a9a0e00000000000000000000000000000000000000000000000000000030 +extends.wfd_connector_type=05 +extends.microsoft_cursor=none +extends.microsoft_rtcp_capability=none +extends.wfd_idr_request_capability=1 +extends.microsoft_latency_management_capability=none +extends.microsoft_format_change_capability=none +extends.microsoft_diagnostics_capability=none +extends.intel_friendly_name=miraclecast +extends.intel_sink_manufacturer_name=GNU Linux +extends.intel_sink_model_name=Arch linux +extends.intel_sink_device_URL=http://github.com/albfan/miraclecast +extends.wfd_uibc_capability=input_category_list=GENERIC, HIDC;generic_cap_list=Keyboard;hidc_cap_list=Keyboard/USB, Mouse/USB, MultiTouch/USB, Gesture/USB, RemoteControl/USB;port=none diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index bd0d967..aeb59bf 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -88,26 +88,67 @@ static void sink_handle_get_parameter(struct ctl_sink *s, /* wfd_content_protection */ check_and_response_option("wfd_content_protection", "none"); + GHashTable* protocol_extensions = s->protocol_extensions; /* wfd_video_formats */ - char wfd_video_formats[128]; - sprintf(wfd_video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", - s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); - check_and_response_option("wfd_video_formats", wfd_video_formats); + gchar* wfd_video_formats = NULL; + if (protocol_extensions != NULL) { + gchar* wfd_video_formats_extension = g_hash_table_lookup(protocol_extensions, WFD_VIDEO_FORMATS); + if (wfd_video_formats_extension != NULL) { + wfd_video_formats = wfd_video_formats_extension; + } + } + if (wfd_video_formats == NULL) { + char video_formats[128]; + sprintf(video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", + s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); + wfd_video_formats = video_formats; + } + check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); + /* wfd_audio_codecs */ - check_and_response_option("wfd_audio_codecs", "AAC 00000007 00"); + gchar* wfd_audio_codecs = "AAC 00000007 00"; + if (protocol_extensions != NULL) { + gchar* wfd_audio_codecs_extension = g_hash_table_lookup(protocol_extensions, WFD_AUDIO_CODECS); + if (wfd_audio_codecs_extension != NULL) { + wfd_audio_codecs = wfd_audio_codecs_extension; + } + } + check_and_response_option(WFD_AUDIO_CODECS, wfd_audio_codecs); + /* wfd_client_rtp_ports */ char wfd_client_rtp_ports[128]; sprintf(wfd_client_rtp_ports, "RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); check_and_response_option("wfd_client_rtp_ports", wfd_client_rtp_ports); + if (protocol_extensions != NULL) { + GList* extension_keys = g_hash_table_get_keys(protocol_extensions); + for (int i = 0; isession); free(s->url); sd_event_unref(s->event); + g_hash_table_destroy(s->protocol_extensions); free(s); } diff --git a/src/ctl/ctl-sink.h b/src/ctl/ctl-sink.h index 996cba0..22c8401 100644 --- a/src/ctl/ctl-sink.h +++ b/src/ctl/ctl-sink.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "ctl.h" #include "rtsp.h" @@ -39,6 +40,10 @@ #include "shl_util.h" #include "wfd.h" +#define WFD_VIDEO_FORMATS "wfd_video_formats" +#define WFD_AUDIO_CODECS "wfd_audio_codecs" +#define WFD_UIBC_CAPABILITY "wfd_uibc_capability" + extern int rstp_port; extern bool uibc_option; extern bool uibc_enabled; @@ -68,6 +73,8 @@ struct ctl_sink { int hres; int vres; + + GHashTable* protocol_extensions; }; bool check_rtsp_option(struct rtsp_message *m, char *option); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 03941a6..d53ff51 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -66,6 +66,7 @@ bool external_player; int rstp_port; int uibc_port; char* player; +GHashTable* protocol_extensions; unsigned int wfd_supported_res_cea = 0x0001ffff; unsigned int wfd_supported_res_vesa = 0x1fffffff; @@ -748,6 +749,7 @@ static int ctl_interactive(char **argv, int argc) r = ctl_sink_new(&sink, cli_event); if (r < 0) goto error; + sink->protocol_extensions = protocol_extensions; ctl_wifi_fetch(wifi); @@ -938,6 +940,22 @@ int main(int argc, char **argv) } g_free(autocmd); } + gchar** sinkctl_keys; + gsize len = 0; + protocol_extensions = g_hash_table_new(g_str_hash, g_str_equal); + + sinkctl_keys = g_key_file_get_keys (gkf, + "sinkctl", + &len, + NULL); + for (int i = 0; i < (int)len; i++) { + if (g_str_has_prefix(sinkctl_keys[i], "extends.")) { + gchar* orig_key = sinkctl_keys[i]; + gchar* key = orig_key+8; + gchar* value = g_key_file_get_string (gkf, "sinkctl", orig_key, NULL); + g_hash_table_insert(protocol_extensions, key, value); + } + } g_key_file_free(gkf); } From a1590ecc17cb5c381acbc60a72feb3fa8b78b69f Mon Sep 17 00:00:00 2001 From: Fernando van Loenhout Date: Mon, 19 Sep 2022 10:35:36 +0200 Subject: [PATCH 104/142] Support more than 2 devices when testing the capabilities At the moment, this typo is preventing the test script from working when you have more than 2 devices plugged in. Fixes #449 --- res/test-hardware-capabilities.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/test-hardware-capabilities.sh b/res/test-hardware-capabilities.sh index 724943d..602c7c8 100755 --- a/res/test-hardware-capabilities.sh +++ b/res/test-hardware-capabilities.sh @@ -28,7 +28,7 @@ then elif [ 1 = $WIFI_COUNT ] then WIFI_NAME="$WIFI_NAMES" -elif [ 2 -ge $WIFI_COUNT ] +elif [ 2 -le $WIFI_COUNT ] then echo Choose wireless device: PS3="device: " From 7f263b06b41630eb1bff69312994c74de170fa58 Mon Sep 17 00:00:00 2001 From: Semara Incorporated Date: Tue, 20 Sep 2022 18:45:06 +0800 Subject: [PATCH 105/142] Change kdus to kdbus Change kdus to kdbus in Arch linux aur installation instruction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd579f1..b100f41 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ See there was interface changes on systemd 219, if you are below that version, u ### Arch linux -Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast-git/). Remember to enable kdus to systemd-git dependency if you are below 221 systemd. +Use existing [AUR package](https://aur.archlinux.org/packages/miraclecast-git/). Remember to enable kdbus to systemd-git dependency if you are below 221 systemd. $ export _systemd_git_kdbus=--enable-kdbus From 85723432f965ee4860d08469f87873af964aa93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= Date: Thu, 3 Jan 2019 10:43:31 +0100 Subject: [PATCH 106/142] Option to use elogind instead of whole systemd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas K. Hüttel --- CMakeLists.txt | 14 +++++++++++++- config.h.cmake | 2 ++ src/ctl/sinkctl.c | 10 ++++++++++ src/shared/CMakeLists.txt | 4 +--- src/wifi/wifid-supplicant.c | 19 ++++++++++++++++++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38fce5a..f9d3453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,19 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}") add_definitions(-D_GNU_SOURCE) +OPTION(ENABLE_SYSTEMD "Enable Systemd support" ON) + +find_package(PkgConfig) + +if(ENABLE_SYSTEMD) + pkg_check_modules (SYSTEMD REQUIRED libsystemd>=213) + SET(SESSION_LIBRARIES "${SYSTEMD_LIBRARIES}") +else(ENABLE_SYSTEMD) + pkg_check_modules (ELOGIND REQUIRED libelogind>=213) + include_directories ("${ELOGIND_INCLUDEDIR}") + SET(SESSION_LIBRARIES "${ELOGIND_LIBRARIES}") +endif(ENABLE_SYSTEMD) + SET(BUILD_BINDIR "${CMAKE_INSTALL_PREFIX}/bin") OPTION(BUILD_ENABLE_DEBUG "Enable Debug" ON ) OPTION(RELY_UDEV "Rely in udev tag to select device" OFF ) @@ -25,7 +38,6 @@ endif() set(SYSCONFDIR "/etc" CACHE STRING "system config dir") set(DATADIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "shared data dir") -find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) pkg_check_modules (SYSTEMD REQUIRED libsystemd) diff --git a/config.h.cmake b/config.h.cmake index f4689e4..13cf088 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,6 +1,8 @@ #ifndef CONFIG_H #define CONFIG_H +#cmakedefine ENABLE_SYSTEMD + #cmakedefine BUILD_BINDIR "@BUILD_BINDIR@" #cmakedefine RELY_UDEV @RELY_UDEV@ #cmakedefine IP_BINARY @IP_BINARY@ diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index d53ff51..e24e2b3 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -17,6 +17,8 @@ * along with MiracleCast; If not, see . */ +#include "config.h" + #include #include #include @@ -30,7 +32,11 @@ #include #include #include + +#ifdef ENABLE_SYSTEMD #include +#endif + #include #include #include "ctl.h" @@ -400,6 +406,7 @@ static void spawn_gst(struct ctl_sink *s) sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, NULL); +#ifdef ENABLE_SYSTEMD /* redirect stdout/stderr to journal */ fd_journal = sd_journal_stream_fd("miracle-sinkctl-gst", LOG_DEBUG, @@ -409,9 +416,12 @@ static void spawn_gst(struct ctl_sink *s) dup2(fd_journal, 1); dup2(fd_journal, 2); } else { +#endif /* no journal? redirect stdout to parent's stderr */ dup2(2, 1); +#ifdef ENABLE_SYSTEMD } +#endif launch_player(s); _exit(1); diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index f757fba..7cbd283 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -1,7 +1,5 @@ set(CMAKE_C_FLAGS "-std=gnu11") -find_package(PkgConfig) -pkg_check_modules (SYSTEMD REQUIRED systemd>=213) set(miracle-shared_SOURCES rtsp.h rtsp.c shl_dlist.h @@ -18,7 +16,7 @@ set(miracle-shared_SOURCES rtsp.h wpas.h wpas.c) add_library(miracle-shared STATIC ${miracle-shared_SOURCES}) -target_link_libraries (miracle-shared systemd) +target_link_libraries (miracle-shared ${SESSION_LIBRARIES}) ########### install files ############### diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 7679d7f..9d8ef91 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -19,6 +19,8 @@ #define LOG_SUBSYSTEM "supplicant" +#include "config.h" + #include #include #include @@ -27,7 +29,11 @@ #include #include #include + +#ifdef ENABLE_SYSTEMD #include +#endif + #include #include "shl_dlist.h" #include "shl_log.h" @@ -35,7 +41,6 @@ #include "util.h" #include "wifid.h" #include "wpas.h" -#include "config.h" struct supplicant_group { unsigned long users; @@ -374,6 +379,7 @@ static int supplicant_group_spawn_dhcp_server(struct supplicant_group *g, sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, NULL); +#ifdef ENABLE_SYSTEMD /* redirect stdout/stderr to journal */ sprintf(journal_id, "miracle-dhcp-%s", g->ifname); fd_journal = sd_journal_stream_fd(journal_id, LOG_INFO, false); @@ -382,9 +388,12 @@ static int supplicant_group_spawn_dhcp_server(struct supplicant_group *g, dup2(fd_journal, 1); dup2(fd_journal, 2); } else { +#endif /* no journal? redirect stdout to parent's stderr */ dup2(2, 1); +#ifdef ENABLE_SYSTEMD } +#endif i = 0; argv[i++] = (char*) "miracle-dhcp"; @@ -442,6 +451,7 @@ static int supplicant_group_spawn_dhcp_client(struct supplicant_group *g) sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, NULL); +#ifdef ENABLE_SYSTEMD /* redirect stdout/stderr to journal */ sprintf(journal_id, "miracle-dhcp-%s", g->ifname); fd_journal = sd_journal_stream_fd(journal_id, LOG_INFO, false); @@ -450,9 +460,12 @@ static int supplicant_group_spawn_dhcp_client(struct supplicant_group *g) dup2(fd_journal, 1); dup2(fd_journal, 2); } else { +#endif /* no journal? redirect stdout to parent's stderr */ dup2(2, 1); +#ifdef ENABLE_SYSTEMD } +#endif i = 0; argv[i++] = (char*) "miracle-dhcp"; @@ -2387,6 +2400,7 @@ static void supplicant_run(struct supplicant *s, const char *binary) sigemptyset(&mask); sigprocmask(SIG_SETMASK, &mask, NULL); +#ifdef ENABLE_SYSTEMD /* redirect stdout/stderr to journal */ sprintf(journal_id, "miracle-wifid-%s-%u", s->l->ifname, s->l->ifindex); @@ -2396,9 +2410,12 @@ static void supplicant_run(struct supplicant *s, const char *binary) dup2(fd_journal, 1); dup2(fd_journal, 2); } else { +#endif /* no journal? redirect stdout to parent's stderr */ dup2(2, 1); +#ifdef ENABLE_SYSTEMD } +#endif /* initialize wpa_supplicant args */ i = 0; From 6f84dc8b7dcbcac9f0884d4a79164247b6eedacf Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 28 May 2022 09:59:51 +0200 Subject: [PATCH 107/142] Add ENABLE_SYSTEMD config to meson and autotools --- CMakeLists.txt | 2 +- configure.ac | 20 ++++++++++++++++---- meson.build | 8 +++++++- meson_options.txt | 4 ++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9d3453..3edc3dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake set(CMAKE_C_FLAGS "-std=gnu11 ${CMAKE_C_FLAGS}") add_definitions(-D_GNU_SOURCE) -OPTION(ENABLE_SYSTEMD "Enable Systemd support" ON) +OPTION(ENABLE_SYSTEMD "Enable Systemd" ON) find_package(PkgConfig) diff --git a/configure.ac b/configure.ac index bdbce1b..cb4566a 100644 --- a/configure.ac +++ b/configure.ac @@ -45,16 +45,28 @@ AC_ARG_VAR(IP_BINARY, [Path for ip binary]) if test -z "$IP_BINARY"; then IP_BINARY=/bin/ip fi +AC_ARG_ENABLE([disable-systemd], + AS_HELP_STRING([--disable-systemd], [Disable systemd]), [], [use_libsystemd=yes], [Disable systemd using elogind]) AC_DEFINE_UNQUOTED([IP_BINARY], [$IP_BINARY], [Path for ip binary]) # # Mandatory dependencies # -m4_ifdef([PKG_CHECK_MODULES], [ - PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219]) - PKG_CHECK_MODULES([GLIB], [glib-2.0]) -]) +AS_IF([test "$use_libsystemd" == "yes"], + [ + AC_DEFINE([ENABLE_SYSTEMD], [], [Use systemd]) + m4_ifdef([PKG_CHECK_MODULES], [ + PKG_CHECK_MODULES([DEPS], [libudev libsystemd > 219]) + PKG_CHECK_MODULES([GLIB], [glib-2.0]) + ]) + ], + [ + m4_ifdef([PKG_CHECK_MODULES], [ + PKG_CHECK_MODULES([DEPS], [libudev libelogind]) + PKG_CHECK_MODULES([GLIB], [glib-2.0]) + ]) + ]) AC_CHECK_HEADERS(readline/readline.h,, AC_MSG_ERROR(GNU readline not found)) diff --git a/meson.build b/meson.build index 32beeb7..9b24bdf 100644 --- a/meson.build +++ b/meson.build @@ -32,11 +32,17 @@ if get_option('rely-udev') add_project_arguments('-DRELY_UDEV', language: 'c') endif +if get_option('enable-systemd') + add_project_arguments('-DENABLE_SYSTEMD', language: 'c') + libsystemd = dependency('libsystemd') +else + libsystemd = dependency('libelogind') +endif + add_project_arguments('-DIP_BINARY='+get_option('ip-binary'), language: 'c') glib2 = dependency('glib-2.0') udev = dependency('libudev') -libsystemd = dependency('libsystemd') subdir('src') subdir('res') diff --git a/meson_options.txt b/meson_options.txt index 86a6862..e3a94aa 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -14,3 +14,7 @@ option('ip-binary', type: 'string', value: '/bin/ip', description: 'Path for ip binary') +option('enable-systemd', + type: 'boolean', + value: 'true', + description: 'Enable systemd') From b46679d5a4eb0cac5e3464472ee972e298768fcd Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 16 Oct 2022 22:44:07 +0200 Subject: [PATCH 108/142] Use posix functions --- src/shared/shl_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/shl_util.c b/src/shared/shl_util.c index 2417624..a5907f8 100644 --- a/src/shared/shl_util.c +++ b/src/shared/shl_util.c @@ -826,8 +826,9 @@ int shl__mkdir_parents(const char *prefix, const char *path, mode_t mode) if (!e || e == path) return 0; - p = strndupa(path, e - path); + p = strndup(path, e - path); r = shl__is_dir(p); + free(p); if (r > 0) return 0; if (r == 0) From 380504b0f833faa46f12d3a1f3861b97d08d32a4 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 16 Oct 2022 23:02:57 +0200 Subject: [PATCH 109/142] helpers to start/stop wifi on several distros --- res/kill-wpa.sh | 2 +- res/miracle-utils.sh | 37 +++++++++--------------------- res/normal-wifi.sh | 54 ++------------------------------------------ 3 files changed, 14 insertions(+), 79 deletions(-) diff --git a/res/kill-wpa.sh b/res/kill-wpa.sh index e210b8f..2485163 100755 --- a/res/kill-wpa.sh +++ b/res/kill-wpa.sh @@ -2,7 +2,7 @@ . miracle-utils.sh -kill_ubuntu_network_manager +kill_network_manager WPA_PID=$(find_wpa_supplicant_pid) if [ -n "$WPA_PID" ] diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index 303ec0a..57f5121 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -159,45 +159,30 @@ function check_debian_distro { } # -# ubuntu manager restarts automatically wpa_supplicant +# kills network manager # -function kill_ubuntu_network_manager { +function kill_network_manager { + echo stopping NetworkManager if check_ubuntu_distro || check_debian_distro then - echo stopping NetworkManager + # ubuntu manager restarts automatically wpa_supplicant sudo service NetworkManager stop - fi -} - -# -# arch linux manager restarts automatically wpa_supplicant -# -function kill_archlinux_network_manager { - if check_ubuntu_distro - then - echo stopping NetworkManager + elif check_archlinux_distro + sudo systemctl stop Network.service + else sudo systemctl stop Network.service fi } # -# start ubuntu manager +# start network manager # -function start_ubuntu_network_manager { +function start_network_manager { + echo starting NetworkManager if check_ubuntu_distro || check_debian_distro then - echo starting NetworkManager sudo service NetworkManager start - fi -} - -# -# start arch linux manager -# -function start_archlinux_network_manager { - if check_archlinux_distro - then - echo starting NetworkManager + elif check_archlinux_distro sudo systemctl start Network.service fi } diff --git a/res/normal-wifi.sh b/res/normal-wifi.sh index 30c5615..c6a2871 100755 --- a/res/normal-wifi.sh +++ b/res/normal-wifi.sh @@ -1,57 +1,7 @@ #!/bin/bash -./kill-wpa.sh - . miracle-utils.sh -ETHER_NAMES=$(find_choosable_networknames) - -ETHER_COUNT=$(echo "$ETHER_NAMES" | wc -l) - -if [ 0 = $ETHER_COUNT ] -then - echo There is no net devices available - exit 1 -elif [ 1 = $ETHER_COUNT ] -then - ETHERNAME="$ETHER_NAMES" -elif [ 2 -le $ETHER_COUNT ] -then - echo choose device for normal connection: - QUIT="exit" - select et_name in $ETHER_NAMES $QUIT - do - case $et_name - in - "$QUIT") - exit - ;; - "") - if [ "$REPLY" = $QUIT ] - then - exit - else - echo unknow $REPLY - fi - ;; - *) - ETHERNAME=$et_name - break - ;; - esac - done -fi - -# default path for config file -CONFIG_FILE=${1:-/run/network/wpa_supplicant_${ETHERNAME}.conf} - - -echo starting wpa_supplicant for normal connection -if check_ubuntu_distro || check_debian_distro -then - start_ubuntu_network_manager - sudo wpa_supplicant -B -u -s -O /var/run/wpa_supplicant -else - sudo wpa_supplicant -B -u -P /run/wpa_supplicant_${ETHERNAME}pid -i ${ETHERNAME} -D nl80211 -c$CONFIG_FILE -fi +./kill-wpa.sh +start_network_manager From 72f61549d9b9a969c54237ab4730154bb7d84c60 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 28 Oct 2022 08:36:17 +0200 Subject: [PATCH 110/142] log messages with time in human readable way --- meson.build | 2 ++ res/miracle-utils.sh | 7 ++++++- src/ctl/ctl-cli.c | 34 +++++++++++++++++++++++++++++++ src/ctl/meson.build | 2 +- src/ctl/sinkctl.c | 19 +++++++++++++++--- src/dhcp/dhcp.c | 14 +++++++++---- src/dhcp/meson.build | 2 +- src/meson.build | 2 +- src/miracled.c | 14 +++++++++---- src/shared/shl_log.c | 48 +++++++++++++++++++++++++++++++++++++------- src/shared/shl_log.h | 10 +++++++++ src/uibc/meson.build | 1 - src/wifi/meson.build | 2 +- src/wifi/wifid.c | 14 +++++++++---- test/meson.build | 2 +- 15 files changed, 144 insertions(+), 29 deletions(-) diff --git a/meson.build b/meson.build index 9b24bdf..84b20c3 100644 --- a/meson.build +++ b/meson.build @@ -44,6 +44,8 @@ add_project_arguments('-DIP_BINARY='+get_option('ip-binary'), language: 'c') glib2 = dependency('glib-2.0') udev = dependency('libudev') +m = c_compiler.find_library('m', required: false) + subdir('src') subdir('res') diff --git a/res/miracle-utils.sh b/res/miracle-utils.sh index 57f5121..05ce20e 100755 --- a/res/miracle-utils.sh +++ b/res/miracle-utils.sh @@ -168,9 +168,11 @@ function kill_network_manager { # ubuntu manager restarts automatically wpa_supplicant sudo service NetworkManager stop elif check_archlinux_distro + then sudo systemctl stop Network.service else - sudo systemctl stop Network.service + sudo systemctl stop NetworkManager + sudo systemctl stop wpa_supplicant fi } @@ -183,6 +185,9 @@ function start_network_manager { then sudo service NetworkManager start elif check_archlinux_distro + then sudo systemctl start Network.service + else + sudo service NetworkManager start fi } diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 0897aa7..654b434 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -32,6 +32,9 @@ #include "ctl.h" #include "shl_macro.h" #include "shl_util.h" +#include "shl_log.h" +#include +#include /* *sigh* readline doesn't include all their deps, so put them last */ #include @@ -73,6 +76,37 @@ void cli_printv(const char *fmt, va_list args) rl_redisplay(); } + long long sec, usec; + time_t now; + struct tm *timeinfo; + struct timeval tv; + char buffertmp[80]; + char buffer[80]; + int millisec; + + + log__time(&sec, &usec); + + if (log_date_time) { + gettimeofday(&tv, NULL); + millisec = lrint(tv.tv_usec/1000.0); + if (millisec>=1000) { + millisec -=1000; + tv.tv_sec++; + } + + time(&now); + timeinfo = localtime(&now); + + strftime(buffertmp, 80, "%x - %X.%03d", timeinfo); + sprintf(buffer, "%s.%03d", buffertmp, millisec); + } + + if (log_date_time) + printf("[%s] ", buffer); + else if (log__have_time()) + printf("[%.4lld.%.6lld] ", sec, usec); + vprintf(fmt, args); if (async) { diff --git a/src/ctl/meson.build b/src/ctl/meson.build index d2ba182..cd9b77a 100644 --- a/src/ctl/meson.build +++ b/src/ctl/meson.build @@ -1,5 +1,5 @@ inc = include_directories('../..') -deps = [libsystemd, libmiracle_shared_dep, glib2] +deps = [libsystemd, libmiracle_shared_dep, glib2, m] if readline.found() deps += readline endif diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e24e2b3..9781bc6 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -726,6 +726,9 @@ void cli_fn_help() " --help-commands Show available commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" + " --log-time Prefix log-messages with timestamp\n" + " --log-date-time Prefix log-messages with date time\n" + "\n" " --log-journal-level Maximum level for journal log messages\n" " --gst-debug [cat:]lvl[,...] List of categories an level of debug\n" " --audio <0/1> Enable audio support (default %d)\n" @@ -813,6 +816,8 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_LOG_TIME, + ARG_LOG_DATE_TIME, ARG_JOURNAL_LEVEL, ARG_GST_DEBUG, ARG_AUDIO, @@ -823,10 +828,12 @@ static int parse_argv(int argc, char *argv[]) ARG_HELP_COMMANDS, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, + { "help", no_argument, NULL, 'h' }, { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, - { "version", no_argument, NULL, ARG_VERSION }, - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "log-date-time", no_argument, NULL, ARG_LOG_DATE_TIME }, { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, { "gst-debug", required_argument, NULL, ARG_GST_DEBUG }, { "audio", required_argument, NULL, ARG_AUDIO }, @@ -861,6 +868,12 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_LEVEL: cli_max_sev = log_parse_arg(optarg); break; + case ARG_LOG_TIME: + log_init_time(); + break; + case ARG_LOG_DATE_TIME: + log_date_time = true; + break; case ARG_GST_DEBUG: gst_debug = optarg; break; diff --git a/src/dhcp/dhcp.c b/src/dhcp/dhcp.c index 83e7295..3a43af5 100644 --- a/src/dhcp/dhcp.c +++ b/src/dhcp/dhcp.c @@ -750,6 +750,7 @@ static int help(void) " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-time Prefix log-messages with timestamp\n" + " --log-date-time Prefix log-messages with date time\n" "\n" " --netdev Network device to run on\n" " --ip-binary Path to 'ip' binary [default: "XSTR(IP_BINARY)"]\n" @@ -775,6 +776,7 @@ static int parse_argv(int argc, char *argv[]) ARG_VERSION = 0x100, ARG_LOG_LEVEL, ARG_LOG_TIME, + ARG_LOG_DATE_TIME, ARG_NETDEV, ARG_IP_BINARY, @@ -790,10 +792,11 @@ static int parse_argv(int argc, char *argv[]) ARG_TO, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, - { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "log-date-time", no_argument, NULL, ARG_LOG_DATE_TIME }, { "netdev", required_argument, NULL, ARG_NETDEV }, { "ip-binary", required_argument, NULL, ARG_IP_BINARY }, @@ -826,6 +829,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_TIME: log_init_time(); break; + case ARG_LOG_DATE_TIME: + log_date_time = true; + break; case ARG_NETDEV: arg_netdev = optarg; break; diff --git a/src/dhcp/meson.build b/src/dhcp/meson.build index 1dce905..9a52302 100644 --- a/src/dhcp/meson.build +++ b/src/dhcp/meson.build @@ -7,5 +7,5 @@ miracle_dhcp_srcs = ['dhcp.c', executable('miracle-dhcp', miracle_dhcp_srcs, install: true, include_directories: include_directories('../..'), - dependencies: [glib2, udev, libmiracle_shared_dep] + dependencies: [glib2, udev, libmiracle_shared_dep, m] ) diff --git a/src/meson.build b/src/meson.build index 1179ab3..bf7311b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,7 +5,7 @@ subdir('ctl') subdir('uibc') executable('miracled', 'miracled.c', - dependencies: libmiracle_shared_dep, + dependencies: [libmiracle_shared_dep, m], include_directories: include_directories('..'), install: true ) diff --git a/src/miracled.c b/src/miracled.c index 2fd435f..c193e95 100644 --- a/src/miracled.c +++ b/src/miracled.c @@ -66,6 +66,7 @@ static int help(void) " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-time Prefix log-messages with timestamp\n" + " --log-date-time Prefix log-messages with date time\n" , program_invocation_short_name); /* * 80-char barrier: @@ -81,12 +82,14 @@ static int parse_argv(int argc, char *argv[]) ARG_VERSION = 0x100, ARG_LOG_LEVEL, ARG_LOG_TIME, + ARG_LOG_DATE_TIME, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, - { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "log-date-time", no_argument, NULL, ARG_LOG_DATE_TIME }, {} }; int c; @@ -104,6 +107,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_TIME: log_init_time(); break; + case ARG_LOG_DATE_TIME: + log_date_time = true; + break; case '?': return -EINVAL; } diff --git a/src/shared/shl_log.c b/src/shared/shl_log.c index 9b311be..eb55501 100644 --- a/src/shared/shl_log.c +++ b/src/shared/shl_log.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include "shl_log.h" @@ -37,7 +39,7 @@ static inline void log_unlock() static struct timeval log__ftime; -static bool log__have_time(void) +bool log__have_time(void) { return !(log__ftime.tv_sec == 0 && log__ftime.tv_usec == 0); } @@ -48,7 +50,7 @@ void log_init_time(void) gettimeofday(&log__ftime, NULL); } -static void log__time(long long *sec, long long *usec) +void log__time(long long *sec, long long *usec) { struct timeval t; @@ -84,6 +86,7 @@ const char *LOG_SUBSYSTEM = NULL; */ unsigned int log_max_sev = LOG_NOTICE; +bool log_date_time = false; char *gst_debug = NULL; @@ -138,25 +141,51 @@ static void log__submit(const char *file, const char *prefix = NULL; FILE *out; long long sec, usec; + time_t now; + struct tm *timeinfo; + struct timeval tv; + char buffertmp[80]; + char buffer[80]; + int millisec; out = stderr; - log__time(&sec, &usec); if (sev < LOG_SEV_NUM && sev > log_max_sev) return; + log__time(&sec, &usec); + + if (log_date_time) { + gettimeofday(&tv, NULL); + millisec = lrint(tv.tv_usec/1000.0); + if (millisec>=1000) { + millisec -=1000; + tv.tv_sec++; + } + + time(&now); + timeinfo = localtime(&now); + + strftime(buffertmp, 80, "%x - %X.%03d", timeinfo); + sprintf(buffer, "%s.%03d", buffertmp, millisec); + } + if (sev < LOG_SEV_NUM) prefix = log__sev2str[sev]; if (prefix) { if (subs) { - if (log__have_time()) + if (log_date_time) + fprintf(out, "[%s] %s: %s: ", buffer, prefix, subs); + else if (log__have_time()) fprintf(out, "[%.4lld.%.6lld] %s: %s: ", sec, usec, prefix, subs); else fprintf(out, "%s: %s: ", prefix, subs); } else { - if (log__have_time()) + if (log_date_time) + fprintf(out, "[%s] %s: ", buffer, prefix); + else if (log__have_time()) fprintf(out, "[%.4lld.%.6lld] %s: ", sec, usec, prefix); else @@ -164,13 +193,18 @@ static void log__submit(const char *file, } } else { if (subs) { - if (log__have_time()) + if (log_date_time) + fprintf(out, "[%s] %s: ", + buffer, subs); + else if (log__have_time()) fprintf(out, "[%.4lld.%.6lld] %s: ", sec, usec, subs); else fprintf(out, "%s: ", subs); } else { - if (log__have_time()) + if (log_date_time) + fprintf(out, "[%s] ", buffer); + else if (log__have_time()) fprintf(out, "[%.4lld.%.6lld] ", sec, usec); } } diff --git a/src/shared/shl_log.h b/src/shared/shl_log.h index 43e972b..61225f2 100644 --- a/src/shared/shl_log.h +++ b/src/shared/shl_log.h @@ -61,6 +61,12 @@ enum log_severity { extern unsigned int log_max_sev; +/* + * Defines if log time should use local time + * Default: false + */ +extern bool log_date_time; + /* * Defines the debug configuration for gstreamer */ @@ -74,6 +80,10 @@ extern char* gst_debug; void log_init_time(void); +void log__time(long long *sec, long long *usec); + +bool log__have_time(void); + /* * Log-Functions * These functions pass a log-message to the log-subsystem. Handy helpers are diff --git a/src/uibc/meson.build b/src/uibc/meson.build index 17a06db..8620ba0 100644 --- a/src/uibc/meson.build +++ b/src/uibc/meson.build @@ -1,4 +1,3 @@ -m = c_compiler.find_library('m', required: false) executable('miracle-uibcctl', 'miracle-uibcctl.h', 'miracle-uibcctl.c', install: true, dependencies: [m, libmiracle_shared_dep] diff --git a/src/wifi/meson.build b/src/wifi/meson.build index e0176f4..c8eac31 100644 --- a/src/wifi/meson.build +++ b/src/wifi/meson.build @@ -9,6 +9,6 @@ miracle_wifid_src = ['wifid.h', executable('miracle-wifid', miracle_wifid_src, include_directories: inc, install: true, - dependencies: [udev, glib2, libsystemd, libmiracle_shared_dep] + dependencies: [udev, glib2, libsystemd, libmiracle_shared_dep, m] ) diff --git a/src/wifi/wifid.c b/src/wifi/wifid.c index 7a45b94..86fb3ff 100644 --- a/src/wifi/wifid.c +++ b/src/wifi/wifid.c @@ -482,6 +482,7 @@ static int help(void) " --version Show package version\n" " --log-level Maximum level for log messages\n" " --log-time Prefix log-messages with timestamp\n" + " --log-date-time Prefix log-messages with date time\n" "\n" " -i --interface Choose the interface to use\n" " --config-methods Define config methods for pairing, default 'pbc'\n" @@ -506,6 +507,7 @@ static int parse_argv(int argc, char *argv[]) ARG_VERSION = 0x100, ARG_LOG_LEVEL, ARG_LOG_TIME, + ARG_LOG_DATE_TIME, ARG_WPA_LOGLEVEL, ARG_WPA_SYSLOG, ARG_USE_DEV, @@ -514,10 +516,11 @@ static int parse_argv(int argc, char *argv[]) ARG_IP_BINARY, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, - { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "log-date-time", no_argument, NULL, ARG_LOG_DATE_TIME }, { "wpa-loglevel", required_argument, NULL, ARG_WPA_LOGLEVEL }, { "wpa-syslog", no_argument, NULL, ARG_WPA_SYSLOG }, @@ -546,6 +549,9 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_TIME: log_init_time(); break; + case ARG_LOG_DATE_TIME: + log_date_time = true; + break; case ARG_USE_DEV: use_dev = true; break; diff --git a/test/meson.build b/test/meson.build index 1514773..46400cf 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,5 +1,5 @@ check = dependency('check', required: false) -deps = [udev, glib2, check, libsystemd, libmiracle_shared_dep] +deps = [udev, glib2, check, libsystemd, libmiracle_shared_dep, m] if check.found() test_rtsp = executable('test_rtsp', 'test_rtsp.c', dependencies: deps) From 175495c729a91251898f733a1f88e3679f7365a4 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 29 Oct 2022 01:01:40 +0200 Subject: [PATCH 111/142] fix cmake dependencies for --- src/CMakeLists.txt | 1 + src/ctl/CMakeLists.txt | 2 ++ src/dhcp/CMakeLists.txt | 1 + src/uibc/CMakeLists.txt | 4 ++-- src/wifi/CMakeLists.txt | 1 + test/CMakeLists.txt | 1 + 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96fe570..7c4d9a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(uibc) set(miracled_SRCS miracled.h miracled.c) add_executable(miracled ${miracled_SRCS}) target_link_libraries(miracled miracle-shared) +target_link_libraries(miracled m) install(TARGETS miracled DESTINATION bin) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt index 837109f..8025da8 100644 --- a/src/ctl/CMakeLists.txt +++ b/src/ctl/CMakeLists.txt @@ -24,6 +24,7 @@ if(READLINE_FOUND) endif(READLINE_FOUND) target_link_libraries(miracle-wifictl miracle-shared) +target_link_libraries(miracle-wifictl m) target_link_libraries(miracle-wifictl ${GLIB2_LIBRARIES}) ########### next target ############### @@ -37,6 +38,7 @@ set(miracle-sinkctl_SRCS ctl.h add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS}) target_link_libraries(miracle-sinkctl ${GLIB2_LIBRARIES}) +target_link_libraries(miracle-sinkctl m) install(TARGETS miracle-sinkctl DESTINATION bin) diff --git a/src/dhcp/CMakeLists.txt b/src/dhcp/CMakeLists.txt index 7935d68..1e37819 100644 --- a/src/dhcp/CMakeLists.txt +++ b/src/dhcp/CMakeLists.txt @@ -19,6 +19,7 @@ pkg_check_modules (UDEV REQUIRED libudev) link_directories( ${UDEV_LIBRARY_DIRS}) include_directories( ${UDEV_INCLUDE_DIRS}) target_link_libraries(miracle-dhcp ${UDEV_LIBRARIES}) +target_link_libraries(miracle-dhcp m) link_directories( ${GLIB2_LIBRARY_DIRS}) include_directories( ${GLIB2_INCLUDE_DIRS}) target_link_libraries(miracle-dhcp ${GLIB2_LIBRARIES}) diff --git a/src/uibc/CMakeLists.txt b/src/uibc/CMakeLists.txt index ac81904..705b934 100644 --- a/src/uibc/CMakeLists.txt +++ b/src/uibc/CMakeLists.txt @@ -2,8 +2,8 @@ set(miracle-uibcctl_SRCS miracle-uibcctl.h miracle-uibcctl.c) add_executable(miracle-uibcctl ${miracle-uibcctl_SRCS}) -target_link_libraries(miracle-uibcctl PRIVATE miracle-shared) -target_link_libraries(miracle-uibcctl PUBLIC m) +target_link_libraries(miracle-uibcctl miracle-shared) +target_link_libraries(miracle-uibcctl m) install(TARGETS miracle-uibcctl DESTINATION bin) diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index 0dd7585..be6bf7f 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -23,6 +23,7 @@ pkg_check_modules (UDEV REQUIRED libudev) #link_directories( ${UDEV_LIBRARY_DIRS}) #include_directories( ${UDEV_INCLUDE_DIRS}) target_link_libraries(miracle-wifid ${UDEV_LIBRARIES}) +target_link_libraries(miracle-wifid m) link_directories( ${GLIB2_LIBRARY_DIRS}) include_directories( ${GLIB2_INCLUDE_DIRS}) target_link_libraries(miracle-wifid ${GLIB2_LIBRARIES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1363051..56bba94 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,6 +20,7 @@ if(CHECK_FOUND) target_link_libraries(test_wpas ${GLIB2_LIBRARIES}) target_link_libraries(test_wpas ${CHECK_LIBRARIES}) target_link_libraries(test_wpas ${CHECK_CFLAGS}) + target_link_libraries(test_wpas m) set(test_valgrind_SOURCES test_common.h test_valgrind.c) add_executable(test_valgrind ${test_valgrind_SOURCES}) From f740af265576783565f9dabd7b2b5b9f01ef10d9 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 29 Oct 2022 01:02:28 +0200 Subject: [PATCH 112/142] Clean cmake files --- src/CMakeLists.txt | 24 -------------- src/ctl/CMakeLists.txt | 41 ----------------------- src/dhcp/CMakeLists.txt | 36 -------------------- src/shared/CMakeLists.txt | 32 ------------------ src/wifi/CMakeLists.txt | 33 ------------------- test/CMakeLists.txt | 69 --------------------------------------- 6 files changed, 235 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c4d9a4..c049c12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,27 +13,3 @@ target_link_libraries(miracled m) install(TARGETS miracled DESTINATION bin) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) - - -########### install files ############### - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#SUBDIRS = shared wifi dhcp ctl -# -#bin_PROGRAMS = miracled -# -#miracled_SOURCES = \ -# miracled.h \ -# miracled.c -#miracled_CPPFLAGS = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) -#miracled_LDADD = \ -# shared/libmiracle-shared.la \ -# $(DEPS_LIBS) -# diff --git a/src/ctl/CMakeLists.txt b/src/ctl/CMakeLists.txt index 8025da8..234b343 100644 --- a/src/ctl/CMakeLists.txt +++ b/src/ctl/CMakeLists.txt @@ -4,7 +4,6 @@ link_directories( ${GLIB2_LIBRARY_DIRS}) include_directories( ${GLIB2_INCLUDE_DIRS}) find_package(Readline REQUIRED) pkg_check_modules (GLIB2 REQUIRED glib-2.0) -########### next target ############### set(miracle-wifictl_SRCS ctl.h ctl-cli.c @@ -26,7 +25,6 @@ endif(READLINE_FOUND) target_link_libraries(miracle-wifictl miracle-shared) target_link_libraries(miracle-wifictl m) target_link_libraries(miracle-wifictl ${GLIB2_LIBRARIES}) -########### next target ############### set(miracle-sinkctl_SRCS ctl.h ctl-cli.c @@ -53,42 +51,3 @@ endif(READLINE_FOUND) target_link_libraries(miracle-sinkctl miracle-shared) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) - -########### install files ############### - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#bin_PROGRAMS = miracle-wifictl miracle-sinkctl -# -#miracle_wifictl_SOURCES = \ -# ctl.h \ -# ctl-cli.c \ -# ctl-wifi.c \ -# wifictl.c -#miracle_wifictl_CPPFLAGS = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) -#miracle_wifictl_LDADD = \ -# ../shared/libmiracle-shared.la \ -# -lreadline \ -# $(DEPS_LIBS) -# -#miracle_sinkctl_SOURCES = \ -# ctl.h \ -# ctl-cli.c \ -# ctl-sink.c \ -# ctl-wifi.c \ -# sinkctl.c -#miracle_sinkctl_CPPFLAGS = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) -#miracle_sinkctl_LDADD = \ -# ../shared/libmiracle-shared.la \ -# -lreadline \ -# $(DEPS_LIBS) -# -# diff --git a/src/dhcp/CMakeLists.txt b/src/dhcp/CMakeLists.txt index 1e37819..7ae3e30 100644 --- a/src/dhcp/CMakeLists.txt +++ b/src/dhcp/CMakeLists.txt @@ -1,6 +1,3 @@ - -########### next target ############### - set(miracle-dhcp_SRCS dhcp.c gdhcp.h unaligned.h @@ -28,36 +25,3 @@ target_link_libraries(miracle-dhcp miracle-shared) install(TARGETS miracle-dhcp DESTINATION bin) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) - - -########### install files ############### - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#bin_PROGRAMS = miracle-dhcp -# -#miracle_dhcp_SOURCES = \ -# dhcp.c \ -# gdhcp.h \ -# unaligned.h \ -# common.h \ -# common.c \ -# ipv4ll.h \ -# ipv4ll.c \ -# client.c \ -# server.c -#miracle_dhcp_CPPFLAGS = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) \ -# $(GDHCP_CFLAGS) -#miracle_dhcp_LDADD = \ -# ../shared/libmiracle-shared.la \ -# $(DEPS_LIBS) \ -# $(GDHCP_LIBS) -# -# -# diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt index 7cbd283..2dea096 100644 --- a/src/shared/CMakeLists.txt +++ b/src/shared/CMakeLists.txt @@ -17,35 +17,3 @@ set(miracle-shared_SOURCES rtsp.h wpas.c) add_library(miracle-shared STATIC ${miracle-shared_SOURCES}) target_link_libraries (miracle-shared ${SESSION_LIBRARIES}) - - -########### install files ############### - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#noinst_LTLIBRARIES = libmiracle-shared.la -# -#libmiracle_shared_la_SOURCES = \ -# rtsp.h \ -# rtsp.c \ -# shl_dlist.h \ -# shl_htable.h \ -# shl_htable.c \ -# shl_log.h \ -# shl_log.c \ -# shl_macro.h \ -# shl_ring.h \ -# shl_ring.c \ -# shl_util.h \ -# shl_util.c \ -# util.h \ -# wpas.h \ -# wpas.c -#libmiracle_shared_la_LIBADD = -lsystemd -# -# -# diff --git a/src/wifi/CMakeLists.txt b/src/wifi/CMakeLists.txt index be6bf7f..5a997aa 100644 --- a/src/wifi/CMakeLists.txt +++ b/src/wifi/CMakeLists.txt @@ -1,6 +1,3 @@ - -########### next target ############### - set(miracle-wifid_SRCS wifid.h wifid.c wifid-dbus.c @@ -20,8 +17,6 @@ target_link_libraries(miracle-wifid miracle-shared) find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) -#link_directories( ${UDEV_LIBRARY_DIRS}) -#include_directories( ${UDEV_INCLUDE_DIRS}) target_link_libraries(miracle-wifid ${UDEV_LIBRARIES}) target_link_libraries(miracle-wifid m) link_directories( ${GLIB2_LIBRARY_DIRS}) @@ -30,31 +25,3 @@ target_link_libraries(miracle-wifid ${GLIB2_LIBRARIES}) install(TARGETS miracle-wifid DESTINATION bin) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) - -########### install files ############### - -#set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake-extensions/ ) - - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#bin_PROGRAMS = miracle-wifid -# -#miracle_wifid_SOURCES = \ -# wifid.h \ -# wifid.c \ -# wifid-dbus.c \ -# wifid-link.c \ -# wifid-peer.c \ -# wifid-supplicant.c -#miracle_wifid_CPPFLAGS = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) -#miracle_wifid_LDADD = \ -# ../shared/libmiracle-shared.la \ -# $(DEPS_LIBS) -# diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 56bba94..a896336 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,3 @@ - -########### next target ############### - find_package(PkgConfig) pkg_check_modules (CHECK check) @@ -51,69 +48,3 @@ if(CHECK_FOUND) COMMENT "verify memcheck") endif(CHECK_FOUND) - -########### install files ############### - - - - -#original Makefile.am contents follow: - -#include $(top_srcdir)/common.am -#tests = \ -# test_rtsp \ -# test_wpas -# -#if BUILD_HAVE_CHECK -#check_PROGRAMS = $(tests) test_valgrind -#TESTS = $(tests) test_valgrind -#MEMTESTS = $(tests) -#endif -# -#test_sources = \ -# test_common.h -#test_libs = \ -# ../src/shared/libmiracle-shared.la \ -# $(DEPS_LIBS) \ -# $(CHECK_LIBS) -#test_cflags = \ -# $(AM_CPPFLAGS) \ -# $(DEPS_CFLAGS) \ -# $(CHECK_CFLAGS) -# -#test_rtsp_SOURCES = test_rtsp.c $(test_sources) -#test_rtsp_CPPFLAGS = $(test_cflags) -#test_rtsp_LDADD = $(test_libs) -# -#test_valgrind_SOURCES = test_valgrind.c $(test_sources) -#test_valgrind_CPPFLAGS = $(test_cflags) -#test_valgrind_LDADD = $(test_libs) -# -#test_wpas_SOURCES = test_wpas.c $(test_sources) -#test_wpas_CPPFLAGS = $(test_cflags) -#test_wpas_LDADD = $(test_libs) -# -### custom recipes -# -#VALGRIND = CK_FORK=no valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --leak-resolution=high --error-exitcode=1 --suppressions=$(top_builddir)/test.supp -# -## verify that test_valgrind actually leaks data -#memcheck-verify: check -# $(AM_V_GEN)$(VALGRIND) --log-file=/dev/null ./test_valgrind >/dev/null ; test 1 = $$? -# -## run memcheck tests via valgrind -#memcheck: memcheck-verify -# $(AM_V_GEN)for i in $(MEMTESTS) ; do \ -# $(VALGRIND) --log-file=$(top_builddir)/$$i.memlog \ -# $(top_builddir)/$$i >/dev/null || (echo "memcheck failed on: $$i" ; exit 1) ; \ -# done -# -#distcheck-hook: memcheck -#AM_MAKEFLAGS = --no-print-directory -#AUTOMAKE_OPTIONS = color-tests -# -## -## Phony targets -## -# -#.PHONY: memcheck-verify From 42c5bda976039d27976515d41f8a73e4e1c5b3a7 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 29 Oct 2022 01:32:45 +0200 Subject: [PATCH 113/142] fix cmake CI --- cmake.Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake.Dockerfile b/cmake.Dockerfile index 4aebe91..240d90b 100644 --- a/cmake.Dockerfile +++ b/cmake.Dockerfile @@ -1,9 +1,9 @@ FROM docker.io/albfan/miraclecast-ci -COPY . ./ +RUN mkdir src -RUN rm -rf build-cmake; \ - mkdir build-cmake; \ - cd build-cmake; \ - cmake ..; \ - make +COPY . ./src + +WORKDIR src + +RUN cmake -Bbuild . && make -C build From 7135a99e712f859e414222a3fe69a65ae593fd72 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 29 Oct 2022 22:42:43 +0200 Subject: [PATCH 114/142] Call script helpers from any path --- res/kill-wpa.sh | 4 +++- res/normal-wifi.sh | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/res/kill-wpa.sh b/res/kill-wpa.sh index 2485163..0f92662 100755 --- a/res/kill-wpa.sh +++ b/res/kill-wpa.sh @@ -1,6 +1,8 @@ #!/bin/bash -. miracle-utils.sh +DIRNAME=$(dirname $0) + +. $DIRNAME/miracle-utils.sh kill_network_manager diff --git a/res/normal-wifi.sh b/res/normal-wifi.sh index c6a2871..e8768c1 100755 --- a/res/normal-wifi.sh +++ b/res/normal-wifi.sh @@ -1,7 +1,9 @@ #!/bin/bash -. miracle-utils.sh +DIRNAME=$(dirname $0) -./kill-wpa.sh +. $DIRNAME/miracle-utils.sh + +./$DIRNAME/kill-wpa.sh start_network_manager From 8cd144271a8c38e96487e9fc60b1d5db3f5b9bc7 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 30 Oct 2022 01:28:28 +0200 Subject: [PATCH 115/142] log messages with time in human readable way --- src/ctl/wifictl.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index d862b9c..35f0f95 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -481,6 +481,8 @@ void cli_fn_help() " --help-commands Show available commands\n" " --version Show package version\n" " --log-level Maximum level for log messages\n" + " --log-time Prefix log-messages with timestamp\n" + " --log-date-time Prefix log-messages with date time\n" " --log-journal-level Maximum level for journal log messages\n" "\n" "Commands:\n" @@ -557,14 +559,18 @@ static int parse_argv(int argc, char *argv[]) enum { ARG_VERSION = 0x100, ARG_LOG_LEVEL, + ARG_LOG_TIME, + ARG_LOG_DATE_TIME, ARG_JOURNAL_LEVEL, ARG_HELP_COMMANDS, }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, + { "help", no_argument, NULL, 'h' }, { "help-commands", no_argument, NULL, ARG_HELP_COMMANDS }, - { "version", no_argument, NULL, ARG_VERSION }, - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "version", no_argument, NULL, ARG_VERSION }, + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-time", no_argument, NULL, ARG_LOG_TIME }, + { "log-date-time", no_argument, NULL, ARG_LOG_DATE_TIME }, { "log-journal-level", required_argument, NULL, ARG_JOURNAL_LEVEL }, {} }; @@ -583,6 +589,12 @@ static int parse_argv(int argc, char *argv[]) case ARG_LOG_LEVEL: cli_max_sev = log_parse_arg(optarg); break; + case ARG_LOG_TIME: + log_init_time(); + break; + case ARG_LOG_DATE_TIME: + log_date_time = true; + break; case ARG_JOURNAL_LEVEL: log_max_sev = log_parse_arg(optarg); break; From f9a61faaa29ede4de92de06dd42a21bb9efc5911 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 8 Nov 2022 08:34:45 +0100 Subject: [PATCH 116/142] Do not prefix command output with time --- src/ctl/ctl-cli.c | 55 +++++++++++++++++++++++------------ src/ctl/ctl.h | 4 ++- src/ctl/sinkctl.c | 60 +++++++++++++++++++------------------- src/ctl/wifictl.c | 74 +++++++++++++++++++++++------------------------ 4 files changed, 106 insertions(+), 87 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 654b434..3e77921 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -57,7 +57,7 @@ static bool is_cli(void) return cli_rl; } -void cli_printv(const char *fmt, va_list args) +void cli_printv(const char *fmt, bool prefix_time, va_list args) { SHL_PROTECT_ERRNO; _shl_free_ char *line = NULL; @@ -76,6 +76,22 @@ void cli_printv(const char *fmt, va_list args) rl_redisplay(); } + if (prefix_time) { + cli_printf_time_prefix(); + } + + vprintf(fmt, args); + + if (async) { + rl_restore_prompt(); + rl_replace_line(line, 0); + rl_point = point; + rl_redisplay(); + } +} + +void cli_printf_time_prefix(const char *fmt, va_list args) +{ long long sec, usec; time_t now; struct tm *timeinfo; @@ -106,15 +122,16 @@ void cli_printv(const char *fmt, va_list args) printf("[%s] ", buffer); else if (log__have_time()) printf("[%.4lld.%.6lld] ", sec, usec); +} - vprintf(fmt, args); +void cli_command_printf(const char *fmt, ...) +{ + SHL_PROTECT_ERRNO; + va_list args; - if (async) { - rl_restore_prompt(); - rl_replace_line(line, 0); - rl_point = point; - rl_redisplay(); - } + va_start(args, fmt); + cli_printv(fmt, false, args); + va_end(args); } void cli_printf(const char *fmt, ...) @@ -123,7 +140,7 @@ void cli_printf(const char *fmt, ...) va_list args; va_start(args, fmt); - cli_printv(fmt, args); + cli_printv(fmt, true, args); va_end(args); } @@ -131,7 +148,7 @@ int cli_help(const struct cli_cmd *cmds, int whitespace) { unsigned int i; - cli_printf("Available commands:\n"); + cli_command_printf("Available commands:\n"); for (i = 0; cmds[i].cmd; ++i) { if (!cmds[i].desc) @@ -141,11 +158,11 @@ int cli_help(const struct cli_cmd *cmds, int whitespace) if (!is_cli() && cmds[i].cli_cmp == CLI_Y) continue; - cli_printf(" %s %-*s %s\n", - cmds[i].cmd, - (int)(whitespace - strlen(cmds[i].cmd)), - cmds[i].args ? : "", - cmds[i].desc ? : ""); + cli_command_printf(" %s %-*s %s\n", + cmds[i].cmd, + (int)(whitespace - strlen(cmds[i].cmd)), + cmds[i].args ? : "", + cmds[i].desc ? : ""); } return 0; @@ -174,21 +191,21 @@ int cli_do(const struct cli_cmd *cmds, char **args, unsigned int n) switch (cmds[i].argc_cmp) { case CLI_EQUAL: if (n != cmds[i].argc) { - cli_printf("Invalid number of arguments\n"); + cli_command_printf("Invalid number of arguments\n"); return -EINVAL; } break; case CLI_MORE: if (n < cmds[i].argc) { - cli_printf("too few arguments\n"); + cli_command_printf("too few arguments\n"); return -EINVAL; } break; case CLI_LESS: if (n > cmds[i].argc) { - cli_printf("too many arguments\n"); + cli_command_printf("too many arguments\n"); return -EINVAL; } @@ -234,7 +251,7 @@ static void cli_handler_fn(char *input) if (r != -EAGAIN) return; - cli_printf("Command not found\n"); + cli_command_printf("Command not found\n"); } static int cli_stdin_fn(sd_event_source *source, diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 02220bc..2ddf8fb 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -123,8 +123,10 @@ bool ctl_sink_is_closed(struct ctl_sink *s); /* CLI handling */ extern unsigned int cli_max_sev; -void cli_printv(const char *fmt, va_list args); +void cli_printv(const char *fmt, bool prefix_time, va_list args); +void cli_printf_time_prefix(); void cli_printf(const char *fmt, ...); +void cli_command_printf(const char *fmt, ...); #define cli_log(_fmt, ...) \ cli_printf(_fmt "\n", ##__VA_ARGS__) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 9781bc6..93a1bc9 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -91,28 +91,28 @@ static int cmd_list(char **args, unsigned int n) /* list links */ - cli_printf("%6s %-24s %-30s %-10s\n", - "LINK", "INTERFACE", "FRIENDLY-NAME", "MANAGED"); + cli_command_printf("%6s %-24s %-30s %-10s\n", + "LINK", "INTERFACE", "FRIENDLY-NAME", "MANAGED"); shl_dlist_for_each(i, &wifi->links) { l = link_from_dlist(i); ++link_cnt; - cli_printf("%6s %-24s %-30s %-10s\n", - l->label, - shl_isempty(l->ifname) ? - "" : l->ifname, + cli_command_printf("%6s %-24s %-30s %-10s\n", + l->label, + shl_isempty(l->ifname) ? + "" : l->ifname, shl_isempty(l->friendly_name) ? "" : l->friendly_name, l->managed ? "yes": "no"); } - cli_printf("\n"); + cli_command_printf("\n"); /* list peers */ - cli_printf("%6s %-24s %-30s %-10s\n", - "LINK", "PEER-ID", "FRIENDLY-NAME", "CONNECTED"); + cli_command_printf("%6s %-24s %-30s %-10s\n", + "LINK", "PEER-ID", "FRIENDLY-NAME", "CONNECTED"); shl_dlist_for_each(i, &wifi->links) { l = link_from_dlist(i); @@ -121,16 +121,16 @@ static int cmd_list(char **args, unsigned int n) p = peer_from_dlist(j); ++peer_cnt; - cli_printf("%6s %-24s %-30s %-10s\n", - p->l->label, - p->label, - shl_isempty(p->friendly_name) ? + cli_command_printf("%6s %-24s %-30s %-10s\n", + p->l->label, + p->label, + shl_isempty(p->friendly_name) ? "" : p->friendly_name, p->connected ? "yes" : "no"); } } - cli_printf("\n %u peers and %u links listed.\n", peer_cnt, link_cnt); + cli_command_printf("\n %u peers and %u links listed.\n", peer_cnt, link_cnt); return 0; } @@ -155,34 +155,34 @@ static int cmd_show(char **args, unsigned int n) } if (l) { - cli_printf("Link=%s\n", l->label); + cli_command_printf("Link=%s\n", l->label); if (l->ifindex > 0) - cli_printf("InterfaceIndex=%u\n", l->ifindex); + cli_command_printf("InterfaceIndex=%u\n", l->ifindex); if (l->ifname && *l->ifname) - cli_printf("InterfaceName=%s\n", l->ifname); + cli_command_printf("InterfaceName=%s\n", l->ifname); if (l->friendly_name && *l->friendly_name) - cli_printf("FriendlyName=%s\n", l->friendly_name); - cli_printf("P2PScanning=%d\n", l->p2p_scanning); + cli_command_printf("FriendlyName=%s\n", l->friendly_name); + cli_command_printf("P2PScanning=%d\n", l->p2p_scanning); if (l->wfd_subelements && *l->wfd_subelements) - cli_printf("WfdSubelements=%s\n", l->wfd_subelements); - cli_printf("Managed=%d\n", l->managed); + cli_command_printf("WfdSubelements=%s\n", l->wfd_subelements); + cli_command_printf("Managed=%d\n", l->managed); } else if (p) { - cli_printf("Peer=%s\n", p->label); + cli_command_printf("Peer=%s\n", p->label); if (p->p2p_mac && *p->p2p_mac) - cli_printf("P2PMac=%s\n", p->p2p_mac); + cli_command_printf("P2PMac=%s\n", p->p2p_mac); if (p->friendly_name && *p->friendly_name) - cli_printf("FriendlyName=%s\n", p->friendly_name); - cli_printf("Connected=%d\n", p->connected); + cli_command_printf("FriendlyName=%s\n", p->friendly_name); + cli_command_printf("Connected=%d\n", p->connected); if (p->interface && *p->interface) - cli_printf("Interface=%s\n", p->interface); + cli_command_printf("Interface=%s\n", p->interface); if (p->local_address && *p->local_address) - cli_printf("LocalAddress=%s\n", p->local_address); + cli_command_printf("LocalAddress=%s\n", p->local_address); if (p->remote_address && *p->remote_address) - cli_printf("RemoteAddress=%s\n", p->remote_address); + cli_command_printf("RemoteAddress=%s\n", p->remote_address); if (p->wfd_subelements && *p->wfd_subelements) - cli_printf("WfdSubelements=%s\n", p->wfd_subelements); + cli_command_printf("WfdSubelements=%s\n", p->wfd_subelements); } else { - cli_printf("Show what?\n"); + cli_command_printf("Show what?\n"); return 0; } diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 35f0f95..5b511fb 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -52,27 +52,27 @@ static int cmd_list(char **args, unsigned int n) /* list links */ - cli_printf("%6s %-24s %-30s %-10s\n", + cli_command_printf("%6s %-24s %-30s %-10s\n", "LINK", "INTERFACE", "FRIENDLY-NAME", "MANAGED"); shl_dlist_for_each(i, &wifi->links) { l = link_from_dlist(i); ++link_cnt; - cli_printf("%6s %-24s %-30s %-10s\n", - l->label, - shl_isempty(l->ifname) ? - "" : l->ifname, - shl_isempty(l->friendly_name) ? - "" : l->friendly_name, - l->managed ? "yes": "no"); + cli_command_printf("%6s %-24s %-30s %-10s\n", + l->label, + shl_isempty(l->ifname) ? + "" : l->ifname, + shl_isempty(l->friendly_name) ? + "" : l->friendly_name, + l->managed ? "yes": "no"); } - cli_printf("\n"); + cli_command_printf("\n"); /* list peers */ - cli_printf("%6s %-24s %-30s %-10s\n", + cli_command_printf("%6s %-24s %-30s %-10s\n", "LINK", "PEER-ID", "FRIENDLY-NAME", "CONNECTED"); shl_dlist_for_each(i, &wifi->links) { @@ -82,16 +82,16 @@ static int cmd_list(char **args, unsigned int n) p = peer_from_dlist(j); ++peer_cnt; - cli_printf("%6s %-24s %-30s %-10s\n", - p->l->label, - p->label, - shl_isempty(p->friendly_name) ? - "" : p->friendly_name, - p->connected ? "yes" : "no"); + cli_command_printf("%6s %-24s %-30s %-10s\n", + p->l->label, + p->label, + shl_isempty(p->friendly_name) ? + "" : p->friendly_name, + p->connected ? "yes" : "no"); } } - cli_printf("\n %u peers and %u links listed.\n", peer_cnt, link_cnt); + cli_command_printf("\n %u peers and %u links listed.\n", peer_cnt, link_cnt); return 0; } @@ -148,34 +148,34 @@ static int cmd_show(char **args, unsigned int n) } if (l) { - cli_printf("Link=%s\n", l->label); + cli_command_printf("Link=%s\n", l->label); if (l->ifindex > 0) - cli_printf("InterfaceIndex=%u\n", l->ifindex); + cli_command_printf("InterfaceIndex=%u\n", l->ifindex); if (l->ifname && *l->ifname) - cli_printf("InterfaceName=%s\n", l->ifname); + cli_command_printf("InterfaceName=%s\n", l->ifname); if (l->friendly_name && *l->friendly_name) - cli_printf("FriendlyName=%s\n", l->friendly_name); - cli_printf("P2PScanning=%d\n", l->p2p_scanning); + cli_command_printf("FriendlyName=%s\n", l->friendly_name); + cli_command_printf("P2PScanning=%d\n", l->p2p_scanning); if (l->wfd_subelements && *l->wfd_subelements) - cli_printf("WfdSubelements=%s\n", l->wfd_subelements); - cli_printf("Managed=%d\n", l->managed); + cli_command_printf("WfdSubelements=%s\n", l->wfd_subelements); + cli_command_printf("Managed=%d\n", l->managed); } else if (p) { - cli_printf("Peer=%s\n", p->label); + cli_command_printf("Peer=%s\n", p->label); if (p->p2p_mac && *p->p2p_mac) - cli_printf("P2PMac=%s\n", p->p2p_mac); + cli_command_printf("P2PMac=%s\n", p->p2p_mac); if (p->friendly_name && *p->friendly_name) - cli_printf("FriendlyName=%s\n", p->friendly_name); - cli_printf("Connected=%d\n", p->connected); + cli_command_printf("FriendlyName=%s\n", p->friendly_name); + cli_command_printf("Connected=%d\n", p->connected); if (p->interface && *p->interface) - cli_printf("Interface=%s\n", p->interface); + cli_command_printf("Interface=%s\n", p->interface); if (p->local_address && *p->local_address) - cli_printf("LocalAddress=%s\n", p->local_address); + cli_command_printf("LocalAddress=%s\n", p->local_address); if (p->remote_address && *p->remote_address) - cli_printf("RemoteAddress=%s\n", p->remote_address); + cli_command_printf("RemoteAddress=%s\n", p->remote_address); if (p->wfd_subelements && *p->wfd_subelements) - cli_printf("WfdSubelements=%s\n", p->wfd_subelements); + cli_command_printf("WfdSubelements=%s\n", p->wfd_subelements); } else { - cli_printf("Show what?\n"); + cli_command_printf("Show what?\n"); return 0; } @@ -192,7 +192,7 @@ static int cmd_set_friendly_name(char **args, unsigned int n) const char *name; if (n < 1) { - cli_printf("To what?\n"); + cli_command_printf("To what?\n"); return 0; } @@ -228,7 +228,7 @@ static int cmd_set_managed(char **args, unsigned int n) bool managed = true; if (n < 1) { - cli_printf("To what?\n"); + cli_command_printf("To what?\n"); return 0; } @@ -310,7 +310,7 @@ static int cmd_connect(char **args, unsigned int n) const char *prov, *pin; if (n < 1) { - cli_printf("To whom?\n"); + cli_command_printf("To whom?\n"); return 0; } @@ -353,7 +353,7 @@ static int cmd_disconnect(char **args, unsigned int n) struct ctl_peer *p; if (n < 1) { - cli_printf("From whom?\n"); + cli_command_printf("From whom?\n"); return 0; } From c215f05d5d93a6663935056ccb5df40d87fbf39e Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 8 Nov 2022 08:42:05 +0100 Subject: [PATCH 117/142] Exit CLI if daemon is not available --- src/ctl/ctl-sink.c | 3 ++- src/ctl/sinkctl.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index aeb59bf..a613434 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -566,7 +566,8 @@ void ctl_sink_free(struct ctl_sink *s) free(s->session); free(s->url); sd_event_unref(s->event); - g_hash_table_destroy(s->protocol_extensions); + if (s->protocol_extensions) + g_hash_table_destroy(s->protocol_extensions); free(s); } diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 93a1bc9..e2167de 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -764,7 +764,9 @@ static int ctl_interactive(char **argv, int argc) goto error; sink->protocol_extensions = protocol_extensions; - ctl_wifi_fetch(wifi); + r = ctl_wifi_fetch(wifi); + if (r < 0) + goto error; if (argc > 0) { r = cli_do(cli_cmds, argv, argc); From 20816ad138c7072fff46bfa76915d1861317766f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Tue, 8 Nov 2022 08:49:54 +0100 Subject: [PATCH 118/142] Add command friendly-name to sink controller --- src/ctl/sinkctl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e2167de..eb932aa 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -189,6 +189,41 @@ static int cmd_show(char **args, unsigned int n) return 0; } +/* + * cmd: set-friendly-name + */ + +static int cmd_set_friendly_name(char **args, unsigned int n) +{ + struct ctl_link *l = NULL; + const char *name; + + if (n < 1) { + cli_command_printf("To what?\n"); + return 0; + } + + if (n > 1) { + l = ctl_wifi_search_link(wifi, args[0]); + if (!l) { + cli_error("unknown link %s", args[0]); + return 0; + } + + name = args[1]; + } else { + name = args[0]; + } + + l = l ? : running_link; + if (!l) { + cli_error("no running link"); + return 0; + } + + return ctl_link_set_friendly_name(l, name); +} + /* * cmd: run */ @@ -381,6 +416,7 @@ static const struct cli_cmd cli_cmds[] = { { "show", "", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information" }, { "run", "", CLI_M, CLI_EQUAL, 1, cmd_run, "Run sink on given link" }, { "bind", "", CLI_M, CLI_EQUAL, 1, cmd_bind, "Like 'run' but bind the link name to run when it is hotplugged" }, + { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object" }, { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link" }, { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program" }, { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL }, From 788d37d7d27dbf6c26cb82ecafe48525504fa810 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 13 Nov 2022 11:29:16 +0100 Subject: [PATCH 119/142] CLI commands autocompletion --- src/ctl/ctl-cli.c | 321 +++++++++++++++++++++++++++++++++++++++++++++- src/ctl/ctl.h | 13 ++ src/ctl/sinkctl.c | 37 ++++-- src/ctl/wifictl.c | 38 ++++-- 4 files changed, 386 insertions(+), 23 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 3e77921..15ce621 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -36,9 +36,6 @@ #include #include -/* *sigh* readline doesn't include all their deps, so put them last */ -#include -#include /* * Helpers for interactive commands @@ -246,7 +243,10 @@ static void cli_handler_fn(char *input) else if (!r) return; - add_history(original); + if (!(strcmp(original, "quit") == 0 || strcmp(original, "exit") == 0)) { + add_history(original); + write_history(get_history_filename()); + } r = cli_do(cli_cmds, args, r); if (r != -EAGAIN) return; @@ -325,6 +325,315 @@ void cli_destroy(void) cli_event = NULL; } +char *yes_no_options[] = {"yes", "no", NULL}; + +char * +yes_no_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + /* Return the next name which partially matches from the command list. */ + while (name = yes_no_options[list_index]) + { + list_index++; + + if (strncmp (name, text, len) == 0) + return (strdup(name)); + } + + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +char * +links_peers_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + size_t peer_cnt = 0; + size_t link_cnt = 0; + struct shl_dlist *i, *j; + struct ctl_link *l; + struct ctl_peer *p; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + shl_dlist_for_each(i, &get_wifi()->links) { + l = link_from_dlist(i); + + char *name = l->label; + if (strncmp (name, text, len) == 0) + { + if (link_cnt == list_index) + { + list_index++; + return strdup(name); + } + link_cnt++; + } + + name = l->friendly_name; + if (!shl_isempty(name)) + { + if (strncmp (name, text, len) == 0) + { + if (link_cnt == list_index) + { + list_index++; + return strdup(name); + } + link_cnt++; + } + } + } + + peer_cnt = link_cnt; + + shl_dlist_for_each(i, &get_wifi()->links) { + l = link_from_dlist(i); + + shl_dlist_for_each(j, &l->peers) { + p = peer_from_dlist(j); + char *name = p->label; + if (strncmp (name, text, len) == 0) + { + if (peer_cnt == list_index) + { + list_index++; + return strdup(name); + } + peer_cnt++; + } + name = p->friendly_name; + if (!shl_isempty(name)) + { + if (strncmp (name, text, len) == 0) + { + if (peer_cnt == list_index) + { + list_index++; + return strdup(name); + } + peer_cnt++; + } + } + } + } + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +char * +peers_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + size_t peer_cnt = 0; + struct shl_dlist *i, *j; + struct ctl_link *l; + struct ctl_peer *p; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + shl_dlist_for_each(i, &get_wifi()->links) { + l = link_from_dlist(i); + + shl_dlist_for_each(j, &l->peers) { + p = peer_from_dlist(j); + char *name = p->label; + if (strncmp (name, text, len) == 0) + { + if (peer_cnt == list_index) + { + list_index++; + return strdup(name); + } + peer_cnt++; + } + name = p->friendly_name; + if (!shl_isempty(name)) + { + if (strncmp (name, text, len) == 0) + { + if (peer_cnt == list_index) + { + list_index++; + return strdup(name); + } + peer_cnt++; + } + } + } + } + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +char * +links_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + size_t link_cnt = 0; + struct shl_dlist *i; + struct ctl_link *l; + + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + shl_dlist_for_each(i, &get_wifi()->links) { + l = link_from_dlist(i); + + + char *name = l->label; + if (strncmp (name, text, len) == 0) + { + if (link_cnt == list_index) + { + list_index++; + return strdup(name); + } + link_cnt++; + } + name = l->friendly_name; + if (!shl_isempty(name)) + { + if (strncmp (name, text, len) == 0) + { + if (link_cnt == list_index) + { + list_index++; + return strdup(name); + } + link_cnt++; + } + } + } + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +/* Generator function for command completion. STATE lets us know whether + * to start from scratch; without any state (i.e. STATE == 0), then we + * start at the top of the list. + */ + +char * +command_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + /* Return the next name which partially matches from the command list. */ + while (name = cli_cmds[list_index].cmd) + { + list_index++; + + if (strncmp (name, text, len) == 0) + return (strdup(name)); + } + + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +int get_args(char* line) +{ + char* tmp = line; + char* last_delim = tmp; + int count = 0; + + /* Count how many elements will be extracted. */ + while (*tmp) + { + if (' ' == *tmp) + { + if (last_delim+1 < tmp) + count++; + last_delim = tmp; + } + tmp++; + } + if (" " != *last_delim) + count++; + return count; +} + +/* + * Attempt to complete on the contents of TEXT. START and END bound the + * region of rl_line_buffer that contains the word to complete. TEXT is + * the word to complete. We can use the entire contents of rl_line_buffer + * in case we want to do some simple parsing. Return the array of matches, + * or NULL if there aren't any. + */ +char ** +completion_fn (const char *text, int start, int end) +{ + char **matches; + + rl_attempted_completion_over = 1; + if (start == 0) + matches = rl_completion_matches (text, command_generator); + else + { + matches = (char **)NULL; + struct cli_cmd cmd; + int cmd_pos = 0; + while ((cmd = cli_cmds[cmd_pos++]).cmd) + { + if (strncmp(cmd.cmd, rl_line_buffer, strlen(cmd.cmd)) == 0) + { + int nargs = get_args(rl_line_buffer); + rl_compentry_func_t* completion_fn = cmd.completion_fns[nargs-2]; + if (completion_fn) + matches = rl_completion_matches (text, completion_fn); + } + } + } + + return (matches); +} + int cli_init(sd_bus *bus, const struct cli_cmd *cmds) { static const int sigs[] = { @@ -382,7 +691,11 @@ int cli_init(sd_bus *bus, const struct cli_cmd *cmds) cli_rl = true; rl_erase_empty_line = 1; + rl_attempted_completion_function = completion_fn; rl_callback_handler_install(NULL, cli_handler_fn); + using_history(); + read_history(get_history_filename()); + rl_end_of_history(0, 0); rl_set_prompt(CLI_PROMPT); printf("\r"); diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 2ddf8fb..69b0db8 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -29,6 +29,11 @@ #include "shl_dlist.h" #include "shl_log.h" +/* *sigh* readline doesn't include all their deps, so put them last */ +#include +#include +#include + #ifndef CTL_CTL_H #define CTL_CTL_H @@ -36,6 +41,13 @@ struct ctl_wifi; struct ctl_link; struct ctl_peer; +char* get_history_filename (); +struct ctl_wifi * get_wifi (); +char * links_peers_generator (const char *text, int state); +char * links_generator (const char *text, int state); +char * peers_generator (const char *text, int state); +char * yes_no_generator (const char *text, int state); + /* wifi handling */ struct ctl_peer { @@ -209,6 +221,7 @@ struct cli_cmd { int argc; int (*fn) (char **args, unsigned int n); const char *desc; + rl_compentry_func_t *completion_fns[2]; }; extern sd_event *cli_event; diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index eb932aa..fde3e9f 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -47,6 +47,10 @@ #include "util.h" #include "config.h" +#include + +#define HISTORY_FILENAME ".miracle-sink.history" + static sd_bus *bus; static struct ctl_wifi *wifi; static struct ctl_sink *sink; @@ -78,6 +82,21 @@ unsigned int wfd_supported_res_cea = 0x0001ffff; unsigned int wfd_supported_res_vesa = 0x1fffffff; unsigned int wfd_supported_res_hh = 0x00001fff; +struct ctl_wifi *get_wifi() +{ + return wifi; +} + + +/* + * get history filename + */ + +char* get_history_filename() +{ + return HISTORY_FILENAME; +} + /* * cmd list */ @@ -412,15 +431,15 @@ static int sink_timeout_fn(sd_event_source *s, uint64_t usec, void *data) } static const struct cli_cmd cli_cmds[] = { - { "list", NULL, CLI_M, CLI_LESS, 0, cmd_list, "List all objects" }, - { "show", "", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information" }, - { "run", "", CLI_M, CLI_EQUAL, 1, cmd_run, "Run sink on given link" }, - { "bind", "", CLI_M, CLI_EQUAL, 1, cmd_bind, "Like 'run' but bind the link name to run when it is hotplugged" }, - { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object" }, - { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link" }, - { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program" }, - { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL }, - { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help" }, + { "list", NULL, CLI_M, CLI_LESS, 0, cmd_list, "List all objects", {NULL} }, + { "show", "", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information", {links_peers_generator, NULL} }, + { "run", "", CLI_M, CLI_EQUAL, 1, cmd_run, "Run sink on given link", {links_generator, NULL} }, + { "bind", "", CLI_M, CLI_EQUAL, 1, cmd_bind, "Like 'run' but bind the link name to run when it is hotplugged", {links_generator, NULL} }, + { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object", {links_generator, NULL} }, + { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link", {links_generator, yes_no_generator, NULL} }, + { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program", {NULL} }, + { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL, {NULL} }, + { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help", {NULL} }, { }, }; diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 5b511fb..9720b75 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -34,11 +34,29 @@ #include "util.h" #include "config.h" +#include + +#define HISTORY_FILENAME ".miracle-wifi.history" + static sd_bus *bus; static struct ctl_wifi *wifi; static struct ctl_link *selected_link; +/* + * get history filename + */ + +char* get_history_filename() +{ + return HISTORY_FILENAME; +} + +struct ctl_wifi *get_wifi() +{ + return wifi; +} + /* * cmd list */ @@ -386,17 +404,17 @@ static int cmd_quit(char **args, unsigned int n) */ static const struct cli_cmd cli_cmds[] = { - { "list", NULL, CLI_M, CLI_LESS, 0, cmd_list, "List all objects" }, - { "select", "[link]", CLI_Y, CLI_LESS, 1, cmd_select, "Select default link" }, - { "show", "[link|peer]", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information" }, - { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object" }, + { "list", NULL, CLI_M, CLI_LESS, 0, cmd_list, "List all objects", {NULL}}, + { "select", "[link]", CLI_Y, CLI_LESS, 1, cmd_select, "Select default link", {links_generator, NULL} }, + { "show", "[link|peer]", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information", {links_peers_generator, NULL} }, + { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object", {links_generator, yes_no_generator, NULL} }, { "set-managed", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_managed, "Manage or unmnage a link" }, - { "p2p-scan", "[link] [stop]", CLI_Y, CLI_LESS, 2, cmd_p2p_scan, "Control neighborhood P2P scanning" }, - { "connect", " [provision] [pin]", CLI_M, CLI_LESS, 3, cmd_connect, "Connect to peer" }, - { "disconnect", "", CLI_M, CLI_EQUAL, 1, cmd_disconnect, "Disconnect from peer" }, - { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program" }, - { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL }, - { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help" }, + { "p2p-scan", "[link] [stop]", CLI_Y, CLI_LESS, 2, cmd_p2p_scan, "Control neighborhood P2P scanning", {links_generator, NULL} }, + { "connect", " [provision] [pin]", CLI_M, CLI_LESS, 3, cmd_connect, "Connect to peer", {peers_generator, NULL} }, + { "disconnect", "", CLI_M, CLI_EQUAL, 1, cmd_disconnect, "Disconnect from peer", {peers_generator, NULL} }, + { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program", {NULL} }, + { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL , {NULL}}, + { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help" , {NULL} }, { }, }; From 66c86f2971c0ef6dd0f1604f6beb91404b73039f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Mon, 14 Nov 2022 07:12:00 +0100 Subject: [PATCH 120/142] fix memory error settting wfd_video_formats --- src/ctl/ctl-sink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index a613434..bb592b3 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -98,12 +98,13 @@ static void sink_handle_get_parameter(struct ctl_sink *s, } } if (wfd_video_formats == NULL) { - char video_formats[128]; + gchar video_formats[128]; sprintf(video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); - wfd_video_formats = video_formats; + wfd_video_formats = strdup(video_formats); } check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); + g_free(wfd_video_formats); /* wfd_audio_codecs */ gchar* wfd_audio_codecs = "AAC 00000007 00"; From 314aa5aed59b3500e8385f408ab523e190cba0ad Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 9 Nov 2022 00:12:03 +0100 Subject: [PATCH 121/142] Use default rstp port --- res/gstplayer | 2 +- res/test-viewer.sh | 2 +- src/ctl/sinkctl.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/gstplayer b/res/gstplayer index 2cbbb9b..f048e6a 100755 --- a/res/gstplayer +++ b/res/gstplayer @@ -204,7 +204,7 @@ if __name__ == '__main__': parser.add_argument("uri", nargs="?", help="Uri to play") parser.add_argument("-v", "--version", help="Show package version") parser.add_argument("--log-level", metavar="lvl", help="Maximum level for log messages") - parser.add_argument("-p", "--port", type=int, default=1991, help="Port for rtsp") + parser.add_argument("-p", "--port", type=int, default=7236, help="Port for rtsp") parser.add_argument("-a", "--audio", dest="audio", action="store_true", help="Enable audio support") parser.add_argument("-s", "--scale", metavar="WxH", help="Scale to resolution") parser.add_argument("-d", "--debug", help="Debug") diff --git a/res/test-viewer.sh b/res/test-viewer.sh index 38bd83a..914012c 100755 --- a/res/test-viewer.sh +++ b/res/test-viewer.sh @@ -35,7 +35,7 @@ Try installing packages "gst-plugins-bad, gst-plugins-base, gst-plugins-base-lib If that fails too, try: -$ vlc rtp://@:1991 +$ vlc rtp://@:7236 EOF else diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index fde3e9f..8f0e0c8 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -69,7 +69,7 @@ void launch_player(struct ctl_sink *s); char *gst_scale_res; int gst_audio_en = 1; -static const int DEFAULT_RSTP_PORT = 1991; +static const int DEFAULT_RSTP_PORT = 7236; bool uibc_option; bool uibc_enabled; bool external_player; From abc9b2f92cca7fbdb6259eb00d87eb030a73c50f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Wed, 9 Nov 2022 02:35:01 +0100 Subject: [PATCH 122/142] set wfd elements on source selected --- src/ctl/.ctl-sink.c.swo | Bin 0 -> 32768 bytes src/ctl/wifictl.c | 1 + 2 files changed, 1 insertion(+) create mode 100644 src/ctl/.ctl-sink.c.swo diff --git a/src/ctl/.ctl-sink.c.swo b/src/ctl/.ctl-sink.c.swo new file mode 100644 index 0000000000000000000000000000000000000000..7736518bf28c51337843b3c2cbe72d477c9a781d GIT binary patch literal 32768 zcmeI43veVyd4LxufMxq^0tt_@34LpKyv9&&s8Xuixw4b98{SZ(o*T+}WnpWh zR6RJDd;Bz$5Qzj532ZT4{b-!2Pm{QtrF|FKh2sZYb*a5cOf&V~n1PNi;vLvR&r zhle+%Qn$kqco_`B0~iXv3*Ujy!aeXA_!xW`J_H5G!&XRxg6F}HPE4ilh0np8;X1e$ zvM>f)VE~>AzdnI7!pGnicsslrvM>X~@O(HKHo-4?QmOC5{qT?Qez*y)fxm<+pakP^ zHvB0(9scL|RO(Uq4!jF)gCblGyI~y0pa&knSaLtS4{n8b!V+8t6EF_F@B@q{x5BlM zhx6bb3?XlXOJNFj!E@jj7*KA2J@72p1b5SB(r)j8Ww;o=g48+VjJg3-tTvZz+kWm#Tm3EQYq2nDM`ss{_i$f?l2s5t9wU#I5 z<}!7OB%-OS3)FC5s;5pR(XchE;xroel4Dh!74&PZyeb1ZQyEab{2EYm3-hyDyIR?c z2aFmUK_}DyRh=Z!)sZxs)w)x#WK1@5+>hK+{iGJk^-!vZj}c+lz?HsK!?V3oPA$8o zypqj#D8gzUCAj1u6uWL$9M7p|{MhW!vm}t}Zw&C+T?z=bS5>rMiPc>1jbZ zTM$_@%>IA0(tz4Cv0%-P&W%n_EKJM|sQKv6K)UJK=3=>&`@d|$P&~iCaelNT+)VBo zYmRMyXb&@#BCR_)GnSox+%Z^@5qKz2E~3REqddq_2B_*^Y%;CtUiJZ_miqIyXZNvA zkS9XFR+VZVb&9f14fUr|r0M`spBcTG-BE*wyV**&>1GciA}nBA#SMYms=9NRlJI;Up$&dp}$CkBy| z6O>D`-9Nc-AzD<8&KywtN9X29?!br^j@$HNe}j^ua!5S65Zp z=1HTLow_uvuCWMoH?vZZi{77dmxj`qiqsAYUA$ruxT=mnw9K!JJ#!=_e9x zl&xxisZiQFUTW0J_Ue$nMQ2x&w5L;Ho})!4gGSc>KV{8*D{FRH|8Mba1oyJm{{*}T z-VJYpYoG}pEW#YT1p44aI01f+J>X~XQ}`6z4R^o?;C6T$ycKSS3LJz{coFP`Q(zN3 zM0x%beg>a}yWlpEa=sIiPa=Ut0*M3?2_zCoB#=lTkw7AWL;{Hfo|qEA!s=ULHaFDa z!(!zwt?M1pq8S!<6W>lB? zVjB=csks=fgZ39p%w(r0rZbX-u8@bfK%&xo;%Qqe*5u5-(Wx+2T^vE%d_O~}DmHr$ zhwbQYYjS2{VL+Kw{4x(xcgwGqtp9NhrxxWu*8k!DeAe>cg#Q591MpgS4V2-};UbuX zAxOh!_zCOw_rP1g0}JNiJUAD&z_UQs^*@FO;Ro8^8XC;2mJY7`zak3#Y+x z@F4#D55w*7Ubq=7I1l>a5&ZZ+hA+bx;S2C-cm=FL1;N$RK zxDjM8z%n%9rSK>4W&Ho2fe*m#@MgFiE`w9yWcV-k13U~5!O!8J;oWc>yaBF<%ivNt z3wq%+I2C@yzJYIm>?3$JTmomqb{K{scryHuKJpFt8vFy?2_J%6;4SbfcqOcW?oV17 z_w=+6%%H0?CW_6Pxak?ydORARQwBqDMFKhHh9kFhI2ld#rV|VkTvn-`P8CNeu@Z|e z!&Rd7f^RnFryo4(5K{e>fll+Zc+v{hK!vpI(^`LuyDL&!s}c8*`DH(%r1aWzEwmIE4kYvo=k?!kEGPLshi5cbDR++*y zOhpiNRFc~7X6|I9^^VnBKs>e!cuIC_&^kI#zd5_N--#L}08QyHJPYD3%c#HP=zNxOA6?vOc~m72+)$k!NtIr}rq2eSx)*p*bwy<0 z^#ofkbOYknMEt!K z8x()w>ty^l>t&r@a7l*H-dW!vYCPM$;%${a+ukqNaEbOrdVy3~Hx|})yz%K7S1sFR zZ11u)pvEqiz+`Uiotwhrtjl6XkSUvt;OL0LAF{OMFgx%I+I2v!xi_Hh*m>C!kUoU( z_y|JPTNL~>*+C#`gsZ*&6)6onx~9)In-L=QYTJ-tdN%`D3rXuRQC?;zk!W4^=*Xro z{B3N^F@F_{@-10N{SYpbJEL6?Sx--I7^Sxrr?(ZUqctLR>*rG}7F#up?fa0%m0F#p z>?ONYmAdIB)76VOBAcbf9L_t>V-^{12#_wrbz;cMuc8(c ze`eU)ksgtO6x@$~cTYh=EYg1tc8?^t*N!N6wFI21>>tWg5;L8U8{Ix4bR8k^O&&^h z3ntgf?ozNdW$)y!F(o>cu9(+*Q*;_~WsSN@K8*(6!a_!i2)RgTqfJet>Dbcr?FCpV zmdcJY@#KC-0JG(>P4v1%JY)-{rEZPj&s;ilYZG6=W`YxM3aN{p?br=RW<2qn%x8$?92l_9I4TSbn#@!MlW`Z-7tr?q3f5gbL5&E{=oHP z>wzly)%9{%|6Fg}_O`U35t?1I7fa=mw;B%JR=JE?Jf@M0vWn==J+3EXJEk^+C#^I~ zz3ev!(ZW{H0gh2O`iYx^YA(N6nq43gInR9P=zw=gHd=foC?3fhVTG<555auf`5Xy!Od_J+z1EZG8l(p z7=&lTCO8pJfNx@F_;$JOm$wcfjAmYvC|l0ZUMT126;AunW$C7eF6m;4y3zkAj?G_y&9( z{tjLTt5AepFaXbmr-9frzrZbU9b5w|AT|ygE`mwe3eSg4a1#6o zo5nXmY#vv`e%J>W!;4`j?0{#&AH#|8BuK%Jv1xoAJ`Ep(n_(4p!MSh_oDE|4_$7P= zJ_~Z5;*%g}DqaJB0~L_5F#{X;^oUta+t=iojq)sFhHGSAxc$s?WXcuZE!dS(d6oOV zg-({s(W&M{+`MP3zMFlsVrT%?GeTkpyMxV=S!|B}O1a_Y4oaRD^Jn=c!$azbtfnPO zur8L(&td}Zwq9maTWc}y+ak3U#5@inbDEym*@-+GQ0wlh*gd=K$BsmkN5L9_s7BtB zy=b0gcBv9h{}fTiA4lO&HtNZ?v1o|Ug4)dx6^flC%~Pq%Sryy6t9@mB^<czu)V{K;&{u zV!q!&ye-nBh$2nMhQ*vX2>e3}p)AdfR$mRn`f;@#F^s0IB4NLlUlL4TmEE4XqUrj< z7VGe4-Kn_Cj>XxZTrs#QZNZj(9a-C<2pu*EshXZ0^BhSx@7VM2*SDi>`l5~_Ifq~Z zYN=o{F&>xm$)LUdNBtwz4h1mDb7H2UmZcF!E!boJa;=du-PR9z$?4P?wgQgtanppz*l3evPl zpw9dIT3#p$rZv2{p`xvB#_-(SOg3~98JD3LEJU)y(xdcW^VzYBt@(wyiP32UrGJf0 zWhX9~7z=*RWM_6w5enhx!65~4^Z^6Od$7^4%mYoN6Z8RDW^_EpOkrCQv{Hywp_PDi zBLC??rsi3Cn=MZTFG`IEOZ}~_AsfErJNd_Ss{YO_4CyMT=Yf8j`W&R@uZXO{*=OB7CX1 z>Q$L8BQ3CLn%rA{V(C|rs5&NNu&ct6k=3DXWF;Muq-h$ntPhS>wbe$OZCm<>0z{?O zCNkoNR~TqU9tb2D&8{f8)_^p_QL9$b1sl=38%W9P)bJ?rK*{LAxuGJl&%UaC(o#U3 zf>z2g=ZjxkrbUWb8P+eokzJbD^svy&BRy7YB&`}m;##noG}bA)N}!VzYFwT|o}-E` zo|?=V`94et6>W~!@ewQbbLnMm4b>BIixI-tg!=HDgbo_nS6UshTdfkPNjzoJW3kbR zik5*tpPjNqhl$&JK5Nmfvz-6wB{%*rJ9=u!m*{xoxtDT?DB4D%_Urk^LX)=t~OCV?S zZ-m28gG=EO*bmQ!`&qAk7vx<28{qYDDeMGU%RUoMhE4Dl)~VvBe=A%MN8m6xAZPRC zT>cpJ!}H)2I2j&gJ^CQX`t~mPAiN!32d{uCRA3ln4SNcl43DrDy%X+$L*Rm(>puW9 zAm{sKJ$oAbmi6ejLHzcggb%_8zyn#crr?LHLB9&JPQ3-*1h0qd;958gFN0Nh5j+=8 zh40a}p9k^R-v-yh)o=h_0<)moUoUX=>_e-&z;}3TM^&2~++V8dBSC16wH!+f0<&t> zt{6Ie==s%VP~U$OhKd-JhJ#4thm)4|J1BMQe|$)W}ZMD%hNiT zM9EAfJ_Ts4Dn&v0lK@ea%iIyY%a@KMn%7*CFS#VzQ(t0lmIO1}H?z##S2i3Nr=7oK z&6r=POo<`-Q%BI=zqWXR-!F(6{O%f;37>hmhS~aEBZwXLlr9-dWTP}qp-f#5iHPLU z73*=n3$p9Iu!LRj1|{g2ut}o^zS7P~OLU1uvyrslym}%WOk7$|u*ke({p|(6wHIxjt3S_5x$?5+6r2Vd-=JVfmvtsOwKisJ5?@siT&MT#4vfKPRqs zPTr}g*?@J-TDN_j#IV!bYl2CTJe!W@xG?(E7jx{X7E1Ea1={x(xOruvIpS}s)o;Sl zvCQ3Q5rQ{4$PO}pvr>@6A*~C7T!TsNIxmIzot>qR`^VRQCx*PXzodvgT(-J&NNwOKyGDlxfez%*5Q} z80l!0tDB}ZoPzhSw6&Pt?-Z0a-uEK?ZtY%v&{@@suclbef^>p!zYeU;nqutTaEBn# zE~&*!7vzCbWqXp?V}dKuZyD_t;3%*bn{+v=>J=?{EM&qrdRg4(@ltA&mAvsFBg^6vk%vcA>4GKQ zK`a)`OJ1=pejfo|@B*2S2IZFTJyT@aui{y?H=)dUr3l@IW~59T7`*bdTCH8IqOf_u^pKDLEbGje=DY} z|L(6gl?>_(^gjd0-a6e&gg&W{Hn1N}~as7D7S0aH#0*M3?2_zCo zB#=lTkw7AWL;{Hf5(zv(BoLTl+E=gI7PHPuxc!CM$-BeD*Qg(zxgoH0L~Lx)*O_DI c2;Uvf>%(8jE3(rV7C8AJR)APYPSmCT7uF$2B>(^b literal 0 HcmV?d00001 diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 9720b75..c53d4af 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -139,6 +139,7 @@ static int cmd_select(char **args, unsigned int n) } selected_link = l; + ctl_link_set_wfd_subelements(l, "000600111c4400c8"); cli_printf("link %s selected\n", selected_link->label); return 0; From 31f7fbba33d0a72a584ed03c555ac8534bd24698 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 20 Nov 2022 11:47:35 +0100 Subject: [PATCH 123/142] Set custom ctl names --- src/ctl/ctl-cli.c | 2 +- src/ctl/ctl.h | 9 ++++----- src/ctl/sinkctl.c | 6 ++++++ src/ctl/wifictl.c | 7 +++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 15ce621..ba56dc8 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -697,7 +697,7 @@ int cli_init(sd_bus *bus, const struct cli_cmd *cmds) read_history(get_history_filename()); rl_end_of_history(0, 0); - rl_set_prompt(CLI_PROMPT); + rl_set_prompt(get_cli_prompt()); printf("\r"); rl_on_new_line(); rl_redisplay(); diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 69b0db8..cb8855f 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -17,6 +17,9 @@ * along with MiracleCast; If not, see . */ +#ifndef CTL_CTL_H +#define CTL_CTL_H + #include #include #include @@ -34,9 +37,6 @@ #include #include -#ifndef CTL_CTL_H -#define CTL_CTL_H - struct ctl_wifi; struct ctl_link; struct ctl_peer; @@ -203,8 +203,6 @@ void cli_command_printf(const char *fmt, ...); #define CLI_BOLDGRAY "\x1B[1;30m" #define CLI_BOLDWHITE "\x1B[1;37m" -#define CLI_PROMPT CLI_BLUE "[miraclectl] # " CLI_DEFAULT - struct cli_cmd { const char *cmd; const char *args; @@ -231,6 +229,7 @@ extern unsigned int wfd_supported_res_cea; extern unsigned int wfd_supported_res_vesa; extern unsigned int wfd_supported_res_hh; +char* get_cli_prompt(); int cli_init(sd_bus *bus, const struct cli_cmd *cmds); void cli_destroy(void); int cli_run(void); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 8f0e0c8..e1335df 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -51,6 +51,8 @@ #define HISTORY_FILENAME ".miracle-sink.history" +#define CLI_PROMPT CLI_BLUE "[sinkctl] # " CLI_DEFAULT + static sd_bus *bus; static struct ctl_wifi *wifi; static struct ctl_sink *sink; @@ -87,6 +89,10 @@ struct ctl_wifi *get_wifi() return wifi; } +char* get_cli_prompt() +{ + return CLI_PROMPT; +} /* * get history filename diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index c53d4af..5447554 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -38,11 +38,18 @@ #define HISTORY_FILENAME ".miracle-wifi.history" +#define CLI_PROMPT CLI_BLUE "[wifictl] # " CLI_DEFAULT + static sd_bus *bus; static struct ctl_wifi *wifi; static struct ctl_link *selected_link; +char* get_cli_prompt() +{ + return CLI_PROMPT; +} + /* * get history filename */ From 439dac09c554d67eaa4f3d8bce8fa89415e60a26 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 20 Nov 2022 12:48:40 +0100 Subject: [PATCH 124/142] Ignore special chars on color prompt --- src/ctl/ctl-cli.c | 3 +-- src/ctl/sinkctl.c | 2 +- src/ctl/wifictl.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index ba56dc8..9240ee4 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -692,12 +692,11 @@ int cli_init(sd_bus *bus, const struct cli_cmd *cmds) rl_erase_empty_line = 1; rl_attempted_completion_function = completion_fn; - rl_callback_handler_install(NULL, cli_handler_fn); + rl_callback_handler_install(get_cli_prompt(), cli_handler_fn); using_history(); read_history(get_history_filename()); rl_end_of_history(0, 0); - rl_set_prompt(get_cli_prompt()); printf("\r"); rl_on_new_line(); rl_redisplay(); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e1335df..706f936 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -51,7 +51,7 @@ #define HISTORY_FILENAME ".miracle-sink.history" -#define CLI_PROMPT CLI_BLUE "[sinkctl] # " CLI_DEFAULT +#define CLI_PROMPT "\001" CLI_BLUE "\002" "[sinkctl] # " "\001" CLI_DEFAULT "\002" static sd_bus *bus; static struct ctl_wifi *wifi; diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 5447554..5279958 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -38,7 +38,7 @@ #define HISTORY_FILENAME ".miracle-wifi.history" -#define CLI_PROMPT CLI_BLUE "[wifictl] # " CLI_DEFAULT +#define CLI_PROMPT "\001" CLI_BLUE "\002" "[wifictl] # " "\001" CLI_DEFAULT "\002" static sd_bus *bus; static struct ctl_wifi *wifi; From a36e9bd19fe7500af00d555668eb9e32c17dba69 Mon Sep 17 00:00:00 2001 From: Tanish Azad <73871477+Taz03@users.noreply.github.com> Date: Mon, 28 Nov 2022 12:39:51 +0000 Subject: [PATCH 125/142] fixed error message --- src/ctl/sinkctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index 706f936..cecf667 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -174,7 +174,7 @@ static int cmd_show(char **args, unsigned int n) !(p = ctl_wifi_find_peer(wifi, args[0])) && !(l = ctl_wifi_search_link(wifi, args[0])) && !(p = ctl_wifi_search_peer(wifi, args[0]))) { - cli_error("unknown link or peer %s", args[0]); + cli_error("unknown %s", args[0]); return 0; } } From 3018aac1f2efa1387281e6d435a4dfe6b738309a Mon Sep 17 00:00:00 2001 From: Xiao Qiang Liang Date: Tue, 3 Jan 2023 15:25:51 +0100 Subject: [PATCH 126/142] Fix cmake build for latest gcc libraries link order is relevant on latest gcc --- src/dhcp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dhcp/CMakeLists.txt b/src/dhcp/CMakeLists.txt index 7ae3e30..d7f8b7b 100644 --- a/src/dhcp/CMakeLists.txt +++ b/src/dhcp/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(miracle-dhcp ${miracle-dhcp_SRCS}) find_package(PkgConfig) pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) +target_link_libraries(miracle-dhcp miracle-shared) link_directories( ${UDEV_LIBRARY_DIRS}) include_directories( ${UDEV_INCLUDE_DIRS}) target_link_libraries(miracle-dhcp ${UDEV_LIBRARIES}) @@ -21,7 +22,6 @@ link_directories( ${GLIB2_LIBRARY_DIRS}) include_directories( ${GLIB2_INCLUDE_DIRS}) target_link_libraries(miracle-dhcp ${GLIB2_LIBRARIES}) -target_link_libraries(miracle-dhcp miracle-shared) install(TARGETS miracle-dhcp DESTINATION bin) INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src/shared) From c803c88572e843562ea28c049f981397146017e5 Mon Sep 17 00:00:00 2001 From: Erik Andresen Date: Sun, 8 Jan 2023 16:28:02 +0100 Subject: [PATCH 127/142] CMakeLists: Remove duplicate systemd requirement closes #3 --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3edc3dc..8e4dd04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,6 @@ set(DATADIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "shared data dir") pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (UDEV REQUIRED libudev) -pkg_check_modules (SYSTEMD REQUIRED libsystemd) CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) From 279303d0d6bf3ee1215686e5afd7517f35c50ae7 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 22 Jan 2023 10:17:44 +0100 Subject: [PATCH 128/142] fix double free reading custom parameter --- src/ctl/ctl-sink.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index bb592b3..3897b9b 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -97,14 +97,17 @@ static void sink_handle_get_parameter(struct ctl_sink *s, wfd_video_formats = wfd_video_formats_extension; } } - if (wfd_video_formats == NULL) { + bool create_wfd_video_formats = wfd_video_formats == NULL; + if (create_wfd_video_formats) { gchar video_formats[128]; sprintf(video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); wfd_video_formats = strdup(video_formats); } check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); - g_free(wfd_video_formats); + if (create_wfd_video_formats) { + g_free(wfd_video_formats); + } /* wfd_audio_codecs */ gchar* wfd_audio_codecs = "AAC 00000007 00"; From f3debd5678e7699dfd8acfdcc77fda64e9509cae Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 22 Jan 2023 10:23:32 +0100 Subject: [PATCH 129/142] whitespace --- src/ctl/ctl-sink.c | 148 ++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/src/ctl/ctl-sink.c b/src/ctl/ctl-sink.c index 3897b9b..dd89fa4 100644 --- a/src/ctl/ctl-sink.c +++ b/src/ctl/ctl-sink.c @@ -77,88 +77,88 @@ static void sink_handle_options(struct ctl_sink *s, } static void sink_handle_get_parameter(struct ctl_sink *s, - struct rtsp_message *m) + struct rtsp_message *m) { - _rtsp_message_unref_ struct rtsp_message *rep = NULL; - int r; + _rtsp_message_unref_ struct rtsp_message *rep = NULL; + int r; - r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); - if (r < 0) - return cli_vERR(r); + r = rtsp_message_new_reply_for(m, &rep, RTSP_CODE_OK, NULL); + if (r < 0) + return cli_vERR(r); - /* wfd_content_protection */ - check_and_response_option("wfd_content_protection", "none"); - GHashTable* protocol_extensions = s->protocol_extensions; - /* wfd_video_formats */ - gchar* wfd_video_formats = NULL; + /* wfd_content_protection */ + check_and_response_option("wfd_content_protection", "none"); + GHashTable* protocol_extensions = s->protocol_extensions; + /* wfd_video_formats */ + gchar* wfd_video_formats = NULL; + if (protocol_extensions != NULL) { + gchar* wfd_video_formats_extension = g_hash_table_lookup(protocol_extensions, WFD_VIDEO_FORMATS); + if (wfd_video_formats_extension != NULL) { + wfd_video_formats = wfd_video_formats_extension; + } + } + bool create_wfd_video_formats = wfd_video_formats == NULL; + if (create_wfd_video_formats) { + gchar video_formats[128]; + sprintf(video_formats, "00 00 03 10 %08x %08x %08x 00 0000 0000 10 none none", + s->resolutions_cea, s->resolutions_vesa, s->resolutions_hh); + wfd_video_formats = strdup(video_formats); + } + check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); + if (create_wfd_video_formats) { + g_free(wfd_video_formats); + } + + /* wfd_audio_codecs */ + gchar* wfd_audio_codecs = "AAC 00000007 00"; + if (protocol_extensions != NULL) { + gchar* wfd_audio_codecs_extension = g_hash_table_lookup(protocol_extensions, WFD_AUDIO_CODECS); + if (wfd_audio_codecs_extension != NULL) { + wfd_audio_codecs = wfd_audio_codecs_extension; + } + } + check_and_response_option(WFD_AUDIO_CODECS, wfd_audio_codecs); + + /* wfd_client_rtp_ports */ + char wfd_client_rtp_ports[128]; + sprintf(wfd_client_rtp_ports, "RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); + check_and_response_option("wfd_client_rtp_ports", wfd_client_rtp_ports); + + if (protocol_extensions != NULL) { + GList* extension_keys = g_hash_table_get_keys(protocol_extensions); + for (int i = 0; iresolutions_cea, s->resolutions_vesa, s->resolutions_hh); - wfd_video_formats = strdup(video_formats); - } - check_and_response_option(WFD_VIDEO_FORMATS, wfd_video_formats); - if (create_wfd_video_formats) { - g_free(wfd_video_formats); - } + check_and_response_option(WFD_UIBC_CAPABILITY, wfd_uibc_capability); + } - /* wfd_audio_codecs */ - gchar* wfd_audio_codecs = "AAC 00000007 00"; - if (protocol_extensions != NULL) { - gchar* wfd_audio_codecs_extension = g_hash_table_lookup(protocol_extensions, WFD_AUDIO_CODECS); - if (wfd_audio_codecs_extension != NULL) { - wfd_audio_codecs = wfd_audio_codecs_extension; - } - } - check_and_response_option(WFD_AUDIO_CODECS, wfd_audio_codecs); + rtsp_message_seal(rep); + cli_debug("OUTGOING: %s\n", rtsp_message_get_raw(rep)); - /* wfd_client_rtp_ports */ - char wfd_client_rtp_ports[128]; - sprintf(wfd_client_rtp_ports, "RTP/AVP/UDP;unicast %d 0 mode=play", rstp_port); - check_and_response_option("wfd_client_rtp_ports", wfd_client_rtp_ports); - - if (protocol_extensions != NULL) { - GList* extension_keys = g_hash_table_get_keys(protocol_extensions); - for (int i = 0; irtsp, rep); - if (r < 0) - return cli_vERR(r); + r = rtsp_send(s->rtsp, rep); + if (r < 0) + return cli_vERR(r); } bool check_rtsp_option(struct rtsp_message *m, char *option) { From 850a1c6f7c69b727b24fa1858d86490b7698c482 Mon Sep 17 00:00:00 2001 From: Kai Jan Schmidt-Brauns <12021253+KaiJan57@users.noreply.github.com> Date: Thu, 16 Feb 2023 16:32:53 +0100 Subject: [PATCH 130/142] Fix dependency check to be posix-compliant test with "==" operator works in bash but fails in other shells such as `sh` --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cb4566a..6cc2870 100644 --- a/configure.ac +++ b/configure.ac @@ -53,7 +53,7 @@ AC_DEFINE_UNQUOTED([IP_BINARY], [$IP_BINARY], [Path for ip binary]) # Mandatory dependencies # -AS_IF([test "$use_libsystemd" == "yes"], +AS_IF([test "$use_libsystemd" = "yes"], [ AC_DEFINE([ENABLE_SYSTEMD], [], [Use systemd]) m4_ifdef([PKG_CHECK_MODULES], [ From fdb8671c4087826541c4ffc14df5716c28acd62a Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 14 Jul 2023 21:54:44 +0200 Subject: [PATCH 131/142] fix autotools build for libm --- src/shared/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am index b98dd81..9145e39 100644 --- a/src/shared/Makefile.am +++ b/src/shared/Makefile.am @@ -19,5 +19,6 @@ libmiracle_shared_la_SOURCES = \ wpas.c libmiracle_shared_la_LIBADD = -lsystemd \ $(DEPS_LIBS) \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + $(LIBM) From af6ab257eae83bb0270a776a8fe00c0148bc53c4 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Mon, 13 Nov 2023 00:48:03 +0100 Subject: [PATCH 132/142] Remove systemd and it comes with DEP_LIBS --- src/shared/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am index 9145e39..766b9dc 100644 --- a/src/shared/Makefile.am +++ b/src/shared/Makefile.am @@ -17,7 +17,7 @@ libmiracle_shared_la_SOURCES = \ util.h \ wpas.h \ wpas.c -libmiracle_shared_la_LIBADD = -lsystemd \ +libmiracle_shared_la_LIBADD = \ $(DEPS_LIBS) \ $(GLIB_LIBS) \ $(LIBM) From c83802fd06e62d1cff18c5a59cbb3fc38604624f Mon Sep 17 00:00:00 2001 From: Mark Muth Date: Sat, 1 Jun 2024 22:46:43 +0200 Subject: [PATCH 133/142] Fix build with GCC 14.1 on Arch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compiling with `gcc (GCC) 14.1.1 20240507` raised the following warning: `error: implicit declaration of function ‘gettimeofday’ [-Wimplicit-function-declaration]` Adding `#include ` according to `man gettimeofday` fixes #509. --- src/ctl/ctl-cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 9240ee4..2273743 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "ctl.h" @@ -34,7 +35,6 @@ #include "shl_util.h" #include "shl_log.h" #include -#include /* From 210ef327ce61a5d9efc6a1f2b10406dfb27e531f Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sun, 2 Jun 2024 02:19:24 +0200 Subject: [PATCH 134/142] Configure usage of systemd or elogind --- configure.ac | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6cc2870..a93c08c 100644 --- a/configure.ac +++ b/configure.ac @@ -45,8 +45,15 @@ AC_ARG_VAR(IP_BINARY, [Path for ip binary]) if test -z "$IP_BINARY"; then IP_BINARY=/bin/ip fi -AC_ARG_ENABLE([disable-systemd], - AS_HELP_STRING([--disable-systemd], [Disable systemd]), [], [use_libsystemd=yes], [Disable systemd using elogind]) +AC_ARG_ENABLE([systemd], + AS_HELP_STRING([--disable-systemd], [Disable systemd]), + [case "${enableval}" in + yes) use_libsystemd=yes ;; + no) use_libsystemd=no ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-systemd]) ;; + esac], + [use_libsystemd=yes]) + AC_DEFINE_UNQUOTED([IP_BINARY], [$IP_BINARY], [Path for ip binary]) # From 1df6392a23564de68867bbe133e4a0c0dcd87282 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:09:57 +0200 Subject: [PATCH 135/142] remove unused variables --- src/ctl/ctl-cli.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 2273743..b66dd6e 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -359,7 +359,6 @@ char * links_peers_generator (const char *text, int state) { static int list_index, len; - char *name; size_t peer_cnt = 0; size_t link_cnt = 0; struct shl_dlist *i, *j; @@ -444,7 +443,6 @@ char * peers_generator (const char *text, int state) { static int list_index, len; - char *name; size_t peer_cnt = 0; struct shl_dlist *i, *j; struct ctl_link *l; @@ -497,7 +495,6 @@ char * links_generator (const char *text, int state) { static int list_index, len; - char *name; size_t link_cnt = 0; struct shl_dlist *i; struct ctl_link *l; From faea95fbfa7f3f48713018d9360978a70fd9924e Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:10:37 +0200 Subject: [PATCH 136/142] resize output buffer --- src/ctl/ctl-cli.c | 2 +- src/shared/shl_log.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index b66dd6e..51136fd 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -94,7 +94,7 @@ void cli_printf_time_prefix(const char *fmt, va_list args) struct tm *timeinfo; struct timeval tv; char buffertmp[80]; - char buffer[80]; + char buffer[120]; int millisec; diff --git a/src/shared/shl_log.c b/src/shared/shl_log.c index eb55501..feb49b4 100644 --- a/src/shared/shl_log.c +++ b/src/shared/shl_log.c @@ -145,7 +145,7 @@ static void log__submit(const char *file, struct tm *timeinfo; struct timeval tv; char buffertmp[80]; - char buffer[80]; + char buffer[120]; int millisec; out = stderr; From c664d1ba2718b364b74c6a4d4197af9883fd8f11 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:11:16 +0200 Subject: [PATCH 137/142] detect empty input to finish app --- src/uibc/miracle-uibcctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uibc/miracle-uibcctl.c b/src/uibc/miracle-uibcctl.c index 3aee587..27fc6e6 100644 --- a/src/uibc/miracle-uibcctl.c +++ b/src/uibc/miracle-uibcctl.c @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) { } bzero(buffer, 256); fgets(buffer, 255, stdin); - if (buffer == NULL) { + if (strlen(buffer) == 0) { break; } if (!daemon) { From aecd52a3545b8ac3e14985d8fb88f084a671bf1e Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:12:27 +0200 Subject: [PATCH 138/142] manage const pointers --- src/ctl/ctl-cli.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index 51136fd..fc1e415 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -331,7 +331,7 @@ char * yes_no_generator (const char *text, int state) { static int list_index, len; - char *name; + const char *name; /* If this is a new word to complete, initialize now. This includes saving the length of TEXT for efficiency, and initializing the index @@ -343,7 +343,7 @@ yes_no_generator (const char *text, int state) } /* Return the next name which partially matches from the command list. */ - while (name = yes_no_options[list_index]) + while ((name = yes_no_options[list_index]) != NULL) { list_index++; @@ -550,7 +550,7 @@ char * command_generator (const char *text, int state) { static int list_index, len; - char *name; + const char *name; /* If this is a new word to complete, initialize now. This includes saving the length of TEXT for efficiency, and initializing the index @@ -562,7 +562,7 @@ command_generator (const char *text, int state) } /* Return the next name which partially matches from the command list. */ - while (name = cli_cmds[list_index].cmd) + while ((name = cli_cmds[list_index].cmd) != NULL) { list_index++; From a67a182a059fecb8d247b5b43824064831c825ea Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:12:52 +0200 Subject: [PATCH 139/142] compare correctly with char --- src/ctl/ctl-cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctl/ctl-cli.c b/src/ctl/ctl-cli.c index fc1e415..844d774 100644 --- a/src/ctl/ctl-cli.c +++ b/src/ctl/ctl-cli.c @@ -591,7 +591,7 @@ int get_args(char* line) } tmp++; } - if (" " != *last_delim) + if (' ' != *last_delim) count++; return count; } From 430b1a39b8991e2b80028e76d18c91ac077548be Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:13:41 +0200 Subject: [PATCH 140/142] Max completion functions allowed are two --- src/ctl/sinkctl.c | 2 +- src/ctl/wifictl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index cecf667..841dbb2 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -442,7 +442,7 @@ static const struct cli_cmd cli_cmds[] = { { "run", "", CLI_M, CLI_EQUAL, 1, cmd_run, "Run sink on given link", {links_generator, NULL} }, { "bind", "", CLI_M, CLI_EQUAL, 1, cmd_bind, "Like 'run' but bind the link name to run when it is hotplugged", {links_generator, NULL} }, { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object", {links_generator, NULL} }, - { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link", {links_generator, yes_no_generator, NULL} }, + { "set-managed", " ", CLI_M, CLI_EQUAL, 2, cmd_set_managed, "Manage or unmnage a link", {links_generator, yes_no_generator} }, { "quit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, "Quit program", {NULL} }, { "exit", NULL, CLI_Y, CLI_MORE, 0, cmd_quit, NULL, {NULL} }, { "help", NULL, CLI_M, CLI_MORE, 0, NULL, "Print help", {NULL} }, diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 5279958..0af1f5c 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -415,7 +415,7 @@ static const struct cli_cmd cli_cmds[] = { { "list", NULL, CLI_M, CLI_LESS, 0, cmd_list, "List all objects", {NULL}}, { "select", "[link]", CLI_Y, CLI_LESS, 1, cmd_select, "Select default link", {links_generator, NULL} }, { "show", "[link|peer]", CLI_M, CLI_LESS, 1, cmd_show, "Show detailed object information", {links_peers_generator, NULL} }, - { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object", {links_generator, yes_no_generator, NULL} }, + { "set-friendly-name", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_friendly_name, "Set friendly name of an object", {links_generator, yes_no_generator} }, { "set-managed", "[link] ", CLI_M, CLI_LESS, 2, cmd_set_managed, "Manage or unmnage a link" }, { "p2p-scan", "[link] [stop]", CLI_Y, CLI_LESS, 2, cmd_p2p_scan, "Control neighborhood P2P scanning", {links_generator, NULL} }, { "connect", " [provision] [pin]", CLI_M, CLI_LESS, 3, cmd_connect, "Connect to peer", {peers_generator, NULL} }, From c9c8bd7a7ac18f03db8e06214a0655c46735d6b7 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:14:10 +0200 Subject: [PATCH 141/142] cast free to avoid warnings --- src/shared/shl_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/shl_util.c b/src/shared/shl_util.c index a5907f8..0dc89a2 100644 --- a/src/shared/shl_util.c +++ b/src/shared/shl_util.c @@ -828,7 +828,7 @@ int shl__mkdir_parents(const char *prefix, const char *path, mode_t mode) p = strndup(path, e - path); r = shl__is_dir(p); - free(p); + free((char*)p); if (r > 0) return 0; if (r == 0) From 937747fd4de64a33bccf5adb73924c435ceb821b Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Sat, 13 Jul 2024 19:14:55 +0200 Subject: [PATCH 142/142] control null terminated string copying --- src/shared/wpas.c | 2 +- src/wifi/wifid-peer.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shared/wpas.c b/src/shared/wpas.c index 171a472..6882431 100644 --- a/src/shared/wpas.c +++ b/src/shared/wpas.c @@ -1054,7 +1054,7 @@ static int wpas__bind_server_socket(int fd, const char *ctrl_path, char *name) } } - strncpy(name, src.sun_path, UNIX_PATH_MAX - 1); + strncpy(name, src.sun_path, UNIX_PATH_MAX); name[UNIX_PATH_MAX - 1] = 0; return 0; diff --git a/src/wifi/wifid-peer.c b/src/wifi/wifid-peer.c index a361089..b87d0cc 100644 --- a/src/wifi/wifid-peer.c +++ b/src/wifi/wifid-peer.c @@ -61,7 +61,8 @@ int peer_new(struct link *l, r = log_ENOMEM(); goto error; } - strncpy(p->p2p_mac, mac, MAC_STRLEN - 1); + strncpy(p->p2p_mac, mac, MAC_STRLEN); + p->p2p_mac[MAC_STRLEN - 1] = 0; r = shl_htable_insert_str(&l->peers, &p->p2p_mac, NULL); if (r < 0) {