From 2b44051cbfa70deafc30d9767323214debbc1a75 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Tue, 3 Jul 2012 10:34:17 +0200 Subject: [PATCH] LibCecSharp: fixed - set the primary LA in CecLogicalAddresses added GetLibInfo()/cec_get_lib_info() to the interface, that shows how libCEC was compiled and with which features included. added cec-client -i / cec-client --info added ToString(cec_user_control_code_key) to the interface added cecVersion to libcec_configuration, that configures the spec version that libCEC will use for devices it controls. defaults to v1.4 header cleanups, cleaned locks around callbacks, added CAdapterFactory, to create IAdapterCommunication instances, added --debug, --enable-optimisation fixed: disallow sending CEC_OPCODE_SET_STREAM_PATH - not allowed by the CEC spec fixed: when an image view source message was received from another device, then libCEC incorrectly marked that device as active source internally. fixed: persist the configuration in the eeprom after initialising the client. fixes wrong/old settings being used in autonomous mode, which broke the wake on cec funtion fixed: don't use a CTryLockObject in ReplaceHandler, but a standard lock and wait fixed: unregister a registered client in RegisterClient() before requesting the vendorid, so the device members get reset. don't call ReplaceHander() another time, since GetVendorId() already doe$ fixed: don't try to write to the eeprom more than once within 30 seconds, and schedule another write if more than one change came in within the 30 seconds --- .gitignore | 11 + ChangeLog | 24 + Doxyfile | 2 +- README | 7 +- configure.ac | 250 +++++++++-- debian/changelog | 24 + include/cec.h | 20 +- include/cecc.h | 4 + include/cectypes.h | 21 +- project/LibCecSharp.vcproj | 12 +- project/cec-config.rc | Bin 3232 -> 3232 bytes project/cec-config.vcxproj | 8 +- project/libcec.rc | Bin 3202 -> 3202 bytes project/libcec.vcxproj | 38 +- project/libcec.vcxproj.filters | 75 ++-- project/testclient.rc | Bin 3230 -> 3230 bytes project/testclient.vcxproj | 8 +- src/CecSharpTester/Properties/AssemblyInfo.cs | 4 +- src/LibCecSharp/AssemblyInfo.cpp | 2 +- src/LibCecSharp/CecSharpTypes.h | 11 +- src/LibCecSharp/LibCecSharp.cpp | 6 + src/cec-config-gui/Properties/AssemblyInfo.cs | 4 +- src/cec-config/cec-config.cpp | 11 +- src/env.h | 39 ++ src/lib/CECClient.cpp | 419 +++++++++++------- src/lib/CECClient.h | 34 +- src/lib/CECInputBuffer.h | 1 - src/lib/CECProcessor.cpp | 100 +++-- src/lib/CECProcessor.h | 10 +- src/lib/CECTypeUtils.h | 181 +++++++- src/lib/LibCEC.cpp | 71 ++- src/lib/LibCEC.h | 5 +- src/lib/LibCECC.cpp | 16 +- src/lib/LibCECDll.cpp | 1 + src/lib/Makefile.am | 33 +- src/lib/adapter/AdapterCommunication.h | 42 +- src/lib/adapter/AdapterFactory.cpp | 84 ++++ src/lib/adapter/AdapterFactory.h | 57 +++ .../USBCECAdapterCommands.cpp | 68 ++- .../{ => Pulse-Eight}/USBCECAdapterCommands.h | 32 +- .../USBCECAdapterCommunication.cpp | 107 ++++- .../USBCECAdapterCommunication.h | 24 +- .../USBCECAdapterDetection.cpp | 7 +- .../USBCECAdapterDetection.h | 2 - .../USBCECAdapterMessage.cpp | 9 +- .../{ => Pulse-Eight}/USBCECAdapterMessage.h | 18 +- .../USBCECAdapterMessageQueue.cpp | 25 +- .../USBCECAdapterMessageQueue.h | 16 +- src/lib/devices/CECAudioSystem.cpp | 22 +- src/lib/devices/CECAudioSystem.h | 6 +- src/lib/devices/CECBusDevice.cpp | 77 ++-- src/lib/devices/CECBusDevice.h | 29 +- src/lib/devices/CECDeviceMap.cpp | 4 +- src/lib/devices/CECDeviceMap.h | 1 - src/lib/devices/CECPlaybackDevice.cpp | 14 +- src/lib/devices/CECPlaybackDevice.h | 2 +- src/lib/devices/CECRecordingDevice.cpp | 1 + src/lib/devices/CECTV.cpp | 1 + src/lib/devices/CECTuner.cpp | 1 + src/lib/implementations/ANCommandHandler.cpp | 10 +- src/lib/implementations/CECCommandHandler.cpp | 152 ++++--- src/lib/implementations/CECCommandHandler.h | 37 +- src/lib/implementations/RLCommandHandler.cpp | 11 +- src/lib/implementations/RLCommandHandler.h | 1 - src/lib/implementations/SLCommandHandler.cpp | 51 ++- src/lib/implementations/SLCommandHandler.h | 3 +- src/lib/implementations/VLCommandHandler.cpp | 16 +- src/lib/platform/adl/adl-edid.cpp | 1 + src/lib/platform/adl/adl-edid.h | 4 +- src/lib/platform/nvidia/nv-edid.cpp | 5 +- src/lib/platform/nvidia/nv-edid.h | 3 +- src/lib/platform/os.h | 1 - src/lib/platform/posix/os-edid.cpp | 3 +- src/lib/platform/posix/os-socket.h | 4 +- src/lib/platform/posix/serialport.cpp | 11 +- src/lib/platform/posix/serversocket.cpp | 16 +- src/lib/platform/sockets/serialport.h | 8 +- src/lib/platform/sockets/serversocket.h | 10 +- src/lib/platform/sockets/socket.h | 37 +- src/lib/platform/sockets/tcp.h | 4 +- src/lib/platform/threads/mutex.h | 8 +- src/lib/platform/util/StdString.h | 2 +- src/lib/platform/util/buffer.h | 2 +- src/lib/platform/util/edid.h | 2 +- src/lib/platform/util/timeutils.h | 4 +- src/lib/platform/windows/dlfcn-win32.cpp | 1 + src/lib/platform/windows/os-edid.cpp | 3 +- src/lib/platform/windows/os-socket.h | 8 +- src/lib/platform/windows/os-threads.cpp | 2 +- src/lib/platform/windows/os-threads.h | 2 + src/lib/platform/windows/os-types.h | 1 - src/lib/platform/windows/serialport.cpp | 11 +- src/testclient/main.cpp | 30 +- 93 files changed, 1774 insertions(+), 791 deletions(-) create mode 100644 src/env.h create mode 100644 src/lib/adapter/AdapterFactory.cpp create mode 100644 src/lib/adapter/AdapterFactory.h rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterCommands.cpp (92%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterCommands.h (93%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterCommunication.cpp (86%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterCommunication.h (87%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterDetection.cpp (98%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterDetection.h (97%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterMessage.cpp (98%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterMessage.h (87%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterMessageQueue.cpp (94%) rename src/lib/adapter/{ => Pulse-Eight}/USBCECAdapterMessageQueue.h (95%) diff --git a/.gitignore b/.gitignore index 38b8af7..420dc5e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /build /.cproject /.project +/.settings *.dll *.exe *.exp @@ -14,6 +15,8 @@ *.suo *.user +*~ + /support/private /driver/p8usb-cec.cat @@ -34,6 +37,10 @@ ltmain.sh Makefile Makefile.in missing +config.h +config.h.in +config.h.in~ +stamp-h1 include/boost @@ -48,6 +55,10 @@ project/Properties project/x64 +project/RPi/toolchain +project/RPi/firmware +project/RPi/deps + src/lib/.deps src/lib/.libs src/lib/*.a diff --git a/ChangeLog b/ChangeLog index b8b13b9..6c599ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +libcec (1.8.1-1) unstable; urgency=low + + * changed/added: + * added cec-client -i / cec-client --info that calls GetLibInfo() + * header cleanups + * added CAdapterFactory, to create IAdapterCommunication instances + * added --debug to configure, to include -ggdb + + * interface changes: + * added GetLibInfo()/cec_get_lib_info(), that shows how libCEC was compiled + and with which features included. + * added ToString(cec_user_control_code_key) to the interface + + * fixed: + * disallow sending CEC_OPCODE_SET_STREAM_PATH - not allowed by the CEC spec + * persist the configuration in the eeprom after initialising the client. + fixes wrong/old settings being used in autonomous mode, which broke the + wake on cec funtion + * persist the new configuration when the hdmi port setting changed + * cleaned locks around callbacks + * LibCecSharp: set the primary LA in CecLogicalAddresses + + -- Pulse-Eight Packaging Thu, 12 Jul 2012 16:48:00 +0100 + libcec (1.7.2-1) unstable; urgency=low * changed/added: diff --git a/Doxyfile b/Doxyfile index c8162fe..a87a171 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1295,7 +1295,7 @@ INCLUDE_PATH = # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = config.h # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of diff --git a/README b/README index 7825aef..f610204 100644 --- a/README +++ b/README @@ -12,12 +12,15 @@ libCEC needs the following dependencies in order to work correctly: To compile libCEC on Linux, you'll need the following dependencies: * autoconf 2.13 or later * automake 1.11 or later -* pkg-config * libtool -* udev development headers v151 or later * gcc 4.2 or later * liblockdev 1.0 development headers +The following dependencies are recommended. Without them, the adapter can not +be auto-detected. +* pkg-config +* udev development headers v151 or later + To compile, execute the following commands: # autoreconf -vif # ./configure diff --git a/configure.ac b/configure.ac index 9e72964..1ae91b0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,68 +1,254 @@ AC_PREREQ(2.59) -AC_INIT([libcec], [1:7:0], [http://libcec.pulse-eight.com/]) +AC_INIT([libcec], [1:8:0], [http://libcec.pulse-eight.com/]) +AC_CONFIG_HEADERS([config.h]) +AH_TOP([#pragma once]) + +AM_INIT_AUTOMAKE([foreign]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES]) + AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) +AC_CANONICAL_HOST + +cflags_reset="$CFLAGS" +AC_LANG(C++) AC_PROG_CXX AC_PROG_LIBTOOL +AC_PROG_INSTALL +AC_LIBTOOL_DLOPEN +CFLAGS="$cflags_reset" + +msg_pkg_config_missing="'pkg-config' is missing - adapter detection will not be available" +msg_pthread_missing="required library 'pthread' is missing" +msg_dl_missing="required library 'dl' is missing" +msg_udev_missing="library 'udev' is missing - adapter detection will not be available" +msg_dirent_missing="dirent.h header is missing - adapter detection will not be available" +msg_lockdev_missing="required library 'liblockdev' is missing" +msg_required_header_missing="required header is missing" + +## debugging symbols +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [include debug symbols (default is no)])], + [use_debug=$enableval], + [use_debug=no]) + +## optimisation +AC_ARG_ENABLE([optimisation], + [AS_HELP_STRING([--enable-optimisation], + [optimisation flag (default is yes)])], + [use_optimisation=$enableval], + [use_optimisation=yes]) -# search for pthread, required by all targets -AC_SEARCH_LIBS([pthread_create],[pthread],, - AC_MSG_ERROR("required library 'pthread' is missing")) +## add the top dir and include to the include path, so we can include config.h and cec.h +CPPFLAGS="$CPPFLAGS -I\$(abs_top_srcdir)/src -I\$(abs_top_srcdir)/include" -# search for dlopen, required by all targets +## search for pkg-config +AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes) +if test "x$HAVE_PKG_CONFIG" != "xyes" ; then + AC_MSG_WARN($msg_pkg_config_missing) +fi + +## search for pthread, required by all targets +AC_SEARCH_LIBS([pthread_create],[pthread],,AC_MSG_ERROR($msg_pthread_missing)) +AC_CHECK_FUNCS([pthread_mutexattr_init pthread_cond_init pthread_cond_destroy pthread_cond_signal pthread_cond_broadcast pthread_cond_wait pthread_cond_timedwait]) + +## search for dlopen, required by all targets AC_SEARCH_LIBS([dlopen], [dl], [test "$ac_cv_search_dlopen" = "none required" || LIBS_DL=$ac_cv_search_dlopen], - AC_MSG_ERROR("required library 'dl' is missing")) + AC_MSG_ERROR($msg_dl_missing)) +AC_CHECK_FUNCS([dlopen dlcose dlsym]) - -# platform specific libs, required by all targets +## platform specific libs, required by all targets case "${host}" in *-*-linux*) - LIBS+=" -lrt" + # for timeutils + LIBS="$LIBS -lrt" ;; *-apple-darwin*) - LIBS+="-framework CoreVideo -framework IOKit" - ;; - *-freebsd*) + LIBS="$LIBS -framework CoreVideo -framework IOKit" ;; esac -libs_client=$LIBS +## we found all the libs and headers that we need for the client applications +libs_client="$LIBS" -# search for udev and lockdev, only required by libCEC -has_libudev="yes" +## search for udev, lockdev and the RPi API, only required by libCEC +use_udev="no" +use_adapter_detection="yes" case "${host}" in *-*-linux*) - PKG_CHECK_MODULES([UDEV],[libudev],, - [has_libudev="no"]; AC_MSG_WARN("library 'udev' is missing - adapter detection will not be available")) + ## search for udev if pkg-config was found + if test "x$HAVE_PKG_CONFIG" = "xyes" ; then + PKG_CHECK_MODULES([UDEV],[libudev],use_udev="yes",AC_MSG_WARN($msg_udev_missing)) + fi + + ## we need dirent.h on linux too + if test "$use_udev" = "yes"; then + AC_CHECK_HEADER(dirent.h,,[use_udev="no";AC_MSG_WARN($msg_dirent_missing)]) + fi - AC_CHECK_HEADER(lockdev.h,, - AC_MSG_ERROR("required library 'liblockdev' is missing")) + if test "$use_udev" != "yes"; then + use_adapter_detection="no" + fi - LIBS+=" -llockdev" + ## search for lockdev + AC_CHECK_HEADER(lockdev.h,,AC_MSG_ERROR($msg_lockdev_missing)) + AC_CHECK_LIB(lockdev,dev_unlock,,AC_MSG_ERROR($msg_lockdev_missing)) + + AC_CHECK_HEADER(time.h,,AC_MSG_ERROR($msg_required_header_missing)) + AC_CHECK_HEADER(sys/prctl.h,,AC_MSG_ERROR($msg_required_header_missing)) ;; *-apple-darwin*) - has_libudev="no"; - ;; - *-freebsd*) - has_libudev="no" + AC_CHECK_HEADER(mach/mach_time.h,,AC_MSG_ERROR($msg_required_header_missing)) + AC_CHECK_HEADER(CoreVideo/CVHostTime.h,,AC_MSG_ERROR($msg_required_header_missing)) ;; esac -# mark udev as available if it was found, so we can include adapter autodetection code -if test "x$has_libudev" != "xno"; then - INCLUDES="$INCLUDES $UDEV_CFLAGS";LIBS="$LIBS $UDEV_LIBS" - AC_DEFINE([HAVE_LIBUDEV],[1],["Define to 1 if libudev is installed"]) - REQUIRES="udev" +## define the build info +LIB_INFO="host: ${host}, features:" + +features="Configured features:\n Pulse-Eight CEC Adapter :\t\tyes" +LIB_INFO="$LIB_INFO 'P8 USB'" +AC_DEFINE([HAVE_P8_USB],[1],[Define to 1 to include support for the Pulse-Eight USB-CEC Adapter]) +AM_CONDITIONAL(USE_P8_USB, true) + +## mark adapter detection as available if the required deps were found +if test "x$use_adapter_detection" = "xyes"; then + ## mark udev as available if it was found + if test "x$use_udev" = "xyes"; then + INCLUDES="$INCLUDES $UDEV_CFLAGS" + LIBS="$LIBS $UDEV_LIBS" + AC_DEFINE([HAVE_LIBUDEV],[1],[Define to 1 if libudev is installed]) + REQUIRES="$REQUIRES udev" + fi + + AC_DEFINE([HAVE_P8_USB_DETECT],[1],[Define to 1 to include autodetection support for the Pulse-Eight USB-CEC Adapter]) + AM_CONDITIONAL(USE_P8_USB_DETECT, true) + + features="$features\n Pulse-Eight CEC Adapter detection :\tyes" + LIB_INFO="$LIB_INFO 'P8 USB detect'" +else + AM_CONDITIONAL(USE_P8_USB_DETECT, false) + features="$features\n Pulse-Eight CEC Adapter detection :\tno" fi -LIBS_LIBCEC=$LIBS -LIBS=$libs_client +## check if our build system is complete +AC_CHECK_HEADER(algorithm,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(ctype.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(dlfcn.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(errno.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(fcntl.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(functional,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(locale,,AC_DEFINE([SS_NO_LOCALE],[1],[Define to 1 to exclude locale support])) +AC_CHECK_HEADER(map,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(netdb.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(poll.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(queue,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(semaphore.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(set,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(stdarg.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(stdint.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(stdio.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(stdlib.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(string,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(string.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(termios.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(unistd.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(vector,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(wchar.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(wctype.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(arpa/inet.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(netinet/in.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(netinet/tcp.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(sys/socket.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(sys/time.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_HEADER(sys/types.h,,AC_MSG_ERROR($msg_required_header_missing)) +AC_CHECK_FUNCS([close fcntl select write read shutdown send recv memset sprintf getaddrinfo getsockopt setsockopt connect poll sched_yield open strerror tcsetattr tcgetattr cfsetispeed cfsetospeed bind freeaddrinfo listen accept socket]) -CXXFLAGS="-fPIC -Wall -Wextra -Wno-missing-field-initializers $CXXFLAGS" +## add the build date to LIB_INFO +AC_CHECK_PROG(HAVE_GIT, git, yes) +if test "x$HAVE_GIT" = "xyes"; then + revision=$(git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h" HEAD) +fi +if test "x$revision" != "x"; then + LIB_INFO="$LIB_INFO, git revision: ${revision}" +fi + +AC_CHECK_PROG(HAVE_DATE, date, yes) +if test "x$HAVE_DATE" = "xyes"; then + LIB_INFO="$LIB_INFO, compiled on: `date -u`" +else + LIB_INFO="$LIB_INFO, compiled on: (unknown date)" +fi + +## add the name of the user who built libCEC to LIB_INFO +AC_CHECK_PROG(HAVE_WHOAMI, whoami, yes) +if test "x$HAVE_WHOAMI" = "xyes" ; then + LIB_INFO="$LIB_INFO by `whoami`" +else + LIB_INFO="$LIB_INFO by (unknown user)" +fi + +## add the hostname of the build host of libCEC to LIB_INFO +AC_CHECK_PROG(HAVE_HOSTNAME, hostname, yes) +if test "x$HAVE_HOSTNAME" = "xyes"; then + LIB_INFO="$LIB_INFO@`hostname -f`" +fi + +## add the system info of the build host of libCEC to LIB_INFO +AC_CHECK_PROG(HAVE_UNAME, uname, yes) +if test "x$HAVE_UNAME" = "xyes"; then + LIB_INFO="$LIB_INFO on `uname -s` `uname -r` (`uname -m`)" +fi + +## redefine the LIBS, so cec-client and cec-config aren't linked against things they don't need +LIBS_LIBCEC="$LIBS" +LIBS="$libs_client" + +CXXFLAGS="$CXXFLAGS -fPIC -Wall -Wextra -Wno-missing-field-initializers" + +if test "x$use_debug" = "xyes"; then + CXXFLAGS="$CXXFLAGS -g" +fi + +if test "x$optimisation" = "xyes"; then + CXXFLAGS="$CXXFLAGS -O2" +fi + +AC_DEFINE_UNQUOTED(LIB_INFO,"$LIB_INFO", "information about how libCEC was compiled") AC_SUBST([REQUIRES]) AC_SUBST([LIBS]) AC_SUBST([LIBS_LIBCEC]) +AC_SUBST([LIB_INFO]) +AC_SUBST([USE_P8_USB]) +AC_SUBST([USE_P8_USB_DETECT]) +AC_SUBST([USE_RPI_API]) AC_CONFIG_FILES([src/lib/libcec.pc]) AC_OUTPUT([Makefile src/lib/Makefile src/testclient/Makefile src/cec-config/Makefile]) + +cat < Thu, 12 Jul 2012 16:48:00 +0100 + libcec (1.7.2-1) unstable; urgency=low * changed/added: diff --git a/include/cec.h b/include/cec.h index de7129d..807bcd9 100644 --- a/include/cec.h +++ b/include/cec.h @@ -36,7 +36,7 @@ #include "cectypes.h" -#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_1_7_1 +#define LIBCEC_VERSION_CURRENT CEC_SERVER_VERSION_1_8_0 namespace CEC { @@ -482,6 +482,24 @@ namespace CEC */ virtual uint16_t GetDevicePhysicalAddress(cec_logical_address iLogicalAddress) = 0; #endif + + /*! + * @return A string with information about how libCEC was compiled. + */ + virtual const char *GetLibInfo(void) = 0; + + virtual const char *ToString(const cec_user_control_code key) = 0; + + /*! + * @brief Calling this method will initialise the host on which libCEC is running. + * Calling this method will initialise the host on which libCEC is running. On the RPi, it calls + * bcm_host_init(), which may only be called once per process, and is called by any process using + * the video api on that system. So only call this method if libCEC is used in an application that + * does not already initialise the video api. + * + * Should be called as first call to libCEC, directly after CECInitialise() and before using Open() + */ + virtual void InitVideoStandalone(void) = 0; }; }; diff --git a/include/cecc.h b/include/cecc.h index 779f211..60b54bd 100644 --- a/include/cecc.h +++ b/include/cecc.h @@ -302,6 +302,10 @@ extern DECLSPEC int cec_get_device_information(const char *strPort, CEC::libcec_ extern DECLSPEC int cec_get_device_information(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs); #endif +extern DECLSPEC const char * cec_get_lib_info(void); + +extern DECLSPEC void cec_init_video_standalone(void); + #ifdef __cplusplus }; #endif diff --git a/include/cectypes.h b/include/cectypes.h index 47168a2..794e124 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -99,6 +99,7 @@ namespace CEC { #define CEC_DEFAULT_DEVICE_LANGUAGE "eng" #define CEC_DEFAULT_SETTING_AUTODETECT_ADDRESS 0 #define CEC_DEFAULT_SETTING_GET_SETTINGS_FROM_ROM 0 +#define CEC_DEFAULT_SETTING_CEC_VERSION 0x05 #define CEC_DEFAULT_TRANSMIT_RETRY_WAIT 500 #define CEC_DEFAULT_TRANSMIT_TIMEOUT 1000 @@ -113,10 +114,13 @@ namespace CEC { #define CEC_ACTIVE_SOURCE_SWITCH_RETRY_TIME_MS 5000 #define CEC_FORWARD_STANDBY_MIN_INTERVAL 10000 +#define CEC_RPI_VIRTUAL_PATH "Raspberry Pi" +#define CEC_RPI_VIRTUAL_COM "RPI" + #define CEC_MIN_LIB_VERSION 1 #define CEC_LIB_VERSION_MAJOR 1 #define CEC_LIB_VERSION_MAJOR_STR "1" -#define CEC_LIB_VERSION_MINOR 7 +#define CEC_LIB_VERSION_MINOR 8 typedef enum cec_abort_reason { @@ -684,6 +688,7 @@ typedef enum cec_vendor_id CEC_VENDOR_MEDION = 0x000CB8, CEC_VENDOR_SHARP = 0x08001F, CEC_VENDOR_VIZIO = 0x6B746D, + CEC_VENDOR_BROADCOM = 0x18C086, CEC_VENDOR_UNKNOWN = 0 } cec_vendor_id; @@ -1223,7 +1228,9 @@ typedef enum cec_client_version CEC_CLIENT_VERSION_1_6_2 = 0x1602, CEC_CLIENT_VERSION_1_6_3 = 0x1603, CEC_CLIENT_VERSION_1_7_0 = 0x1700, - CEC_CLIENT_VERSION_1_7_1 = 0x1701 + CEC_CLIENT_VERSION_1_7_1 = 0x1701, + CEC_CLIENT_VERSION_1_7_2 = 0x1702, + CEC_CLIENT_VERSION_1_8_0 = 0x1800 } cec_client_version; typedef enum cec_server_version @@ -1238,7 +1245,9 @@ typedef enum cec_server_version CEC_SERVER_VERSION_1_6_2 = 0x1602, CEC_SERVER_VERSION_1_6_3 = 0x1603, CEC_SERVER_VERSION_1_7_0 = 0x1700, - CEC_SERVER_VERSION_1_7_1 = 0x1701 + CEC_SERVER_VERSION_1_7_1 = 0x1701, + CEC_SERVER_VERSION_1_7_2 = 0x1702, + CEC_SERVER_VERSION_1_8_0 = 0x1800 } cec_server_version; typedef struct libcec_configuration @@ -1274,6 +1283,7 @@ typedef struct libcec_configuration char strDeviceLanguage[3]; /*!< the menu language used by the client. 3 character ISO 639-2 country code. see http://http://www.loc.gov/standards/iso639-2/ added in 1.6.2 */ uint32_t iFirmwareBuildDate; /*!< (read-only) the build date of the firmware, in seconds since epoch. if not available, this value will be set to 0. added in 1.6.2 */ uint8_t bMonitorOnly; /*!< won't allocate a CCECClient when starting the connection when set (same as monitor mode). added in 1.6.3 */ + cec_version cecVersion; /*!< CEC spec version to use by libCEC. defaults to v1.4. added in 1.8.0 */ #ifdef __cplusplus // @todo re-add in v2.0 (breaks ABI) @@ -1309,7 +1319,9 @@ typedef struct libcec_configuration (other.clientVersion < CEC_CLIENT_VERSION_1_6_2 || !strncmp(strDeviceLanguage, other.strDeviceLanguage, 3)) && (other.clientVersion < CEC_CLIENT_VERSION_1_6_2 || iFirmwareBuildDate == other.iFirmwareBuildDate) && /* libcec 1.6.3+ */ - (other.clientVersion < CEC_CLIENT_VERSION_1_6_3 || bMonitorOnly == other.bMonitorOnly)); + (other.clientVersion < CEC_CLIENT_VERSION_1_6_3 || bMonitorOnly == other.bMonitorOnly) && + /* libcec 1.8.0+ */ + (other.clientVersion < CEC_CLIENT_VERSION_1_8_0 || cecVersion == other.cecVersion)); } bool operator!=(const libcec_configuration &other) const @@ -1341,6 +1353,7 @@ typedef struct libcec_configuration memcpy(strDeviceLanguage, CEC_DEFAULT_DEVICE_LANGUAGE, 3); iFirmwareBuildDate = CEC_FW_BUILD_UNKNOWN; bMonitorOnly = 0; + cecVersion = (cec_version)CEC_DEFAULT_SETTING_CEC_VERSION; memset(strDeviceName, 0, 13); deviceTypes.clear(); diff --git a/project/LibCecSharp.vcproj b/project/LibCecSharp.vcproj index 38be809..39f93b5 100644 --- a/project/LibCecSharp.vcproj +++ b/project/LibCecSharp.vcproj @@ -47,7 +47,7 @@ + + diff --git a/project/cec-config.rc b/project/cec-config.rc index e47ea2df3279b884fe8c99eab847d927c60998ad..be84610b70b362d685b2929de1e9a8273473d396 100644 GIT binary patch delta 64 zcmZ1=xj=G*7c;8`gARkiWPfH|2y1gAGdoC7kHKJbFPke9JDAC!H(8!laxx32(ByTT LT$}kgCouy6v8oLn delta 64 zcmZ1=xj=G*7c;9lgARk?WPfH|2y1gAGdoC7kHK(rFPke9JDAC!H(8!laxx32(ByTT LT$}kgCouy6v6>AX diff --git a/project/cec-config.vcxproj b/project/cec-config.vcxproj index 6ca84e4..5fef417 100644 --- a/project/cec-config.vcxproj +++ b/project/cec-config.vcxproj @@ -87,7 +87,7 @@ true - $(SolutiontDir)..\include;%(AdditionalIncludeDirectories) + $(SolutiontDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Console @@ -106,7 +106,7 @@ true - $(SolutiontDir)..\include;%(AdditionalIncludeDirectories) + $(SolutiontDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Console @@ -129,7 +129,7 @@ true - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Speed @@ -152,7 +152,7 @@ true - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Speed diff --git a/project/libcec.rc b/project/libcec.rc index 547d08c9389c3aa6ffc77b8c1cdf3db06311bb4f..a73c7fd76e24097f5966e570d827043dde290481 100644 GIT binary patch delta 68 zcmZpYY?9pI#ms8Kpu=D=*`HY#!rI)(EX>Sl!Jx-r0K$_Ovg>X>#rBGk9V#?go>g-4 NGY+B6&p75V0|59m5C#AM delta 68 zcmZpYY?9pI#ms8Xpu=D|*`HY#!rI)(EX>Sl&Y;I&2*d`H7qaVaKE?KmksT^DS)NsL O@-q&h&CfXIFarSiBoGDw diff --git a/project/libcec.vcxproj b/project/libcec.vcxproj index 29fb689..3c26ad7 100644 --- a/project/libcec.vcxproj +++ b/project/libcec.vcxproj @@ -24,11 +24,12 @@ - - - - - + + + + + + @@ -69,11 +70,12 @@ - - - - - + + + + + + @@ -175,8 +177,8 @@ Level4 Disabled - _USE_32BIT_TIME_T;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + HAVE_P8_USB;_USE_32BIT_TIME_T;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) true @@ -191,8 +193,8 @@ Level4 Disabled - _WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + HAVE_P8_USB;_WIN64;_DEBUG;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) true @@ -213,8 +215,8 @@ Full true true - $(SolutionDir)..\src\lib\platform\pthread_win32;$(SolutionDir)..\include;%(AdditionalIncludeDirectories) - _USE_32BIT_TIME_T;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) + HAVE_P8_USB;_USE_32BIT_TIME_T;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) true @@ -233,8 +235,8 @@ Level4 Full true - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - _WIN64;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) + HAVE_P8_USB;_WIN64;_CRT_SECURE_NO_WARNINGS;_WINSOCKAPI_;__STDC_CONSTANT_MACROS;DLL_EXPORT;%(PreprocessorDefinitions) true diff --git a/project/libcec.vcxproj.filters b/project/libcec.vcxproj.filters index 58d0dbb..e867399 100644 --- a/project/libcec.vcxproj.filters +++ b/project/libcec.vcxproj.filters @@ -34,6 +34,9 @@ {685e2589-204d-4f9a-a637-a7ba1b61c669} + + {a5e91a49-0595-49bd-9bdb-d729d63f024e} + @@ -122,27 +125,9 @@ platform\windows - - adapter - - - adapter - - - adapter - - - adapter - implementations - - adapter - - - adapter - @@ -170,6 +155,27 @@ platform\nvidia + + adapter + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter + @@ -212,24 +218,9 @@ platform\windows - - adapter - - - adapter - implementations - - adapter - - - adapter - - - adapter - devices @@ -246,6 +237,24 @@ platform\nvidia + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter\Pulse-Eight + + + adapter + diff --git a/project/testclient.rc b/project/testclient.rc index 1025fccbcb9e2494a1695bc100757a470fb7a5fc..0ee2868b392d0258a520fcbbb3a2928d5d0f4f4a 100644 GIT binary patch delta 66 zcmbOyIZtwf7c;8`gARkiWPfH|2y1gAGcPl{1%n=g0fXLTc~;5E2Ux{6A7SHRLKfWo Ifnyyr0N0TYf&c&j delta 66 zcmbOyIZtwf7c;9lgARk?WPfH|2y1gAGcPl{IfEX9A%oszc~;5E2Ux{6A7SHRLKfWo Ifnyyr0M~&If&c&j diff --git a/project/testclient.vcxproj b/project/testclient.vcxproj index 0862f27..53cebe5 100644 --- a/project/testclient.vcxproj +++ b/project/testclient.vcxproj @@ -86,7 +86,7 @@ true - $(SolutiontDir)..\include;%(AdditionalIncludeDirectories) + $(SolutiontDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Console @@ -105,7 +105,7 @@ true - $(SolutiontDir)..\include;%(AdditionalIncludeDirectories) + $(SolutiontDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Console @@ -128,7 +128,7 @@ true - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Speed @@ -151,7 +151,7 @@ true - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + $(SolutionDir)..\include;$(SolutionDir)..\src;%(AdditionalIncludeDirectories) Speed diff --git a/src/CecSharpTester/Properties/AssemblyInfo.cs b/src/CecSharpTester/Properties/AssemblyInfo.cs index 1e6b929..d941918 100644 --- a/src/CecSharpTester/Properties/AssemblyInfo.cs +++ b/src/CecSharpTester/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.1.0")] -[assembly: AssemblyFileVersion("1.7.1.0")] +[assembly: AssemblyVersion("1.8.0.0")] +[assembly: AssemblyFileVersion("1.8.0.0")] diff --git a/src/LibCecSharp/AssemblyInfo.cpp b/src/LibCecSharp/AssemblyInfo.cpp index 4aa58ec..1640d3c 100644 --- a/src/LibCecSharp/AssemblyInfo.cpp +++ b/src/LibCecSharp/AssemblyInfo.cpp @@ -13,7 +13,7 @@ using namespace System::Security::Permissions; [assembly:AssemblyTrademarkAttribute("")]; [assembly:AssemblyCultureAttribute("")]; -[assembly:AssemblyVersionAttribute("1.7.1.0")]; +[assembly:AssemblyVersionAttribute("1.8.0.0")]; [assembly:ComVisible(false)]; [assembly:CLSCompliantAttribute(true)]; diff --git a/src/LibCecSharp/CecSharpTypes.h b/src/LibCecSharp/CecSharpTypes.h index 33f3200..0ba3c04 100644 --- a/src/LibCecSharp/CecSharpTypes.h +++ b/src/LibCecSharp/CecSharpTypes.h @@ -368,7 +368,9 @@ namespace CecSharp Version1_6_2 = 0x1602, Version1_6_3 = 0x1603, Version1_7_0 = 0x1700, - Version1_7_1 = 0x1701 + Version1_7_1 = 0x1701, + Version1_7_2 = 0x1702, + Version1_8_0 = 0x1800 }; public enum class CecServerVersion @@ -383,7 +385,9 @@ namespace CecSharp Version1_6_2 = 0x1602, Version1_6_3 = 0x1603, Version1_7_0 = 0x1700, - Version1_7_1 = 0x1701 + Version1_7_1 = 0x1701, + Version1_7_2 = 0x1702, + Version1_8_0 = 0x1800 }; public ref class CecAdapter @@ -423,6 +427,7 @@ namespace CecSharp void Clear(void) { + Primary = CecLogicalAddress::Unknown; for (unsigned int iPtr = 0; iPtr < 16; iPtr++) Addresses[iPtr] = CecLogicalAddress::Unknown; } @@ -435,6 +440,8 @@ namespace CecSharp void Set(CecLogicalAddress iAddress) { Addresses[(unsigned int)iAddress] = iAddress; + if (Primary == CecLogicalAddress::Unknown) + Primary = iAddress; } property CecLogicalAddress Primary; diff --git a/src/LibCecSharp/LibCecSharp.cpp b/src/LibCecSharp/LibCecSharp.cpp index cd0f6d0..634edc5 100644 --- a/src/LibCecSharp/LibCecSharp.cpp +++ b/src/LibCecSharp/LibCecSharp.cpp @@ -598,6 +598,12 @@ namespace CecSharp return gcnew String(retVal); } + String ^ GetLibInfo() + { + const char *retVal = m_libCec->GetLibInfo(); + return gcnew String(retVal); + } + private: ICECAdapter * m_libCec; CecCallbackMethods ^ m_callbacks; diff --git a/src/cec-config-gui/Properties/AssemblyInfo.cs b/src/cec-config-gui/Properties/AssemblyInfo.cs index 56ca7ec..d47600b 100644 --- a/src/cec-config-gui/Properties/AssemblyInfo.cs +++ b/src/cec-config-gui/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.1.0")] -[assembly: AssemblyFileVersion("1.7.1.0")] +[assembly: AssemblyVersion("1.8.0.0")] +[assembly: AssemblyFileVersion("1.8.0.0")] diff --git a/src/cec-config/cec-config.cpp b/src/cec-config/cec-config.cpp index 7b203cb..fbfdd36 100644 --- a/src/cec-config/cec-config.cpp +++ b/src/cec-config/cec-config.cpp @@ -30,7 +30,8 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cec.h" +#include "../env.h" +#include "../include/cec.h" #include #include @@ -41,6 +42,7 @@ #include "../lib/platform/threads/mutex.h" #include "../lib/platform/util/timeutils.h" #include "../lib/implementations/CECCommandHandler.h" +#include "../lib/platform/util/StdString.h" using namespace CEC; using namespace std; @@ -169,6 +171,9 @@ bool OpenConnection(cec_device_type type = CEC_DEVICE_TYPE_RECORDING_DEVICE) if (!g_parser) return false; + // init video on targets that need this + g_parser->InitVideoStandalone(); + CStdString strPort; cec_adapter devices[10]; uint8_t iDevicesFound = g_parser->FindAdapters(devices, 10, NULL); @@ -431,11 +436,11 @@ int main (int UNUSED(argc), char *UNUSED(argv[])) CStdString strWakeDevices; for (uint8_t iPtr = 0; iPtr < 16; iPtr++) if (g_config.wakeDevices[iPtr]) - strWakeDevices.AppendFormat(" %d" + iPtr); + strWakeDevices.AppendFormat(" %d", iPtr); CStdString strStandbyDevices; for (uint8_t iPtr = 0; iPtr < 16; iPtr++) if (g_config.powerOffDevices[iPtr]) - strStandbyDevices.AppendFormat(" %d" + iPtr); + strStandbyDevices.AppendFormat(" %d", iPtr); configOutput << "\n" << diff --git a/src/env.h b/src/env.h new file mode 100644 index 0000000..21f0d79 --- /dev/null +++ b/src/env.h @@ -0,0 +1,39 @@ +#pragma once +/* + * This file is part of the libCEC(R) library. + * + * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is an original work, containing original code. + * + * libCEC(R) is a trademark of Pulse-Eight Limited. + * + * This program is dual-licensed; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Alternatively, you can license this library under a commercial license, + * please contact Pulse-Eight Licensing for more information. + * + * For more information contact: + * Pulse-Eight Licensing + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../include/cectypes.h" +#include "lib/platform/os.h" diff --git a/src/lib/CECClient.cpp b/src/lib/CECClient.cpp index b0d7e18..b6c0812 100644 --- a/src/lib/CECClient.cpp +++ b/src/lib/CECClient.cpp @@ -30,7 +30,9 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECClient.h" + #include "CECProcessor.h" #include "LibCEC.h" #include "CECTypeUtils.h" @@ -183,7 +185,7 @@ bool CCECClient::SetHDMIPort(const cec_logical_address iBaseDevice, const uint8_ // and set the address SetDevicePhysicalAddress(iPhysicalAddress); - ConfigurationChanged(m_configuration); + CallbackConfigurationChanged(m_configuration); return bReturn; } @@ -224,28 +226,27 @@ void CCECClient::SetPhysicalAddress(const libcec_configuration &configuration) bool CCECClient::SetPhysicalAddress(const uint16_t iPhysicalAddress) { // update the configuration + bool bChanged(true); { CLockObject lock(m_mutex); if (m_configuration.iPhysicalAddress == iPhysicalAddress) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "physical address unchanged (%04X)", iPhysicalAddress); - return true; - } + bChanged = false; else - { m_configuration.iPhysicalAddress = iPhysicalAddress; - LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting physical address to '%04X'", iPhysicalAddress); - } + } + if (!bChanged) + { + LIB_CEC->AddLog(CEC_LOG_DEBUG, "physical address unchanged (%04X)", iPhysicalAddress); + return true; } - // persist the new configuration - m_processor->PersistConfiguration(m_configuration); + LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting physical address to '%04X'", iPhysicalAddress); // set the physical address for each device SetDevicePhysicalAddress(iPhysicalAddress); // and send back the updated configuration - ConfigurationChanged(m_configuration); + CallbackConfigurationChanged(m_configuration); return true; } @@ -275,6 +276,9 @@ void CCECClient::SetSupportedDeviceTypes(void) // set the new type list m_configuration.deviceTypes = types; + + // persist the new configuration + PersistConfiguration(m_configuration); } bool CCECClient::AllocateLogicalAddresses(void) @@ -321,6 +325,9 @@ bool CCECClient::AllocateLogicalAddresses(void) m_configuration.logicalAddresses.Set(address); } + // persist the new configuration + PersistConfiguration(m_configuration); + return true; } @@ -329,11 +336,11 @@ cec_logical_address CCECClient::AllocateLogicalAddressRecordingDevice(void) cec_logical_address retVal(CECDEVICE_UNKNOWN); LIB_CEC->AddLog(CEC_LOG_DEBUG, "detecting logical address for type 'recording device'"); - if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE1)) + if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE1, m_configuration.cecVersion)) retVal = CECDEVICE_RECORDINGDEVICE1; - else if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE2)) + else if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE2, m_configuration.cecVersion)) retVal = CECDEVICE_RECORDINGDEVICE2; - else if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE3)) + else if (m_processor->TryLogicalAddress(CECDEVICE_RECORDINGDEVICE3, m_configuration.cecVersion)) retVal = CECDEVICE_RECORDINGDEVICE3; return retVal; @@ -344,13 +351,13 @@ cec_logical_address CCECClient::AllocateLogicalAddressTuner(void) cec_logical_address retVal(CECDEVICE_UNKNOWN); LIB_CEC->AddLog(CEC_LOG_DEBUG, "detecting logical address for type 'tuner'"); - if (m_processor->TryLogicalAddress(CECDEVICE_TUNER1)) + if (m_processor->TryLogicalAddress(CECDEVICE_TUNER1, m_configuration.cecVersion)) retVal = CECDEVICE_TUNER1; - else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER2)) + else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER2, m_configuration.cecVersion)) retVal = CECDEVICE_TUNER2; - else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER3)) + else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER3, m_configuration.cecVersion)) retVal = CECDEVICE_TUNER3; - else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER4)) + else if (m_processor->TryLogicalAddress(CECDEVICE_TUNER4, m_configuration.cecVersion)) retVal = CECDEVICE_TUNER4; return retVal; @@ -361,11 +368,11 @@ cec_logical_address CCECClient::AllocateLogicalAddressPlaybackDevice(void) cec_logical_address retVal(CECDEVICE_UNKNOWN); LIB_CEC->AddLog(CEC_LOG_DEBUG, "detecting logical address for type 'playback device'"); - if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE1)) + if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE1, m_configuration.cecVersion)) retVal = CECDEVICE_PLAYBACKDEVICE1; - else if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE2)) + else if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE2, m_configuration.cecVersion)) retVal = CECDEVICE_PLAYBACKDEVICE2; - else if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE3)) + else if (m_processor->TryLogicalAddress(CECDEVICE_PLAYBACKDEVICE3, m_configuration.cecVersion)) retVal = CECDEVICE_PLAYBACKDEVICE3; return retVal; @@ -376,7 +383,7 @@ cec_logical_address CCECClient::AllocateLogicalAddressAudioSystem(void) cec_logical_address retVal(CECDEVICE_UNKNOWN); LIB_CEC->AddLog(CEC_LOG_DEBUG, "detecting logical address for type 'audiosystem'"); - if (m_processor->TryLogicalAddress(CECDEVICE_AUDIOSYSTEM)) + if (m_processor->TryLogicalAddress(CECDEVICE_AUDIOSYSTEM, m_configuration.cecVersion)) retVal = CECDEVICE_AUDIOSYSTEM; return retVal; @@ -398,31 +405,36 @@ CCECBusDevice *CCECClient::GetDeviceByType(const cec_device_type type) const bool CCECClient::ChangeDeviceType(const cec_device_type from, const cec_device_type to) { - LIB_CEC->AddLog(CEC_LOG_NOTICE, "changing device type '%s' into '%s'", ToString(from), ToString(to)); - - CLockObject lock(m_mutex); + if (from == to) + return true; - // get the previous device that was allocated - CCECBusDevice *previousDevice = GetDeviceByType(from); - if (!previousDevice) - return false; + LIB_CEC->AddLog(CEC_LOG_NOTICE, "changing device type '%s' into '%s'", ToString(from), ToString(to)); - // change the type in the device type list - bool bChanged(false); - for (uint8_t iPtr = 0; iPtr < 5; iPtr++) { - if (m_configuration.deviceTypes.types[iPtr] == CEC_DEVICE_TYPE_RESERVED) - continue; + CLockObject lock(m_mutex); - if (m_configuration.deviceTypes.types[iPtr] == from) - { - bChanged = true; - m_configuration.deviceTypes.types[iPtr] = to; - } - else if (m_configuration.deviceTypes.types[iPtr] == to && bChanged) + // get the previous device that was allocated + CCECBusDevice *previousDevice = GetDeviceByType(from); + if (!previousDevice) + return false; + + // change the type in the device type list + bool bChanged(false); + for (uint8_t iPtr = 0; iPtr < 5; iPtr++) { - // ensure that dupes are removed - m_configuration.deviceTypes.types[iPtr] = CEC_DEVICE_TYPE_RESERVED; + if (m_configuration.deviceTypes.types[iPtr] == CEC_DEVICE_TYPE_RESERVED) + continue; + + if (m_configuration.deviceTypes.types[iPtr] == from) + { + bChanged = true; + m_configuration.deviceTypes.types[iPtr] = to; + } + else if (m_configuration.deviceTypes.types[iPtr] == to && bChanged) + { + // ensure that dupes are removed + m_configuration.deviceTypes.types[iPtr] = CEC_DEVICE_TYPE_RESERVED; + } } } @@ -430,29 +442,38 @@ bool CCECClient::ChangeDeviceType(const cec_device_type from, const cec_device_t if (!m_processor->RegisterClient(this)) return false; + // persist the new configuration + PersistConfiguration(m_configuration); + return true; } bool CCECClient::SetLogicalAddress(const cec_logical_address iLogicalAddress) { - CLockObject lock(m_mutex); + bool bReturn(true); + if (GetPrimaryLogicalAdddress() != iLogicalAddress) { + LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< setting primary logical address to %1x", iLogicalAddress); { CLockObject lock(m_mutex); - LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< setting primary logical address to %1x", iLogicalAddress); m_configuration.logicalAddresses.primary = iLogicalAddress; m_configuration.logicalAddresses.Set(iLogicalAddress); } - return m_processor->RegisterClient(this); + + bReturn = m_processor->RegisterClient(this); + + // persist the new configuration + if (bReturn) + PersistConfiguration(m_configuration); } - return true; + return bReturn; } -bool CCECClient::Transmit(const cec_command &data) +bool CCECClient::Transmit(const cec_command &data, bool bIsReply) { - return m_processor ? m_processor->Transmit(data) : false; + return m_processor ? m_processor->Transmit(data, bIsReply) : false; } bool CCECClient::SendPowerOnDevices(const cec_logical_address address /* = CECDEVICE_TV */) @@ -553,7 +574,7 @@ bool CCECClient::SendSetDeckControlMode(const cec_deck_control_mode mode, bool b // and set the deck control mode if there is a match device->SetDeckControlMode(mode); if (bSendUpdate) - return device->TransmitDeckStatus(CECDEVICE_TV); + return device->TransmitDeckStatus(CECDEVICE_TV, false); return true; } @@ -570,7 +591,7 @@ bool CCECClient::SendSetDeckInfo(const cec_deck_info info, bool bSendUpdate /* = // and set the deck status if there is a match device->SetDeckStatus(info); if (bSendUpdate) - return device->AsPlaybackDevice()->TransmitDeckStatus(CECDEVICE_TV); + return device->AsPlaybackDevice()->TransmitDeckStatus(CECDEVICE_TV, false); return true; } @@ -588,7 +609,7 @@ bool CCECClient::SendSetMenuState(const cec_menu_state state, bool bSendUpdate / { (*it)->SetMenuState(state); if (bSendUpdate) - (*it)->TransmitMenuState(CECDEVICE_TV); + (*it)->TransmitMenuState(CECDEVICE_TV, false); } return true; @@ -616,7 +637,7 @@ bool CCECClient::SendSetOSDString(const cec_logical_address iLogicalAddress, con { CCECBusDevice *primary = GetPrimaryDevice(); if (primary) - return primary->TransmitOSDString(iLogicalAddress, duration, strMessage); + return primary->TransmitOSDString(iLogicalAddress, duration, strMessage, false); return false; } @@ -863,7 +884,8 @@ bool CCECClient::SetConfiguration(const libcec_configuration &configuration) SetPhysicalAddress(configuration); } - m_processor->PersistConfiguration(m_configuration); + // persist the new configuration + PersistConfiguration(m_configuration); if (!primary) primary = GetPrimaryDevice(); @@ -897,109 +919,51 @@ void CCECClient::AddCommand(const cec_command &command) if (command.destination == CECDEVICE_BROADCAST || GetLogicalAddresses().IsSet(command.destination)) { - CLockObject lock(m_mutex); - LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> %s (%X) -> %s (%X): %s (%2X)", ToString(command.initiator), command.initiator, ToString(command.destination), command.destination, ToString(command.opcode), command.opcode); - - if (m_configuration.callbacks && m_configuration.callbacks->CBCecCommand) - m_configuration.callbacks->CBCecCommand(m_configuration.callbackParam, command); - else if (!m_commandBuffer.Push(command)) - LIB_CEC->AddLog(CEC_LOG_WARNING, "command buffer is full"); + CallbackAddCommand(command); } } int CCECClient::MenuStateChanged(const cec_menu_state newState) { - CLockObject lock(m_mutex); - LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> %s: %s", ToString(CEC_OPCODE_MENU_REQUEST), ToString(newState)); - - if (m_configuration.callbacks && - m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_2 && - m_configuration.callbacks->CBCecMenuStateChanged) - return m_configuration.callbacks->CBCecMenuStateChanged(m_configuration.callbackParam, newState); - - return 0; -} - -void CCECClient::SourceActivated(const cec_logical_address logicalAddress) -{ - CLockObject lock(m_mutex); - - LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source activated: %s (%x)", ToString(logicalAddress), logicalAddress); - - if (m_configuration.callbacks && - m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 && - m_configuration.callbacks->CBCecSourceActivated) - m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, 1); -} - -void CCECClient::SourceDeactivated(const cec_logical_address logicalAddress) -{ - CLockObject lock(m_mutex); - - LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source deactivated: %s (%x)", ToString(logicalAddress), logicalAddress); - - if (m_configuration.callbacks && - m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 && - m_configuration.callbacks->CBCecSourceActivated) - m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, 0); -} - -void CCECClient::Alert(const libcec_alert type, const libcec_parameter ¶m) -{ - CLockObject lock(m_mutex); - - if (m_configuration.callbacks && - m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_0 && - m_configuration.callbacks->CBCecAlert) - m_configuration.callbacks->CBCecAlert(m_configuration.callbackParam, type, param); -} - -void CCECClient::AddLog(const cec_log_message &message) -{ - CLockObject lock(m_logMutex); - if (m_configuration.callbacks && m_configuration.callbacks->CBCecLogMessage) - m_configuration.callbacks->CBCecLogMessage(m_configuration.callbackParam, message); - else - m_logBuffer.Push(message); + return CallbackMenuStateChanged(newState); } void CCECClient::AddKey(void) { - CLockObject lock(m_mutex); + cec_keypress key; + key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN; - if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN) { - cec_keypress key; - - key.duration = (unsigned int) (GetTimeMs() - m_buttontime); - key.keycode = m_iCurrentButton; - LIB_CEC->AddLog(CEC_LOG_DEBUG, "key released: %1x", key.keycode); + CLockObject lock(m_mutex); + if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN) + { + key.duration = (unsigned int) (GetTimeMs() - m_buttontime); + key.keycode = m_iCurrentButton; - if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress) - m_configuration.callbacks->CBCecKeyPress(m_configuration.callbackParam, key); - else - m_keyBuffer.Push(key); - m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; + m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; + m_buttontime = 0; + } } - m_buttontime = 0; + if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN) + { + LIB_CEC->AddLog(CEC_LOG_DEBUG, "key released: %s (%1x)", ToString(key.keycode), key.keycode); + CallbackAddKey(key); + } } void CCECClient::AddKey(const cec_keypress &key) { - CLockObject lock(m_mutex); - - LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %1x", key.keycode); - - if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress) - m_configuration.callbacks->CBCecKeyPress(m_configuration.callbackParam, key); - else - m_keyBuffer.Push(key); + { + CLockObject lock(m_mutex); + m_iCurrentButton = key.duration > 0 ? CEC_USER_CONTROL_CODE_UNKNOWN : key.keycode; + m_buttontime = key.duration > 0 ? 0 : GetTimeMs(); + } - m_iCurrentButton = key.duration > 0 ? CEC_USER_CONTROL_CODE_UNKNOWN : key.keycode; - m_buttontime = key.duration > 0 ? 0 : GetTimeMs(); + LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(key.keycode), key.keycode); + CallbackAddKey(key); } void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode) @@ -1014,27 +978,34 @@ void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode) void CCECClient::CheckKeypressTimeout(void) { - if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && GetTimeMs() - m_buttontime > CEC_BUTTON_TIMEOUT) + cec_keypress key; + { - AddKey(); - m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; - } -} + CLockObject lock(m_mutex); + uint64_t iNow = GetTimeMs(); -void CCECClient::ConfigurationChanged(const libcec_configuration &config) -{ - CLockObject lock(m_mutex); + if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && + iNow - m_buttontime > CEC_BUTTON_TIMEOUT) + { + key.duration = (unsigned int) (iNow - m_buttontime); + key.keycode = m_iCurrentButton; - if (m_configuration.callbacks && - m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0 && - m_configuration.callbacks->CBCecConfigurationChanged && - m_processor->CECInitialised()) - m_configuration.callbacks->CBCecConfigurationChanged(m_configuration.callbackParam, config); + m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN; + m_buttontime = 0; + } + else + { + return; + } + } + + LIB_CEC->AddLog(CEC_LOG_DEBUG, "key auto-released: %s (%1x)", ToString(key.keycode), key.keycode); + CallbackAddKey(key); } bool CCECClient::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks) { - CLockObject lock(m_mutex); + CLockObject lock(m_cbMutex); m_configuration.callbackParam = cbParam; m_configuration.callbacks = callbacks; return true; @@ -1060,7 +1031,7 @@ bool CCECClient::GetNextCommand(cec_command *command) return m_commandBuffer.Pop(*command); } -CStdString CCECClient::GetConnectionInfo(void) +std::string CCECClient::GetConnectionInfo(void) { CStdString strLog; strLog.Format("libCEC version = %s, client version = %s, firmware version = %d", ToString((cec_server_version)m_configuration.serverVersion), ToString((cec_client_version)m_configuration.clientVersion), m_configuration.iFirmwareVersion); @@ -1087,7 +1058,10 @@ CStdString CCECClient::GetConnectionInfo(void) else strLog.AppendFormat(", physical address: %04x", m_configuration.iPhysicalAddress); - return strLog; + strLog.AppendFormat(", %s", LIB_CEC->GetLibInfo()); + + std::string strReturn(strLog.c_str()); + return strReturn; } void CCECClient::SetTVVendorOverride(const cec_vendor_id id) @@ -1105,6 +1079,9 @@ void CCECClient::SetTVVendorOverride(const cec_vendor_id id) if (tv) tv->SetVendorId((uint64_t)id); } + + // persist the new configuration + PersistConfiguration(m_configuration); } cec_vendor_id CCECClient::GetTVVendorOverride(void) @@ -1113,7 +1090,7 @@ cec_vendor_id CCECClient::GetTVVendorOverride(void) return (cec_vendor_id)m_configuration.tvVendor; } -void CCECClient::SetOSDName(const CStdString &strDeviceName) +void CCECClient::SetOSDName(const std::string &strDeviceName) { { CLockObject lock(m_mutex); @@ -1123,25 +1100,32 @@ void CCECClient::SetOSDName(const CStdString &strDeviceName) LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - using OSD name '%s'", __FUNCTION__, strDeviceName.c_str()); CCECBusDevice *primary = GetPrimaryDevice(); - if (primary && !primary->GetCurrentOSDName().Equals(strDeviceName)) + if (primary && !primary->GetCurrentOSDName().Equals(strDeviceName.c_str())) { primary->SetOSDName(strDeviceName); if (m_processor && m_processor->CECInitialised()) - primary->TransmitOSDName(CECDEVICE_TV); + primary->TransmitOSDName(CECDEVICE_TV, false); } + + // persist the new configuration + PersistConfiguration(m_configuration); } -CStdString CCECClient::GetOSDName(void) +std::string CCECClient::GetOSDName(void) { CLockObject lock(m_mutex); - CStdString strOSDName(m_configuration.strDeviceName); + std::string strOSDName(m_configuration.strDeviceName); return strOSDName; } void CCECClient::SetWakeDevices(const cec_logical_addresses &addresses) { - CLockObject lock(m_mutex); - m_configuration.wakeDevices = addresses; + { + CLockObject lock(m_mutex); + m_configuration.wakeDevices = addresses; + } + // persist the new configuration + PersistConfiguration(m_configuration); } cec_logical_addresses CCECClient::GetWakeDevices(void) @@ -1196,6 +1180,9 @@ bool CCECClient::SetDeviceTypes(const cec_device_type_list &deviceTypes) m_configuration.deviceTypes = deviceTypes; } + // persist the new configuration + PersistConfiguration(m_configuration); + if (bNeedReinit) LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - using primary device type '%s'", __FUNCTION__, ToString(deviceTypes[0])); @@ -1237,7 +1224,7 @@ bool CCECClient::SetDevicePhysicalAddress(const uint16_t iPhysicalAddress) // and transmit it if (IsInitialised()) - (*it)->TransmitPhysicalAddress(); + (*it)->TransmitPhysicalAddress(false); } // reactivate the previous active source @@ -1250,6 +1237,9 @@ bool CCECClient::SetDevicePhysicalAddress(const uint16_t iPhysicalAddress) device->ActivateSource(); } + // persist the new configuration + PersistConfiguration(m_configuration); + return true; } @@ -1277,7 +1267,7 @@ bool CCECClient::PollDevice(const cec_logical_address iAddress) CCECBusDevice *primary = GetPrimaryDevice(); // poll the destination, with the primary as source if (primary) - return primary->TransmitPoll(iAddress); + return primary->TransmitPoll(iAddress, false); return m_processor ? m_processor->PollDevice(iAddress) : false; } @@ -1325,7 +1315,21 @@ bool CCECClient::SetStreamPath(const cec_logical_address iAddress) bool CCECClient::SetStreamPath(const uint16_t iPhysicalAddress) { - return m_processor ? m_processor->SetStreamPath(iPhysicalAddress) : false; + bool bReturn(false); + + CCECBusDevice *device = GetDeviceByType(CEC_DEVICE_TYPE_TV); + if (device) + { + device->SetStreamPath(iPhysicalAddress); + bReturn = device->GetHandler()->TransmitSetStreamPath(iPhysicalAddress, false); + device->MarkHandlerReady(); + } + else + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "only the TV is allowed to send CEC_OPCODE_SET_STREAM_PATH"); + } + + return bReturn; } cec_logical_addresses CCECClient::GetLogicalAddresses(void) @@ -1343,7 +1347,9 @@ bool CCECClient::CanPersistConfiguration(void) bool CCECClient::PersistConfiguration(const libcec_configuration &configuration) { - return m_processor ? m_processor->PersistConfiguration(configuration) : false; + return m_processor && IsRegistered() ? + m_processor->PersistConfiguration(configuration) : + false; } void CCECClient::RescanActiveDevices(void) @@ -1364,3 +1370,92 @@ bool CCECClient::IsLibCECActiveSource(void) } return bReturn; } + +void CCECClient::SourceActivated(const cec_logical_address logicalAddress) +{ + LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source activated: %s (%x)", ToString(logicalAddress), logicalAddress); + CallbackSourceActivated(true, logicalAddress); +} + +void CCECClient::SourceDeactivated(const cec_logical_address logicalAddress) +{ + LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source deactivated: %s (%x)", ToString(logicalAddress), logicalAddress); + CallbackSourceActivated(false, logicalAddress); +} + +void CCECClient::CallbackAddCommand(const cec_command &command) +{ + { + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && m_configuration.callbacks->CBCecCommand) + { + m_configuration.callbacks->CBCecCommand(m_configuration.callbackParam, command); + return; + } + } + m_commandBuffer.Push(command); +} + +void CCECClient::CallbackAddKey(const cec_keypress &key) +{ + { + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress) + { + m_configuration.callbacks->CBCecKeyPress(m_configuration.callbackParam, key); + return; + } + } + m_keyBuffer.Push(key); +} + +void CCECClient::CallbackAddLog(const cec_log_message &message) +{ + { + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && m_configuration.callbacks->CBCecLogMessage) + { + m_configuration.callbacks->CBCecLogMessage(m_configuration.callbackParam, message); + return; + } + } + m_logBuffer.Push(message); +} + +void CCECClient::CallbackConfigurationChanged(const libcec_configuration &config) +{ + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && + m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_5_0 && + m_configuration.callbacks->CBCecConfigurationChanged && + m_processor->CECInitialised()) + m_configuration.callbacks->CBCecConfigurationChanged(m_configuration.callbackParam, config); +} + +void CCECClient::CallbackSourceActivated(bool bActivated, const cec_logical_address logicalAddress) +{ + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && + m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_7_1 && + m_configuration.callbacks->CBCecSourceActivated) + m_configuration.callbacks->CBCecSourceActivated(m_configuration.callbackParam, logicalAddress, bActivated ? 1 : 0); +} + +void CCECClient::CallbackAlert(const libcec_alert type, const libcec_parameter ¶m) +{ + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && + m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_0 && + m_configuration.callbacks->CBCecAlert) + m_configuration.callbacks->CBCecAlert(m_configuration.callbackParam, type, param); +} + +int CCECClient::CallbackMenuStateChanged(const cec_menu_state newState) +{ + CLockObject lock(m_cbMutex); + if (m_configuration.callbacks && + m_configuration.clientVersion >= CEC_CLIENT_VERSION_1_6_2 && + m_configuration.callbacks->CBCecMenuStateChanged) + return m_configuration.callbacks->CBCecMenuStateChanged(m_configuration.callbackParam, newState); + return 0; +} diff --git a/src/lib/CECClient.h b/src/lib/CECClient.h index 26944a7..be72448 100644 --- a/src/lib/CECClient.h +++ b/src/lib/CECClient.h @@ -31,15 +31,15 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cectypes.h" +#include #include "platform/threads/mutex.h" #include "platform/util/buffer.h" -#include "devices/CECBusDevice.h" - namespace CEC { class CCECProcessor; + class CCECBusDevice; + class CCECPlaybackDevice; class CCECClient { @@ -97,7 +97,7 @@ namespace CEC /*! * @return A string that describes this client. */ - virtual CStdString GetConnectionInfo(void); + virtual std::string GetConnectionInfo(void); /*! * @return The current value of the TV vendor override setting. @@ -107,7 +107,7 @@ namespace CEC /*! * @return The current value of the OSD name setting. */ - virtual CStdString GetOSDName(void); + virtual std::string GetOSDName(void); /*! * @return Get the current value of the wake device setting. @@ -130,7 +130,7 @@ namespace CEC virtual bool GetNextLogMessage(cec_log_message *message); /**< @deprecated will be removed in v2.0 */ virtual bool GetNextKeypress(cec_keypress *key); /**< @deprecated will be removed in v2.0 */ virtual bool GetNextCommand(cec_command *command); /**< @deprecated will be removed in v2.0 */ - virtual bool Transmit(const cec_command &data); + virtual bool Transmit(const cec_command &data, bool bIsReply); virtual bool SetLogicalAddress(const cec_logical_address iLogicalAddress); virtual bool SetPhysicalAddress(const uint16_t iPhysicalAddress); virtual bool SetHDMIPort(const cec_logical_address iBaseDevice, const uint8_t iPort, bool bForce = false); @@ -176,8 +176,8 @@ namespace CEC // callbacks virtual void AddCommand(const cec_command &command); virtual int MenuStateChanged(const cec_menu_state newState); - virtual void Alert(const libcec_alert type, const libcec_parameter ¶m); - virtual void AddLog(const cec_log_message &message); + virtual void Alert(const libcec_alert type, const libcec_parameter ¶m) { CallbackAlert(type, param); } + virtual void AddLog(const cec_log_message &message) { CallbackAddLog(message); } virtual void AddKey(void); virtual void AddKey(const cec_keypress &key); virtual void SetCurrentButton(const cec_user_control_code iButtonCode); @@ -219,7 +219,7 @@ namespace CEC * @brief Change the OSD name of the primary device that this client is controlling. * @param strDeviceName The new value. */ - virtual void SetOSDName(const CStdString &strDeviceName); + virtual void SetOSDName(const std::string &strDeviceName); /*! * @brief Change the value of the devices to wake. @@ -282,12 +282,6 @@ namespace CEC */ virtual bool SetDevicePhysicalAddress(const uint16_t iPhysicalAddress); - /*! - * @brief Called when the configuration changed and needs to be sent back to the client. - * @param config The new configuration. - */ - virtual void ConfigurationChanged(const libcec_configuration &config); - /*! * @brief Try to autodetect the physical address. * @return True when autodetected (and set in m_configuration), false otherwise. @@ -299,12 +293,20 @@ namespace CEC */ virtual void SetSupportedDeviceTypes(void); + virtual void CallbackAddCommand(const cec_command &command); + virtual void CallbackAddKey(const cec_keypress &key); + virtual void CallbackAddLog(const cec_log_message &message); + virtual void CallbackAlert(const libcec_alert type, const libcec_parameter ¶m); + virtual void CallbackConfigurationChanged(const libcec_configuration &config); + virtual int CallbackMenuStateChanged(const cec_menu_state newState); + virtual void CallbackSourceActivated(bool bActivated, const cec_logical_address logicalAddress); + CCECProcessor * m_processor; /**< a pointer to the processor */ libcec_configuration m_configuration; /**< the configuration of this client */ bool m_bInitialised; /**< true when initialised, false otherwise */ bool m_bRegistered; /**< true when registered in the processor, false otherwise */ PLATFORM::CMutex m_mutex; /**< mutex for changes to this instance */ - PLATFORM::CMutex m_logMutex; /**< mutex that is held when sending a log message back to the client */ + PLATFORM::CMutex m_cbMutex; /**< mutex that is held when doing anything with callbacks */ cec_user_control_code m_iCurrentButton; /**< the control code of the button that's currently held down (if any) */ int64_t m_buttontime; /**< the timestamp when the button was pressed (in seconds since epoch), or 0 if none was pressed. */ int64_t m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */ diff --git a/src/lib/CECInputBuffer.h b/src/lib/CECInputBuffer.h index 9daf582..019cfdd 100644 --- a/src/lib/CECInputBuffer.h +++ b/src/lib/CECInputBuffer.h @@ -31,7 +31,6 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cectypes.h" #include "platform/threads/mutex.h" #include "platform/util/buffer.h" diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 28adee3..71e5c69 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -30,9 +30,10 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECProcessor.h" -#include "adapter/USBCECAdapterCommunication.h" +#include "adapter/AdapterFactory.h" #include "devices/CECBusDevice.h" #include "devices/CECAudioSystem.h" #include "devices/CECPlaybackDevice.h" @@ -135,7 +136,7 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint } // create a new connection - m_communication = new CUSBCECAdapterCommunication(this, strPort, iBaudRate); + m_communication = CAdapterFactory(this->m_libcec).GetInstance(strPort, iBaudRate); // open a new connection unsigned iConnectTry(0); @@ -170,7 +171,7 @@ void CCECProcessor::SetCECInitialised(bool bSetTo /* = true */) UnregisterClients(); } -bool CCECProcessor::TryLogicalAddress(cec_logical_address address) +bool CCECProcessor::TryLogicalAddress(cec_logical_address address, cec_version libCECSpecVersion /* = CEC_VERSION_1_4 */) { // find the device CCECBusDevice *device = m_busDevices->At(address); @@ -181,8 +182,7 @@ bool CCECProcessor::TryLogicalAddress(cec_logical_address address) return false; // poll the LA if not - SetAckMask(0); - return device->TryLogicalAddress(); + return device->TryLogicalAddress(libCECSpecVersion); } return false; @@ -308,13 +308,11 @@ bool CCECProcessor::PollDevice(cec_logical_address iAddress) CCECBusDevice *primary = GetPrimaryDevice(); // poll the destination, with the primary as source if (primary) - return primary->TransmitPoll(iAddress); + return primary->TransmitPoll(iAddress, false); - // try to find the destination - CCECBusDevice *device = m_busDevices->At(iAddress); - // and poll the destination, with the same LA as source + CCECBusDevice *device = m_busDevices->At(CECDEVICE_UNREGISTERED); if (device) - return device->TransmitPoll(iAddress); + return device->TransmitPoll(iAddress, false); return false; } @@ -361,8 +359,9 @@ bool CCECProcessor::IsActiveSource(cec_logical_address iAddress) return device && device->IsActiveSource(); } -bool CCECProcessor::Transmit(const cec_command &data) +bool CCECProcessor::Transmit(const cec_command &data, bool bIsReply) { + cec_command transmitData(data); uint8_t iMaxTries(0); bool bRetry(true); uint8_t iTries(0); @@ -373,10 +372,24 @@ bool CCECProcessor::Transmit(const cec_command &data) // reset the state of this message to 'unknown' cec_adapter_message_state adapterState = ADAPTER_MESSAGE_STATE_UNKNOWN; - LogOutput(data); + if (!m_communication->SupportsSourceLogicalAddress(transmitData.initiator)) + { + if (transmitData.initiator == CECDEVICE_UNREGISTERED && m_communication->SupportsSourceLogicalAddress(CECDEVICE_FREEUSE)) + { + m_libcec->AddLog(CEC_LOG_DEBUG, "initiator '%s' is not supported by the CEC adapter. using '%s' instead", ToString(transmitData.initiator), ToString(CECDEVICE_FREEUSE)); + transmitData.initiator = CECDEVICE_FREEUSE; + } + else + { + m_libcec->AddLog(CEC_LOG_DEBUG, "initiator '%s' is not supported by the CEC adapter", ToString(transmitData.initiator)); + return false; + } + } + + LogOutput(transmitData); // find the initiator device - CCECBusDevice *initiator = m_busDevices->At(data.initiator); + CCECBusDevice *initiator = m_busDevices->At(transmitData.initiator); if (!initiator) { m_libcec->AddLog(CEC_LOG_WARNING, "invalid initiator"); @@ -384,10 +397,10 @@ bool CCECProcessor::Transmit(const cec_command &data) } // find the destination device, if it's not the broadcast address - if (data.destination != CECDEVICE_BROADCAST) + if (transmitData.destination != CECDEVICE_BROADCAST) { // check if the device is marked as handled by libCEC - CCECBusDevice *destination = m_busDevices->At(data.destination); + CCECBusDevice *destination = m_busDevices->At(transmitData.destination); if (destination && destination->IsHandledByLibCEC()) { // and reject the command if it's trying to send data to a device that is handled by libCEC @@ -407,11 +420,11 @@ bool CCECProcessor::Transmit(const cec_command &data) // and try to send the command while (bRetry && ++iTries < iMaxTries) { - if (initiator->IsUnsupportedFeature(data.opcode)) + if (initiator->IsUnsupportedFeature(transmitData.opcode)) return false; adapterState = !IsStopped() && m_communication && m_communication->IsOpen() ? - m_communication->Write(data, bRetry, iLineTimeout) : + m_communication->Write(transmitData, bRetry, iLineTimeout, bIsReply) : ADAPTER_MESSAGE_STATE_ERROR; iLineTimeout = m_iRetryLineTimeout; } @@ -428,7 +441,7 @@ void CCECProcessor::TransmitAbort(cec_logical_address source, cec_logical_addres command.parameters.PushBack((uint8_t)opcode); command.parameters.PushBack((uint8_t)reason); - Transmit(command); + Transmit(command, true); } void CCECProcessor::ProcessCommand(const cec_command &command) @@ -468,9 +481,15 @@ uint16_t CCECProcessor::GetDetectedPhysicalAddress(void) const return m_communication ? m_communication->GetPhysicalAddress() : CEC_INVALID_PHYSICAL_ADDRESS; } -bool CCECProcessor::SetAckMask(uint16_t iMask) +bool CCECProcessor::ClearLogicalAddresses(void) +{ + cec_logical_addresses addresses; addresses.Clear(); + return SetLogicalAddresses(addresses); +} + +bool CCECProcessor::SetLogicalAddresses(const cec_logical_addresses &addresses) { - return m_communication ? m_communication->SetAckMask(iMask) : false; + return m_communication ? m_communication->SetLogicalAddresses(addresses) : false; } bool CCECProcessor::StandbyDevices(const cec_logical_address initiator, const CECDEVICEVEC &devices) @@ -507,7 +526,8 @@ bool CCECProcessor::StartBootloader(const char *strPort /* = NULL */) // open a connection if no connection has been opened if (!m_communication && strPort) { - IAdapterCommunication *comm = new CUSBCECAdapterCommunication(this, strPort); + CAdapterFactory factory(this->m_libcec); + IAdapterCommunication *comm = factory.GetInstance(strPort); CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT); int iConnectTry(0); while (timeout.TimeLeft() > 0 && (bReturn = comm->Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false) @@ -551,14 +571,6 @@ bool CCECProcessor::HandleReceiveFailed(cec_logical_address initiator) return !device || !device->HandleReceiveFailed(); } -bool CCECProcessor::SetStreamPath(uint16_t iPhysicalAddress) -{ - // stream path changes are sent by the TV - bool bReturn = GetTV()->GetHandler()->TransmitSetStreamPath(iPhysicalAddress); - GetTV()->MarkHandlerReady(); - return bReturn; -} - bool CCECProcessor::CanPersistConfiguration(void) { return m_communication ? m_communication->GetFirmwareVersion() >= 2 : false; @@ -566,7 +578,15 @@ bool CCECProcessor::CanPersistConfiguration(void) bool CCECProcessor::PersistConfiguration(const libcec_configuration &configuration) { - return m_communication ? m_communication->PersistConfiguration(configuration) : false; + libcec_configuration persistConfiguration = configuration; + if (!CLibCEC::IsValidPhysicalAddress(configuration.iPhysicalAddress)) + { + CCECBusDevice *device = GetPrimaryDevice(); + if (device) + persistConfiguration.iPhysicalAddress = device->GetCurrentPhysicalAddress(); + } + + return m_communication ? m_communication->PersistConfiguration(persistConfiguration) : false; } void CCECProcessor::RescanActiveDevices(void) @@ -636,15 +656,17 @@ bool CCECProcessor::RegisterClient(CCECClient *client) return false; } - // ensure that we know the vendor id of the TV - CCECBusDevice *tv = GetTV(); - tv->GetVendorId(CECDEVICE_UNREGISTERED); - tv->ReplaceHandler(false); - // unregister the client first if it's already been marked as registered if (client->IsRegistered()) UnregisterClient(client); + // ensure that we know the vendor id of the TV + CCECBusDevice *tv = GetTV(); + if (m_communication->SupportsSourceLogicalAddress(CECDEVICE_UNREGISTERED)) + tv->GetVendorId(CECDEVICE_UNREGISTERED); + else if (m_communication->SupportsSourceLogicalAddress(CECDEVICE_FREEUSE)) + tv->GetVendorId(CECDEVICE_FREEUSE); + // get the configuration from the client m_libcec->AddLog(CEC_LOG_NOTICE, "registering new CEC client - v%s", ToString((cec_client_version)configuration.clientVersion)); @@ -653,13 +675,13 @@ bool CCECProcessor::RegisterClient(CCECClient *client) client->SetInitialised(false); // get the current ackmask, so we can restore it if polling fails - uint16_t iPreviousMask(m_communication->GetAckMask()); + cec_logical_addresses previousMask = GetLogicalAddresses(); // find logical addresses for this client if (!client->AllocateLogicalAddresses()) { m_libcec->AddLog(CEC_LOG_ERROR, "failed to register the new CEC client - cannot allocate the requested device types"); - SetAckMask(iPreviousMask); + SetLogicalAddresses(previousMask); return false; } @@ -701,7 +723,7 @@ bool CCECProcessor::RegisterClient(CCECClient *client) client->SetRegistered(true); // set the new ack mask - bool bReturn = SetAckMask(GetLogicalAddresses().AckMask()) && + bool bReturn = SetLogicalAddresses(GetLogicalAddresses()) && // and initialise the client client->OnRegister(); @@ -762,7 +784,7 @@ bool CCECProcessor::UnregisterClient(CCECClient *client) } // set the new ackmask - return SetAckMask(GetLogicalAddresses().AckMask()); + return SetLogicalAddresses(GetLogicalAddresses());; } void CCECProcessor::UnregisterClients(void) diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 5f496d2..5aa532b 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -32,7 +32,6 @@ */ #include -#include "../../include/cectypes.h" #include "platform/threads/threads.h" #include "platform/util/buffer.h" @@ -89,7 +88,6 @@ namespace CEC cec_logical_address GetActiveSource(bool bRequestActiveSource = true); bool IsActiveSource(cec_logical_address iAddress); bool CECInitialised(void); - bool SetStreamPath(uint16_t iPhysicalAddress); bool StandbyDevices(const cec_logical_address initiator, const CECDEVICEVEC &devices); bool StandbyDevice(const cec_logical_address initiator, cec_logical_address address); @@ -109,7 +107,7 @@ namespace CEC bool SetLineTimeout(uint8_t iTimeout); - bool Transmit(const cec_command &data); + bool Transmit(const cec_command &data, bool bIsReply); void TransmitAbort(cec_logical_address source, cec_logical_address destination, cec_opcode opcode, cec_abort_reason reason = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE); bool StartBootloader(const char *strPort = NULL); @@ -126,7 +124,7 @@ namespace CEC bool IsHandledByLibCEC(const cec_logical_address address) const; - bool TryLogicalAddress(cec_logical_address address); + bool TryLogicalAddress(cec_logical_address address, cec_version libCECSpecVersion = CEC_VERSION_1_4); bool IsRunningLatestFirmware(void); private: @@ -135,7 +133,9 @@ namespace CEC void ReplaceHandlers(void); bool PhysicalAddressInUse(uint16_t iPhysicalAddress); - bool SetAckMask(uint16_t iMask); + + bool ClearLogicalAddresses(void); + bool SetLogicalAddresses(const cec_logical_addresses &addresses); void LogOutput(const cec_command &data); void ProcessCommand(const cec_command &command); diff --git a/src/lib/CECTypeUtils.h b/src/lib/CECTypeUtils.h index a62637b..f088796 100644 --- a/src/lib/CECTypeUtils.h +++ b/src/lib/CECTypeUtils.h @@ -31,8 +31,6 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cectypes.h" - namespace CEC { class CCECTypeUtils @@ -510,6 +508,8 @@ namespace CEC return "Sharp"; case CEC_VENDOR_VIZIO: return "Vizio"; + case CEC_VENDOR_BROADCOM: + return "Broadcom"; default: return "Unknown"; } @@ -541,6 +541,10 @@ namespace CEC return "1.7.0"; case CEC_CLIENT_VERSION_1_7_1: return "1.7.1"; + case CEC_CLIENT_VERSION_1_7_2: + return "1.7.2"; + case CEC_CLIENT_VERSION_1_8_0: + return "1.8.0"; default: return "Unknown"; } @@ -572,6 +576,10 @@ namespace CEC return "1.7.0"; case CEC_SERVER_VERSION_1_7_1: return "1.7.1"; + case CEC_SERVER_VERSION_1_7_2: + return "1.7.2"; + case CEC_SERVER_VERSION_1_8_0: + return "1.8.0"; default: return "Unknown"; } @@ -595,5 +603,174 @@ namespace CEC return "unknown"; } } + + static const char *ToString(const cec_user_control_code key) + { + switch (key) + { + case CEC_USER_CONTROL_CODE_SELECT: + return "select"; + case CEC_USER_CONTROL_CODE_UP: + return "up"; + case CEC_USER_CONTROL_CODE_DOWN: + return "down"; + case CEC_USER_CONTROL_CODE_LEFT: + return "left"; + case CEC_USER_CONTROL_CODE_RIGHT: + return "right"; + case CEC_USER_CONTROL_CODE_RIGHT_UP: + return "right+up"; + case CEC_USER_CONTROL_CODE_RIGHT_DOWN: + return "right+down"; + case CEC_USER_CONTROL_CODE_LEFT_UP: + return "left+up"; + case CEC_USER_CONTROL_CODE_LEFT_DOWN: + return "left+down"; + case CEC_USER_CONTROL_CODE_ROOT_MENU: + return "root menu"; + case CEC_USER_CONTROL_CODE_SETUP_MENU: + return "setup menu"; + case CEC_USER_CONTROL_CODE_CONTENTS_MENU: + return "contents menu"; + case CEC_USER_CONTROL_CODE_FAVORITE_MENU: + return "favourite menu"; + case CEC_USER_CONTROL_CODE_EXIT: + return "exit"; + case CEC_USER_CONTROL_CODE_NUMBER0: + return "0"; + case CEC_USER_CONTROL_CODE_NUMBER1: + return "1"; + case CEC_USER_CONTROL_CODE_NUMBER2: + return "2"; + case CEC_USER_CONTROL_CODE_NUMBER3: + return "3"; + case CEC_USER_CONTROL_CODE_NUMBER4: + return "4"; + case CEC_USER_CONTROL_CODE_NUMBER5: + return "5"; + case CEC_USER_CONTROL_CODE_NUMBER6: + return "6"; + case CEC_USER_CONTROL_CODE_NUMBER7: + return "7"; + case CEC_USER_CONTROL_CODE_NUMBER8: + return "8"; + case CEC_USER_CONTROL_CODE_NUMBER9: + return "9"; + case CEC_USER_CONTROL_CODE_DOT: + return "."; + case CEC_USER_CONTROL_CODE_ENTER: + return "enter"; + case CEC_USER_CONTROL_CODE_CLEAR: + return "clear"; + case CEC_USER_CONTROL_CODE_NEXT_FAVORITE: + return "next favourite"; + case CEC_USER_CONTROL_CODE_CHANNEL_UP: + return "channel up"; + case CEC_USER_CONTROL_CODE_CHANNEL_DOWN: + return "channel down"; + case CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL: + return "previous channel"; + case CEC_USER_CONTROL_CODE_SOUND_SELECT: + return "sound select"; + case CEC_USER_CONTROL_CODE_INPUT_SELECT: + return "input select"; + case CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION: + return "display information"; + case CEC_USER_CONTROL_CODE_HELP: + return "help"; + case CEC_USER_CONTROL_CODE_PAGE_UP: + return "page up"; + case CEC_USER_CONTROL_CODE_PAGE_DOWN: + return "page down"; + case CEC_USER_CONTROL_CODE_POWER: + return "power"; + case CEC_USER_CONTROL_CODE_VOLUME_UP: + return "volume up"; + case CEC_USER_CONTROL_CODE_VOLUME_DOWN: + return "volume down"; + case CEC_USER_CONTROL_CODE_MUTE: + return "mute"; + case CEC_USER_CONTROL_CODE_PLAY: + return "play"; + case CEC_USER_CONTROL_CODE_STOP: + return "stop"; + case CEC_USER_CONTROL_CODE_PAUSE: + return "pause"; + case CEC_USER_CONTROL_CODE_RECORD: + return "record"; + case CEC_USER_CONTROL_CODE_REWIND: + return "rewind"; + case CEC_USER_CONTROL_CODE_FAST_FORWARD: + return "Fast forward"; + case CEC_USER_CONTROL_CODE_EJECT: + return "eject"; + case CEC_USER_CONTROL_CODE_FORWARD: + return "forward"; + case CEC_USER_CONTROL_CODE_BACKWARD: + return "backward"; + case CEC_USER_CONTROL_CODE_STOP_RECORD: + return "stop record"; + case CEC_USER_CONTROL_CODE_PAUSE_RECORD: + return "pause record"; + case CEC_USER_CONTROL_CODE_ANGLE: + return "angle"; + case CEC_USER_CONTROL_CODE_SUB_PICTURE: + return "sub picture"; + case CEC_USER_CONTROL_CODE_VIDEO_ON_DEMAND: + return "video on demand"; + case CEC_USER_CONTROL_CODE_ELECTRONIC_PROGRAM_GUIDE: + return "electronic program guide"; + case CEC_USER_CONTROL_CODE_TIMER_PROGRAMMING: + return "timer programming"; + case CEC_USER_CONTROL_CODE_INITIAL_CONFIGURATION: + return "initial configuration"; + case CEC_USER_CONTROL_CODE_PLAY_FUNCTION: + return "play (function)"; + case CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION: + return "pause play (function)"; + case CEC_USER_CONTROL_CODE_RECORD_FUNCTION: + return "record (function)"; + case CEC_USER_CONTROL_CODE_PAUSE_RECORD_FUNCTION: + return "pause record (function)"; + case CEC_USER_CONTROL_CODE_STOP_FUNCTION: + return "stop (function)"; + case CEC_USER_CONTROL_CODE_MUTE_FUNCTION: + return "mute (function)"; + case CEC_USER_CONTROL_CODE_RESTORE_VOLUME_FUNCTION: + return "restore volume"; + case CEC_USER_CONTROL_CODE_TUNE_FUNCTION: + return "tune"; + case CEC_USER_CONTROL_CODE_SELECT_MEDIA_FUNCTION: + return "select media"; + case CEC_USER_CONTROL_CODE_SELECT_AV_INPUT_FUNCTION: + return "select AV input"; + case CEC_USER_CONTROL_CODE_SELECT_AUDIO_INPUT_FUNCTION: + return "select audio input"; + case CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION: + return "power toggle"; + case CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION: + return "power off"; + case CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION: + return "power on"; + case CEC_USER_CONTROL_CODE_F1_BLUE: + return "F1 (blue)"; + case CEC_USER_CONTROL_CODE_F2_RED: + return "F2 (red)"; + case CEC_USER_CONTROL_CODE_F3_GREEN: + return "F3 (green)"; + case CEC_USER_CONTROL_CODE_F4_YELLOW: + return "F4 (yellow)"; + case CEC_USER_CONTROL_CODE_F5: + return "F5"; + case CEC_USER_CONTROL_CODE_DATA: + return "data"; + case CEC_USER_CONTROL_CODE_AN_RETURN: + return "return (Samsung)"; + case CEC_USER_CONTROL_CODE_AN_CHANNELS_LIST: + return "channels list (Samsung)"; + default: + return "unknown"; + } + } }; } diff --git a/src/lib/LibCEC.cpp b/src/lib/LibCEC.cpp index c0931c3..ad4ce66 100644 --- a/src/lib/LibCEC.cpp +++ b/src/lib/LibCEC.cpp @@ -30,10 +30,11 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "LibCEC.h" -#include "adapter/USBCECAdapterDetection.h" -#include "adapter/USBCECAdapterCommunication.h" +#include "adapter/AdapterFactory.h" +#include "adapter/AdapterCommunication.h" #include "CECProcessor.h" #include "CECTypeUtils.h" #include "devices/CECAudioSystem.h" @@ -114,13 +115,7 @@ void CLibCEC::Close(void) int8_t CLibCEC::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */) { - if (!CUSBCECAdapterDetection::CanAutodetect()) - { - AddLog(CEC_LOG_WARNING, "libCEC has not been compiled with adapter detection code for this target, so the path to the COM port has to be provided to libCEC"); - return 0; - } - - return CUSBCECAdapterDetection::FindAdapters(deviceList, iBufSize, strDevicePath); + return CAdapterFactory(this).FindAdapters(deviceList, iBufSize, strDevicePath); } bool CLibCEC::StartBootloader(void) @@ -171,7 +166,7 @@ bool CLibCEC::IsLibCECActiveSource(void) bool CLibCEC::Transmit(const cec_command &data) { - return m_client ? m_client->Transmit(data) : false; + return m_client ? m_client->Transmit(data, false) : false; } bool CLibCEC::SetLogicalAddress(cec_logical_address iLogicalAddress) @@ -578,7 +573,7 @@ void * CECCreate(const char *strDeviceName, CEC::cec_logical_address iLogicalAdd // client version < 1.5.0 snprintf(configuration.strDeviceName, 13, "%s", strDeviceName); configuration.iPhysicalAddress = iPhysicalAddress; - configuration.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE); + configuration.deviceTypes.Add(CCECTypeUtils::GetType(iLogicalAddress)); return CECInitialise(&configuration); } @@ -587,17 +582,24 @@ bool CECStartBootloader(void) { bool bReturn(false); cec_adapter deviceList[1]; - if (CUSBCECAdapterDetection::FindAdapters(deviceList, 1) > 0) + if (CAdapterFactory(NULL).FindAdapters(deviceList, 1, 0) > 0) { - CUSBCECAdapterCommunication comm(NULL, deviceList[0].comm); - CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT); - while (timeout.TimeLeft() > 0 && (bReturn = comm.Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false) + CAdapterFactory factory(NULL); + IAdapterCommunication *comm = factory.GetInstance(deviceList[0].comm); + if (comm) { - comm.Close(); - CEvent::Sleep(500); + CTimeout timeout(CEC_DEFAULT_CONNECT_TIMEOUT); + while (timeout.TimeLeft() > 0 && + (bReturn = comm->Open(timeout.TimeLeft() / CEC_CONNECT_TRIES, true)) == false) + { + comm->Close(); + CEvent::Sleep(500); + } + if (comm->IsOpen()) + bReturn = comm->StartBootloader(); + + delete comm; } - if (comm.IsOpen()) - bReturn = comm.StartBootloader(); } return bReturn; @@ -616,6 +618,37 @@ bool CLibCEC::GetDeviceInformation(const char *strPort, libcec_configuration *co return m_cec->GetDeviceInformation(strPort, config, iTimeoutMs); } +const char *CLibCEC::GetLibInfo(void) +{ +#ifndef LIB_INFO +#ifdef _WIN32 +#define FEATURES "'P8 USB' 'P8 USB detect'" +#ifdef _WIN64 +#define HOST_TYPE "Windows (x64)" +#else +#define HOST_TYPE "Windows (x86)" +#endif +#else +#define HOST_TYPE "unknown" +#define FEATURES "unknown" +#endif + + return "host: " HOST_TYPE ", features: " FEATURES ", compiled: " __DATE__; +#else + return LIB_INFO; +#endif +} + +const char *CLibCEC::ToString(const cec_user_control_code key) +{ + return CCECTypeUtils::ToString(key); +} + +void CLibCEC::InitVideoStandalone(void) +{ + CAdapterFactory::InitVideoStandalone(); +} + // no longer being used void CLibCEC::AddKey(const cec_keypress &UNUSED(key)) {} void CLibCEC::ConfigurationChanged(const libcec_configuration &UNUSED(config)) {} diff --git a/src/lib/LibCEC.h b/src/lib/LibCEC.h index 6407e57..76d2919 100644 --- a/src/lib/LibCEC.h +++ b/src/lib/LibCEC.h @@ -32,7 +32,7 @@ */ #include -#include "../../include/cec.h" +#include "cec.h" #include "platform/util/buffer.h" namespace CEC @@ -146,6 +146,9 @@ namespace CEC CCECClient *RegisterClient(libcec_configuration &configuration); void UnregisterClients(void); std::vector GetClients(void) { return m_clients; }; + const char *GetLibInfo(void); + const char *ToString(const cec_user_control_code key); + void InitVideoStandalone(void); CCECProcessor * m_cec; diff --git a/src/lib/LibCECC.cpp b/src/lib/LibCECC.cpp index 4a7e0be..2576da0 100644 --- a/src/lib/LibCECC.cpp +++ b/src/lib/LibCECC.cpp @@ -30,8 +30,9 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cec.h" -#include "../../include/cecc.h" +#include "env.h" +#include "cec.h" +#include "cecc.h" using namespace CEC; using namespace std; @@ -426,4 +427,15 @@ int cec_get_device_information(const char *strPort, CEC::libcec_configuration *c return cec_parser ? (cec_parser->GetDeviceInformation(strPort, config, iTimeoutMs) ? 1 : 0) : -1; } +const char * cec_get_lib_info(void) +{ + return cec_parser ? cec_parser->GetLibInfo() : NULL; +} + +void cec_init_video_standalone(void) +{ + if (cec_parser) + cec_parser->InitVideoStandalone(); +} + //@} diff --git a/src/lib/LibCECDll.cpp b/src/lib/LibCECDll.cpp index 819d609..9657b57 100644 --- a/src/lib/LibCECDll.cpp +++ b/src/lib/LibCECDll.cpp @@ -30,6 +30,7 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "platform/os.h" int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 3d34f83..d4340ec 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -8,15 +8,12 @@ library_include_HEADERS = ../../include/cec.h \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcec.pc +## libCEC core libcec_la_SOURCES = CECProcessor.cpp \ LibCEC.cpp \ LibCECC.cpp \ CECClient.cpp \ - adapter/USBCECAdapterCommands.cpp \ - adapter/USBCECAdapterCommunication.cpp \ - adapter/USBCECAdapterDetection.cpp \ - adapter/USBCECAdapterMessage.cpp \ - adapter/USBCECAdapterMessageQueue.cpp \ + adapter/AdapterFactory.cpp \ devices/CECAudioSystem.cpp \ devices/CECBusDevice.cpp \ devices/CECDeviceMap.cpp \ @@ -28,12 +25,22 @@ libcec_la_SOURCES = CECProcessor.cpp \ implementations/CECCommandHandler.cpp \ implementations/SLCommandHandler.cpp \ implementations/VLCommandHandler.cpp \ - implementations/RLCommandHandler.cpp \ - platform/posix/serialport.cpp \ - platform/posix/serversocket.cpp\ - platform/posix/os-edid.cpp \ - platform/adl/adl-edid.cpp \ - platform/nvidia/nv-edid.cpp - + implementations/RLCommandHandler.cpp + +## server sockets, currently unused +##libcec_la_SOURCES += platform/posix/serversocket.cpp + +## Pulse-Eight USB-CEC support +if USE_P8_USB +libcec_la_SOURCES += adapter/Pulse-Eight/USBCECAdapterMessage.cpp \ + adapter/Pulse-Eight/USBCECAdapterCommands.cpp \ + adapter/Pulse-Eight/USBCECAdapterCommunication.cpp \ + adapter/Pulse-Eight/USBCECAdapterMessageQueue.cpp \ + adapter/Pulse-Eight/USBCECAdapterDetection.cpp \ + platform/posix/serialport.cpp \ + platform/posix/os-edid.cpp \ + platform/adl/adl-edid.cpp \ + platform/nvidia/nv-edid.cpp +endif + libcec_la_LDFLAGS = @LIBS_LIBCEC@ -version-info @VERSION@ -libcec_la_CPPFLAGS = -I@abs_top_srcdir@/include diff --git a/src/lib/adapter/AdapterCommunication.h b/src/lib/adapter/AdapterCommunication.h index 11af5e7..03880b6 100644 --- a/src/lib/adapter/AdapterCommunication.h +++ b/src/lib/adapter/AdapterCommunication.h @@ -31,13 +31,23 @@ * http://www.pulse-eight.net/ */ -#include "../platform/util/StdString.h" -#include "USBCECAdapterMessage.h" +#include namespace CEC { class CLibCEC; + typedef enum cec_adapter_message_state + { + ADAPTER_MESSAGE_STATE_UNKNOWN = 0, /**< the initial state */ + ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT, /**< waiting in the send queue of the adapter, or timed out */ + ADAPTER_MESSAGE_STATE_SENT, /**< sent and waiting on an ACK */ + ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED, /**< sent, but failed to ACK */ + ADAPTER_MESSAGE_STATE_SENT_ACKED, /**< sent, and ACK received */ + ADAPTER_MESSAGE_STATE_INCOMING, /**< received from another device */ + ADAPTER_MESSAGE_STATE_ERROR /**< an error occured */ + } cec_adapter_message_state; + class IAdapterCommunicationCallback { public: @@ -100,16 +110,17 @@ namespace CEC /*! * @return The last error message, or an empty string if there was none */ - virtual CStdString GetError(void) const = 0; + virtual std::string GetError(void) const = 0; /*! * @brief Write a cec_command to the adapter * @param data The command to write * @param bRetry The command can be retried * @param iLineTimeout The line timeout to be used + * @param bIsReply True when this message is a reply, false otherwise * @return The last state of the transmitted command */ - virtual cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout = 3) = 0; + virtual cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply) = 0; /*! * @brief Change the current line timeout on the CEC bus @@ -124,13 +135,8 @@ namespace CEC */ virtual bool StartBootloader(void) = 0; - /*! - * @brief Change the ACK-mask of the device, the mask for logical addresses to which the CEC device should ACK - * @param iMask The new mask - * @return True when set, false otherwise. - */ - virtual bool SetAckMask(uint16_t iMask) = 0; - virtual uint16_t GetAckMask(void) = 0; + virtual bool SetLogicalAddresses(const cec_logical_addresses &addresses) = 0; + virtual cec_logical_addresses GetLogicalAddresses(void) = 0; /*! * @brief Check whether the CEC adapter responds @@ -175,13 +181,25 @@ namespace CEC /*! * @return The name of the port */ - virtual CStdString GetPortName(void) = 0; + virtual std::string GetPortName(void) = 0; /*! * @return The physical address, if the adapter supports this. 0 otherwise. */ virtual uint16_t GetPhysicalAddress(void) = 0; + /*! + * @return The vendor id for this device + */ + virtual cec_vendor_id GetVendorId(void) = 0; + + /*! + * @brief Checks whether a logical address is supported by the adapter. + * @param address The address to check. + * @return True when supported, false otherwise. + */ + virtual bool SupportsSourceLogicalAddress(const cec_logical_address address) = 0; + IAdapterCommunicationCallback *m_callback; }; }; diff --git a/src/lib/adapter/AdapterFactory.cpp b/src/lib/adapter/AdapterFactory.cpp new file mode 100644 index 0000000..ec216ab --- /dev/null +++ b/src/lib/adapter/AdapterFactory.cpp @@ -0,0 +1,84 @@ +/* + * This file is part of the libCEC(R) library. + * + * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is an original work, containing original code. + * + * libCEC(R) is a trademark of Pulse-Eight Limited. + * + * This program is dual-licensed; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Alternatively, you can license this library under a commercial license, + * please contact Pulse-Eight Licensing for more information. + * + * For more information contact: + * Pulse-Eight Licensing + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include "env.h" +#include "AdapterFactory.h" + +#include +#include "lib/LibCEC.h" +#include "lib/CECProcessor.h" + +#if defined(HAVE_P8_USB) +#include "Pulse-Eight/USBCECAdapterDetection.h" +#include "Pulse-Eight/USBCECAdapterCommunication.h" +#endif + +using namespace std; +using namespace CEC; + +int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */) +{ + int8_t iAdaptersFound(0); + +#if defined(HAVE_P8_USB) + if (!CUSBCECAdapterDetection::CanAutodetect()) + { + if (m_lib) + m_lib->AddLog(CEC_LOG_WARNING, "libCEC has not been compiled with detection code for the Pulse-Eight USB-CEC Adapter, so the path to the COM port has to be provided to libCEC if this adapter is being used"); + } + else + iAdaptersFound += CUSBCECAdapterDetection::FindAdapters(deviceList, iBufSize, strDevicePath); +#else + m_lib->AddLog(CEC_LOG_WARNING, "libCEC has not been compiled with support for the Pulse-Eight USB-CEC Adapter"); +#endif + +#if !defined(HAVE_P8_USB) +#error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" +#endif + + return iAdaptersFound; +} + +IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_t iBaudRate) +{ +#if defined(HAVE_P8_USB) + return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate); +#endif + +#if !defined(HAVE_P8_USB) + return NULL; +#endif +} + +void CAdapterFactory::InitVideoStandalone(void) +{ +} diff --git a/src/lib/adapter/AdapterFactory.h b/src/lib/adapter/AdapterFactory.h new file mode 100644 index 0000000..d8a1360 --- /dev/null +++ b/src/lib/adapter/AdapterFactory.h @@ -0,0 +1,57 @@ +#pragma once +/* + * This file is part of the libCEC(R) library. + * + * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is an original work, containing original code. + * + * libCEC(R) is a trademark of Pulse-Eight Limited. + * + * This program is dual-licensed; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * Alternatively, you can license this library under a commercial license, + * please contact Pulse-Eight Licensing for more information. + * + * For more information contact: + * Pulse-Eight Licensing + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include +#include + +namespace CEC +{ + class CLibCEC; + class IAdapterCommunication; + + class CAdapterFactory + { + public: + CAdapterFactory(CLibCEC *lib) : + m_lib(lib) {} + virtual ~CAdapterFactory(void) {}; + + int8_t FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath = NULL); + IAdapterCommunication *GetInstance(const char *strPort, uint16_t iBaudRate = CEC_SERIAL_DEFAULT_BAUDRATE); + + static void InitVideoStandalone(void); + + private: + CLibCEC *m_lib; + }; +} diff --git a/src/lib/adapter/USBCECAdapterCommands.cpp b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.cpp similarity index 92% rename from src/lib/adapter/USBCECAdapterCommands.cpp rename to src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.cpp index 6642ac8..bbd15d4 100644 --- a/src/lib/adapter/USBCECAdapterCommands.cpp +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.cpp @@ -30,10 +30,15 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "USBCECAdapterCommands.h" -#include "../LibCEC.h" -#include "../CECProcessor.h" -#include "../CECTypeUtils.h" + +#include "USBCECAdapterMessage.h" +#include "USBCECAdapterCommunication.h" +#include "lib/LibCEC.h" +#include "lib/CECProcessor.h" +#include "lib/CECTypeUtils.h" +#include using namespace CEC; using namespace PLATFORM; @@ -222,14 +227,11 @@ bool CUSBCECAdapterCommands::RequestSettingPhysicalAddress(void) bool CUSBCECAdapterCommands::SetSettingAutoEnabled(bool enabled) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_bSettingAutoEnabled == enabled) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "autonomous mode setting unchanged (%s)", enabled ? "on" : "off"); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "turning autonomous mode %s", enabled ? "on" : "off"); @@ -248,14 +250,11 @@ bool CUSBCECAdapterCommands::SetSettingAutoEnabled(bool enabled) bool CUSBCECAdapterCommands::SetSettingDeviceType(cec_device_type type) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_persistedConfiguration.deviceTypes.types[0] == type) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "device type setting unchanged (%X)", (uint8_t)type); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the device type to %X (previous: %X)", (uint8_t)type, (uint8_t)m_persistedConfiguration.deviceTypes.types[0]); @@ -271,14 +270,11 @@ bool CUSBCECAdapterCommands::SetSettingDeviceType(cec_device_type type) bool CUSBCECAdapterCommands::SetSettingDefaultLogicalAddress(cec_logical_address address) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_persistedConfiguration.logicalAddresses.primary == address) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "logical address setting unchanged (%X)", (uint8_t)address); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the default logical address to %X (previous: %X)", (uint8_t)address, (uint8_t)m_persistedConfiguration.logicalAddresses.primary); @@ -297,14 +293,11 @@ bool CUSBCECAdapterCommands::SetSettingDefaultLogicalAddress(cec_logical_address bool CUSBCECAdapterCommands::SetSettingLogicalAddressMask(uint16_t iMask) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_iSettingLAMask == iMask) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "logical address mask setting unchanged (%2X)", iMask); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the logical address mask to %2X (previous: %2X)", iMask, m_iSettingLAMask); @@ -324,14 +317,11 @@ bool CUSBCECAdapterCommands::SetSettingLogicalAddressMask(uint16_t iMask) bool CUSBCECAdapterCommands::SetSettingPhysicalAddress(uint16_t iPhysicalAddress) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_persistedConfiguration.iPhysicalAddress == iPhysicalAddress) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "physical address setting unchanged (%04X)", iPhysicalAddress); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the physical address to %04X (previous: %04X)", iPhysicalAddress, m_persistedConfiguration.iPhysicalAddress); @@ -351,14 +341,11 @@ bool CUSBCECAdapterCommands::SetSettingPhysicalAddress(uint16_t iPhysicalAddress bool CUSBCECAdapterCommands::SetSettingCECVersion(cec_version version) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (m_settingCecVersion == version) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "CEC version setting unchanged (%s)", ToString(version)); return bReturn; - } m_bNeedsWrite = true; LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the CEC version to %s (previous: %s)", ToString(version), ToString(m_settingCecVersion)); @@ -377,14 +364,11 @@ bool CUSBCECAdapterCommands::SetSettingCECVersion(cec_version version) bool CUSBCECAdapterCommands::SetSettingOSDName(const char *strOSDName) { - bool bReturn(true); + bool bReturn(false); /* check whether this value was changed */ if (!strcmp(m_persistedConfiguration.strDeviceName, strOSDName)) - { - LIB_CEC->AddLog(CEC_LOG_DEBUG, "OSD name setting unchanged (%s)", strOSDName); return bReturn; - } LIB_CEC->AddLog(CEC_LOG_DEBUG, "setting the OSD name to %s (previous: %s)", strOSDName, m_persistedConfiguration.strDeviceName); @@ -417,21 +401,21 @@ bool CUSBCECAdapterCommands::WriteEEPROM(void) bool CUSBCECAdapterCommands::PersistConfiguration(const libcec_configuration &configuration) { + bool bReturn(false); if (m_persistedConfiguration.iFirmwareVersion < 2) - return false; + return bReturn; if (!RequestSettings()) - return false; + return bReturn; + + bReturn |= SetSettingAutoEnabled(true); + bReturn |= SetSettingDeviceType(CLibCEC::GetType(configuration.logicalAddresses.primary)); + bReturn |= SetSettingDefaultLogicalAddress(configuration.logicalAddresses.primary); + bReturn |= SetSettingLogicalAddressMask(CLibCEC::GetMaskForType(configuration.logicalAddresses.primary)); + bReturn |= SetSettingPhysicalAddress(configuration.iPhysicalAddress); + bReturn |= SetSettingCECVersion(configuration.clientVersion >= CEC_CLIENT_VERSION_1_8_0 ? configuration.cecVersion : CEC_VERSION_1_4); + bReturn |= SetSettingOSDName(configuration.strDeviceName); - bool bReturn(true); - bReturn &= SetSettingAutoEnabled(true); - bReturn &= SetSettingDeviceType(CLibCEC::GetType(configuration.logicalAddresses.primary)); - bReturn &= SetSettingDefaultLogicalAddress(configuration.logicalAddresses.primary); - bReturn &= SetSettingLogicalAddressMask(CLibCEC::GetMaskForType(configuration.logicalAddresses.primary)); - bReturn &= SetSettingPhysicalAddress(configuration.iPhysicalAddress); - bReturn &= SetSettingCECVersion(CEC_VERSION_1_3A); - bReturn &= SetSettingOSDName(configuration.strDeviceName); - bReturn &= WriteEEPROM(); return bReturn; } diff --git a/src/lib/adapter/USBCECAdapterCommands.h b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.h similarity index 93% rename from src/lib/adapter/USBCECAdapterCommands.h rename to src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.h index 70feae9..ff0c187 100644 --- a/src/lib/adapter/USBCECAdapterCommands.h +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommands.h @@ -31,10 +31,10 @@ * http://www.pulse-eight.net/ */ -#include "USBCECAdapterCommunication.h" - namespace CEC { + class CUSBCECAdapterCommunication; + class CUSBCECAdapterCommands { public: @@ -52,10 +52,10 @@ namespace CEC uint16_t GetFirmwareVersion(void) const { return m_persistedConfiguration.iFirmwareVersion; }; /*! - * @brief Persist the current configuration in the EEPROM. + * @brief Update the current configuration in the adapter. Does not do an eeprom update. * @attention Not all settings are persisted at this time. * @param configuration The configuration to persist. - * @return True when persisted, false otherwise. + * @return True when something changed, false otherwise. */ bool PersistConfiguration(const libcec_configuration &configuration); @@ -111,6 +111,12 @@ namespace CEC */ uint32_t GetPersistedBuildDate(void) const { return m_iBuildDate; }; + /*! + * @brief Persist the current settings in the EEPROM + * @return True when persisted, false otherwise. + */ + bool WriteEEPROM(void); + private: /*! * @brief Reads all settings from the eeprom. @@ -128,7 +134,7 @@ namespace CEC /*! * @brief Change the value of the "auto enabled" setting. * @param enabled The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingAutoEnabled(bool enabled); @@ -141,7 +147,7 @@ namespace CEC /*! * @brief Change the value of the "device type" setting, used when the device is in autonomous mode. * @param type The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingDeviceType(cec_device_type type); @@ -154,7 +160,7 @@ namespace CEC /*! * @brief Change the value of the "default logical address" setting, used when the device is in autonomous mode. * @param address The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingDefaultLogicalAddress(cec_logical_address address); @@ -167,7 +173,7 @@ namespace CEC /*! * @brief Change the value of the "logical address mask" setting, used when the device is in autonomous mode. * @param iMask The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingLogicalAddressMask(uint16_t iMask); @@ -180,7 +186,7 @@ namespace CEC /*! * @brief Change the value of the "physical address" setting, used when the device is in autonomous mode. * @param iPhysicalAddress The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingPhysicalAddress(uint16_t iPhysicalAddress); @@ -193,7 +199,7 @@ namespace CEC /*! * @brief Change the value of the "CEC version" setting, used when the device is in autonomous mode. * @param version The new value. - * @return True when set, false otherwise. + * @return True when changed and set, false otherwise. */ bool SetSettingCECVersion(cec_version version); @@ -216,12 +222,6 @@ namespace CEC */ bool RequestSettingOSDName(void); - /*! - * @brief Persist the current settings in the EEPROM - * @return True when persisted, false otherwise. - */ - bool WriteEEPROM(void); - CUSBCECAdapterCommunication *m_comm; /**< the communication handler */ bool m_bSettingsRetrieved; /**< true when the settings were read from the eeprom, false otherwise */ bool m_bSettingAutoEnabled; /**< the value of the auto-enabled setting */ diff --git a/src/lib/adapter/USBCECAdapterCommunication.cpp b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp similarity index 86% rename from src/lib/adapter/USBCECAdapterCommunication.cpp rename to src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp index b3f0f7d..e4806e8 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.cpp +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp @@ -30,23 +30,28 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "USBCECAdapterCommunication.h" + #include "USBCECAdapterCommands.h" #include "USBCECAdapterMessageQueue.h" -#include "../platform/sockets/serialport.h" -#include "../platform/util/timeutils.h" -#include "../platform/util/util.h" -#include "../platform/util/edid.h" -#include "../platform/adl/adl-edid.h" -#include "../platform/nvidia/nv-edid.h" -#include "../LibCEC.h" -#include "../CECProcessor.h" +#include "USBCECAdapterMessage.h" +#include "lib/platform/sockets/serialport.h" +#include "lib/platform/util/timeutils.h" +#include "lib/platform/util/util.h" +#include "lib/platform/util/edid.h" +#include "lib/platform/adl/adl-edid.h" +#include "lib/platform/nvidia/nv-edid.h" +#include "lib/LibCEC.h" +#include "lib/CECProcessor.h" using namespace std; using namespace CEC; using namespace PLATFORM; -#define CEC_ADAPTER_PING_TIMEOUT 15000 +#define CEC_ADAPTER_PING_TIMEOUT 15000 +#define CEC_ADAPTER_EEPROM_WRITE_INTERVAL 30000 +#define CEC_ADAPTER_EEPROM_WRITE_RETRY 5000 // firmware version 2 #define CEC_LATEST_ADAPTER_FW_VERSION 2 @@ -64,8 +69,10 @@ CUSBCECAdapterCommunication::CUSBCECAdapterCommunication(IAdapterCommunicationCa m_pingThread(NULL), m_commands(NULL), m_adapterMessageQueue(NULL), - m_iAckMask(0xFFFF) + m_iLastEepromWrite(0), + m_iScheduleEepromWrite(0) { + m_logicalAddresses.Clear(); for (unsigned int iPtr = CECDEVICE_TV; iPtr < CECDEVICE_BROADCAST; iPtr++) m_bWaitingForAck[iPtr] = false; m_port = new CSerialPort(strPort, iBaudRate); @@ -149,7 +156,8 @@ bool CUSBCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN } // always start by setting the ackmask to 0, to clear previous values - SetAckMask(0); + cec_logical_addresses addresses; addresses.Clear(); + SetLogicalAddresses(addresses); if (!CreateThread()) { @@ -194,7 +202,8 @@ void CUSBCECAdapterCommunication::Close(void) if (IsOpen() && m_port->GetErrorNumber() == 0) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - closing the connection", __FUNCTION__); - SetAckMask(0); + cec_logical_addresses addresses; addresses.Clear(); + SetLogicalAddresses(addresses); if (m_commands->GetFirmwareVersion() >= 2) SetControlledMode(false); } @@ -209,7 +218,7 @@ void CUSBCECAdapterCommunication::Close(void) m_port->Close(); } -cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout) +cec_adapter_message_state CUSBCECAdapterCommunication::Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool UNUSED(bIsReply)) { cec_adapter_message_state retVal(ADAPTER_MESSAGE_STATE_UNKNOWN); if (!IsRunning()) @@ -235,6 +244,7 @@ void *CUSBCECAdapterCommunication::Process(void) CCECAdapterMessage msg; LIB_CEC->AddLog(CEC_LOG_DEBUG, "communication thread started"); + bool bWriteEeprom(false); while (!IsStopped()) { /* read from the serial port */ @@ -247,6 +257,30 @@ void *CUSBCECAdapterCommunication::Process(void) break; } + // check if we need to do another eeprom write + { + CLockObject lock(m_mutex); + uint64_t iNow = GetTimeMs(); + if (m_iScheduleEepromWrite > 0 && m_iScheduleEepromWrite >= iNow) + { + m_iScheduleEepromWrite = 0; + m_iLastEepromWrite = iNow; + bWriteEeprom = true; + } + } + + if (bWriteEeprom) + { + LIB_CEC->AddLog(CEC_LOG_DEBUG, "updating the eeprom (scheduled)"); + bWriteEeprom = false; + if (!m_commands->WriteEEPROM()) + { + // failed, retry later + CLockObject lock(m_mutex); + m_iScheduleEepromWrite = GetTimeMs() + CEC_ADAPTER_EEPROM_WRITE_RETRY; + } + } + /* TODO sleep 5 ms so other threads can get a lock */ Sleep(5); } @@ -470,7 +504,7 @@ bool CUSBCECAdapterCommunication::IsOpen(void) return !IsStopped() && m_port->IsOpen() && IsRunning(); } -CStdString CUSBCECAdapterCommunication::GetError(void) const +std::string CUSBCECAdapterCommunication::GetError(void) const { return m_port->GetError(); } @@ -497,18 +531,18 @@ bool CUSBCECAdapterCommunication::StartBootloader(void) return false; } -bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) +bool CUSBCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses) { { CLockObject lock(m_mutex); - if (m_iAckMask == iMask) + if (m_logicalAddresses == addresses) return true; } - if (IsOpen() && m_commands->SetAckMask(iMask)) + if (IsOpen() && m_commands->SetAckMask(addresses.AckMask())) { CLockObject lock(m_mutex); - m_iAckMask = iMask; + m_logicalAddresses = addresses; return true; } @@ -516,10 +550,12 @@ bool CUSBCECAdapterCommunication::SetAckMask(uint16_t iMask) return false; } -uint16_t CUSBCECAdapterCommunication::GetAckMask(void) +cec_logical_addresses CUSBCECAdapterCommunication::GetLogicalAddresses(void) { + cec_logical_addresses addresses; CLockObject lock(m_mutex); - return m_iAckMask; + addresses = m_logicalAddresses; + return addresses; } bool CUSBCECAdapterCommunication::PingAdapter(void) @@ -545,6 +581,35 @@ bool CUSBCECAdapterCommunication::IsRunningLatestFirmware(void) bool CUSBCECAdapterCommunication::PersistConfiguration(const libcec_configuration &configuration) { + if (IsOpen()) + { + // returns true when something changed + if (m_commands->PersistConfiguration(configuration)) + { + { + CLockObject lock(m_mutex); + uint64_t iNow = GetTimeMs(); + if (iNow - m_iLastEepromWrite < CEC_ADAPTER_EEPROM_WRITE_INTERVAL) + { + // if there was more than 1 write within the last 30 seconds, schedule another one + if (m_iScheduleEepromWrite == 0) + m_iScheduleEepromWrite = m_iLastEepromWrite + CEC_ADAPTER_EEPROM_WRITE_INTERVAL; + return true; + } + else + { + m_iLastEepromWrite = iNow; + } + } + + if (!m_commands->WriteEEPROM()) + { + // write failed, retry later + CLockObject lock(m_mutex); + m_iScheduleEepromWrite = GetTimeMs() + CEC_ADAPTER_EEPROM_WRITE_RETRY; + } + } + } return IsOpen() ? m_commands->PersistConfiguration(configuration) : false; } @@ -553,7 +618,7 @@ bool CUSBCECAdapterCommunication::GetConfiguration(libcec_configuration &configu return IsOpen() ? m_commands->GetConfiguration(configuration) : false; } -CStdString CUSBCECAdapterCommunication::GetPortName(void) +std::string CUSBCECAdapterCommunication::GetPortName(void) { return m_port->GetName(); } diff --git a/src/lib/adapter/USBCECAdapterCommunication.h b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.h similarity index 87% rename from src/lib/adapter/USBCECAdapterCommunication.h rename to src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.h index 948f2de..a14b3a5 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.h +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterCommunication.h @@ -31,11 +31,8 @@ * http://www.pulse-eight.net/ */ -#include "../../../include/cectypes.h" -#include "../platform/threads/threads.h" -#include "../platform/util/buffer.h" -#include "AdapterCommunication.h" -#include "USBCECAdapterMessage.h" +#include "lib/platform/threads/threads.h" +#include "lib/adapter/AdapterCommunication.h" namespace PLATFORM { @@ -48,6 +45,7 @@ namespace CEC class CAdapterPingThread; class CUSBCECAdapterCommands; class CCECAdapterMessageQueue; + class CCECAdapterMessage; class CUSBCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread { @@ -69,21 +67,23 @@ namespace CEC bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true); void Close(void); bool IsOpen(void); - CStdString GetError(void) const; - cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout = 3); + std::string GetError(void) const; + cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply); bool StartBootloader(void); - bool SetAckMask(uint16_t iMask); - uint16_t GetAckMask(void); + bool SetLogicalAddresses(const cec_logical_addresses &addresses); + cec_logical_addresses GetLogicalAddresses(void); bool PingAdapter(void); uint16_t GetFirmwareVersion(void); uint32_t GetFirmwareBuildDate(void); bool IsRunningLatestFirmware(void); bool PersistConfiguration(const libcec_configuration &configuration); bool GetConfiguration(libcec_configuration &configuration); - CStdString GetPortName(void); + std::string GetPortName(void); uint16_t GetPhysicalAddress(void); bool SetControlledMode(bool controlled); + cec_vendor_id GetVendorId(void) { return CEC_VENDOR_UNKNOWN; } + bool SupportsSourceLogicalAddress(const cec_logical_address UNUSED(address)) { return true; } ///} void *Process(void); @@ -171,7 +171,9 @@ namespace CEC CAdapterPingThread * m_pingThread; /**< ping thread, that pings the adapter every 15 seconds */ CUSBCECAdapterCommands * m_commands; /**< commands that can be sent to the adapter */ CCECAdapterMessageQueue * m_adapterMessageQueue; /**< the incoming and outgoing message queue */ - uint16_t m_iAckMask; + cec_logical_addresses m_logicalAddresses; /**< the logical address list that this instance is using */ + uint64_t m_iLastEepromWrite; /**< last time that this instance did an eeprom write */ + bool m_iScheduleEepromWrite; /**< in case there were more than 2 changes within 30 seconds, do another write at this time */ }; class CAdapterPingThread : public PLATFORM::CThread diff --git a/src/lib/adapter/USBCECAdapterDetection.cpp b/src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.cpp similarity index 98% rename from src/lib/adapter/USBCECAdapterDetection.cpp rename to src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.cpp index 78b2760..f9969d8 100644 --- a/src/lib/adapter/USBCECAdapterDetection.cpp +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.cpp @@ -30,8 +30,9 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "USBCECAdapterDetection.h" -#include "../platform/util/StdString.h" +#include "lib/platform/util/StdString.h" #if defined(__APPLE__) #include @@ -348,6 +349,10 @@ uint8_t CUSBCECAdapterDetection::FindAdapters(cec_adapter *deviceList, uint8_t i snprintf(deviceList[iFound++].comm, sizeof(deviceList[iFound].path), "%s", devicePath); } } +#else + //silence "unused" warnings + void *tmp = (void*)deviceList; + tmp = (void *)strDevicePath; #endif iBufSize = 0; /* silence "unused" warning on linux/osx */ diff --git a/src/lib/adapter/USBCECAdapterDetection.h b/src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.h similarity index 97% rename from src/lib/adapter/USBCECAdapterDetection.h rename to src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.h index 9b6c624..dfccd65 100644 --- a/src/lib/adapter/USBCECAdapterDetection.h +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterDetection.h @@ -31,8 +31,6 @@ * http://www.pulse-eight.net/ */ -#include "../../../include/cectypes.h" - namespace CEC { class CUSBCECAdapterDetection diff --git a/src/lib/adapter/USBCECAdapterMessage.cpp b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.cpp similarity index 98% rename from src/lib/adapter/USBCECAdapterMessage.cpp rename to src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.cpp index 8ef5662..f213c1d 100644 --- a/src/lib/adapter/USBCECAdapterMessage.cpp +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.cpp @@ -30,8 +30,11 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "USBCECAdapterMessage.h" -#include "../LibCEC.h" + +#include "lib/LibCEC.h" +#include "lib/platform/util/StdString.h" using namespace CEC; using namespace PLATFORM; @@ -91,7 +94,7 @@ CCECAdapterMessage::CCECAdapterMessage(const cec_command &command, uint8_t iLine lineTimeout = iLineTimeout; } -CStdString CCECAdapterMessage::ToString(void) const +std::string CCECAdapterMessage::ToString(void) const { CStdString strMsg; if (Size() == 0) @@ -130,7 +133,7 @@ CStdString CCECAdapterMessage::ToString(void) const } } - return strMsg; + return std::string(strMsg.c_str()); } const char *CCECAdapterMessage::ToString(cec_adapter_messagecode msgCode) diff --git a/src/lib/adapter/USBCECAdapterMessage.h b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.h similarity index 87% rename from src/lib/adapter/USBCECAdapterMessage.h rename to src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.h index 4d571b1..e4fedce 100644 --- a/src/lib/adapter/USBCECAdapterMessage.h +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessage.h @@ -31,24 +31,10 @@ * http://www.pulse-eight.net/ */ -#include "../platform/util/StdString.h" -#include "../platform/util/buffer.h" -#include "../platform/threads/mutex.h" -#include "../../../include/cectypes.h" +#include "lib/adapter/AdapterCommunication.h" namespace CEC { - typedef enum cec_adapter_message_state - { - ADAPTER_MESSAGE_STATE_UNKNOWN = 0, /**< the initial state */ - ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT, /**< waiting in the send queue of the adapter, or timed out */ - ADAPTER_MESSAGE_STATE_SENT, /**< sent and waiting on an ACK */ - ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED, /**< sent, but failed to ACK */ - ADAPTER_MESSAGE_STATE_SENT_ACKED, /**< sent, and ACK received */ - ADAPTER_MESSAGE_STATE_INCOMING, /**< received from another device */ - ADAPTER_MESSAGE_STATE_ERROR /**< an error occured */ - } cec_adapter_message_state; - class CCECAdapterMessage { public: @@ -67,7 +53,7 @@ namespace CEC /*! * @return the message as human readable string. */ - CStdString ToString(void) const; + std::string ToString(void) const; /*! * @brief Translate the messagecode into a human readable string. diff --git a/src/lib/adapter/USBCECAdapterMessageQueue.cpp b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.cpp similarity index 94% rename from src/lib/adapter/USBCECAdapterMessageQueue.cpp rename to src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.cpp index 847115a..c713eea 100644 --- a/src/lib/adapter/USBCECAdapterMessageQueue.cpp +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.cpp @@ -30,10 +30,14 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "USBCECAdapterMessageQueue.h" + #include "USBCECAdapterCommunication.h" -#include "../platform/sockets/socket.h" -#include "../LibCEC.h" +#include "USBCECAdapterMessage.h" +#include "lib/platform/sockets/socket.h" +#include "lib/LibCEC.h" +#include "lib/platform/util/StdString.h" using namespace CEC; using namespace PLATFORM; @@ -212,11 +216,20 @@ bool CCECAdapterMessageQueueEntry::MessageReceivedResponse(const CCECAdapterMess return true; } +CCECAdapterMessageQueue::CCECAdapterMessageQueue(CUSBCECAdapterCommunication *com) : + PLATFORM::CThread(), + m_com(com), + m_iNextMessage(0) +{ + m_incomingAdapterMessage = new CCECAdapterMessage; + m_currentCECFrame.Clear(); +} CCECAdapterMessageQueue::~CCECAdapterMessageQueue(void) { Clear(); StopThread(0); + delete m_incomingAdapterMessage; } void CCECAdapterMessageQueue::Clear(void) @@ -264,7 +277,7 @@ void CCECAdapterMessageQueue::MessageReceived(const CCECAdapterMessage &msg) { /* the message wasn't handled */ bool bIsError(m_com->HandlePoll(msg)); - m_com->m_callback->GetLib()->AddLog(bIsError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString()); + m_com->m_callback->GetLib()->AddLog(bIsError ? CEC_LOG_WARNING : CEC_LOG_DEBUG, msg.ToString().c_str()); /* push this message to the current frame */ if (!bIsError && msg.PushToCecCommand(m_currentCECFrame)) @@ -286,19 +299,19 @@ void CCECAdapterMessageQueue::AddData(uint8_t *data, size_t iLen) bool bFullMessage(false); { CLockObject lock(m_mutex); - bFullMessage = m_incomingAdapterMessage.PushReceivedByte(data[iPtr]); + bFullMessage = m_incomingAdapterMessage->PushReceivedByte(data[iPtr]); } if (bFullMessage) { /* a full message was received */ CCECAdapterMessage newMessage; - newMessage.packet = m_incomingAdapterMessage.packet; + newMessage.packet = m_incomingAdapterMessage->packet; MessageReceived(newMessage); /* clear the current message */ CLockObject lock(m_mutex); - m_incomingAdapterMessage.Clear(); + m_incomingAdapterMessage->Clear(); } } } diff --git a/src/lib/adapter/USBCECAdapterMessageQueue.h b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.h similarity index 95% rename from src/lib/adapter/USBCECAdapterMessageQueue.h rename to src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.h index 44c930b..6e325a7 100644 --- a/src/lib/adapter/USBCECAdapterMessageQueue.h +++ b/src/lib/adapter/Pulse-Eight/USBCECAdapterMessageQueue.h @@ -31,14 +31,15 @@ * http://www.pulse-eight.net/ */ -#include "USBCECAdapterMessage.h" -#include "../platform/threads/threads.h" +#include "lib/platform/threads/threads.h" +#include "lib/platform/util/buffer.h" #include namespace CEC { class CUSBCECAdapterCommunication; class CCECAdapterMessageQueue; + class CCECAdapterMessage; class CCECAdapterMessageQueueEntry { @@ -133,14 +134,7 @@ namespace CEC * @param com The communication handler callback to use. * @param iQueueSize The outgoing message queue size. */ - CCECAdapterMessageQueue(CUSBCECAdapterCommunication *com) : - PLATFORM::CThread(), - m_com(com), - m_iNextMessage(0) - { - m_currentCECFrame.Clear(); - } - + CCECAdapterMessageQueue(CUSBCECAdapterCommunication *com); virtual ~CCECAdapterMessageQueue(void); /*! @@ -176,7 +170,7 @@ namespace CEC std::map m_messages; /**< the outgoing message queue */ PLATFORM::SyncedBuffer m_writeQueue; /**< the queue for messages that are to be written */ uint64_t m_iNextMessage; /**< the index of the next message */ - CCECAdapterMessage m_incomingAdapterMessage; /**< the current incoming message that's being assembled */ + CCECAdapterMessage *m_incomingAdapterMessage; /**< the current incoming message that's being assembled */ cec_command m_currentCECFrame; /**< the current incoming CEC command that's being assembled */ }; } diff --git a/src/lib/devices/CECAudioSystem.cpp b/src/lib/devices/CECAudioSystem.cpp index 7824451..91a3e99 100644 --- a/src/lib/devices/CECAudioSystem.cpp +++ b/src/lib/devices/CECAudioSystem.cpp @@ -30,11 +30,13 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECAudioSystem.h" -#include "../CECProcessor.h" -#include "../implementations/CECCommandHandler.h" -#include "../LibCEC.h" -#include "../CECTypeUtils.h" + +#include "lib/CECProcessor.h" +#include "lib/implementations/CECCommandHandler.h" +#include "lib/LibCEC.h" +#include "lib/CECTypeUtils.h" using namespace CEC; using namespace PLATFORM; @@ -76,7 +78,7 @@ bool CCECAudioSystem::SetSystemAudioModeStatus(const cec_system_audio_status mod return false; } -bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest) +bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest, bool bIsReply) { uint8_t state; { @@ -85,10 +87,10 @@ bool CCECAudioSystem::TransmitAudioStatus(cec_logical_address dest) state = m_audioStatus; } - return m_handler->TransmitAudioStatus(m_iLogicalAddress, dest, state); + return m_handler->TransmitAudioStatus(m_iLogicalAddress, dest, state, bIsReply); } -bool CCECAudioSystem::TransmitSetSystemAudioMode(cec_logical_address dest) +bool CCECAudioSystem::TransmitSetSystemAudioMode(cec_logical_address dest, bool bIsReply) { cec_system_audio_status state; { @@ -97,10 +99,10 @@ bool CCECAudioSystem::TransmitSetSystemAudioMode(cec_logical_address dest) state = m_systemAudioStatus; } - return m_handler->TransmitSetSystemAudioMode(m_iLogicalAddress, dest, state); + return m_handler->TransmitSetSystemAudioMode(m_iLogicalAddress, dest, state, bIsReply); } -bool CCECAudioSystem::TransmitSystemAudioModeStatus(cec_logical_address dest) +bool CCECAudioSystem::TransmitSystemAudioModeStatus(cec_logical_address dest, bool bIsReply) { cec_system_audio_status state; { @@ -109,7 +111,7 @@ bool CCECAudioSystem::TransmitSystemAudioModeStatus(cec_logical_address dest) state = m_systemAudioStatus; } - return m_handler->TransmitSystemAudioModeStatus(m_iLogicalAddress, dest, state); + return m_handler->TransmitSystemAudioModeStatus(m_iLogicalAddress, dest, state, bIsReply); } uint8_t CCECAudioSystem::VolumeUp(const cec_logical_address source, bool bSendRelease /* = true */) diff --git a/src/lib/devices/CECAudioSystem.h b/src/lib/devices/CECAudioSystem.h index e2e3cd2..7950311 100644 --- a/src/lib/devices/CECAudioSystem.h +++ b/src/lib/devices/CECAudioSystem.h @@ -43,9 +43,9 @@ namespace CEC bool SetAudioStatus(uint8_t status); bool SetSystemAudioModeStatus(const cec_system_audio_status mode); - bool TransmitAudioStatus(cec_logical_address dest); - bool TransmitSetSystemAudioMode(cec_logical_address dest); - bool TransmitSystemAudioModeStatus(cec_logical_address dest); + bool TransmitAudioStatus(cec_logical_address dest, bool bIsReply); + bool TransmitSetSystemAudioMode(cec_logical_address dest, bool bIsReply); + bool TransmitSystemAudioModeStatus(cec_logical_address dest, bool bIsReply); uint8_t VolumeUp(const cec_logical_address source, bool bSendRelease = true); uint8_t VolumeDown(const cec_logical_address source, bool bSendRelease = true); diff --git a/src/lib/devices/CECBusDevice.cpp b/src/lib/devices/CECBusDevice.cpp index 91dd835..5b3e2cb 100644 --- a/src/lib/devices/CECBusDevice.cpp +++ b/src/lib/devices/CECBusDevice.cpp @@ -30,17 +30,19 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECBusDevice.h" -#include "../CECProcessor.h" -#include "../CECClient.h" -#include "../implementations/ANCommandHandler.h" -#include "../implementations/CECCommandHandler.h" -#include "../implementations/SLCommandHandler.h" -#include "../implementations/VLCommandHandler.h" -#include "../LibCEC.h" -#include "../CECTypeUtils.h" -#include "../platform/util/timeutils.h" -#include "../platform/util/util.h" + +#include "lib/CECProcessor.h" +#include "lib/CECClient.h" +#include "lib/implementations/ANCommandHandler.h" +#include "lib/implementations/CECCommandHandler.h" +#include "lib/implementations/SLCommandHandler.h" +#include "lib/implementations/VLCommandHandler.h" +#include "lib/LibCEC.h" +#include "lib/CECTypeUtils.h" +#include "lib/platform/util/timeutils.h" +#include "lib/platform/util/util.h" #include "CECAudioSystem.h" #include "CECPlaybackDevice.h" @@ -95,10 +97,7 @@ bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */) { bool bInitHandler(false); { - CTryLockObject lock(m_mutex); - if (!lock.IsLocked()) - return false; - + CLockObject lock(m_mutex); CLockObject handlerLock(m_handlerMutex); if (m_iHandlerUseCount > 0) return false; @@ -311,7 +310,7 @@ bool CCECBusDevice::RequestCecVersion(const cec_logical_address initiator, bool return bReturn; } -bool CCECBusDevice::TransmitCECVersion(const cec_logical_address destination) +bool CCECBusDevice::TransmitCECVersion(const cec_logical_address destination, bool bIsReply) { cec_version version; { @@ -321,7 +320,7 @@ bool CCECBusDevice::TransmitCECVersion(const cec_logical_address destination) } MarkBusy(); - bool bReturn = m_handler->TransmitCECVersion(m_iLogicalAddress, destination, version); + bool bReturn = m_handler->TransmitCECVersion(m_iLogicalAddress, destination, version, bIsReply); MarkReady(); return bReturn; } @@ -380,7 +379,7 @@ bool CCECBusDevice::RequestMenuLanguage(const cec_logical_address initiator, boo return bReturn; } -bool CCECBusDevice::TransmitSetMenuLanguage(const cec_logical_address destination) +bool CCECBusDevice::TransmitSetMenuLanguage(const cec_logical_address destination, bool bIsReply) { bool bReturn(false); cec_menu_language language; @@ -407,20 +406,20 @@ bool CCECBusDevice::TransmitSetMenuLanguage(const cec_logical_address destinatio else { LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> broadcast (F): Menu language '%s'", GetLogicalAddressName(), m_iLogicalAddress, lang); - bReturn = m_handler->TransmitSetMenuLanguage(m_iLogicalAddress, lang); + bReturn = m_handler->TransmitSetMenuLanguage(m_iLogicalAddress, lang, bIsReply); } MarkReady(); return bReturn; } -bool CCECBusDevice::TransmitOSDString(const cec_logical_address destination, cec_display_control duration, const char *strMessage) +bool CCECBusDevice::TransmitOSDString(const cec_logical_address destination, cec_display_control duration, const char *strMessage, bool bIsReply) { bool bReturn(false); if (!m_processor->GetDevice(destination)->IsUnsupportedFeature(CEC_OPCODE_SET_OSD_STRING)) { LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): display OSD message '%s'", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, strMessage); MarkBusy(); - bReturn = m_handler->TransmitOSDString(m_iLogicalAddress, destination, duration, strMessage); + bReturn = m_handler->TransmitOSDString(m_iLogicalAddress, destination, duration, strMessage, bIsReply); MarkReady(); } return bReturn; @@ -478,7 +477,7 @@ bool CCECBusDevice::RequestOSDName(const cec_logical_address initiator, bool bWa return bReturn; } -bool CCECBusDevice::TransmitOSDName(const cec_logical_address destination) +bool CCECBusDevice::TransmitOSDName(const cec_logical_address destination, bool bIsReply) { CStdString strDeviceName; { @@ -488,7 +487,7 @@ bool CCECBusDevice::TransmitOSDName(const cec_logical_address destination) } MarkBusy(); - bool bReturn = m_handler->TransmitOSDName(m_iLogicalAddress, destination, strDeviceName); + bool bReturn = m_handler->TransmitOSDName(m_iLogicalAddress, destination, strDeviceName, bIsReply); MarkReady(); return bReturn; } @@ -553,7 +552,7 @@ bool CCECBusDevice::RequestPhysicalAddress(const cec_logical_address initiator, return bReturn; } -bool CCECBusDevice::TransmitPhysicalAddress(void) +bool CCECBusDevice::TransmitPhysicalAddress(bool bIsReply) { uint16_t iPhysicalAddress; cec_device_type type; @@ -568,7 +567,7 @@ bool CCECBusDevice::TransmitPhysicalAddress(void) } MarkBusy(); - bool bReturn = m_handler->TransmitPhysicalAddress(m_iLogicalAddress, iPhysicalAddress, type); + bool bReturn = m_handler->TransmitPhysicalAddress(m_iLogicalAddress, iPhysicalAddress, type, bIsReply); MarkReady(); return bReturn; } @@ -628,7 +627,7 @@ bool CCECBusDevice::RequestPowerStatus(const cec_logical_address initiator, bool return bReturn; } -bool CCECBusDevice::TransmitPowerState(const cec_logical_address destination) +bool CCECBusDevice::TransmitPowerState(const cec_logical_address destination, bool bIsReply) { cec_power_status state; { @@ -638,7 +637,7 @@ bool CCECBusDevice::TransmitPowerState(const cec_logical_address destination) } MarkBusy(); - bool bReturn = m_handler->TransmitPowerState(m_iLogicalAddress, destination, state); + bool bReturn = m_handler->TransmitPowerState(m_iLogicalAddress, destination, state, bIsReply); MarkReady(); return bReturn; } @@ -704,7 +703,7 @@ bool CCECBusDevice::RequestVendorId(const cec_logical_address initiator, bool bW return bReturn; } -bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool bSendAbort /* = true */) +bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool bSendAbort, bool bIsReply) { bool bReturn(false); uint64_t iVendorId; @@ -726,7 +725,7 @@ bool CCECBusDevice::TransmitVendorID(const cec_logical_address destination, bool else { LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): vendor id %s (%x)", GetLogicalAddressName(), m_iLogicalAddress, ToString(destination), destination, ToString((cec_vendor_id)iVendorId), iVendorId); - bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, iVendorId); + bReturn = m_handler->TransmitVendorID(m_iLogicalAddress, iVendorId, bIsReply); } MarkReady(); return bReturn; @@ -757,7 +756,7 @@ cec_bus_device_status CCECBusDevice::GetStatus(bool bForcePoll /* = false */, bo return status; } -void CCECBusDevice::SetDeviceStatus(const cec_bus_device_status newStatus) +void CCECBusDevice::SetDeviceStatus(const cec_bus_device_status newStatus, cec_version libCECSpecVersion /* = CEC_VERSION_1_4 */) { { CLockObject lock(m_mutex); @@ -769,7 +768,7 @@ void CCECBusDevice::SetDeviceStatus(const cec_bus_device_status newStatus) SetPowerStatus (CEC_POWER_STATUS_ON); SetVendorId (CEC_VENDOR_UNKNOWN); SetMenuState (CEC_MENU_STATE_ACTIVATED); - SetCecVersion (CEC_VERSION_1_3A); + SetCecVersion (libCECSpecVersion); SetStreamPath (CEC_INVALID_PHYSICAL_ADDRESS); MarkAsInactiveSource(); m_iLastActive = 0; @@ -816,7 +815,7 @@ void CCECBusDevice::ResetDeviceStatus(void) m_deviceStatus = CEC_DEVICE_STATUS_UNKNOWN; } -bool CCECBusDevice::TransmitPoll(const cec_logical_address dest) +bool CCECBusDevice::TransmitPoll(const cec_logical_address dest, bool bIsReply) { bool bReturn(false); cec_logical_address destination(dest); @@ -829,7 +828,7 @@ bool CCECBusDevice::TransmitPoll(const cec_logical_address dest) MarkBusy(); LIB_CEC->AddLog(CEC_LOG_NOTICE, "<< %s (%X) -> %s (%X): POLL", GetLogicalAddressName(), m_iLogicalAddress, ToString(dest), dest); - bReturn = m_handler->TransmitPoll(m_iLogicalAddress, destination); + bReturn = m_handler->TransmitPoll(m_iLogicalAddress, destination, bIsReply); LIB_CEC->AddLog(CEC_LOG_DEBUG, bReturn ? ">> POLL sent" : ">> POLL not sent"); CLockObject lock(m_mutex); @@ -884,7 +883,7 @@ void CCECBusDevice::SetMenuState(const cec_menu_state state) } } -bool CCECBusDevice::TransmitMenuState(const cec_logical_address dest) +bool CCECBusDevice::TransmitMenuState(const cec_logical_address dest, bool bIsReply) { cec_menu_state menuState; { @@ -894,7 +893,7 @@ bool CCECBusDevice::TransmitMenuState(const cec_logical_address dest) } MarkBusy(); - bool bReturn = m_handler->TransmitMenuState(m_iLogicalAddress, dest, menuState); + bool bReturn = m_handler->TransmitMenuState(m_iLogicalAddress, dest, menuState, bIsReply); MarkReady(); return bReturn; } @@ -990,7 +989,7 @@ void CCECBusDevice::MarkAsInactiveSource(void) } } -bool CCECBusDevice::TransmitActiveSource(void) +bool CCECBusDevice::TransmitActiveSource(bool bIsReply) { bool bSendActiveSource(false); uint16_t iPhysicalAddress(CEC_INVALID_PHYSICAL_ADDRESS); @@ -1020,7 +1019,7 @@ bool CCECBusDevice::TransmitActiveSource(void) if (bSendActiveSource) { MarkBusy(); - bActiveSourceSent = m_handler->TransmitActiveSource(m_iLogicalAddress, iPhysicalAddress); + bActiveSourceSent = m_handler->TransmitActiveSource(m_iLogicalAddress, iPhysicalAddress, bIsReply); MarkReady(); } @@ -1279,14 +1278,14 @@ void CCECBusDevice::MarkReady(void) --m_iHandlerUseCount; } -bool CCECBusDevice::TryLogicalAddress(void) +bool CCECBusDevice::TryLogicalAddress(cec_version libCECSpecVersion /* = CEC_VERSION_1_4 */) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "trying logical address '%s'", GetLogicalAddressName()); - if (!TransmitPoll(m_iLogicalAddress)) + if (!TransmitPoll(m_iLogicalAddress, false)) { LIB_CEC->AddLog(CEC_LOG_NOTICE, "using logical address '%s'", GetLogicalAddressName()); - SetDeviceStatus(CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC); + SetDeviceStatus(CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC, libCECSpecVersion); return true; } diff --git a/src/lib/devices/CECBusDevice.h b/src/lib/devices/CECBusDevice.h index 89fb690..4e21553 100644 --- a/src/lib/devices/CECBusDevice.h +++ b/src/lib/devices/CECBusDevice.h @@ -31,11 +31,10 @@ * http://www.pulse-eight.net/ */ -#include "../../../include/cectypes.h" #include #include -#include "../platform/threads/mutex.h" -#include "../platform/util/StdString.h" +#include "lib/platform/threads/mutex.h" +#include "lib/platform/util/StdString.h" namespace CEC { @@ -167,61 +166,61 @@ namespace CEC virtual cec_version GetCecVersion(const cec_logical_address initiator, bool bUpdate = false); virtual void SetCecVersion(const cec_version newVersion); virtual bool RequestCecVersion(const cec_logical_address initiator, bool bWaitForResponse = true); - virtual bool TransmitCECVersion(const cec_logical_address destination); + virtual bool TransmitCECVersion(const cec_logical_address destination, bool bIsReply); virtual cec_menu_language & GetMenuLanguage(const cec_logical_address initiator, bool bUpdate = false); virtual void SetMenuLanguage(const char *strLanguage); virtual void SetMenuLanguage(const cec_menu_language &menuLanguage); virtual bool RequestMenuLanguage(const cec_logical_address initiator, bool bWaitForResponse = true); - virtual bool TransmitSetMenuLanguage(const cec_logical_address destination); + virtual bool TransmitSetMenuLanguage(const cec_logical_address destination, bool bIsReply); - virtual bool TransmitOSDString(const cec_logical_address destination, cec_display_control duration, const char *strMessage); + virtual bool TransmitOSDString(const cec_logical_address destination, cec_display_control duration, const char *strMessage, bool bIsReply); virtual CStdString GetCurrentOSDName(void); virtual CStdString GetOSDName(const cec_logical_address initiator, bool bUpdate = false); virtual void SetOSDName(CStdString strName); virtual bool RequestOSDName(const cec_logical_address source, bool bWaitForResponse = true); - virtual bool TransmitOSDName(const cec_logical_address destination); + virtual bool TransmitOSDName(const cec_logical_address destination, bool bIsReply); virtual uint16_t GetCurrentPhysicalAddress(void); virtual bool HasValidPhysicalAddress(void); virtual uint16_t GetPhysicalAddress(const cec_logical_address initiator, bool bSuppressUpdate = false); virtual bool SetPhysicalAddress(uint16_t iNewAddress); virtual bool RequestPhysicalAddress(const cec_logical_address initiator, bool bWaitForResponse = true); - virtual bool TransmitPhysicalAddress(void); + virtual bool TransmitPhysicalAddress(bool bIsReply); virtual cec_power_status GetCurrentPowerStatus(void); virtual cec_power_status GetPowerStatus(const cec_logical_address initiator, bool bUpdate = false); virtual void SetPowerStatus(const cec_power_status powerStatus); virtual bool RequestPowerStatus(const cec_logical_address initiator, bool bWaitForResponse = true); - virtual bool TransmitPowerState(const cec_logical_address destination); + virtual bool TransmitPowerState(const cec_logical_address destination, bool bIsReply); virtual cec_vendor_id GetCurrentVendorId(void); virtual cec_vendor_id GetVendorId(const cec_logical_address initiator, bool bUpdate = false); virtual const char * GetVendorName(const cec_logical_address initiator, bool bUpdate = false); virtual bool SetVendorId(uint64_t iVendorId); virtual bool RequestVendorId(const cec_logical_address initiator, bool bWaitForResponse = true); - virtual bool TransmitVendorID(const cec_logical_address destination, bool bSendAbort = true); + virtual bool TransmitVendorID(const cec_logical_address destination, bool bSendAbort, bool bIsReply); virtual cec_bus_device_status GetCurrentStatus(void) { return GetStatus(false, true); } virtual cec_bus_device_status GetStatus(bool bForcePoll = false, bool bSuppressPoll = false); - virtual void SetDeviceStatus(const cec_bus_device_status newStatus); + virtual void SetDeviceStatus(const cec_bus_device_status newStatus, cec_version libCECSpecVersion = CEC_VERSION_1_4); virtual void ResetDeviceStatus(void); - virtual bool TransmitPoll(const cec_logical_address destination); + virtual bool TransmitPoll(const cec_logical_address destination, bool bIsReply); virtual void HandlePoll(const cec_logical_address destination); virtual void HandlePollFrom(const cec_logical_address initiator); virtual bool HandleReceiveFailed(void); virtual cec_menu_state GetMenuState(const cec_logical_address initiator); virtual void SetMenuState(const cec_menu_state state); - virtual bool TransmitMenuState(const cec_logical_address destination); + virtual bool TransmitMenuState(const cec_logical_address destination, bool bIsReply); virtual bool ActivateSource(uint64_t iDelay = 0); virtual bool IsActiveSource(void) const { return m_bActiveSource; } virtual bool RequestActiveSource(bool bWaitForResponse = true); virtual void MarkAsActiveSource(void); virtual void MarkAsInactiveSource(void); - virtual bool TransmitActiveSource(void); + virtual bool TransmitActiveSource(bool bIsReply); virtual bool TransmitImageViewOn(void); virtual bool TransmitInactiveSource(void); virtual bool TransmitPendingActiveSourceCommands(void); @@ -230,7 +229,7 @@ namespace CEC virtual bool PowerOn(const cec_logical_address initiator); virtual bool Standby(const cec_logical_address initiator); - virtual bool TryLogicalAddress(void); + virtual bool TryLogicalAddress(cec_version libCECSpecVersion = CEC_VERSION_1_4); CCECClient * GetClient(void); void SignalOpcode(cec_opcode opcode); diff --git a/src/lib/devices/CECDeviceMap.cpp b/src/lib/devices/CECDeviceMap.cpp index 3c70603..a21b2b4 100644 --- a/src/lib/devices/CECDeviceMap.cpp +++ b/src/lib/devices/CECDeviceMap.cpp @@ -30,13 +30,15 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECDeviceMap.h" + #include "CECAudioSystem.h" #include "CECPlaybackDevice.h" #include "CECRecordingDevice.h" #include "CECTuner.h" #include "CECTV.h" -#include "../CECProcessor.h" +#include "lib/CECProcessor.h" using namespace std; using namespace CEC; diff --git a/src/lib/devices/CECDeviceMap.h b/src/lib/devices/CECDeviceMap.h index 128f574..d4af816 100644 --- a/src/lib/devices/CECDeviceMap.h +++ b/src/lib/devices/CECDeviceMap.h @@ -31,7 +31,6 @@ * http://www.pulse-eight.net/ */ -#include "../../../include/cectypes.h" #include #include diff --git a/src/lib/devices/CECPlaybackDevice.cpp b/src/lib/devices/CECPlaybackDevice.cpp index 1beed4f..ac5371e 100644 --- a/src/lib/devices/CECPlaybackDevice.cpp +++ b/src/lib/devices/CECPlaybackDevice.cpp @@ -30,11 +30,13 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECPlaybackDevice.h" -#include "../implementations/CECCommandHandler.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" -#include "../CECTypeUtils.h" + +#include "lib/implementations/CECCommandHandler.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" +#include "lib/CECTypeUtils.h" using namespace CEC; using namespace PLATFORM; @@ -81,7 +83,7 @@ void CCECPlaybackDevice::SetDeckControlMode(cec_deck_control_mode mode) } } -bool CCECPlaybackDevice::TransmitDeckStatus(cec_logical_address dest) +bool CCECPlaybackDevice::TransmitDeckStatus(cec_logical_address dest, bool bIsReply) { cec_deck_info state; { @@ -90,7 +92,7 @@ bool CCECPlaybackDevice::TransmitDeckStatus(cec_logical_address dest) state = m_deckStatus; } - return m_handler->TransmitDeckStatus(m_iLogicalAddress, dest, state); + return m_handler->TransmitDeckStatus(m_iLogicalAddress, dest, state, bIsReply); } void CCECPlaybackDevice::ResetDeviceStatus(void) diff --git a/src/lib/devices/CECPlaybackDevice.h b/src/lib/devices/CECPlaybackDevice.h index c21bf30..d12c150 100644 --- a/src/lib/devices/CECPlaybackDevice.h +++ b/src/lib/devices/CECPlaybackDevice.h @@ -47,7 +47,7 @@ namespace CEC void SetDeckStatus(cec_deck_info deckStatus); void SetDeckControlMode(cec_deck_control_mode mode); - bool TransmitDeckStatus(cec_logical_address dest); + bool TransmitDeckStatus(cec_logical_address dest, bool bIsReply); virtual void ResetDeviceStatus(void); diff --git a/src/lib/devices/CECRecordingDevice.cpp b/src/lib/devices/CECRecordingDevice.cpp index 2a82902..8b1d575 100644 --- a/src/lib/devices/CECRecordingDevice.cpp +++ b/src/lib/devices/CECRecordingDevice.cpp @@ -30,6 +30,7 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECRecordingDevice.h" using namespace CEC; diff --git a/src/lib/devices/CECTV.cpp b/src/lib/devices/CECTV.cpp index b26dbdc..2f852ae 100644 --- a/src/lib/devices/CECTV.cpp +++ b/src/lib/devices/CECTV.cpp @@ -30,6 +30,7 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECTV.h" using namespace CEC; diff --git a/src/lib/devices/CECTuner.cpp b/src/lib/devices/CECTuner.cpp index 4721c1a..2de4a1f 100644 --- a/src/lib/devices/CECTuner.cpp +++ b/src/lib/devices/CECTuner.cpp @@ -30,6 +30,7 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECTuner.h" using namespace CEC; diff --git a/src/lib/implementations/ANCommandHandler.cpp b/src/lib/implementations/ANCommandHandler.cpp index 8eccf88..648f4a0 100644 --- a/src/lib/implementations/ANCommandHandler.cpp +++ b/src/lib/implementations/ANCommandHandler.cpp @@ -30,11 +30,13 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "ANCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" -#include "../CECClient.h" + +#include "lib/devices/CECBusDevice.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" +#include "lib/CECClient.h" using namespace CEC; diff --git a/src/lib/implementations/CECCommandHandler.cpp b/src/lib/implementations/CECCommandHandler.cpp index ffe78b8..46edf98 100644 --- a/src/lib/implementations/CECCommandHandler.cpp +++ b/src/lib/implementations/CECCommandHandler.cpp @@ -30,15 +30,17 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "CECCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../devices/CECAudioSystem.h" -#include "../devices/CECPlaybackDevice.h" -#include "../CECClient.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" -#include "../CECTypeUtils.h" -#include "../platform/util/util.h" + +#include "lib/devices/CECBusDevice.h" +#include "lib/devices/CECAudioSystem.h" +#include "lib/devices/CECPlaybackDevice.h" +#include "lib/CECClient.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" +#include "lib/CECTypeUtils.h" +#include "lib/platform/util/util.h" using namespace CEC; using namespace std; @@ -267,7 +269,7 @@ int CCECCommandHandler::HandleGetCecVersion(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitCECVersion(command.initiator)) + if (device && device->TransmitCECVersion(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -280,7 +282,7 @@ int CCECCommandHandler::HandleGiveAudioStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECAudioSystem *device = CCECBusDevice::AsAudioSystem(GetDevice(command.destination)); - if (device && device->TransmitAudioStatus(command.initiator)) + if (device && device->TransmitAudioStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -293,7 +295,7 @@ int CCECCommandHandler::HandleGiveDeckStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECPlaybackDevice *device = CCECBusDevice::AsPlaybackDevice(GetDevice(command.destination)); - if (device && device->TransmitDeckStatus(command.initiator)) + if (device && device->TransmitDeckStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -306,7 +308,7 @@ int CCECCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitPowerState(command.initiator)) + if (device && device->TransmitPowerState(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -319,7 +321,7 @@ int CCECCommandHandler::HandleGiveDeviceVendorId(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitVendorID(command.initiator)) + if (device && device->TransmitVendorID(command.initiator, true, true)) return COMMAND_HANDLED; } @@ -331,7 +333,7 @@ int CCECCommandHandler::HandleGiveOSDName(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitOSDName(command.initiator)) + if (device && device->TransmitOSDName(command.initiator, true)) return COMMAND_HANDLED; } @@ -343,7 +345,7 @@ int CCECCommandHandler::HandleGivePhysicalAddress(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitPhysicalAddress()) + if (device && device->TransmitPhysicalAddress(true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -356,7 +358,7 @@ int CCECCommandHandler::HandleGiveMenuLanguage(const cec_command &command) if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECBusDevice *device = GetDevice(command.destination); - if (device && device->TransmitSetMenuLanguage(command.initiator)) + if (device && device->TransmitSetMenuLanguage(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -369,7 +371,7 @@ int CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &comma if (m_processor->CECInitialised() && m_processor->IsHandledByLibCEC(command.destination)) { CCECAudioSystem *device = CCECBusDevice::AsAudioSystem(GetDevice(command.destination)); - if (device && device->TransmitSystemAudioModeStatus(command.initiator)) + if (device && device->TransmitSystemAudioModeStatus(command.initiator, true)) return COMMAND_HANDLED; return CEC_ABORT_REASON_INVALID_OPERAND; } @@ -379,7 +381,14 @@ int CCECCommandHandler::HandleGiveSystemAudioModeStatus(const cec_command &comma int CCECCommandHandler::HandleImageViewOn(const cec_command &command) { - m_processor->GetDevice(command.initiator)->MarkAsActiveSource(); + CCECBusDevice *device = GetDevice(command.destination); + if (device && (device->GetCurrentStatus() == CEC_DEVICE_STATUS_PRESENT || + device->GetCurrentStatus() == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC)) + { + if (device->GetCurrentPowerStatus() == CEC_POWER_STATUS_STANDBY || + device->GetCurrentPowerStatus() == CEC_POWER_STATUS_IN_TRANSITION_ON_TO_STANDBY) + device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); + } return COMMAND_HANDLED; } @@ -404,7 +413,7 @@ int CCECCommandHandler::HandleMenuRequest(const cec_command &command) device->SetMenuState(CEC_MENU_STATE_DEACTIVATED); } } - if (device->TransmitMenuState(command.initiator)) + if (device->TransmitMenuState(command.initiator, true)) return COMMAND_HANDLED; } return CEC_ABORT_REASON_INVALID_OPERAND; @@ -467,7 +476,7 @@ int CCECCommandHandler::HandleRequestActiveSource(const cec_command &command) vector devices; for (size_t iDevicePtr = 0; iDevicePtr < GetMyDevices(devices); iDevicePtr++) - devices[iDevicePtr]->TransmitActiveSource(); + devices[iDevicePtr]->TransmitActiveSource(true); } return COMMAND_HANDLED; @@ -589,13 +598,13 @@ int CCECCommandHandler::HandleSystemAudioModeRequest(const cec_command &command) CCECBusDevice *newActiveDevice = GetDeviceByPhysicalAddress(iNewAddress); if (newActiveDevice) newActiveDevice->MarkAsActiveSource(); - if (device->TransmitSetSystemAudioMode(command.initiator)) + if (device->TransmitSetSystemAudioMode(command.initiator, true)) return COMMAND_HANDLED; } else { device->SetSystemAudioModeStatus(CEC_SYSTEM_AUDIO_STATUS_OFF); - if (device->TransmitSetSystemAudioMode(command.initiator)) + if (device->TransmitSetSystemAudioMode(command.initiator, true)) return COMMAND_HANDLED; } } @@ -809,7 +818,7 @@ bool CCECCommandHandler::TransmitImageViewOn(const cec_logical_address iInitiato cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_IMAGE_VIEW_ON); - return Transmit(command); + return Transmit(command, false, false); } bool CCECCommandHandler::TransmitStandby(const cec_logical_address iInitiator, const cec_logical_address iDestination) @@ -817,7 +826,7 @@ bool CCECCommandHandler::TransmitStandby(const cec_logical_address iInitiator, c cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_STANDBY); - return Transmit(command); + return Transmit(command, false, false); } bool CCECCommandHandler::TransmitRequestActiveSource(const cec_logical_address iInitiator, bool bWaitForResponse /* = true */) @@ -825,7 +834,7 @@ bool CCECCommandHandler::TransmitRequestActiveSource(const cec_logical_address i cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_REQUEST_ACTIVE_SOURCE); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestCecVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -833,7 +842,7 @@ bool CCECCommandHandler::TransmitRequestCecVersion(const cec_logical_address iIn cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GET_CEC_VERSION); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestMenuLanguage(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -841,7 +850,7 @@ bool CCECCommandHandler::TransmitRequestMenuLanguage(const cec_logical_address i cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GET_MENU_LANGUAGE); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -849,7 +858,7 @@ bool CCECCommandHandler::TransmitRequestOSDName(const cec_logical_address iIniti cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_OSD_NAME); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -857,7 +866,7 @@ bool CCECCommandHandler::TransmitRequestPhysicalAddress(const cec_logical_addres cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_PHYSICAL_ADDRESS); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -865,7 +874,7 @@ bool CCECCommandHandler::TransmitRequestPowerStatus(const cec_logical_address iI cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_POWER_STATUS); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } bool CCECCommandHandler::TransmitRequestVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse /* = true */) @@ -873,26 +882,26 @@ bool CCECCommandHandler::TransmitRequestVendorId(const cec_logical_address iInit cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_GIVE_DEVICE_VENDOR_ID); - return Transmit(command, !bWaitForResponse); + return Transmit(command, !bWaitForResponse, false); } -bool CCECCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress) +bool CCECCommandHandler::TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_ACTIVE_SOURCE); command.parameters.PushBack((uint8_t) ((iPhysicalAddress >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) (iPhysicalAddress & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion) +bool CCECCommandHandler::TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_CEC_VERSION); command.parameters.PushBack((uint8_t)cecVersion); - return Transmit(command); + return Transmit(command, false, bIsReply); } bool CCECCommandHandler::TransmitInactiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress) @@ -902,29 +911,29 @@ bool CCECCommandHandler::TransmitInactiveSource(const cec_logical_address iIniti command.parameters.PushBack((iPhysicalAddress >> 8) & 0xFF); command.parameters.PushBack(iPhysicalAddress & 0xFF); - return Transmit(command); + return Transmit(command, false, false); } -bool CCECCommandHandler::TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState) +bool CCECCommandHandler::TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_MENU_STATUS); command.parameters.PushBack((uint8_t)menuState); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, CStdString strDeviceName) +bool CCECCommandHandler::TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, std::string strDeviceName, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_OSD_NAME); for (size_t iPtr = 0; iPtr < strDeviceName.length(); iPtr++) command.parameters.PushBack(strDeviceName.at(iPtr)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage) +bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_OSD_STRING); @@ -936,10 +945,10 @@ bool CCECCommandHandler::TransmitOSDString(const cec_logical_address iInitiator, for (size_t iPtr = 0; iPtr < iLen; iPtr++) command.parameters.PushBack(strMessage[iPtr]); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type) +bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_REPORT_PHYSICAL_ADDRESS); @@ -947,10 +956,10 @@ bool CCECCommandHandler::TransmitPhysicalAddress(const cec_logical_address iInit command.parameters.PushBack((uint8_t) (iPhysicalAddress & 0xFF)); command.parameters.PushBack((uint8_t) (type)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3]) +bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3], bool bIsReply) { cec_command command; command.Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_SET_MENU_LANGUAGE); @@ -958,27 +967,27 @@ bool CCECCommandHandler::TransmitSetMenuLanguage(const cec_logical_address iInit command.parameters.PushBack((uint8_t) lang[1]); command.parameters.PushBack((uint8_t) lang[2]); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination) +bool CCECCommandHandler::TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_NONE); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state) +bool CCECCommandHandler::TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_REPORT_POWER_STATUS); command.parameters.PushBack((uint8_t) state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId) +bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, CECDEVICE_BROADCAST, CEC_OPCODE_DEVICE_VENDOR_ID); @@ -987,53 +996,58 @@ bool CCECCommandHandler::TransmitVendorID(const cec_logical_address iInitiator, command.parameters.PushBack((uint8_t) (((uint64_t)iVendorId >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) ((uint64_t)iVendorId & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state) +bool CCECCommandHandler::TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_REPORT_AUDIO_STATUS); command.parameters.PushBack(state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state) +bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SET_SYSTEM_AUDIO_MODE); command.parameters.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSetStreamPath(uint16_t iStreamPath) +bool CCECCommandHandler::TransmitSetStreamPath(uint16_t iStreamPath, bool bIsReply) { + if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "only the TV is allowed to send CEC_OPCODE_SET_STREAM_PATH"); + return false; + } cec_command command; cec_command::Format(command, m_busDevice->GetLogicalAddress(), CECDEVICE_BROADCAST, CEC_OPCODE_SET_STREAM_PATH); command.parameters.PushBack((uint8_t) ((iStreamPath >> 8) & 0xFF)); command.parameters.PushBack((uint8_t) (iStreamPath & 0xFF)); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state) +bool CCECCommandHandler::TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS); command.parameters.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } -bool CCECCommandHandler::TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state) +bool CCECCommandHandler::TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state, bool bIsReply) { cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_DECK_STATUS); command.PushBack((uint8_t)state); - return Transmit(command); + return Transmit(command, false, bIsReply); } bool CCECCommandHandler::TransmitKeypress(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_user_control_code key, bool bWait /* = true */) @@ -1042,7 +1056,7 @@ bool CCECCommandHandler::TransmitKeypress(const cec_logical_address iInitiator, cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_USER_CONTROL_PRESSED); command.parameters.PushBack((uint8_t)key); - return Transmit(command, !bWait); + return Transmit(command, !bWait, false); } bool CCECCommandHandler::TransmitKeyRelease(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWait /* = true */) @@ -1050,10 +1064,10 @@ bool CCECCommandHandler::TransmitKeyRelease(const cec_logical_address iInitiator cec_command command; cec_command::Format(command, iInitiator, iDestination, CEC_OPCODE_USER_CONTROL_RELEASE); - return Transmit(command, !bWait); + return Transmit(command, !bWait, false); } -bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait /* = false */) +bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait, bool bIsReply) { bool bReturn(false); cec_opcode expectedResponse(cec_command::GetResponseOpcode(command.opcode)); @@ -1070,7 +1084,7 @@ bool CCECCommandHandler::Transmit(cec_command &command, bool bSuppressWait /* = uint8_t iTries(0), iMaxTries(!command.opcode_set ? 1 : m_iTransmitRetries + 1); while (!bReturn && ++iTries <= iMaxTries && !m_busDevice->IsUnsupportedFeature(command.opcode)) { - if ((bReturn = m_processor->Transmit(command)) == true) + if ((bReturn = m_processor->Transmit(command, bIsReply)) == true) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "command transmitted"); if (bExpectResponse) @@ -1120,15 +1134,15 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f // switch sources (if allowed) if (!bActiveSourceFailed && bSourceSwitchAllowed) { - bActiveSourceFailed = !m_busDevice->TransmitActiveSource() || - !m_busDevice->TransmitMenuState(CECDEVICE_TV); + bActiveSourceFailed = !m_busDevice->TransmitActiveSource(false) || + !m_busDevice->TransmitMenuState(CECDEVICE_TV, false); // update the deck status for playback devices if (!bActiveSourceFailed) { CCECPlaybackDevice *playbackDevice = m_busDevice->AsPlaybackDevice(); if (playbackDevice && SendDeckStatusUpdateOnActiveSource()) - bActiveSourceFailed = !playbackDevice->TransmitDeckStatus(CECDEVICE_TV); + bActiveSourceFailed = !playbackDevice->TransmitDeckStatus(CECDEVICE_TV, false); } } diff --git a/src/lib/implementations/CECCommandHandler.h b/src/lib/implementations/CECCommandHandler.h index bc42128..45e3522 100644 --- a/src/lib/implementations/CECCommandHandler.h +++ b/src/lib/implementations/CECCommandHandler.h @@ -31,10 +31,9 @@ * http://www.pulse-eight.net/ */ -#include "../../../include/cectypes.h" #include -#include "../platform/threads/mutex.h" -#include "../platform/util/StdString.h" +#include +#include "lib/platform/threads/mutex.h" namespace CEC { @@ -74,24 +73,24 @@ namespace CEC virtual bool TransmitRequestPhysicalAddress(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true); virtual bool TransmitRequestPowerStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true); virtual bool TransmitRequestVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWaitForResponse = true); - virtual bool TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress); - virtual bool TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion); + virtual bool TransmitActiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, bool bIsReply); + virtual bool TransmitCECVersion(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_version cecVersion, bool bIsReply); virtual bool TransmitInactiveSource(const cec_logical_address iInitiator, uint16_t iPhysicalAddress); - virtual bool TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState); - virtual bool TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, CStdString strDeviceName); - virtual bool TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage); - virtual bool TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type); - virtual bool TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3]); - virtual bool TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination); - virtual bool TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state); - virtual bool TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId); - virtual bool TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state); - virtual bool TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state); - virtual bool TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state); - virtual bool TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state); + virtual bool TransmitMenuState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_menu_state menuState, bool bIsReply); + virtual bool TransmitOSDName(const cec_logical_address iInitiator, const cec_logical_address iDestination, std::string strDeviceName, bool bIsReply); + virtual bool TransmitOSDString(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_display_control duration, const char *strMessage, bool bIsReply); + virtual bool TransmitPhysicalAddress(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, cec_device_type type, bool bIsReply); + virtual bool TransmitSetMenuLanguage(const cec_logical_address iInitiator, const char lang[3], bool bIsReply); + virtual bool TransmitPoll(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bIsReply); + virtual bool TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state, bool bIsReply); + virtual bool TransmitVendorID(const cec_logical_address iInitiator, uint64_t iVendorId, bool bIsReply); + virtual bool TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state, bool bIsReply); + virtual bool TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply); + virtual bool TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply); + virtual bool TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state, bool bIsReply); virtual bool TransmitKeypress(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_user_control_code key, bool bWait = true); virtual bool TransmitKeyRelease(const cec_logical_address iInitiator, const cec_logical_address iDestination, bool bWait = true); - virtual bool TransmitSetStreamPath(uint16_t iStreamPath); + virtual bool TransmitSetStreamPath(uint16_t iStreamPath, bool bIsReply); virtual bool SendDeckStatusUpdateOnActiveSource(void) const { return m_bOPTSendDeckStatusUpdateOnActiveSource; }; virtual void ScheduleActivateSource(uint64_t iDelay); @@ -146,7 +145,7 @@ namespace CEC virtual bool SetVendorId(const cec_command &command); virtual void SetPhysicalAddress(cec_logical_address iAddress, uint16_t iNewAddress); - virtual bool Transmit(cec_command &command, bool bSuppressWait = false); + virtual bool Transmit(cec_command &command, bool bSuppressWait, bool bIsReply); virtual bool SourceSwitchAllowed(void) { return true; } diff --git a/src/lib/implementations/RLCommandHandler.cpp b/src/lib/implementations/RLCommandHandler.cpp index 5653137..f1f936a 100644 --- a/src/lib/implementations/RLCommandHandler.cpp +++ b/src/lib/implementations/RLCommandHandler.cpp @@ -30,10 +30,13 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "RLCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" + +#include "lib/platform/util/timeutils.h" +#include "lib/devices/CECBusDevice.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" using namespace CEC; using namespace PLATFORM; @@ -67,7 +70,7 @@ bool CRLCommandHandler::InitHandler(void) if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV) { /* send the vendor id */ - primary->TransmitVendorID(CECDEVICE_BROADCAST); + primary->TransmitVendorID(CECDEVICE_BROADCAST, false, false); } } diff --git a/src/lib/implementations/RLCommandHandler.h b/src/lib/implementations/RLCommandHandler.h index ec9edd9..446c91b 100644 --- a/src/lib/implementations/RLCommandHandler.h +++ b/src/lib/implementations/RLCommandHandler.h @@ -32,7 +32,6 @@ */ #include "CECCommandHandler.h" -#include "../platform/util/timeutils.h" namespace CEC { diff --git a/src/lib/implementations/SLCommandHandler.cpp b/src/lib/implementations/SLCommandHandler.cpp index 222fc95..32902c2 100644 --- a/src/lib/implementations/SLCommandHandler.cpp +++ b/src/lib/implementations/SLCommandHandler.cpp @@ -30,11 +30,14 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "SLCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../devices/CECPlaybackDevice.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" + +#include "lib/platform/util/timeutils.h" +#include "lib/devices/CECBusDevice.h" +#include "lib/devices/CECPlaybackDevice.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" using namespace CEC; using namespace PLATFORM; @@ -97,10 +100,10 @@ bool CSLCommandHandler::InitHandler(void) { /* start as 'in transition standby->on' */ primary->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); - primary->TransmitPowerState(CECDEVICE_TV); + primary->TransmitPowerState(CECDEVICE_TV, false); /* send the vendor id */ - primary->TransmitVendorID(CECDEVICE_BROADCAST); + primary->TransmitVendorID(CECDEVICE_BROADCAST, false, false); } } @@ -124,7 +127,7 @@ int CSLCommandHandler::HandleActiveSource(const cec_command &command) CLockObject lock(m_SLMutex); m_bActiveSourceSent = false; } - primary->TransmitPowerState(CECDEVICE_TV); + primary->TransmitPowerState(CECDEVICE_TV, false); } return COMMAND_HANDLED; @@ -149,7 +152,7 @@ int CSLCommandHandler::HandleDeviceVendorId(const cec_command &command) cec_command response; cec_command::Format(response, initiator, command.initiator, CEC_OPCODE_FEATURE_ABORT); - Transmit(response); + Transmit(response, false, true); return COMMAND_HANDLED; } } @@ -203,7 +206,7 @@ void CSLCommandHandler::TransmitVendorCommand0205(const cec_logical_address iSou response.PushBack(SL_COMMAND_UNKNOWN_02); response.PushBack(SL_COMMAND_TYPE_HDDRECORDER); - Transmit(response); + Transmit(response, false, true); } void CSLCommandHandler::HandleVendorCommandPowerOn(const cec_command &command) @@ -217,12 +220,12 @@ void CSLCommandHandler::HandleVendorCommandPowerOn(const cec_command &command) SetSLInitialised(); device->MarkAsActiveSource(); device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); CEvent::Sleep(2000); device->SetPowerStatus(CEC_POWER_STATUS_ON); - device->TransmitPowerState(command.initiator); - device->TransmitPhysicalAddress(); + device->TransmitPowerState(command.initiator, false); + device->TransmitPhysicalAddress(false); { CLockObject lock(m_SLMutex); m_bActiveSourceSent = false; @@ -237,7 +240,7 @@ void CSLCommandHandler::HandleVendorCommandPowerOnStatus(const cec_command &comm if (device) { device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); device->SetPowerStatus(CEC_POWER_STATUS_ON); } } @@ -257,7 +260,7 @@ void CSLCommandHandler::TransmitVendorCommandSetDeviceMode(const cec_logical_add cec_command::Format(response, iSource, iDestination, CEC_OPCODE_VENDOR_COMMAND); response.PushBack(SL_COMMAND_SET_DEVICE_MODE); response.PushBack((uint8_t)type); - Transmit(response); + Transmit(response, false, true); } int CSLCommandHandler::HandleGiveDeckStatus(const cec_command &command) @@ -273,14 +276,14 @@ int CSLCommandHandler::HandleGiveDeckStatus(const cec_command &command) device->SetDeckStatus(!device->IsActiveSource() ? CEC_DECK_INFO_OTHER_STATUS : CEC_DECK_INFO_OTHER_STATUS_LG); if (command.parameters[0] == CEC_STATUS_REQUEST_ON) { - device->TransmitDeckStatus(command.initiator); + device->TransmitDeckStatus(command.initiator, true); if (!ActiveSourceSent()) ActivateSource(); return COMMAND_HANDLED; } else if (command.parameters[0] == CEC_STATUS_REQUEST_ONCE) { - device->TransmitDeckStatus(command.initiator); + device->TransmitDeckStatus(command.initiator, true); return COMMAND_HANDLED; } @@ -294,7 +297,7 @@ int CSLCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) CCECBusDevice *device = GetDevice(command.destination); if (device && device->GetCurrentPowerStatus() != CEC_POWER_STATUS_ON) { - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); device->SetPowerStatus(CEC_POWER_STATUS_ON); } else @@ -302,7 +305,7 @@ int CSLCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) if (!ActiveSourceSent()) { device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); ActivateSource(); } else if (m_resetPowerState.IsSet() && m_resetPowerState.TimeLeft() > 0) @@ -314,13 +317,13 @@ int CSLCommandHandler::HandleGiveDevicePowerStatus(const cec_command &command) m_bActiveSourceSent = false; } device->SetPowerStatus(CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON); - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); device->SetPowerStatus(CEC_POWER_STATUS_ON); m_resetPowerState.Init(5000); } else { - device->TransmitPowerState(command.initiator); + device->TransmitPowerState(command.initiator, true); m_resetPowerState.Init(5000); } } @@ -349,8 +352,8 @@ int CSLCommandHandler::HandleFeatureAbort(const cec_command &command) if (command.parameters.size == 0 && m_processor->GetPrimaryDevice()->GetCurrentPowerStatus() == CEC_POWER_STATUS_ON && !SLInitialised() && command.initiator == CECDEVICE_TV) { - m_processor->GetPrimaryDevice()->TransmitPowerState(command.initiator); - m_processor->GetPrimaryDevice()->TransmitVendorID(CECDEVICE_BROADCAST, false); + m_processor->GetPrimaryDevice()->TransmitPowerState(command.initiator, false); + m_processor->GetPrimaryDevice()->TransmitVendorID(CECDEVICE_BROADCAST, false, false); } return CCECCommandHandler::HandleFeatureAbort(command); @@ -403,12 +406,12 @@ bool CSLCommandHandler::PowerOn(const cec_logical_address iInitiator, const cec_ cec_command command; if (!m_bSLEnabled) - TransmitVendorID(CECDEVICE_TV, CEC_VENDOR_LG); + TransmitVendorID(CECDEVICE_TV, CEC_VENDOR_LG, false); cec_command::Format(command, CECDEVICE_TV, iDestination, CEC_OPCODE_VENDOR_COMMAND); command.PushBack(SL_COMMAND_POWER_ON); command.PushBack(0); - return Transmit(command); + return Transmit(command, false, false); } return CCECCommandHandler::PowerOn(iInitiator, iDestination); diff --git a/src/lib/implementations/SLCommandHandler.h b/src/lib/implementations/SLCommandHandler.h index 8c6902d..8cc64f1 100644 --- a/src/lib/implementations/SLCommandHandler.h +++ b/src/lib/implementations/SLCommandHandler.h @@ -32,7 +32,6 @@ */ #include "CECCommandHandler.h" -#include "../platform/util/timeutils.h" namespace CEC { @@ -67,7 +66,7 @@ namespace CEC int HandleRequestActiveSource(const cec_command &command); int HandleFeatureAbort(const cec_command &command); int HandleStandby(const cec_command &command); - bool TransmitMenuState(const cec_logical_address UNUSED(iInitiator), const cec_logical_address UNUSED(iDestination), cec_menu_state UNUSED(menuState)) { return true; } + bool TransmitMenuState(const cec_logical_address UNUSED(iInitiator), const cec_logical_address UNUSED(iDestination), cec_menu_state UNUSED(menuState), bool UNUSED(bIsReply)) { return true; } bool PowerOn(const cec_logical_address iInitiator, const cec_logical_address iDestination); void ResetSLState(void); diff --git a/src/lib/implementations/VLCommandHandler.cpp b/src/lib/implementations/VLCommandHandler.cpp index 97d06a2..e78f942 100644 --- a/src/lib/implementations/VLCommandHandler.cpp +++ b/src/lib/implementations/VLCommandHandler.cpp @@ -30,13 +30,15 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "VLCommandHandler.h" -#include "../devices/CECBusDevice.h" -#include "../devices/CECPlaybackDevice.h" -#include "../devices/CECTV.h" -#include "../CECProcessor.h" -#include "../LibCEC.h" -#include "../CECClient.h" + +#include "lib/devices/CECBusDevice.h" +#include "lib/devices/CECPlaybackDevice.h" +#include "lib/devices/CECTV.h" +#include "lib/CECProcessor.h" +#include "lib/LibCEC.h" +#include "lib/CECClient.h" #define VL_POWER_CHANGE 0x20 #define VL_POWERED_UP 0x00 @@ -200,7 +202,7 @@ int CVLCommandHandler::HandleVendorCommand(const cec_command &command) uint8_t iResponseData[] = {0x10, 0x02, 0xFF, 0xFF, 0x00, 0x05, 0x05, 0x45, 0x55, 0x5c, 0x58, 0x32}; response.PushArray(12, iResponseData); - Transmit(response, true); + Transmit(response, false, true); return COMMAND_HANDLED; } diff --git a/src/lib/platform/adl/adl-edid.cpp b/src/lib/platform/adl/adl-edid.cpp index 368b86b..c69c813 100644 --- a/src/lib/platform/adl/adl-edid.cpp +++ b/src/lib/platform/adl/adl-edid.cpp @@ -30,6 +30,7 @@ * http://www.pulse-eight.net/ */ +#include "env.h" #include "adl-edid.h" // for dlsym and friends diff --git a/src/lib/platform/adl/adl-edid.h b/src/lib/platform/adl/adl-edid.h index 10b76c9..e6b1b04 100644 --- a/src/lib/platform/adl/adl-edid.h +++ b/src/lib/platform/adl/adl-edid.h @@ -33,8 +33,8 @@ #define HAS_ADL_EDID_PARSER -#include "../os.h" -#include "../util/edid.h" +#include "lib/platform/os.h" +#include "lib/platform/util/edid.h" #if !defined(__WINDOWS__) #include "adl_sdk.h" diff --git a/src/lib/platform/nvidia/nv-edid.cpp b/src/lib/platform/nvidia/nv-edid.cpp index 0c0bbd6..3de7754 100644 --- a/src/lib/platform/nvidia/nv-edid.cpp +++ b/src/lib/platform/nvidia/nv-edid.cpp @@ -30,6 +30,9 @@ * http://www.pulse-eight.net/ */ +#include "env.h" + +#include "lib/platform/os.h" #include "nv-edid.h" using namespace PLATFORM; @@ -46,7 +49,7 @@ uint16_t CNVEdidParser::GetPhysicalAddress(void) char buf[4096]; memset(buf, 0, sizeof(buf)); int iPtr(0); - char c(0); + int c(0); while (c != EOF) { c = fgetc(fp); diff --git a/src/lib/platform/nvidia/nv-edid.h b/src/lib/platform/nvidia/nv-edid.h index 81f10ce..a9ba940 100644 --- a/src/lib/platform/nvidia/nv-edid.h +++ b/src/lib/platform/nvidia/nv-edid.h @@ -33,8 +33,7 @@ #define HAS_NVIDIA_EDID_PARSER -#include "../os.h" -#include "../util/edid.h" +#include "lib/platform/util/edid.h" namespace PLATFORM { diff --git a/src/lib/platform/os.h b/src/lib/platform/os.h index 60e02d6..70e603c 100644 --- a/src/lib/platform/os.h +++ b/src/lib/platform/os.h @@ -31,7 +31,6 @@ * http://www.pulse-eight.net/ */ - #ifdef UNUSED #elif defined(__GNUC__) #define UNUSED(x) UNUSED_ ## x __attribute__((unused)) diff --git a/src/lib/platform/posix/os-edid.cpp b/src/lib/platform/posix/os-edid.cpp index 1a346dc..05ce9fa 100644 --- a/src/lib/platform/posix/os-edid.cpp +++ b/src/lib/platform/posix/os-edid.cpp @@ -30,7 +30,8 @@ * http://www.pulse-eight.net/ */ -#include "../util/edid.h" +#include "env.h" +#include "lib/platform/util/edid.h" using namespace PLATFORM; diff --git a/src/lib/platform/posix/os-socket.h b/src/lib/platform/posix/os-socket.h index 036be3f..7539aab 100644 --- a/src/lib/platform/posix/os-socket.h +++ b/src/lib/platform/posix/os-socket.h @@ -32,8 +32,8 @@ */ -#include "../os.h" -#include "../util/timeutils.h" +#include "lib/platform/os.h" +#include "lib/platform/util/timeutils.h" #include #include #include diff --git a/src/lib/platform/posix/serialport.cpp b/src/lib/platform/posix/serialport.cpp index 3764a15..c1b3b22 100644 --- a/src/lib/platform/posix/serialport.cpp +++ b/src/lib/platform/posix/serialport.cpp @@ -30,12 +30,12 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "env.h" #include #include -#include "../sockets/serialport.h" -#include "../util/baudrate.h" -#include "../posix/os-socket.h" +#include "lib/platform/sockets/serialport.h" +#include "lib/platform/util/baudrate.h" +#include "lib/platform/posix/os-socket.h" #if defined(__APPLE__) || defined(__FreeBSD__) #ifndef XCASE @@ -58,6 +58,9 @@ inline bool RemoveLock(const char *strDeviceName) { #if !defined(__APPLE__) && !defined(__FreeBSD__) return dev_unlock(strDeviceName, 0) == 0; + #else + void *tmp = (void*)strDeviceName; // silence unused warning + return true; #endif } diff --git a/src/lib/platform/posix/serversocket.cpp b/src/lib/platform/posix/serversocket.cpp index dce13d3..30d80ee 100644 --- a/src/lib/platform/posix/serversocket.cpp +++ b/src/lib/platform/posix/serversocket.cpp @@ -30,9 +30,9 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" -#include "../sockets/tcp.h" -#include "../sockets/serversocket.h" +#include "env.h" +#include "lib/platform/sockets/tcp.h" +#include "lib/platform/sockets/serversocket.h" using namespace std; using namespace PLATFORM; @@ -103,10 +103,10 @@ bool CTcpServerSocket::IsOpen(void) return m_socket != INVALID_SOCKET_VALUE; } -CStdString CTcpServerSocket::GetError(void) +std::string CTcpServerSocket::GetError(void) { - CStdString strError; - strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError; + std::string strError; + strError = m_strError.empty() && m_iError != 0 ? strerror(m_iError) : m_strError; return strError; } @@ -115,9 +115,9 @@ int CTcpServerSocket::GetErrorNumber(void) return m_iError; } -CStdString CTcpServerSocket::GetName(void) +std::string CTcpServerSocket::GetName(void) { - CStdString strName("localhost"); + std::string strName("localhost"); return strName; } diff --git a/src/lib/platform/sockets/serialport.h b/src/lib/platform/sockets/serialport.h index eed05a0..cb78b37 100644 --- a/src/lib/platform/sockets/serialport.h +++ b/src/lib/platform/sockets/serialport.h @@ -31,8 +31,8 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" -#include "../util/buffer.h" +#include "lib/platform/os.h" +#include "lib/platform/util/buffer.h" #include #include @@ -69,7 +69,7 @@ namespace PLATFORM class CSerialSocket : public CCommonSocket { public: - CSerialSocket(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : + CSerialSocket(const std::string &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : CCommonSocket(INVALID_SERIAL_SOCKET_VALUE, strName), #ifdef __WINDOWS__ m_iCurrentReadTimeout(MAXDWORD), @@ -114,7 +114,7 @@ namespace PLATFORM class CSerialPort : public CProtectedSocket { public: - CSerialPort(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : + CSerialPort(const std::string &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : CProtectedSocket (new CSerialSocket(strName, iBaudrate, iDatabits, iStopbits, iParity)) {} virtual ~CSerialPort(void) {} }; diff --git a/src/lib/platform/sockets/serversocket.h b/src/lib/platform/sockets/serversocket.h index edc7fcd..0aa51eb 100644 --- a/src/lib/platform/sockets/serversocket.h +++ b/src/lib/platform/sockets/serversocket.h @@ -50,9 +50,9 @@ namespace PLATFORM virtual bool IsOpen(void) = 0; ssize_t Write(void* data, size_t len) { (void) data; (void) len; return EINVAL; } ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) { (void) data; (void) len; (void) iTimeoutMs; return EINVAL; } - virtual CStdString GetError(void) = 0; + virtual std::string GetError(void) = 0; virtual int GetErrorNumber(void) = 0; - virtual CStdString GetName(void) = 0; + virtual std::string GetName(void) = 0; virtual ISocket* Accept(void) = 0; }; @@ -72,9 +72,9 @@ namespace PLATFORM virtual void Close(void); virtual void Shutdown(void); virtual bool IsOpen(void); - virtual CStdString GetError(void); + virtual std::string GetError(void); virtual int GetErrorNumber(void); - virtual CStdString GetName(void); + virtual std::string GetName(void); virtual ISocket* Accept(void); @@ -84,7 +84,7 @@ namespace PLATFORM protected: uint16_t m_iPort; tcp_socket_t m_socket; - CStdString m_strError; + std::string m_strError; int m_iError; }; } diff --git a/src/lib/platform/sockets/socket.h b/src/lib/platform/sockets/socket.h index f56d515..e894172 100644 --- a/src/lib/platform/sockets/socket.h +++ b/src/lib/platform/sockets/socket.h @@ -31,15 +31,16 @@ * http://www.pulse-eight.net/ */ -#include "../threads/mutex.h" -#include "../util/StdString.h" +#include "lib/platform/threads/mutex.h" #if defined(__WINDOWS__) -#include "../windows/os-socket.h" +#include "lib/platform/windows/os-socket.h" #else -#include "../posix/os-socket.h" +#include "lib/platform/posix/os-socket.h" #endif +#include + // Common socket operations namespace PLATFORM @@ -56,26 +57,26 @@ namespace PLATFORM virtual bool IsOpen(void) = 0; virtual ssize_t Write(void* data, size_t len) = 0; virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0; - virtual CStdString GetError(void) = 0; + virtual std::string GetError(void) = 0; virtual int GetErrorNumber(void) = 0; - virtual CStdString GetName(void) = 0; + virtual std::string GetName(void) = 0; }; template class CCommonSocket : public ISocket { public: - CCommonSocket(_SType initialSocketValue, const CStdString &strName) : + CCommonSocket(_SType initialSocketValue, const std::string &strName) : m_socket(initialSocketValue), m_strName(strName), m_iError(0) {} virtual ~CCommonSocket(void) {} - virtual CStdString GetError(void) + virtual std::string GetError(void) { - CStdString strError; - strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError; + std::string strError; + strError = m_strError.empty() && m_iError != 0 ? strerror(m_iError) : m_strError; return strError; } @@ -84,17 +85,17 @@ namespace PLATFORM return m_iError; } - virtual CStdString GetName(void) + virtual std::string GetName(void) { - CStdString strName; + std::string strName; strName = m_strName; return strName; } protected: _SType m_socket; - CStdString m_strError; - CStdString m_strName; + std::string m_strError; + std::string m_strName; int m_iError; CMutex m_mutex; }; @@ -182,9 +183,9 @@ namespace PLATFORM return iReturn; } - virtual CStdString GetError(void) + virtual std::string GetError(void) { - CStdString strError; + std::string strError; CLockObject lock(m_mutex); strError = m_socket ? m_socket->GetError() : ""; return strError; @@ -196,9 +197,9 @@ namespace PLATFORM return m_socket ? m_socket->GetErrorNumber() : -EINVAL; } - virtual CStdString GetName(void) + virtual std::string GetName(void) { - CStdString strName; + std::string strName; CLockObject lock(m_mutex); strName = m_socket ? m_socket->GetName() : ""; return strName; diff --git a/src/lib/platform/sockets/tcp.h b/src/lib/platform/sockets/tcp.h index 1693354..1dad499 100644 --- a/src/lib/platform/sockets/tcp.h +++ b/src/lib/platform/sockets/tcp.h @@ -40,7 +40,7 @@ namespace PLATFORM class CTcpSocket : public CCommonSocket { public: - CTcpSocket(const CStdString &strHostname, uint16_t iPort) : + CTcpSocket(const std::string &strHostname, uint16_t iPort) : CCommonSocket(INVALID_SOCKET_VALUE, strHostname), m_iPort(iPort) {} @@ -165,7 +165,7 @@ namespace PLATFORM class CTcpConnection : public CProtectedSocket { public: - CTcpConnection(const CStdString &strHostname, uint16_t iPort) : + CTcpConnection(const std::string &strHostname, uint16_t iPort) : CProtectedSocket (new CTcpSocket(strHostname, iPort)) {} virtual ~CTcpConnection(void) {} }; diff --git a/src/lib/platform/threads/mutex.h b/src/lib/platform/threads/mutex.h index 6fc57d1..00953db 100644 --- a/src/lib/platform/threads/mutex.h +++ b/src/lib/platform/threads/mutex.h @@ -31,15 +31,15 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "lib/platform/os.h" #if defined(__WINDOWS__) -#include "../windows/os-threads.h" +#include "lib/platform/windows/os-threads.h" #else -#include "../posix/os-threads.h" +#include "lib/platform/posix/os-threads.h" #endif -#include "../util/timeutils.h" +#include "lib/platform/util/timeutils.h" namespace PLATFORM { diff --git a/src/lib/platform/util/StdString.h b/src/lib/platform/util/StdString.h index 496dae7..63b3bf1 100644 --- a/src/lib/platform/util/StdString.h +++ b/src/lib/platform/util/StdString.h @@ -1,5 +1,5 @@ #pragma once -#include "../os.h" +#include "lib/platform/os.h" #include #include #include diff --git a/src/lib/platform/util/buffer.h b/src/lib/platform/util/buffer.h index aa658ee..4b57a29 100644 --- a/src/lib/platform/util/buffer.h +++ b/src/lib/platform/util/buffer.h @@ -31,7 +31,7 @@ * http://www.pulse-eight.net/ */ -#include "../threads/mutex.h" +#include "lib/platform/threads/mutex.h" #include namespace PLATFORM diff --git a/src/lib/platform/util/edid.h b/src/lib/platform/util/edid.h index 1db4f99..148728e 100644 --- a/src/lib/platform/util/edid.h +++ b/src/lib/platform/util/edid.h @@ -31,7 +31,7 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "lib/platform/os.h" #include "StdString.h" namespace PLATFORM diff --git a/src/lib/platform/util/timeutils.h b/src/lib/platform/util/timeutils.h index 5f2d27a..e95c10d 100644 --- a/src/lib/platform/util/timeutils.h +++ b/src/lib/platform/util/timeutils.h @@ -31,7 +31,8 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "env.h" +#include "lib/platform/os.h" #if defined(__APPLE__) #include @@ -39,6 +40,7 @@ #elif defined(__WINDOWS__) #include #else +#include #include #endif diff --git a/src/lib/platform/windows/dlfcn-win32.cpp b/src/lib/platform/windows/dlfcn-win32.cpp index 5839921..38bafd8 100644 --- a/src/lib/platform/windows/dlfcn-win32.cpp +++ b/src/lib/platform/windows/dlfcn-win32.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "env.h" #include #include diff --git a/src/lib/platform/windows/os-edid.cpp b/src/lib/platform/windows/os-edid.cpp index 2678392..d956ee8 100644 --- a/src/lib/platform/windows/os-edid.cpp +++ b/src/lib/platform/windows/os-edid.cpp @@ -30,7 +30,8 @@ * http://www.pulse-eight.net/ */ -#include "../util/edid.h" +#include "env.h" +#include "lib/platform/util/edid.h" #include "windows.h" #include "setupapi.h" diff --git a/src/lib/platform/windows/os-socket.h b/src/lib/platform/windows/os-socket.h index 5174cba..0c38555 100644 --- a/src/lib/platform/windows/os-socket.h +++ b/src/lib/platform/windows/os-socket.h @@ -31,8 +31,8 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" -#include "../util/timeutils.h" +#include "lib/platform/os.h" +#include "lib/platform/util/timeutils.h" #include #include @@ -181,7 +181,9 @@ namespace PLATFORM tv.tv_usec = 1000 * (long)(iTimeoutMs % 1000); FD_ZERO(&fd_read); + #pragma warning(disable:4127) /* disable 'conditional expression is constant' */ FD_SET(socket, &fd_read); + #pragma warning(default:4127) if (select((int)socket + 1, &fd_read, NULL, NULL, &tv) == 0) { @@ -270,8 +272,10 @@ namespace PLATFORM FD_ZERO(&fd_write); FD_ZERO(&fd_except); + #pragma warning(disable:4127) /* disable 'conditional expression is constant' */ FD_SET(socket, &fd_write); FD_SET(socket, &fd_except); + #pragma warning(default:4127) int iPollResult = select(sizeof(socket)*8, NULL, &fd_write, &fd_except, &tv); if (iPollResult == 0) diff --git a/src/lib/platform/windows/os-threads.cpp b/src/lib/platform/windows/os-threads.cpp index 7c06d41..6a06dd2 100644 --- a/src/lib/platform/windows/os-threads.cpp +++ b/src/lib/platform/windows/os-threads.cpp @@ -30,7 +30,7 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "env.h" #include "os-threads.h" using namespace PLATFORM; diff --git a/src/lib/platform/windows/os-threads.h b/src/lib/platform/windows/os-threads.h index 47101dc..091e962 100644 --- a/src/lib/platform/windows/os-threads.h +++ b/src/lib/platform/windows/os-threads.h @@ -31,6 +31,8 @@ * http://www.pulse-eight.net/ */ +#include + namespace PLATFORM { #define thread_t HANDLE diff --git a/src/lib/platform/windows/os-types.h b/src/lib/platform/windows/os-types.h index 9b0dca0..2fc6269 100644 --- a/src/lib/platform/windows/os-types.h +++ b/src/lib/platform/windows/os-types.h @@ -49,7 +49,6 @@ #include #include #include -#include typedef SOCKET tcp_socket_t; #define INVALID_SOCKET_VALUE INVALID_SOCKET diff --git a/src/lib/platform/windows/serialport.cpp b/src/lib/platform/windows/serialport.cpp index 96e743f..ad7f871 100644 --- a/src/lib/platform/windows/serialport.cpp +++ b/src/lib/platform/windows/serialport.cpp @@ -30,14 +30,15 @@ * http://www.pulse-eight.net/ */ -#include "../sockets/serialport.h" -#include "../util/baudrate.h" -#include "../util/timeutils.h" +#include "env.h" +#include "lib/platform/sockets/serialport.h" +#include "lib/platform/util/baudrate.h" +#include "lib/platform/util/timeutils.h" using namespace std; using namespace PLATFORM; -void FormatWindowsError(int iErrorCode, CStdString &strMessage) +void FormatWindowsError(int iErrorCode, std::string &strMessage) { if (iErrorCode != ERROR_SUCCESS) { @@ -119,7 +120,7 @@ bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) if (IsOpen()) return false; - CStdString strComPath = "\\\\.\\" + m_strName; + std::string strComPath = "\\\\.\\" + m_strName; CLockObject lock(m_mutex); m_socket = CreateFile(strComPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (m_socket == INVALID_HANDLE_VALUE) diff --git a/src/testclient/main.cpp b/src/testclient/main.cpp index fe3f893..97bdcc6 100644 --- a/src/testclient/main.cpp +++ b/src/testclient/main.cpp @@ -30,7 +30,8 @@ * http://www.pulse-eight.net/ */ -#include "../../include/cec.h" +#include "../env.h" +#include "../include/cec.h" #include #include @@ -40,12 +41,13 @@ #include #include "../lib/platform/os.h" #include "../lib/implementations/CECCommandHandler.h" +#include "../lib/platform/util/StdString.h" using namespace CEC; using namespace std; using namespace PLATFORM; -#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_1_7_1; +#define CEC_CONFIG_VERSION CEC_CLIENT_VERSION_1_8_0; #include @@ -221,7 +223,7 @@ void ListDevices(ICECAdapter *parser) { time_t buildTime = (time_t)config.iFirmwareBuildDate; strDeviceInfo.AppendFormat("firmware build date: %s", asctime(gmtime(&buildTime))); - strDeviceInfo = strDeviceInfo.Left((int)strDeviceInfo.length() - 1); // strip \n added by asctime + strDeviceInfo = strDeviceInfo.Left(strDeviceInfo.length() > 1 ? (unsigned)(strDeviceInfo.length() - 1) : 0); // strip \n added by asctime strDeviceInfo.append(" +0000"); } } @@ -253,6 +255,7 @@ void ShowHelpCommandLine(const char* strExec) " on devices on startup and power them off on exit." << endl << " -o --osd-name {osd name} Use a custom osd name." << endl << " -m --monitor Start a monitor-only client." << endl << + " -i --info Shows information about how libCEC was compiled." << endl << " [COM PORT] The com port to connect to. If no COM" << endl << " port is given, the client tries to connect to the" << endl << " first device that is detected." << endl << @@ -1007,6 +1010,24 @@ bool ProcessCommandLineArguments(int argc, char *argv[]) } ++iArgPtr; } + else if (!strcmp(argv[iArgPtr], "--info") || + !strcmp(argv[iArgPtr], "-i")) + { + if (g_cecLogLevel == -1) + g_cecLogLevel = CEC_LOG_WARNING + CEC_LOG_ERROR; + ICECAdapter *parser = LibCecInitialise(&g_config); + if (parser) + { + CStdString strMessage; + strMessage.Format("libCEC version: %s", parser->ToString((cec_server_version)g_config.serverVersion)); + if (g_config.serverVersion >= CEC_SERVER_VERSION_1_7_2) + strMessage.AppendFormat(", %s", parser->GetLibInfo()); + PrintToStdOut(strMessage.c_str()); + UnloadLibCec(parser); + parser = NULL; + } + bReturn = false; + } else if (!strcmp(argv[iArgPtr], "--list-devices") || !strcmp(argv[iArgPtr], "-l")) { @@ -1144,6 +1165,9 @@ int main (int argc, char *argv[]) return 1; } + // init video on targets that need this + parser->InitVideoStandalone(); + if (!g_bSingleCommand) { CStdString strLog; -- 2.34.1