From 9500c4c898404ccef239eb50336d2ad3d4046c94 Mon Sep 17 00:00:00 2001 From: Micke Prag Date: Mon, 27 Feb 2012 17:37:52 +0100 Subject: [PATCH] Convert dos endings to unix in telldus-core, see #160 --- telldus-core/CMakeLists.txt | 124 +- telldus-core/client/CMakeLists.txt | 264 +-- telldus-core/client/Client.cpp | 532 ++--- telldus-core/client/Client.h | 84 +- telldus-core/client/libtelldus-core.def | 120 +- telldus-core/cmake/FindSignTool.cmake | 36 +- telldus-core/common/CMakeLists.txt | 152 +- telldus-core/common/Event.cpp | 154 +- telldus-core/common/EventHandler.h | 58 +- telldus-core/common/EventHandler_unix.cpp | 144 +- telldus-core/common/EventHandler_win.cpp | 138 +- telldus-core/common/Event_unix.cpp | 56 +- telldus-core/common/Event_win.cpp | 70 +- telldus-core/common/Message.cpp | 256 +-- telldus-core/common/Message.h | 62 +- telldus-core/common/Socket.h | 66 +- telldus-core/common/Socket_unix.cpp | 254 +-- telldus-core/common/Socket_win.cpp | 358 +-- telldus-core/common/Strings.cpp | 514 ++--- telldus-core/common/Strings.h | 66 +- telldus-core/service/CMakeLists.txt | 504 ++--- .../service/ClientCommunicationHandler.cpp | 530 ++--- telldus-core/service/ConnectionListener.h | 62 +- .../service/ConnectionListener_unix.cpp | 182 +- .../service/ConnectionListener_win.cpp | 298 +-- telldus-core/service/Controller.cpp | 106 +- telldus-core/service/Controller.h | 64 +- telldus-core/service/ControllerManager.cpp | 674 +++--- telldus-core/service/ControllerMessage.cpp | 178 +- telldus-core/service/Device.cpp | 506 ++--- telldus-core/service/Device.h | 86 +- telldus-core/service/DeviceManager.cpp | 1566 +++++++------- telldus-core/service/EventUpdateManager.cpp | 252 +-- telldus-core/service/Log.cpp | 362 ++-- telldus-core/service/Protocol.cpp | 526 ++--- telldus-core/service/Protocol.h | 82 +- telldus-core/service/ProtocolBrateck.cpp | 92 +- telldus-core/service/ProtocolComen.cpp | 24 +- telldus-core/service/ProtocolEverflourish.cpp | 260 +-- telldus-core/service/ProtocolFineoffset.cpp | 90 +- telldus-core/service/ProtocolFuhaote.cpp | 108 +- telldus-core/service/ProtocolGroup.cpp | 16 +- telldus-core/service/ProtocolGroup.h | 8 +- telldus-core/service/ProtocolHasta.cpp | 130 +- telldus-core/service/ProtocolIkea.cpp | 254 +-- telldus-core/service/ProtocolMandolyn.cpp | 76 +- telldus-core/service/ProtocolNexa.cpp | 564 ++--- telldus-core/service/ProtocolOregon.cpp | 230 +- telldus-core/service/ProtocolRisingSun.cpp | 222 +- telldus-core/service/ProtocolSartano.cpp | 208 +- telldus-core/service/ProtocolScene.cpp | 16 +- telldus-core/service/ProtocolScene.h | 8 +- telldus-core/service/ProtocolSilvanChip.cpp | 280 +-- telldus-core/service/ProtocolUpm.cpp | 142 +- telldus-core/service/ProtocolWaveman.cpp | 138 +- telldus-core/service/ProtocolX10.cpp | 348 +-- telldus-core/service/ProtocolYidong.cpp | 48 +- telldus-core/service/SettingsWinRegistry.cpp | 536 ++--- telldus-core/service/TellStick_ftd2xx.cpp | 70 +- telldus-core/service/TelldusMain.cpp | 284 +-- telldus-core/service/TelldusMain.h | 46 +- .../service/TelldusWinService_win.cpp | 354 +-- telldus-core/service/TelldusWinService_win.h | 70 +- telldus-core/service/Timer.cpp | 228 +- telldus-core/service/ftd2xx.h | 30 +- telldus-core/service/main_win.cpp | 40 +- telldus-core/service/win/ftd2xx.h | 1926 ++++++++--------- telldus-core/tdadmin/CMakeLists.txt | 158 +- telldus-core/tdadmin/main.cpp | 170 +- telldus-core/tdtool/CMakeLists.txt | 112 +- telldus-core/tdtool/main.cpp | 972 ++++----- telldus-core/tests/common/CMakeLists.txt | 18 +- 72 files changed, 8881 insertions(+), 8881 deletions(-) diff --git a/telldus-core/CMakeLists.txt b/telldus-core/CMakeLists.txt index af00e1c8..47ca4881 100644 --- a/telldus-core/CMakeLists.txt +++ b/telldus-core/CMakeLists.txt @@ -1,62 +1,62 @@ -PROJECT( telldus-core ) - -CMAKE_MINIMUM_REQUIRED( VERSION 2.6.0 ) - -CMAKE_POLICY(SET CMP0003 NEW) - -OPTION(FORCE_COMPILE_FROM_TRUNK FALSE "Accept compiling source from trunk. This is unsupported and highly unrecommended") -IF(NOT FORCE_COMPILE_FROM_TRUNK) - MESSAGE(FATAL_ERROR "You are compiling sources from trunk. Don't do that!") -ENDIF(NOT FORCE_COMPILE_FROM_TRUNK) - -SET(PACKAGE_MAJOR_VERSION 2) -SET(PACKAGE_MINOR_VERSION 1) -SET(PACKAGE_PATCH_VERSION 1) -SET(PACKAGE_VERSION "${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_PATCH_VERSION}") -SET(PACKAGE_SUBVERSION "") -SET(PACKAGE_SOVERSION 2) - -SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") - -IF (PACKAGE_SUBVERSION) - SET(DISPLAYED_VERSION "${PACKAGE_VERSION}_${PACKAGE_SUBVERSION}") -ELSE (PACKAGE_SUBVERSION) - SET(DISPLAYED_VERSION ${PACKAGE_VERSION}) -ENDIF(PACKAGE_SUBVERSION) - -SET(BUILD_LIBTELLDUS-CORE TRUE CACHE BOOL "Build libtelldus-core") - -IF (WIN32) - SET(TDADMIN_DEFAULT FALSE) -ELSEIF(APPLE) - SET(TDADMIN_DEFAULT FALSE) -ELSE (WIN32) - SET(TDADMIN_DEFAULT TRUE) -ENDIF (WIN32) - -IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - INCLUDE_DIRECTORIES(/usr/local/include) - LINK_DIRECTORIES(/usr/local/lib) -ENDIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - -SET(BUILD_TDTOOL TRUE CACHE BOOL "Build tdtool") -SET(BUILD_TDADMIN ${TDADMIN_DEFAULT} CACHE BOOL "Build tdadmin") - -SET(GENERATE_MAN FALSE CACHE BOOL "Enable generation of man-files") - -ADD_SUBDIRECTORY(common) -ADD_SUBDIRECTORY(service) -ADD_SUBDIRECTORY(client) - -IF(BUILD_TDTOOL) - IF(WIN32) - ADD_SUBDIRECTORY(3rdparty/openbsd-getopt) - ENDIF() - ADD_SUBDIRECTORY(tdtool) -ENDIF(BUILD_TDTOOL) -IF(BUILD_TDADMIN) - ADD_SUBDIRECTORY(tdadmin) -ENDIF(BUILD_TDADMIN) - -ENABLE_TESTING() -ADD_SUBDIRECTORY(tests) +PROJECT( telldus-core ) + +CMAKE_MINIMUM_REQUIRED( VERSION 2.6.0 ) + +CMAKE_POLICY(SET CMP0003 NEW) + +OPTION(FORCE_COMPILE_FROM_TRUNK FALSE "Accept compiling source from trunk. This is unsupported and highly unrecommended") +IF(NOT FORCE_COMPILE_FROM_TRUNK) + MESSAGE(FATAL_ERROR "You are compiling sources from trunk. Don't do that!") +ENDIF(NOT FORCE_COMPILE_FROM_TRUNK) + +SET(PACKAGE_MAJOR_VERSION 2) +SET(PACKAGE_MINOR_VERSION 1) +SET(PACKAGE_PATCH_VERSION 1) +SET(PACKAGE_VERSION "${PACKAGE_MAJOR_VERSION}.${PACKAGE_MINOR_VERSION}.${PACKAGE_PATCH_VERSION}") +SET(PACKAGE_SUBVERSION "") +SET(PACKAGE_SOVERSION 2) + +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + +IF (PACKAGE_SUBVERSION) + SET(DISPLAYED_VERSION "${PACKAGE_VERSION}_${PACKAGE_SUBVERSION}") +ELSE (PACKAGE_SUBVERSION) + SET(DISPLAYED_VERSION ${PACKAGE_VERSION}) +ENDIF(PACKAGE_SUBVERSION) + +SET(BUILD_LIBTELLDUS-CORE TRUE CACHE BOOL "Build libtelldus-core") + +IF (WIN32) + SET(TDADMIN_DEFAULT FALSE) +ELSEIF(APPLE) + SET(TDADMIN_DEFAULT FALSE) +ELSE (WIN32) + SET(TDADMIN_DEFAULT TRUE) +ENDIF (WIN32) + +IF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + INCLUDE_DIRECTORIES(/usr/local/include) + LINK_DIRECTORIES(/usr/local/lib) +ENDIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + +SET(BUILD_TDTOOL TRUE CACHE BOOL "Build tdtool") +SET(BUILD_TDADMIN ${TDADMIN_DEFAULT} CACHE BOOL "Build tdadmin") + +SET(GENERATE_MAN FALSE CACHE BOOL "Enable generation of man-files") + +ADD_SUBDIRECTORY(common) +ADD_SUBDIRECTORY(service) +ADD_SUBDIRECTORY(client) + +IF(BUILD_TDTOOL) + IF(WIN32) + ADD_SUBDIRECTORY(3rdparty/openbsd-getopt) + ENDIF() + ADD_SUBDIRECTORY(tdtool) +ENDIF(BUILD_TDTOOL) +IF(BUILD_TDADMIN) + ADD_SUBDIRECTORY(tdadmin) +ENDIF(BUILD_TDADMIN) + +ENABLE_TESTING() +ADD_SUBDIRECTORY(tests) diff --git a/telldus-core/client/CMakeLists.txt b/telldus-core/client/CMakeLists.txt index 03dbd6da..d764c3a7 100644 --- a/telldus-core/client/CMakeLists.txt +++ b/telldus-core/client/CMakeLists.txt @@ -1,132 +1,132 @@ -IF(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -ENDIF(COMMAND cmake_policy) - -FIND_PACKAGE( SignTool REQUIRED ) - -######## Non configurable options ######## -SET( telldus-core_SRCS - CallbackDispatcher.cpp - CallbackMainDispatcher.cpp - Client.cpp - telldus-core.cpp -) - -SET( telldus-core_HDRS - CallbackDispatcher.h - CallbackMainDispatcher.cpp - Client.h -) -SET( telldus-core_PUB_HDRS - telldus-core.h -) - -FIND_PACKAGE(Threads) -LIST(APPEND telldus-core_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../common -) - -######## Configurable options for the platform ######## - - - -######## Platforms-specific, non configurable ######## - -IF (APPLE) - #### Mac OS X #### - SET( telldus-core_TARGET TelldusCore ) - ADD_DEFINITIONS( - -D_MACOSX - ) - LIST(APPEND telldus-core_LIBRARIES - TelldusCommon - ) -ELSEIF (WIN32) - #### Windows #### - ADD_DEFINITIONS( -DUNICODE ) - ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No - SET( telldus-core_TARGET TelldusCore ) - LIST(APPEND telldus-core_LIBRARIES - TelldusCommon - ) - CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc - ) - LIST(APPEND telldus-core_SRCS - libtelldus-core.def - ${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc - ) - ADD_DEFINITIONS( - -D_WINDOWS - -DTELLDUSCORE_EXPORTS - ) - IF (CMAKE_CL_64) - ADD_DEFINITIONS(-D_CL64) - ENDIF(CMAKE_CL_64) -ELSE (APPLE) - #### Linux #### - SET( telldus-core_TARGET telldus-core ) - LIST(APPEND telldus-core_LIBRARIES - TelldusCommon - ) - - ADD_DEFINITIONS( - -D_LINUX - ) -ENDIF (APPLE) - - - -######## Configuring ######## - -ADD_LIBRARY(${telldus-core_TARGET} SHARED - ${telldus-core_SRCS} - ${telldus-core_HDRS} - ${telldus-core_PUB_HDRS} -) - -#Copy public headers files on windows -IF (WIN32) - FOREACH(_FILE ${telldus-core_PUB_HDRS}) - ADD_CUSTOM_COMMAND( TARGET ${telldus-core_TARGET} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy \"${CMAKE_CURRENT_SOURCE_DIR}/${_FILE}\" \"${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}\" - COMMENT "Copy ${_FILE}" - ) - ENDFOREACH(_FILE) -ENDIF () - -ADD_DEPENDENCIES(${telldus-core_TARGET} TelldusCommon) - -IF (UNIX) - SET_TARGET_PROPERTIES( ${telldus-core_TARGET} PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden") -ENDIF (UNIX) - -TARGET_LINK_LIBRARIES( ${telldus-core_TARGET} ${telldus-core_LIBRARIES} ) - -SET_TARGET_PROPERTIES(${telldus-core_TARGET} PROPERTIES - FRAMEWORK TRUE - INSTALL_NAME_DIR "/Library/Frameworks" - PUBLIC_HEADER ${telldus-core_PUB_HDRS} - VERSION ${PACKAGE_VERSION} - SOVERSION ${PACKAGE_SOVERSION} -) -SIGN(${telldus-core_TARGET}) - -IF (NOT LIB_INSTALL_DIR) - SET(LIB_INSTALL_DIR "lib") -ENDIF (NOT LIB_INSTALL_DIR) - -IF (UNIX) - INSTALL(TARGETS ${telldus-core_TARGET} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} - FRAMEWORK DESTINATION "/Library/Frameworks" - PUBLIC_HEADER DESTINATION include - ) -ENDIF (UNIX) - +IF(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +FIND_PACKAGE( SignTool REQUIRED ) + +######## Non configurable options ######## +SET( telldus-core_SRCS + CallbackDispatcher.cpp + CallbackMainDispatcher.cpp + Client.cpp + telldus-core.cpp +) + +SET( telldus-core_HDRS + CallbackDispatcher.h + CallbackMainDispatcher.cpp + Client.h +) +SET( telldus-core_PUB_HDRS + telldus-core.h +) + +FIND_PACKAGE(Threads) +LIST(APPEND telldus-core_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../common +) + +######## Configurable options for the platform ######## + + + +######## Platforms-specific, non configurable ######## + +IF (APPLE) + #### Mac OS X #### + SET( telldus-core_TARGET TelldusCore ) + ADD_DEFINITIONS( + -D_MACOSX + ) + LIST(APPEND telldus-core_LIBRARIES + TelldusCommon + ) +ELSEIF (WIN32) + #### Windows #### + ADD_DEFINITIONS( -DUNICODE ) + ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No + SET( telldus-core_TARGET TelldusCore ) + LIST(APPEND telldus-core_LIBRARIES + TelldusCommon + ) + CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc + ) + LIST(APPEND telldus-core_SRCS + libtelldus-core.def + ${CMAKE_CURRENT_SOURCE_DIR}/telldus-core.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/telldus-core.rc + ) + ADD_DEFINITIONS( + -D_WINDOWS + -DTELLDUSCORE_EXPORTS + ) + IF (CMAKE_CL_64) + ADD_DEFINITIONS(-D_CL64) + ENDIF(CMAKE_CL_64) +ELSE (APPLE) + #### Linux #### + SET( telldus-core_TARGET telldus-core ) + LIST(APPEND telldus-core_LIBRARIES + TelldusCommon + ) + + ADD_DEFINITIONS( + -D_LINUX + ) +ENDIF (APPLE) + + + +######## Configuring ######## + +ADD_LIBRARY(${telldus-core_TARGET} SHARED + ${telldus-core_SRCS} + ${telldus-core_HDRS} + ${telldus-core_PUB_HDRS} +) + +#Copy public headers files on windows +IF (WIN32) + FOREACH(_FILE ${telldus-core_PUB_HDRS}) + ADD_CUSTOM_COMMAND( TARGET ${telldus-core_TARGET} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy \"${CMAKE_CURRENT_SOURCE_DIR}/${_FILE}\" \"${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}\" + COMMENT "Copy ${_FILE}" + ) + ENDFOREACH(_FILE) +ENDIF () + +ADD_DEPENDENCIES(${telldus-core_TARGET} TelldusCommon) + +IF (UNIX) + SET_TARGET_PROPERTIES( ${telldus-core_TARGET} PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden") +ENDIF (UNIX) + +TARGET_LINK_LIBRARIES( ${telldus-core_TARGET} ${telldus-core_LIBRARIES} ) + +SET_TARGET_PROPERTIES(${telldus-core_TARGET} PROPERTIES + FRAMEWORK TRUE + INSTALL_NAME_DIR "/Library/Frameworks" + PUBLIC_HEADER ${telldus-core_PUB_HDRS} + VERSION ${PACKAGE_VERSION} + SOVERSION ${PACKAGE_SOVERSION} +) +SIGN(${telldus-core_TARGET}) + +IF (NOT LIB_INSTALL_DIR) + SET(LIB_INSTALL_DIR "lib") +ENDIF (NOT LIB_INSTALL_DIR) + +IF (UNIX) + INSTALL(TARGETS ${telldus-core_TARGET} + LIBRARY DESTINATION ${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${LIB_INSTALL_DIR} + FRAMEWORK DESTINATION "/Library/Frameworks" + PUBLIC_HEADER DESTINATION include + ) +ENDIF (UNIX) + diff --git a/telldus-core/client/Client.cpp b/telldus-core/client/Client.cpp index 3b65b079..20e7e89f 100644 --- a/telldus-core/client/Client.cpp +++ b/telldus-core/client/Client.cpp @@ -1,266 +1,266 @@ -#include "Client.h" -#include "CallbackDispatcher.h" -#include "CallbackMainDispatcher.h" -#include "Socket.h" -#include "Strings.h" -#include "Mutex.h" - -#include - -using namespace TelldusCore; - -class Client::PrivateData { -public: - Socket eventSocket; - bool running, sensorCached, controllerCached; - std::wstring sensorCache, controllerCache; - TelldusCore::Mutex mutex; - CallbackMainDispatcher callbackMainDispatcher; - -}; - -Client *Client::instance = 0; - -Client::Client() - : Thread() -{ - d = new PrivateData; - d->running = true; - d->sensorCached = false; - d->controllerCached = false; - d->callbackMainDispatcher.start(); - start(); -} - -Client::~Client(void) { - stopThread(); - wait(); - { - TelldusCore::MutexLocker locker(&d->mutex); - } - delete d; -} - -void Client::close() { - if (Client::instance != 0) { - delete Client::instance; - Client::instance = 0; - } -} - -Client *Client::getInstance() { - if (Client::instance == 0) { - Client::instance = new Client(); - } - return Client::instance; -} - -bool Client::getBoolFromService(const Message &msg) { - return getIntegerFromService(msg) == TELLSTICK_SUCCESS; -} - -int Client::getIntegerFromService(const Message &msg) { - std::wstring response = sendToService(msg); - if (response.compare(L"") == 0) { - return TELLSTICK_ERROR_COMMUNICATING_SERVICE; - } - return Message::takeInt(&response); -} - -std::wstring Client::getWStringFromService(const Message &msg) { - std::wstring response = sendToService(msg); - return Message::takeString(&response); -} - -int Client::registerEvent( CallbackStruct::CallbackType type, void *eventFunction, void *context ) { - return d->callbackMainDispatcher.registerCallback(type, eventFunction, context ); -} - -void Client::run(){ - //listen here - d->eventSocket.connect(L"TelldusEvents"); - - while(d->running){ - - if(!d->eventSocket.isConnected()){ - d->eventSocket.connect(L"TelldusEvents"); //try to reconnect to service - if(!d->eventSocket.isConnected()){ - //reconnect didn't succeed, wait a while and try again - msleep(2000); - continue; - } - } - - std::wstring clientMessage = d->eventSocket.read(1000); //testing 5 second timeout - - while(clientMessage != L""){ - //a message arrived - std::wstring type = Message::takeString(&clientMessage); - if(type == L"TDDeviceChangeEvent"){ - DeviceChangeEventCallbackData *data = new DeviceChangeEventCallbackData(); - data->deviceId = Message::takeInt(&clientMessage); - data->changeEvent = Message::takeInt(&clientMessage); - data->changeType = Message::takeInt(&clientMessage); - d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); - - } else if(type == L"TDDeviceEvent"){ - DeviceEventCallbackData *data = new DeviceEventCallbackData(); - data->deviceId = Message::takeInt(&clientMessage); - data->deviceState = Message::takeInt(&clientMessage); - data->deviceStateValue = TelldusCore::wideToString(Message::takeString(&clientMessage)); - d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); - - } else if(type == L"TDRawDeviceEvent"){ - RawDeviceEventCallbackData *data = new RawDeviceEventCallbackData(); - data->data = TelldusCore::wideToString(Message::takeString(&clientMessage)); - data->controllerId = Message::takeInt(&clientMessage); - d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); - - } else if(type == L"TDSensorEvent"){ - SensorEventCallbackData *data = new SensorEventCallbackData(); - data->protocol = TelldusCore::wideToString(Message::takeString(&clientMessage)); - data->model = TelldusCore::wideToString(Message::takeString(&clientMessage)); - data->id = Message::takeInt(&clientMessage); - data->dataType = Message::takeInt(&clientMessage); - data->value = TelldusCore::wideToString(Message::takeString(&clientMessage)); - data->timestamp = Message::takeInt(&clientMessage); - d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); - - } else if(type == L"TDControllerEvent") { - ControllerEventCallbackData *data = new ControllerEventCallbackData(); - data->controllerId = Message::takeInt(&clientMessage); - data->changeEvent = Message::takeInt(&clientMessage); - data->changeType = Message::takeInt(&clientMessage); - data->newValue = TelldusCore::wideToString(Message::takeString(&clientMessage)); - d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); - - } else { - clientMessage = L""; //cleanup, if message contained garbage/unhandled data - } - } - } -} - -std::wstring Client::sendToService(const Message &msg) { - - int tries = 0; - std::wstring readData; - while(tries < 20){ - tries++; - if(tries == 20){ - TelldusCore::Message msg; - msg.addArgument(TELLSTICK_ERROR_CONNECTING_SERVICE); - return msg; - } - Socket s; - s.connect(L"TelldusClient"); - if (!s.isConnected()) { //Connection failed - msleep(500); - continue; //retry - } - s.write(msg.data()); - if (!s.isConnected()) { //Connection failed sometime during operation... (better check here, instead of 5 seconds timeout later) - msleep(500); - continue; //retry - } - readData = s.read(8000); //TODO changed to 10000 from 5000, how much does this do...? - if(readData == L""){ - msleep(500); - continue; //TODO can we be really sure it SHOULD be anything? - //TODO perhaps break here instead? - } - - if (!s.isConnected()) { //Connection failed sometime during operation... - msleep(500); - continue; //retry - } - break; - } - - return readData; -} - -void Client::stopThread(){ - d->running = false; - d->eventSocket.stopReadWait(); -} - -bool Client::unregisterCallback( int callbackId ) { - return d->callbackMainDispatcher.unregisterCallback(callbackId); -} - -int Client::getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *sensorId, int *dataTypes) { - if (!d->sensorCached) { - Message msg(L"tdSensor"); - std::wstring response = Client::getWStringFromService(msg); - int count = Message::takeInt(&response); - d->sensorCached = true; - d->sensorCache = L""; - if (count > 0) { - d->sensorCache = response; - } - } - - if (d->sensorCache == L"") { - d->sensorCached = false; - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - std::wstring p = Message::takeString(&d->sensorCache); - std::wstring m = Message::takeString(&d->sensorCache); - int id = Message::takeInt(&d->sensorCache); - int dt = Message::takeInt(&d->sensorCache); - - if (protocol && protocolLen) { - strncpy(protocol, TelldusCore::wideToString(p).c_str(), protocolLen); - } - if (model && modelLen) { - strncpy(model, TelldusCore::wideToString(m).c_str(), modelLen); - } - if (sensorId) { - (*sensorId) = id; - } - if (dataTypes) { - (*dataTypes) = dt; - } - - return TELLSTICK_SUCCESS; -} - -int Client::getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available) { - if (!d->controllerCached) { - Message msg(L"tdController"); - std::wstring response = Client::getWStringFromService(msg); - int count = Message::takeInt(&response); - d->controllerCached = true; - d->controllerCache = L""; - if (count > 0) { - d->controllerCache = response; - } - } - - if (d->controllerCache == L"") { - d->controllerCached = false; - return TELLSTICK_ERROR_NOT_FOUND; - } - - int id = Message::takeInt(&d->controllerCache); - int type = Message::takeInt(&d->controllerCache); - std::wstring n = Message::takeString(&d->controllerCache); - int a = Message::takeInt(&d->controllerCache); - - if (controllerId) { - (*controllerId) = id; - } - if (controllerType) { - (*controllerType) = type; - } - if (name && nameLen) { - strncpy(name, TelldusCore::wideToString(n).c_str(), nameLen); - } - if (available) { - (*available) = a; - } - - return TELLSTICK_SUCCESS; -} +#include "Client.h" +#include "CallbackDispatcher.h" +#include "CallbackMainDispatcher.h" +#include "Socket.h" +#include "Strings.h" +#include "Mutex.h" + +#include + +using namespace TelldusCore; + +class Client::PrivateData { +public: + Socket eventSocket; + bool running, sensorCached, controllerCached; + std::wstring sensorCache, controllerCache; + TelldusCore::Mutex mutex; + CallbackMainDispatcher callbackMainDispatcher; + +}; + +Client *Client::instance = 0; + +Client::Client() + : Thread() +{ + d = new PrivateData; + d->running = true; + d->sensorCached = false; + d->controllerCached = false; + d->callbackMainDispatcher.start(); + start(); +} + +Client::~Client(void) { + stopThread(); + wait(); + { + TelldusCore::MutexLocker locker(&d->mutex); + } + delete d; +} + +void Client::close() { + if (Client::instance != 0) { + delete Client::instance; + Client::instance = 0; + } +} + +Client *Client::getInstance() { + if (Client::instance == 0) { + Client::instance = new Client(); + } + return Client::instance; +} + +bool Client::getBoolFromService(const Message &msg) { + return getIntegerFromService(msg) == TELLSTICK_SUCCESS; +} + +int Client::getIntegerFromService(const Message &msg) { + std::wstring response = sendToService(msg); + if (response.compare(L"") == 0) { + return TELLSTICK_ERROR_COMMUNICATING_SERVICE; + } + return Message::takeInt(&response); +} + +std::wstring Client::getWStringFromService(const Message &msg) { + std::wstring response = sendToService(msg); + return Message::takeString(&response); +} + +int Client::registerEvent( CallbackStruct::CallbackType type, void *eventFunction, void *context ) { + return d->callbackMainDispatcher.registerCallback(type, eventFunction, context ); +} + +void Client::run(){ + //listen here + d->eventSocket.connect(L"TelldusEvents"); + + while(d->running){ + + if(!d->eventSocket.isConnected()){ + d->eventSocket.connect(L"TelldusEvents"); //try to reconnect to service + if(!d->eventSocket.isConnected()){ + //reconnect didn't succeed, wait a while and try again + msleep(2000); + continue; + } + } + + std::wstring clientMessage = d->eventSocket.read(1000); //testing 5 second timeout + + while(clientMessage != L""){ + //a message arrived + std::wstring type = Message::takeString(&clientMessage); + if(type == L"TDDeviceChangeEvent"){ + DeviceChangeEventCallbackData *data = new DeviceChangeEventCallbackData(); + data->deviceId = Message::takeInt(&clientMessage); + data->changeEvent = Message::takeInt(&clientMessage); + data->changeType = Message::takeInt(&clientMessage); + d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); + + } else if(type == L"TDDeviceEvent"){ + DeviceEventCallbackData *data = new DeviceEventCallbackData(); + data->deviceId = Message::takeInt(&clientMessage); + data->deviceState = Message::takeInt(&clientMessage); + data->deviceStateValue = TelldusCore::wideToString(Message::takeString(&clientMessage)); + d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); + + } else if(type == L"TDRawDeviceEvent"){ + RawDeviceEventCallbackData *data = new RawDeviceEventCallbackData(); + data->data = TelldusCore::wideToString(Message::takeString(&clientMessage)); + data->controllerId = Message::takeInt(&clientMessage); + d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); + + } else if(type == L"TDSensorEvent"){ + SensorEventCallbackData *data = new SensorEventCallbackData(); + data->protocol = TelldusCore::wideToString(Message::takeString(&clientMessage)); + data->model = TelldusCore::wideToString(Message::takeString(&clientMessage)); + data->id = Message::takeInt(&clientMessage); + data->dataType = Message::takeInt(&clientMessage); + data->value = TelldusCore::wideToString(Message::takeString(&clientMessage)); + data->timestamp = Message::takeInt(&clientMessage); + d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); + + } else if(type == L"TDControllerEvent") { + ControllerEventCallbackData *data = new ControllerEventCallbackData(); + data->controllerId = Message::takeInt(&clientMessage); + data->changeEvent = Message::takeInt(&clientMessage); + data->changeType = Message::takeInt(&clientMessage); + data->newValue = TelldusCore::wideToString(Message::takeString(&clientMessage)); + d->callbackMainDispatcher.retrieveCallbackEvent()->signal(data); + + } else { + clientMessage = L""; //cleanup, if message contained garbage/unhandled data + } + } + } +} + +std::wstring Client::sendToService(const Message &msg) { + + int tries = 0; + std::wstring readData; + while(tries < 20){ + tries++; + if(tries == 20){ + TelldusCore::Message msg; + msg.addArgument(TELLSTICK_ERROR_CONNECTING_SERVICE); + return msg; + } + Socket s; + s.connect(L"TelldusClient"); + if (!s.isConnected()) { //Connection failed + msleep(500); + continue; //retry + } + s.write(msg.data()); + if (!s.isConnected()) { //Connection failed sometime during operation... (better check here, instead of 5 seconds timeout later) + msleep(500); + continue; //retry + } + readData = s.read(8000); //TODO changed to 10000 from 5000, how much does this do...? + if(readData == L""){ + msleep(500); + continue; //TODO can we be really sure it SHOULD be anything? + //TODO perhaps break here instead? + } + + if (!s.isConnected()) { //Connection failed sometime during operation... + msleep(500); + continue; //retry + } + break; + } + + return readData; +} + +void Client::stopThread(){ + d->running = false; + d->eventSocket.stopReadWait(); +} + +bool Client::unregisterCallback( int callbackId ) { + return d->callbackMainDispatcher.unregisterCallback(callbackId); +} + +int Client::getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *sensorId, int *dataTypes) { + if (!d->sensorCached) { + Message msg(L"tdSensor"); + std::wstring response = Client::getWStringFromService(msg); + int count = Message::takeInt(&response); + d->sensorCached = true; + d->sensorCache = L""; + if (count > 0) { + d->sensorCache = response; + } + } + + if (d->sensorCache == L"") { + d->sensorCached = false; + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + std::wstring p = Message::takeString(&d->sensorCache); + std::wstring m = Message::takeString(&d->sensorCache); + int id = Message::takeInt(&d->sensorCache); + int dt = Message::takeInt(&d->sensorCache); + + if (protocol && protocolLen) { + strncpy(protocol, TelldusCore::wideToString(p).c_str(), protocolLen); + } + if (model && modelLen) { + strncpy(model, TelldusCore::wideToString(m).c_str(), modelLen); + } + if (sensorId) { + (*sensorId) = id; + } + if (dataTypes) { + (*dataTypes) = dt; + } + + return TELLSTICK_SUCCESS; +} + +int Client::getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available) { + if (!d->controllerCached) { + Message msg(L"tdController"); + std::wstring response = Client::getWStringFromService(msg); + int count = Message::takeInt(&response); + d->controllerCached = true; + d->controllerCache = L""; + if (count > 0) { + d->controllerCache = response; + } + } + + if (d->controllerCache == L"") { + d->controllerCached = false; + return TELLSTICK_ERROR_NOT_FOUND; + } + + int id = Message::takeInt(&d->controllerCache); + int type = Message::takeInt(&d->controllerCache); + std::wstring n = Message::takeString(&d->controllerCache); + int a = Message::takeInt(&d->controllerCache); + + if (controllerId) { + (*controllerId) = id; + } + if (controllerType) { + (*controllerType) = type; + } + if (name && nameLen) { + strncpy(name, TelldusCore::wideToString(n).c_str(), nameLen); + } + if (available) { + (*available) = a; + } + + return TELLSTICK_SUCCESS; +} diff --git a/telldus-core/client/Client.h b/telldus-core/client/Client.h index ccaf00db..2bd0c5ce 100644 --- a/telldus-core/client/Client.h +++ b/telldus-core/client/Client.h @@ -1,42 +1,42 @@ -#ifndef CLIENT_H -#define CLIENT_H - -#include "Message.h" -#include "telldus-core.h" -#include "Thread.h" -#include "CallbackDispatcher.h" - -namespace TelldusCore { - class Client : public Thread - { - public: - ~Client(void); - - static Client *getInstance(); - static void close(); - - int registerEvent(CallbackStruct::CallbackType type, void *eventFunction, void *context ); - void stopThread(void); - bool unregisterCallback( int callbackId ); - - int getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *id, int *dataTypes); - int getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available); - - static bool getBoolFromService(const Message &msg); - static int getIntegerFromService(const Message &msg); - static std::wstring getWStringFromService(const Message &msg); - - protected: - void run(void); - - private: - Client(); - static std::wstring sendToService(const Message &msg); - - class PrivateData; - PrivateData *d; - static Client *instance; - }; -} - -#endif //CLIENT_H +#ifndef CLIENT_H +#define CLIENT_H + +#include "Message.h" +#include "telldus-core.h" +#include "Thread.h" +#include "CallbackDispatcher.h" + +namespace TelldusCore { + class Client : public Thread + { + public: + ~Client(void); + + static Client *getInstance(); + static void close(); + + int registerEvent(CallbackStruct::CallbackType type, void *eventFunction, void *context ); + void stopThread(void); + bool unregisterCallback( int callbackId ); + + int getSensor(char *protocol, int protocolLen, char *model, int modelLen, int *id, int *dataTypes); + int getController(int *controllerId, int *controllerType, char *name, int nameLen, int *available); + + static bool getBoolFromService(const Message &msg); + static int getIntegerFromService(const Message &msg); + static std::wstring getWStringFromService(const Message &msg); + + protected: + void run(void); + + private: + Client(); + static std::wstring sendToService(const Message &msg); + + class PrivateData; + PrivateData *d; + static Client *instance; + }; +} + +#endif //CLIENT_H diff --git a/telldus-core/client/libtelldus-core.def b/telldus-core/client/libtelldus-core.def index be32e8cb..57c3976e 100644 --- a/telldus-core/client/libtelldus-core.def +++ b/telldus-core/client/libtelldus-core.def @@ -1,60 +1,60 @@ -LIBRARY tellduscore -EXPORTS - tdGetNumberOfDevices @1 - tdGetDeviceId @2 - - tdGetName @3 - tdGetProtocol @4 - tdGetModel @5 - tdGetDeviceParameter @6 - - tdSetName @7 - tdSetProtocol @8 - tdSetModel @9 - tdSetDeviceParameter @10 - - tdAddDevice @11 - tdRemoveDevice @12 - - tdMethods @13 - tdTurnOn @14 - tdTurnOff @15 - tdBell @16 - tdDim @17 - - tdGetErrorString @18 - - tdClose @19 - - tdInit @20 - tdRegisterDeviceEvent @21 - tdLastSentCommand @22 - tdGetDeviceType @23 - - tdSendRawCommand @24 - tdRegisterRawDeviceEvent @25 - - tdLearn @26 - tdLastSentValue @27 - - tdReleaseString @28 - tdUnregisterCallback @29 - - tdConnectTellStickController @30 - tdDisconnectTellStickController @31 - - tdRegisterDeviceChangeEvent @32 - tdExecute @33 - tdUp @34 - tdDown @35 - tdStop @36 - - tdRegisterSensorEvent @37 - tdSensor @38 - tdSensorValue @39 - - tdController @40 - tdControllerValue @41 - tdSetControllerValue @42 - tdRemoveController @43 - tdRegisterControllerEvent @44 +LIBRARY tellduscore +EXPORTS + tdGetNumberOfDevices @1 + tdGetDeviceId @2 + + tdGetName @3 + tdGetProtocol @4 + tdGetModel @5 + tdGetDeviceParameter @6 + + tdSetName @7 + tdSetProtocol @8 + tdSetModel @9 + tdSetDeviceParameter @10 + + tdAddDevice @11 + tdRemoveDevice @12 + + tdMethods @13 + tdTurnOn @14 + tdTurnOff @15 + tdBell @16 + tdDim @17 + + tdGetErrorString @18 + + tdClose @19 + + tdInit @20 + tdRegisterDeviceEvent @21 + tdLastSentCommand @22 + tdGetDeviceType @23 + + tdSendRawCommand @24 + tdRegisterRawDeviceEvent @25 + + tdLearn @26 + tdLastSentValue @27 + + tdReleaseString @28 + tdUnregisterCallback @29 + + tdConnectTellStickController @30 + tdDisconnectTellStickController @31 + + tdRegisterDeviceChangeEvent @32 + tdExecute @33 + tdUp @34 + tdDown @35 + tdStop @36 + + tdRegisterSensorEvent @37 + tdSensor @38 + tdSensorValue @39 + + tdController @40 + tdControllerValue @41 + tdSetControllerValue @42 + tdRemoveController @43 + tdRegisterControllerEvent @44 diff --git a/telldus-core/cmake/FindSignTool.cmake b/telldus-core/cmake/FindSignTool.cmake index 5ea02930..ff7dfc08 100644 --- a/telldus-core/cmake/FindSignTool.cmake +++ b/telldus-core/cmake/FindSignTool.cmake @@ -1,19 +1,19 @@ -IF(WIN32) - SET(SIGN_FILES FALSE CACHE BOOL "Sign the generated files. This requires a certificate to be installed on the computer!") -ENDIF() - -FUNCTION(SIGN TARGET) - IF (NOT WIN32) - RETURN() - ENDIF() - IF (NOT SIGN_FILES) - RETURN() - ENDIF() - GET_TARGET_PROPERTY(file ${TARGET} LOCATION) - GET_FILENAME_COMPONENT(filename ${file} NAME) - ADD_CUSTOM_COMMAND( TARGET ${TARGET} POST_BUILD - COMMAND signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll ${file} - COMMENT "Signing file ${filename}" - ) -ENDFUNCTION() +IF(WIN32) + SET(SIGN_FILES FALSE CACHE BOOL "Sign the generated files. This requires a certificate to be installed on the computer!") +ENDIF() + +FUNCTION(SIGN TARGET) + IF (NOT WIN32) + RETURN() + ENDIF() + IF (NOT SIGN_FILES) + RETURN() + ENDIF() + GET_TARGET_PROPERTY(file ${TARGET} LOCATION) + GET_FILENAME_COMPONENT(filename ${file} NAME) + ADD_CUSTOM_COMMAND( TARGET ${TARGET} POST_BUILD + COMMAND signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll ${file} + COMMENT "Signing file ${filename}" + ) +ENDFUNCTION() diff --git a/telldus-core/common/CMakeLists.txt b/telldus-core/common/CMakeLists.txt index c0d64759..b55277e4 100644 --- a/telldus-core/common/CMakeLists.txt +++ b/telldus-core/common/CMakeLists.txt @@ -1,87 +1,87 @@ -IF(COMMAND cmake_policy) - CMAKE_POLICY(SET CMP0003 NEW) -ENDIF(COMMAND cmake_policy) - -######## Non configurable options ######## -SET( telldus-common_SRCS - Event.cpp - Message.cpp - Mutex.cpp - Strings.cpp - Thread.cpp -) - -SET( telldus-common_HDRS - common.h - Event.h - EventHandler.h - Message.h - Mutex.h - Socket.h - Strings.h - Thread.h -) - -######## Configurable options for the platform ######## - - -######## Platforms-specific, non configurable ######## - -IF (APPLE) - #### Mac OS X #### - FIND_LIBRARY(ICONV_LIBRARY iconv) - ADD_DEFINITIONS( -D_MACOSX ) - LIST(APPEND telldus-common_SRCS - Event_unix.cpp - EventHandler_unix.cpp - Socket_unix.cpp +IF(COMMAND cmake_policy) + CMAKE_POLICY(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +######## Non configurable options ######## +SET( telldus-common_SRCS + Event.cpp + Message.cpp + Mutex.cpp + Strings.cpp + Thread.cpp +) + +SET( telldus-common_HDRS + common.h + Event.h + EventHandler.h + Message.h + Mutex.h + Socket.h + Strings.h + Thread.h +) + +######## Configurable options for the platform ######## + + +######## Platforms-specific, non configurable ######## + +IF (APPLE) + #### Mac OS X #### + FIND_LIBRARY(ICONV_LIBRARY iconv) + ADD_DEFINITIONS( -D_MACOSX ) + LIST(APPEND telldus-common_SRCS + Event_unix.cpp + EventHandler_unix.cpp + Socket_unix.cpp stdlibc_workaround.cpp #Remove this when we drop support for 10.5 - ) - LIST(APPEND telldus-common_LIBRARIES - ${ICONV_LIBRARY} - ) -ELSEIF (WIN32) - #### Windows #### - ADD_DEFINITIONS( -DUNICODE ) - ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No - ADD_DEFINITIONS( -D_WINDOWS ) - LIST(APPEND telldus-common_SRCS - Event_win.cpp - EventHandler_win.cpp - Socket_win.cpp - ) + ) + LIST(APPEND telldus-common_LIBRARIES + ${ICONV_LIBRARY} + ) +ELSEIF (WIN32) + #### Windows #### + ADD_DEFINITIONS( -DUNICODE ) + ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No + ADD_DEFINITIONS( -D_WINDOWS ) + LIST(APPEND telldus-common_SRCS + Event_win.cpp + EventHandler_win.cpp + Socket_win.cpp + ) ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") #### FreeBSD #### FIND_LIBRARY(ICONV_LIBRARY iconv) ADD_DEFINITIONS( -D_FREEBSD ) LIST(APPEND telldus-common_SRCS - Event_unix.cpp - EventHandler_unix.cpp + Event_unix.cpp + EventHandler_unix.cpp Socket_unix.cpp ) LIST(APPEND telldus-common_LIBRARIES ${ICONV_LIBRARY} ) -ELSE (APPLE) - #### Linux #### - ADD_DEFINITIONS( -D_LINUX ) - LIST(APPEND telldus-common_SRCS - Event_unix.cpp - EventHandler_unix.cpp - Socket_unix.cpp - ) -ENDIF (APPLE) - - -######## Configuring ######## - -ADD_LIBRARY(TelldusCommon STATIC - ${telldus-common_SRCS} - ${telldus-common_HDRS} -) - -IF (UNIX) - SET_TARGET_PROPERTIES( TelldusCommon PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden") -ENDIF (UNIX) - -TARGET_LINK_LIBRARIES( TelldusCommon ${telldus-common_LIBRARIES} ) +ELSE (APPLE) + #### Linux #### + ADD_DEFINITIONS( -D_LINUX ) + LIST(APPEND telldus-common_SRCS + Event_unix.cpp + EventHandler_unix.cpp + Socket_unix.cpp + ) +ENDIF (APPLE) + + +######## Configuring ######## + +ADD_LIBRARY(TelldusCommon STATIC + ${telldus-common_SRCS} + ${telldus-common_HDRS} +) + +IF (UNIX) + SET_TARGET_PROPERTIES( TelldusCommon PROPERTIES COMPILE_FLAGS "-fPIC -fvisibility=hidden") +ENDIF (UNIX) + +TARGET_LINK_LIBRARIES( TelldusCommon ${telldus-common_LIBRARIES} ) diff --git a/telldus-core/common/Event.cpp b/telldus-core/common/Event.cpp index 76d060cb..02ed6b8c 100644 --- a/telldus-core/common/Event.cpp +++ b/telldus-core/common/Event.cpp @@ -1,77 +1,77 @@ -#include "Event.h" -#include "EventHandler.h" -#include "Mutex.h" - -#include - -using namespace TelldusCore; - -EventData::~EventData() { -} - -bool EventData::isValid() const { - return false; -}; - -bool EventDataBase::isValid() const { - return true; -}; - -class EventBase::PrivateData { -public: - TelldusCore::Mutex mutex; - EventHandler *handler; - std::list eventDataList; -}; - -EventBase::EventBase(TelldusCore::EventHandler *handler) { - d = new PrivateData; - d->handler = handler; -} - -EventBase::~EventBase(void) { - delete d; -} - -void EventBase::clearHandler() { - TelldusCore::MutexLocker locker(&d->mutex); - d->handler = 0; -} - -void EventBase::popSignal() { - this->takeSignal(); -} - -EventHandler *EventBase::handler() const { - return d->handler; -} - -bool EventBase::isSignaled() { - TelldusCore::MutexLocker locker(&d->mutex); - return (d->eventDataList.size() > 0); -} - -void EventBase::signal() { - signal(new EventData()); -} - -void EventBase::signal(EventData *eventData) { - { - TelldusCore::MutexLocker locker(&d->mutex); - d->eventDataList.push_back(EventDataRef(eventData)); - } - sendSignal(); -} - -EventDataRef EventBase::takeSignal() { - TelldusCore::MutexLocker locker(&d->mutex); - if (d->eventDataList.size() == 0) { - return EventDataRef(new EventData()); - } - EventDataRef data = d->eventDataList.front(); - d->eventDataList.pop_front(); - if (d->eventDataList.size() == 0) { - this->clearSignal(); - } - return data; -} +#include "Event.h" +#include "EventHandler.h" +#include "Mutex.h" + +#include + +using namespace TelldusCore; + +EventData::~EventData() { +} + +bool EventData::isValid() const { + return false; +}; + +bool EventDataBase::isValid() const { + return true; +}; + +class EventBase::PrivateData { +public: + TelldusCore::Mutex mutex; + EventHandler *handler; + std::list eventDataList; +}; + +EventBase::EventBase(TelldusCore::EventHandler *handler) { + d = new PrivateData; + d->handler = handler; +} + +EventBase::~EventBase(void) { + delete d; +} + +void EventBase::clearHandler() { + TelldusCore::MutexLocker locker(&d->mutex); + d->handler = 0; +} + +void EventBase::popSignal() { + this->takeSignal(); +} + +EventHandler *EventBase::handler() const { + return d->handler; +} + +bool EventBase::isSignaled() { + TelldusCore::MutexLocker locker(&d->mutex); + return (d->eventDataList.size() > 0); +} + +void EventBase::signal() { + signal(new EventData()); +} + +void EventBase::signal(EventData *eventData) { + { + TelldusCore::MutexLocker locker(&d->mutex); + d->eventDataList.push_back(EventDataRef(eventData)); + } + sendSignal(); +} + +EventDataRef EventBase::takeSignal() { + TelldusCore::MutexLocker locker(&d->mutex); + if (d->eventDataList.size() == 0) { + return EventDataRef(new EventData()); + } + EventDataRef data = d->eventDataList.front(); + d->eventDataList.pop_front(); + if (d->eventDataList.size() == 0) { + this->clearSignal(); + } + return data; +} diff --git a/telldus-core/common/EventHandler.h b/telldus-core/common/EventHandler.h index d6a59ef7..7123bf90 100644 --- a/telldus-core/common/EventHandler.h +++ b/telldus-core/common/EventHandler.h @@ -1,29 +1,29 @@ -#ifndef EVENTHANDLER_H -#define EVENTHANDLER_H - -#include "Event.h" - -namespace TelldusCore { - - class EventHandler { - public: - EventHandler(); - virtual ~EventHandler(void); - - EventRef addEvent(); - - bool waitForAny(); - - protected: - void signal(Event *event); - - private: - class PrivateData; - PrivateData *d; - bool listIsSignalled(); - - friend class Event; - }; -} - -#endif //EVENTHANDLER_H +#ifndef EVENTHANDLER_H +#define EVENTHANDLER_H + +#include "Event.h" + +namespace TelldusCore { + + class EventHandler { + public: + EventHandler(); + virtual ~EventHandler(void); + + EventRef addEvent(); + + bool waitForAny(); + + protected: + void signal(Event *event); + + private: + class PrivateData; + PrivateData *d; + bool listIsSignalled(); + + friend class Event; + }; +} + +#endif //EVENTHANDLER_H diff --git a/telldus-core/common/EventHandler_unix.cpp b/telldus-core/common/EventHandler_unix.cpp index f826c004..df36338e 100644 --- a/telldus-core/common/EventHandler_unix.cpp +++ b/telldus-core/common/EventHandler_unix.cpp @@ -1,72 +1,72 @@ -#include "EventHandler.h" -#include "Event.h" -#include "Mutex.h" -#include "Thread.h" -#include -#include -#include - -using namespace TelldusCore; - -class EventHandler::PrivateData { -public: - pthread_cond_t event; - pthread_mutex_t mutex; - std::list eventList; - TelldusCore::Mutex listMutex; -}; - -EventHandler::EventHandler() { - d = new PrivateData; - pthread_cond_init(&d->event, NULL); - pthread_mutex_init(&d->mutex, NULL); -} - -EventHandler::~EventHandler(void) { - pthread_mutex_destroy(&d->mutex); - pthread_cond_destroy(&d->event); - - std::list::const_iterator it = d->eventList.begin(); - for(; it != d->eventList.end(); ++it) { - //We clear the handler if someone else still has a reference to the event - (*it)->clearHandler(); - } - - delete d; -} - -EventRef EventHandler::addEvent() { - EventRef event(new Event(this)); - TelldusCore::MutexLocker locker(&d->listMutex); - d->eventList.push_back(event); - return event; -} - -bool EventHandler::listIsSignalled(){ - TelldusCore::MutexLocker locker(&d->listMutex); - - std::list::const_iterator it = d->eventList.begin(); - for(; it != d->eventList.end(); ++it) { - if((*it)->isSignaled()){ - return true; - } - } - return false; -} - -void EventHandler::signal(Event *event) { - pthread_mutex_lock(&d->mutex); - //event->setSignaled(); - pthread_cond_signal(&d->event); - pthread_mutex_unlock(&d->mutex); -} - -bool EventHandler::waitForAny() { - pthread_mutex_lock(&d->mutex); - while(!listIsSignalled()) { - pthread_cond_wait(&d->event, &d->mutex); - } - pthread_mutex_unlock(&d->mutex); - - return true; -} +#include "EventHandler.h" +#include "Event.h" +#include "Mutex.h" +#include "Thread.h" +#include +#include +#include + +using namespace TelldusCore; + +class EventHandler::PrivateData { +public: + pthread_cond_t event; + pthread_mutex_t mutex; + std::list eventList; + TelldusCore::Mutex listMutex; +}; + +EventHandler::EventHandler() { + d = new PrivateData; + pthread_cond_init(&d->event, NULL); + pthread_mutex_init(&d->mutex, NULL); +} + +EventHandler::~EventHandler(void) { + pthread_mutex_destroy(&d->mutex); + pthread_cond_destroy(&d->event); + + std::list::const_iterator it = d->eventList.begin(); + for(; it != d->eventList.end(); ++it) { + //We clear the handler if someone else still has a reference to the event + (*it)->clearHandler(); + } + + delete d; +} + +EventRef EventHandler::addEvent() { + EventRef event(new Event(this)); + TelldusCore::MutexLocker locker(&d->listMutex); + d->eventList.push_back(event); + return event; +} + +bool EventHandler::listIsSignalled(){ + TelldusCore::MutexLocker locker(&d->listMutex); + + std::list::const_iterator it = d->eventList.begin(); + for(; it != d->eventList.end(); ++it) { + if((*it)->isSignaled()){ + return true; + } + } + return false; +} + +void EventHandler::signal(Event *event) { + pthread_mutex_lock(&d->mutex); + //event->setSignaled(); + pthread_cond_signal(&d->event); + pthread_mutex_unlock(&d->mutex); +} + +bool EventHandler::waitForAny() { + pthread_mutex_lock(&d->mutex); + while(!listIsSignalled()) { + pthread_cond_wait(&d->event, &d->mutex); + } + pthread_mutex_unlock(&d->mutex); + + return true; +} diff --git a/telldus-core/common/EventHandler_win.cpp b/telldus-core/common/EventHandler_win.cpp index 9c8b4be5..35158a41 100644 --- a/telldus-core/common/EventHandler_win.cpp +++ b/telldus-core/common/EventHandler_win.cpp @@ -1,69 +1,69 @@ -#include "EventHandler.h" -#include "Event.h" -#include "Mutex.h" - -#include -#include - -using namespace TelldusCore; - -class EventHandler::PrivateData { -public: - HANDLE *eventArray; - EventRef *eventObjectArray; - TelldusCore::Mutex mutex; - int eventCount; -}; - -EventHandler::EventHandler() { - d = new PrivateData; - d->eventCount = 0; - d->eventArray = new HANDLE[0]; - d->eventObjectArray = new EventRef[0]; -} - -EventHandler::~EventHandler(void) { - delete[] d->eventObjectArray; - delete[] d->eventArray; - delete d; -} - -EventRef EventHandler::addEvent() { - EventRef event(new Event(this)); - - TelldusCore::MutexLocker locker(&d->mutex); - - HANDLE *newArray = new HANDLE[d->eventCount+1]; - EventRef *newObjectArray = new EventRef[d->eventCount+1]; - for (int i = 0; i < d->eventCount; ++i) { - newArray[i] = d->eventArray[i]; - newObjectArray[i] = d->eventObjectArray[i]; - } - delete[] d->eventArray; - delete[] d->eventObjectArray; - d->eventArray = newArray; - d->eventObjectArray = newObjectArray; - d->eventArray[d->eventCount] = event->retrieveNative(); - d->eventObjectArray[d->eventCount] = event; - ++d->eventCount; - return event; -} - -void EventHandler::signal(Event *) { -} - -bool EventHandler::waitForAny() { - - while(1){ - int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, 1000); - if (result == WAIT_TIMEOUT) { - continue; - } - TelldusCore::MutexLocker locker(&d->mutex); - int eventIndex = result - WAIT_OBJECT_0; - if (eventIndex >= d->eventCount) { - return false; - } - return true; - } -} +#include "EventHandler.h" +#include "Event.h" +#include "Mutex.h" + +#include +#include + +using namespace TelldusCore; + +class EventHandler::PrivateData { +public: + HANDLE *eventArray; + EventRef *eventObjectArray; + TelldusCore::Mutex mutex; + int eventCount; +}; + +EventHandler::EventHandler() { + d = new PrivateData; + d->eventCount = 0; + d->eventArray = new HANDLE[0]; + d->eventObjectArray = new EventRef[0]; +} + +EventHandler::~EventHandler(void) { + delete[] d->eventObjectArray; + delete[] d->eventArray; + delete d; +} + +EventRef EventHandler::addEvent() { + EventRef event(new Event(this)); + + TelldusCore::MutexLocker locker(&d->mutex); + + HANDLE *newArray = new HANDLE[d->eventCount+1]; + EventRef *newObjectArray = new EventRef[d->eventCount+1]; + for (int i = 0; i < d->eventCount; ++i) { + newArray[i] = d->eventArray[i]; + newObjectArray[i] = d->eventObjectArray[i]; + } + delete[] d->eventArray; + delete[] d->eventObjectArray; + d->eventArray = newArray; + d->eventObjectArray = newObjectArray; + d->eventArray[d->eventCount] = event->retrieveNative(); + d->eventObjectArray[d->eventCount] = event; + ++d->eventCount; + return event; +} + +void EventHandler::signal(Event *) { +} + +bool EventHandler::waitForAny() { + + while(1){ + int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, 1000); + if (result == WAIT_TIMEOUT) { + continue; + } + TelldusCore::MutexLocker locker(&d->mutex); + int eventIndex = result - WAIT_OBJECT_0; + if (eventIndex >= d->eventCount) { + return false; + } + return true; + } +} diff --git a/telldus-core/common/Event_unix.cpp b/telldus-core/common/Event_unix.cpp index 0cf88cc2..e6a375d7 100644 --- a/telldus-core/common/Event_unix.cpp +++ b/telldus-core/common/Event_unix.cpp @@ -1,28 +1,28 @@ -#include "Event.h" -#include "EventHandler.h" -#include "Thread.h" - -using namespace TelldusCore; - -class Event::PrivateData { -public: -}; - -Event::Event(EventHandler *handler) - :EventBase(handler){ - d = new PrivateData; -} - -Event::~Event(void) { - delete d; -} - -void Event::clearSignal() { -} - -void Event::sendSignal() { - EventHandler *handler = this->handler(); - if (handler) { - handler->signal(this); - } -} +#include "Event.h" +#include "EventHandler.h" +#include "Thread.h" + +using namespace TelldusCore; + +class Event::PrivateData { +public: +}; + +Event::Event(EventHandler *handler) + :EventBase(handler){ + d = new PrivateData; +} + +Event::~Event(void) { + delete d; +} + +void Event::clearSignal() { +} + +void Event::sendSignal() { + EventHandler *handler = this->handler(); + if (handler) { + handler->signal(this); + } +} diff --git a/telldus-core/common/Event_win.cpp b/telldus-core/common/Event_win.cpp index 7a9e9fb5..681d5e91 100644 --- a/telldus-core/common/Event_win.cpp +++ b/telldus-core/common/Event_win.cpp @@ -1,35 +1,35 @@ -#include "Event.h" -#include "Thread.h" - -using namespace TelldusCore; - -class Event::PrivateData { -public: - EVENT_T event; -}; - -Event::Event(EventHandler *handler) - :EventBase(handler) -{ - d = new PrivateData; - d->event = CreateEvent(NULL, true, false, NULL); -} - -Event::~Event(void) { - CloseHandle(d->event); - delete d; -} - -EVENT_T Event::retrieveNative() { - return d->event; -} - -void Event::clearSignal() { - ResetEvent(d->event); -} - -void Event::sendSignal() { - SetEvent(d->event); -} - - +#include "Event.h" +#include "Thread.h" + +using namespace TelldusCore; + +class Event::PrivateData { +public: + EVENT_T event; +}; + +Event::Event(EventHandler *handler) + :EventBase(handler) +{ + d = new PrivateData; + d->event = CreateEvent(NULL, true, false, NULL); +} + +Event::~Event(void) { + CloseHandle(d->event); + delete d; +} + +EVENT_T Event::retrieveNative() { + return d->event; +} + +void Event::clearSignal() { + ResetEvent(d->event); +} + +void Event::sendSignal() { + SetEvent(d->event); +} + + diff --git a/telldus-core/common/Message.cpp b/telldus-core/common/Message.cpp index f2820021..efc847ea 100644 --- a/telldus-core/common/Message.cpp +++ b/telldus-core/common/Message.cpp @@ -1,128 +1,128 @@ -#include "Message.h" -#include "Socket.h" -#include "Strings.h" -#include -#include -#include - -using namespace TelldusCore; - - -Message::Message() - : std::wstring() -{ -} - -Message::Message(const std::wstring &functionName) - :std::wstring() -{ - this->addArgument(functionName); -} - -Message::~Message(void) { -} - -void Message::addArgument(const std::wstring &value) { - //std::wstringstream st; - //st << (int)value.size(); - this->append(TelldusCore::intToWstring(value.size())); //st.str()); - this->append(L":"); - this->append(value); -} - -void Message::addArgument(int value) { - //std::wstringstream st; - //st << (int)value; - this->append(L"i"); - this->append(TelldusCore::intToWstring(value)); // st.str()); - this->append(L"s"); -} - -/* -void Message::addSpecialArgument(const std::wstring &value){ - int i = 0; - while(i<1000000){ - i++; - - char numstr[21]; // enough to hold all numbers up to 64-bits - //sprintf(numstr, "%d", value.size()); - //this->append(TelldusCore::charToWstring(numstr)); //.str()); - - itoa(value.size(), numstr, 10); - std::string test(numstr); - std::wstring temp(test.length(), L' '); - std::copy(test.begin(), test.end(), temp.begin()); - - this->append(temp); - this->append(L":"); - this->append(value); - - /* - std::wstringstream st; - st << (int)value.size(); - this->append(st.str()); - this->append(L":"); - this->append(value); - - } -} - -void Message::addSpecialArgument(int value){ - int i = 0; - while(i<1000000){ - i++; - /* - //std::wstringstream st; - //st << (int)value; - this->append(L"i"); - //this->append(st.str()); - this->append(L"s"); - - } -} -*/ -/* -void Message::addSpecialArgument(const char *value){ - this->addSpecialArgument(TelldusCore::charToWstring(value)); -} -*/ - -void Message::addArgument(const char *value) { - this->addArgument(TelldusCore::charToWstring(value)); -} - -bool Message::nextIsInt(const std::wstring &message) { - if (message.length() == 0) { - return false; - } - return (message.at(0) == 'i'); -} - -bool Message::nextIsString(const std::wstring &message) { - if (message.length() == 0) { - return false; - } - return (iswdigit(message.at(0)) != 0); -} - -std::wstring Message::takeString(std::wstring *message) { - - if (!Message::nextIsString(*message)) { - return L""; - } - size_t index = message->find(':'); - int length = wideToInteger(message->substr(0, index)); - std::wstring retval(message->substr(index+1, length)); - message->erase(0, index+length+1); - return retval; -} - -int Message::takeInt(std::wstring *message) { - if (!Message::nextIsInt(*message)) { - return 0; - } - size_t index = message->find('s'); - int value = wideToInteger(message->substr(1, index - 1)); - message->erase(0, index+1); - return value; -} +#include "Message.h" +#include "Socket.h" +#include "Strings.h" +#include +#include +#include + +using namespace TelldusCore; + + +Message::Message() + : std::wstring() +{ +} + +Message::Message(const std::wstring &functionName) + :std::wstring() +{ + this->addArgument(functionName); +} + +Message::~Message(void) { +} + +void Message::addArgument(const std::wstring &value) { + //std::wstringstream st; + //st << (int)value.size(); + this->append(TelldusCore::intToWstring(value.size())); //st.str()); + this->append(L":"); + this->append(value); +} + +void Message::addArgument(int value) { + //std::wstringstream st; + //st << (int)value; + this->append(L"i"); + this->append(TelldusCore::intToWstring(value)); // st.str()); + this->append(L"s"); +} + +/* +void Message::addSpecialArgument(const std::wstring &value){ + int i = 0; + while(i<1000000){ + i++; + + char numstr[21]; // enough to hold all numbers up to 64-bits + //sprintf(numstr, "%d", value.size()); + //this->append(TelldusCore::charToWstring(numstr)); //.str()); + + itoa(value.size(), numstr, 10); + std::string test(numstr); + std::wstring temp(test.length(), L' '); + std::copy(test.begin(), test.end(), temp.begin()); + + this->append(temp); + this->append(L":"); + this->append(value); + + /* + std::wstringstream st; + st << (int)value.size(); + this->append(st.str()); + this->append(L":"); + this->append(value); + + } +} + +void Message::addSpecialArgument(int value){ + int i = 0; + while(i<1000000){ + i++; + /* + //std::wstringstream st; + //st << (int)value; + this->append(L"i"); + //this->append(st.str()); + this->append(L"s"); + + } +} +*/ +/* +void Message::addSpecialArgument(const char *value){ + this->addSpecialArgument(TelldusCore::charToWstring(value)); +} +*/ + +void Message::addArgument(const char *value) { + this->addArgument(TelldusCore::charToWstring(value)); +} + +bool Message::nextIsInt(const std::wstring &message) { + if (message.length() == 0) { + return false; + } + return (message.at(0) == 'i'); +} + +bool Message::nextIsString(const std::wstring &message) { + if (message.length() == 0) { + return false; + } + return (iswdigit(message.at(0)) != 0); +} + +std::wstring Message::takeString(std::wstring *message) { + + if (!Message::nextIsString(*message)) { + return L""; + } + size_t index = message->find(':'); + int length = wideToInteger(message->substr(0, index)); + std::wstring retval(message->substr(index+1, length)); + message->erase(0, index+length+1); + return retval; +} + +int Message::takeInt(std::wstring *message) { + if (!Message::nextIsInt(*message)) { + return 0; + } + size_t index = message->find('s'); + int value = wideToInteger(message->substr(1, index - 1)); + message->erase(0, index+1); + return value; +} diff --git a/telldus-core/common/Message.h b/telldus-core/common/Message.h index 4b13123b..50c06702 100644 --- a/telldus-core/common/Message.h +++ b/telldus-core/common/Message.h @@ -1,31 +1,31 @@ -#ifndef MESSAGE_H -#define MESSAGE_H - -#include - -namespace TelldusCore { - class Message : public std::wstring { - public: - Message(); - Message(const std::wstring &); - ~Message(void); - - void addArgument(const std::wstring &); - //void addSpecialArgument(const std::wstring &); - //void addSpecialArgument(int); - //void addSpecialArgument(const char *); - void addArgument(int); - void addArgument(const char *); - - static bool nextIsInt(const std::wstring &); - static bool nextIsString(const std::wstring &); - - static std::wstring takeString(std::wstring *); - static int takeInt(std::wstring *); - - private: - - }; -} - -#endif //MESSAGE_H +#ifndef MESSAGE_H +#define MESSAGE_H + +#include + +namespace TelldusCore { + class Message : public std::wstring { + public: + Message(); + Message(const std::wstring &); + ~Message(void); + + void addArgument(const std::wstring &); + //void addSpecialArgument(const std::wstring &); + //void addSpecialArgument(int); + //void addSpecialArgument(const char *); + void addArgument(int); + void addArgument(const char *); + + static bool nextIsInt(const std::wstring &); + static bool nextIsString(const std::wstring &); + + static std::wstring takeString(std::wstring *); + static int takeInt(std::wstring *); + + private: + + }; +} + +#endif //MESSAGE_H diff --git a/telldus-core/common/Socket.h b/telldus-core/common/Socket.h index 194a2d6c..a7ef6435 100644 --- a/telldus-core/common/Socket.h +++ b/telldus-core/common/Socket.h @@ -1,33 +1,33 @@ -#ifndef SOCKET_H -#define SOCKET_H - -#include - -#ifdef _WINDOWS - #include - typedef HANDLE SOCKET_T; -#else - typedef int SOCKET_T; -#endif - -namespace TelldusCore { - class Socket - { - public: - Socket(); - Socket(SOCKET_T hPipe); - virtual ~Socket(void); - - void connect(const std::wstring &server); - bool isConnected(); - std::wstring read(); - std::wstring read(int timeout); - void stopReadWait(); - void write(const std::wstring &msg); - - private: - class PrivateData; - PrivateData *d; - }; -} -#endif //SOCKET_H +#ifndef SOCKET_H +#define SOCKET_H + +#include + +#ifdef _WINDOWS + #include + typedef HANDLE SOCKET_T; +#else + typedef int SOCKET_T; +#endif + +namespace TelldusCore { + class Socket + { + public: + Socket(); + Socket(SOCKET_T hPipe); + virtual ~Socket(void); + + void connect(const std::wstring &server); + bool isConnected(); + std::wstring read(); + std::wstring read(int timeout); + void stopReadWait(); + void write(const std::wstring &msg); + + private: + class PrivateData; + PrivateData *d; + }; +} +#endif //SOCKET_H diff --git a/telldus-core/common/Socket_unix.cpp b/telldus-core/common/Socket_unix.cpp index 0a2a2639..23512a60 100644 --- a/telldus-core/common/Socket_unix.cpp +++ b/telldus-core/common/Socket_unix.cpp @@ -1,127 +1,127 @@ -#include "Socket.h" - -#include "Mutex.h" -#include "Strings.h" - -#include -#include -#include -#include - -#define BUFSIZE 512 - -using namespace TelldusCore; - -int connectWrapper(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - return connect(sockfd, addr, addrlen); -} - -class Socket::PrivateData { -public: - SOCKET_T socket; - bool connected; - fd_set infds; - Mutex mutex; -}; - -Socket::Socket() { - d = new PrivateData; - d->socket = 0; - d->connected = false; - FD_ZERO(&d->infds); -} - -Socket::Socket(SOCKET_T socket) -{ - d = new PrivateData; - d->socket = socket; - FD_ZERO(&d->infds); - d->connected = true; -} - -Socket::~Socket(void) { - if(d->socket){ - close(d->socket); - } - delete d; -} - -void Socket::connect(const std::wstring &server) { - struct sockaddr_un remote; - socklen_t len; - - if ((d->socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - return; - } - std::string name = "/tmp/" + std::string(server.begin(), server.end()); - remote.sun_family = AF_UNIX; - strcpy(remote.sun_path, name.c_str()); - - len = SUN_LEN(&remote); - if (connectWrapper(d->socket, (struct sockaddr *)&remote, len) == -1) { - return; - } - - TelldusCore::MutexLocker locker(&d->mutex); - d->connected = true; -} - -bool Socket::isConnected(){ - TelldusCore::MutexLocker locker(&d->mutex); - return d->connected; -} - -std::wstring Socket::read() { - return this->read(0); -} - -std::wstring Socket::read(int timeout) { - struct timeval tv; - char inbuf[BUFSIZE]; - - FD_SET(d->socket, &d->infds); - std::string msg; - while(isConnected()) { - tv.tv_sec = floor(timeout / 1000.0); - tv.tv_usec = timeout % 1000; - - int response = select(d->socket+1, &d->infds, NULL, NULL, &tv); - if (response == 0 && timeout > 0) { - return L""; - } else if (response <= 0) { - FD_SET(d->socket, &d->infds); - continue; - } - - int received = BUFSIZE; - while(received >= (BUFSIZE - 1)){ - memset(inbuf, '\0', sizeof(inbuf)); - received = recv(d->socket, inbuf, BUFSIZE - 1, 0); - if(received > 0){ - msg.append(std::string(inbuf)); - } - } - if (received < 0) { - TelldusCore::MutexLocker locker(&d->mutex); - d->connected = false; - } - break; - } - - return TelldusCore::charToWstring(msg.c_str()); -} - -void Socket::stopReadWait(){ - TelldusCore::MutexLocker locker(&d->mutex); - d->connected = false; - //TODO somehow signal the socket here? -} - -void Socket::write(const std::wstring &msg) { - std::string newMsg(TelldusCore::wideToString(msg)); - int sent = send(d->socket, newMsg.c_str(), newMsg.length(), 0); - if (sent < 0) { - TelldusCore::MutexLocker locker(&d->mutex); - d->connected = false; - } -} +#include "Socket.h" + +#include "Mutex.h" +#include "Strings.h" + +#include +#include +#include +#include + +#define BUFSIZE 512 + +using namespace TelldusCore; + +int connectWrapper(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + return connect(sockfd, addr, addrlen); +} + +class Socket::PrivateData { +public: + SOCKET_T socket; + bool connected; + fd_set infds; + Mutex mutex; +}; + +Socket::Socket() { + d = new PrivateData; + d->socket = 0; + d->connected = false; + FD_ZERO(&d->infds); +} + +Socket::Socket(SOCKET_T socket) +{ + d = new PrivateData; + d->socket = socket; + FD_ZERO(&d->infds); + d->connected = true; +} + +Socket::~Socket(void) { + if(d->socket){ + close(d->socket); + } + delete d; +} + +void Socket::connect(const std::wstring &server) { + struct sockaddr_un remote; + socklen_t len; + + if ((d->socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + return; + } + std::string name = "/tmp/" + std::string(server.begin(), server.end()); + remote.sun_family = AF_UNIX; + strcpy(remote.sun_path, name.c_str()); + + len = SUN_LEN(&remote); + if (connectWrapper(d->socket, (struct sockaddr *)&remote, len) == -1) { + return; + } + + TelldusCore::MutexLocker locker(&d->mutex); + d->connected = true; +} + +bool Socket::isConnected(){ + TelldusCore::MutexLocker locker(&d->mutex); + return d->connected; +} + +std::wstring Socket::read() { + return this->read(0); +} + +std::wstring Socket::read(int timeout) { + struct timeval tv; + char inbuf[BUFSIZE]; + + FD_SET(d->socket, &d->infds); + std::string msg; + while(isConnected()) { + tv.tv_sec = floor(timeout / 1000.0); + tv.tv_usec = timeout % 1000; + + int response = select(d->socket+1, &d->infds, NULL, NULL, &tv); + if (response == 0 && timeout > 0) { + return L""; + } else if (response <= 0) { + FD_SET(d->socket, &d->infds); + continue; + } + + int received = BUFSIZE; + while(received >= (BUFSIZE - 1)){ + memset(inbuf, '\0', sizeof(inbuf)); + received = recv(d->socket, inbuf, BUFSIZE - 1, 0); + if(received > 0){ + msg.append(std::string(inbuf)); + } + } + if (received < 0) { + TelldusCore::MutexLocker locker(&d->mutex); + d->connected = false; + } + break; + } + + return TelldusCore::charToWstring(msg.c_str()); +} + +void Socket::stopReadWait(){ + TelldusCore::MutexLocker locker(&d->mutex); + d->connected = false; + //TODO somehow signal the socket here? +} + +void Socket::write(const std::wstring &msg) { + std::string newMsg(TelldusCore::wideToString(msg)); + int sent = send(d->socket, newMsg.c_str(), newMsg.length(), 0); + if (sent < 0) { + TelldusCore::MutexLocker locker(&d->mutex); + d->connected = false; + } +} diff --git a/telldus-core/common/Socket_win.cpp b/telldus-core/common/Socket_win.cpp index f71c84f7..87b6b37a 100644 --- a/telldus-core/common/Socket_win.cpp +++ b/telldus-core/common/Socket_win.cpp @@ -1,180 +1,180 @@ -#include "Socket.h" - -#include -#include -#include - -#define BUFSIZE 512 - -using namespace TelldusCore; - -class Socket::PrivateData { -public: - HANDLE hPipe; - HANDLE readEvent; - bool connected; - bool running; -}; - -Socket::Socket() { - d = new PrivateData; - d->hPipe = INVALID_HANDLE_VALUE; - d->connected = false; - d->running = true; -} - -Socket::Socket(SOCKET_T hPipe) -{ - d = new PrivateData; - d->hPipe = hPipe; - d->connected = true; - d->running = true; -} - - -Socket::~Socket(void){ - d->running = false; - SetEvent(d->readEvent); //signal for break - if (d->hPipe != INVALID_HANDLE_VALUE) { - CloseHandle(d->hPipe); - d->hPipe = 0; - } - delete d; -} - -void Socket::connect(const std::wstring &server){ - BOOL fSuccess = false; - - std::wstring name(L"\\\\.\\pipe\\" + server); - d->hPipe = CreateFile( - (const wchar_t *)name.c_str(), // pipe name - GENERIC_READ | // read and write access - GENERIC_WRITE, - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - FILE_FLAG_OVERLAPPED, // default attributes - NULL); // no template file - - if (d->hPipe == INVALID_HANDLE_VALUE) { - return; - } - - DWORD dwMode = PIPE_READMODE_MESSAGE; - fSuccess = SetNamedPipeHandleState( - d->hPipe, // pipe handle - &dwMode, // new pipe mode - NULL, // don't set maximum bytes - NULL); // don't set maximum time - - if (!fSuccess) { - return; - } - d->connected = true; -} - -void Socket::stopReadWait(){ - d->running = false; - SetEvent(d->readEvent); -} - -std::wstring Socket::read() { - return read(INFINITE); -} - -std::wstring Socket::read(int timeout){ - wchar_t buf[BUFSIZE]; - int result; - DWORD cbBytesRead = 0; - OVERLAPPED oOverlap; - - memset(&oOverlap, 0, sizeof(OVERLAPPED)); - - d->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - oOverlap.hEvent = d->readEvent; - BOOL fSuccess = false; - std::wstring returnString; - bool moreData = true; - - while(moreData){ - moreData = false; - memset(&buf, 0, sizeof(buf)); - - ReadFile( d->hPipe, &buf, sizeof(buf)-sizeof(wchar_t), &cbBytesRead, &oOverlap); - - result = WaitForSingleObject(oOverlap.hEvent, timeout); - - if(!d->running){ - CancelIo(d->hPipe); - WaitForSingleObject(oOverlap.hEvent, INFINITE); - d->readEvent = 0; - CloseHandle(oOverlap.hEvent); - return L""; - } - - if (result == WAIT_TIMEOUT) { - CancelIo(d->hPipe); - // Cancel, we still need to cleanup - } - fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, true); - - if (!fSuccess) { - DWORD err = GetLastError(); - - if(err == ERROR_MORE_DATA){ - moreData = true; - } - else{ - buf[0] = 0; - } - if (err == ERROR_BROKEN_PIPE) { - d->connected = false; - } - } - returnString.append(buf); - } - d->readEvent = 0; - CloseHandle(oOverlap.hEvent); - return returnString; -} - -void Socket::write(const std::wstring &msg){ - - OVERLAPPED oOverlap; - DWORD bytesWritten = 0; - int result; - BOOL fSuccess = false; - - memset(&oOverlap, 0, sizeof(OVERLAPPED)); - - HANDLE writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - oOverlap.hEvent = writeEvent; - - BOOL writeSuccess = WriteFile(d->hPipe, msg.data(), (DWORD)msg.length()*sizeof(wchar_t), &bytesWritten, &oOverlap); - result = GetLastError(); - if (writeSuccess || result == ERROR_IO_PENDING) { - result = WaitForSingleObject(writeEvent, 500); - if (result == WAIT_TIMEOUT) { - CancelIo(d->hPipe); - WaitForSingleObject(oOverlap.hEvent, INFINITE); - CloseHandle(writeEvent); - CloseHandle(d->hPipe); - d->hPipe = 0; - d->connected = false; - return; - } - fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE); - } - - CloseHandle(writeEvent); - if (!fSuccess) { - CloseHandle(d->hPipe); - d->hPipe = 0; - d->connected = false; - return; - } -} - -bool Socket::isConnected(){ - return d->connected; +#include "Socket.h" + +#include +#include +#include + +#define BUFSIZE 512 + +using namespace TelldusCore; + +class Socket::PrivateData { +public: + HANDLE hPipe; + HANDLE readEvent; + bool connected; + bool running; +}; + +Socket::Socket() { + d = new PrivateData; + d->hPipe = INVALID_HANDLE_VALUE; + d->connected = false; + d->running = true; +} + +Socket::Socket(SOCKET_T hPipe) +{ + d = new PrivateData; + d->hPipe = hPipe; + d->connected = true; + d->running = true; +} + + +Socket::~Socket(void){ + d->running = false; + SetEvent(d->readEvent); //signal for break + if (d->hPipe != INVALID_HANDLE_VALUE) { + CloseHandle(d->hPipe); + d->hPipe = 0; + } + delete d; +} + +void Socket::connect(const std::wstring &server){ + BOOL fSuccess = false; + + std::wstring name(L"\\\\.\\pipe\\" + server); + d->hPipe = CreateFile( + (const wchar_t *)name.c_str(), // pipe name + GENERIC_READ | // read and write access + GENERIC_WRITE, + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // opens existing pipe + FILE_FLAG_OVERLAPPED, // default attributes + NULL); // no template file + + if (d->hPipe == INVALID_HANDLE_VALUE) { + return; + } + + DWORD dwMode = PIPE_READMODE_MESSAGE; + fSuccess = SetNamedPipeHandleState( + d->hPipe, // pipe handle + &dwMode, // new pipe mode + NULL, // don't set maximum bytes + NULL); // don't set maximum time + + if (!fSuccess) { + return; + } + d->connected = true; +} + +void Socket::stopReadWait(){ + d->running = false; + SetEvent(d->readEvent); +} + +std::wstring Socket::read() { + return read(INFINITE); +} + +std::wstring Socket::read(int timeout){ + wchar_t buf[BUFSIZE]; + int result; + DWORD cbBytesRead = 0; + OVERLAPPED oOverlap; + + memset(&oOverlap, 0, sizeof(OVERLAPPED)); + + d->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + oOverlap.hEvent = d->readEvent; + BOOL fSuccess = false; + std::wstring returnString; + bool moreData = true; + + while(moreData){ + moreData = false; + memset(&buf, 0, sizeof(buf)); + + ReadFile( d->hPipe, &buf, sizeof(buf)-sizeof(wchar_t), &cbBytesRead, &oOverlap); + + result = WaitForSingleObject(oOverlap.hEvent, timeout); + + if(!d->running){ + CancelIo(d->hPipe); + WaitForSingleObject(oOverlap.hEvent, INFINITE); + d->readEvent = 0; + CloseHandle(oOverlap.hEvent); + return L""; + } + + if (result == WAIT_TIMEOUT) { + CancelIo(d->hPipe); + // Cancel, we still need to cleanup + } + fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, true); + + if (!fSuccess) { + DWORD err = GetLastError(); + + if(err == ERROR_MORE_DATA){ + moreData = true; + } + else{ + buf[0] = 0; + } + if (err == ERROR_BROKEN_PIPE) { + d->connected = false; + } + } + returnString.append(buf); + } + d->readEvent = 0; + CloseHandle(oOverlap.hEvent); + return returnString; +} + +void Socket::write(const std::wstring &msg){ + + OVERLAPPED oOverlap; + DWORD bytesWritten = 0; + int result; + BOOL fSuccess = false; + + memset(&oOverlap, 0, sizeof(OVERLAPPED)); + + HANDLE writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + oOverlap.hEvent = writeEvent; + + BOOL writeSuccess = WriteFile(d->hPipe, msg.data(), (DWORD)msg.length()*sizeof(wchar_t), &bytesWritten, &oOverlap); + result = GetLastError(); + if (writeSuccess || result == ERROR_IO_PENDING) { + result = WaitForSingleObject(writeEvent, 500); + if (result == WAIT_TIMEOUT) { + CancelIo(d->hPipe); + WaitForSingleObject(oOverlap.hEvent, INFINITE); + CloseHandle(writeEvent); + CloseHandle(d->hPipe); + d->hPipe = 0; + d->connected = false; + return; + } + fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE); + } + + CloseHandle(writeEvent); + if (!fSuccess) { + CloseHandle(d->hPipe); + d->hPipe = 0; + d->connected = false; + return; + } +} + +bool Socket::isConnected(){ + return d->connected; } \ No newline at end of file diff --git a/telldus-core/common/Strings.cpp b/telldus-core/common/Strings.cpp index b4d02376..5bee53a9 100644 --- a/telldus-core/common/Strings.cpp +++ b/telldus-core/common/Strings.cpp @@ -1,257 +1,257 @@ -#include "Strings.h" - -#include -#include -#include -#include -#include - -#ifdef _WINDOWS -#include -#else -#include -#endif - -#ifdef _MACOSX -#define WCHAR_T_ENCODING "UCS-4-INTERNAL" -#else -#define WCHAR_T_ENCODING "WCHAR_T" -#endif - -std::wstring TelldusCore::charToWstring(const char *value) { -#ifdef _WINDOWS - //Determine size - int size = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0); - if (size == 0) { - return L""; - } - wchar_t *buffer; - buffer = new wchar_t[size]; - memset(buffer, 0, sizeof(wchar_t)*(size)); - - int bytes = MultiByteToWideChar(CP_UTF8, 0, value, -1, buffer, size); - std::wstring retval(buffer); - delete[] buffer; - return retval; - -#else - size_t utf8Length = strlen(value); - size_t outbytesLeft = utf8Length*sizeof(wchar_t); - - //Copy the instring - char *inString = new char[strlen(value)+1]; - strcpy(inString, value); - - //Create buffer for output - char *outString = (char*)new wchar_t[utf8Length+1]; - memset(outString, 0, sizeof(wchar_t)*(utf8Length+1)); - -#ifdef _FREEBSD - const char *inPointer = inString; -#else - char *inPointer = inString; -#endif - char *outPointer = outString; - - iconv_t convDesc = iconv_open(WCHAR_T_ENCODING, "UTF-8"); - iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft); - iconv_close(convDesc); - - std::wstring retval( (wchar_t *)outString ); - - //Cleanup - delete[] inString; - delete[] outString; - - return retval; -#endif -} - -int TelldusCore::charToInteger(const char *input){ - std::stringstream inputstream; - inputstream << input; - int retval; - inputstream >> retval; - return retval; -} - -std::wstring TelldusCore::charUnsignedToWstring(const unsigned char value) { - std::wstringstream st; - st << value; - return st.str(); -} - -/** -* This method doesn't support all locales -*/ -bool TelldusCore::comparei(std::wstring stringA, std::wstring stringB) { - transform(stringA.begin(), stringA.end(), stringA.begin(), toupper); - transform(stringB.begin(), stringB.end(), stringB.begin(), toupper); - - return stringA == stringB; -} - -std::wstring TelldusCore::intToWstring(int value) { -#ifdef _WINDOWS - //no stream used -//TODO! Make effective and safe... - wchar_t numstr[21]; // enough to hold all numbers up to 64-bits - _itow_s(value, numstr, sizeof(numstr), 10); - std::wstring newstring(numstr); - return newstring; - //return TelldusCore::charToWstring(stdstring.c_str()); - //std::wstring temp = TelldusCore::charToWstring(stdstring.c_str()); - //std::wstring temp(stdstring.length(), L' '); - //std::copy(stdstring.begin(), stdstring.end(), temp.begin()); - //return temp; -#else - std::wstringstream st; - st << value; - return st.str(); -#endif -} - -std::string TelldusCore::intToString(int value) { -//Not sure if this is neecssary (for ordinary stringstream that is) -#ifdef _WINDOWS - char numstr[21]; // enough to hold all numbers up to 64-bits - _itoa_s(value, numstr, sizeof(numstr), 10); - std::string stdstring(numstr); - return stdstring; -#else - std::stringstream st; - st << value; - return st.str(); -#endif -} - -/* -std::wstring TelldusCore::intToWStringSafe(int value){ - #ifdef _WINDOWS - //no stream used - //TODO! Make effective and safe... - char numstr[21]; // enough to hold all numbers up to 64-bits - itoa(value, numstr, 10); - std::string stdstring(numstr); - return TelldusCore::charToWstring(stdstring.c_str()); - //std::wstring temp = TelldusCore::charToWstring(stdstring.c_str()); - //std::wstring temp(stdstring.length(), L' '); - //std::copy(stdstring.begin(), stdstring.end(), temp.begin()); - //return temp; - #else - return TelldusCore::intToWString(value); - #endif -} -*/ - -uint64_t TelldusCore::hexTo64l(const std::string data){ -#ifdef _WINDOWS - return _strtoui64(data.c_str(), NULL, 16); -#elif defined(_MACOSX) - return strtoq(data.c_str(), NULL, 16); -#else - return strtoull(data.c_str(), NULL, 16); -#endif -} - -int TelldusCore::wideToInteger(const std::wstring &input){ - std::wstringstream inputstream; - inputstream << input; - int retval; - inputstream >> retval; - return retval; -} - -std::string TelldusCore::wideToString(const std::wstring &input) { -#ifdef _WINDOWS - //Determine size - int size = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL); - if (size == 0) { - return ""; - } - char *buffer; - buffer = new char[size]; - memset(buffer, 0, sizeof(char)*size); - - int bytes = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, buffer, size, NULL, NULL); - std::string retval(buffer); - delete[] buffer; - return retval; - -#else - size_t wideSize = sizeof(wchar_t)*input.length(); - size_t outbytesLeft = wideSize+sizeof(char); //We cannot know how many wide character there is yet - - //Copy the instring - char *inString = (char*)new wchar_t[input.length()+1]; - memcpy(inString, input.c_str(), wideSize+sizeof(wchar_t)); - - //Create buffer for output - char *outString = new char[outbytesLeft]; - memset(outString, 0, sizeof(char)*(outbytesLeft)); - -#ifdef _FREEBSD - const char *inPointer = inString; -#else - char *inPointer = inString; -#endif - char *outPointer = outString; - - iconv_t convDesc = iconv_open("UTF-8", WCHAR_T_ENCODING); - iconv(convDesc, &inPointer, &wideSize, &outPointer, &outbytesLeft); - iconv_close(convDesc); - - std::string retval(outString); - - //Cleanup - delete[] inString; - delete[] outString; - - return retval; -#endif -} - -std::string TelldusCore::formatf(const char *format, ...) { - va_list ap; - va_start(ap, format); - std::string retval = sformatf(format, ap); - va_end(ap); - return retval; -} - -std::string TelldusCore::sformatf(const char *format, va_list ap) { - //This code is based on code from the Linux man-pages project (man vsprintf) - int n; - int size = 100; /* Guess we need no more than 100 bytes. */ - char *p, *np; - - if ((p = (char*)malloc(size)) == NULL) { - return ""; - } - - while (1) { - /* Try to print in the allocated space. */ - n = vsnprintf(p, size, format, ap); - - /* If that worked, return the string. */ - if (n > -1 && n < size) { - std::string retval(p); - free(p); - return retval; - } - - /* Else try again with more space. */ - - if (n > -1) { /* glibc 2.1 */ - size = n+1; /* precisely what is needed */ - } else { /* glibc 2.0 */ - size *= 2; /* twice the old size */ - } - if ((np = (char *)realloc (p, size)) == NULL) { - free(p); - return ""; - } else { - p = np; - } - } -} +#include "Strings.h" + +#include +#include +#include +#include +#include + +#ifdef _WINDOWS +#include +#else +#include +#endif + +#ifdef _MACOSX +#define WCHAR_T_ENCODING "UCS-4-INTERNAL" +#else +#define WCHAR_T_ENCODING "WCHAR_T" +#endif + +std::wstring TelldusCore::charToWstring(const char *value) { +#ifdef _WINDOWS + //Determine size + int size = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0); + if (size == 0) { + return L""; + } + wchar_t *buffer; + buffer = new wchar_t[size]; + memset(buffer, 0, sizeof(wchar_t)*(size)); + + int bytes = MultiByteToWideChar(CP_UTF8, 0, value, -1, buffer, size); + std::wstring retval(buffer); + delete[] buffer; + return retval; + +#else + size_t utf8Length = strlen(value); + size_t outbytesLeft = utf8Length*sizeof(wchar_t); + + //Copy the instring + char *inString = new char[strlen(value)+1]; + strcpy(inString, value); + + //Create buffer for output + char *outString = (char*)new wchar_t[utf8Length+1]; + memset(outString, 0, sizeof(wchar_t)*(utf8Length+1)); + +#ifdef _FREEBSD + const char *inPointer = inString; +#else + char *inPointer = inString; +#endif + char *outPointer = outString; + + iconv_t convDesc = iconv_open(WCHAR_T_ENCODING, "UTF-8"); + iconv(convDesc, &inPointer, &utf8Length, &outPointer, &outbytesLeft); + iconv_close(convDesc); + + std::wstring retval( (wchar_t *)outString ); + + //Cleanup + delete[] inString; + delete[] outString; + + return retval; +#endif +} + +int TelldusCore::charToInteger(const char *input){ + std::stringstream inputstream; + inputstream << input; + int retval; + inputstream >> retval; + return retval; +} + +std::wstring TelldusCore::charUnsignedToWstring(const unsigned char value) { + std::wstringstream st; + st << value; + return st.str(); +} + +/** +* This method doesn't support all locales +*/ +bool TelldusCore::comparei(std::wstring stringA, std::wstring stringB) { + transform(stringA.begin(), stringA.end(), stringA.begin(), toupper); + transform(stringB.begin(), stringB.end(), stringB.begin(), toupper); + + return stringA == stringB; +} + +std::wstring TelldusCore::intToWstring(int value) { +#ifdef _WINDOWS + //no stream used +//TODO! Make effective and safe... + wchar_t numstr[21]; // enough to hold all numbers up to 64-bits + _itow_s(value, numstr, sizeof(numstr), 10); + std::wstring newstring(numstr); + return newstring; + //return TelldusCore::charToWstring(stdstring.c_str()); + //std::wstring temp = TelldusCore::charToWstring(stdstring.c_str()); + //std::wstring temp(stdstring.length(), L' '); + //std::copy(stdstring.begin(), stdstring.end(), temp.begin()); + //return temp; +#else + std::wstringstream st; + st << value; + return st.str(); +#endif +} + +std::string TelldusCore::intToString(int value) { +//Not sure if this is neecssary (for ordinary stringstream that is) +#ifdef _WINDOWS + char numstr[21]; // enough to hold all numbers up to 64-bits + _itoa_s(value, numstr, sizeof(numstr), 10); + std::string stdstring(numstr); + return stdstring; +#else + std::stringstream st; + st << value; + return st.str(); +#endif +} + +/* +std::wstring TelldusCore::intToWStringSafe(int value){ + #ifdef _WINDOWS + //no stream used + //TODO! Make effective and safe... + char numstr[21]; // enough to hold all numbers up to 64-bits + itoa(value, numstr, 10); + std::string stdstring(numstr); + return TelldusCore::charToWstring(stdstring.c_str()); + //std::wstring temp = TelldusCore::charToWstring(stdstring.c_str()); + //std::wstring temp(stdstring.length(), L' '); + //std::copy(stdstring.begin(), stdstring.end(), temp.begin()); + //return temp; + #else + return TelldusCore::intToWString(value); + #endif +} +*/ + +uint64_t TelldusCore::hexTo64l(const std::string data){ +#ifdef _WINDOWS + return _strtoui64(data.c_str(), NULL, 16); +#elif defined(_MACOSX) + return strtoq(data.c_str(), NULL, 16); +#else + return strtoull(data.c_str(), NULL, 16); +#endif +} + +int TelldusCore::wideToInteger(const std::wstring &input){ + std::wstringstream inputstream; + inputstream << input; + int retval; + inputstream >> retval; + return retval; +} + +std::string TelldusCore::wideToString(const std::wstring &input) { +#ifdef _WINDOWS + //Determine size + int size = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, NULL, 0, NULL, NULL); + if (size == 0) { + return ""; + } + char *buffer; + buffer = new char[size]; + memset(buffer, 0, sizeof(char)*size); + + int bytes = WideCharToMultiByte(CP_UTF8, 0, input.c_str(), -1, buffer, size, NULL, NULL); + std::string retval(buffer); + delete[] buffer; + return retval; + +#else + size_t wideSize = sizeof(wchar_t)*input.length(); + size_t outbytesLeft = wideSize+sizeof(char); //We cannot know how many wide character there is yet + + //Copy the instring + char *inString = (char*)new wchar_t[input.length()+1]; + memcpy(inString, input.c_str(), wideSize+sizeof(wchar_t)); + + //Create buffer for output + char *outString = new char[outbytesLeft]; + memset(outString, 0, sizeof(char)*(outbytesLeft)); + +#ifdef _FREEBSD + const char *inPointer = inString; +#else + char *inPointer = inString; +#endif + char *outPointer = outString; + + iconv_t convDesc = iconv_open("UTF-8", WCHAR_T_ENCODING); + iconv(convDesc, &inPointer, &wideSize, &outPointer, &outbytesLeft); + iconv_close(convDesc); + + std::string retval(outString); + + //Cleanup + delete[] inString; + delete[] outString; + + return retval; +#endif +} + +std::string TelldusCore::formatf(const char *format, ...) { + va_list ap; + va_start(ap, format); + std::string retval = sformatf(format, ap); + va_end(ap); + return retval; +} + +std::string TelldusCore::sformatf(const char *format, va_list ap) { + //This code is based on code from the Linux man-pages project (man vsprintf) + int n; + int size = 100; /* Guess we need no more than 100 bytes. */ + char *p, *np; + + if ((p = (char*)malloc(size)) == NULL) { + return ""; + } + + while (1) { + /* Try to print in the allocated space. */ + n = vsnprintf(p, size, format, ap); + + /* If that worked, return the string. */ + if (n > -1 && n < size) { + std::string retval(p); + free(p); + return retval; + } + + /* Else try again with more space. */ + + if (n > -1) { /* glibc 2.1 */ + size = n+1; /* precisely what is needed */ + } else { /* glibc 2.0 */ + size *= 2; /* twice the old size */ + } + if ((np = (char *)realloc (p, size)) == NULL) { + free(p); + return ""; + } else { + p = np; + } + } +} diff --git a/telldus-core/common/Strings.h b/telldus-core/common/Strings.h index 7c5f85ad..28e671c2 100644 --- a/telldus-core/common/Strings.h +++ b/telldus-core/common/Strings.h @@ -1,33 +1,33 @@ -#ifndef STRING_H -#define STRING_H - -#include -#include -#ifdef _MSC_VER -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; -#else -#include -#endif - -namespace TelldusCore { - std::wstring charToWstring(const char *value); - int charToInteger(const char *value); - std::wstring charUnsignedToWstring(const unsigned char value); - - bool comparei(std::wstring stringA, std::wstring stringB); - std::wstring intToWstring(int value); - //std::wstring intToWStringSafe(int value); - std::string intToString(int value); - uint64_t hexTo64l(const std::string data); - std::string wideToString(const std::wstring &input); - - int wideToInteger(const std::wstring &input); - - std::string formatf(const char *format, ...); - std::string sformatf(const char *format, va_list ap); -} - -#endif //STRING_H +#ifndef STRING_H +#define STRING_H + +#include +#include +#ifdef _MSC_VER +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +namespace TelldusCore { + std::wstring charToWstring(const char *value); + int charToInteger(const char *value); + std::wstring charUnsignedToWstring(const unsigned char value); + + bool comparei(std::wstring stringA, std::wstring stringB); + std::wstring intToWstring(int value); + //std::wstring intToWStringSafe(int value); + std::string intToString(int value); + uint64_t hexTo64l(const std::string data); + std::string wideToString(const std::wstring &input); + + int wideToInteger(const std::wstring &input); + + std::string formatf(const char *format, ...); + std::string sformatf(const char *format, va_list ap); +} + +#endif //STRING_H diff --git a/telldus-core/service/CMakeLists.txt b/telldus-core/service/CMakeLists.txt index b7d0fa3c..0545af4a 100644 --- a/telldus-core/service/CMakeLists.txt +++ b/telldus-core/service/CMakeLists.txt @@ -1,252 +1,252 @@ -IF(COMMAND cmake_policy) - CMAKE_POLICY(SET CMP0003 NEW) -ENDIF(COMMAND cmake_policy) - -FIND_PACKAGE( SignTool REQUIRED ) - -SET (telldusd_DESCRIPTION - "background service for Telldus TellStick, must be running to control TellStick" -) - -ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) - -######## Non configurable options ######## -SET( telldus-service_SRCS - ClientCommunicationHandler.cpp - Controller.cpp - ControllerManager.cpp - ControllerMessage.cpp - Device.cpp - DeviceManager.cpp - Log.cpp - Sensor.cpp - Settings.cpp - TelldusMain.cpp - TellStick.cpp - Timer.cpp - EventUpdateManager.cpp -) -SET( telldus-service_protocol_SRCS - Protocol.h - Protocol.cpp - ProtocolBrateck.h - ProtocolBrateck.cpp - ProtocolComen.h - ProtocolComen.cpp - ProtocolEverflourish.h - ProtocolEverflourish.cpp - ProtocolFineoffset.h - ProtocolFineoffset.cpp - ProtocolFuhaote.h - ProtocolFuhaote.cpp - ProtocolGroup.h - ProtocolGroup.cpp - ProtocolHasta.h - ProtocolHasta.cpp - ProtocolIkea.h - ProtocolIkea.cpp - ProtocolMandolyn.h - ProtocolMandolyn.cpp - ProtocolNexa.h - ProtocolNexa.cpp - ProtocolOregon.h - ProtocolOregon.cpp - ProtocolRisingSun.h - ProtocolRisingSun.cpp - ProtocolSartano.h - ProtocolSartano.cpp - ProtocolScene.h - ProtocolScene.cpp - ProtocolSilvanChip.h - ProtocolSilvanChip.cpp - ProtocolUpm.h - ProtocolUpm.cpp - ProtocolWaveman.h - ProtocolWaveman.cpp - ProtocolX10.h - ProtocolX10.cpp - ProtocolYidong.h - ProtocolYidong.cpp -) -SET( telldus-service_HDRS - ClientCommunicationHandler.h - ConnectionListener.h - Controller.h - ControllerListener.h - ControllerManager.h - ControllerMessage.h - Device.h - DeviceManager.h - EventUpdateManager.h - Log.h - Sensor.h - Settings.h - TelldusMain.h - TellStick.h - Timer.h -) -FIND_PACKAGE(Threads REQUIRED) -LIST(APPEND telldus-service_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../common -) - -######## Configurable options for the platform ######## - -######## Platforms-specific, non configurable ######## - -IF (APPLE) #### Mac OS X #### - SET(DEFAULT_FTDI_ENGINE "ftd2xx") - SET( telldus-service_TARGET TelldusService ) - ADD_DEFINITIONS( -D_MACOSX ) - FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation) - FIND_LIBRARY(IOKIT_LIBRARY IOKit) - - SET( telldus-service_LIBRARIES - ${telldus-service_LIBRARIES} - ${COREFOUNDATION_LIBRARY} - ${IOKIT_LIBRARY} - TelldusCommon - ) - LIST(APPEND telldus-service_SRCS - main_mac.cpp - ConnectionListener_unix.cpp - ControllerListener_mac.cpp - SettingsCoreFoundationPreferences.cpp - ) - -ELSEIF (WIN32) #### Windows #### - SET(DEFAULT_FTDI_ENGINE "ftd2xx") - SET( telldus-service_TARGET TelldusService ) - ADD_DEFINITIONS( -DUNICODE ) - ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No - SET(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE" - ) - LIST(APPEND telldus-service_LIBRARIES - TelldusCommon - ) - LIST(APPEND telldus-service_SRCS - ConnectionListener_win.cpp - main_win.cpp - SettingsWinRegistry.cpp - TelldusWinService_win.cpp - Messages.mc - ${CMAKE_CURRENT_BINARY_DIR}/Messages.rc - ${CMAKE_CURRENT_BINARY_DIR}/Messages.h - ) - LIST(APPEND telldus-service_HDRS - TelldusWinService_win.h - ) - ADD_CUSTOM_COMMAND( - OUTPUT Messages.rc Messages.h - COMMAND mc.exe -u -r \"${CMAKE_CURRENT_BINARY_DIR}\" -h \"${CMAKE_CURRENT_BINARY_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc\" - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc - DEPENDS Messages.rc - COMMENT "Compiling Messages Resource" - ) - INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ) - -ELSE (APPLE) #### Linux #### - SET(DEFAULT_FTDI_ENGINE "libftdi") - FIND_LIBRARY(CONFUSE_LIBRARY confuse) - ADD_DEFINITIONS( -D_CONFUSE ) - ADD_DEFINITIONS( -D_LINUX ) - - SET( telldus-service_TARGET telldusd ) - LIST(APPEND telldus-service_SRCS - ConnectionListener_unix.cpp - main_unix.cpp - SettingsConfuse.cpp - ) - LIST(APPEND telldus-service_LIBRARIES - ${CONFUSE_LIBRARY} - TelldusCommon - ) -ENDIF (APPLE) - -SET(FTDI_ENGINE ${DEFAULT_FTDI_ENGINE} CACHE STRING "Which FTDI engine to use. This could be either 'libftdi' or 'ftd2xx'") -IF (FTDI_ENGINE STREQUAL "ftd2xx") - FIND_LIBRARY(FTD2XX_LIBRARY ftd2xx) - ADD_DEFINITIONS( -DLIBFTD2XX ) - LIST(APPEND telldus-service_SRCS TellStick_ftd2xx.cpp ) - LIST(APPEND telldus-service_LIBRARIES ${FTD2XX_LIBRARY}) -ELSE (FTDI_ENGINE STREQUAL "ftd2xx") - FIND_LIBRARY(FTDI_LIBRARY ftdi) - INCLUDE(FindPkgConfig) - PKG_SEARCH_MODULE(FTDI libftdi) - INCLUDE_DIRECTORIES( ${FTDI_INCLUDEDIR} ) - ADD_DEFINITIONS( -DLIBFTDI ) - LIST(APPEND telldus-service_SRCS TellStick_libftdi.cpp ) - LIST(APPEND telldus-service_LIBRARIES ${FTDI_LIBRARY}) -ENDIF (FTDI_ENGINE STREQUAL "ftd2xx") - -######## Configuring ######## - -SOURCE_GROUP("Protocol Files" FILES ${telldus-service_protocol_SRCS}) - -ADD_EXECUTABLE(${telldus-service_TARGET} - ${telldus-service_SRCS} - ${telldus-service_protocol_SRCS} - ${telldus-service_HDRS} -) -ADD_DEPENDENCIES(${telldus-service_TARGET} TelldusCommon) -SET_SOURCE_FILES_PROPERTIES(${telldus-service_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - -TARGET_LINK_LIBRARIES( ${telldus-service_TARGET} ${telldus-service_LIBRARIES} ) - -SIGN(${telldus-service_TARGET}) - -SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist -) -IF (APPLE) - SET(TELLDUS_SERVICE_TARGET_PATH "/Library/Telldus" CACHE STRING "Path to install TelldusService") - SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} - ) - INSTALL(TARGETS ${telldus-service_TARGET} - RUNTIME DESTINATION ${TELLDUS_SERVICE_TARGET_PATH} - ) - INSTALL(CODE " - INCLUDE(GetPrerequisites) - GET_FILENAME_COMPONENT(DESTDIR \$ENV{DESTDIR} ABSOLUTE) - GET_PREREQUISITES(\"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\" prereqs 1 0 \"\$\" \"\$\") - FOREACH(pr \${prereqs}) - GET_FILENAME_COMPONENT(lib \${pr} NAME) - FILE(INSTALL \${pr} DESTINATION ${TELLDUS_SERVICE_TARGET_PATH}) - EXECUTE_PROCESS(COMMAND install_name_tool - -change \"\${pr}\" \"${TELLDUS_SERVICE_TARGET_PATH}/\${lib}\" \"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\" - ) - ENDFOREACH () - ") - INSTALL(FILES com.telldus.service.plist DESTINATION /Library/LaunchDaemons) -ENDIF (APPLE) - -IF (UNIX) - IF (GENERATE_MAN) - ADD_CUSTOM_COMMAND( - TARGET ${telldus-service_TARGET} - POST_BUILD - COMMAND help2man -n ${telldusd_DESCRIPTION} ./telldusd > telldusd.1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating man file telldusd.1" - ) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/telldusd.1 DESTINATION share/man/man1) - ENDIF (GENERATE_MAN) -ENDIF (UNIX) - -IF (UNIX AND NOT APPLE) - INSTALL(TARGETS ${telldus-service_TARGET} RUNTIME DESTINATION sbin) - SET(SYSCONF_INSTALL_DIR "/etc" CACHE PATH "The sysconfig install dir (default prefix/etc)" ) - SET(STATE_INSTALL_DIR "/var/state" CACHE PATH "The directory to store state information of the devices" ) - - INSTALL(FILES tellstick.conf - DESTINATION ${SYSCONF_INSTALL_DIR} - ) - INSTALL(FILES telldus-core.conf - DESTINATION ${STATE_INSTALL_DIR} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE WORLD_READ WORLD_WRITE - ) -ENDIF (UNIX AND NOT APPLE) +IF(COMMAND cmake_policy) + CMAKE_POLICY(SET CMP0003 NEW) +ENDIF(COMMAND cmake_policy) + +FIND_PACKAGE( SignTool REQUIRED ) + +SET (telldusd_DESCRIPTION + "background service for Telldus TellStick, must be running to control TellStick" +) + +ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) + +######## Non configurable options ######## +SET( telldus-service_SRCS + ClientCommunicationHandler.cpp + Controller.cpp + ControllerManager.cpp + ControllerMessage.cpp + Device.cpp + DeviceManager.cpp + Log.cpp + Sensor.cpp + Settings.cpp + TelldusMain.cpp + TellStick.cpp + Timer.cpp + EventUpdateManager.cpp +) +SET( telldus-service_protocol_SRCS + Protocol.h + Protocol.cpp + ProtocolBrateck.h + ProtocolBrateck.cpp + ProtocolComen.h + ProtocolComen.cpp + ProtocolEverflourish.h + ProtocolEverflourish.cpp + ProtocolFineoffset.h + ProtocolFineoffset.cpp + ProtocolFuhaote.h + ProtocolFuhaote.cpp + ProtocolGroup.h + ProtocolGroup.cpp + ProtocolHasta.h + ProtocolHasta.cpp + ProtocolIkea.h + ProtocolIkea.cpp + ProtocolMandolyn.h + ProtocolMandolyn.cpp + ProtocolNexa.h + ProtocolNexa.cpp + ProtocolOregon.h + ProtocolOregon.cpp + ProtocolRisingSun.h + ProtocolRisingSun.cpp + ProtocolSartano.h + ProtocolSartano.cpp + ProtocolScene.h + ProtocolScene.cpp + ProtocolSilvanChip.h + ProtocolSilvanChip.cpp + ProtocolUpm.h + ProtocolUpm.cpp + ProtocolWaveman.h + ProtocolWaveman.cpp + ProtocolX10.h + ProtocolX10.cpp + ProtocolYidong.h + ProtocolYidong.cpp +) +SET( telldus-service_HDRS + ClientCommunicationHandler.h + ConnectionListener.h + Controller.h + ControllerListener.h + ControllerManager.h + ControllerMessage.h + Device.h + DeviceManager.h + EventUpdateManager.h + Log.h + Sensor.h + Settings.h + TelldusMain.h + TellStick.h + Timer.h +) +FIND_PACKAGE(Threads REQUIRED) +LIST(APPEND telldus-service_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/../common +) + +######## Configurable options for the platform ######## + +######## Platforms-specific, non configurable ######## + +IF (APPLE) #### Mac OS X #### + SET(DEFAULT_FTDI_ENGINE "ftd2xx") + SET( telldus-service_TARGET TelldusService ) + ADD_DEFINITIONS( -D_MACOSX ) + FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation) + FIND_LIBRARY(IOKIT_LIBRARY IOKit) + + SET( telldus-service_LIBRARIES + ${telldus-service_LIBRARIES} + ${COREFOUNDATION_LIBRARY} + ${IOKIT_LIBRARY} + TelldusCommon + ) + LIST(APPEND telldus-service_SRCS + main_mac.cpp + ConnectionListener_unix.cpp + ControllerListener_mac.cpp + SettingsCoreFoundationPreferences.cpp + ) + +ELSEIF (WIN32) #### Windows #### + SET(DEFAULT_FTDI_ENGINE "ftd2xx") + SET( telldus-service_TARGET TelldusService ) + ADD_DEFINITIONS( -DUNICODE ) + ADD_DEFINITIONS( /Zc:wchar_t- ) # Treat wchar_t as Built-in Type' = No + SET(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE" + ) + LIST(APPEND telldus-service_LIBRARIES + TelldusCommon + ) + LIST(APPEND telldus-service_SRCS + ConnectionListener_win.cpp + main_win.cpp + SettingsWinRegistry.cpp + TelldusWinService_win.cpp + Messages.mc + ${CMAKE_CURRENT_BINARY_DIR}/Messages.rc + ${CMAKE_CURRENT_BINARY_DIR}/Messages.h + ) + LIST(APPEND telldus-service_HDRS + TelldusWinService_win.h + ) + ADD_CUSTOM_COMMAND( + OUTPUT Messages.rc Messages.h + COMMAND mc.exe -u -r \"${CMAKE_CURRENT_BINARY_DIR}\" -h \"${CMAKE_CURRENT_BINARY_DIR}\" \"${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc\" + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Messages.mc + DEPENDS Messages.rc + COMMENT "Compiling Messages Resource" + ) + INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ) + +ELSE (APPLE) #### Linux #### + SET(DEFAULT_FTDI_ENGINE "libftdi") + FIND_LIBRARY(CONFUSE_LIBRARY confuse) + ADD_DEFINITIONS( -D_CONFUSE ) + ADD_DEFINITIONS( -D_LINUX ) + + SET( telldus-service_TARGET telldusd ) + LIST(APPEND telldus-service_SRCS + ConnectionListener_unix.cpp + main_unix.cpp + SettingsConfuse.cpp + ) + LIST(APPEND telldus-service_LIBRARIES + ${CONFUSE_LIBRARY} + TelldusCommon + ) +ENDIF (APPLE) + +SET(FTDI_ENGINE ${DEFAULT_FTDI_ENGINE} CACHE STRING "Which FTDI engine to use. This could be either 'libftdi' or 'ftd2xx'") +IF (FTDI_ENGINE STREQUAL "ftd2xx") + FIND_LIBRARY(FTD2XX_LIBRARY ftd2xx) + ADD_DEFINITIONS( -DLIBFTD2XX ) + LIST(APPEND telldus-service_SRCS TellStick_ftd2xx.cpp ) + LIST(APPEND telldus-service_LIBRARIES ${FTD2XX_LIBRARY}) +ELSE (FTDI_ENGINE STREQUAL "ftd2xx") + FIND_LIBRARY(FTDI_LIBRARY ftdi) + INCLUDE(FindPkgConfig) + PKG_SEARCH_MODULE(FTDI libftdi) + INCLUDE_DIRECTORIES( ${FTDI_INCLUDEDIR} ) + ADD_DEFINITIONS( -DLIBFTDI ) + LIST(APPEND telldus-service_SRCS TellStick_libftdi.cpp ) + LIST(APPEND telldus-service_LIBRARIES ${FTDI_LIBRARY}) +ENDIF (FTDI_ENGINE STREQUAL "ftd2xx") + +######## Configuring ######## + +SOURCE_GROUP("Protocol Files" FILES ${telldus-service_protocol_SRCS}) + +ADD_EXECUTABLE(${telldus-service_TARGET} + ${telldus-service_SRCS} + ${telldus-service_protocol_SRCS} + ${telldus-service_HDRS} +) +ADD_DEPENDENCIES(${telldus-service_TARGET} TelldusCommon) +SET_SOURCE_FILES_PROPERTIES(${telldus-service_RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + +TARGET_LINK_LIBRARIES( ${telldus-service_TARGET} ${telldus-service_LIBRARIES} ) + +SIGN(${telldus-service_TARGET}) + +SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist +) +IF (APPLE) + SET(TELLDUS_SERVICE_TARGET_PATH "/Library/Telldus" CACHE STRING "Path to install TelldusService") + SET_TARGET_PROPERTIES(${telldus-service_TARGET} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} + ) + INSTALL(TARGETS ${telldus-service_TARGET} + RUNTIME DESTINATION ${TELLDUS_SERVICE_TARGET_PATH} + ) + INSTALL(CODE " + INCLUDE(GetPrerequisites) + GET_FILENAME_COMPONENT(DESTDIR \$ENV{DESTDIR} ABSOLUTE) + GET_PREREQUISITES(\"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\" prereqs 1 0 \"\$\" \"\$\") + FOREACH(pr \${prereqs}) + GET_FILENAME_COMPONENT(lib \${pr} NAME) + FILE(INSTALL \${pr} DESTINATION ${TELLDUS_SERVICE_TARGET_PATH}) + EXECUTE_PROCESS(COMMAND install_name_tool + -change \"\${pr}\" \"${TELLDUS_SERVICE_TARGET_PATH}/\${lib}\" \"\${DESTDIR}/${TELLDUS_SERVICE_TARGET_PATH}/${telldus-service_TARGET}\" + ) + ENDFOREACH () + ") + INSTALL(FILES com.telldus.service.plist DESTINATION /Library/LaunchDaemons) +ENDIF (APPLE) + +IF (UNIX) + IF (GENERATE_MAN) + ADD_CUSTOM_COMMAND( + TARGET ${telldus-service_TARGET} + POST_BUILD + COMMAND help2man -n ${telldusd_DESCRIPTION} ./telldusd > telldusd.1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating man file telldusd.1" + ) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/telldusd.1 DESTINATION share/man/man1) + ENDIF (GENERATE_MAN) +ENDIF (UNIX) + +IF (UNIX AND NOT APPLE) + INSTALL(TARGETS ${telldus-service_TARGET} RUNTIME DESTINATION sbin) + SET(SYSCONF_INSTALL_DIR "/etc" CACHE PATH "The sysconfig install dir (default prefix/etc)" ) + SET(STATE_INSTALL_DIR "/var/state" CACHE PATH "The directory to store state information of the devices" ) + + INSTALL(FILES tellstick.conf + DESTINATION ${SYSCONF_INSTALL_DIR} + ) + INSTALL(FILES telldus-core.conf + DESTINATION ${STATE_INSTALL_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ GROUP_WRITE WORLD_READ WORLD_WRITE + ) +ENDIF (UNIX AND NOT APPLE) diff --git a/telldus-core/service/ClientCommunicationHandler.cpp b/telldus-core/service/ClientCommunicationHandler.cpp index 21159209..c6de79d0 100644 --- a/telldus-core/service/ClientCommunicationHandler.cpp +++ b/telldus-core/service/ClientCommunicationHandler.cpp @@ -1,265 +1,265 @@ -#include "ClientCommunicationHandler.h" -#include "Message.h" -#include "Strings.h" - -#include - -class ClientCommunicationHandler::PrivateData { -public: - TelldusCore::Socket *clientSocket; - TelldusCore::EventRef event, deviceUpdateEvent; - bool done; - DeviceManager *deviceManager; - ControllerManager *controllerManager; -}; - -ClientCommunicationHandler::ClientCommunicationHandler(){ - -} - -ClientCommunicationHandler::ClientCommunicationHandler(TelldusCore::Socket *clientSocket, TelldusCore::EventRef event, DeviceManager *deviceManager, TelldusCore::EventRef deviceUpdateEvent, ControllerManager *controllerManager) - :Thread() -{ - d = new PrivateData; - d->clientSocket = clientSocket; - d->event = event; - d->done = false; - d->deviceManager = deviceManager; - d->deviceUpdateEvent = deviceUpdateEvent; - d->controllerManager = controllerManager; -} - -ClientCommunicationHandler::~ClientCommunicationHandler(void) -{ - wait(); - delete(d->clientSocket); - delete d; -} - -void ClientCommunicationHandler::run(){ - //run thread - - std::wstring clientMessage = d->clientSocket->read(2000); - - int intReturn; - std::wstring strReturn; - strReturn = L""; - parseMessage(clientMessage, &intReturn, &strReturn); - - TelldusCore::Message msg; - - if(strReturn == L""){ - msg.addArgument(intReturn); - } - else{ - msg.addArgument(strReturn); - } - msg.append(L"\n"); - d->clientSocket->write(msg); - - //We are done, signal for removal - d->done = true; - d->event->signal(); -} - -bool ClientCommunicationHandler::isDone(){ - return d->done; -} - - -void ClientCommunicationHandler::parseMessage(const std::wstring &clientMessage, int *intReturn, std::wstring *wstringReturn){ - - (*intReturn) = 0; - (*wstringReturn) = L""; - std::wstring msg(clientMessage); //Copy - std::wstring function(TelldusCore::Message::takeString(&msg)); - - if (function == L"tdTurnOn") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNON, 0); - - } else if (function == L"tdTurnOff") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNOFF, 0); - - } else if (function == L"tdBell") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_BELL, 0); - - } else if (function == L"tdDim") { - int deviceId = TelldusCore::Message::takeInt(&msg); - int level = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DIM, level); - - } else if (function == L"tdExecute") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_EXECUTE, 0); - - } else if (function == L"tdUp") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_UP, 0); - - } else if (function == L"tdDown") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DOWN, 0); - - } else if (function == L"tdStop") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_STOP, 0); - - } else if (function == L"tdLearn") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_LEARN, 0); - - } else if (function == L"tdLastSentCommand") { - int deviceId = TelldusCore::Message::takeInt(&msg); - int methodsSupported = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->getDeviceLastSentCommand(deviceId, methodsSupported); - - } else if (function == L"tdLastSentValue") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*wstringReturn) = d->deviceManager->getDeviceStateValue(deviceId); - - } else if(function == L"tdGetNumberOfDevices"){ - - (*intReturn) = d->deviceManager->getNumberOfDevices(); - - } else if (function == L"tdGetDeviceId") { - int deviceIndex = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->getDeviceId(deviceIndex); - - } else if (function == L"tdGetDeviceType") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->getDeviceType(deviceId); - - } else if (function == L"tdGetName") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*wstringReturn) = d->deviceManager->getDeviceName(deviceId); - - } else if (function == L"tdSetName") { - int deviceId = TelldusCore::Message::takeInt(&msg); - std::wstring name = TelldusCore::Message::takeString(&msg); - (*intReturn) = d->deviceManager->setDeviceName(deviceId, name); - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME); - - } else if (function == L"tdGetProtocol") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*wstringReturn) = d->deviceManager->getDeviceProtocol(deviceId); - - } else if (function == L"tdSetProtocol") { - int deviceId = TelldusCore::Message::takeInt(&msg); - std::wstring protocol = TelldusCore::Message::takeString(&msg); - int oldMethods = d->deviceManager->getDeviceMethods(deviceId); - (*intReturn) = d->deviceManager->setDeviceProtocol(deviceId, protocol); - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_PROTOCOL); - if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); - } - - } else if (function == L"tdGetModel") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*wstringReturn) = d->deviceManager->getDeviceModel(deviceId); - - } else if (function == L"tdSetModel") { - int deviceId = TelldusCore::Message::takeInt(&msg); - std::wstring model = TelldusCore::Message::takeString(&msg); - int oldMethods = d->deviceManager->getDeviceMethods(deviceId); - (*intReturn) = d->deviceManager->setDeviceModel(deviceId, model); - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_MODEL); - if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); - } - - } else if (function == L"tdGetDeviceParameter") { - int deviceId = TelldusCore::Message::takeInt(&msg); - std::wstring name = TelldusCore::Message::takeString(&msg); - std::wstring defaultValue = TelldusCore::Message::takeString(&msg); - (*wstringReturn) = d->deviceManager->getDeviceParameter(deviceId, name, defaultValue); - - } else if (function == L"tdSetDeviceParameter") { - int deviceId = TelldusCore::Message::takeInt(&msg); - std::wstring name = TelldusCore::Message::takeString(&msg); - std::wstring value = TelldusCore::Message::takeString(&msg); - int oldMethods = d->deviceManager->getDeviceMethods(deviceId); - (*intReturn) = d->deviceManager->setDeviceParameter(deviceId, name, value); - if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); - } - - } else if (function == L"tdAddDevice") { - (*intReturn) = d->deviceManager->addDevice(); - if((*intReturn) >= 0){ - sendDeviceSignal((*intReturn), TELLSTICK_DEVICE_ADDED, 0); - } - - } else if (function == L"tdRemoveDevice") { - int deviceId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->removeDevice(deviceId); - if((*intReturn) == TELLSTICK_SUCCESS){ - sendDeviceSignal(deviceId, TELLSTICK_DEVICE_REMOVED, 0); - } - - } else if (function == L"tdMethods") { - int deviceId = TelldusCore::Message::takeInt(&msg); - int intMethodsSupported = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->getDeviceMethods(deviceId, intMethodsSupported); - - } else if (function == L"tdSendRawCommand") { - std::wstring command = TelldusCore::Message::takeString(&msg); - int reserved = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->deviceManager->sendRawCommand(command, reserved); - - } else if (function == L"tdConnectTellStickController") { - int vid = TelldusCore::Message::takeInt(&msg); - int pid = TelldusCore::Message::takeInt(&msg); - std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg)); - d->deviceManager->connectTellStickController(vid, pid, serial); - - } else if (function == L"tdDisconnectTellStickController") { - int vid = TelldusCore::Message::takeInt(&msg); - int pid = TelldusCore::Message::takeInt(&msg); - std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg)); - d->deviceManager->disconnectTellStickController(vid, pid, serial); - - } else if (function == L"tdSensor") { - (*wstringReturn) = d->deviceManager->getSensors(); - - } else if (function == L"tdSensorValue") { - std::wstring protocol = TelldusCore::Message::takeString(&msg); - std::wstring model = TelldusCore::Message::takeString(&msg); - int id = TelldusCore::Message::takeInt(&msg); - int dataType = TelldusCore::Message::takeInt(&msg); - (*wstringReturn) = d->deviceManager->getSensorValue(protocol, model, id, dataType); - - } else if (function == L"tdController") { - (*wstringReturn) = d->controllerManager->getControllers(); - - } else if (function == L"tdControllerValue") { - int id = TelldusCore::Message::takeInt(&msg); - std::wstring name = TelldusCore::Message::takeString(&msg); - (*wstringReturn) = d->controllerManager->getControllerValue(id, name); - - } else if (function == L"tdSetControllerValue") { - int id = TelldusCore::Message::takeInt(&msg); - std::wstring name = TelldusCore::Message::takeString(&msg); - std::wstring value = TelldusCore::Message::takeString(&msg); - (*intReturn) = d->controllerManager->setControllerValue(id, name, value); - - } else if (function == L"tdRemoveController") { - int controllerId = TelldusCore::Message::takeInt(&msg); - (*intReturn) = d->controllerManager->removeController(controllerId); - - } else{ - (*intReturn) = TELLSTICK_ERROR_UNKNOWN; - } -} - -void ClientCommunicationHandler::sendDeviceSignal(int deviceId, int eventDeviceChanges, int eventChangeType){ - - EventUpdateData *eventData = new EventUpdateData(); - eventData->messageType = L"TDDeviceChangeEvent"; - eventData->deviceId = deviceId; - eventData->eventDeviceChanges = eventDeviceChanges; - eventData->eventChangeType = eventChangeType; - d->deviceUpdateEvent->signal(eventData); -} +#include "ClientCommunicationHandler.h" +#include "Message.h" +#include "Strings.h" + +#include + +class ClientCommunicationHandler::PrivateData { +public: + TelldusCore::Socket *clientSocket; + TelldusCore::EventRef event, deviceUpdateEvent; + bool done; + DeviceManager *deviceManager; + ControllerManager *controllerManager; +}; + +ClientCommunicationHandler::ClientCommunicationHandler(){ + +} + +ClientCommunicationHandler::ClientCommunicationHandler(TelldusCore::Socket *clientSocket, TelldusCore::EventRef event, DeviceManager *deviceManager, TelldusCore::EventRef deviceUpdateEvent, ControllerManager *controllerManager) + :Thread() +{ + d = new PrivateData; + d->clientSocket = clientSocket; + d->event = event; + d->done = false; + d->deviceManager = deviceManager; + d->deviceUpdateEvent = deviceUpdateEvent; + d->controllerManager = controllerManager; +} + +ClientCommunicationHandler::~ClientCommunicationHandler(void) +{ + wait(); + delete(d->clientSocket); + delete d; +} + +void ClientCommunicationHandler::run(){ + //run thread + + std::wstring clientMessage = d->clientSocket->read(2000); + + int intReturn; + std::wstring strReturn; + strReturn = L""; + parseMessage(clientMessage, &intReturn, &strReturn); + + TelldusCore::Message msg; + + if(strReturn == L""){ + msg.addArgument(intReturn); + } + else{ + msg.addArgument(strReturn); + } + msg.append(L"\n"); + d->clientSocket->write(msg); + + //We are done, signal for removal + d->done = true; + d->event->signal(); +} + +bool ClientCommunicationHandler::isDone(){ + return d->done; +} + + +void ClientCommunicationHandler::parseMessage(const std::wstring &clientMessage, int *intReturn, std::wstring *wstringReturn){ + + (*intReturn) = 0; + (*wstringReturn) = L""; + std::wstring msg(clientMessage); //Copy + std::wstring function(TelldusCore::Message::takeString(&msg)); + + if (function == L"tdTurnOn") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNON, 0); + + } else if (function == L"tdTurnOff") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNOFF, 0); + + } else if (function == L"tdBell") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_BELL, 0); + + } else if (function == L"tdDim") { + int deviceId = TelldusCore::Message::takeInt(&msg); + int level = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DIM, level); + + } else if (function == L"tdExecute") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_EXECUTE, 0); + + } else if (function == L"tdUp") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_UP, 0); + + } else if (function == L"tdDown") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_DOWN, 0); + + } else if (function == L"tdStop") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_STOP, 0); + + } else if (function == L"tdLearn") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_LEARN, 0); + + } else if (function == L"tdLastSentCommand") { + int deviceId = TelldusCore::Message::takeInt(&msg); + int methodsSupported = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->getDeviceLastSentCommand(deviceId, methodsSupported); + + } else if (function == L"tdLastSentValue") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*wstringReturn) = d->deviceManager->getDeviceStateValue(deviceId); + + } else if(function == L"tdGetNumberOfDevices"){ + + (*intReturn) = d->deviceManager->getNumberOfDevices(); + + } else if (function == L"tdGetDeviceId") { + int deviceIndex = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->getDeviceId(deviceIndex); + + } else if (function == L"tdGetDeviceType") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->getDeviceType(deviceId); + + } else if (function == L"tdGetName") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*wstringReturn) = d->deviceManager->getDeviceName(deviceId); + + } else if (function == L"tdSetName") { + int deviceId = TelldusCore::Message::takeInt(&msg); + std::wstring name = TelldusCore::Message::takeString(&msg); + (*intReturn) = d->deviceManager->setDeviceName(deviceId, name); + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME); + + } else if (function == L"tdGetProtocol") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*wstringReturn) = d->deviceManager->getDeviceProtocol(deviceId); + + } else if (function == L"tdSetProtocol") { + int deviceId = TelldusCore::Message::takeInt(&msg); + std::wstring protocol = TelldusCore::Message::takeString(&msg); + int oldMethods = d->deviceManager->getDeviceMethods(deviceId); + (*intReturn) = d->deviceManager->setDeviceProtocol(deviceId, protocol); + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_PROTOCOL); + if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); + } + + } else if (function == L"tdGetModel") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*wstringReturn) = d->deviceManager->getDeviceModel(deviceId); + + } else if (function == L"tdSetModel") { + int deviceId = TelldusCore::Message::takeInt(&msg); + std::wstring model = TelldusCore::Message::takeString(&msg); + int oldMethods = d->deviceManager->getDeviceMethods(deviceId); + (*intReturn) = d->deviceManager->setDeviceModel(deviceId, model); + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_MODEL); + if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); + } + + } else if (function == L"tdGetDeviceParameter") { + int deviceId = TelldusCore::Message::takeInt(&msg); + std::wstring name = TelldusCore::Message::takeString(&msg); + std::wstring defaultValue = TelldusCore::Message::takeString(&msg); + (*wstringReturn) = d->deviceManager->getDeviceParameter(deviceId, name, defaultValue); + + } else if (function == L"tdSetDeviceParameter") { + int deviceId = TelldusCore::Message::takeInt(&msg); + std::wstring name = TelldusCore::Message::takeString(&msg); + std::wstring value = TelldusCore::Message::takeString(&msg); + int oldMethods = d->deviceManager->getDeviceMethods(deviceId); + (*intReturn) = d->deviceManager->setDeviceParameter(deviceId, name, value); + if(oldMethods != d->deviceManager->getDeviceMethods(deviceId)){ + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_METHOD); + } + + } else if (function == L"tdAddDevice") { + (*intReturn) = d->deviceManager->addDevice(); + if((*intReturn) >= 0){ + sendDeviceSignal((*intReturn), TELLSTICK_DEVICE_ADDED, 0); + } + + } else if (function == L"tdRemoveDevice") { + int deviceId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->removeDevice(deviceId); + if((*intReturn) == TELLSTICK_SUCCESS){ + sendDeviceSignal(deviceId, TELLSTICK_DEVICE_REMOVED, 0); + } + + } else if (function == L"tdMethods") { + int deviceId = TelldusCore::Message::takeInt(&msg); + int intMethodsSupported = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->getDeviceMethods(deviceId, intMethodsSupported); + + } else if (function == L"tdSendRawCommand") { + std::wstring command = TelldusCore::Message::takeString(&msg); + int reserved = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->deviceManager->sendRawCommand(command, reserved); + + } else if (function == L"tdConnectTellStickController") { + int vid = TelldusCore::Message::takeInt(&msg); + int pid = TelldusCore::Message::takeInt(&msg); + std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg)); + d->deviceManager->connectTellStickController(vid, pid, serial); + + } else if (function == L"tdDisconnectTellStickController") { + int vid = TelldusCore::Message::takeInt(&msg); + int pid = TelldusCore::Message::takeInt(&msg); + std::string serial = TelldusCore::wideToString(TelldusCore::Message::takeString(&msg)); + d->deviceManager->disconnectTellStickController(vid, pid, serial); + + } else if (function == L"tdSensor") { + (*wstringReturn) = d->deviceManager->getSensors(); + + } else if (function == L"tdSensorValue") { + std::wstring protocol = TelldusCore::Message::takeString(&msg); + std::wstring model = TelldusCore::Message::takeString(&msg); + int id = TelldusCore::Message::takeInt(&msg); + int dataType = TelldusCore::Message::takeInt(&msg); + (*wstringReturn) = d->deviceManager->getSensorValue(protocol, model, id, dataType); + + } else if (function == L"tdController") { + (*wstringReturn) = d->controllerManager->getControllers(); + + } else if (function == L"tdControllerValue") { + int id = TelldusCore::Message::takeInt(&msg); + std::wstring name = TelldusCore::Message::takeString(&msg); + (*wstringReturn) = d->controllerManager->getControllerValue(id, name); + + } else if (function == L"tdSetControllerValue") { + int id = TelldusCore::Message::takeInt(&msg); + std::wstring name = TelldusCore::Message::takeString(&msg); + std::wstring value = TelldusCore::Message::takeString(&msg); + (*intReturn) = d->controllerManager->setControllerValue(id, name, value); + + } else if (function == L"tdRemoveController") { + int controllerId = TelldusCore::Message::takeInt(&msg); + (*intReturn) = d->controllerManager->removeController(controllerId); + + } else{ + (*intReturn) = TELLSTICK_ERROR_UNKNOWN; + } +} + +void ClientCommunicationHandler::sendDeviceSignal(int deviceId, int eventDeviceChanges, int eventChangeType){ + + EventUpdateData *eventData = new EventUpdateData(); + eventData->messageType = L"TDDeviceChangeEvent"; + eventData->deviceId = deviceId; + eventData->eventDeviceChanges = eventDeviceChanges; + eventData->eventChangeType = eventChangeType; + d->deviceUpdateEvent->signal(eventData); +} diff --git a/telldus-core/service/ConnectionListener.h b/telldus-core/service/ConnectionListener.h index 365fd393..fe84f093 100644 --- a/telldus-core/service/ConnectionListener.h +++ b/telldus-core/service/ConnectionListener.h @@ -1,31 +1,31 @@ -#ifndef CONNECTIONLISTENER_H -#define CONNECTIONLISTENER_H - -#include -#include "Thread.h" -#include "Event.h" - -class Event; -namespace TelldusCore { - class Socket; -}; - -class ConnectionListenerEventData : public TelldusCore::EventDataBase { -public: - TelldusCore::Socket *socket; -}; - -class ConnectionListener : public TelldusCore::Thread { -public: - ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent); - virtual ~ConnectionListener(void); - -protected: - void run(); - -private: - class PrivateData; - PrivateData *d; -}; - -#endif //CONNECTIONLISTENER_H +#ifndef CONNECTIONLISTENER_H +#define CONNECTIONLISTENER_H + +#include +#include "Thread.h" +#include "Event.h" + +class Event; +namespace TelldusCore { + class Socket; +}; + +class ConnectionListenerEventData : public TelldusCore::EventDataBase { +public: + TelldusCore::Socket *socket; +}; + +class ConnectionListener : public TelldusCore::Thread { +public: + ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent); + virtual ~ConnectionListener(void); + +protected: + void run(); + +private: + class PrivateData; + PrivateData *d; +}; + +#endif //CONNECTIONLISTENER_H diff --git a/telldus-core/service/ConnectionListener_unix.cpp b/telldus-core/service/ConnectionListener_unix.cpp index 4c6c6ab6..b1fbe2a4 100644 --- a/telldus-core/service/ConnectionListener_unix.cpp +++ b/telldus-core/service/ConnectionListener_unix.cpp @@ -1,91 +1,91 @@ -#include "ConnectionListener.h" -#include "Socket.h" - -#include -#include -#include -#include -#include - - -#include -#include -#include - -class ConnectionListener::PrivateData { -public: - TelldusCore::EventRef waitEvent; - std::string name; - bool running; -}; - -ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) -{ - d = new PrivateData; - d->waitEvent = waitEvent; - - d->name = "/tmp/" + std::string(name.begin(), name.end()); - d->running = true; - - this->start(); -} - -ConnectionListener::~ConnectionListener(void) { - d->running = false; - this->wait(); - unlink(d->name.c_str()); - delete d; -} - -void ConnectionListener::run(){ - struct timeval tv = { 0, 0 }; - - //Timeout for select - - SOCKET_T serverSocket; - struct sockaddr_un name; - socklen_t len; - serverSocket = socket(PF_LOCAL, SOCK_STREAM, 0); - if (serverSocket < 0) { - return; - } - name.sun_family = AF_LOCAL; - memset(name.sun_path, '\0', sizeof(name.sun_path)); - strncpy(name.sun_path, d->name.c_str(), sizeof(name.sun_path)); - unlink(name.sun_path); - int size = SUN_LEN(&name); - bind(serverSocket, (struct sockaddr *)&name, size); - listen(serverSocket, 5); - - //Change permissions to allow everyone - chmod(d->name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); - len = sizeof(struct sockaddr_un); - - fd_set infds; - FD_ZERO(&infds); - FD_SET(serverSocket, &infds); - - while(d->running) { - tv.tv_sec = 5; - - int response = select(serverSocket+1, &infds, NULL, NULL, &tv); - if (response == 0) { - FD_SET(serverSocket, &infds); - continue; - } else if (response < 0 ) { - continue; - } - //Make sure it is a new connection - if (!FD_ISSET(serverSocket, &infds)) { - continue; - } - SOCKET_T clientSocket = accept(serverSocket, NULL, NULL); - - ConnectionListenerEventData *data = new ConnectionListenerEventData(); - data->socket = new TelldusCore::Socket(clientSocket); - d->waitEvent->signal(data); - - } - close(serverSocket); -} - +#include "ConnectionListener.h" +#include "Socket.h" + +#include +#include +#include +#include +#include + + +#include +#include +#include + +class ConnectionListener::PrivateData { +public: + TelldusCore::EventRef waitEvent; + std::string name; + bool running; +}; + +ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) +{ + d = new PrivateData; + d->waitEvent = waitEvent; + + d->name = "/tmp/" + std::string(name.begin(), name.end()); + d->running = true; + + this->start(); +} + +ConnectionListener::~ConnectionListener(void) { + d->running = false; + this->wait(); + unlink(d->name.c_str()); + delete d; +} + +void ConnectionListener::run(){ + struct timeval tv = { 0, 0 }; + + //Timeout for select + + SOCKET_T serverSocket; + struct sockaddr_un name; + socklen_t len; + serverSocket = socket(PF_LOCAL, SOCK_STREAM, 0); + if (serverSocket < 0) { + return; + } + name.sun_family = AF_LOCAL; + memset(name.sun_path, '\0', sizeof(name.sun_path)); + strncpy(name.sun_path, d->name.c_str(), sizeof(name.sun_path)); + unlink(name.sun_path); + int size = SUN_LEN(&name); + bind(serverSocket, (struct sockaddr *)&name, size); + listen(serverSocket, 5); + + //Change permissions to allow everyone + chmod(d->name.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + len = sizeof(struct sockaddr_un); + + fd_set infds; + FD_ZERO(&infds); + FD_SET(serverSocket, &infds); + + while(d->running) { + tv.tv_sec = 5; + + int response = select(serverSocket+1, &infds, NULL, NULL, &tv); + if (response == 0) { + FD_SET(serverSocket, &infds); + continue; + } else if (response < 0 ) { + continue; + } + //Make sure it is a new connection + if (!FD_ISSET(serverSocket, &infds)) { + continue; + } + SOCKET_T clientSocket = accept(serverSocket, NULL, NULL); + + ConnectionListenerEventData *data = new ConnectionListenerEventData(); + data->socket = new TelldusCore::Socket(clientSocket); + d->waitEvent->signal(data); + + } + close(serverSocket); +} + diff --git a/telldus-core/service/ConnectionListener_win.cpp b/telldus-core/service/ConnectionListener_win.cpp index ec10d8bd..6e1c35a8 100644 --- a/telldus-core/service/ConnectionListener_win.cpp +++ b/telldus-core/service/ConnectionListener_win.cpp @@ -1,149 +1,149 @@ -#include "ConnectionListener.h" -#include "Event.h" -#include "Socket.h" - -#include -#include -#include - -#define BUFSIZE 512 - -class ConnectionListener::PrivateData { -public: - std::wstring pipename; - SECURITY_ATTRIBUTES sa; - HANDLE hEvent; - bool running; - TelldusCore::EventRef waitEvent; -}; - -ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) -{ - d = new PrivateData; - d->hEvent = 0; - - d->running = true; - d->waitEvent = waitEvent; - d->pipename = L"\\\\.\\pipe\\" + name; - - PSECURITY_DESCRIPTOR pSD = NULL; - PACL pACL = NULL; - EXPLICIT_ACCESS ea; - PSID pEveryoneSID = NULL; - SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; - - pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); - if (pSD == NULL) { - return; - } - - if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { - LocalFree(pSD); - return; - } - - if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { - LocalFree(pSD); - } - - ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); - ea.grfAccessPermissions = STANDARD_RIGHTS_ALL; - ea.grfAccessMode = SET_ACCESS; - ea.grfInheritance= NO_INHERITANCE; - ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; - ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; - ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID; - - - // Add the ACL to the security descriptor. - if (!SetSecurityDescriptorDacl(pSD, - TRUE, // bDaclPresent flag - pACL, - FALSE)) // not a default DACL - { - LocalFree(pSD); - FreeSid(pEveryoneSID); - } - - - d->sa.nLength = sizeof(SECURITY_ATTRIBUTES); - d->sa.lpSecurityDescriptor = pSD; - d->sa.bInheritHandle = false; - - start(); -} - -ConnectionListener::~ConnectionListener(void) { - d->running = false; - if (d->hEvent) { - SetEvent(d->hEvent); - } - wait(); - delete d; -} - -void ConnectionListener::run() { - HANDLE hPipe; - OVERLAPPED oOverlap; - DWORD cbBytesRead; - - memset(&oOverlap, 0, sizeof(OVERLAPPED)); - - d->hEvent = CreateEvent(NULL, true, false, NULL); - oOverlap.hEvent = d->hEvent; - bool recreate = true; - - while (1) { - BOOL alreadyConnected = false; - if (recreate) { - hPipe = CreateNamedPipe( - (const wchar_t *)d->pipename.c_str(), // pipe name - PIPE_ACCESS_DUPLEX | // read/write access - FILE_FLAG_OVERLAPPED, //Overlapped mode - PIPE_TYPE_MESSAGE | // message type pipe - PIPE_READMODE_MESSAGE | // message-read mode - PIPE_WAIT, // blocking mode - PIPE_UNLIMITED_INSTANCES, // max. instances - BUFSIZE, // output buffer size - BUFSIZE, // input buffer size - 0, // client time-out - &d->sa); // default security attribute - - if (hPipe == INVALID_HANDLE_VALUE) { - return; - } - - ConnectNamedPipe(hPipe, &oOverlap); - alreadyConnected = GetLastError() == ERROR_PIPE_CONNECTED; - recreate = false; - } - if(!alreadyConnected){ - DWORD result = WaitForSingleObject(oOverlap.hEvent, 1000); - if (!d->running) { - CancelIo(hPipe); - WaitForSingleObject(oOverlap.hEvent, INFINITE); - break; - } - - if(result == WAIT_TIMEOUT){ - //CloseHandle(hPipe); - continue; - } - BOOL connected = GetOverlappedResult(hPipe, &oOverlap, &cbBytesRead, false); - - if (!connected) { - CloseHandle(hPipe); - return; - } - } - ConnectionListenerEventData *data = new ConnectionListenerEventData(); - ResetEvent(oOverlap.hEvent); - data->socket = new TelldusCore::Socket(hPipe); - d->waitEvent->signal(data); - - recreate = true; - } - - CloseHandle(d->hEvent); - CloseHandle(hPipe); -} +#include "ConnectionListener.h" +#include "Event.h" +#include "Socket.h" + +#include +#include +#include + +#define BUFSIZE 512 + +class ConnectionListener::PrivateData { +public: + std::wstring pipename; + SECURITY_ATTRIBUTES sa; + HANDLE hEvent; + bool running; + TelldusCore::EventRef waitEvent; +}; + +ConnectionListener::ConnectionListener(const std::wstring &name, TelldusCore::EventRef waitEvent) +{ + d = new PrivateData; + d->hEvent = 0; + + d->running = true; + d->waitEvent = waitEvent; + d->pipename = L"\\\\.\\pipe\\" + name; + + PSECURITY_DESCRIPTOR pSD = NULL; + PACL pACL = NULL; + EXPLICIT_ACCESS ea; + PSID pEveryoneSID = NULL; + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; + + pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + if (pSD == NULL) { + return; + } + + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { + LocalFree(pSD); + return; + } + + if(!AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) { + LocalFree(pSD); + } + + ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); + ea.grfAccessPermissions = STANDARD_RIGHTS_ALL; + ea.grfAccessMode = SET_ACCESS; + ea.grfInheritance= NO_INHERITANCE; + ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea.Trustee.ptstrName = (LPTSTR) pEveryoneSID; + + + // Add the ACL to the security descriptor. + if (!SetSecurityDescriptorDacl(pSD, + TRUE, // bDaclPresent flag + pACL, + FALSE)) // not a default DACL + { + LocalFree(pSD); + FreeSid(pEveryoneSID); + } + + + d->sa.nLength = sizeof(SECURITY_ATTRIBUTES); + d->sa.lpSecurityDescriptor = pSD; + d->sa.bInheritHandle = false; + + start(); +} + +ConnectionListener::~ConnectionListener(void) { + d->running = false; + if (d->hEvent) { + SetEvent(d->hEvent); + } + wait(); + delete d; +} + +void ConnectionListener::run() { + HANDLE hPipe; + OVERLAPPED oOverlap; + DWORD cbBytesRead; + + memset(&oOverlap, 0, sizeof(OVERLAPPED)); + + d->hEvent = CreateEvent(NULL, true, false, NULL); + oOverlap.hEvent = d->hEvent; + bool recreate = true; + + while (1) { + BOOL alreadyConnected = false; + if (recreate) { + hPipe = CreateNamedPipe( + (const wchar_t *)d->pipename.c_str(), // pipe name + PIPE_ACCESS_DUPLEX | // read/write access + FILE_FLAG_OVERLAPPED, //Overlapped mode + PIPE_TYPE_MESSAGE | // message type pipe + PIPE_READMODE_MESSAGE | // message-read mode + PIPE_WAIT, // blocking mode + PIPE_UNLIMITED_INSTANCES, // max. instances + BUFSIZE, // output buffer size + BUFSIZE, // input buffer size + 0, // client time-out + &d->sa); // default security attribute + + if (hPipe == INVALID_HANDLE_VALUE) { + return; + } + + ConnectNamedPipe(hPipe, &oOverlap); + alreadyConnected = GetLastError() == ERROR_PIPE_CONNECTED; + recreate = false; + } + if(!alreadyConnected){ + DWORD result = WaitForSingleObject(oOverlap.hEvent, 1000); + if (!d->running) { + CancelIo(hPipe); + WaitForSingleObject(oOverlap.hEvent, INFINITE); + break; + } + + if(result == WAIT_TIMEOUT){ + //CloseHandle(hPipe); + continue; + } + BOOL connected = GetOverlappedResult(hPipe, &oOverlap, &cbBytesRead, false); + + if (!connected) { + CloseHandle(hPipe); + return; + } + } + ConnectionListenerEventData *data = new ConnectionListenerEventData(); + ResetEvent(oOverlap.hEvent); + data->socket = new TelldusCore::Socket(hPipe); + d->waitEvent->signal(data); + + recreate = true; + } + + CloseHandle(d->hEvent); + CloseHandle(hPipe); +} diff --git a/telldus-core/service/Controller.cpp b/telldus-core/service/Controller.cpp index 02a6b279..a9f22fc1 100644 --- a/telldus-core/service/Controller.cpp +++ b/telldus-core/service/Controller.cpp @@ -1,53 +1,53 @@ -#include "Controller.h" -#include "Protocol.h" -#include "EventUpdateManager.h" -#include "Strings.h" - -class Controller::PrivateData { -public: - TelldusCore::EventRef event, updateEvent; - int id, firmwareVersion; -}; - -Controller::Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent){ - d = new PrivateData; - d->event = event; - d->updateEvent = updateEvent; - d->id = id; - d->firmwareVersion = 0; -} - -Controller::~Controller(){ - delete d; -} - -void Controller::publishData(const std::string &msg) const { - ControllerEventData *data = new ControllerEventData; - data->msg = msg; - data->controllerId = d->id; - d->event->signal(data); -} - -void Controller::decodePublishData(const std::string &data) const { - - std::list msgList = Protocol::decodeData(data); - - for (std::list::iterator msgIt = msgList.begin(); msgIt != msgList.end(); ++msgIt){ - this->publishData(*msgIt); - } -} - -int Controller::firmwareVersion() const { - return d->firmwareVersion; -} - -void Controller::setFirmwareVersion(int version) { - d->firmwareVersion = version; - EventUpdateData *eventData = new EventUpdateData(); - eventData->messageType = L"TDControllerEvent"; - eventData->controllerId = d->id; - eventData->eventState = TELLSTICK_DEVICE_CHANGED; - eventData->eventChangeType = TELLSTICK_CHANGE_FIRMWARE; - eventData->eventValue = TelldusCore::intToWstring(version); - d->updateEvent->signal(eventData); -} +#include "Controller.h" +#include "Protocol.h" +#include "EventUpdateManager.h" +#include "Strings.h" + +class Controller::PrivateData { +public: + TelldusCore::EventRef event, updateEvent; + int id, firmwareVersion; +}; + +Controller::Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent){ + d = new PrivateData; + d->event = event; + d->updateEvent = updateEvent; + d->id = id; + d->firmwareVersion = 0; +} + +Controller::~Controller(){ + delete d; +} + +void Controller::publishData(const std::string &msg) const { + ControllerEventData *data = new ControllerEventData; + data->msg = msg; + data->controllerId = d->id; + d->event->signal(data); +} + +void Controller::decodePublishData(const std::string &data) const { + + std::list msgList = Protocol::decodeData(data); + + for (std::list::iterator msgIt = msgList.begin(); msgIt != msgList.end(); ++msgIt){ + this->publishData(*msgIt); + } +} + +int Controller::firmwareVersion() const { + return d->firmwareVersion; +} + +void Controller::setFirmwareVersion(int version) { + d->firmwareVersion = version; + EventUpdateData *eventData = new EventUpdateData(); + eventData->messageType = L"TDControllerEvent"; + eventData->controllerId = d->id; + eventData->eventState = TELLSTICK_DEVICE_CHANGED; + eventData->eventChangeType = TELLSTICK_CHANGE_FIRMWARE; + eventData->eventValue = TelldusCore::intToWstring(version); + d->updateEvent->signal(eventData); +} diff --git a/telldus-core/service/Controller.h b/telldus-core/service/Controller.h index eff903f7..410abf53 100644 --- a/telldus-core/service/Controller.h +++ b/telldus-core/service/Controller.h @@ -1,32 +1,32 @@ -#ifndef CONTROLLER_H -#define CONTROLLER_H - -#include "Event.h" -#include - -class ControllerEventData : public TelldusCore::EventDataBase { -public: - std::string msg; - int controllerId; -}; - -class Controller { -public: - virtual ~Controller(); - - virtual int firmwareVersion() const; - virtual int send( const std::string &message ) = 0; - virtual int reset() = 0; - -protected: - Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent); - void publishData(const std::string &data) const; - void decodePublishData(const std::string &data) const; - void setFirmwareVersion(int version); - -private: - class PrivateData; - PrivateData *d; -}; - -#endif //CONTROLLER_H +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#include "Event.h" +#include + +class ControllerEventData : public TelldusCore::EventDataBase { +public: + std::string msg; + int controllerId; +}; + +class Controller { +public: + virtual ~Controller(); + + virtual int firmwareVersion() const; + virtual int send( const std::string &message ) = 0; + virtual int reset() = 0; + +protected: + Controller(int id, TelldusCore::EventRef event, TelldusCore::EventRef updateEvent); + void publishData(const std::string &data) const; + void decodePublishData(const std::string &data) const; + void setFirmwareVersion(int version); + +private: + class PrivateData; + PrivateData *d; +}; + +#endif //CONTROLLER_H diff --git a/telldus-core/service/ControllerManager.cpp b/telldus-core/service/ControllerManager.cpp index ba6bcff3..2ccfa9a6 100644 --- a/telldus-core/service/ControllerManager.cpp +++ b/telldus-core/service/ControllerManager.cpp @@ -1,337 +1,337 @@ -#include "ControllerManager.h" -#include "Controller.h" -#include "Mutex.h" -#include "TellStick.h" -#include "Log.h" -#include "Message.h" -#include "Strings.h" -#include "Settings.h" -#include "EventUpdateManager.h" -#include "../client/telldus-core.h" - -#include -#include - -class ControllerDescriptor { -public: - std::wstring name, serial; - int type; - Controller *controller; -}; - -typedef std::map ControllerMap; - -class ControllerManager::PrivateData { -public: - int lastControllerId; - Settings settings; - ControllerMap controllers; - TelldusCore::EventRef event, updateEvent; - TelldusCore::Mutex mutex; -}; - -ControllerManager::ControllerManager(TelldusCore::EventRef event, TelldusCore::EventRef updateEvent){ - d = new PrivateData; - d->lastControllerId = 0; - d->event = event; - d->updateEvent = updateEvent; - this->loadStoredControllers(); - this->loadControllers(); -} - -ControllerManager::~ControllerManager() { - for (ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { - if (it->second.controller) { - delete( it->second.controller ); - } - } - delete d; -} - -void ControllerManager::deviceInsertedOrRemoved(int vid, int pid, const std::string &serial, bool inserted) { - if (vid == 0x0 && pid == 0x0) { //All - if (inserted) { - loadControllers(); - } else { - //Disconnect all - TelldusCore::MutexLocker locker(&d->mutex); - while(d->controllers.size()) { - ControllerMap::iterator it = d->controllers.begin(); - delete it->second.controller; - it->second.controller = 0; - signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0"); - } - } - return; - } - if (vid != 0x1781) { - return; - } - if (pid != 0x0C30 && pid != 0x0C31) { - return; - } - if (inserted) { - loadControllers(); - } else { - //Autodetect which has been disconnected - TelldusCore::MutexLocker locker(&d->mutex); - for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { - if (!it->second.controller) { - continue; - } - TellStick *tellstick = reinterpret_cast(it->second.controller); - if (!tellstick) { - continue; - } - if (serial.compare("") != 0) { - TellStickDescriptor tsd; - tsd.vid = vid; - tsd.pid = pid; - tsd.serial = serial; - if (!tellstick->isSameAsDescriptor(tsd)) { - continue; - } - } else if (tellstick->stillConnected()) { - continue; - } - - it->second.controller = 0; - delete tellstick; - signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0"); - } - } -} - -Controller *ControllerManager::getBestControllerById(int id) { - TelldusCore::MutexLocker locker(&d->mutex); - if (!d->controllers.size()) { - return 0; - } - ControllerMap::const_iterator it = d->controllers.find(id); - if (it != d->controllers.end() && it->second.controller) { - return it->second.controller; - } - //Find first available controller - for(it = d->controllers.begin(); it != d->controllers.end(); ++it) { - if (it->second.controller) { - return it->second.controller; - } - } - return 0; - -} - -void ControllerManager::loadControllers() { - TelldusCore::MutexLocker locker(&d->mutex); - - std::list list = TellStick::findAll(); - - std::list::iterator it = list.begin(); - for(; it != list.end(); ++it) { - //Most backend only report non-opened devices. - //If they don't make sure we don't open them twice - bool found = false; - ControllerMap::const_iterator cit = d->controllers.begin(); - for(; cit != d->controllers.end(); ++cit) { - if (!cit->second.controller) { - continue; - } - TellStick *tellstick = reinterpret_cast(cit->second.controller); - if (!tellstick) { - continue; - } - if (tellstick->isSameAsDescriptor(*it)) { - found = true; - break; - } - } - if (found) { - continue; - } - - int type = TELLSTICK_CONTROLLER_TELLSTICK; - if ((*it).pid == 0x0c31) { - type = TELLSTICK_CONTROLLER_TELLSTICK_DUO; - } - int controllerId = 0; - //See if the controller matches one of the loaded, non available controllers - std::wstring serial = TelldusCore::charToWstring((*it).serial.c_str()); - for(cit = d->controllers.begin(); cit != d->controllers.end(); ++cit) { - if (cit->second.type == type && cit->second.serial.compare(serial) == 0) { - controllerId = cit->first; - break; - } - } - bool isNew = false; - if (!controllerId) { - controllerId = d->settings.addNode(Settings::Controller); - if(controllerId < 0){ - //TODO: How to handle this? - continue; - } - isNew = true; - d->controllers[controllerId].type = type; - d->settings.setControllerType(controllerId, type); - d->controllers[controllerId].serial = TelldusCore::charToWstring((*it).serial.c_str()); - d->settings.setControllerSerial(controllerId, d->controllers[controllerId].serial); - } - - //int controllerId = d->lastControllerId+1; - TellStick *controller = new TellStick(controllerId, d->event, d->updateEvent, *it); - if (!controller->isOpen()) { - delete controller; - continue; - } - d->controllers[controllerId].controller = controller; - if (isNew) { - signalControllerEvent(controllerId, TELLSTICK_DEVICE_ADDED, type, L""); - } else { - signalControllerEvent(controllerId, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"1"); - } - } -} - -void ControllerManager::loadStoredControllers() { - int numberOfControllers = d->settings.getNumberOfNodes(Settings::Controller); - TelldusCore::MutexLocker locker(&d->mutex); - - for (int i = 0; i < numberOfControllers; ++i) { - int id = d->settings.getNodeId(Settings::Controller, i); - d->controllers[id].controller = NULL; - d->controllers[id].name = d->settings.getName(Settings::Controller, id); - d->controllers[id].type = d->settings.getControllerType(id); - d->controllers[id].serial = d->settings.getControllerSerial(id); - signalControllerEvent(id, TELLSTICK_DEVICE_ADDED, 0, L""); - } -} - -void ControllerManager::queryControllerStatus(){ - - std::list tellStickControllers; - - { - TelldusCore::MutexLocker locker(&d->mutex); - for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { - if (!it->second.controller) { - continue; - } - TellStick *tellstick = reinterpret_cast(it->second.controller); - if (tellstick) { - tellStickControllers.push_back(tellstick); - } - } - } - - bool reloadControllers = false; - std::string noop = "N+"; - for(std::list::iterator it = tellStickControllers.begin(); it != tellStickControllers.end(); ++it) { - int success = (*it)->send(noop); - if(success == TELLSTICK_ERROR_BROKEN_PIPE){ - Log::warning("TellStick query: Error in communication with TellStick, resetting USB"); - resetController(*it); - } - if(success == TELLSTICK_ERROR_BROKEN_PIPE || success == TELLSTICK_ERROR_NOT_FOUND){ - reloadControllers = true; - } - } - - if(!tellStickControllers.size() || reloadControllers){ - //no tellstick at all found, or controller was reset - Log::debug("TellStick query: Rescanning USB ports"); //only log as debug, since this will happen all the time if no TellStick is connected - loadControllers(); - } -} - -int ControllerManager::resetController(Controller *controller) { - TellStick *tellstick = reinterpret_cast(controller); - if (!tellstick) { - return true; //not tellstick, nothing to reset at the moment, just return true - } - int success = tellstick->reset(); - deviceInsertedOrRemoved(tellstick->vid(), tellstick->pid(), tellstick->serial(), false); //remove from list and delete - return success; -} - -std::wstring ControllerManager::getControllers() const { - TelldusCore::MutexLocker locker(&d->mutex); - - TelldusCore::Message msg; - - msg.addArgument((int)d->controllers.size()); - - for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { - msg.addArgument(it->first); - msg.addArgument(it->second.type); - msg.addArgument(it->second.name.c_str()); - msg.addArgument(it->second.controller ? 1 : 0); - } - return msg; -} - -std::wstring ControllerManager::getControllerValue(int id, const std::wstring &name) { - TelldusCore::MutexLocker locker(&d->mutex); - - ControllerMap::iterator it = d->controllers.find(id); - if (it == d->controllers.end()) { - return L""; - } - if (name == L"serial") { - return it->second.serial; - } else if (name == L"firmware") { - if (!it->second.controller) { - return L"-1"; - } - return TelldusCore::intToWstring(it->second.controller->firmwareVersion()); - } - return L""; -} - -int ControllerManager::removeController(int id) { - TelldusCore::MutexLocker locker(&d->mutex); - - ControllerMap::iterator it = d->controllers.find(id); - if (it == d->controllers.end()) { - return TELLSTICK_ERROR_NOT_FOUND; - } - if (it->second.controller) { - //Still connected - return TELLSTICK_ERROR_PERMISSION_DENIED; - } - - int ret = d->settings.removeNode(Settings::Controller, id); - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - - d->controllers.erase(it); - - signalControllerEvent(id, TELLSTICK_DEVICE_REMOVED, 0, L""); - return TELLSTICK_SUCCESS; -} - -int ControllerManager::setControllerValue(int id, const std::wstring &name, const std::wstring &value) { - TelldusCore::MutexLocker locker(&d->mutex); - - ControllerMap::iterator it = d->controllers.find(id); - if (it == d->controllers.end()) { - return TELLSTICK_ERROR_NOT_FOUND; - } - if (name == L"name") { - it->second.name = value; - d->settings.setName(Settings::Controller, id, value); - signalControllerEvent(id, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME, value); - } else { - return TELLSTICK_ERROR_SYNTAX; //TODO: Is this the best error? - } - return TELLSTICK_SUCCESS; -} - -void ControllerManager::signalControllerEvent(int controllerId, int changeEvent, int changeType, const std::wstring &newValue) { - EventUpdateData *eventData = new EventUpdateData(); - eventData->messageType = L"TDControllerEvent"; - eventData->controllerId = controllerId; - eventData->eventState = changeEvent; - eventData->eventChangeType = changeType; - eventData->eventValue = newValue; - d->updateEvent->signal(eventData); -} +#include "ControllerManager.h" +#include "Controller.h" +#include "Mutex.h" +#include "TellStick.h" +#include "Log.h" +#include "Message.h" +#include "Strings.h" +#include "Settings.h" +#include "EventUpdateManager.h" +#include "../client/telldus-core.h" + +#include +#include + +class ControllerDescriptor { +public: + std::wstring name, serial; + int type; + Controller *controller; +}; + +typedef std::map ControllerMap; + +class ControllerManager::PrivateData { +public: + int lastControllerId; + Settings settings; + ControllerMap controllers; + TelldusCore::EventRef event, updateEvent; + TelldusCore::Mutex mutex; +}; + +ControllerManager::ControllerManager(TelldusCore::EventRef event, TelldusCore::EventRef updateEvent){ + d = new PrivateData; + d->lastControllerId = 0; + d->event = event; + d->updateEvent = updateEvent; + this->loadStoredControllers(); + this->loadControllers(); +} + +ControllerManager::~ControllerManager() { + for (ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { + if (it->second.controller) { + delete( it->second.controller ); + } + } + delete d; +} + +void ControllerManager::deviceInsertedOrRemoved(int vid, int pid, const std::string &serial, bool inserted) { + if (vid == 0x0 && pid == 0x0) { //All + if (inserted) { + loadControllers(); + } else { + //Disconnect all + TelldusCore::MutexLocker locker(&d->mutex); + while(d->controllers.size()) { + ControllerMap::iterator it = d->controllers.begin(); + delete it->second.controller; + it->second.controller = 0; + signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0"); + } + } + return; + } + if (vid != 0x1781) { + return; + } + if (pid != 0x0C30 && pid != 0x0C31) { + return; + } + if (inserted) { + loadControllers(); + } else { + //Autodetect which has been disconnected + TelldusCore::MutexLocker locker(&d->mutex); + for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { + if (!it->second.controller) { + continue; + } + TellStick *tellstick = reinterpret_cast(it->second.controller); + if (!tellstick) { + continue; + } + if (serial.compare("") != 0) { + TellStickDescriptor tsd; + tsd.vid = vid; + tsd.pid = pid; + tsd.serial = serial; + if (!tellstick->isSameAsDescriptor(tsd)) { + continue; + } + } else if (tellstick->stillConnected()) { + continue; + } + + it->second.controller = 0; + delete tellstick; + signalControllerEvent(it->first, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"0"); + } + } +} + +Controller *ControllerManager::getBestControllerById(int id) { + TelldusCore::MutexLocker locker(&d->mutex); + if (!d->controllers.size()) { + return 0; + } + ControllerMap::const_iterator it = d->controllers.find(id); + if (it != d->controllers.end() && it->second.controller) { + return it->second.controller; + } + //Find first available controller + for(it = d->controllers.begin(); it != d->controllers.end(); ++it) { + if (it->second.controller) { + return it->second.controller; + } + } + return 0; + +} + +void ControllerManager::loadControllers() { + TelldusCore::MutexLocker locker(&d->mutex); + + std::list list = TellStick::findAll(); + + std::list::iterator it = list.begin(); + for(; it != list.end(); ++it) { + //Most backend only report non-opened devices. + //If they don't make sure we don't open them twice + bool found = false; + ControllerMap::const_iterator cit = d->controllers.begin(); + for(; cit != d->controllers.end(); ++cit) { + if (!cit->second.controller) { + continue; + } + TellStick *tellstick = reinterpret_cast(cit->second.controller); + if (!tellstick) { + continue; + } + if (tellstick->isSameAsDescriptor(*it)) { + found = true; + break; + } + } + if (found) { + continue; + } + + int type = TELLSTICK_CONTROLLER_TELLSTICK; + if ((*it).pid == 0x0c31) { + type = TELLSTICK_CONTROLLER_TELLSTICK_DUO; + } + int controllerId = 0; + //See if the controller matches one of the loaded, non available controllers + std::wstring serial = TelldusCore::charToWstring((*it).serial.c_str()); + for(cit = d->controllers.begin(); cit != d->controllers.end(); ++cit) { + if (cit->second.type == type && cit->second.serial.compare(serial) == 0) { + controllerId = cit->first; + break; + } + } + bool isNew = false; + if (!controllerId) { + controllerId = d->settings.addNode(Settings::Controller); + if(controllerId < 0){ + //TODO: How to handle this? + continue; + } + isNew = true; + d->controllers[controllerId].type = type; + d->settings.setControllerType(controllerId, type); + d->controllers[controllerId].serial = TelldusCore::charToWstring((*it).serial.c_str()); + d->settings.setControllerSerial(controllerId, d->controllers[controllerId].serial); + } + + //int controllerId = d->lastControllerId+1; + TellStick *controller = new TellStick(controllerId, d->event, d->updateEvent, *it); + if (!controller->isOpen()) { + delete controller; + continue; + } + d->controllers[controllerId].controller = controller; + if (isNew) { + signalControllerEvent(controllerId, TELLSTICK_DEVICE_ADDED, type, L""); + } else { + signalControllerEvent(controllerId, TELLSTICK_DEVICE_STATE_CHANGED, TELLSTICK_CHANGE_AVAILABLE, L"1"); + } + } +} + +void ControllerManager::loadStoredControllers() { + int numberOfControllers = d->settings.getNumberOfNodes(Settings::Controller); + TelldusCore::MutexLocker locker(&d->mutex); + + for (int i = 0; i < numberOfControllers; ++i) { + int id = d->settings.getNodeId(Settings::Controller, i); + d->controllers[id].controller = NULL; + d->controllers[id].name = d->settings.getName(Settings::Controller, id); + d->controllers[id].type = d->settings.getControllerType(id); + d->controllers[id].serial = d->settings.getControllerSerial(id); + signalControllerEvent(id, TELLSTICK_DEVICE_ADDED, 0, L""); + } +} + +void ControllerManager::queryControllerStatus(){ + + std::list tellStickControllers; + + { + TelldusCore::MutexLocker locker(&d->mutex); + for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { + if (!it->second.controller) { + continue; + } + TellStick *tellstick = reinterpret_cast(it->second.controller); + if (tellstick) { + tellStickControllers.push_back(tellstick); + } + } + } + + bool reloadControllers = false; + std::string noop = "N+"; + for(std::list::iterator it = tellStickControllers.begin(); it != tellStickControllers.end(); ++it) { + int success = (*it)->send(noop); + if(success == TELLSTICK_ERROR_BROKEN_PIPE){ + Log::warning("TellStick query: Error in communication with TellStick, resetting USB"); + resetController(*it); + } + if(success == TELLSTICK_ERROR_BROKEN_PIPE || success == TELLSTICK_ERROR_NOT_FOUND){ + reloadControllers = true; + } + } + + if(!tellStickControllers.size() || reloadControllers){ + //no tellstick at all found, or controller was reset + Log::debug("TellStick query: Rescanning USB ports"); //only log as debug, since this will happen all the time if no TellStick is connected + loadControllers(); + } +} + +int ControllerManager::resetController(Controller *controller) { + TellStick *tellstick = reinterpret_cast(controller); + if (!tellstick) { + return true; //not tellstick, nothing to reset at the moment, just return true + } + int success = tellstick->reset(); + deviceInsertedOrRemoved(tellstick->vid(), tellstick->pid(), tellstick->serial(), false); //remove from list and delete + return success; +} + +std::wstring ControllerManager::getControllers() const { + TelldusCore::MutexLocker locker(&d->mutex); + + TelldusCore::Message msg; + + msg.addArgument((int)d->controllers.size()); + + for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) { + msg.addArgument(it->first); + msg.addArgument(it->second.type); + msg.addArgument(it->second.name.c_str()); + msg.addArgument(it->second.controller ? 1 : 0); + } + return msg; +} + +std::wstring ControllerManager::getControllerValue(int id, const std::wstring &name) { + TelldusCore::MutexLocker locker(&d->mutex); + + ControllerMap::iterator it = d->controllers.find(id); + if (it == d->controllers.end()) { + return L""; + } + if (name == L"serial") { + return it->second.serial; + } else if (name == L"firmware") { + if (!it->second.controller) { + return L"-1"; + } + return TelldusCore::intToWstring(it->second.controller->firmwareVersion()); + } + return L""; +} + +int ControllerManager::removeController(int id) { + TelldusCore::MutexLocker locker(&d->mutex); + + ControllerMap::iterator it = d->controllers.find(id); + if (it == d->controllers.end()) { + return TELLSTICK_ERROR_NOT_FOUND; + } + if (it->second.controller) { + //Still connected + return TELLSTICK_ERROR_PERMISSION_DENIED; + } + + int ret = d->settings.removeNode(Settings::Controller, id); + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + + d->controllers.erase(it); + + signalControllerEvent(id, TELLSTICK_DEVICE_REMOVED, 0, L""); + return TELLSTICK_SUCCESS; +} + +int ControllerManager::setControllerValue(int id, const std::wstring &name, const std::wstring &value) { + TelldusCore::MutexLocker locker(&d->mutex); + + ControllerMap::iterator it = d->controllers.find(id); + if (it == d->controllers.end()) { + return TELLSTICK_ERROR_NOT_FOUND; + } + if (name == L"name") { + it->second.name = value; + d->settings.setName(Settings::Controller, id, value); + signalControllerEvent(id, TELLSTICK_DEVICE_CHANGED, TELLSTICK_CHANGE_NAME, value); + } else { + return TELLSTICK_ERROR_SYNTAX; //TODO: Is this the best error? + } + return TELLSTICK_SUCCESS; +} + +void ControllerManager::signalControllerEvent(int controllerId, int changeEvent, int changeType, const std::wstring &newValue) { + EventUpdateData *eventData = new EventUpdateData(); + eventData->messageType = L"TDControllerEvent"; + eventData->controllerId = controllerId; + eventData->eventState = changeEvent; + eventData->eventChangeType = changeType; + eventData->eventValue = newValue; + d->updateEvent->signal(eventData); +} diff --git a/telldus-core/service/ControllerMessage.cpp b/telldus-core/service/ControllerMessage.cpp index 72c83f24..aa0135c9 100644 --- a/telldus-core/service/ControllerMessage.cpp +++ b/telldus-core/service/ControllerMessage.cpp @@ -1,89 +1,89 @@ -#include "ControllerMessage.h" -#include "Device.h" -#include "Strings.h" - -#include "common.h" - -#include - -class ControllerMessage::PrivateData { -public: - std::map parameters; - std::string protocol, model, msgClass; - int method; -}; - -ControllerMessage::ControllerMessage(const std::string &message) { - d = new PrivateData; - - //Process our message into bits - size_t prevPos = 0; - size_t pos = message.find(";"); - while(pos != std::string::npos) { - std::string param = message.substr(prevPos, pos-prevPos); - prevPos = pos+1; - size_t delim = param.find(":"); - if (delim == std::string::npos) { - break; - } - if (param.substr(0, delim).compare("class") == 0) { - d->msgClass = param.substr(delim+1, param.length()-delim); - } else if (param.substr(0, delim).compare("protocol") == 0) { - d->protocol = param.substr(delim+1, param.length()-delim); - } else if (param.substr(0, delim).compare("model") == 0) { - d->model = param.substr(delim+1, param.length()-delim); - } else if (param.substr(0, delim).compare("method") == 0) { - d->method = Device::methodId(param.substr(delim+1, param.length()-delim)); - } else { - d->parameters[param.substr(0, delim)] = param.substr(delim+1, param.length()-delim); - } - pos = message.find(";", pos+1); - } -} - -ControllerMessage::~ControllerMessage(){ - delete d; -} - -std::string ControllerMessage::msgClass() const { - return d->msgClass; -} - -int ControllerMessage::method() const { - return d->method; -} - -std::wstring ControllerMessage::protocol() const { - return TelldusCore::charToWstring(d->protocol.c_str()); -} - -std::wstring ControllerMessage::model() const { - return TelldusCore::charToWstring(d->model.c_str()); -} - -int ControllerMessage::getIntParameter(const std::string &key) const { - std::string strValue = getParameter(key); - if (strValue.compare("") == 0) { - return -1; - } - if (strValue.substr(0,2).compare("0x") == 0) { - return strtol(strValue.c_str(), NULL, 16); - } - return strtol(strValue.c_str(), NULL, 10); -} - -std::string ControllerMessage::getParameter(const std::string &key) const { - std::map::iterator it = d->parameters.find(key); - if (it == d->parameters.end()) { - return ""; - } - return d->parameters[key]; -} - -bool ControllerMessage::hasParameter(const std::string &key) const { - std::map::iterator it = d->parameters.find(key); - if (it == d->parameters.end()) { - return false; - } - return true; -} +#include "ControllerMessage.h" +#include "Device.h" +#include "Strings.h" + +#include "common.h" + +#include + +class ControllerMessage::PrivateData { +public: + std::map parameters; + std::string protocol, model, msgClass; + int method; +}; + +ControllerMessage::ControllerMessage(const std::string &message) { + d = new PrivateData; + + //Process our message into bits + size_t prevPos = 0; + size_t pos = message.find(";"); + while(pos != std::string::npos) { + std::string param = message.substr(prevPos, pos-prevPos); + prevPos = pos+1; + size_t delim = param.find(":"); + if (delim == std::string::npos) { + break; + } + if (param.substr(0, delim).compare("class") == 0) { + d->msgClass = param.substr(delim+1, param.length()-delim); + } else if (param.substr(0, delim).compare("protocol") == 0) { + d->protocol = param.substr(delim+1, param.length()-delim); + } else if (param.substr(0, delim).compare("model") == 0) { + d->model = param.substr(delim+1, param.length()-delim); + } else if (param.substr(0, delim).compare("method") == 0) { + d->method = Device::methodId(param.substr(delim+1, param.length()-delim)); + } else { + d->parameters[param.substr(0, delim)] = param.substr(delim+1, param.length()-delim); + } + pos = message.find(";", pos+1); + } +} + +ControllerMessage::~ControllerMessage(){ + delete d; +} + +std::string ControllerMessage::msgClass() const { + return d->msgClass; +} + +int ControllerMessage::method() const { + return d->method; +} + +std::wstring ControllerMessage::protocol() const { + return TelldusCore::charToWstring(d->protocol.c_str()); +} + +std::wstring ControllerMessage::model() const { + return TelldusCore::charToWstring(d->model.c_str()); +} + +int ControllerMessage::getIntParameter(const std::string &key) const { + std::string strValue = getParameter(key); + if (strValue.compare("") == 0) { + return -1; + } + if (strValue.substr(0,2).compare("0x") == 0) { + return strtol(strValue.c_str(), NULL, 16); + } + return strtol(strValue.c_str(), NULL, 10); +} + +std::string ControllerMessage::getParameter(const std::string &key) const { + std::map::iterator it = d->parameters.find(key); + if (it == d->parameters.end()) { + return ""; + } + return d->parameters[key]; +} + +bool ControllerMessage::hasParameter(const std::string &key) const { + std::map::iterator it = d->parameters.find(key); + if (it == d->parameters.end()) { + return false; + } + return true; +} diff --git a/telldus-core/service/Device.cpp b/telldus-core/service/Device.cpp index b660c671..b0777542 100644 --- a/telldus-core/service/Device.cpp +++ b/telldus-core/service/Device.cpp @@ -1,253 +1,253 @@ -#include "Device.h" -#include "Settings.h" -#include "TellStick.h" - -class Device::PrivateData { -public: - std::wstring model; - std::wstring name; - ParameterMap parameterList; - Protocol *protocol; - std::wstring protocolName; - int preferredControllerId; - int state; - std::wstring stateValue; -}; - -Device::Device(int id) - :Mutex() -{ - d = new PrivateData; - d->protocol = 0; - d->preferredControllerId = 0; - d->state = 0; -} - -Device::~Device(void) { - delete d->protocol; - delete d; -} - -/** -* Get-/Set-methods -*/ - -int Device::getLastSentCommand(int methodsSupported){ - - int lastSentCommand = Device::maskUnsupportedMethods(d->state, methodsSupported); - - if (lastSentCommand == TELLSTICK_BELL) { - //Bell is not a state - lastSentCommand = TELLSTICK_TURNOFF; - } - if (lastSentCommand == 0) { - lastSentCommand = TELLSTICK_TURNOFF; - } - return lastSentCommand; - -} - -int Device::getMethods() const { - Protocol *p = this->retrieveProtocol(); - if (p) { - return p->methods(); - } - return 0; -} - -void Device::setLastSentCommand(int command, std::wstring value){ - d->state = command; - d->stateValue = value; -} - -std::wstring Device::getModel(){ - return d->model; -} - -void Device::setModel(const std::wstring &model){ - if(d->protocol){ - delete(d->protocol); - d->protocol = 0; - } - d->model = model; -} - -std::wstring Device::getName(){ - return d->name; -} - -void Device::setName(const std::wstring &name){ - d->name = name; -} - -std::wstring Device::getParameter(const std::wstring &key){ - ParameterMap::iterator it = d->parameterList.find(key); - if (it == d->parameterList.end()) { - return L""; - } - return d->parameterList[key]; -} - -std::list Device::getParametersForProtocol() const { - return Protocol::getParametersForProtocol(getProtocolName()); -} - -void Device::setParameter(const std::wstring &key, const std::wstring &value){ - d->parameterList[key] = value; - if(d->protocol){ - d->protocol->setParameters(d->parameterList); - } -} - -int Device::getPreferredControllerId(){ - return d->preferredControllerId; -} - -void Device::setPreferredControllerId(int controllerId){ - d->preferredControllerId = controllerId; -} - -std::wstring Device::getProtocolName() const { - return d->protocolName; -} - -void Device::setProtocolName(const std::wstring &protocolName){ - if(d->protocol){ - delete(d->protocol); - d->protocol = 0; - } - d->protocolName = protocolName; -} - -std::wstring Device::getStateValue(){ - return d->stateValue; -} - -int Device::getType(){ - if(d->protocolName == L"group"){ - return TELLSTICK_TYPE_GROUP; - } - else if(d->protocolName == L"scene"){ - return TELLSTICK_TYPE_SCENE; - } - return TELLSTICK_TYPE_DEVICE; -} - -/** -* End Get-/Set -*/ - -int Device::doAction(int action, unsigned char data, Controller *controller) { - Protocol *p = this->retrieveProtocol(); - if(p){ - //Try to determine if we need to call another method due to masking - int methods = p->methods(); - if ((action & methods) == 0) { - //Loop all methods an see if any method masks to this one - for(int i = 1; i <= methods; i<<=1) { - if ((i & methods) == 0) { - continue; - } - if (this->maskUnsupportedMethods(i, action)) { - action = i; - break; - } - } - } - if ((action & methods) == 0) { - return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; - } - std::string code = p->getStringForMethod(action, data, controller); - if (code == "") { - return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; - } - if (code[0] != 'S' && code[0] != 'T' && code[0] != 'P' && code[0] != 'R') { - //Try autodetect sendtype - TellStick *tellstick = reinterpret_cast(controller); - if (!tellstick) { - return TELLSTICK_ERROR_UNKNOWN; - } - unsigned int maxlength = 80; - if (tellstick->pid() == 0x0c31) { - maxlength = 512; - } - if (code.length() <= maxlength) { - //S is enough - code.insert(0, 1, 'S'); - code.append(1, '+'); - } else { - code = TellStick::createTPacket(code); - } - } - return controller->send(code); - } - return TELLSTICK_ERROR_UNKNOWN; -} - -Protocol* Device::retrieveProtocol() const { - if (d->protocol) { - return d->protocol; - } - - d->protocol = Protocol::getProtocolInstance(d->protocolName); - if(d->protocol){ - d->protocol->setModel(d->model); - d->protocol->setParameters(d->parameterList); - return d->protocol; - } - - return 0; -} - -int Device::maskUnsupportedMethods(int methods, int supportedMethods) { - // Bell -> On - if ((methods & TELLSTICK_BELL) && !(supportedMethods & TELLSTICK_BELL)) { - methods |= TELLSTICK_TURNON; - } - - // Execute -> On - if ((methods & TELLSTICK_EXECUTE) && !(supportedMethods & TELLSTICK_EXECUTE)) { - methods |= TELLSTICK_TURNON; - } - - // Up -> Off - if ((methods & TELLSTICK_UP) && !(supportedMethods & TELLSTICK_UP)) { - methods |= TELLSTICK_TURNOFF; - } - - // Down -> On - if ((methods & TELLSTICK_DOWN) && !(supportedMethods & TELLSTICK_DOWN)) { - methods |= TELLSTICK_TURNON; - } - - //Cut of the rest of the unsupported methods we don't have a fallback for - return methods & supportedMethods; -} - -int Device::methodId( const std::string &methodName ) { - if (methodName.compare("turnon") == 0) { - return TELLSTICK_TURNON; - } - if (methodName.compare("turnoff") == 0) { - return TELLSTICK_TURNOFF; - } - if (methodName.compare("bell") == 0) { - return TELLSTICK_BELL; - } - if (methodName.compare("dim") == 0) { - return TELLSTICK_DIM; - } - if (methodName.compare("execute") == 0) { - return TELLSTICK_EXECUTE; - } - if (methodName.compare("up") == 0) { - return TELLSTICK_UP; - } - if (methodName.compare("down") == 0) { - return TELLSTICK_DOWN; - } - if (methodName.compare("stop") == 0) { - return TELLSTICK_STOP; - } - return 0; -} +#include "Device.h" +#include "Settings.h" +#include "TellStick.h" + +class Device::PrivateData { +public: + std::wstring model; + std::wstring name; + ParameterMap parameterList; + Protocol *protocol; + std::wstring protocolName; + int preferredControllerId; + int state; + std::wstring stateValue; +}; + +Device::Device(int id) + :Mutex() +{ + d = new PrivateData; + d->protocol = 0; + d->preferredControllerId = 0; + d->state = 0; +} + +Device::~Device(void) { + delete d->protocol; + delete d; +} + +/** +* Get-/Set-methods +*/ + +int Device::getLastSentCommand(int methodsSupported){ + + int lastSentCommand = Device::maskUnsupportedMethods(d->state, methodsSupported); + + if (lastSentCommand == TELLSTICK_BELL) { + //Bell is not a state + lastSentCommand = TELLSTICK_TURNOFF; + } + if (lastSentCommand == 0) { + lastSentCommand = TELLSTICK_TURNOFF; + } + return lastSentCommand; + +} + +int Device::getMethods() const { + Protocol *p = this->retrieveProtocol(); + if (p) { + return p->methods(); + } + return 0; +} + +void Device::setLastSentCommand(int command, std::wstring value){ + d->state = command; + d->stateValue = value; +} + +std::wstring Device::getModel(){ + return d->model; +} + +void Device::setModel(const std::wstring &model){ + if(d->protocol){ + delete(d->protocol); + d->protocol = 0; + } + d->model = model; +} + +std::wstring Device::getName(){ + return d->name; +} + +void Device::setName(const std::wstring &name){ + d->name = name; +} + +std::wstring Device::getParameter(const std::wstring &key){ + ParameterMap::iterator it = d->parameterList.find(key); + if (it == d->parameterList.end()) { + return L""; + } + return d->parameterList[key]; +} + +std::list Device::getParametersForProtocol() const { + return Protocol::getParametersForProtocol(getProtocolName()); +} + +void Device::setParameter(const std::wstring &key, const std::wstring &value){ + d->parameterList[key] = value; + if(d->protocol){ + d->protocol->setParameters(d->parameterList); + } +} + +int Device::getPreferredControllerId(){ + return d->preferredControllerId; +} + +void Device::setPreferredControllerId(int controllerId){ + d->preferredControllerId = controllerId; +} + +std::wstring Device::getProtocolName() const { + return d->protocolName; +} + +void Device::setProtocolName(const std::wstring &protocolName){ + if(d->protocol){ + delete(d->protocol); + d->protocol = 0; + } + d->protocolName = protocolName; +} + +std::wstring Device::getStateValue(){ + return d->stateValue; +} + +int Device::getType(){ + if(d->protocolName == L"group"){ + return TELLSTICK_TYPE_GROUP; + } + else if(d->protocolName == L"scene"){ + return TELLSTICK_TYPE_SCENE; + } + return TELLSTICK_TYPE_DEVICE; +} + +/** +* End Get-/Set +*/ + +int Device::doAction(int action, unsigned char data, Controller *controller) { + Protocol *p = this->retrieveProtocol(); + if(p){ + //Try to determine if we need to call another method due to masking + int methods = p->methods(); + if ((action & methods) == 0) { + //Loop all methods an see if any method masks to this one + for(int i = 1; i <= methods; i<<=1) { + if ((i & methods) == 0) { + continue; + } + if (this->maskUnsupportedMethods(i, action)) { + action = i; + break; + } + } + } + if ((action & methods) == 0) { + return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; + } + std::string code = p->getStringForMethod(action, data, controller); + if (code == "") { + return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; + } + if (code[0] != 'S' && code[0] != 'T' && code[0] != 'P' && code[0] != 'R') { + //Try autodetect sendtype + TellStick *tellstick = reinterpret_cast(controller); + if (!tellstick) { + return TELLSTICK_ERROR_UNKNOWN; + } + unsigned int maxlength = 80; + if (tellstick->pid() == 0x0c31) { + maxlength = 512; + } + if (code.length() <= maxlength) { + //S is enough + code.insert(0, 1, 'S'); + code.append(1, '+'); + } else { + code = TellStick::createTPacket(code); + } + } + return controller->send(code); + } + return TELLSTICK_ERROR_UNKNOWN; +} + +Protocol* Device::retrieveProtocol() const { + if (d->protocol) { + return d->protocol; + } + + d->protocol = Protocol::getProtocolInstance(d->protocolName); + if(d->protocol){ + d->protocol->setModel(d->model); + d->protocol->setParameters(d->parameterList); + return d->protocol; + } + + return 0; +} + +int Device::maskUnsupportedMethods(int methods, int supportedMethods) { + // Bell -> On + if ((methods & TELLSTICK_BELL) && !(supportedMethods & TELLSTICK_BELL)) { + methods |= TELLSTICK_TURNON; + } + + // Execute -> On + if ((methods & TELLSTICK_EXECUTE) && !(supportedMethods & TELLSTICK_EXECUTE)) { + methods |= TELLSTICK_TURNON; + } + + // Up -> Off + if ((methods & TELLSTICK_UP) && !(supportedMethods & TELLSTICK_UP)) { + methods |= TELLSTICK_TURNOFF; + } + + // Down -> On + if ((methods & TELLSTICK_DOWN) && !(supportedMethods & TELLSTICK_DOWN)) { + methods |= TELLSTICK_TURNON; + } + + //Cut of the rest of the unsupported methods we don't have a fallback for + return methods & supportedMethods; +} + +int Device::methodId( const std::string &methodName ) { + if (methodName.compare("turnon") == 0) { + return TELLSTICK_TURNON; + } + if (methodName.compare("turnoff") == 0) { + return TELLSTICK_TURNOFF; + } + if (methodName.compare("bell") == 0) { + return TELLSTICK_BELL; + } + if (methodName.compare("dim") == 0) { + return TELLSTICK_DIM; + } + if (methodName.compare("execute") == 0) { + return TELLSTICK_EXECUTE; + } + if (methodName.compare("up") == 0) { + return TELLSTICK_UP; + } + if (methodName.compare("down") == 0) { + return TELLSTICK_DOWN; + } + if (methodName.compare("stop") == 0) { + return TELLSTICK_STOP; + } + return 0; +} diff --git a/telldus-core/service/Device.h b/telldus-core/service/Device.h index 75037d1a..5efb8e06 100644 --- a/telldus-core/service/Device.h +++ b/telldus-core/service/Device.h @@ -1,45 +1,45 @@ #ifndef DEVICE_H -#define DEVICE_H - -#include "Controller.h" -#include "Mutex.h" -#include "Protocol.h" -#include -#include - -class Device : public TelldusCore::Mutex -{ -public: - Device(int id); - ~Device(void); - - int doAction(int action, unsigned char data, Controller *controller); - std::wstring getStateValue(); - int getLastSentCommand(int methodsSupported); - int getMethods() const; - std::wstring getModel(); - void setModel(const std::wstring &model); - std::wstring getName(); - void setName(const std::wstring &name); - std::wstring getParameter(const std::wstring &key); - std::list getParametersForProtocol() const; - void setParameter(const std::wstring &key, const std::wstring &value); - int getPreferredControllerId(); - void setPreferredControllerId(int controllerId); - std::wstring getProtocolName() const; - void setProtocolName(const std::wstring &name); - void setStateValue(int stateValue); - void setLastSentCommand(int command, std::wstring value); - int getType(); - - static int maskUnsupportedMethods(int methods, int supportedMethods); - static int methodId( const std::string &methodName ); - -private: - Protocol *retrieveProtocol() const; - - class PrivateData; - PrivateData *d; -}; - +#define DEVICE_H + +#include "Controller.h" +#include "Mutex.h" +#include "Protocol.h" +#include +#include + +class Device : public TelldusCore::Mutex +{ +public: + Device(int id); + ~Device(void); + + int doAction(int action, unsigned char data, Controller *controller); + std::wstring getStateValue(); + int getLastSentCommand(int methodsSupported); + int getMethods() const; + std::wstring getModel(); + void setModel(const std::wstring &model); + std::wstring getName(); + void setName(const std::wstring &name); + std::wstring getParameter(const std::wstring &key); + std::list getParametersForProtocol() const; + void setParameter(const std::wstring &key, const std::wstring &value); + int getPreferredControllerId(); + void setPreferredControllerId(int controllerId); + std::wstring getProtocolName() const; + void setProtocolName(const std::wstring &name); + void setStateValue(int stateValue); + void setLastSentCommand(int command, std::wstring value); + int getType(); + + static int maskUnsupportedMethods(int methods, int supportedMethods); + static int methodId( const std::string &methodName ); + +private: + Protocol *retrieveProtocol() const; + + class PrivateData; + PrivateData *d; +}; + #endif //DEVICE_H diff --git a/telldus-core/service/DeviceManager.cpp b/telldus-core/service/DeviceManager.cpp index 701f681c..3c8753e9 100644 --- a/telldus-core/service/DeviceManager.cpp +++ b/telldus-core/service/DeviceManager.cpp @@ -1,783 +1,783 @@ -#include "DeviceManager.h" -#include "ControllerMessage.h" -#include "Mutex.h" -#include "Sensor.h" -#include "Settings.h" -#include "Strings.h" -#include "Message.h" -#include "Log.h" - -#include -#include -#include -#include - -typedef std::map DeviceMap; - -class DeviceManager::PrivateData { -public: - DeviceMap devices; - std::list sensorList; - Settings set; - TelldusCore::Mutex lock; - ControllerManager *controllerManager; - TelldusCore::EventRef deviceUpdateEvent; -}; - -DeviceManager::DeviceManager(ControllerManager *controllerManager, TelldusCore::EventRef deviceUpdateEvent){ - d = new PrivateData; - d->controllerManager = controllerManager; - d->deviceUpdateEvent = deviceUpdateEvent; - fillDevices(); -} - -DeviceManager::~DeviceManager(void) { - { - TelldusCore::MutexLocker deviceListLocker(&d->lock); - for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { - {TelldusCore::MutexLocker deviceLocker(it->second);} //aquire lock, and release it, just to see that the device it's not in use anywhere - delete(it->second); - } - for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { - {TelldusCore::MutexLocker sensorLocker(*it);} //aquire lock, and release it, just to see that the device it's not in use anywhere - delete(*it); - } - } - delete d; -} - -void DeviceManager::fillDevices(){ - int numberOfDevices = d->set.getNumberOfNodes(Settings::Device); - TelldusCore::MutexLocker deviceListLocker(&d->lock); - - for (int i = 0; i < numberOfDevices; ++i) { - int id = d->set.getNodeId(Settings::Device, i); - d->devices[id] = new Device(id); - d->devices[id]->setName(d->set.getName(Settings::Device, id)); - d->devices[id]->setModel(d->set.getModel(id)); - d->devices[id]->setProtocolName(d->set.getProtocol(id)); - d->devices[id]->setPreferredControllerId(d->set.getPreferredControllerId(id)); - d->devices[id]->setLastSentCommand(d->set.getDeviceState(id), d->set.getDeviceStateValue(id)); - d->devices[id]->setParameter(L"house", d->set.getDeviceParameter(id, L"house")); - d->devices[id]->setParameter(L"unit", d->set.getDeviceParameter(id, L"unit")); - d->devices[id]->setParameter(L"code", d->set.getDeviceParameter(id, L"code")); - d->devices[id]->setParameter(L"units", d->set.getDeviceParameter(id, L"units")); - d->devices[id]->setParameter(L"fade", d->set.getDeviceParameter(id, L"fade")); - d->devices[id]->setParameter(L"system", d->set.getDeviceParameter(id, L"system")); - d->devices[id]->setParameter(L"devices", d->set.getDeviceParameter(id, L"devices")); - } -} - -int DeviceManager::getDeviceLastSentCommand(int deviceId, int methodsSupported){ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getLastSentCommand(methodsSupported); - } - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; -} - -int DeviceManager::setDeviceLastSentCommand(int deviceId, int command, const std::wstring &value) -{ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - d->set.setDeviceState(deviceId, command,value); - it->second->setLastSentCommand(command, value); - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - return TELLSTICK_SUCCESS; -} - -std::wstring DeviceManager::getDeviceStateValue(int deviceId){ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return L"UNKNOWN"; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getStateValue(); - } - return L"UNKNOWN"; -} - -int DeviceManager::getDeviceMethods(int deviceId, int methodsSupported) { - return Device::maskUnsupportedMethods(DeviceManager::getDeviceMethods(deviceId), methodsSupported); -} - -int DeviceManager::getDeviceMethods(int deviceId) { - std::set duplicateDeviceIds; - return DeviceManager::getDeviceMethods(deviceId, duplicateDeviceIds); -} - -int DeviceManager::getDeviceMethods(int deviceId, std::set &duplicateDeviceIds){ - int type = 0; - int methods = 0; - std::wstring deviceIds; - std::wstring protocol; - - { - //devices locked - TelldusCore::MutexLocker deviceListLocker(&d->lock); - - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - - { - TelldusCore::MutexLocker deviceLocker(it->second); - type = it->second->getType(); - methods = it->second->getMethods(); - deviceIds = it->second->getParameter(L"devices"); - protocol = it->second->getProtocolName(); - } - } - } - if(type == 0){ - return 0; - } - if(type == TELLSTICK_TYPE_GROUP){ - - //get all methods that some device in the groups supports - std::wstring deviceIdBuffer; - std::wstringstream devicesstream(deviceIds); - methods = 0; - - duplicateDeviceIds.insert(deviceId); - - while(std::getline(devicesstream, deviceIdBuffer, L',')){ - int deviceIdInGroup = TelldusCore::wideToInteger(deviceIdBuffer); - if(duplicateDeviceIds.count(deviceIdInGroup) == 1){ - //action for device already executed, or will execute, do nothing to avoid infinite loop - continue; - } - - duplicateDeviceIds.insert(deviceIdInGroup); - - int deviceMethods = getDeviceMethods(deviceIdInGroup, duplicateDeviceIds); - if(deviceMethods > 0){ - methods |= deviceMethods; - } - } - } - return methods; -} - -std::wstring DeviceManager::getDeviceModel(int deviceId){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return L"UNKNOWN"; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getModel(); - } - return L"UNKNOWN"; -} - -int DeviceManager::setDeviceModel(int deviceId, const std::wstring &model) -{ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - int ret = d->set.setModel(deviceId, model); - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - it->second->setModel(model); - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - return TELLSTICK_SUCCESS; -} - -std::wstring DeviceManager::getDeviceName(int deviceId){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return L"UNKNOWN"; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getName(); - } - return L"UNKNOWN"; -} - -int DeviceManager::setDeviceName(int deviceId, const std::wstring &name){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - int ret = d->set.setName(Settings::Device, deviceId, name); - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - it->second->setName(name); - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - return TELLSTICK_SUCCESS; -} - -std::wstring DeviceManager::getDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &defaultValue){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return defaultValue; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()){ - TelldusCore::MutexLocker deviceLocker(it->second); - std::wstring returnString = it->second->getParameter(name); - if(returnString != L""){ - return returnString; - } - } - return defaultValue; -} - -int DeviceManager::setDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &value) -{ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - int ret = d->set.setDeviceParameter(deviceId, name, value); - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - it->second->setParameter(name, value); - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - return TELLSTICK_SUCCESS; -} - -std::wstring DeviceManager::getDeviceProtocol(int deviceId){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return L"UNKNOWN"; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getProtocolName(); - } - return L"UNKNOWN"; -} - -int DeviceManager::setDeviceProtocol(int deviceId, const std::wstring &protocol) -{ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - int ret = d->set.setProtocol(deviceId, protocol); - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - it->second->setProtocolName(protocol); - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - return TELLSTICK_SUCCESS; -} - -int DeviceManager::getNumberOfDevices(){ - TelldusCore::MutexLocker deviceListLocker(&d->lock); - return (int)d->devices.size(); -} - -int DeviceManager::addDevice(){ - - int id = d->set.addNode(Settings::Device); - if(id < 0){ - return id; - } - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - d->devices[id] = new Device(id); - if(!d->devices[id]){ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - return id; -} - -int DeviceManager::getDeviceId(int deviceIndex) { - return d->set.getNodeId(Settings::Device, deviceIndex); -} - -int DeviceManager::getDeviceType(int deviceId){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getType(); - } - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; -} - -int DeviceManager::getPreferredControllerId(int deviceId){ - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - TelldusCore::MutexLocker deviceLocker(it->second); - return it->second->getPreferredControllerId(); - } - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; -} - -void DeviceManager::connectTellStickController(int vid, int pid, const std::string &serial){ - d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, true); -} - -void DeviceManager::disconnectTellStickController(int vid, int pid, const std::string &serial){ - d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, false); -} - -int DeviceManager::doAction(int deviceId, int action, unsigned char data){ - Device *device = 0; - //On the stack and will be released if we have a device lock. - std::auto_ptr deviceLocker(0); - { - //devicelist locked - TelldusCore::MutexLocker deviceListLocker(&d->lock); - - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it == d->devices.end()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; //not found - } - //device locked - deviceLocker = std::auto_ptr(new TelldusCore::MutexLocker(it->second)); - device = it->second; - } //devicelist unlocked - - int retval = TELLSTICK_ERROR_UNKNOWN; - - if(device->getType() == TELLSTICK_TYPE_GROUP || device->getType() == TELLSTICK_TYPE_SCENE){ - std::wstring devices = device->getParameter(L"devices"); - deviceLocker = std::auto_ptr(0); - std::set *duplicateDeviceIds = new std::set; - retval = doGroupAction(devices, action, data, device->getType(), deviceId, duplicateDeviceIds); - delete duplicateDeviceIds; - - { - //reaquire device lock, make sure it still exists - //devicelist locked - TelldusCore::MutexLocker deviceListLocker(&d->lock); - - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it == d->devices.end()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; //not found - } - //device locked - deviceLocker = std::auto_ptr(new TelldusCore::MutexLocker(it->second)); - device = it->second; - } //devicelist unlocked - } - else{ - Controller *controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); - if(!controller){ - Log::warning("Trying to execute action, but no controller found. Rescanning USB ports"); - //no controller found, scan for one, and retry once - d->controllerManager->loadControllers(); - controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); - } - - if(controller){ - retval = device->doAction(action, data, controller); - if(retval == TELLSTICK_ERROR_BROKEN_PIPE){ - Log::warning("Error in communication with TellStick when executing action. Resetting USB"); - d->controllerManager->resetController(controller); - } - if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND){ - Log::warning("Rescanning USB ports"); - d->controllerManager->loadControllers(); - controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); - if(!controller){ - Log::error("No contoller (TellStick) found, even after reset. Giving up."); - return TELLSTICK_ERROR_NOT_FOUND; - } - retval = device->doAction(action, data, controller); //retry one more time - } - } else { - Log::error("No contoller (TellStick) found after one retry. Giving up."); - return TELLSTICK_ERROR_NOT_FOUND; - } - } - if(retval == TELLSTICK_SUCCESS && device->getType() != TELLSTICK_TYPE_SCENE && device->getMethods() & action) { - //if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state - std::wstring datastring = TelldusCore::charUnsignedToWstring(data); - if (this->triggerDeviceStateChange(deviceId, action, datastring)) { - device->setLastSentCommand(action, datastring); - d->set.setDeviceState(deviceId, action, datastring); - } - } - return retval; -} - -int DeviceManager::doGroupAction(const std::wstring devices, const int action, const unsigned char data, const int type, const int groupDeviceId, std::set *duplicateDeviceIds){ - int retval = TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; - std::wstring singledevice; - std::wstringstream devicesstream(devices); - - duplicateDeviceIds->insert(groupDeviceId); - - while(std::getline(devicesstream, singledevice, L',')){ - - int deviceId = TelldusCore::wideToInteger(singledevice); - - if(duplicateDeviceIds->count(deviceId) == 1){ - //action for device already executed, or will execute, do nothing to avoid infinite loop - continue; - } - - duplicateDeviceIds->insert(deviceId); - - int deviceReturnValue = TELLSTICK_SUCCESS; - - if(type == TELLSTICK_TYPE_SCENE && (action == TELLSTICK_TURNON || action == TELLSTICK_EXECUTE)){ - deviceReturnValue = executeScene(singledevice, groupDeviceId); - } - else if(type == TELLSTICK_TYPE_GROUP){ - if(deviceId != 0){ - int childType = DeviceManager::getDeviceType(deviceId); - if(childType == TELLSTICK_TYPE_DEVICE){ - deviceReturnValue = doAction(deviceId, action, data); - } - else if(childType == TELLSTICK_TYPE_SCENE){ - deviceReturnValue = doGroupAction(DeviceManager::getDeviceParameter(deviceId, L"devices", L""), action, data, childType, deviceId, duplicateDeviceIds); //TODO make scenes infinite loops-safe - } - else{ - //group (in group) - deviceReturnValue = doGroupAction(DeviceManager::getDeviceParameter(deviceId, L"devices", L""), action, data, childType, deviceId, duplicateDeviceIds); - - if(deviceReturnValue == TELLSTICK_SUCCESS) { - std::wstring datastring = TelldusCore::charUnsignedToWstring(data); - if (this->triggerDeviceStateChange(deviceId, action, datastring)) { - DeviceManager::setDeviceLastSentCommand(deviceId, action, datastring); - d->set.setDeviceState(deviceId, action, datastring); - } - } - } - } - else{ - deviceReturnValue = TELLSTICK_ERROR_DEVICE_NOT_FOUND; //Probably incorrectly formatted parameter - } - } - - if(deviceReturnValue != TELLSTICK_ERROR_METHOD_NOT_SUPPORTED){ - //if error(s), return the last error, but still try to continue the action with the other devices - //if the error is a method not supported we igore is since there might be others supporting it - //If no devices support the method the default value will be returned (method not supported) - retval = deviceReturnValue; - } - - } - return retval; -} - -int DeviceManager::executeScene(std::wstring singledevice, int groupDeviceId){ - - std::wstringstream devicestream(singledevice); - - const int deviceParameterLength = 3; - std::wstring deviceParts[deviceParameterLength] = {L"", L"", L""}; - std::wstring devicePart = L""; - int i = 0; - while(std::getline(devicestream, devicePart, L':') && i < deviceParameterLength){ - deviceParts[i] = devicePart; - i++; - } - - if(deviceParts[0] == L"" || deviceParts[1] == L""){ - return TELLSTICK_ERROR_UNKNOWN; //malformed or missing parameter - } - - int deviceId = TelldusCore::wideToInteger(deviceParts[0]); - if(deviceId == groupDeviceId){ - return TELLSTICK_ERROR_UNKNOWN; //the scene itself has been added to its devices, avoid infinite loop - } - int method = Device::methodId(TelldusCore::wideToString(deviceParts[1])); //support methodparts both in the form of integers (e.g. TELLSTICK_TURNON) or text (e.g. "turnon") - if(method == 0){ - method = TelldusCore::wideToInteger(deviceParts[1]); - } - unsigned char devicedata = 0; - if(deviceParts[2] != L""){ - devicedata = TelldusCore::wideToInteger(deviceParts[2]); - } - - if(deviceId > 0 && method > 0){ //check for format error in parameter "devices" - return doAction(deviceId, method, devicedata); - } - - return TELLSTICK_ERROR_UNKNOWN; -} - -int DeviceManager::removeDevice(int deviceId){ - - Device *device = 0; - { - int ret = d->set.removeNode(Settings::Device, deviceId); //remove from register/settings - if (ret != TELLSTICK_SUCCESS) { - return ret; - } - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - if (!d->devices.size()) { - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - DeviceMap::iterator it = d->devices.find(deviceId); - if (it != d->devices.end()) { - device = it->second; - d->devices.erase(it); //remove from list, keep reference - } - else{ - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - } - {TelldusCore::MutexLocker lock(device);} //waiting for device lock, if it's aquired, just unlock again. Device is removed from list, and cannot be accessed from anywhere else - delete device; - - return TELLSTICK_SUCCESS; -} - -std::wstring DeviceManager::getSensors() const { - TelldusCore::MutexLocker sensorListLocker(&d->lock); - - TelldusCore::Message msg; - - msg.addArgument((int)d->sensorList.size()); - - for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { - TelldusCore::MutexLocker sensorLocker(*it); - msg.addArgument((*it)->protocol()); - msg.addArgument((*it)->model()); - msg.addArgument((*it)->id()); - msg.addArgument((*it)->dataTypes()); - } - - return msg; -} - -std::wstring DeviceManager::getSensorValue(const std::wstring &protocol, const std::wstring &model, int id, int dataType) const { - TelldusCore::MutexLocker sensorListLocker(&d->lock); - Sensor *sensor = 0; - for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { - TelldusCore::MutexLocker sensorLocker(*it); - if (!TelldusCore::comparei((*it)->protocol(), protocol)) { - continue; - } - if (!TelldusCore::comparei((*it)->model(), model)) { - continue; - } - if ((*it)->id() != id) { - continue; - } - sensor = *it; - break; - } - - if (!sensor) { - return L""; - } - TelldusCore::MutexLocker sensorLocker(sensor); - TelldusCore::Message msg; - std::string value = sensor->value(dataType); - if (value.length() > 0) { - msg.addArgument(TelldusCore::charToWstring(value.c_str())); - msg.addArgument((int)sensor->timestamp()); - } - return msg; -} - - -void DeviceManager::handleControllerMessage(const ControllerEventData &eventData) { - //Trigger raw-event - EventUpdateData *eventUpdateData = new EventUpdateData(); - eventUpdateData->messageType = L"TDRawDeviceEvent"; - eventUpdateData->controllerId = eventData.controllerId; - eventUpdateData->eventValue = TelldusCore::charToWstring(eventData.msg.c_str()); - d->deviceUpdateEvent->signal(eventUpdateData); - - ControllerMessage msg(eventData.msg); - if (msg.msgClass().compare("sensor") == 0) { - handleSensorMessage(msg); - return; - } - - TelldusCore::MutexLocker deviceListLocker(&d->lock); - for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { - TelldusCore::MutexLocker deviceLocker(it->second); - if (!TelldusCore::comparei(it->second->getProtocolName(), msg.protocol())) { - continue; - } - if (! (it->second->getMethods() & msg.method())) { - continue; - } - - std::list parameters = it->second->getParametersForProtocol(); - bool thisDevice = true; - for (std::list::iterator paramIt = parameters.begin(); paramIt != parameters.end(); ++paramIt){ - if(!TelldusCore::comparei(it->second->getParameter(TelldusCore::charToWstring((*paramIt).c_str())), TelldusCore::charToWstring(msg.getParameter(*paramIt).c_str()))){ - thisDevice = false; - break; - } - } - - if(!thisDevice){ - continue; - } - - if (this->triggerDeviceStateChange(it->first, msg.method(), L"")) { - d->set.setDeviceState(it->first, msg.method(), L""); - it->second->setLastSentCommand(msg.method(), L""); - } - } -} - -void DeviceManager::handleSensorMessage(const ControllerMessage &msg) { - TelldusCore::MutexLocker sensorListLocker(&d->lock); - Sensor *sensor = 0; - for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { - TelldusCore::MutexLocker sensorLocker(*it); - if (!TelldusCore::comparei((*it)->protocol(), msg.protocol())) { - continue; - } - if (!TelldusCore::comparei((*it)->model(), msg.model())) { - continue; - } - if ((*it)->id() != msg.getIntParameter("id")) { - continue; - } - sensor = *it; - break; - } - - if (!sensor) { - sensor = new Sensor(msg.protocol(), msg.model(), msg.getIntParameter("id")); - d->sensorList.push_back(sensor); - } - TelldusCore::MutexLocker sensorLocker(sensor); - - time_t t = time(NULL); - - setSensorValueAndSignal("temp", TELLSTICK_TEMPERATURE, sensor, msg, t); - setSensorValueAndSignal("humidity", TELLSTICK_HUMIDITY, sensor, msg, t); -} - -void DeviceManager::setSensorValueAndSignal( const std::string &dataType, int dataTypeId, Sensor *sensor, const ControllerMessage &msg, time_t timestamp) const { - if (!msg.hasParameter(dataType)) { - return; - } - sensor->setValue(dataTypeId, msg.getParameter(dataType), timestamp); - - EventUpdateData *eventData = new EventUpdateData(); - eventData->messageType = L"TDSensorEvent"; - eventData->protocol = sensor->protocol(); - eventData->model = sensor->model(); - eventData->sensorId = sensor->id(); - eventData->dataType = dataTypeId; - eventData->value = TelldusCore::charToWstring(sensor->value(dataTypeId).c_str()); - eventData->timestamp = (int)timestamp; - d->deviceUpdateEvent->signal(eventData); -} - -int DeviceManager::sendRawCommand(const std::wstring &command, int reserved){ - - Controller *controller = d->controllerManager->getBestControllerById(-1); - - if(!controller){ - //no controller found, scan for one, and retry once - d->controllerManager->loadControllers(); - controller = d->controllerManager->getBestControllerById(-1); - } - - int retval = TELLSTICK_ERROR_UNKNOWN; - if(controller){ - retval = controller->send(TelldusCore::wideToString(command)); - if(retval == TELLSTICK_ERROR_BROKEN_PIPE){ - d->controllerManager->resetController(controller); - } - if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND){ - d->controllerManager->loadControllers(); - controller = d->controllerManager->getBestControllerById(-1); - if(!controller){ - return TELLSTICK_ERROR_NOT_FOUND; - } - retval = controller->send(TelldusCore::wideToString(command)); //retry one more time - } - return retval; - } else { - return TELLSTICK_ERROR_NOT_FOUND; - } -} - -bool DeviceManager::triggerDeviceStateChange(int deviceId, int intDeviceState, const std::wstring &strDeviceStateValue ) { - if ( intDeviceState == TELLSTICK_BELL || intDeviceState == TELLSTICK_LEARN || intDeviceState == TELLSTICK_EXECUTE) { - return false; - } - - EventUpdateData *eventData = new EventUpdateData(); - eventData->messageType = L"TDDeviceEvent"; - eventData->eventState = intDeviceState; - eventData->deviceId = deviceId; - eventData->eventValue = strDeviceStateValue; - d->deviceUpdateEvent->signal(eventData); - return true; -} +#include "DeviceManager.h" +#include "ControllerMessage.h" +#include "Mutex.h" +#include "Sensor.h" +#include "Settings.h" +#include "Strings.h" +#include "Message.h" +#include "Log.h" + +#include +#include +#include +#include + +typedef std::map DeviceMap; + +class DeviceManager::PrivateData { +public: + DeviceMap devices; + std::list sensorList; + Settings set; + TelldusCore::Mutex lock; + ControllerManager *controllerManager; + TelldusCore::EventRef deviceUpdateEvent; +}; + +DeviceManager::DeviceManager(ControllerManager *controllerManager, TelldusCore::EventRef deviceUpdateEvent){ + d = new PrivateData; + d->controllerManager = controllerManager; + d->deviceUpdateEvent = deviceUpdateEvent; + fillDevices(); +} + +DeviceManager::~DeviceManager(void) { + { + TelldusCore::MutexLocker deviceListLocker(&d->lock); + for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { + {TelldusCore::MutexLocker deviceLocker(it->second);} //aquire lock, and release it, just to see that the device it's not in use anywhere + delete(it->second); + } + for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { + {TelldusCore::MutexLocker sensorLocker(*it);} //aquire lock, and release it, just to see that the device it's not in use anywhere + delete(*it); + } + } + delete d; +} + +void DeviceManager::fillDevices(){ + int numberOfDevices = d->set.getNumberOfNodes(Settings::Device); + TelldusCore::MutexLocker deviceListLocker(&d->lock); + + for (int i = 0; i < numberOfDevices; ++i) { + int id = d->set.getNodeId(Settings::Device, i); + d->devices[id] = new Device(id); + d->devices[id]->setName(d->set.getName(Settings::Device, id)); + d->devices[id]->setModel(d->set.getModel(id)); + d->devices[id]->setProtocolName(d->set.getProtocol(id)); + d->devices[id]->setPreferredControllerId(d->set.getPreferredControllerId(id)); + d->devices[id]->setLastSentCommand(d->set.getDeviceState(id), d->set.getDeviceStateValue(id)); + d->devices[id]->setParameter(L"house", d->set.getDeviceParameter(id, L"house")); + d->devices[id]->setParameter(L"unit", d->set.getDeviceParameter(id, L"unit")); + d->devices[id]->setParameter(L"code", d->set.getDeviceParameter(id, L"code")); + d->devices[id]->setParameter(L"units", d->set.getDeviceParameter(id, L"units")); + d->devices[id]->setParameter(L"fade", d->set.getDeviceParameter(id, L"fade")); + d->devices[id]->setParameter(L"system", d->set.getDeviceParameter(id, L"system")); + d->devices[id]->setParameter(L"devices", d->set.getDeviceParameter(id, L"devices")); + } +} + +int DeviceManager::getDeviceLastSentCommand(int deviceId, int methodsSupported){ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getLastSentCommand(methodsSupported); + } + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; +} + +int DeviceManager::setDeviceLastSentCommand(int deviceId, int command, const std::wstring &value) +{ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + d->set.setDeviceState(deviceId, command,value); + it->second->setLastSentCommand(command, value); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + return TELLSTICK_SUCCESS; +} + +std::wstring DeviceManager::getDeviceStateValue(int deviceId){ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return L"UNKNOWN"; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getStateValue(); + } + return L"UNKNOWN"; +} + +int DeviceManager::getDeviceMethods(int deviceId, int methodsSupported) { + return Device::maskUnsupportedMethods(DeviceManager::getDeviceMethods(deviceId), methodsSupported); +} + +int DeviceManager::getDeviceMethods(int deviceId) { + std::set duplicateDeviceIds; + return DeviceManager::getDeviceMethods(deviceId, duplicateDeviceIds); +} + +int DeviceManager::getDeviceMethods(int deviceId, std::set &duplicateDeviceIds){ + int type = 0; + int methods = 0; + std::wstring deviceIds; + std::wstring protocol; + + { + //devices locked + TelldusCore::MutexLocker deviceListLocker(&d->lock); + + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + + { + TelldusCore::MutexLocker deviceLocker(it->second); + type = it->second->getType(); + methods = it->second->getMethods(); + deviceIds = it->second->getParameter(L"devices"); + protocol = it->second->getProtocolName(); + } + } + } + if(type == 0){ + return 0; + } + if(type == TELLSTICK_TYPE_GROUP){ + + //get all methods that some device in the groups supports + std::wstring deviceIdBuffer; + std::wstringstream devicesstream(deviceIds); + methods = 0; + + duplicateDeviceIds.insert(deviceId); + + while(std::getline(devicesstream, deviceIdBuffer, L',')){ + int deviceIdInGroup = TelldusCore::wideToInteger(deviceIdBuffer); + if(duplicateDeviceIds.count(deviceIdInGroup) == 1){ + //action for device already executed, or will execute, do nothing to avoid infinite loop + continue; + } + + duplicateDeviceIds.insert(deviceIdInGroup); + + int deviceMethods = getDeviceMethods(deviceIdInGroup, duplicateDeviceIds); + if(deviceMethods > 0){ + methods |= deviceMethods; + } + } + } + return methods; +} + +std::wstring DeviceManager::getDeviceModel(int deviceId){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return L"UNKNOWN"; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getModel(); + } + return L"UNKNOWN"; +} + +int DeviceManager::setDeviceModel(int deviceId, const std::wstring &model) +{ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + int ret = d->set.setModel(deviceId, model); + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + it->second->setModel(model); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + return TELLSTICK_SUCCESS; +} + +std::wstring DeviceManager::getDeviceName(int deviceId){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return L"UNKNOWN"; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getName(); + } + return L"UNKNOWN"; +} + +int DeviceManager::setDeviceName(int deviceId, const std::wstring &name){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + int ret = d->set.setName(Settings::Device, deviceId, name); + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + it->second->setName(name); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + return TELLSTICK_SUCCESS; +} + +std::wstring DeviceManager::getDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &defaultValue){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return defaultValue; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()){ + TelldusCore::MutexLocker deviceLocker(it->second); + std::wstring returnString = it->second->getParameter(name); + if(returnString != L""){ + return returnString; + } + } + return defaultValue; +} + +int DeviceManager::setDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &value) +{ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + int ret = d->set.setDeviceParameter(deviceId, name, value); + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + it->second->setParameter(name, value); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + return TELLSTICK_SUCCESS; +} + +std::wstring DeviceManager::getDeviceProtocol(int deviceId){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return L"UNKNOWN"; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getProtocolName(); + } + return L"UNKNOWN"; +} + +int DeviceManager::setDeviceProtocol(int deviceId, const std::wstring &protocol) +{ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + int ret = d->set.setProtocol(deviceId, protocol); + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + it->second->setProtocolName(protocol); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + return TELLSTICK_SUCCESS; +} + +int DeviceManager::getNumberOfDevices(){ + TelldusCore::MutexLocker deviceListLocker(&d->lock); + return (int)d->devices.size(); +} + +int DeviceManager::addDevice(){ + + int id = d->set.addNode(Settings::Device); + if(id < 0){ + return id; + } + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + d->devices[id] = new Device(id); + if(!d->devices[id]){ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + return id; +} + +int DeviceManager::getDeviceId(int deviceIndex) { + return d->set.getNodeId(Settings::Device, deviceIndex); +} + +int DeviceManager::getDeviceType(int deviceId){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getType(); + } + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; +} + +int DeviceManager::getPreferredControllerId(int deviceId){ + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + TelldusCore::MutexLocker deviceLocker(it->second); + return it->second->getPreferredControllerId(); + } + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; +} + +void DeviceManager::connectTellStickController(int vid, int pid, const std::string &serial){ + d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, true); +} + +void DeviceManager::disconnectTellStickController(int vid, int pid, const std::string &serial){ + d->controllerManager->deviceInsertedOrRemoved(vid, pid, serial, false); +} + +int DeviceManager::doAction(int deviceId, int action, unsigned char data){ + Device *device = 0; + //On the stack and will be released if we have a device lock. + std::auto_ptr deviceLocker(0); + { + //devicelist locked + TelldusCore::MutexLocker deviceListLocker(&d->lock); + + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it == d->devices.end()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; //not found + } + //device locked + deviceLocker = std::auto_ptr(new TelldusCore::MutexLocker(it->second)); + device = it->second; + } //devicelist unlocked + + int retval = TELLSTICK_ERROR_UNKNOWN; + + if(device->getType() == TELLSTICK_TYPE_GROUP || device->getType() == TELLSTICK_TYPE_SCENE){ + std::wstring devices = device->getParameter(L"devices"); + deviceLocker = std::auto_ptr(0); + std::set *duplicateDeviceIds = new std::set; + retval = doGroupAction(devices, action, data, device->getType(), deviceId, duplicateDeviceIds); + delete duplicateDeviceIds; + + { + //reaquire device lock, make sure it still exists + //devicelist locked + TelldusCore::MutexLocker deviceListLocker(&d->lock); + + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it == d->devices.end()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; //not found + } + //device locked + deviceLocker = std::auto_ptr(new TelldusCore::MutexLocker(it->second)); + device = it->second; + } //devicelist unlocked + } + else{ + Controller *controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); + if(!controller){ + Log::warning("Trying to execute action, but no controller found. Rescanning USB ports"); + //no controller found, scan for one, and retry once + d->controllerManager->loadControllers(); + controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); + } + + if(controller){ + retval = device->doAction(action, data, controller); + if(retval == TELLSTICK_ERROR_BROKEN_PIPE){ + Log::warning("Error in communication with TellStick when executing action. Resetting USB"); + d->controllerManager->resetController(controller); + } + if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND){ + Log::warning("Rescanning USB ports"); + d->controllerManager->loadControllers(); + controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); + if(!controller){ + Log::error("No contoller (TellStick) found, even after reset. Giving up."); + return TELLSTICK_ERROR_NOT_FOUND; + } + retval = device->doAction(action, data, controller); //retry one more time + } + } else { + Log::error("No contoller (TellStick) found after one retry. Giving up."); + return TELLSTICK_ERROR_NOT_FOUND; + } + } + if(retval == TELLSTICK_SUCCESS && device->getType() != TELLSTICK_TYPE_SCENE && device->getMethods() & action) { + //if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state + std::wstring datastring = TelldusCore::charUnsignedToWstring(data); + if (this->triggerDeviceStateChange(deviceId, action, datastring)) { + device->setLastSentCommand(action, datastring); + d->set.setDeviceState(deviceId, action, datastring); + } + } + return retval; +} + +int DeviceManager::doGroupAction(const std::wstring devices, const int action, const unsigned char data, const int type, const int groupDeviceId, std::set *duplicateDeviceIds){ + int retval = TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; + std::wstring singledevice; + std::wstringstream devicesstream(devices); + + duplicateDeviceIds->insert(groupDeviceId); + + while(std::getline(devicesstream, singledevice, L',')){ + + int deviceId = TelldusCore::wideToInteger(singledevice); + + if(duplicateDeviceIds->count(deviceId) == 1){ + //action for device already executed, or will execute, do nothing to avoid infinite loop + continue; + } + + duplicateDeviceIds->insert(deviceId); + + int deviceReturnValue = TELLSTICK_SUCCESS; + + if(type == TELLSTICK_TYPE_SCENE && (action == TELLSTICK_TURNON || action == TELLSTICK_EXECUTE)){ + deviceReturnValue = executeScene(singledevice, groupDeviceId); + } + else if(type == TELLSTICK_TYPE_GROUP){ + if(deviceId != 0){ + int childType = DeviceManager::getDeviceType(deviceId); + if(childType == TELLSTICK_TYPE_DEVICE){ + deviceReturnValue = doAction(deviceId, action, data); + } + else if(childType == TELLSTICK_TYPE_SCENE){ + deviceReturnValue = doGroupAction(DeviceManager::getDeviceParameter(deviceId, L"devices", L""), action, data, childType, deviceId, duplicateDeviceIds); //TODO make scenes infinite loops-safe + } + else{ + //group (in group) + deviceReturnValue = doGroupAction(DeviceManager::getDeviceParameter(deviceId, L"devices", L""), action, data, childType, deviceId, duplicateDeviceIds); + + if(deviceReturnValue == TELLSTICK_SUCCESS) { + std::wstring datastring = TelldusCore::charUnsignedToWstring(data); + if (this->triggerDeviceStateChange(deviceId, action, datastring)) { + DeviceManager::setDeviceLastSentCommand(deviceId, action, datastring); + d->set.setDeviceState(deviceId, action, datastring); + } + } + } + } + else{ + deviceReturnValue = TELLSTICK_ERROR_DEVICE_NOT_FOUND; //Probably incorrectly formatted parameter + } + } + + if(deviceReturnValue != TELLSTICK_ERROR_METHOD_NOT_SUPPORTED){ + //if error(s), return the last error, but still try to continue the action with the other devices + //if the error is a method not supported we igore is since there might be others supporting it + //If no devices support the method the default value will be returned (method not supported) + retval = deviceReturnValue; + } + + } + return retval; +} + +int DeviceManager::executeScene(std::wstring singledevice, int groupDeviceId){ + + std::wstringstream devicestream(singledevice); + + const int deviceParameterLength = 3; + std::wstring deviceParts[deviceParameterLength] = {L"", L"", L""}; + std::wstring devicePart = L""; + int i = 0; + while(std::getline(devicestream, devicePart, L':') && i < deviceParameterLength){ + deviceParts[i] = devicePart; + i++; + } + + if(deviceParts[0] == L"" || deviceParts[1] == L""){ + return TELLSTICK_ERROR_UNKNOWN; //malformed or missing parameter + } + + int deviceId = TelldusCore::wideToInteger(deviceParts[0]); + if(deviceId == groupDeviceId){ + return TELLSTICK_ERROR_UNKNOWN; //the scene itself has been added to its devices, avoid infinite loop + } + int method = Device::methodId(TelldusCore::wideToString(deviceParts[1])); //support methodparts both in the form of integers (e.g. TELLSTICK_TURNON) or text (e.g. "turnon") + if(method == 0){ + method = TelldusCore::wideToInteger(deviceParts[1]); + } + unsigned char devicedata = 0; + if(deviceParts[2] != L""){ + devicedata = TelldusCore::wideToInteger(deviceParts[2]); + } + + if(deviceId > 0 && method > 0){ //check for format error in parameter "devices" + return doAction(deviceId, method, devicedata); + } + + return TELLSTICK_ERROR_UNKNOWN; +} + +int DeviceManager::removeDevice(int deviceId){ + + Device *device = 0; + { + int ret = d->set.removeNode(Settings::Device, deviceId); //remove from register/settings + if (ret != TELLSTICK_SUCCESS) { + return ret; + } + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + device = it->second; + d->devices.erase(it); //remove from list, keep reference + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + } + {TelldusCore::MutexLocker lock(device);} //waiting for device lock, if it's aquired, just unlock again. Device is removed from list, and cannot be accessed from anywhere else + delete device; + + return TELLSTICK_SUCCESS; +} + +std::wstring DeviceManager::getSensors() const { + TelldusCore::MutexLocker sensorListLocker(&d->lock); + + TelldusCore::Message msg; + + msg.addArgument((int)d->sensorList.size()); + + for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { + TelldusCore::MutexLocker sensorLocker(*it); + msg.addArgument((*it)->protocol()); + msg.addArgument((*it)->model()); + msg.addArgument((*it)->id()); + msg.addArgument((*it)->dataTypes()); + } + + return msg; +} + +std::wstring DeviceManager::getSensorValue(const std::wstring &protocol, const std::wstring &model, int id, int dataType) const { + TelldusCore::MutexLocker sensorListLocker(&d->lock); + Sensor *sensor = 0; + for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { + TelldusCore::MutexLocker sensorLocker(*it); + if (!TelldusCore::comparei((*it)->protocol(), protocol)) { + continue; + } + if (!TelldusCore::comparei((*it)->model(), model)) { + continue; + } + if ((*it)->id() != id) { + continue; + } + sensor = *it; + break; + } + + if (!sensor) { + return L""; + } + TelldusCore::MutexLocker sensorLocker(sensor); + TelldusCore::Message msg; + std::string value = sensor->value(dataType); + if (value.length() > 0) { + msg.addArgument(TelldusCore::charToWstring(value.c_str())); + msg.addArgument((int)sensor->timestamp()); + } + return msg; +} + + +void DeviceManager::handleControllerMessage(const ControllerEventData &eventData) { + //Trigger raw-event + EventUpdateData *eventUpdateData = new EventUpdateData(); + eventUpdateData->messageType = L"TDRawDeviceEvent"; + eventUpdateData->controllerId = eventData.controllerId; + eventUpdateData->eventValue = TelldusCore::charToWstring(eventData.msg.c_str()); + d->deviceUpdateEvent->signal(eventUpdateData); + + ControllerMessage msg(eventData.msg); + if (msg.msgClass().compare("sensor") == 0) { + handleSensorMessage(msg); + return; + } + + TelldusCore::MutexLocker deviceListLocker(&d->lock); + for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { + TelldusCore::MutexLocker deviceLocker(it->second); + if (!TelldusCore::comparei(it->second->getProtocolName(), msg.protocol())) { + continue; + } + if (! (it->second->getMethods() & msg.method())) { + continue; + } + + std::list parameters = it->second->getParametersForProtocol(); + bool thisDevice = true; + for (std::list::iterator paramIt = parameters.begin(); paramIt != parameters.end(); ++paramIt){ + if(!TelldusCore::comparei(it->second->getParameter(TelldusCore::charToWstring((*paramIt).c_str())), TelldusCore::charToWstring(msg.getParameter(*paramIt).c_str()))){ + thisDevice = false; + break; + } + } + + if(!thisDevice){ + continue; + } + + if (this->triggerDeviceStateChange(it->first, msg.method(), L"")) { + d->set.setDeviceState(it->first, msg.method(), L""); + it->second->setLastSentCommand(msg.method(), L""); + } + } +} + +void DeviceManager::handleSensorMessage(const ControllerMessage &msg) { + TelldusCore::MutexLocker sensorListLocker(&d->lock); + Sensor *sensor = 0; + for (std::list::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { + TelldusCore::MutexLocker sensorLocker(*it); + if (!TelldusCore::comparei((*it)->protocol(), msg.protocol())) { + continue; + } + if (!TelldusCore::comparei((*it)->model(), msg.model())) { + continue; + } + if ((*it)->id() != msg.getIntParameter("id")) { + continue; + } + sensor = *it; + break; + } + + if (!sensor) { + sensor = new Sensor(msg.protocol(), msg.model(), msg.getIntParameter("id")); + d->sensorList.push_back(sensor); + } + TelldusCore::MutexLocker sensorLocker(sensor); + + time_t t = time(NULL); + + setSensorValueAndSignal("temp", TELLSTICK_TEMPERATURE, sensor, msg, t); + setSensorValueAndSignal("humidity", TELLSTICK_HUMIDITY, sensor, msg, t); +} + +void DeviceManager::setSensorValueAndSignal( const std::string &dataType, int dataTypeId, Sensor *sensor, const ControllerMessage &msg, time_t timestamp) const { + if (!msg.hasParameter(dataType)) { + return; + } + sensor->setValue(dataTypeId, msg.getParameter(dataType), timestamp); + + EventUpdateData *eventData = new EventUpdateData(); + eventData->messageType = L"TDSensorEvent"; + eventData->protocol = sensor->protocol(); + eventData->model = sensor->model(); + eventData->sensorId = sensor->id(); + eventData->dataType = dataTypeId; + eventData->value = TelldusCore::charToWstring(sensor->value(dataTypeId).c_str()); + eventData->timestamp = (int)timestamp; + d->deviceUpdateEvent->signal(eventData); +} + +int DeviceManager::sendRawCommand(const std::wstring &command, int reserved){ + + Controller *controller = d->controllerManager->getBestControllerById(-1); + + if(!controller){ + //no controller found, scan for one, and retry once + d->controllerManager->loadControllers(); + controller = d->controllerManager->getBestControllerById(-1); + } + + int retval = TELLSTICK_ERROR_UNKNOWN; + if(controller){ + retval = controller->send(TelldusCore::wideToString(command)); + if(retval == TELLSTICK_ERROR_BROKEN_PIPE){ + d->controllerManager->resetController(controller); + } + if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND){ + d->controllerManager->loadControllers(); + controller = d->controllerManager->getBestControllerById(-1); + if(!controller){ + return TELLSTICK_ERROR_NOT_FOUND; + } + retval = controller->send(TelldusCore::wideToString(command)); //retry one more time + } + return retval; + } else { + return TELLSTICK_ERROR_NOT_FOUND; + } +} + +bool DeviceManager::triggerDeviceStateChange(int deviceId, int intDeviceState, const std::wstring &strDeviceStateValue ) { + if ( intDeviceState == TELLSTICK_BELL || intDeviceState == TELLSTICK_LEARN || intDeviceState == TELLSTICK_EXECUTE) { + return false; + } + + EventUpdateData *eventData = new EventUpdateData(); + eventData->messageType = L"TDDeviceEvent"; + eventData->eventState = intDeviceState; + eventData->deviceId = deviceId; + eventData->eventValue = strDeviceStateValue; + d->deviceUpdateEvent->signal(eventData); + return true; +} diff --git a/telldus-core/service/EventUpdateManager.cpp b/telldus-core/service/EventUpdateManager.cpp index 82263bbc..52fef5be 100644 --- a/telldus-core/service/EventUpdateManager.cpp +++ b/telldus-core/service/EventUpdateManager.cpp @@ -1,126 +1,126 @@ -#include "EventUpdateManager.h" - -#include "ConnectionListener.h" -#include "EventHandler.h" -#include "Message.h" -#include "Socket.h" - -#include -#include - -typedef std::list SocketList; - -class EventUpdateManager::PrivateData { -public: - TelldusCore::EventHandler eventHandler; - TelldusCore::EventRef stopEvent, updateEvent, clientConnectEvent; - SocketList clients; - ConnectionListener *eventUpdateClientListener; -}; - -EventUpdateManager::EventUpdateManager() - :Thread() -{ - d = new PrivateData; - d->stopEvent = d->eventHandler.addEvent(); - d->updateEvent = d->eventHandler.addEvent(); - d->clientConnectEvent = d->eventHandler.addEvent(); - d->eventUpdateClientListener = new ConnectionListener(L"TelldusEvents", d->clientConnectEvent); -} - -EventUpdateManager::~EventUpdateManager(void) { - d->stopEvent->signal(); - wait(); - delete d->eventUpdateClientListener; - - for (SocketList::iterator it = d->clients.begin(); it != d->clients.end(); ++it) { - delete(*it); - } - - delete d; -} - -TelldusCore::EventRef EventUpdateManager::retrieveUpdateEvent(){ - - return d->updateEvent; -} - -void EventUpdateManager::run(){ - - while(!d->stopEvent->isSignaled()){ - if (!d->eventHandler.waitForAny()) { - continue; - } - - if(d->clientConnectEvent->isSignaled()){ - //new client added - TelldusCore::EventDataRef eventData = d->clientConnectEvent->takeSignal(); - ConnectionListenerEventData *data = reinterpret_cast(eventData.get()); - if(data){ - d->clients.push_back(data->socket); - } - } - else if(d->updateEvent->isSignaled()){ - //device event, signal all clients - TelldusCore::EventDataRef eventData = d->updateEvent->takeSignal(); - EventUpdateData *data = reinterpret_cast(eventData.get()); - if(data){ - sendMessageToClients(data); - } - } - } -} - -void EventUpdateManager::sendMessageToClients(EventUpdateData *data){ - - int connected = 0; - for(SocketList::iterator it = d->clients.begin(); it != d->clients.end();){ - if((*it)->isConnected()){ - connected++; - TelldusCore::Message msg; - - if(data->messageType == L"TDDeviceEvent"){ - msg.addArgument("TDDeviceEvent"); - msg.addArgument(data->deviceId); - msg.addArgument(data->eventState); - msg.addArgument(data->eventValue); //string - } - else if(data->messageType == L"TDDeviceChangeEvent"){ - msg.addArgument("TDDeviceChangeEvent"); - msg.addArgument(data->deviceId); - msg.addArgument(data->eventDeviceChanges); - msg.addArgument(data->eventChangeType); - } - else if(data->messageType == L"TDRawDeviceEvent"){ - msg.addArgument("TDRawDeviceEvent"); - msg.addArgument(data->eventValue); //string - msg.addArgument(data->controllerId); - } - else if(data->messageType == L"TDSensorEvent"){ - msg.addArgument("TDSensorEvent"); - msg.addArgument(data->protocol); - msg.addArgument(data->model); - msg.addArgument(data->sensorId); - msg.addArgument(data->dataType); - msg.addArgument(data->value); - msg.addArgument(data->timestamp); - } - else if(data->messageType == L"TDControllerEvent") { - msg.addArgument("TDControllerEvent"); - msg.addArgument(data->controllerId); - msg.addArgument(data->eventState); - msg.addArgument(data->eventChangeType); - msg.addArgument(data->eventValue); - } - - (*it)->write(msg); - - it++; - } - else{ - //connection is dead, remove it - delete *it; - it = d->clients.erase(it); - } - } -} +#include "EventUpdateManager.h" + +#include "ConnectionListener.h" +#include "EventHandler.h" +#include "Message.h" +#include "Socket.h" + +#include +#include + +typedef std::list SocketList; + +class EventUpdateManager::PrivateData { +public: + TelldusCore::EventHandler eventHandler; + TelldusCore::EventRef stopEvent, updateEvent, clientConnectEvent; + SocketList clients; + ConnectionListener *eventUpdateClientListener; +}; + +EventUpdateManager::EventUpdateManager() + :Thread() +{ + d = new PrivateData; + d->stopEvent = d->eventHandler.addEvent(); + d->updateEvent = d->eventHandler.addEvent(); + d->clientConnectEvent = d->eventHandler.addEvent(); + d->eventUpdateClientListener = new ConnectionListener(L"TelldusEvents", d->clientConnectEvent); +} + +EventUpdateManager::~EventUpdateManager(void) { + d->stopEvent->signal(); + wait(); + delete d->eventUpdateClientListener; + + for (SocketList::iterator it = d->clients.begin(); it != d->clients.end(); ++it) { + delete(*it); + } + + delete d; +} + +TelldusCore::EventRef EventUpdateManager::retrieveUpdateEvent(){ + + return d->updateEvent; +} + +void EventUpdateManager::run(){ + + while(!d->stopEvent->isSignaled()){ + if (!d->eventHandler.waitForAny()) { + continue; + } + + if(d->clientConnectEvent->isSignaled()){ + //new client added + TelldusCore::EventDataRef eventData = d->clientConnectEvent->takeSignal(); + ConnectionListenerEventData *data = reinterpret_cast(eventData.get()); + if(data){ + d->clients.push_back(data->socket); + } + } + else if(d->updateEvent->isSignaled()){ + //device event, signal all clients + TelldusCore::EventDataRef eventData = d->updateEvent->takeSignal(); + EventUpdateData *data = reinterpret_cast(eventData.get()); + if(data){ + sendMessageToClients(data); + } + } + } +} + +void EventUpdateManager::sendMessageToClients(EventUpdateData *data){ + + int connected = 0; + for(SocketList::iterator it = d->clients.begin(); it != d->clients.end();){ + if((*it)->isConnected()){ + connected++; + TelldusCore::Message msg; + + if(data->messageType == L"TDDeviceEvent"){ + msg.addArgument("TDDeviceEvent"); + msg.addArgument(data->deviceId); + msg.addArgument(data->eventState); + msg.addArgument(data->eventValue); //string + } + else if(data->messageType == L"TDDeviceChangeEvent"){ + msg.addArgument("TDDeviceChangeEvent"); + msg.addArgument(data->deviceId); + msg.addArgument(data->eventDeviceChanges); + msg.addArgument(data->eventChangeType); + } + else if(data->messageType == L"TDRawDeviceEvent"){ + msg.addArgument("TDRawDeviceEvent"); + msg.addArgument(data->eventValue); //string + msg.addArgument(data->controllerId); + } + else if(data->messageType == L"TDSensorEvent"){ + msg.addArgument("TDSensorEvent"); + msg.addArgument(data->protocol); + msg.addArgument(data->model); + msg.addArgument(data->sensorId); + msg.addArgument(data->dataType); + msg.addArgument(data->value); + msg.addArgument(data->timestamp); + } + else if(data->messageType == L"TDControllerEvent") { + msg.addArgument("TDControllerEvent"); + msg.addArgument(data->controllerId); + msg.addArgument(data->eventState); + msg.addArgument(data->eventChangeType); + msg.addArgument(data->eventValue); + } + + (*it)->write(msg); + + it++; + } + else{ + //connection is dead, remove it + delete *it; + it = d->clients.erase(it); + } + } +} diff --git a/telldus-core/service/Log.cpp b/telldus-core/service/Log.cpp index eef21e59..a4e5cf2f 100644 --- a/telldus-core/service/Log.cpp +++ b/telldus-core/service/Log.cpp @@ -1,181 +1,181 @@ -#include "Log.h" -#include - -#if defined(_LINUX) -#include -#elif defined(_WINDOWS) -#include -#include "Strings.h" -#include "Messages.h" -#endif - -class Log::PrivateData { -public: - PrivateData() : logOutput(Log::System), debug(false) {} - - Log::LogOutput logOutput; - bool debug; - - static Log *instance; -#ifdef _WINDOWS - HANDLE eventSource; -#endif -}; - -Log *Log::PrivateData::instance = 0; - -Log::Log() - :d(new PrivateData) -{ -#if defined(_LINUX) - setlogmask(LOG_UPTO(LOG_INFO)); - openlog("telldusd", LOG_CONS, LOG_USER); -#elif defined(_MACOSX) - d->logOutput = Log::StdOut; -#elif defined(_WINDOWS) - //Add ourselves to the registy - HKEY hRegKey = NULL; - DWORD dwError = 0; - TCHAR filePath[MAX_PATH]; - - std::wstring path(L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\TelldusService"); - dwError = RegCreateKey( HKEY_LOCAL_MACHINE, path.c_str(), &hRegKey ); - - GetModuleFileName( NULL, filePath, MAX_PATH ); - dwError = RegSetValueEx( hRegKey, L"EventMessageFile", 0, - REG_EXPAND_SZ, (PBYTE) filePath, - (DWORD)(wcslen(filePath) + 1) * sizeof TCHAR ); - - DWORD dwTypes = LOG_DEBUG | LOG_NOTICE | LOG_WARNING | LOG_ERR; - dwError = RegSetValueEx( hRegKey, L"TypesSupported", - 0, REG_DWORD, (LPBYTE) &dwTypes, sizeof dwTypes ); - - RegCloseKey(hRegKey); - - d->eventSource = RegisterEventSource(NULL, L"TelldusService"); -#endif -} - -Log::~Log() { -#if defined(_LINUX) - closelog(); -#elif defined(_WINDOWS) - if (d->eventSource != NULL) { - DeregisterEventSource(d->eventSource); - } -#endif - delete d; -} - -void Log::destroy() { - if (PrivateData::instance == 0) { - return; - } - delete PrivateData::instance; - PrivateData::instance = 0; -} - -void Log::debug(const char *fmt, ...) { - Log *log = Log::instance(); - va_list ap; - va_start(ap, fmt); - log->message(Debug, fmt, ap); - va_end(ap); -} - -void Log::notice(const char *fmt, ...) { - Log *log = Log::instance(); - va_list ap; - va_start(ap, fmt); - log->message(Notice, fmt, ap); - va_end(ap); -} - -void Log::warning(const char *fmt, ...) { - Log *log = Log::instance(); - va_list ap; - va_start(ap, fmt); - log->message(Warning, fmt, ap); - va_end(ap); -} - -void Log::error(const char *fmt, ...) { - Log *log = Log::instance(); - va_list ap; - va_start(ap, fmt); - log->message(Error, fmt, ap); - va_end(ap); -} - -void Log::setDebug() { - Log *log = Log::instance(); - log->d->debug = true; - Log::debug("Debug message output enabled"); -} - -void Log::setLogOutput(LogOutput logOutput) { -#ifdef _MACOSX - //Always stdout - return; -#endif - Log *log = Log::instance(); - log->d->logOutput = logOutput; -} - -void Log::message(Log::LogLevel logLevel, const char *format, va_list ap) const { - if (logLevel == Debug && d->debug == false) { - return; - } - if (d->logOutput == StdOut) { - FILE *stream = stdout; - if (logLevel == Warning || logLevel == Error) { - stream = stderr; - } - vfprintf(stream, format, ap); - fprintf(stream, "\n"); - fflush(stream); - } else { -#if defined(_LINUX) - switch (logLevel) { - case Debug: - vsyslog(LOG_DEBUG, format, ap); - break; - case Notice: - vsyslog(LOG_NOTICE, format, ap); - break; - case Warning: - vsyslog(LOG_WARNING, format, ap); - break; - case Error: - vsyslog(LOG_ERR, format, ap); - break; - } -#elif defined(_WINDOWS) - LPWSTR pInsertStrings[2] = {NULL, NULL}; - std::wstring str = TelldusCore::charToWstring(TelldusCore::sformatf(format, ap).c_str()); - pInsertStrings[0] = (LPWSTR)str.c_str(); - - switch (logLevel) { - case Debug: - ReportEvent(d->eventSource, EVENTLOG_SUCCESS, NULL, LOG_DEBUG, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); - break; - case Notice: - ReportEvent(d->eventSource, EVENTLOG_INFORMATION_TYPE, NULL, LOG_NOTICE, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); - break; - case Warning: - ReportEvent(d->eventSource, EVENTLOG_WARNING_TYPE, NULL, LOG_WARNING, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); - break; - case Error: - ReportEvent(d->eventSource, EVENTLOG_ERROR_TYPE, NULL, LOG_ERR, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); - break; - } -#endif - } -} - -Log *Log::instance() { - if (PrivateData::instance == 0) { - PrivateData::instance = new Log(); - } - return PrivateData::instance; -} +#include "Log.h" +#include + +#if defined(_LINUX) +#include +#elif defined(_WINDOWS) +#include +#include "Strings.h" +#include "Messages.h" +#endif + +class Log::PrivateData { +public: + PrivateData() : logOutput(Log::System), debug(false) {} + + Log::LogOutput logOutput; + bool debug; + + static Log *instance; +#ifdef _WINDOWS + HANDLE eventSource; +#endif +}; + +Log *Log::PrivateData::instance = 0; + +Log::Log() + :d(new PrivateData) +{ +#if defined(_LINUX) + setlogmask(LOG_UPTO(LOG_INFO)); + openlog("telldusd", LOG_CONS, LOG_USER); +#elif defined(_MACOSX) + d->logOutput = Log::StdOut; +#elif defined(_WINDOWS) + //Add ourselves to the registy + HKEY hRegKey = NULL; + DWORD dwError = 0; + TCHAR filePath[MAX_PATH]; + + std::wstring path(L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\TelldusService"); + dwError = RegCreateKey( HKEY_LOCAL_MACHINE, path.c_str(), &hRegKey ); + + GetModuleFileName( NULL, filePath, MAX_PATH ); + dwError = RegSetValueEx( hRegKey, L"EventMessageFile", 0, + REG_EXPAND_SZ, (PBYTE) filePath, + (DWORD)(wcslen(filePath) + 1) * sizeof TCHAR ); + + DWORD dwTypes = LOG_DEBUG | LOG_NOTICE | LOG_WARNING | LOG_ERR; + dwError = RegSetValueEx( hRegKey, L"TypesSupported", + 0, REG_DWORD, (LPBYTE) &dwTypes, sizeof dwTypes ); + + RegCloseKey(hRegKey); + + d->eventSource = RegisterEventSource(NULL, L"TelldusService"); +#endif +} + +Log::~Log() { +#if defined(_LINUX) + closelog(); +#elif defined(_WINDOWS) + if (d->eventSource != NULL) { + DeregisterEventSource(d->eventSource); + } +#endif + delete d; +} + +void Log::destroy() { + if (PrivateData::instance == 0) { + return; + } + delete PrivateData::instance; + PrivateData::instance = 0; +} + +void Log::debug(const char *fmt, ...) { + Log *log = Log::instance(); + va_list ap; + va_start(ap, fmt); + log->message(Debug, fmt, ap); + va_end(ap); +} + +void Log::notice(const char *fmt, ...) { + Log *log = Log::instance(); + va_list ap; + va_start(ap, fmt); + log->message(Notice, fmt, ap); + va_end(ap); +} + +void Log::warning(const char *fmt, ...) { + Log *log = Log::instance(); + va_list ap; + va_start(ap, fmt); + log->message(Warning, fmt, ap); + va_end(ap); +} + +void Log::error(const char *fmt, ...) { + Log *log = Log::instance(); + va_list ap; + va_start(ap, fmt); + log->message(Error, fmt, ap); + va_end(ap); +} + +void Log::setDebug() { + Log *log = Log::instance(); + log->d->debug = true; + Log::debug("Debug message output enabled"); +} + +void Log::setLogOutput(LogOutput logOutput) { +#ifdef _MACOSX + //Always stdout + return; +#endif + Log *log = Log::instance(); + log->d->logOutput = logOutput; +} + +void Log::message(Log::LogLevel logLevel, const char *format, va_list ap) const { + if (logLevel == Debug && d->debug == false) { + return; + } + if (d->logOutput == StdOut) { + FILE *stream = stdout; + if (logLevel == Warning || logLevel == Error) { + stream = stderr; + } + vfprintf(stream, format, ap); + fprintf(stream, "\n"); + fflush(stream); + } else { +#if defined(_LINUX) + switch (logLevel) { + case Debug: + vsyslog(LOG_DEBUG, format, ap); + break; + case Notice: + vsyslog(LOG_NOTICE, format, ap); + break; + case Warning: + vsyslog(LOG_WARNING, format, ap); + break; + case Error: + vsyslog(LOG_ERR, format, ap); + break; + } +#elif defined(_WINDOWS) + LPWSTR pInsertStrings[2] = {NULL, NULL}; + std::wstring str = TelldusCore::charToWstring(TelldusCore::sformatf(format, ap).c_str()); + pInsertStrings[0] = (LPWSTR)str.c_str(); + + switch (logLevel) { + case Debug: + ReportEvent(d->eventSource, EVENTLOG_SUCCESS, NULL, LOG_DEBUG, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); + break; + case Notice: + ReportEvent(d->eventSource, EVENTLOG_INFORMATION_TYPE, NULL, LOG_NOTICE, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); + break; + case Warning: + ReportEvent(d->eventSource, EVENTLOG_WARNING_TYPE, NULL, LOG_WARNING, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); + break; + case Error: + ReportEvent(d->eventSource, EVENTLOG_ERROR_TYPE, NULL, LOG_ERR, NULL, 1, 0, (LPCWSTR*)pInsertStrings, NULL); + break; + } +#endif + } +} + +Log *Log::instance() { + if (PrivateData::instance == 0) { + PrivateData::instance = new Log(); + } + return PrivateData::instance; +} diff --git a/telldus-core/service/Protocol.cpp b/telldus-core/service/Protocol.cpp index 0a2be23c..67a66e2f 100644 --- a/telldus-core/service/Protocol.cpp +++ b/telldus-core/service/Protocol.cpp @@ -1,263 +1,263 @@ -#include "Protocol.h" -#include "../client/telldus-core.h" - -#include "ControllerMessage.h" -#include "ProtocolBrateck.h" -#include "ProtocolComen.h" -#include "ProtocolEverflourish.h" -#include "ProtocolFineoffset.h" -#include "ProtocolFuhaote.h" -#include "ProtocolGroup.h" -#include "ProtocolHasta.h" -#include "ProtocolIkea.h" -#include "ProtocolMandolyn.h" -#include "ProtocolNexa.h" -#include "ProtocolOregon.h" -#include "ProtocolRisingSun.h" -#include "ProtocolSartano.h" -#include "ProtocolScene.h" -#include "ProtocolSilvanChip.h" -#include "ProtocolUpm.h" -#include "ProtocolWaveman.h" -#include "ProtocolX10.h" -#include "ProtocolYidong.h" - -#include "Strings.h" -#include - -class Protocol::PrivateData { -public: - ParameterMap parameterList; - std::wstring model; -}; - -Protocol::Protocol(){ - - d = new PrivateData; -} - -Protocol::~Protocol(void) { - delete d; -} - -std::wstring Protocol::model() const { - std::wstring strModel = d->model; - //Strip anything after : if it is found - size_t pos = strModel.find(L":"); - if (pos != std::wstring::npos) { - strModel = strModel.substr(0, pos); - } - - return strModel; -} - -void Protocol::setModel(const std::wstring &model){ - d->model = model; -} - -void Protocol::setParameters(ParameterMap ¶meterList){ - d->parameterList = parameterList; -} - -std::wstring Protocol::getStringParameter(const std::wstring &name, const std::wstring &defaultValue) const { - ParameterMap::const_iterator it = d->parameterList.find(name); - if (it == d->parameterList.end()) { - return defaultValue; - } - return it->second; -} - -int Protocol::getIntParameter(const std::wstring &name, int min, int max) const { - std::wstring value = getStringParameter(name, L""); - if (value == L"") { - return min; - } - std::wstringstream st; - st << value; - int intValue = 0; - st >> intValue; - if (intValue < min) { - return min; - } - if (intValue > max) { - return max; - } - return intValue; -} - -bool Protocol::checkBit(int data, int bitno) { - return ((data>>bitno)&0x01); -} - - -Protocol *Protocol::getProtocolInstance(const std::wstring &protocolname){ - - if(TelldusCore::comparei(protocolname, L"arctech")){ - return new ProtocolNexa(); - - } else if (TelldusCore::comparei(protocolname, L"brateck")) { - return new ProtocolBrateck(); - - } else if (TelldusCore::comparei(protocolname, L"comen")) { - return new ProtocolComen(); - - } else if (TelldusCore::comparei(protocolname, L"everflourish")) { - return new ProtocolEverflourish(); - - } else if (TelldusCore::comparei(protocolname, L"fuhaote")) { - return new ProtocolFuhaote(); - - } else if (TelldusCore::comparei(protocolname, L"hasta")) { - return new ProtocolHasta(); - - } else if (TelldusCore::comparei(protocolname, L"ikea")) { - return new ProtocolIkea(); - - } else if (TelldusCore::comparei(protocolname, L"risingsun")) { - return new ProtocolRisingSun(); - - } else if (TelldusCore::comparei(protocolname, L"sartano")) { - return new ProtocolSartano(); - - } else if (TelldusCore::comparei(protocolname, L"silvanchip")) { - return new ProtocolSilvanChip(); - - } else if (TelldusCore::comparei(protocolname, L"upm")) { - return new ProtocolUpm(); - - } else if (TelldusCore::comparei(protocolname, L"waveman")) { - return new ProtocolWaveman(); - - } else if (TelldusCore::comparei(protocolname, L"x10")) { - return new ProtocolX10(); - - } else if (TelldusCore::comparei(protocolname, L"yidong")) { - return new ProtocolYidong(); - - } else if (TelldusCore::comparei(protocolname, L"group")) { - return new ProtocolGroup(); - } - - else if (TelldusCore::comparei(protocolname, L"scene")) { - return new ProtocolScene(); - } - - return 0; -} - -std::list Protocol::getParametersForProtocol(const std::wstring &protocolName) { - std::list parameters; - if(TelldusCore::comparei(protocolName, L"arctech")){ - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"brateck")) { - parameters.push_back("house"); - - } else if (TelldusCore::comparei(protocolName, L"comen")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"everflourish")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"fuhaote")) { - parameters.push_back("code"); - - } else if (TelldusCore::comparei(protocolName, L"hasta")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"ikea")) { - parameters.push_back("system"); - parameters.push_back("units"); - //parameters.push_back("fade"); - - } else if (TelldusCore::comparei(protocolName, L"risingsun")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"sartano")) { - parameters.push_back("code"); - - } else if (TelldusCore::comparei(protocolName, L"silvanchip")) { - parameters.push_back("house"); - - } else if (TelldusCore::comparei(protocolName, L"upm")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"waveman")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"x10")) { - parameters.push_back("house"); - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"yidong")) { - parameters.push_back("unit"); - - } else if (TelldusCore::comparei(protocolName, L"group")) { - parameters.push_back("devices"); - - } else if (TelldusCore::comparei(protocolName, L"scene")) { - parameters.push_back("devices"); - } - - return parameters; -} - -std::list Protocol::decodeData(const std::string &fullData) { - std::list retval; - std::string decoded = ""; - - ControllerMessage dataMsg(fullData); - if( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) { - decoded = ProtocolNexa::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - decoded = ProtocolWaveman::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - decoded = ProtocolSartano::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - else if(TelldusCore::comparei(dataMsg.protocol(), L"everflourish") ) { - decoded = ProtocolEverflourish::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - else if(TelldusCore::comparei(dataMsg.protocol(), L"fineoffset") ) { - decoded = ProtocolFineoffset::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - else if(TelldusCore::comparei(dataMsg.protocol(), L"mandolyn") ) { - decoded = ProtocolMandolyn::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - else if(TelldusCore::comparei(dataMsg.protocol(), L"oregon") ) { - decoded = ProtocolOregon::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - else if(TelldusCore::comparei(dataMsg.protocol(), L"x10") ) { - decoded = ProtocolX10::decodeData(dataMsg); - if (decoded != "") { - retval.push_back(decoded); - } - } - - return retval; -} +#include "Protocol.h" +#include "../client/telldus-core.h" + +#include "ControllerMessage.h" +#include "ProtocolBrateck.h" +#include "ProtocolComen.h" +#include "ProtocolEverflourish.h" +#include "ProtocolFineoffset.h" +#include "ProtocolFuhaote.h" +#include "ProtocolGroup.h" +#include "ProtocolHasta.h" +#include "ProtocolIkea.h" +#include "ProtocolMandolyn.h" +#include "ProtocolNexa.h" +#include "ProtocolOregon.h" +#include "ProtocolRisingSun.h" +#include "ProtocolSartano.h" +#include "ProtocolScene.h" +#include "ProtocolSilvanChip.h" +#include "ProtocolUpm.h" +#include "ProtocolWaveman.h" +#include "ProtocolX10.h" +#include "ProtocolYidong.h" + +#include "Strings.h" +#include + +class Protocol::PrivateData { +public: + ParameterMap parameterList; + std::wstring model; +}; + +Protocol::Protocol(){ + + d = new PrivateData; +} + +Protocol::~Protocol(void) { + delete d; +} + +std::wstring Protocol::model() const { + std::wstring strModel = d->model; + //Strip anything after : if it is found + size_t pos = strModel.find(L":"); + if (pos != std::wstring::npos) { + strModel = strModel.substr(0, pos); + } + + return strModel; +} + +void Protocol::setModel(const std::wstring &model){ + d->model = model; +} + +void Protocol::setParameters(ParameterMap ¶meterList){ + d->parameterList = parameterList; +} + +std::wstring Protocol::getStringParameter(const std::wstring &name, const std::wstring &defaultValue) const { + ParameterMap::const_iterator it = d->parameterList.find(name); + if (it == d->parameterList.end()) { + return defaultValue; + } + return it->second; +} + +int Protocol::getIntParameter(const std::wstring &name, int min, int max) const { + std::wstring value = getStringParameter(name, L""); + if (value == L"") { + return min; + } + std::wstringstream st; + st << value; + int intValue = 0; + st >> intValue; + if (intValue < min) { + return min; + } + if (intValue > max) { + return max; + } + return intValue; +} + +bool Protocol::checkBit(int data, int bitno) { + return ((data>>bitno)&0x01); +} + + +Protocol *Protocol::getProtocolInstance(const std::wstring &protocolname){ + + if(TelldusCore::comparei(protocolname, L"arctech")){ + return new ProtocolNexa(); + + } else if (TelldusCore::comparei(protocolname, L"brateck")) { + return new ProtocolBrateck(); + + } else if (TelldusCore::comparei(protocolname, L"comen")) { + return new ProtocolComen(); + + } else if (TelldusCore::comparei(protocolname, L"everflourish")) { + return new ProtocolEverflourish(); + + } else if (TelldusCore::comparei(protocolname, L"fuhaote")) { + return new ProtocolFuhaote(); + + } else if (TelldusCore::comparei(protocolname, L"hasta")) { + return new ProtocolHasta(); + + } else if (TelldusCore::comparei(protocolname, L"ikea")) { + return new ProtocolIkea(); + + } else if (TelldusCore::comparei(protocolname, L"risingsun")) { + return new ProtocolRisingSun(); + + } else if (TelldusCore::comparei(protocolname, L"sartano")) { + return new ProtocolSartano(); + + } else if (TelldusCore::comparei(protocolname, L"silvanchip")) { + return new ProtocolSilvanChip(); + + } else if (TelldusCore::comparei(protocolname, L"upm")) { + return new ProtocolUpm(); + + } else if (TelldusCore::comparei(protocolname, L"waveman")) { + return new ProtocolWaveman(); + + } else if (TelldusCore::comparei(protocolname, L"x10")) { + return new ProtocolX10(); + + } else if (TelldusCore::comparei(protocolname, L"yidong")) { + return new ProtocolYidong(); + + } else if (TelldusCore::comparei(protocolname, L"group")) { + return new ProtocolGroup(); + } + + else if (TelldusCore::comparei(protocolname, L"scene")) { + return new ProtocolScene(); + } + + return 0; +} + +std::list Protocol::getParametersForProtocol(const std::wstring &protocolName) { + std::list parameters; + if(TelldusCore::comparei(protocolName, L"arctech")){ + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"brateck")) { + parameters.push_back("house"); + + } else if (TelldusCore::comparei(protocolName, L"comen")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"everflourish")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"fuhaote")) { + parameters.push_back("code"); + + } else if (TelldusCore::comparei(protocolName, L"hasta")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"ikea")) { + parameters.push_back("system"); + parameters.push_back("units"); + //parameters.push_back("fade"); + + } else if (TelldusCore::comparei(protocolName, L"risingsun")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"sartano")) { + parameters.push_back("code"); + + } else if (TelldusCore::comparei(protocolName, L"silvanchip")) { + parameters.push_back("house"); + + } else if (TelldusCore::comparei(protocolName, L"upm")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"waveman")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"x10")) { + parameters.push_back("house"); + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"yidong")) { + parameters.push_back("unit"); + + } else if (TelldusCore::comparei(protocolName, L"group")) { + parameters.push_back("devices"); + + } else if (TelldusCore::comparei(protocolName, L"scene")) { + parameters.push_back("devices"); + } + + return parameters; +} + +std::list Protocol::decodeData(const std::string &fullData) { + std::list retval; + std::string decoded = ""; + + ControllerMessage dataMsg(fullData); + if( TelldusCore::comparei(dataMsg.protocol(), L"arctech") ) { + decoded = ProtocolNexa::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + decoded = ProtocolWaveman::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + decoded = ProtocolSartano::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + else if(TelldusCore::comparei(dataMsg.protocol(), L"everflourish") ) { + decoded = ProtocolEverflourish::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + else if(TelldusCore::comparei(dataMsg.protocol(), L"fineoffset") ) { + decoded = ProtocolFineoffset::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + else if(TelldusCore::comparei(dataMsg.protocol(), L"mandolyn") ) { + decoded = ProtocolMandolyn::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + else if(TelldusCore::comparei(dataMsg.protocol(), L"oregon") ) { + decoded = ProtocolOregon::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + else if(TelldusCore::comparei(dataMsg.protocol(), L"x10") ) { + decoded = ProtocolX10::decodeData(dataMsg); + if (decoded != "") { + retval.push_back(decoded); + } + } + + return retval; +} diff --git a/telldus-core/service/Protocol.h b/telldus-core/service/Protocol.h index 6168f8d6..bfcce857 100644 --- a/telldus-core/service/Protocol.h +++ b/telldus-core/service/Protocol.h @@ -1,41 +1,41 @@ -#ifndef PROTOCOL_H -#define PROTOCOL_H - -#include -#include -#include -#include "../client/telldus-core.h" - -typedef std::map ParameterMap; - -class Controller; - -class Protocol -{ -public: - Protocol(); - virtual ~Protocol(void); - - static Protocol *getProtocolInstance(const std::wstring &protocolname); - static std::list getParametersForProtocol(const std::wstring &protocolName); - static std::list decodeData(const std::string &fullData); - - virtual int methods() const = 0; - std::wstring model() const; - void setModel(const std::wstring &model); - void setParameters(ParameterMap ¶meterList); - - virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller) = 0; - -protected: - std::wstring getStringParameter(const std::wstring &name, const std::wstring &defaultValue = L"") const; - int getIntParameter(const std::wstring &name, int min, int max) const; - - static bool checkBit(int data, int bit); - -private: - class PrivateData; - PrivateData *d; -}; - -#endif //PROTOCOL_H +#ifndef PROTOCOL_H +#define PROTOCOL_H + +#include +#include +#include +#include "../client/telldus-core.h" + +typedef std::map ParameterMap; + +class Controller; + +class Protocol +{ +public: + Protocol(); + virtual ~Protocol(void); + + static Protocol *getProtocolInstance(const std::wstring &protocolname); + static std::list getParametersForProtocol(const std::wstring &protocolName); + static std::list decodeData(const std::string &fullData); + + virtual int methods() const = 0; + std::wstring model() const; + void setModel(const std::wstring &model); + void setParameters(ParameterMap ¶meterList); + + virtual std::string getStringForMethod(int method, unsigned char data, Controller *controller) = 0; + +protected: + std::wstring getStringParameter(const std::wstring &name, const std::wstring &defaultValue = L"") const; + int getIntParameter(const std::wstring &name, int min, int max) const; + + static bool checkBit(int data, int bit); + +private: + class PrivateData; + PrivateData *d; +}; + +#endif //PROTOCOL_H diff --git a/telldus-core/service/ProtocolBrateck.cpp b/telldus-core/service/ProtocolBrateck.cpp index 2f01531e..da9e222e 100644 --- a/telldus-core/service/ProtocolBrateck.cpp +++ b/telldus-core/service/ProtocolBrateck.cpp @@ -1,46 +1,46 @@ -#include "ProtocolBrateck.h" - -int ProtocolBrateck::methods() const { - return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; -} - -std::string ProtocolBrateck::getStringForMethod(int method, unsigned char, Controller *) { - const char S = '!'; - const char L = 'V'; - const char B1[] = {L,S,L,S,0}; - const char BX[] = {S,L,L,S,0}; - const char B0[] = {S,L,S,L,0}; - const char BUP[] = {L,S,L,S,S,L,S,L,S,L,S,L,S,L,S,L,S,0}; - const char BSTOP[] = {S,L,S,L,L,S,L,S,S,L,S,L,S,L,S,L,S,0}; - const char BDOWN[] = {S,L,S,L,S,L,S,L,S,L,S,L,L,S,L,S,S,0}; - - std::string strReturn; - std::wstring strHouse = this->getStringParameter(L"house", L""); - if (strHouse == L"") { - return ""; - } - - for( size_t i = 0; i < strHouse.length(); ++i ) { - if (strHouse[i] == '1') { - strReturn.insert(0, B1); - } else if (strHouse[i] == '-') { - strReturn.insert(0, BX); - } else if (strHouse[i] == '0') { - strReturn.insert(0, B0); - } - } - - strReturn.insert(0, "S"); - if (method == TELLSTICK_UP) { - strReturn.append(BUP); - } else if (method == TELLSTICK_DOWN) { - strReturn.append(BDOWN); - } else if (method == TELLSTICK_STOP) { - strReturn.append(BSTOP); - } else { - return ""; - } - strReturn.append("+"); - - return strReturn; -} +#include "ProtocolBrateck.h" + +int ProtocolBrateck::methods() const { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; +} + +std::string ProtocolBrateck::getStringForMethod(int method, unsigned char, Controller *) { + const char S = '!'; + const char L = 'V'; + const char B1[] = {L,S,L,S,0}; + const char BX[] = {S,L,L,S,0}; + const char B0[] = {S,L,S,L,0}; + const char BUP[] = {L,S,L,S,S,L,S,L,S,L,S,L,S,L,S,L,S,0}; + const char BSTOP[] = {S,L,S,L,L,S,L,S,S,L,S,L,S,L,S,L,S,0}; + const char BDOWN[] = {S,L,S,L,S,L,S,L,S,L,S,L,L,S,L,S,S,0}; + + std::string strReturn; + std::wstring strHouse = this->getStringParameter(L"house", L""); + if (strHouse == L"") { + return ""; + } + + for( size_t i = 0; i < strHouse.length(); ++i ) { + if (strHouse[i] == '1') { + strReturn.insert(0, B1); + } else if (strHouse[i] == '-') { + strReturn.insert(0, BX); + } else if (strHouse[i] == '0') { + strReturn.insert(0, B0); + } + } + + strReturn.insert(0, "S"); + if (method == TELLSTICK_UP) { + strReturn.append(BUP); + } else if (method == TELLSTICK_DOWN) { + strReturn.append(BDOWN); + } else if (method == TELLSTICK_STOP) { + strReturn.append(BSTOP); + } else { + return ""; + } + strReturn.append("+"); + + return strReturn; +} diff --git a/telldus-core/service/ProtocolComen.cpp b/telldus-core/service/ProtocolComen.cpp index cfaf99df..9fa36c64 100644 --- a/telldus-core/service/ProtocolComen.cpp +++ b/telldus-core/service/ProtocolComen.cpp @@ -1,12 +1,12 @@ -#include "ProtocolComen.h" - -int ProtocolComen::methods() const { - return (TELLSTICK_TURNON | TELLSTICK_TURNOFF); -} - -std::string ProtocolComen::getStringForMethod(int method, unsigned char level, Controller *) { - int intHouse = getIntParameter(L"house", 1, 33554431); - intHouse <<= 1; //They seem to only accept even codes? - int intCode = getIntParameter(L"unit", 1, 16)-1; - return getStringSelflearningForCode(intHouse, intCode, method, level); -} +#include "ProtocolComen.h" + +int ProtocolComen::methods() const { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF); +} + +std::string ProtocolComen::getStringForMethod(int method, unsigned char level, Controller *) { + int intHouse = getIntParameter(L"house", 1, 33554431); + intHouse <<= 1; //They seem to only accept even codes? + int intCode = getIntParameter(L"unit", 1, 16)-1; + return getStringSelflearningForCode(intHouse, intCode, method, level); +} diff --git a/telldus-core/service/ProtocolEverflourish.cpp b/telldus-core/service/ProtocolEverflourish.cpp index c74326fa..4738bb96 100644 --- a/telldus-core/service/ProtocolEverflourish.cpp +++ b/telldus-core/service/ProtocolEverflourish.cpp @@ -1,131 +1,131 @@ -#include "ProtocolEverflourish.h" -#include -#include -#include "ControllerMessage.h" - -int ProtocolEverflourish::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; -} - -std::string ProtocolEverflourish::getStringForMethod(int method, unsigned char, Controller *) { - unsigned int deviceCode = this->getIntParameter(L"house", 0, 16383); - unsigned int intCode = this->getIntParameter(L"unit", 1, 4)-1; - unsigned char action; - - if (method == TELLSTICK_TURNON) { - action = 15; - } else if (method == TELLSTICK_TURNOFF) { - action = 0; - } else if (method == TELLSTICK_LEARN) { - action = 10; - } else { - return ""; - } - - const char ssss = 85; - const char sssl = 84; // 0 - const char slss = 69; // 1 - - const char bits[2] = {sssl,slss}; - int i, check; - - std::string strCode; - - deviceCode = (deviceCode << 2) | intCode; - - check = calculateChecksum(deviceCode); - - char preamble[] = {'R', 5, 'T', 114,60,1,1,105,ssss,ssss,0}; - strCode.append(preamble); - - for(i=15;i>=0;i--) { - strCode.append(1, bits[(deviceCode>>i)&0x01]); - } - for(i=3;i>=0;i--) { - strCode.append(1, bits[(check>>i)&0x01]); - } - for(i=3;i>=0;i--) { - strCode.append(1, bits[(action>>i)&0x01]); - } - - strCode.append(1, ssss); - strCode.append(1, '+'); - - return strCode; -} - -// The calculation used in this function is provided by Frank Stevenson -unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) { - unsigned int bits[16] = { - 0xf ,0xa ,0x7 ,0xe, - 0xf ,0xd ,0x9 ,0x1, - 0x1 ,0x2 ,0x4 ,0x8, - 0x3 ,0x6 ,0xc ,0xb - }; - unsigned int bit = 1; - unsigned int res = 0x5; - int i; - unsigned int lo,hi; - - if ((x&0x3)==3) { - lo = x & 0x00ff; - hi = x & 0xff00; - lo += 4; - if (lo>0x100) { - lo = 0x12; - } - x = lo | hi; - } - - for(i=0;i<16;i++) { - if (x&bit) { - res = res ^ bits[i]; - } - bit = bit << 1; - } - - return res; -} - -std::string ProtocolEverflourish::decodeData(ControllerMessage &dataMsg) -{ - std::string data = dataMsg.getParameter("data"); - unsigned int allData; - unsigned int house = 0; - unsigned int unit = 0; - unsigned int method = 0; - - sscanf(data.c_str(), "%X", &allData); - - house = allData & 0xFFFC00; - house >>= 10; - - unit = allData & 0x300; - unit >>= 8; - unit++; //unit from 1 to 4 - - method = allData & 0xF; - - if(house < 0 || house > 16383 || unit < 1 || unit > 4){ - //not everflourish - return ""; - } - - std::stringstream retString; - retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:"; - if(method == 0){ - retString << "turnoff;"; - } - else if(method == 15){ - retString << "turnon;"; - } - else if(method == 10){ - retString << "learn;"; - } - else { - //not everflourish - return ""; - } - - return retString.str(); +#include "ProtocolEverflourish.h" +#include +#include +#include "ControllerMessage.h" + +int ProtocolEverflourish::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; +} + +std::string ProtocolEverflourish::getStringForMethod(int method, unsigned char, Controller *) { + unsigned int deviceCode = this->getIntParameter(L"house", 0, 16383); + unsigned int intCode = this->getIntParameter(L"unit", 1, 4)-1; + unsigned char action; + + if (method == TELLSTICK_TURNON) { + action = 15; + } else if (method == TELLSTICK_TURNOFF) { + action = 0; + } else if (method == TELLSTICK_LEARN) { + action = 10; + } else { + return ""; + } + + const char ssss = 85; + const char sssl = 84; // 0 + const char slss = 69; // 1 + + const char bits[2] = {sssl,slss}; + int i, check; + + std::string strCode; + + deviceCode = (deviceCode << 2) | intCode; + + check = calculateChecksum(deviceCode); + + char preamble[] = {'R', 5, 'T', 114,60,1,1,105,ssss,ssss,0}; + strCode.append(preamble); + + for(i=15;i>=0;i--) { + strCode.append(1, bits[(deviceCode>>i)&0x01]); + } + for(i=3;i>=0;i--) { + strCode.append(1, bits[(check>>i)&0x01]); + } + for(i=3;i>=0;i--) { + strCode.append(1, bits[(action>>i)&0x01]); + } + + strCode.append(1, ssss); + strCode.append(1, '+'); + + return strCode; +} + +// The calculation used in this function is provided by Frank Stevenson +unsigned int ProtocolEverflourish::calculateChecksum(unsigned int x) { + unsigned int bits[16] = { + 0xf ,0xa ,0x7 ,0xe, + 0xf ,0xd ,0x9 ,0x1, + 0x1 ,0x2 ,0x4 ,0x8, + 0x3 ,0x6 ,0xc ,0xb + }; + unsigned int bit = 1; + unsigned int res = 0x5; + int i; + unsigned int lo,hi; + + if ((x&0x3)==3) { + lo = x & 0x00ff; + hi = x & 0xff00; + lo += 4; + if (lo>0x100) { + lo = 0x12; + } + x = lo | hi; + } + + for(i=0;i<16;i++) { + if (x&bit) { + res = res ^ bits[i]; + } + bit = bit << 1; + } + + return res; +} + +std::string ProtocolEverflourish::decodeData(ControllerMessage &dataMsg) +{ + std::string data = dataMsg.getParameter("data"); + unsigned int allData; + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + sscanf(data.c_str(), "%X", &allData); + + house = allData & 0xFFFC00; + house >>= 10; + + unit = allData & 0x300; + unit >>= 8; + unit++; //unit from 1 to 4 + + method = allData & 0xF; + + if(house < 0 || house > 16383 || unit < 1 || unit > 4){ + //not everflourish + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:everflourish;model:selflearning;house:" << house << ";unit:" << unit << ";method:"; + if(method == 0){ + retString << "turnoff;"; + } + else if(method == 15){ + retString << "turnon;"; + } + else if(method == 10){ + retString << "learn;"; + } + else { + //not everflourish + return ""; + } + + return retString.str(); } \ No newline at end of file diff --git a/telldus-core/service/ProtocolFineoffset.cpp b/telldus-core/service/ProtocolFineoffset.cpp index 4ed310d0..3e4b444b 100644 --- a/telldus-core/service/ProtocolFineoffset.cpp +++ b/telldus-core/service/ProtocolFineoffset.cpp @@ -1,45 +1,45 @@ -#include "ProtocolFineoffset.h" -#include "Strings.h" -#include -#include -#include - -std::string ProtocolFineoffset::decodeData(ControllerMessage &dataMsg) -{ - std::string data = dataMsg.getParameter("data"); - if (data.length() < 8) { - return ""; - } - - uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); - data = data.substr(0, data.length()-2); - - uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); - data = data.substr(0, data.length()-2); - - uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3)); - double temperature = (value & 0x7FF)/10.0; - - value >>= 11; - if (value & 1) { - temperature = -temperature; - } - data = data.substr(0, data.length()-3); - - uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF; - - std::stringstream retString; - retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:"; - - if (humidity <= 100) { - retString << "temperaturehumidity;humidity:" << (int)humidity << ";"; - } else if (humidity == 0xFF) { - retString << "temperature;"; - } else { - return ""; - } - - retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";"; - - return retString.str(); -} +#include "ProtocolFineoffset.h" +#include "Strings.h" +#include +#include +#include + +std::string ProtocolFineoffset::decodeData(ControllerMessage &dataMsg) +{ + std::string data = dataMsg.getParameter("data"); + if (data.length() < 8) { + return ""; + } + + uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); + data = data.substr(0, data.length()-2); + + uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); + data = data.substr(0, data.length()-2); + + uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3)); + double temperature = (value & 0x7FF)/10.0; + + value >>= 11; + if (value & 1) { + temperature = -temperature; + } + data = data.substr(0, data.length()-3); + + uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF; + + std::stringstream retString; + retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:"; + + if (humidity <= 100) { + retString << "temperaturehumidity;humidity:" << (int)humidity << ";"; + } else if (humidity == 0xFF) { + retString << "temperature;"; + } else { + return ""; + } + + retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolFuhaote.cpp b/telldus-core/service/ProtocolFuhaote.cpp index 33fd9177..7baa2a30 100644 --- a/telldus-core/service/ProtocolFuhaote.cpp +++ b/telldus-core/service/ProtocolFuhaote.cpp @@ -1,54 +1,54 @@ -#include "ProtocolFuhaote.h" - -int ProtocolFuhaote::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF; -} - -std::string ProtocolFuhaote::getStringForMethod(int method, unsigned char, Controller *) { - const char S = 19; - const char L = 58; - const char B0[] = {S,L,L,S,0}; - const char B1[] = {L,S,L,S,0}; - const char OFF[] = {S,L,S,L,S,L,L,S,0}; - const char ON[] = {S,L,L,S,S,L,S,L,0}; - - std::string strReturn = "S"; - std::wstring strCode = this->getStringParameter(L"code", L""); - if (strCode == L"") { - return ""; - } - - //House code - for(size_t i = 0; i < 5; ++i) { - if (strCode[i] == '0') { - strReturn.append(B0); - } else if (strCode[i] == '1') { - strReturn.append(B1); - } - } - //Unit code - for(size_t i = 5; i < 10; ++i) { - if (strCode[i] == '0') { - strReturn.append(B0); - } else if (strCode[i] == '1') { - strReturn.append(1, S); - strReturn.append(1, L); - strReturn.append(1, S); - strReturn.append(1, L); - } - } - - if (method == TELLSTICK_TURNON) { - strReturn.append(ON); - } else if (method == TELLSTICK_TURNOFF) { - strReturn.append(OFF); - } else { - return ""; - } - - strReturn.append(1, S); - strReturn.append("+"); - return strReturn; - -} - +#include "ProtocolFuhaote.h" + +int ProtocolFuhaote::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolFuhaote::getStringForMethod(int method, unsigned char, Controller *) { + const char S = 19; + const char L = 58; + const char B0[] = {S,L,L,S,0}; + const char B1[] = {L,S,L,S,0}; + const char OFF[] = {S,L,S,L,S,L,L,S,0}; + const char ON[] = {S,L,L,S,S,L,S,L,0}; + + std::string strReturn = "S"; + std::wstring strCode = this->getStringParameter(L"code", L""); + if (strCode == L"") { + return ""; + } + + //House code + for(size_t i = 0; i < 5; ++i) { + if (strCode[i] == '0') { + strReturn.append(B0); + } else if (strCode[i] == '1') { + strReturn.append(B1); + } + } + //Unit code + for(size_t i = 5; i < 10; ++i) { + if (strCode[i] == '0') { + strReturn.append(B0); + } else if (strCode[i] == '1') { + strReturn.append(1, S); + strReturn.append(1, L); + strReturn.append(1, S); + strReturn.append(1, L); + } + } + + if (method == TELLSTICK_TURNON) { + strReturn.append(ON); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(OFF); + } else { + return ""; + } + + strReturn.append(1, S); + strReturn.append("+"); + return strReturn; + +} + diff --git a/telldus-core/service/ProtocolGroup.cpp b/telldus-core/service/ProtocolGroup.cpp index 6fdb0222..3d553022 100644 --- a/telldus-core/service/ProtocolGroup.cpp +++ b/telldus-core/service/ProtocolGroup.cpp @@ -1,9 +1,9 @@ -#include "ProtocolGroup.h" - -int ProtocolGroup::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_BELL | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_TOGGLE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; -} - -std::string ProtocolGroup::getStringForMethod(int method, unsigned char data, Controller *) { - return ""; +#include "ProtocolGroup.h" + +int ProtocolGroup::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_BELL | TELLSTICK_LEARN | TELLSTICK_EXECUTE | TELLSTICK_TOGGLE | TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; +} + +std::string ProtocolGroup::getStringForMethod(int method, unsigned char data, Controller *) { + return ""; } diff --git a/telldus-core/service/ProtocolGroup.h b/telldus-core/service/ProtocolGroup.h index b75e36e3..c98a14c3 100644 --- a/telldus-core/service/ProtocolGroup.h +++ b/telldus-core/service/ProtocolGroup.h @@ -10,7 +10,7 @@ public: }; -#endif //PROTOCOLGROUP_H - - - +#endif //PROTOCOLGROUP_H + + + diff --git a/telldus-core/service/ProtocolHasta.cpp b/telldus-core/service/ProtocolHasta.cpp index d9b41db1..5aaa35e4 100644 --- a/telldus-core/service/ProtocolHasta.cpp +++ b/telldus-core/service/ProtocolHasta.cpp @@ -1,66 +1,66 @@ -#include "ProtocolHasta.h" -#include -#include - -int ProtocolHasta::methods() const { - return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; -} - -std::string ProtocolHasta::getStringForMethod(int method, unsigned char, Controller *) { - int house = this->getIntParameter(L"house", 1, 65536); - int unit = this->getIntParameter(L"unit", 1, 15); - std::string strReturn; - - std::string preamble; - strReturn.append(1, 190); - strReturn.append(1, 1); - strReturn.append(1, 190); - strReturn.append(1, 1); - strReturn.append(1, 190); - strReturn.append(1, 190); - - strReturn.append(convertByte( (house&0xFF) )); - strReturn.append(convertByte( (house>>8)&0xFF )); - - int byte = unit&0x0F; - - if (method == TELLSTICK_UP) { - byte |= 0x00; - - } else if (method == TELLSTICK_DOWN) { - byte |= 0x10; - - } else if (method == TELLSTICK_STOP) { - byte |= 0x50; - - } else if (method == TELLSTICK_LEARN) { - byte |= 0x40; - - } else { - return ""; - } - strReturn.append(convertByte(byte)); - - strReturn.append(convertByte(0x0)); - strReturn.append(convertByte(0x0)); - - //Remove the last pulse - strReturn.erase(strReturn.end()-1,strReturn.end()); - - return strReturn; -} - -std::string ProtocolHasta::convertByte(unsigned char byte) { - std::string retval; - for(int i = 0; i < 8; ++i) { - if (byte & 1) { - retval.append(1, 33); - retval.append(1, 17); - } else { - retval.append(1, 17); - retval.append(1, 33); - } - byte >>= 1; - } - return retval; +#include "ProtocolHasta.h" +#include +#include + +int ProtocolHasta::methods() const { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; +} + +std::string ProtocolHasta::getStringForMethod(int method, unsigned char, Controller *) { + int house = this->getIntParameter(L"house", 1, 65536); + int unit = this->getIntParameter(L"unit", 1, 15); + std::string strReturn; + + std::string preamble; + strReturn.append(1, 190); + strReturn.append(1, 1); + strReturn.append(1, 190); + strReturn.append(1, 1); + strReturn.append(1, 190); + strReturn.append(1, 190); + + strReturn.append(convertByte( (house&0xFF) )); + strReturn.append(convertByte( (house>>8)&0xFF )); + + int byte = unit&0x0F; + + if (method == TELLSTICK_UP) { + byte |= 0x00; + + } else if (method == TELLSTICK_DOWN) { + byte |= 0x10; + + } else if (method == TELLSTICK_STOP) { + byte |= 0x50; + + } else if (method == TELLSTICK_LEARN) { + byte |= 0x40; + + } else { + return ""; + } + strReturn.append(convertByte(byte)); + + strReturn.append(convertByte(0x0)); + strReturn.append(convertByte(0x0)); + + //Remove the last pulse + strReturn.erase(strReturn.end()-1,strReturn.end()); + + return strReturn; +} + +std::string ProtocolHasta::convertByte(unsigned char byte) { + std::string retval; + for(int i = 0; i < 8; ++i) { + if (byte & 1) { + retval.append(1, 33); + retval.append(1, 17); + } else { + retval.append(1, 17); + retval.append(1, 33); + } + byte >>= 1; + } + return retval; } \ No newline at end of file diff --git a/telldus-core/service/ProtocolIkea.cpp b/telldus-core/service/ProtocolIkea.cpp index d251a4d4..bed01926 100644 --- a/telldus-core/service/ProtocolIkea.cpp +++ b/telldus-core/service/ProtocolIkea.cpp @@ -1,127 +1,127 @@ -#include "ProtocolIkea.h" -#include "Strings.h" - -#include -#include - -int ProtocolIkea::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM; -} - -std::string ProtocolIkea::getStringForMethod(int method, unsigned char level, Controller *) { - int intSystem = this->getIntParameter(L"system", 1, 16)-1; - int intFadeStyle = TelldusCore::comparei(this->getStringParameter(L"fade", L"true"), L"true"); - std::wstring wstrUnits = this->getStringParameter(L"units", L""); - - if (method == TELLSTICK_TURNON) { - level = 255; - } else if (method == TELLSTICK_TURNOFF) { - level = 0; - } else if (method == TELLSTICK_DIM) { - } else { - return ""; - } - - if (wstrUnits == L"") { - return ""; - } - - std::string strUnits(TelldusCore::wideToString(wstrUnits)); - int intUnits = 0; //Start without any units - - char *tempUnits = new char[strUnits.size()+1]; -#ifdef _WINDOWS - strcpy_s(tempUnits, strUnits.size()+1, strUnits.c_str()); -#else - strcpy(tempUnits, strUnits.c_str()); -#endif - - char *strToken = strtok(tempUnits, ","); - do { - int intUnit = atoi(strToken); - if (intUnit == 10) { - intUnit = 0; - } - intUnits = intUnits | ( 1<<(9-intUnit) ); - } while ( (strToken = strtok(NULL, ",")) != NULL ); - - delete[] tempUnits; - - std::string strReturn = "STTTTTTª"; //Startcode, always like this; - - std::string strChannels = ""; - int intCode = (intSystem << 10) | intUnits; - int checksum1 = 0; - int checksum2 = 0; - for (int i = 13; i >= 0; --i) { - if ((intCode>>i) & 1) { - strChannels.append("TT"); - if (i % 2 == 0) - checksum2++; - else - checksum1++; - } else { - strChannels.append("ª"); - } - } - strReturn.append(strChannels); //System + Units - - strReturn.append(checksum1 %2 == 0 ? "TT" : "ª"); //1st checksum - strReturn.append(checksum2 %2 == 0 ? "TT" : "ª"); //2nd checksum - - int intLevel = 0; - if (level <= 12) { - intLevel = 10; // Level 10 is actually off - } else if (level <= 37) { - intLevel = 1; - } else if (level <= 62) { - intLevel = 2; - } else if (level <= 87) { - intLevel = 3; - } else if (level <= 112) { - intLevel = 4; - } else if (level <= 137) { - intLevel = 5; - } else if (level <= 162) { - intLevel = 6; - } else if (level <= 187) { - intLevel = 7; - } else if (level <= 212) { - intLevel = 8; - } else if (level <= 237) { - intLevel = 9; - } else { - intLevel = 0; // Level 0 is actually full on - } - - int intFade = 0; - if (intFadeStyle == 1) { - intFade = 11 << 4; //Smooth - } else { - intFade = 1 << 4; //Instant - } - - intCode = intLevel | intFade; //Concat level and fade - - checksum1 = 0; - checksum2 = 0; - for (int i = 0; i < 6; ++i) { - if ((intCode>>i) & 1) { - strReturn.append("TT"); - if (i % 2 == 0) - checksum1++; - else - checksum2++; - } else { - strReturn.append("ª"); - } - } - - strReturn.append(checksum1 %2 == 0 ? "TT" : "ª"); //1st checksum - strReturn.append(checksum2 %2 == 0 ? "TT" : "ª"); //2nd checksum - - strReturn.append("+"); - - return strReturn; - -} +#include "ProtocolIkea.h" +#include "Strings.h" + +#include +#include + +int ProtocolIkea::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM; +} + +std::string ProtocolIkea::getStringForMethod(int method, unsigned char level, Controller *) { + int intSystem = this->getIntParameter(L"system", 1, 16)-1; + int intFadeStyle = TelldusCore::comparei(this->getStringParameter(L"fade", L"true"), L"true"); + std::wstring wstrUnits = this->getStringParameter(L"units", L""); + + if (method == TELLSTICK_TURNON) { + level = 255; + } else if (method == TELLSTICK_TURNOFF) { + level = 0; + } else if (method == TELLSTICK_DIM) { + } else { + return ""; + } + + if (wstrUnits == L"") { + return ""; + } + + std::string strUnits(TelldusCore::wideToString(wstrUnits)); + int intUnits = 0; //Start without any units + + char *tempUnits = new char[strUnits.size()+1]; +#ifdef _WINDOWS + strcpy_s(tempUnits, strUnits.size()+1, strUnits.c_str()); +#else + strcpy(tempUnits, strUnits.c_str()); +#endif + + char *strToken = strtok(tempUnits, ","); + do { + int intUnit = atoi(strToken); + if (intUnit == 10) { + intUnit = 0; + } + intUnits = intUnits | ( 1<<(9-intUnit) ); + } while ( (strToken = strtok(NULL, ",")) != NULL ); + + delete[] tempUnits; + + std::string strReturn = "STTTTTTª"; //Startcode, always like this; + + std::string strChannels = ""; + int intCode = (intSystem << 10) | intUnits; + int checksum1 = 0; + int checksum2 = 0; + for (int i = 13; i >= 0; --i) { + if ((intCode>>i) & 1) { + strChannels.append("TT"); + if (i % 2 == 0) + checksum2++; + else + checksum1++; + } else { + strChannels.append("ª"); + } + } + strReturn.append(strChannels); //System + Units + + strReturn.append(checksum1 %2 == 0 ? "TT" : "ª"); //1st checksum + strReturn.append(checksum2 %2 == 0 ? "TT" : "ª"); //2nd checksum + + int intLevel = 0; + if (level <= 12) { + intLevel = 10; // Level 10 is actually off + } else if (level <= 37) { + intLevel = 1; + } else if (level <= 62) { + intLevel = 2; + } else if (level <= 87) { + intLevel = 3; + } else if (level <= 112) { + intLevel = 4; + } else if (level <= 137) { + intLevel = 5; + } else if (level <= 162) { + intLevel = 6; + } else if (level <= 187) { + intLevel = 7; + } else if (level <= 212) { + intLevel = 8; + } else if (level <= 237) { + intLevel = 9; + } else { + intLevel = 0; // Level 0 is actually full on + } + + int intFade = 0; + if (intFadeStyle == 1) { + intFade = 11 << 4; //Smooth + } else { + intFade = 1 << 4; //Instant + } + + intCode = intLevel | intFade; //Concat level and fade + + checksum1 = 0; + checksum2 = 0; + for (int i = 0; i < 6; ++i) { + if ((intCode>>i) & 1) { + strReturn.append("TT"); + if (i % 2 == 0) + checksum1++; + else + checksum2++; + } else { + strReturn.append("ª"); + } + } + + strReturn.append(checksum1 %2 == 0 ? "TT" : "ª"); //1st checksum + strReturn.append(checksum2 %2 == 0 ? "TT" : "ª"); //2nd checksum + + strReturn.append("+"); + + return strReturn; + +} diff --git a/telldus-core/service/ProtocolMandolyn.cpp b/telldus-core/service/ProtocolMandolyn.cpp index 0a6ffcfb..8468adf6 100644 --- a/telldus-core/service/ProtocolMandolyn.cpp +++ b/telldus-core/service/ProtocolMandolyn.cpp @@ -1,38 +1,38 @@ -#include "ProtocolMandolyn.h" -#include "Strings.h" -#include -#include -#include - -std::string ProtocolMandolyn::decodeData(ControllerMessage &dataMsg) -{ - std::string data = dataMsg.getParameter("data"); - uint32_t value = (uint32_t)TelldusCore::hexTo64l(data); - - bool parity = value & 0x1; - value >>= 1; - - double temp = (double)(value & 0x7FFF) - (double)6400; - temp = temp/128.0; - value >>= 15; - - uint8_t humidity = (value & 0x7F); - value >>= 7; - - bool battOk = value & 0x1; - value >>= 3; - - uint8_t channel = (value & 0x3)+1; - value >>= 2; - - uint8_t house = value & 0xF; - - std::stringstream retString; - retString << "class:sensor;protocol:mandolyn;id:" - << house*10+channel - << ";model:temperaturehumidity;" - << "temp:" << std::fixed << std::setprecision(1) << temp - << ";humidity:" << (int)humidity << ";"; - - return retString.str(); -} +#include "ProtocolMandolyn.h" +#include "Strings.h" +#include +#include +#include + +std::string ProtocolMandolyn::decodeData(ControllerMessage &dataMsg) +{ + std::string data = dataMsg.getParameter("data"); + uint32_t value = (uint32_t)TelldusCore::hexTo64l(data); + + bool parity = value & 0x1; + value >>= 1; + + double temp = (double)(value & 0x7FFF) - (double)6400; + temp = temp/128.0; + value >>= 15; + + uint8_t humidity = (value & 0x7F); + value >>= 7; + + bool battOk = value & 0x1; + value >>= 3; + + uint8_t channel = (value & 0x3)+1; + value >>= 2; + + uint8_t house = value & 0xF; + + std::stringstream retString; + retString << "class:sensor;protocol:mandolyn;id:" + << house*10+channel + << ";model:temperaturehumidity;" + << "temp:" << std::fixed << std::setprecision(1) << temp + << ";humidity:" << (int)humidity << ";"; + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolNexa.cpp b/telldus-core/service/ProtocolNexa.cpp index 993f3ff2..7faea29e 100644 --- a/telldus-core/service/ProtocolNexa.cpp +++ b/telldus-core/service/ProtocolNexa.cpp @@ -1,282 +1,282 @@ -#include "ProtocolNexa.h" -#include -#include -#include "TellStick.h" -#include "Strings.h" - -int ProtocolNexa::lastArctecCodeSwitchWasTurnOff=0; //TODO, always removing first turnon now, make more flexible (waveman too) - -int ProtocolNexa::methods() const { - if (TelldusCore::comparei(model(), L"codeswitch")) { - return (TELLSTICK_TURNON | TELLSTICK_TURNOFF); - - } else if (TelldusCore::comparei(model(), L"selflearning-switch")) { - return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); - - } else if (TelldusCore::comparei(model(), L"selflearning-dimmer")) { - return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_LEARN); - - } else if (TelldusCore::comparei(model(), L"bell")) { - return TELLSTICK_BELL; - } - return 0; -} - -std::string ProtocolNexa::getStringForMethod(int method, unsigned char data, Controller *controller) { - if (TelldusCore::comparei(model(), L"codeswitch")) { - return getStringCodeSwitch(method); - } else if (TelldusCore::comparei(model(), L"bell")) { - return getStringBell(); - } - if ((method == TELLSTICK_TURNON) && TelldusCore::comparei(model(), L"selflearning-dimmer")) { - //Workaround for not letting a dimmer do into "dimming mode" - return getStringSelflearning(TELLSTICK_DIM, 255); - } - if (method == TELLSTICK_LEARN) { - std::string str = getStringSelflearning(TELLSTICK_TURNON, data); - - //Check to see if we are an old TellStick (fw <= 2, batch <= 8) - TellStick *ts = reinterpret_cast(controller); - if (!ts) { - return str; - } - if (ts->pid() == 0x0c30 && ts->firmwareVersion() <= 2) { - //Workaround for the bug in early firmwares - //The TellStick have a fixed pause (max) between two packets. - //It is only correct between the first and second packet. - //It seems faster to send two packes at a time and some - //receivers seems picky about this when learning. - //We also return the last packet so Device::doAction() doesn't - //report TELLSTICK_ERROR_METHOD_NOT_SUPPORTED - - str.insert(0, 1, 2); //Repeat two times - str.insert(0, 1, 'R'); - for (int i = 0; i < 5; ++i) { - controller->send(str); - } - } - return str; - } - return getStringSelflearning(method, data); -} - -std::string ProtocolNexa::getStringCodeSwitch(int method) { - std::string strReturn = "S"; - - std::wstring house = getStringParameter(L"house", L"A"); - int intHouse = house[0] - L'A'; - strReturn.append(getCodeSwitchTuple(intHouse)); - strReturn.append(getCodeSwitchTuple(getIntParameter(L"unit", 1, 16)-1)); - - if (method == TELLSTICK_TURNON) { - strReturn.append("$k$k$kk$$kk$$kk$$k+"); - } else if (method == TELLSTICK_TURNOFF) { - strReturn.append(this->getOffCode()); - } else { - return ""; - } - return strReturn; -} - -std::string ProtocolNexa::getStringBell() { - std::string strReturn = "S"; - - std::wstring house = getStringParameter(L"house", L"A"); - int intHouse = house[0] - L'A'; - strReturn.append(getCodeSwitchTuple(intHouse)); - strReturn.append("$kk$$kk$$kk$$k$k"); //Unit 7 - strReturn.append("$kk$$kk$$kk$$kk$$k+"); //Bell - return strReturn; -} - -std::string ProtocolNexa::getStringSelflearning(int method, unsigned char level) { - int intHouse = getIntParameter(L"house", 1, 67108863); - int intCode = getIntParameter(L"unit", 1, 16)-1; - return getStringSelflearningForCode(intHouse, intCode, method, level); -} - -std::string ProtocolNexa::getStringSelflearningForCode(int intHouse, int intCode, int method, unsigned char level) { - const unsigned char START[] = {'T',127,255,24,1,0}; -// const char START[] = {'T',130,255,26,24,0}; - - std::string strMessage(reinterpret_cast(START)); - strMessage.append(1,(method == TELLSTICK_DIM ? 147 : 132)); //Number of pulses - - std::string m; - for (int i = 25; i >= 0; --i) { - m.append( intHouse & 1 << i ? "10" : "01" ); - } - m.append("01"); //Group - - //On/off - if (method == TELLSTICK_DIM) { - m.append("00"); - } else if (method == TELLSTICK_TURNOFF) { - m.append("01"); - } else if (method == TELLSTICK_TURNON) { - m.append("10"); - } else { - return ""; - } - - for (int i = 3; i >= 0; --i) { - m.append( intCode & 1 << i ? "10" : "01" ); - } - - if (method == TELLSTICK_DIM) { - unsigned char newLevel = level/16; - for (int i = 3; i >= 0; --i) { - m.append(newLevel & 1 << i ? "10" : "01"); - } - } - - //The number of data is odd. - //Add this to make it even, otherwise the following loop will not work - m.append("0"); - - unsigned char code = 9; //b1001, startcode - for (unsigned int i = 0; i < m.length(); ++i) { - code <<= 4; - if (m[i] == '1') { - code |= 8; //b1000 - } else { - code |= 10; //b1010 -// code |= 11; //b1011 - } - if (i % 2 == 0) { - strMessage.append(1,code); - code = 0; - } - } - strMessage.append("+"); - -// for( int i = 0; i < strMessage.length(); ++i ) { -// printf("%i,", (unsigned char)strMessage[i]); -// } -// printf("\n"); - return strMessage; -} - -std::string ProtocolNexa::decodeData(ControllerMessage& dataMsg) -{ - unsigned long allData = 0; - - sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData); - - if(TelldusCore::comparei(dataMsg.model(), L"selflearning")){ - //selflearning - return decodeDataSelfLearning(allData); - } - else{ - //codeswitch - return decodeDataCodeSwitch(allData); - } -} - -std::string ProtocolNexa::decodeDataSelfLearning(long allData){ - unsigned int house = 0; - unsigned int unit = 0; - unsigned int group = 0; - unsigned int method = 0; - - house = allData & 0xFFFFFFC0; - house >>= 6; - - group = allData & 0x20; - group >>= 5; - - method = allData & 0x10; - method >>= 4; - - unit = allData & 0xF; - unit++; - - if(house < 1 || house > 67108863 || unit < 1 || unit > 16){ - //not arctech selflearning - return ""; - } - - std::stringstream retString; - retString << "class:command;protocol:arctech;model:selflearning;house:" << house << ";unit:" << unit << ";group:" << group << ";method:"; - if(method == 1){ - retString << "turnon;"; - } - else if(method == 0){ - retString << "turnoff;"; - } - else { - //not arctech selflearning - return ""; - } - - return retString.str(); -} - -std::string ProtocolNexa::decodeDataCodeSwitch(long allData){ - - unsigned int house = 0; - unsigned int unit = 0; - unsigned int method = 0; - - method = allData & 0xF00; - method >>= 8; - - unit = allData & 0xF0; - unit >>= 4; - unit++; - - house = allData & 0xF; - - if(house < 0 || house > 16 || unit < 1 || unit > 16){ - //not arctech codeswitch - return ""; - } - - house = house + 'A'; //house from A to P - - if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1){ - lastArctecCodeSwitchWasTurnOff = 0; - return ""; //probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose - //one turnon/bell, but it's better than the alternative... - } - - if(method == 6){ - lastArctecCodeSwitchWasTurnOff = 1; - } - - std::stringstream retString; - retString << "class:command;protocol:arctech;model:codeswitch;house:" << char(house); - - if(method == 6){ - retString << ";unit:" << unit << ";method:turnoff;"; - } - else if(method == 14){ - retString << ";unit:" << unit << ";method:turnon;"; - } - else if(method == 15){ - retString << ";method:bell;"; - } - else { - //not arctech codeswitch - return ""; - } - - return retString.str(); -} - -std::string ProtocolNexa::getCodeSwitchTuple(int intCode) { - std::string strReturn = ""; - for( int i = 0; i < 4; ++i ) { - if (intCode & 1) { //Convert 1 - strReturn.append("$kk$"); - } else { //Convert 0 - strReturn.append("$k$k"); - } - intCode >>= 1; - } - return strReturn; -} - -std::string ProtocolNexa::getOffCode() const { - return "$k$k$kk$$kk$$k$k$k+"; -} +#include "ProtocolNexa.h" +#include +#include +#include "TellStick.h" +#include "Strings.h" + +int ProtocolNexa::lastArctecCodeSwitchWasTurnOff=0; //TODO, always removing first turnon now, make more flexible (waveman too) + +int ProtocolNexa::methods() const { + if (TelldusCore::comparei(model(), L"codeswitch")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF); + + } else if (TelldusCore::comparei(model(), L"selflearning-switch")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); + + } else if (TelldusCore::comparei(model(), L"selflearning-dimmer")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_DIM | TELLSTICK_LEARN); + + } else if (TelldusCore::comparei(model(), L"bell")) { + return TELLSTICK_BELL; + } + return 0; +} + +std::string ProtocolNexa::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"codeswitch")) { + return getStringCodeSwitch(method); + } else if (TelldusCore::comparei(model(), L"bell")) { + return getStringBell(); + } + if ((method == TELLSTICK_TURNON) && TelldusCore::comparei(model(), L"selflearning-dimmer")) { + //Workaround for not letting a dimmer do into "dimming mode" + return getStringSelflearning(TELLSTICK_DIM, 255); + } + if (method == TELLSTICK_LEARN) { + std::string str = getStringSelflearning(TELLSTICK_TURNON, data); + + //Check to see if we are an old TellStick (fw <= 2, batch <= 8) + TellStick *ts = reinterpret_cast(controller); + if (!ts) { + return str; + } + if (ts->pid() == 0x0c30 && ts->firmwareVersion() <= 2) { + //Workaround for the bug in early firmwares + //The TellStick have a fixed pause (max) between two packets. + //It is only correct between the first and second packet. + //It seems faster to send two packes at a time and some + //receivers seems picky about this when learning. + //We also return the last packet so Device::doAction() doesn't + //report TELLSTICK_ERROR_METHOD_NOT_SUPPORTED + + str.insert(0, 1, 2); //Repeat two times + str.insert(0, 1, 'R'); + for (int i = 0; i < 5; ++i) { + controller->send(str); + } + } + return str; + } + return getStringSelflearning(method, data); +} + +std::string ProtocolNexa::getStringCodeSwitch(int method) { + std::string strReturn = "S"; + + std::wstring house = getStringParameter(L"house", L"A"); + int intHouse = house[0] - L'A'; + strReturn.append(getCodeSwitchTuple(intHouse)); + strReturn.append(getCodeSwitchTuple(getIntParameter(L"unit", 1, 16)-1)); + + if (method == TELLSTICK_TURNON) { + strReturn.append("$k$k$kk$$kk$$kk$$k+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(this->getOffCode()); + } else { + return ""; + } + return strReturn; +} + +std::string ProtocolNexa::getStringBell() { + std::string strReturn = "S"; + + std::wstring house = getStringParameter(L"house", L"A"); + int intHouse = house[0] - L'A'; + strReturn.append(getCodeSwitchTuple(intHouse)); + strReturn.append("$kk$$kk$$kk$$k$k"); //Unit 7 + strReturn.append("$kk$$kk$$kk$$kk$$k+"); //Bell + return strReturn; +} + +std::string ProtocolNexa::getStringSelflearning(int method, unsigned char level) { + int intHouse = getIntParameter(L"house", 1, 67108863); + int intCode = getIntParameter(L"unit", 1, 16)-1; + return getStringSelflearningForCode(intHouse, intCode, method, level); +} + +std::string ProtocolNexa::getStringSelflearningForCode(int intHouse, int intCode, int method, unsigned char level) { + const unsigned char START[] = {'T',127,255,24,1,0}; +// const char START[] = {'T',130,255,26,24,0}; + + std::string strMessage(reinterpret_cast(START)); + strMessage.append(1,(method == TELLSTICK_DIM ? 147 : 132)); //Number of pulses + + std::string m; + for (int i = 25; i >= 0; --i) { + m.append( intHouse & 1 << i ? "10" : "01" ); + } + m.append("01"); //Group + + //On/off + if (method == TELLSTICK_DIM) { + m.append("00"); + } else if (method == TELLSTICK_TURNOFF) { + m.append("01"); + } else if (method == TELLSTICK_TURNON) { + m.append("10"); + } else { + return ""; + } + + for (int i = 3; i >= 0; --i) { + m.append( intCode & 1 << i ? "10" : "01" ); + } + + if (method == TELLSTICK_DIM) { + unsigned char newLevel = level/16; + for (int i = 3; i >= 0; --i) { + m.append(newLevel & 1 << i ? "10" : "01"); + } + } + + //The number of data is odd. + //Add this to make it even, otherwise the following loop will not work + m.append("0"); + + unsigned char code = 9; //b1001, startcode + for (unsigned int i = 0; i < m.length(); ++i) { + code <<= 4; + if (m[i] == '1') { + code |= 8; //b1000 + } else { + code |= 10; //b1010 +// code |= 11; //b1011 + } + if (i % 2 == 0) { + strMessage.append(1,code); + code = 0; + } + } + strMessage.append("+"); + +// for( int i = 0; i < strMessage.length(); ++i ) { +// printf("%i,", (unsigned char)strMessage[i]); +// } +// printf("\n"); + return strMessage; +} + +std::string ProtocolNexa::decodeData(ControllerMessage& dataMsg) +{ + unsigned long allData = 0; + + sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData); + + if(TelldusCore::comparei(dataMsg.model(), L"selflearning")){ + //selflearning + return decodeDataSelfLearning(allData); + } + else{ + //codeswitch + return decodeDataCodeSwitch(allData); + } +} + +std::string ProtocolNexa::decodeDataSelfLearning(long allData){ + unsigned int house = 0; + unsigned int unit = 0; + unsigned int group = 0; + unsigned int method = 0; + + house = allData & 0xFFFFFFC0; + house >>= 6; + + group = allData & 0x20; + group >>= 5; + + method = allData & 0x10; + method >>= 4; + + unit = allData & 0xF; + unit++; + + if(house < 1 || house > 67108863 || unit < 1 || unit > 16){ + //not arctech selflearning + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:arctech;model:selflearning;house:" << house << ";unit:" << unit << ";group:" << group << ";method:"; + if(method == 1){ + retString << "turnon;"; + } + else if(method == 0){ + retString << "turnoff;"; + } + else { + //not arctech selflearning + return ""; + } + + return retString.str(); +} + +std::string ProtocolNexa::decodeDataCodeSwitch(long allData){ + + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + method = allData & 0xF00; + method >>= 8; + + unit = allData & 0xF0; + unit >>= 4; + unit++; + + house = allData & 0xF; + + if(house < 0 || house > 16 || unit < 1 || unit > 16){ + //not arctech codeswitch + return ""; + } + + house = house + 'A'; //house from A to P + + if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1){ + lastArctecCodeSwitchWasTurnOff = 0; + return ""; //probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose + //one turnon/bell, but it's better than the alternative... + } + + if(method == 6){ + lastArctecCodeSwitchWasTurnOff = 1; + } + + std::stringstream retString; + retString << "class:command;protocol:arctech;model:codeswitch;house:" << char(house); + + if(method == 6){ + retString << ";unit:" << unit << ";method:turnoff;"; + } + else if(method == 14){ + retString << ";unit:" << unit << ";method:turnon;"; + } + else if(method == 15){ + retString << ";method:bell;"; + } + else { + //not arctech codeswitch + return ""; + } + + return retString.str(); +} + +std::string ProtocolNexa::getCodeSwitchTuple(int intCode) { + std::string strReturn = ""; + for( int i = 0; i < 4; ++i ) { + if (intCode & 1) { //Convert 1 + strReturn.append("$kk$"); + } else { //Convert 0 + strReturn.append("$k$k"); + } + intCode >>= 1; + } + return strReturn; +} + +std::string ProtocolNexa::getOffCode() const { + return "$k$k$kk$$kk$$k$k$k+"; +} diff --git a/telldus-core/service/ProtocolOregon.cpp b/telldus-core/service/ProtocolOregon.cpp index c5847952..a22d2942 100644 --- a/telldus-core/service/ProtocolOregon.cpp +++ b/telldus-core/service/ProtocolOregon.cpp @@ -1,115 +1,115 @@ -#include "ProtocolOregon.h" -#include "Strings.h" -#include -#include -#include - -std::string ProtocolOregon::decodeData(ControllerMessage &dataMsg) -{ - std::string data = dataMsg.getParameter("data"); - - std::wstring model = dataMsg.model(); - if (model.compare(L"0xEA4C") == 0) { - return decodeEA4C(data); - } else if (model.compare(L"0x1A2D") == 0) { - return decode1A2D(data); - } - - return ""; -} - -std::string ProtocolOregon::decodeEA4C(const std::string &data) { - uint64_t value = TelldusCore::hexTo64l(data); - - uint8_t checksum = 0xE + 0xA + 0x4 + 0xC; - checksum -= (value & 0xF) * 0x10; - checksum -= 0xA; - value >>= 8; - - uint8_t checksumw = (value >> 4) & 0xF; - bool neg = value & (1 << 3); - checksum += (value & 0xF); - value >>= 8; - - uint8_t temp2 = value & 0xF; - uint8_t temp1 = (value >> 4) & 0xF; - checksum += temp2 + temp1; - value >>= 8; - - uint8_t temp3 = (value >> 4) & 0xF; - checksum += (value & 0xF) + temp3; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t address = value & 0xFF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t channel = (value >> 4) & 0x7; - - if (checksum != checksumw) { - return ""; - } - - double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; - if (neg) { - temperature = -temperature; - } - - std::stringstream retString; - retString << "class:sensor;protocol:oregon;model:EA4C;id:" << (int)address - << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; - - return retString.str(); -} - -std::string ProtocolOregon::decode1A2D(const std::string &data) { - uint64_t value = TelldusCore::hexTo64l(data); - uint8_t checksum2 = value & 0xFF; - value >>= 8; - uint8_t checksum1 = value & 0xFF; - value >>= 8; - - uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); - uint8_t hum1 = value & 0xF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t neg = value & (1 << 3); - uint8_t hum2 = (value >> 4) & 0xF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t temp2 = value & 0xF; - uint8_t temp1 = (value >> 4) & 0xF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t temp3 = (value >> 4) & 0xF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t address = value & 0xFF; - value >>= 8; - - checksum += ((value >> 4) & 0xF) + (value & 0xF); - uint8_t channel = (value >> 4) & 0x7; - - checksum += 0x1 + 0xA + 0x2 + 0xD - 0xA; - - //TODO: Find out how checksum2 works - if (checksum != checksum1) { - return ""; - } - - double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; - if (neg) { - temperature = -temperature; - } - - std::stringstream retString; - retString << "class:sensor;protocol:oregon;model:1A2D;id:" << (int)address - << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; - - return retString.str(); -} +#include "ProtocolOregon.h" +#include "Strings.h" +#include +#include +#include + +std::string ProtocolOregon::decodeData(ControllerMessage &dataMsg) +{ + std::string data = dataMsg.getParameter("data"); + + std::wstring model = dataMsg.model(); + if (model.compare(L"0xEA4C") == 0) { + return decodeEA4C(data); + } else if (model.compare(L"0x1A2D") == 0) { + return decode1A2D(data); + } + + return ""; +} + +std::string ProtocolOregon::decodeEA4C(const std::string &data) { + uint64_t value = TelldusCore::hexTo64l(data); + + uint8_t checksum = 0xE + 0xA + 0x4 + 0xC; + checksum -= (value & 0xF) * 0x10; + checksum -= 0xA; + value >>= 8; + + uint8_t checksumw = (value >> 4) & 0xF; + bool neg = value & (1 << 3); + checksum += (value & 0xF); + value >>= 8; + + uint8_t temp2 = value & 0xF; + uint8_t temp1 = (value >> 4) & 0xF; + checksum += temp2 + temp1; + value >>= 8; + + uint8_t temp3 = (value >> 4) & 0xF; + checksum += (value & 0xF) + temp3; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t address = value & 0xFF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t channel = (value >> 4) & 0x7; + + if (checksum != checksumw) { + return ""; + } + + double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:EA4C;id:" << (int)address + << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + + return retString.str(); +} + +std::string ProtocolOregon::decode1A2D(const std::string &data) { + uint64_t value = TelldusCore::hexTo64l(data); + uint8_t checksum2 = value & 0xFF; + value >>= 8; + uint8_t checksum1 = value & 0xFF; + value >>= 8; + + uint8_t checksum = ((value >> 4) & 0xF) + (value & 0xF); + uint8_t hum1 = value & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t neg = value & (1 << 3); + uint8_t hum2 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t temp2 = value & 0xF; + uint8_t temp1 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t temp3 = (value >> 4) & 0xF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t address = value & 0xFF; + value >>= 8; + + checksum += ((value >> 4) & 0xF) + (value & 0xF); + uint8_t channel = (value >> 4) & 0x7; + + checksum += 0x1 + 0xA + 0x2 + 0xD - 0xA; + + //TODO: Find out how checksum2 works + if (checksum != checksum1) { + return ""; + } + + double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0; + if (neg) { + temperature = -temperature; + } + + std::stringstream retString; + retString << "class:sensor;protocol:oregon;model:1A2D;id:" << (int)address + << ";temp:" << std::fixed << std::setprecision(1) << temperature << ";"; + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolRisingSun.cpp b/telldus-core/service/ProtocolRisingSun.cpp index 4068ba40..192c900d 100644 --- a/telldus-core/service/ProtocolRisingSun.cpp +++ b/telldus-core/service/ProtocolRisingSun.cpp @@ -1,111 +1,111 @@ -#include "ProtocolRisingSun.h" -#include "Strings.h" - -int ProtocolRisingSun::methods() const { - if (TelldusCore::comparei(model(), L"selflearning")) { - return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); - } - return TELLSTICK_TURNON | TELLSTICK_TURNOFF; -} - -std::string ProtocolRisingSun::getStringForMethod(int method, unsigned char data, Controller *controller) { - if (TelldusCore::comparei(model(), L"selflearning")) { - return getStringSelflearning(method); - } - return getStringCodeSwitch(method); -} - -std::string ProtocolRisingSun::getStringSelflearning(int method) { - int intHouse = this->getIntParameter(L"house", 1, 33554432)-1; - int intCode = this->getIntParameter(L"code", 1, 16)-1; - - const char code_on[][7] = { - "110110", "001110", "100110", "010110", - "111001", "000101", "101001", "011001", - "110000", "001000", "100000", "010000", - "111100", "000010", "101100", "011100" - }; - const char code_off[][7] = { - "111110", "000001", "101110", "011110", - "110101", "001101", "100101", "010101", - "111000", "000100", "101000", "011000", - "110010", "001010", "100010", "010010" - }; - const char l = 120; - const char s = 51; - - std::string strCode = "10"; - int code = intCode; - code = (code < 0 ? 0 : code); - code = (code > 15 ? 15 : code); - if (method == TELLSTICK_TURNON) { - strCode.append(code_on[code]); - } else if (method == TELLSTICK_TURNOFF) { - strCode.append(code_off[code]); - } else if (method == TELLSTICK_LEARN) { - strCode.append(code_on[code]); - } else { - return ""; - } - - int house = intHouse; - for(int i = 0; i < 25; ++i) { - if (house & 1) { - strCode.append(1, '1'); - } else { - strCode.append(1, '0'); - } - house >>= 1; - } - - std::string strReturn; - for(unsigned int i = 0; i < strCode.length(); ++i) { - if (strCode[i] == '1') { - strReturn.append(1, l); - strReturn.append(1, s); - } else { - strReturn.append(1, s); - strReturn.append(1, l); - } - } - - std::string prefix = "P"; - prefix.append(1, 5); - if (method == TELLSTICK_LEARN) { - prefix.append("R"); - prefix.append( 1, 50 ); - } - prefix.append("S"); - strReturn.insert(0, prefix); - strReturn.append(1, '+'); - return strReturn; -} - -std::string ProtocolRisingSun::getStringCodeSwitch(int method) { - std::string strReturn = "S.e"; - strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"house", 1, 4)-1)); - strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"unit", 1, 4)-1)); - if (method == TELLSTICK_TURNON) { - strReturn.append("e..ee..ee..ee..e+"); - } else if (method == TELLSTICK_TURNOFF) { - strReturn.append("e..ee..ee..e.e.e+"); - } else { - return ""; - } - return strReturn; - -} - -std::string ProtocolRisingSun::getCodeSwitchTuple(int intToConvert) { - - std::string strReturn = ""; - for(int i = 0; i < 4; ++i) { - if (i == intToConvert) { - strReturn.append( ".e.e" ); - } else { - strReturn.append( "e..e" ); - } - } - return strReturn; - -} +#include "ProtocolRisingSun.h" +#include "Strings.h" + +int ProtocolRisingSun::methods() const { + if (TelldusCore::comparei(model(), L"selflearning")) { + return (TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN); + } + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolRisingSun::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"selflearning")) { + return getStringSelflearning(method); + } + return getStringCodeSwitch(method); +} + +std::string ProtocolRisingSun::getStringSelflearning(int method) { + int intHouse = this->getIntParameter(L"house", 1, 33554432)-1; + int intCode = this->getIntParameter(L"code", 1, 16)-1; + + const char code_on[][7] = { + "110110", "001110", "100110", "010110", + "111001", "000101", "101001", "011001", + "110000", "001000", "100000", "010000", + "111100", "000010", "101100", "011100" + }; + const char code_off[][7] = { + "111110", "000001", "101110", "011110", + "110101", "001101", "100101", "010101", + "111000", "000100", "101000", "011000", + "110010", "001010", "100010", "010010" + }; + const char l = 120; + const char s = 51; + + std::string strCode = "10"; + int code = intCode; + code = (code < 0 ? 0 : code); + code = (code > 15 ? 15 : code); + if (method == TELLSTICK_TURNON) { + strCode.append(code_on[code]); + } else if (method == TELLSTICK_TURNOFF) { + strCode.append(code_off[code]); + } else if (method == TELLSTICK_LEARN) { + strCode.append(code_on[code]); + } else { + return ""; + } + + int house = intHouse; + for(int i = 0; i < 25; ++i) { + if (house & 1) { + strCode.append(1, '1'); + } else { + strCode.append(1, '0'); + } + house >>= 1; + } + + std::string strReturn; + for(unsigned int i = 0; i < strCode.length(); ++i) { + if (strCode[i] == '1') { + strReturn.append(1, l); + strReturn.append(1, s); + } else { + strReturn.append(1, s); + strReturn.append(1, l); + } + } + + std::string prefix = "P"; + prefix.append(1, 5); + if (method == TELLSTICK_LEARN) { + prefix.append("R"); + prefix.append( 1, 50 ); + } + prefix.append("S"); + strReturn.insert(0, prefix); + strReturn.append(1, '+'); + return strReturn; +} + +std::string ProtocolRisingSun::getStringCodeSwitch(int method) { + std::string strReturn = "S.e"; + strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"house", 1, 4)-1)); + strReturn.append(getCodeSwitchTuple(this->getIntParameter(L"unit", 1, 4)-1)); + if (method == TELLSTICK_TURNON) { + strReturn.append("e..ee..ee..ee..e+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append("e..ee..ee..e.e.e+"); + } else { + return ""; + } + return strReturn; + +} + +std::string ProtocolRisingSun::getCodeSwitchTuple(int intToConvert) { + + std::string strReturn = ""; + for(int i = 0; i < 4; ++i) { + if (i == intToConvert) { + strReturn.append( ".e.e" ); + } else { + strReturn.append( "e..e" ); + } + } + return strReturn; + +} diff --git a/telldus-core/service/ProtocolSartano.cpp b/telldus-core/service/ProtocolSartano.cpp index 6c214cb6..b0456825 100644 --- a/telldus-core/service/ProtocolSartano.cpp +++ b/telldus-core/service/ProtocolSartano.cpp @@ -1,104 +1,104 @@ -#include "ProtocolSartano.h" -#include -#include - -int ProtocolSartano::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF; -} - -std::string ProtocolSartano::getStringForMethod(int method, unsigned char, Controller *) { - std::wstring strCode = this->getStringParameter(L"code", L""); - return getStringForCode(strCode, method); -} - -std::string ProtocolSartano::getStringForCode(const std::wstring &strCode, int method) { - - std::string strReturn("S"); - - for (size_t i = 0; i < strCode.length(); ++i) { - if (strCode[i] == L'1') { - strReturn.append("$k$k"); - } else { - strReturn.append("$kk$"); - } - } - - if (method == TELLSTICK_TURNON) { - strReturn.append("$k$k$kk$$k+"); - } else if (method == TELLSTICK_TURNOFF) { - strReturn.append("$kk$$k$k$k+"); - } else { - return ""; - } - - return strReturn; - -} - -std::string ProtocolSartano::decodeData(ControllerMessage &dataMsg) -{ - std::string data = dataMsg.getParameter("data"); - signed int allDataIn; - signed int allData = 0; - unsigned int code = 0; - unsigned int method1 = 0; - unsigned int method2 = 0; - unsigned int method = 0; - - sscanf(data.c_str(), "%X", &allDataIn); - - unsigned long mask = (1<<11); - for(int i=0;i<12;++i){ - allData >>= 1; - if((allDataIn & mask) == 0){ - allData |= (1<<11); - } - mask >>= 1; - } - - code = allData & 0xFFC; - code >>= 2; - - method1 = allData & 0x2; - method1 >>= 1; - - method2 = allData & 0x1; - - if(method1 == 0 && method2 == 1){ - method = 0; //off - } - else if(method1 == 1 && method2 == 0){ - method = 1; //on - } - else{ - return ""; - } - - if(code < 0 || code > 1023){ - //not sartano - return ""; - } - - std::stringstream retString; - retString << "class:command;protocol:sartano;model:codeswitch;code:"; - mask = (1<<9); - for(int i=0;i<10;i++){ - if((code & mask) != 0){ - retString << 1; - } - else{ - retString << 0; - } - mask >>= 1; - } - retString << ";method:"; - - if(method == 0){ - retString << "turnoff;"; - } - else{ - retString << "turnon;"; - } - - return retString.str(); -} +#include "ProtocolSartano.h" +#include +#include + +int ProtocolSartano::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolSartano::getStringForMethod(int method, unsigned char, Controller *) { + std::wstring strCode = this->getStringParameter(L"code", L""); + return getStringForCode(strCode, method); +} + +std::string ProtocolSartano::getStringForCode(const std::wstring &strCode, int method) { + + std::string strReturn("S"); + + for (size_t i = 0; i < strCode.length(); ++i) { + if (strCode[i] == L'1') { + strReturn.append("$k$k"); + } else { + strReturn.append("$kk$"); + } + } + + if (method == TELLSTICK_TURNON) { + strReturn.append("$k$k$kk$$k+"); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append("$kk$$k$k$k+"); + } else { + return ""; + } + + return strReturn; + +} + +std::string ProtocolSartano::decodeData(ControllerMessage &dataMsg) +{ + std::string data = dataMsg.getParameter("data"); + signed int allDataIn; + signed int allData = 0; + unsigned int code = 0; + unsigned int method1 = 0; + unsigned int method2 = 0; + unsigned int method = 0; + + sscanf(data.c_str(), "%X", &allDataIn); + + unsigned long mask = (1<<11); + for(int i=0;i<12;++i){ + allData >>= 1; + if((allDataIn & mask) == 0){ + allData |= (1<<11); + } + mask >>= 1; + } + + code = allData & 0xFFC; + code >>= 2; + + method1 = allData & 0x2; + method1 >>= 1; + + method2 = allData & 0x1; + + if(method1 == 0 && method2 == 1){ + method = 0; //off + } + else if(method1 == 1 && method2 == 0){ + method = 1; //on + } + else{ + return ""; + } + + if(code < 0 || code > 1023){ + //not sartano + return ""; + } + + std::stringstream retString; + retString << "class:command;protocol:sartano;model:codeswitch;code:"; + mask = (1<<9); + for(int i=0;i<10;i++){ + if((code & mask) != 0){ + retString << 1; + } + else{ + retString << 0; + } + mask >>= 1; + } + retString << ";method:"; + + if(method == 0){ + retString << "turnoff;"; + } + else{ + retString << "turnon;"; + } + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolScene.cpp b/telldus-core/service/ProtocolScene.cpp index 811aa7f0..e18e362a 100644 --- a/telldus-core/service/ProtocolScene.cpp +++ b/telldus-core/service/ProtocolScene.cpp @@ -1,9 +1,9 @@ -#include "ProtocolScene.h" - -int ProtocolScene::methods() const { - return TELLSTICK_EXECUTE; -} - -std::string ProtocolScene::getStringForMethod(int method, unsigned char data, Controller *) { - return ""; +#include "ProtocolScene.h" + +int ProtocolScene::methods() const { + return TELLSTICK_EXECUTE; +} + +std::string ProtocolScene::getStringForMethod(int method, unsigned char data, Controller *) { + return ""; } diff --git a/telldus-core/service/ProtocolScene.h b/telldus-core/service/ProtocolScene.h index 4b1b6903..aaa22ebb 100644 --- a/telldus-core/service/ProtocolScene.h +++ b/telldus-core/service/ProtocolScene.h @@ -10,7 +10,7 @@ public: }; -#endif //PROTOCOLSCENE_H - - - +#endif //PROTOCOLSCENE_H + + + diff --git a/telldus-core/service/ProtocolSilvanChip.cpp b/telldus-core/service/ProtocolSilvanChip.cpp index dbde18bf..23226e69 100644 --- a/telldus-core/service/ProtocolSilvanChip.cpp +++ b/telldus-core/service/ProtocolSilvanChip.cpp @@ -1,140 +1,140 @@ -#include "ProtocolSilvanChip.h" -#include "Strings.h" - -int ProtocolSilvanChip::methods() const { - if (TelldusCore::comparei(model(), L"kp100")) { - return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; - } else if (TelldusCore::comparei(model(), L"ecosavers")) { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; - } else if (TelldusCore::comparei(model(), L"displaymatic")) { - return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; - } - return 0; -} - -std::string ProtocolSilvanChip::getStringForMethod(int method, unsigned char data, Controller *controller) { - if (TelldusCore::comparei(model(), L"kp100")) { - std::string preamble; - preamble.append(1, 100); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 100); - - const std::string one = "\xFF\x1\x2E\x2E"; - const std::string zero = "\x2E\xFF\x1\x2E"; - int button = 0; - if (method == TELLSTICK_UP) { - button = 2; - } else if (method == TELLSTICK_DOWN) { - button = 8; - } else if (method == TELLSTICK_STOP) { - button = 4; - } else if (method == TELLSTICK_LEARN) { - button = 1; - } else { - return ""; - } - return this->getString(preamble, one, zero, button); - } else if (TelldusCore::comparei(model(), L"displaymatic")) { - std::string preamble; - preamble.append(1, 0x25); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 0x25); - const std::string one = "\x69\25"; - const std::string zero = "\x25\x69"; - int button = 0; - if (method == TELLSTICK_UP) { - button = 1; - } else if (method == TELLSTICK_DOWN) { - button = 4; - } else if (method == TELLSTICK_STOP) { - button = 2; - } - return this->getString(preamble, one, zero, button); - } else if (TelldusCore::comparei(model(), L"ecosavers")) { - std::string preamble; - preamble.append(1, 0x25); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 255); - preamble.append(1, 1); - preamble.append(1, 0x25); - const std::string one = "\x69\25"; - const std::string zero = "\x25\x69"; - int intUnit = this->getIntParameter(L"unit", 1, 4); - int button = 0; - if (intUnit == 1) { - button = 7; - } else if (intUnit == 2) { - button = 3; - } else if (intUnit == 3) { - button = 5; - } else if (intUnit == 4) { - button = 6; - } - - if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { - button |= 8; - } - return this->getString(preamble, one, zero, button); - } - return ""; -} - -std::string ProtocolSilvanChip::getString(const std::string &preamble, const std::string &one, const std::string &zero, int button) { - - int intHouse = this->getIntParameter(L"house", 1, 1048575); - std::string strReturn = preamble; - - for( int i = 19; i >= 0; --i ) { - if (intHouse & (1 << i)) { - strReturn.append(one); - } else { - strReturn.append(zero); - } - } - - for( int i = 3; i >= 0; --i) { - if (button & (1 << i)) { - strReturn.append(one); - } else { - strReturn.append(zero); - } - } - - strReturn.append(zero); - return strReturn; -} +#include "ProtocolSilvanChip.h" +#include "Strings.h" + +int ProtocolSilvanChip::methods() const { + if (TelldusCore::comparei(model(), L"kp100")) { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP | TELLSTICK_LEARN; + } else if (TelldusCore::comparei(model(), L"ecosavers")) { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; + } else if (TelldusCore::comparei(model(), L"displaymatic")) { + return TELLSTICK_UP | TELLSTICK_DOWN | TELLSTICK_STOP; + } + return 0; +} + +std::string ProtocolSilvanChip::getStringForMethod(int method, unsigned char data, Controller *controller) { + if (TelldusCore::comparei(model(), L"kp100")) { + std::string preamble; + preamble.append(1, 100); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 100); + + const std::string one = "\xFF\x1\x2E\x2E"; + const std::string zero = "\x2E\xFF\x1\x2E"; + int button = 0; + if (method == TELLSTICK_UP) { + button = 2; + } else if (method == TELLSTICK_DOWN) { + button = 8; + } else if (method == TELLSTICK_STOP) { + button = 4; + } else if (method == TELLSTICK_LEARN) { + button = 1; + } else { + return ""; + } + return this->getString(preamble, one, zero, button); + } else if (TelldusCore::comparei(model(), L"displaymatic")) { + std::string preamble; + preamble.append(1, 0x25); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 0x25); + const std::string one = "\x69\25"; + const std::string zero = "\x25\x69"; + int button = 0; + if (method == TELLSTICK_UP) { + button = 1; + } else if (method == TELLSTICK_DOWN) { + button = 4; + } else if (method == TELLSTICK_STOP) { + button = 2; + } + return this->getString(preamble, one, zero, button); + } else if (TelldusCore::comparei(model(), L"ecosavers")) { + std::string preamble; + preamble.append(1, 0x25); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 255); + preamble.append(1, 1); + preamble.append(1, 0x25); + const std::string one = "\x69\25"; + const std::string zero = "\x25\x69"; + int intUnit = this->getIntParameter(L"unit", 1, 4); + int button = 0; + if (intUnit == 1) { + button = 7; + } else if (intUnit == 2) { + button = 3; + } else if (intUnit == 3) { + button = 5; + } else if (intUnit == 4) { + button = 6; + } + + if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { + button |= 8; + } + return this->getString(preamble, one, zero, button); + } + return ""; +} + +std::string ProtocolSilvanChip::getString(const std::string &preamble, const std::string &one, const std::string &zero, int button) { + + int intHouse = this->getIntParameter(L"house", 1, 1048575); + std::string strReturn = preamble; + + for( int i = 19; i >= 0; --i ) { + if (intHouse & (1 << i)) { + strReturn.append(one); + } else { + strReturn.append(zero); + } + } + + for( int i = 3; i >= 0; --i) { + if (button & (1 << i)) { + strReturn.append(one); + } else { + strReturn.append(zero); + } + } + + strReturn.append(zero); + return strReturn; +} diff --git a/telldus-core/service/ProtocolUpm.cpp b/telldus-core/service/ProtocolUpm.cpp index 5150009d..65bf7b28 100644 --- a/telldus-core/service/ProtocolUpm.cpp +++ b/telldus-core/service/ProtocolUpm.cpp @@ -1,71 +1,71 @@ -#include "ProtocolUpm.h" - -int ProtocolUpm::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; -} - -std::string ProtocolUpm::getStringForMethod(int method, unsigned char, Controller *) { - const char S = ';'; - const char L = '~'; - const char START[] = {S,0}; - const char B1[] = {L,S,0}; - const char B0[] = {S,L,0}; - //const char BON[] = {S,L,L,S,0}; - //const char BOFF[] = {S,L,S,L,0}; - - int intUnit = this->getIntParameter(L"unit", 1, 4)-1; - std::string strReturn; - - int code = this->getIntParameter(L"house", 0, 4095); - for( size_t i = 0; i < 12; ++i ) { - if (code & 1) { - strReturn.insert(0, B1); - } else { - strReturn.insert(0, B0); - } - code >>= 1; - } - strReturn.insert(0, START); //Startcode, first - - code = 0; - if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { - code += 2; - } else if (method != TELLSTICK_TURNOFF) { - return ""; - } - code <<= 2; - code += intUnit; - - int check1 = 0, check2 = 0; - for( size_t i = 0; i < 6; ++i ) { - if (code & 1) { - if (i % 2 == 0) { - check1++; - } else { - check2++; - } - } - if (code & 1) { - strReturn.append(B1); - } else { - strReturn.append(B0); - } - code >>= 1; - } - - if (check1 % 2 == 0) { - strReturn.append(B0); - } else { - strReturn.append(B1); - } - if (check2 % 2 == 0) { - strReturn.append(B0); - } else { - strReturn.append(B1); - } - - strReturn.insert(0, "S"); - strReturn.append("+"); - return strReturn; -} - +#include "ProtocolUpm.h" + +int ProtocolUpm::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF | TELLSTICK_LEARN; +} + +std::string ProtocolUpm::getStringForMethod(int method, unsigned char, Controller *) { + const char S = ';'; + const char L = '~'; + const char START[] = {S,0}; + const char B1[] = {L,S,0}; + const char B0[] = {S,L,0}; + //const char BON[] = {S,L,L,S,0}; + //const char BOFF[] = {S,L,S,L,0}; + + int intUnit = this->getIntParameter(L"unit", 1, 4)-1; + std::string strReturn; + + int code = this->getIntParameter(L"house", 0, 4095); + for( size_t i = 0; i < 12; ++i ) { + if (code & 1) { + strReturn.insert(0, B1); + } else { + strReturn.insert(0, B0); + } + code >>= 1; + } + strReturn.insert(0, START); //Startcode, first + + code = 0; + if (method == TELLSTICK_TURNON || method == TELLSTICK_LEARN) { + code += 2; + } else if (method != TELLSTICK_TURNOFF) { + return ""; + } + code <<= 2; + code += intUnit; + + int check1 = 0, check2 = 0; + for( size_t i = 0; i < 6; ++i ) { + if (code & 1) { + if (i % 2 == 0) { + check1++; + } else { + check2++; + } + } + if (code & 1) { + strReturn.append(B1); + } else { + strReturn.append(B0); + } + code >>= 1; + } + + if (check1 % 2 == 0) { + strReturn.append(B0); + } else { + strReturn.append(B1); + } + if (check2 % 2 == 0) { + strReturn.append(B0); + } else { + strReturn.append(B1); + } + + strReturn.insert(0, "S"); + strReturn.append("+"); + return strReturn; +} + diff --git a/telldus-core/service/ProtocolWaveman.cpp b/telldus-core/service/ProtocolWaveman.cpp index c5f68d2e..14ddb65b 100644 --- a/telldus-core/service/ProtocolWaveman.cpp +++ b/telldus-core/service/ProtocolWaveman.cpp @@ -1,69 +1,69 @@ -#include "ProtocolWaveman.h" -#include -#include - -int ProtocolWaveman::lastArctecCodeSwitchWasTurnOff=0; - -int ProtocolWaveman::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF; -} - -std::string ProtocolWaveman::getStringForMethod(int method, unsigned char, Controller *) { - return getStringCodeSwitch(method); -} - -std::string ProtocolWaveman::getOffCode() const { - return "$k$k$k$k$k$k$k$k$k+"; -} - -std::string ProtocolWaveman::decodeData(ControllerMessage& dataMsg) -{ - unsigned long allData = 0; - unsigned int house = 0; - unsigned int unit = 0; - unsigned int method = 0; - - sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData); - - method = allData & 0xF00; - method >>= 8; - - unit = allData & 0xF0; - unit >>= 4; - unit++; - - house = allData & 0xF; - - if(house < 0 || house > 16 || unit < 1 || unit > 16){ - //not waveman - return ""; - } - - house = house + 'A'; //house from A to P - - if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1){ - lastArctecCodeSwitchWasTurnOff = 0; - return ""; //probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose - //one turnon/bell, but it's better than the alternative... - } - - if(method == 6){ - lastArctecCodeSwitchWasTurnOff = 1; - } - - std::stringstream retString; - retString << "class:command;protocol:waveman;model:codeswitch;house:" << char(house); - - if(method == 0){ - retString << ";unit:" << unit << ";method:turnoff;"; - } - else if(method == 14){ - retString << ";unit:" << unit << ";method:turnon;"; - } - else { - //not waveman - return ""; - } - - return retString.str(); -} +#include "ProtocolWaveman.h" +#include +#include + +int ProtocolWaveman::lastArctecCodeSwitchWasTurnOff=0; + +int ProtocolWaveman::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolWaveman::getStringForMethod(int method, unsigned char, Controller *) { + return getStringCodeSwitch(method); +} + +std::string ProtocolWaveman::getOffCode() const { + return "$k$k$k$k$k$k$k$k$k+"; +} + +std::string ProtocolWaveman::decodeData(ControllerMessage& dataMsg) +{ + unsigned long allData = 0; + unsigned int house = 0; + unsigned int unit = 0; + unsigned int method = 0; + + sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData); + + method = allData & 0xF00; + method >>= 8; + + unit = allData & 0xF0; + unit >>= 4; + unit++; + + house = allData & 0xF; + + if(house < 0 || house > 16 || unit < 1 || unit > 16){ + //not waveman + return ""; + } + + house = house + 'A'; //house from A to P + + if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1){ + lastArctecCodeSwitchWasTurnOff = 0; + return ""; //probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose + //one turnon/bell, but it's better than the alternative... + } + + if(method == 6){ + lastArctecCodeSwitchWasTurnOff = 1; + } + + std::stringstream retString; + retString << "class:command;protocol:waveman;model:codeswitch;house:" << char(house); + + if(method == 0){ + retString << ";unit:" << unit << ";method:turnoff;"; + } + else if(method == 14){ + retString << ";unit:" << unit << ";method:turnon;"; + } + else { + //not waveman + return ""; + } + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolX10.cpp b/telldus-core/service/ProtocolX10.cpp index e6d3fef8..ad9bcb55 100644 --- a/telldus-core/service/ProtocolX10.cpp +++ b/telldus-core/service/ProtocolX10.cpp @@ -1,174 +1,174 @@ -#include "ProtocolX10.h" -#include -#include - -const unsigned char HOUSES[] = {6,0xE,2,0xA,1,9,5,0xD,7,0xF,3,0xB,0,8,4,0xC}; - -int ProtocolX10::methods() const { - return TELLSTICK_TURNON | TELLSTICK_TURNOFF; -} - -std::string ProtocolX10::getStringForMethod(int method, unsigned char data, Controller *controller) { - const unsigned char S = 59, L = 169; - const char B0[] = {S,S,0}; - const char B1[] = {S,L,0}; - const unsigned char START_CODE[] = {'S',255,1,255,1,255,1,100,255,1,180,0}; - const unsigned char STOP_CODE[] = {S,0}; - - std::string strReturn = reinterpret_cast(START_CODE); - std::string strComplement = ""; - - std::wstring strHouse = getStringParameter(L"house", L"A"); - int intHouse = strHouse[0] - L'A'; - if (intHouse < 0) { - intHouse = 0; - } else if (intHouse > 15) { - intHouse = 15; - } - //Translate it - intHouse = HOUSES[intHouse]; - int intCode = getIntParameter(L"unit", 1, 16)-1; - - for( int i = 0; i < 4; ++i ) { - if (intHouse & 1) { - strReturn.append(B1); - strComplement.append(B0); - } else { - strReturn.append(B0); - strComplement.append(B1); - } - intHouse >>= 1; - } - strReturn.append( B0 ); - strComplement.append( B1 ); - - if (intCode >= 8) { - strReturn.append(B1); - strComplement.append(B0); - } else { - strReturn.append(B0); - strComplement.append(B1); - } - - strReturn.append( B0 ); - strComplement.append( B1 ); - strReturn.append( B0 ); - strComplement.append( B1 ); - - strReturn.append( strComplement ); - strComplement = ""; - - strReturn.append( B0 ); - strComplement.append( B1 ); - - if (intCode >> 2 & 1) { //Bit 2 of intCode - strReturn.append(B1); - strComplement.append(B0); - } else { - strReturn.append(B0); - strComplement.append(B1); - } - - if (method == TELLSTICK_TURNON) { - strReturn.append(B0); - strComplement.append(B1); - } else if (method == TELLSTICK_TURNOFF) { - strReturn.append(B1); - strComplement.append(B0); - } else { - return ""; - } - - if (intCode & 1) { //Bit 0 of intCode - strReturn.append(B1); - strComplement.append(B0); - } else { - strReturn.append(B0); - strComplement.append(B1); - } - - if (intCode >> 1 & 1) { //Bit 1 of intCode - strReturn.append(B1); - strComplement.append(B0); - } else { - strReturn.append(B0); - strComplement.append(B1); - } - - for( int i = 0; i < 3; ++i ) { - strReturn.append( B0 ); - strComplement.append( B1 ); - } - - strReturn.append( strComplement ); - strReturn.append( reinterpret_cast(STOP_CODE) ); - strReturn.append("+"); - return strReturn; - -} - -std::string ProtocolX10::decodeData(ControllerMessage& dataMsg) { - int intData = 0, currentBit = 31; - bool method=0; - sscanf(dataMsg.getParameter("data").c_str(), "%X", &intData); - - int unit = 0; - int rawHouse = 0; - for(int i = 0; i < 4; ++i) { - rawHouse >>= 1; - if (checkBit(intData, currentBit--)) { - rawHouse |= 0x8; - } - } - - if (checkBit(intData, currentBit--) != 0) { - return ""; - } - - if (checkBit(intData, currentBit--)) { - unit |= (1<<3); - } - - if (checkBit(intData, currentBit--)) { - return ""; - } - if (checkBit(intData, currentBit--)) { - return ""; - } - - currentBit = 14; - - if (checkBit(intData, currentBit--)) { - unit |= (1<<2); - } - if (checkBit(intData, currentBit--)) { - method = 1; - } - if (checkBit(intData, currentBit--)) { - unit |= (1<<0); - } - if (checkBit(intData, currentBit--)) { - unit |= (1<<1); - } - - int intHouse = 0; - for(int i = 0; i < 16; ++i) { - if (HOUSES[i] == rawHouse) { - intHouse = i; - break; - } - } - - std::stringstream retString; - retString << "class:command;protocol:x10;model:codeswitch;"; - retString << "house:" << (char)('A' + intHouse); - retString << ";unit:" << unit+1; - retString << ";method:"; - if(method == 0){ - retString << "turnon;"; - } else { - retString << "turnoff;"; - } - - return retString.str(); -} +#include "ProtocolX10.h" +#include +#include + +const unsigned char HOUSES[] = {6,0xE,2,0xA,1,9,5,0xD,7,0xF,3,0xB,0,8,4,0xC}; + +int ProtocolX10::methods() const { + return TELLSTICK_TURNON | TELLSTICK_TURNOFF; +} + +std::string ProtocolX10::getStringForMethod(int method, unsigned char data, Controller *controller) { + const unsigned char S = 59, L = 169; + const char B0[] = {S,S,0}; + const char B1[] = {S,L,0}; + const unsigned char START_CODE[] = {'S',255,1,255,1,255,1,100,255,1,180,0}; + const unsigned char STOP_CODE[] = {S,0}; + + std::string strReturn = reinterpret_cast(START_CODE); + std::string strComplement = ""; + + std::wstring strHouse = getStringParameter(L"house", L"A"); + int intHouse = strHouse[0] - L'A'; + if (intHouse < 0) { + intHouse = 0; + } else if (intHouse > 15) { + intHouse = 15; + } + //Translate it + intHouse = HOUSES[intHouse]; + int intCode = getIntParameter(L"unit", 1, 16)-1; + + for( int i = 0; i < 4; ++i ) { + if (intHouse & 1) { + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + intHouse >>= 1; + } + strReturn.append( B0 ); + strComplement.append( B1 ); + + if (intCode >= 8) { + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + strReturn.append( B0 ); + strComplement.append( B1 ); + strReturn.append( B0 ); + strComplement.append( B1 ); + + strReturn.append( strComplement ); + strComplement = ""; + + strReturn.append( B0 ); + strComplement.append( B1 ); + + if (intCode >> 2 & 1) { //Bit 2 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + if (method == TELLSTICK_TURNON) { + strReturn.append(B0); + strComplement.append(B1); + } else if (method == TELLSTICK_TURNOFF) { + strReturn.append(B1); + strComplement.append(B0); + } else { + return ""; + } + + if (intCode & 1) { //Bit 0 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + if (intCode >> 1 & 1) { //Bit 1 of intCode + strReturn.append(B1); + strComplement.append(B0); + } else { + strReturn.append(B0); + strComplement.append(B1); + } + + for( int i = 0; i < 3; ++i ) { + strReturn.append( B0 ); + strComplement.append( B1 ); + } + + strReturn.append( strComplement ); + strReturn.append( reinterpret_cast(STOP_CODE) ); + strReturn.append("+"); + return strReturn; + +} + +std::string ProtocolX10::decodeData(ControllerMessage& dataMsg) { + int intData = 0, currentBit = 31; + bool method=0; + sscanf(dataMsg.getParameter("data").c_str(), "%X", &intData); + + int unit = 0; + int rawHouse = 0; + for(int i = 0; i < 4; ++i) { + rawHouse >>= 1; + if (checkBit(intData, currentBit--)) { + rawHouse |= 0x8; + } + } + + if (checkBit(intData, currentBit--) != 0) { + return ""; + } + + if (checkBit(intData, currentBit--)) { + unit |= (1<<3); + } + + if (checkBit(intData, currentBit--)) { + return ""; + } + if (checkBit(intData, currentBit--)) { + return ""; + } + + currentBit = 14; + + if (checkBit(intData, currentBit--)) { + unit |= (1<<2); + } + if (checkBit(intData, currentBit--)) { + method = 1; + } + if (checkBit(intData, currentBit--)) { + unit |= (1<<0); + } + if (checkBit(intData, currentBit--)) { + unit |= (1<<1); + } + + int intHouse = 0; + for(int i = 0; i < 16; ++i) { + if (HOUSES[i] == rawHouse) { + intHouse = i; + break; + } + } + + std::stringstream retString; + retString << "class:command;protocol:x10;model:codeswitch;"; + retString << "house:" << (char)('A' + intHouse); + retString << ";unit:" << unit+1; + retString << ";method:"; + if(method == 0){ + retString << "turnon;"; + } else { + retString << "turnoff;"; + } + + return retString.str(); +} diff --git a/telldus-core/service/ProtocolYidong.cpp b/telldus-core/service/ProtocolYidong.cpp index 3961a29c..e0310d08 100644 --- a/telldus-core/service/ProtocolYidong.cpp +++ b/telldus-core/service/ProtocolYidong.cpp @@ -1,24 +1,24 @@ -#include "ProtocolYidong.h" - -std::string ProtocolYidong::getStringForMethod(int method, unsigned char, Controller *) { - int intCode = this->getIntParameter(L"unit", 1, 4); - std::wstring strCode = L"111"; - - switch(intCode) { - case 1: - strCode.append(L"0010"); - break; - case 2: - strCode.append(L"0001"); - break; - case 3: - strCode.append(L"0100"); - break; - case 4: - strCode.append(L"1000"); - break; - } - - strCode.append(L"110"); - return getStringForCode(strCode, method); -} +#include "ProtocolYidong.h" + +std::string ProtocolYidong::getStringForMethod(int method, unsigned char, Controller *) { + int intCode = this->getIntParameter(L"unit", 1, 4); + std::wstring strCode = L"111"; + + switch(intCode) { + case 1: + strCode.append(L"0010"); + break; + case 2: + strCode.append(L"0001"); + break; + case 3: + strCode.append(L"0100"); + break; + case 4: + strCode.append(L"1000"); + break; + } + + strCode.append(L"110"); + return getStringForCode(strCode, method); +} diff --git a/telldus-core/service/SettingsWinRegistry.cpp b/telldus-core/service/SettingsWinRegistry.cpp index 639335f6..86f43132 100644 --- a/telldus-core/service/SettingsWinRegistry.cpp +++ b/telldus-core/service/SettingsWinRegistry.cpp @@ -1,272 +1,272 @@ -#include "Settings.h" -#include "Strings.h" -#include -#include -#include -#include -#include -#include -#include "common.h" - -#include "../client/telldus-core.h" - -const int intMaxRegValueLength = 1000; - -class Settings::PrivateData { -public: - HKEY rootKey; - std::wstring strRegPath; - std::wstring getNodePath(Settings::Node type); -}; - -std::wstring Settings::PrivateData::getNodePath(Settings::Node type) { - if (type == Settings::Device) { - return L"SOFTWARE\\Telldus\\Devices\\"; - } else if (type == Settings::Controller) { - return L"SOFTWARE\\Telldus\\Controllers\\"; - } - return L""; -} - -/* -* Constructor -*/ -Settings::Settings(void) { - d = new PrivateData(); - d->strRegPath = L"SOFTWARE\\Telldus\\"; - d->rootKey = HKEY_LOCAL_MACHINE; -} - -/* -* Destructor -*/ -Settings::~Settings(void) { - delete d; -} - -/* -* Return the number of stored devices -*/ -int Settings::getNumberOfNodes(Node type) const { +#include "Settings.h" +#include "Strings.h" +#include +#include +#include +#include +#include +#include +#include "common.h" + +#include "../client/telldus-core.h" + +const int intMaxRegValueLength = 1000; + +class Settings::PrivateData { +public: + HKEY rootKey; + std::wstring strRegPath; + std::wstring getNodePath(Settings::Node type); +}; + +std::wstring Settings::PrivateData::getNodePath(Settings::Node type) { + if (type == Settings::Device) { + return L"SOFTWARE\\Telldus\\Devices\\"; + } else if (type == Settings::Controller) { + return L"SOFTWARE\\Telldus\\Controllers\\"; + } + return L""; +} + +/* +* Constructor +*/ +Settings::Settings(void) { + d = new PrivateData(); + d->strRegPath = L"SOFTWARE\\Telldus\\"; + d->rootKey = HKEY_LOCAL_MACHINE; +} + +/* +* Destructor +*/ +Settings::~Settings(void) { + delete d; +} + +/* +* Return the number of stored devices +*/ +int Settings::getNumberOfNodes(Node type) const { TelldusCore::MutexLocker locker(&mutex); - - int intNumberOfNodes = 0; - HKEY hk; - - long lnExists = RegOpenKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, KEY_QUERY_VALUE, &hk); - - if(lnExists == ERROR_SUCCESS){ - - std::wstring strNumSubKeys; - DWORD dNumSubKeys; - RegQueryInfoKey(hk, NULL, NULL, NULL, &dNumSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - - intNumberOfNodes = (int)dNumSubKeys; - - RegCloseKey(hk); - } - return intNumberOfNodes; -} - - -int Settings::getNodeId(Node type, int intNodeIndex) const { + + int intNumberOfNodes = 0; + HKEY hk; + + long lnExists = RegOpenKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, KEY_QUERY_VALUE, &hk); + + if(lnExists == ERROR_SUCCESS){ + + std::wstring strNumSubKeys; + DWORD dNumSubKeys; + RegQueryInfoKey(hk, NULL, NULL, NULL, &dNumSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + intNumberOfNodes = (int)dNumSubKeys; + + RegCloseKey(hk); + } + return intNumberOfNodes; +} + + +int Settings::getNodeId(Node type, int intNodeIndex) const { TelldusCore::MutexLocker locker(&mutex); - - int intReturn = -1; - HKEY hk; - - long lnExists = RegOpenKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, KEY_READ, &hk); - - if(lnExists == ERROR_SUCCESS){ - - wchar_t* Buff = new wchar_t[intMaxRegValueLength]; - DWORD size = intMaxRegValueLength; - if (RegEnumKeyEx(hk, intNodeIndex, (LPWSTR)Buff, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - intReturn = _wtoi(Buff); - } - - delete[] Buff; - RegCloseKey(hk); - } - return intReturn; -} - -/* -* Add a new node -*/ -int Settings::addNode(Node type) { + + int intReturn = -1; + HKEY hk; + + long lnExists = RegOpenKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, KEY_READ, &hk); + + if(lnExists == ERROR_SUCCESS){ + + wchar_t* Buff = new wchar_t[intMaxRegValueLength]; + DWORD size = intMaxRegValueLength; + if (RegEnumKeyEx(hk, intNodeIndex, (LPWSTR)Buff, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + intReturn = _wtoi(Buff); + } + + delete[] Buff; + RegCloseKey(hk); + } + return intReturn; +} + +/* +* Add a new node +*/ +int Settings::addNode(Node type) { TelldusCore::MutexLocker locker(&mutex); - - int intNodeId = -1; - HKEY hk; - - DWORD dwDisp; - intNodeId = getNextNodeId(type); - - std::wstring strCompleteRegPath = d->getNodePath(type); - strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); - - if (RegCreateKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) { - //fail - intNodeId = -1; - } - - RegCloseKey(hk); - return intNodeId; -} - -/* -* Get next available device id -*/ -int Settings::getNextNodeId(Node type) const { - //Private, no locks needed - int intReturn = -1; - HKEY hk; - DWORD dwDisp; - - long lnExists = RegCreateKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDisp); //create or open if already created - - if(lnExists == ERROR_SUCCESS){ - - DWORD dwLength = sizeof(DWORD); - DWORD nResult(0); - - long lngStatus = RegQueryValueEx(hk, L"LastUsedId", NULL, NULL, reinterpret_cast(&nResult), &dwLength); - - if(lngStatus == ERROR_SUCCESS){ - intReturn = nResult + 1; - } else { - intReturn = 1; - } - DWORD dwVal = intReturn; - RegSetValueEx (hk, L"LastUsedId", 0L, REG_DWORD, (CONST BYTE*) &dwVal, sizeof(DWORD)); - - } - RegCloseKey(hk); - return intReturn; -} - -/* -* Remove a device -*/ -int Settings::removeNode(Node type, int intNodeId) { + + int intNodeId = -1; + HKEY hk; + + DWORD dwDisp; + intNodeId = getNextNodeId(type); + + std::wstring strCompleteRegPath = d->getNodePath(type); + strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); + + if (RegCreateKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) { + //fail + intNodeId = -1; + } + + RegCloseKey(hk); + return intNodeId; +} + +/* +* Get next available device id +*/ +int Settings::getNextNodeId(Node type) const { + //Private, no locks needed + int intReturn = -1; + HKEY hk; + DWORD dwDisp; + + long lnExists = RegCreateKeyEx(d->rootKey, d->getNodePath(type).c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDisp); //create or open if already created + + if(lnExists == ERROR_SUCCESS){ + + DWORD dwLength = sizeof(DWORD); + DWORD nResult(0); + + long lngStatus = RegQueryValueEx(hk, L"LastUsedId", NULL, NULL, reinterpret_cast(&nResult), &dwLength); + + if(lngStatus == ERROR_SUCCESS){ + intReturn = nResult + 1; + } else { + intReturn = 1; + } + DWORD dwVal = intReturn; + RegSetValueEx (hk, L"LastUsedId", 0L, REG_DWORD, (CONST BYTE*) &dwVal, sizeof(DWORD)); + + } + RegCloseKey(hk); + return intReturn; +} + +/* +* Remove a device +*/ +int Settings::removeNode(Node type, int intNodeId) { TelldusCore::MutexLocker locker(&mutex); - - std::wstring strCompleteRegPath = d->getNodePath(type); - strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); - - long lngSuccess = RegDeleteKey(d->rootKey, strCompleteRegPath.c_str()); - - if(lngSuccess == ERROR_SUCCESS){ - //one of the deletions succeeded - return TELLSTICK_SUCCESS; - } - - return TELLSTICK_ERROR_UNKNOWN; -} - -std::wstring Settings::getSetting(const std::wstring &strName) const{ - std::wstring strReturn; - HKEY hk; - - std::wstring strCompleteRegPath = d->strRegPath; - long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_QUERY_VALUE, &hk); - - if(lnExists == ERROR_SUCCESS){ - wchar_t* Buff = new wchar_t[intMaxRegValueLength]; - DWORD dwLength = sizeof(wchar_t)*intMaxRegValueLength; - long lngStatus = RegQueryValueEx(hk, strName.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); - - if(lngStatus == ERROR_MORE_DATA){ - //The buffer is to small, recreate it - delete[] Buff; - Buff = new wchar_t[dwLength]; - lngStatus = RegQueryValueEx(hk, strName.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); - } - if (lngStatus == ERROR_SUCCESS) { - strReturn = Buff; - } - delete[] Buff; - } - RegCloseKey(hk); - return strReturn; -} - -std::wstring Settings::getStringSetting(Node type, int intNodeId, const std::wstring &name, bool parameter) const { - std::wstring strReturn; - HKEY hk; - - std::wstring strCompleteRegPath = d->getNodePath(type); - strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); - long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_QUERY_VALUE, &hk); - - if(lnExists == ERROR_SUCCESS){ - wchar_t* Buff = new wchar_t[intMaxRegValueLength]; - DWORD dwLength = sizeof(wchar_t)*intMaxRegValueLength; - long lngStatus = RegQueryValueEx(hk, name.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); - - if(lngStatus == ERROR_MORE_DATA){ - //The buffer is to small, recreate it - delete[] Buff; - Buff = new wchar_t[dwLength]; - lngStatus = RegQueryValueEx(hk, name.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); - } - if (lngStatus == ERROR_SUCCESS) { - strReturn = Buff; - } - delete[] Buff; - } - RegCloseKey(hk); - return strReturn; -} - -int Settings::setStringSetting(Node type, int intNodeId, const std::wstring &name, const std::wstring &value, bool parameter) { - - HKEY hk; - int ret = TELLSTICK_SUCCESS; - - std::wstring strNodeId = TelldusCore::intToWstring(intNodeId); - std::wstring strCompleteRegPath = d->getNodePath(type); - strCompleteRegPath.append(strNodeId); - long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk); - - if (lnExists == ERROR_SUCCESS){ - int length = (int)value.length() * sizeof(wchar_t); - RegSetValueEx(hk, name.c_str(), 0, REG_SZ, (LPBYTE)value.c_str(), length+1); - } else { - ret = TELLSTICK_ERROR_UNKNOWN; - } - RegCloseKey(hk); - - return ret; - -} - -int Settings::getIntSetting(Node type, int intNodeId, const std::wstring &name, bool parameter) const { - int intReturn = 0; - - std::wstring strSetting = getStringSetting(type, intNodeId, name, parameter); - if (strSetting.length()) { - intReturn = (int)strSetting[0]; //TODO: do real conversion instead - } - - return intReturn; -} - -int Settings::setIntSetting(Node type, int intNodeId, const std::wstring &name, int value, bool parameter) { - int intReturn = TELLSTICK_ERROR_UNKNOWN; - HKEY hk; - - std::wstring strCompleteRegPath = d->getNodePath(type); - strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); - long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk); - if (lnExists == ERROR_SUCCESS) { - DWORD dwVal = value; - lnExists = RegSetValueEx (hk, name.c_str(), 0L, REG_DWORD, (CONST BYTE*) &dwVal, sizeof(DWORD)); - if (lnExists == ERROR_SUCCESS) { - intReturn = TELLSTICK_SUCCESS; - } - } - RegCloseKey(hk); - return intReturn; -} + + std::wstring strCompleteRegPath = d->getNodePath(type); + strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); + + long lngSuccess = RegDeleteKey(d->rootKey, strCompleteRegPath.c_str()); + + if(lngSuccess == ERROR_SUCCESS){ + //one of the deletions succeeded + return TELLSTICK_SUCCESS; + } + + return TELLSTICK_ERROR_UNKNOWN; +} + +std::wstring Settings::getSetting(const std::wstring &strName) const{ + std::wstring strReturn; + HKEY hk; + + std::wstring strCompleteRegPath = d->strRegPath; + long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_QUERY_VALUE, &hk); + + if(lnExists == ERROR_SUCCESS){ + wchar_t* Buff = new wchar_t[intMaxRegValueLength]; + DWORD dwLength = sizeof(wchar_t)*intMaxRegValueLength; + long lngStatus = RegQueryValueEx(hk, strName.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); + + if(lngStatus == ERROR_MORE_DATA){ + //The buffer is to small, recreate it + delete[] Buff; + Buff = new wchar_t[dwLength]; + lngStatus = RegQueryValueEx(hk, strName.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); + } + if (lngStatus == ERROR_SUCCESS) { + strReturn = Buff; + } + delete[] Buff; + } + RegCloseKey(hk); + return strReturn; +} + +std::wstring Settings::getStringSetting(Node type, int intNodeId, const std::wstring &name, bool parameter) const { + std::wstring strReturn; + HKEY hk; + + std::wstring strCompleteRegPath = d->getNodePath(type); + strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); + long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_QUERY_VALUE, &hk); + + if(lnExists == ERROR_SUCCESS){ + wchar_t* Buff = new wchar_t[intMaxRegValueLength]; + DWORD dwLength = sizeof(wchar_t)*intMaxRegValueLength; + long lngStatus = RegQueryValueEx(hk, name.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); + + if(lngStatus == ERROR_MORE_DATA){ + //The buffer is to small, recreate it + delete[] Buff; + Buff = new wchar_t[dwLength]; + lngStatus = RegQueryValueEx(hk, name.c_str(), NULL, NULL, (LPBYTE)Buff, &dwLength); + } + if (lngStatus == ERROR_SUCCESS) { + strReturn = Buff; + } + delete[] Buff; + } + RegCloseKey(hk); + return strReturn; +} + +int Settings::setStringSetting(Node type, int intNodeId, const std::wstring &name, const std::wstring &value, bool parameter) { + + HKEY hk; + int ret = TELLSTICK_SUCCESS; + + std::wstring strNodeId = TelldusCore::intToWstring(intNodeId); + std::wstring strCompleteRegPath = d->getNodePath(type); + strCompleteRegPath.append(strNodeId); + long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk); + + if (lnExists == ERROR_SUCCESS){ + int length = (int)value.length() * sizeof(wchar_t); + RegSetValueEx(hk, name.c_str(), 0, REG_SZ, (LPBYTE)value.c_str(), length+1); + } else { + ret = TELLSTICK_ERROR_UNKNOWN; + } + RegCloseKey(hk); + + return ret; + +} + +int Settings::getIntSetting(Node type, int intNodeId, const std::wstring &name, bool parameter) const { + int intReturn = 0; + + std::wstring strSetting = getStringSetting(type, intNodeId, name, parameter); + if (strSetting.length()) { + intReturn = (int)strSetting[0]; //TODO: do real conversion instead + } + + return intReturn; +} + +int Settings::setIntSetting(Node type, int intNodeId, const std::wstring &name, int value, bool parameter) { + int intReturn = TELLSTICK_ERROR_UNKNOWN; + HKEY hk; + + std::wstring strCompleteRegPath = d->getNodePath(type); + strCompleteRegPath.append(TelldusCore::intToWstring(intNodeId)); + long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk); + if (lnExists == ERROR_SUCCESS) { + DWORD dwVal = value; + lnExists = RegSetValueEx (hk, name.c_str(), 0L, REG_DWORD, (CONST BYTE*) &dwVal, sizeof(DWORD)); + if (lnExists == ERROR_SUCCESS) { + intReturn = TELLSTICK_SUCCESS; + } + } + RegCloseKey(hk); + return intReturn; +} diff --git a/telldus-core/service/TellStick_ftd2xx.cpp b/telldus-core/service/TellStick_ftd2xx.cpp index a10e71f3..d4d8efc4 100644 --- a/telldus-core/service/TellStick_ftd2xx.cpp +++ b/telldus-core/service/TellStick_ftd2xx.cpp @@ -55,8 +55,8 @@ TellStick::TellStick(int controllerId, TelldusCore::EventRef event, TelldusCore: d->vid = td.vid; d->pid = td.pid; d->serial = td.serial; - Settings set; - d->ignoreControllerConfirmation = set.getSetting(L"ignoreControllerConfirmation")==L"true"; + Settings set; + d->ignoreControllerConfirmation = set.getSetting(L"ignoreControllerConfirmation")==L"true"; char *tempSerial = new char[td.serial.size()+1]; #ifdef _WINDOWS @@ -112,13 +112,13 @@ int TellStick::pid() const { return d->pid; } -int TellStick::vid() const { - return d->vid; -} - -std::string TellStick::serial() const { - return d->serial; -} +int TellStick::vid() const { + return d->vid; +} + +std::string TellStick::serial() const { + return d->serial; +} bool TellStick::isOpen() const { return d->open; @@ -146,8 +146,8 @@ void TellStick::processData( const std::string &data ) { setFirmwareVersion(TelldusCore::charToInteger(d->message.substr(2).c_str())); } else if (d->message.substr(0,2).compare("+R") == 0) { this->publishData(d->message.substr(2)); - } else if(d->message.substr(0,2).compare("+W") == 0) { - this->decodePublishData(d->message.substr(2)); + } else if(d->message.substr(0,2).compare("+W") == 0) { + this->decodePublishData(d->message.substr(2)); } d->message.clear(); } else { // Append the character @@ -156,16 +156,16 @@ void TellStick::processData( const std::string &data ) { } } -int TellStick::reset(){ -#ifndef _WINDOWS - return TELLSTICK_SUCCESS; //nothing to be done on other platforms -#else - int success = FT_CyclePort( d->ftHandle ); - if(success == FT_OK){ - return TELLSTICK_SUCCESS; - } - return TELLSTICK_ERROR_UNKNOWN; -#endif +int TellStick::reset(){ +#ifndef _WINDOWS + return TELLSTICK_SUCCESS; //nothing to be done on other platforms +#else + int success = FT_CyclePort( d->ftHandle ); + if(success == FT_OK){ + return TELLSTICK_SUCCESS; + } + return TELLSTICK_ERROR_UNKNOWN; +#endif } void TellStick::run() { @@ -228,20 +228,20 @@ int TellStick::send( const std::string &strMessage ) { FT_STATUS ftStatus; ftStatus = FT_Write(d->ftHandle, tempMessage, (DWORD)strMessage.length(), &bytesWritten); free(tempMessage); - - if(ftStatus != FT_OK){ - Log::debug("Broken pipe on send"); - return TELLSTICK_ERROR_BROKEN_PIPE; - } - - if(strMessage.compare("N+") == 0 && ((pid() == 0x0C31 && firmwareVersion() < 5) || (pid() == 0x0C30 && firmwareVersion() < 6))){ - //these firmware versions doesn't implement ack to noop, just check that the noop can be sent correctly - return TELLSTICK_SUCCESS; + + if(ftStatus != FT_OK){ + Log::debug("Broken pipe on send"); + return TELLSTICK_ERROR_BROKEN_PIPE; } - if(d->ignoreControllerConfirmation){ - //wait for TellStick to finish its air-sending - msleep(1000); - return TELLSTICK_SUCCESS; + + if(strMessage.compare("N+") == 0 && ((pid() == 0x0C31 && firmwareVersion() < 5) || (pid() == 0x0C30 && firmwareVersion() < 6))){ + //these firmware versions doesn't implement ack to noop, just check that the noop can be sent correctly + return TELLSTICK_SUCCESS; + } + if(d->ignoreControllerConfirmation){ + //wait for TellStick to finish its air-sending + msleep(1000); + return TELLSTICK_SUCCESS; } while(1) { @@ -257,7 +257,7 @@ int TellStick::send( const std::string &strMessage ) { return TELLSTICK_ERROR_COMMUNICATION; } } else { //Error - Log::debug("Broken pipe on read"); + Log::debug("Broken pipe on read"); return TELLSTICK_ERROR_BROKEN_PIPE; } } diff --git a/telldus-core/service/TelldusMain.cpp b/telldus-core/service/TelldusMain.cpp index cb852ca5..a45f9899 100644 --- a/telldus-core/service/TelldusMain.cpp +++ b/telldus-core/service/TelldusMain.cpp @@ -1,142 +1,142 @@ -#include "TelldusMain.h" -#include "ConnectionListener.h" -#include "EventHandler.h" -#include "ClientCommunicationHandler.h" -#include "DeviceManager.h" -#include "ControllerManager.h" -#include "ControllerListener.h" -#include "EventUpdateManager.h" -#include "Timer.h" -#include "Log.h" - -#include -#include -#include - -class TelldusMain::PrivateData { -public: - TelldusCore::EventHandler eventHandler; - TelldusCore::EventRef stopEvent, controllerChangeEvent; -}; - -TelldusMain::TelldusMain(void) -{ - d = new PrivateData; - d->stopEvent = d->eventHandler.addEvent(); - d->controllerChangeEvent = d->eventHandler.addEvent(); -} - -TelldusMain::~TelldusMain(void) { - delete d; -} - -void TelldusMain::deviceInsertedOrRemoved(int vid, int pid, bool inserted) { - ControllerChangeEventData *data = new ControllerChangeEventData; - data->vid = vid; - data->pid = pid; - data->inserted = inserted; - d->controllerChangeEvent->signal(data); -} - -void TelldusMain::resume() { - Log::notice("Came back from suspend"); - ControllerChangeEventData *data = new ControllerChangeEventData; - data->vid = 0x0; - data->pid = 0x0; - data->inserted = true; - d->controllerChangeEvent->signal(data); -} - -void TelldusMain::suspend() { - Log::notice("Preparing for suspend"); - ControllerChangeEventData *data = new ControllerChangeEventData; - data->vid = 0x0; - data->pid = 0x0; - data->inserted = false; - d->controllerChangeEvent->signal(data); -} - -void TelldusMain::start(void) { - TelldusCore::EventRef clientEvent = d->eventHandler.addEvent(); - TelldusCore::EventRef dataEvent = d->eventHandler.addEvent(); - TelldusCore::EventRef janitor = d->eventHandler.addEvent(); //Used for regular cleanups - Timer supervisor(janitor); //Tells the janitor to go back to work - supervisor.setInterval(60); //Once every minute - supervisor.start(); - - EventUpdateManager eventUpdateManager; - TelldusCore::EventRef deviceUpdateEvent = eventUpdateManager.retrieveUpdateEvent(); - eventUpdateManager.start(); - ControllerManager controllerManager(dataEvent, deviceUpdateEvent); - DeviceManager deviceManager(&controllerManager, deviceUpdateEvent); - - ConnectionListener clientListener(L"TelldusClient", clientEvent); - - std::list clientCommunicationHandlerList; - - TelldusCore::EventRef handlerEvent = d->eventHandler.addEvent(); - -#ifdef _MACOSX - //This is only needed on OS X - ControllerListener controllerListener(d->controllerChangeEvent); -#endif - - - while(!d->stopEvent->isSignaled()) { - if (!d->eventHandler.waitForAny()) { - continue; - } - if (clientEvent->isSignaled()) { - //New client connection - TelldusCore::EventDataRef eventDataRef = clientEvent->takeSignal(); - ConnectionListenerEventData *data = reinterpret_cast(eventDataRef.get()); - if (data) { - ClientCommunicationHandler *clientCommunication = new ClientCommunicationHandler(data->socket, handlerEvent, &deviceManager, deviceUpdateEvent, &controllerManager); - clientCommunication->start(); - clientCommunicationHandlerList.push_back(clientCommunication); - } - } - - if (d->controllerChangeEvent->isSignaled()) { - TelldusCore::EventDataRef eventDataRef = d->controllerChangeEvent->takeSignal(); - ControllerChangeEventData *data = reinterpret_cast(eventDataRef.get()); - if (data) { - controllerManager.deviceInsertedOrRemoved(data->vid, data->pid, "", data->inserted); - } - } - - if (dataEvent->isSignaled()) { - TelldusCore::EventDataRef eventData = dataEvent->takeSignal(); - ControllerEventData *data = reinterpret_cast(eventData.get()); - if (data) { - deviceManager.handleControllerMessage(*data); - } - } - - if (handlerEvent->isSignaled()) { - handlerEvent->popSignal(); - for ( std::list::iterator it = clientCommunicationHandlerList.begin(); it != clientCommunicationHandlerList.end(); ){ - if ((*it)->isDone()){ - delete *it; - it = clientCommunicationHandlerList.erase(it); - - } else { - ++it; - } - } - } - if (janitor->isSignaled()) { - //Clear all of them if there is more than one - while(janitor->isSignaled()) { - janitor->popSignal(); - } - controllerManager.queryControllerStatus(); - } - } - - supervisor.stop(); -} - -void TelldusMain::stop(void){ - d->stopEvent->signal(); -} +#include "TelldusMain.h" +#include "ConnectionListener.h" +#include "EventHandler.h" +#include "ClientCommunicationHandler.h" +#include "DeviceManager.h" +#include "ControllerManager.h" +#include "ControllerListener.h" +#include "EventUpdateManager.h" +#include "Timer.h" +#include "Log.h" + +#include +#include +#include + +class TelldusMain::PrivateData { +public: + TelldusCore::EventHandler eventHandler; + TelldusCore::EventRef stopEvent, controllerChangeEvent; +}; + +TelldusMain::TelldusMain(void) +{ + d = new PrivateData; + d->stopEvent = d->eventHandler.addEvent(); + d->controllerChangeEvent = d->eventHandler.addEvent(); +} + +TelldusMain::~TelldusMain(void) { + delete d; +} + +void TelldusMain::deviceInsertedOrRemoved(int vid, int pid, bool inserted) { + ControllerChangeEventData *data = new ControllerChangeEventData; + data->vid = vid; + data->pid = pid; + data->inserted = inserted; + d->controllerChangeEvent->signal(data); +} + +void TelldusMain::resume() { + Log::notice("Came back from suspend"); + ControllerChangeEventData *data = new ControllerChangeEventData; + data->vid = 0x0; + data->pid = 0x0; + data->inserted = true; + d->controllerChangeEvent->signal(data); +} + +void TelldusMain::suspend() { + Log::notice("Preparing for suspend"); + ControllerChangeEventData *data = new ControllerChangeEventData; + data->vid = 0x0; + data->pid = 0x0; + data->inserted = false; + d->controllerChangeEvent->signal(data); +} + +void TelldusMain::start(void) { + TelldusCore::EventRef clientEvent = d->eventHandler.addEvent(); + TelldusCore::EventRef dataEvent = d->eventHandler.addEvent(); + TelldusCore::EventRef janitor = d->eventHandler.addEvent(); //Used for regular cleanups + Timer supervisor(janitor); //Tells the janitor to go back to work + supervisor.setInterval(60); //Once every minute + supervisor.start(); + + EventUpdateManager eventUpdateManager; + TelldusCore::EventRef deviceUpdateEvent = eventUpdateManager.retrieveUpdateEvent(); + eventUpdateManager.start(); + ControllerManager controllerManager(dataEvent, deviceUpdateEvent); + DeviceManager deviceManager(&controllerManager, deviceUpdateEvent); + + ConnectionListener clientListener(L"TelldusClient", clientEvent); + + std::list clientCommunicationHandlerList; + + TelldusCore::EventRef handlerEvent = d->eventHandler.addEvent(); + +#ifdef _MACOSX + //This is only needed on OS X + ControllerListener controllerListener(d->controllerChangeEvent); +#endif + + + while(!d->stopEvent->isSignaled()) { + if (!d->eventHandler.waitForAny()) { + continue; + } + if (clientEvent->isSignaled()) { + //New client connection + TelldusCore::EventDataRef eventDataRef = clientEvent->takeSignal(); + ConnectionListenerEventData *data = reinterpret_cast(eventDataRef.get()); + if (data) { + ClientCommunicationHandler *clientCommunication = new ClientCommunicationHandler(data->socket, handlerEvent, &deviceManager, deviceUpdateEvent, &controllerManager); + clientCommunication->start(); + clientCommunicationHandlerList.push_back(clientCommunication); + } + } + + if (d->controllerChangeEvent->isSignaled()) { + TelldusCore::EventDataRef eventDataRef = d->controllerChangeEvent->takeSignal(); + ControllerChangeEventData *data = reinterpret_cast(eventDataRef.get()); + if (data) { + controllerManager.deviceInsertedOrRemoved(data->vid, data->pid, "", data->inserted); + } + } + + if (dataEvent->isSignaled()) { + TelldusCore::EventDataRef eventData = dataEvent->takeSignal(); + ControllerEventData *data = reinterpret_cast(eventData.get()); + if (data) { + deviceManager.handleControllerMessage(*data); + } + } + + if (handlerEvent->isSignaled()) { + handlerEvent->popSignal(); + for ( std::list::iterator it = clientCommunicationHandlerList.begin(); it != clientCommunicationHandlerList.end(); ){ + if ((*it)->isDone()){ + delete *it; + it = clientCommunicationHandlerList.erase(it); + + } else { + ++it; + } + } + } + if (janitor->isSignaled()) { + //Clear all of them if there is more than one + while(janitor->isSignaled()) { + janitor->popSignal(); + } + controllerManager.queryControllerStatus(); + } + } + + supervisor.stop(); +} + +void TelldusMain::stop(void){ + d->stopEvent->signal(); +} diff --git a/telldus-core/service/TelldusMain.h b/telldus-core/service/TelldusMain.h index 13f19486..19f08a4a 100644 --- a/telldus-core/service/TelldusMain.h +++ b/telldus-core/service/TelldusMain.h @@ -1,23 +1,23 @@ -#ifndef TELLDUSMAIN_H -#define TELLDUSMAIN_H - -class TelldusMain -{ -public: - TelldusMain(void); - ~TelldusMain(void); - - void start(); - void stop(); - - //Thread safe! - void deviceInsertedOrRemoved(int vid, int pid, bool inserted); - void resume(); - void suspend(); - -private: - class PrivateData; - PrivateData *d; -}; - -#endif //TELLDUSMAIN_H +#ifndef TELLDUSMAIN_H +#define TELLDUSMAIN_H + +class TelldusMain +{ +public: + TelldusMain(void); + ~TelldusMain(void); + + void start(); + void stop(); + + //Thread safe! + void deviceInsertedOrRemoved(int vid, int pid, bool inserted); + void resume(); + void suspend(); + +private: + class PrivateData; + PrivateData *d; +}; + +#endif //TELLDUSMAIN_H diff --git a/telldus-core/service/TelldusWinService_win.cpp b/telldus-core/service/TelldusWinService_win.cpp index 3fb51221..b122a5c1 100644 --- a/telldus-core/service/TelldusWinService_win.cpp +++ b/telldus-core/service/TelldusWinService_win.cpp @@ -1,177 +1,177 @@ -#include "TelldusWinService_win.h" -#include "TelldusMain.h" -#include "Log.h" - -#include -#include -#include - -int g_argc; -char **g_argv; - - -static const GUID GUID_DEVINTERFACE_USBRAW = -{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; - -TelldusWinService::TelldusWinService() - :tm(0) -{ - tm = new TelldusMain(); -} - -TelldusWinService::~TelldusWinService() { - delete tm; -} - - -void TelldusWinService::stop() { - tm->stop(); -} - -DWORD WINAPI TelldusWinService::serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ) { - switch ( controlCode ) { - case SERVICE_CONTROL_INTERROGATE: - SetServiceStatus( serviceStatusHandle, &serviceStatus ); - return NO_ERROR; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - stop(); - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus( serviceStatusHandle, &serviceStatus ); - - return NO_ERROR; - case SERVICE_CONTROL_POWEREVENT: - if (dwEventType == PBT_APMSUSPEND) { - tm->suspend(); - } else if (dwEventType == PBT_APMRESUMEAUTOMATIC) { - tm->resume(); - } - return NO_ERROR; - } - return ERROR_CALL_NOT_IMPLEMENTED; -} - -DWORD WINAPI TelldusWinService::deviceNotificationHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ) { - if (controlCode != SERVICE_CONTROL_DEVICEEVENT) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - - if (dwEventType != DBT_DEVICEARRIVAL && dwEventType != DBT_DEVICEREMOVECOMPLETE) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - - PDEV_BROADCAST_DEVICEINTERFACE pDevInf = reinterpret_cast(lpEventData); - if (!pDevInf) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - - std::wstring name(pDevInf->dbcc_name); - transform(name.begin(), name.end(), name.begin(), toupper); - - //Parse VID - size_t posStart = name.find(L"VID_"); - if (posStart == std::wstring::npos) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - posStart += 4; - size_t posEnd = name.find(L'&', posStart); - if (posEnd == std::wstring::npos) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - std::wstring strVID = name.substr(posStart, posEnd-posStart); - - //Parse PID - posStart = name.find(L"PID_"); - if (posStart == std::wstring::npos) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - posStart += 4; - posEnd = name.find(L'#', posStart); - if (posEnd == std::wstring::npos) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - std::wstring strPID = name.substr(posStart, posEnd-posStart); - - long int vid = strtol(std::string(strVID.begin(), strVID.end()).c_str(), NULL, 16); - long int pid = strtol(std::string(strPID.begin(), strPID.end()).c_str(), NULL, 16); - - if (dwEventType == DBT_DEVICEARRIVAL) { - tm->deviceInsertedOrRemoved(vid, pid, true); - } else { - tm->deviceInsertedOrRemoved(vid, pid, false); - } - - return NO_ERROR; -} - -DWORD WINAPI TelldusWinService::serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { - TelldusWinService *instance = reinterpret_cast(lpContext); - if (!instance) { - return ERROR_CALL_NOT_IMPLEMENTED; - } - if (controlCode == SERVICE_CONTROL_DEVICEEVENT) { - return instance->deviceNotificationHandler(controlCode, dwEventType, lpEventData); - } - return instance->serviceControlHandler(controlCode, dwEventType, lpEventData); -} - -void WINAPI TelldusWinService::serviceMain( DWORD argc, TCHAR* argv[] ) { - TelldusWinService instance; - - //Enable debug if we hade this supplied - for(unsigned int i = 1; i < argc; ++i) { - if (wcscmp(argv[i], L"--debug") == 0) { - Log::setDebug(); - } - } - - // initialise service status - instance.serviceStatus.dwServiceType = SERVICE_WIN32; - instance.serviceStatus.dwCurrentState = SERVICE_STOPPED; - instance.serviceStatus.dwControlsAccepted = 0; - instance.serviceStatus.dwWin32ExitCode = NO_ERROR; - instance.serviceStatus.dwServiceSpecificExitCode = NO_ERROR; - instance.serviceStatus.dwCheckPoint = 0; - instance.serviceStatus.dwWaitHint = 0; - - instance.serviceStatusHandle = RegisterServiceCtrlHandlerEx( serviceName, TelldusWinService::serviceControlHandler, &instance ); - - if ( instance.serviceStatusHandle ) { - // service is starting - instance.serviceStatus.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); - - // running - instance.serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - // Register for power management notification - instance.serviceStatus.dwControlsAccepted |= SERVICE_ACCEPT_POWEREVENT; - instance.serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); - - // Register for device notification - DEV_BROADCAST_DEVICEINTERFACE devInterface; - ZeroMemory( &devInterface, sizeof(devInterface) ); - devInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); - devInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - devInterface.dbcc_classguid = GUID_DEVINTERFACE_USBRAW; - HDEVNOTIFY deviceNotificationHandle = RegisterDeviceNotificationW(instance.serviceStatusHandle, &devInterface, DEVICE_NOTIFY_SERVICE_HANDLE); - - Log::notice("TelldusService started"); - - //Start our main-loop - instance.tm->start(); - - Log::notice("TelldusService stopping"); - Log::destroy(); - - // service was stopped - instance.serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); - - // service is now stopped - instance.serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - instance.serviceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); - } -} +#include "TelldusWinService_win.h" +#include "TelldusMain.h" +#include "Log.h" + +#include +#include +#include + +int g_argc; +char **g_argv; + + +static const GUID GUID_DEVINTERFACE_USBRAW = +{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }; + +TelldusWinService::TelldusWinService() + :tm(0) +{ + tm = new TelldusMain(); +} + +TelldusWinService::~TelldusWinService() { + delete tm; +} + + +void TelldusWinService::stop() { + tm->stop(); +} + +DWORD WINAPI TelldusWinService::serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ) { + switch ( controlCode ) { + case SERVICE_CONTROL_INTERROGATE: + SetServiceStatus( serviceStatusHandle, &serviceStatus ); + return NO_ERROR; + + case SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL_STOP: + stop(); + serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus( serviceStatusHandle, &serviceStatus ); + + return NO_ERROR; + case SERVICE_CONTROL_POWEREVENT: + if (dwEventType == PBT_APMSUSPEND) { + tm->suspend(); + } else if (dwEventType == PBT_APMRESUMEAUTOMATIC) { + tm->resume(); + } + return NO_ERROR; + } + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD WINAPI TelldusWinService::deviceNotificationHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ) { + if (controlCode != SERVICE_CONTROL_DEVICEEVENT) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + + if (dwEventType != DBT_DEVICEARRIVAL && dwEventType != DBT_DEVICEREMOVECOMPLETE) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + + PDEV_BROADCAST_DEVICEINTERFACE pDevInf = reinterpret_cast(lpEventData); + if (!pDevInf) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + + std::wstring name(pDevInf->dbcc_name); + transform(name.begin(), name.end(), name.begin(), toupper); + + //Parse VID + size_t posStart = name.find(L"VID_"); + if (posStart == std::wstring::npos) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + posStart += 4; + size_t posEnd = name.find(L'&', posStart); + if (posEnd == std::wstring::npos) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + std::wstring strVID = name.substr(posStart, posEnd-posStart); + + //Parse PID + posStart = name.find(L"PID_"); + if (posStart == std::wstring::npos) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + posStart += 4; + posEnd = name.find(L'#', posStart); + if (posEnd == std::wstring::npos) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + std::wstring strPID = name.substr(posStart, posEnd-posStart); + + long int vid = strtol(std::string(strVID.begin(), strVID.end()).c_str(), NULL, 16); + long int pid = strtol(std::string(strPID.begin(), strPID.end()).c_str(), NULL, 16); + + if (dwEventType == DBT_DEVICEARRIVAL) { + tm->deviceInsertedOrRemoved(vid, pid, true); + } else { + tm->deviceInsertedOrRemoved(vid, pid, false); + } + + return NO_ERROR; +} + +DWORD WINAPI TelldusWinService::serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { + TelldusWinService *instance = reinterpret_cast(lpContext); + if (!instance) { + return ERROR_CALL_NOT_IMPLEMENTED; + } + if (controlCode == SERVICE_CONTROL_DEVICEEVENT) { + return instance->deviceNotificationHandler(controlCode, dwEventType, lpEventData); + } + return instance->serviceControlHandler(controlCode, dwEventType, lpEventData); +} + +void WINAPI TelldusWinService::serviceMain( DWORD argc, TCHAR* argv[] ) { + TelldusWinService instance; + + //Enable debug if we hade this supplied + for(unsigned int i = 1; i < argc; ++i) { + if (wcscmp(argv[i], L"--debug") == 0) { + Log::setDebug(); + } + } + + // initialise service status + instance.serviceStatus.dwServiceType = SERVICE_WIN32; + instance.serviceStatus.dwCurrentState = SERVICE_STOPPED; + instance.serviceStatus.dwControlsAccepted = 0; + instance.serviceStatus.dwWin32ExitCode = NO_ERROR; + instance.serviceStatus.dwServiceSpecificExitCode = NO_ERROR; + instance.serviceStatus.dwCheckPoint = 0; + instance.serviceStatus.dwWaitHint = 0; + + instance.serviceStatusHandle = RegisterServiceCtrlHandlerEx( serviceName, TelldusWinService::serviceControlHandler, &instance ); + + if ( instance.serviceStatusHandle ) { + // service is starting + instance.serviceStatus.dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); + + // running + instance.serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + // Register for power management notification + instance.serviceStatus.dwControlsAccepted |= SERVICE_ACCEPT_POWEREVENT; + instance.serviceStatus.dwCurrentState = SERVICE_RUNNING; + SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); + + // Register for device notification + DEV_BROADCAST_DEVICEINTERFACE devInterface; + ZeroMemory( &devInterface, sizeof(devInterface) ); + devInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + devInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + devInterface.dbcc_classguid = GUID_DEVINTERFACE_USBRAW; + HDEVNOTIFY deviceNotificationHandle = RegisterDeviceNotificationW(instance.serviceStatusHandle, &devInterface, DEVICE_NOTIFY_SERVICE_HANDLE); + + Log::notice("TelldusService started"); + + //Start our main-loop + instance.tm->start(); + + Log::notice("TelldusService stopping"); + Log::destroy(); + + // service was stopped + instance.serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); + + // service is now stopped + instance.serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); + instance.serviceStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus( instance.serviceStatusHandle, &instance.serviceStatus ); + } +} diff --git a/telldus-core/service/TelldusWinService_win.h b/telldus-core/service/TelldusWinService_win.h index 04a5df0c..5cd78104 100644 --- a/telldus-core/service/TelldusWinService_win.h +++ b/telldus-core/service/TelldusWinService_win.h @@ -1,35 +1,35 @@ -#ifndef TELLDUSSERVICE_WIN_H -#define TELLDUSSERVICE_WIN_H - -#include - -extern int g_argc; -extern char **g_argv; - -class TelldusMain; - -#define serviceName TEXT("TelldusCore") - -class TelldusWinService { -public: - TelldusWinService(); - ~TelldusWinService(); - - static void WINAPI serviceMain( DWORD /*argc*/, TCHAR* /*argv*/[] ); - -protected: - - void stop(); - - DWORD WINAPI serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ); - DWORD WINAPI deviceNotificationHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ); - -private: - TelldusMain *tm; - SERVICE_STATUS serviceStatus; - SERVICE_STATUS_HANDLE serviceStatusHandle; - - static DWORD WINAPI serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ); - -}; -#endif TELLDUSSERVICE_WIN_H +#ifndef TELLDUSSERVICE_WIN_H +#define TELLDUSSERVICE_WIN_H + +#include + +extern int g_argc; +extern char **g_argv; + +class TelldusMain; + +#define serviceName TEXT("TelldusCore") + +class TelldusWinService { +public: + TelldusWinService(); + ~TelldusWinService(); + + static void WINAPI serviceMain( DWORD /*argc*/, TCHAR* /*argv*/[] ); + +protected: + + void stop(); + + DWORD WINAPI serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ); + DWORD WINAPI deviceNotificationHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData ); + +private: + TelldusMain *tm; + SERVICE_STATUS serviceStatus; + SERVICE_STATUS_HANDLE serviceStatusHandle; + + static DWORD WINAPI serviceControlHandler( DWORD controlCode, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ); + +}; +#endif TELLDUSSERVICE_WIN_H diff --git a/telldus-core/service/Timer.cpp b/telldus-core/service/Timer.cpp index a31d0ad2..567befb0 100644 --- a/telldus-core/service/Timer.cpp +++ b/telldus-core/service/Timer.cpp @@ -1,114 +1,114 @@ -#include "Timer.h" -#include "Mutex.h" -#ifdef _WINDOWS -#else -#include -#include -#endif - -class Timer::PrivateData { -public: - PrivateData() : interval(0), running(false) {} - TelldusCore::EventRef event; - int interval; - bool running; -#ifdef _WINDOWS - HANDLE cond; - TelldusCore::Mutex mutex; -#else - pthread_mutex_t waitMutex; - pthread_cond_t cond; -#endif -}; - -Timer::Timer(TelldusCore::EventRef event) - :TelldusCore::Thread(), d(new PrivateData) -{ - d->event = event; -#ifdef _WINDOWS - d->cond = CreateEventW(NULL, false, false, NULL); -#else - pthread_cond_init(&d->cond, NULL); - pthread_mutex_init(&d->waitMutex, NULL); -#endif -} - -Timer::~Timer() { - this->stop(); - this->wait(); - -#ifdef _WINDOWS -#else - pthread_mutex_destroy(&d->waitMutex); - pthread_cond_destroy(&d->cond); - delete d; -#endif -} - -void Timer::setInterval(int sec) { - d->interval = sec; -} - -void Timer::stop() { -#ifdef _WINDOWS - TelldusCore::MutexLocker(&d->mutex); - d->running = false; - SetEvent(d->cond); -#else - //Signal event - pthread_mutex_lock(&d->waitMutex); - if (d->running) { - d->running = false; - pthread_cond_signal(&d->cond); - } - pthread_mutex_unlock(&d->waitMutex); -#endif -} - -void Timer::run() { -#ifdef _WINDOWS - int interval = 0; - { - TelldusCore::MutexLocker(&d->mutex); - d->running = true; - interval = d->interval*1000; - } - while(1) { - DWORD retval = WaitForSingleObject(d->cond, interval); - if (retval == WAIT_TIMEOUT) { - d->event->signal(); - } - TelldusCore::MutexLocker(&d->mutex); - if (!d->running) { - break; - } - } -#else - struct timespec ts; - struct timeval tp; - - pthread_mutex_lock(&d->waitMutex); - d->running = true; - pthread_mutex_unlock(&d->waitMutex); - - while(1) { - int rc = gettimeofday(&tp, NULL); - - ts.tv_sec = tp.tv_sec; - ts.tv_nsec = tp.tv_usec * 1000; - ts.tv_sec += d->interval; - - pthread_mutex_lock( &d->waitMutex ); - if (d->running) { - rc = pthread_cond_timedwait(&d->cond, &d->waitMutex, &ts); - } else { - pthread_mutex_unlock( &d->waitMutex ); - break; - } - pthread_mutex_unlock( &d->waitMutex ); - if (rc == ETIMEDOUT) { - d->event->signal(); - } - } -#endif -} +#include "Timer.h" +#include "Mutex.h" +#ifdef _WINDOWS +#else +#include +#include +#endif + +class Timer::PrivateData { +public: + PrivateData() : interval(0), running(false) {} + TelldusCore::EventRef event; + int interval; + bool running; +#ifdef _WINDOWS + HANDLE cond; + TelldusCore::Mutex mutex; +#else + pthread_mutex_t waitMutex; + pthread_cond_t cond; +#endif +}; + +Timer::Timer(TelldusCore::EventRef event) + :TelldusCore::Thread(), d(new PrivateData) +{ + d->event = event; +#ifdef _WINDOWS + d->cond = CreateEventW(NULL, false, false, NULL); +#else + pthread_cond_init(&d->cond, NULL); + pthread_mutex_init(&d->waitMutex, NULL); +#endif +} + +Timer::~Timer() { + this->stop(); + this->wait(); + +#ifdef _WINDOWS +#else + pthread_mutex_destroy(&d->waitMutex); + pthread_cond_destroy(&d->cond); + delete d; +#endif +} + +void Timer::setInterval(int sec) { + d->interval = sec; +} + +void Timer::stop() { +#ifdef _WINDOWS + TelldusCore::MutexLocker(&d->mutex); + d->running = false; + SetEvent(d->cond); +#else + //Signal event + pthread_mutex_lock(&d->waitMutex); + if (d->running) { + d->running = false; + pthread_cond_signal(&d->cond); + } + pthread_mutex_unlock(&d->waitMutex); +#endif +} + +void Timer::run() { +#ifdef _WINDOWS + int interval = 0; + { + TelldusCore::MutexLocker(&d->mutex); + d->running = true; + interval = d->interval*1000; + } + while(1) { + DWORD retval = WaitForSingleObject(d->cond, interval); + if (retval == WAIT_TIMEOUT) { + d->event->signal(); + } + TelldusCore::MutexLocker(&d->mutex); + if (!d->running) { + break; + } + } +#else + struct timespec ts; + struct timeval tp; + + pthread_mutex_lock(&d->waitMutex); + d->running = true; + pthread_mutex_unlock(&d->waitMutex); + + while(1) { + int rc = gettimeofday(&tp, NULL); + + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_sec += d->interval; + + pthread_mutex_lock( &d->waitMutex ); + if (d->running) { + rc = pthread_cond_timedwait(&d->cond, &d->waitMutex, &ts); + } else { + pthread_mutex_unlock( &d->waitMutex ); + break; + } + pthread_mutex_unlock( &d->waitMutex ); + if (rc == ETIMEDOUT) { + d->event->signal(); + } + } +#endif +} diff --git a/telldus-core/service/ftd2xx.h b/telldus-core/service/ftd2xx.h index f9d7b817..020aff93 100644 --- a/telldus-core/service/ftd2xx.h +++ b/telldus-core/service/ftd2xx.h @@ -1,15 +1,15 @@ - - -#ifdef LIBFTD2XX - #ifdef _WINDOWS - #include - #include "win\ftd2xx.h" - #else - #include "osx/WinTypes.h" - #include "osx/ftd2xx.h" - #endif -#endif - -#ifdef LIBFTDI - #include -#endif + + +#ifdef LIBFTD2XX + #ifdef _WINDOWS + #include + #include "win\ftd2xx.h" + #else + #include "osx/WinTypes.h" + #include "osx/ftd2xx.h" + #endif +#endif + +#ifdef LIBFTDI + #include +#endif diff --git a/telldus-core/service/main_win.cpp b/telldus-core/service/main_win.cpp index 95257b1e..018e61ee 100644 --- a/telldus-core/service/main_win.cpp +++ b/telldus-core/service/main_win.cpp @@ -1,20 +1,20 @@ -#include "TelldusWinService_win.h" -//#include - -#include -#include - - -int main(int argc, char **argv) { - g_argc = argc; - g_argv = argv; - - SERVICE_TABLE_ENTRY serviceTable[] = { - {serviceName, TelldusWinService::serviceMain }, - { 0, 0 } - }; - - StartServiceCtrlDispatcher( serviceTable ); - - return 0; -} +#include "TelldusWinService_win.h" +//#include + +#include +#include + + +int main(int argc, char **argv) { + g_argc = argc; + g_argv = argv; + + SERVICE_TABLE_ENTRY serviceTable[] = { + {serviceName, TelldusWinService::serviceMain }, + { 0, 0 } + }; + + StartServiceCtrlDispatcher( serviceTable ); + + return 0; +} diff --git a/telldus-core/service/win/ftd2xx.h b/telldus-core/service/win/ftd2xx.h index 96a4d318..d5bc3bff 100644 --- a/telldus-core/service/win/ftd2xx.h +++ b/telldus-core/service/win/ftd2xx.h @@ -1,963 +1,963 @@ -/*++ - -Copyright (c) 2001-2007 Future Technology Devices International Ltd. - -Module Name: - - ftd2xx.h - -Abstract: - - Native USB device driver for FTDI FT8U232/245 - FTD2XX library definitions - -Environment: - - kernel & user mode - -Revision History: - - 13/03/01 awm Created. - 13/01/03 awm Added device information support. - 19/03/03 awm Added FT_W32_CancelIo. - 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. - 18/09/03 awm Added FT_SetResetPipeRetryCount. - 10/10/03 awm Added FT_ResetPort. - 23/01/04 awm Added support for open-by-location. - 16/03/04 awm Added support for FT2232C. - 23/09/04 awm Added support for FT232R. - 20/10/04 awm Added FT_CyclePort. - 18/01/05 awm Added FT_DEVICE_LIST_INFO_NODE type. - 11/02/05 awm Added LocId to FT_DEVICE_LIST_INFO_NODE. - 25/08/05 awm Added FT_SetDeadmanTimeout. - 02/12/05 awm Removed obsolete references. - 05/12/05 awm Added FT_GetVersion, FT_GetVersionEx. - 08/09/06 awm Added FT_W32_GetCommMask. - 11/09/06 awm Added FT_Rescan. - 11/07/07 awm Added support for FT2232H and FT4232H. - 10/08/07 awm Added flags definitions. - 21/11/07 mja Added FT_GetComPortNumber. - 05/06/08 mja Added EEPROM extensions for FT2232H. - - ---*/ - - -#ifndef FTD2XX_H -#define FTD2XX_H - -// The following ifdef block is the standard way of creating macros -// which make exporting from a DLL simpler. All files within this DLL -// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. -// This symbol should not be defined on any project that uses this DLL. -// This way any other project whose source files include this file see -// FTD2XX_API functions as being imported from a DLL, whereas this DLL -// sees symbols defined with this macro as being exported. - -#ifdef FTD2XX_EXPORTS -#define FTD2XX_API __declspec(dllexport) -#else -#define FTD2XX_API __declspec(dllimport) -#endif - - -typedef PVOID FT_HANDLE; -typedef ULONG FT_STATUS; - -// -// Device status -// -enum { - FT_OK, - FT_INVALID_HANDLE, - FT_DEVICE_NOT_FOUND, - FT_DEVICE_NOT_OPENED, - FT_IO_ERROR, - FT_INSUFFICIENT_RESOURCES, - FT_INVALID_PARAMETER, - FT_INVALID_BAUD_RATE, - - FT_DEVICE_NOT_OPENED_FOR_ERASE, - FT_DEVICE_NOT_OPENED_FOR_WRITE, - FT_FAILED_TO_WRITE_DEVICE, - FT_EEPROM_READ_FAILED, - FT_EEPROM_WRITE_FAILED, - FT_EEPROM_ERASE_FAILED, - FT_EEPROM_NOT_PRESENT, - FT_EEPROM_NOT_PROGRAMMED, - FT_INVALID_ARGS, - FT_NOT_SUPPORTED, - FT_OTHER_ERROR, - FT_DEVICE_LIST_NOT_READY, -}; - - -#define FT_SUCCESS(status) ((status) == FT_OK) - -// -// FT_OpenEx Flags -// - -#define FT_OPEN_BY_SERIAL_NUMBER 1 -#define FT_OPEN_BY_DESCRIPTION 2 -#define FT_OPEN_BY_LOCATION 4 - -// -// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags -// - -#define FT_LIST_NUMBER_ONLY 0x80000000 -#define FT_LIST_BY_INDEX 0x40000000 -#define FT_LIST_ALL 0x20000000 - -#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) - -// -// Baud Rates -// - -#define FT_BAUD_300 300 -#define FT_BAUD_600 600 -#define FT_BAUD_1200 1200 -#define FT_BAUD_2400 2400 -#define FT_BAUD_4800 4800 -#define FT_BAUD_9600 9600 -#define FT_BAUD_14400 14400 -#define FT_BAUD_19200 19200 -#define FT_BAUD_38400 38400 -#define FT_BAUD_57600 57600 -#define FT_BAUD_115200 115200 -#define FT_BAUD_230400 230400 -#define FT_BAUD_460800 460800 -#define FT_BAUD_921600 921600 - -// -// Word Lengths -// - -#define FT_BITS_8 (UCHAR) 8 -#define FT_BITS_7 (UCHAR) 7 -#define FT_BITS_6 (UCHAR) 6 -#define FT_BITS_5 (UCHAR) 5 - -// -// Stop Bits -// - -#define FT_STOP_BITS_1 (UCHAR) 0 -#define FT_STOP_BITS_1_5 (UCHAR) 1 -#define FT_STOP_BITS_2 (UCHAR) 2 - -// -// Parity -// - -#define FT_PARITY_NONE (UCHAR) 0 -#define FT_PARITY_ODD (UCHAR) 1 -#define FT_PARITY_EVEN (UCHAR) 2 -#define FT_PARITY_MARK (UCHAR) 3 -#define FT_PARITY_SPACE (UCHAR) 4 - -// -// Flow Control -// - -#define FT_FLOW_NONE 0x0000 -#define FT_FLOW_RTS_CTS 0x0100 -#define FT_FLOW_DTR_DSR 0x0200 -#define FT_FLOW_XON_XOFF 0x0400 - -// -// Purge rx and tx buffers -// -#define FT_PURGE_RX 1 -#define FT_PURGE_TX 2 - -// -// Events -// - -typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); - -#define FT_EVENT_RXCHAR 1 -#define FT_EVENT_MODEM_STATUS 2 -#define FT_EVENT_LINE_STATUS 4 - -// -// Timeouts -// - -#define FT_DEFAULT_RX_TIMEOUT 300 -#define FT_DEFAULT_TX_TIMEOUT 300 - -// -// Device types -// - -typedef ULONG FT_DEVICE; - -enum { - FT_DEVICE_BM, - FT_DEVICE_AM, - FT_DEVICE_100AX, - FT_DEVICE_UNKNOWN, - FT_DEVICE_2232C, - FT_DEVICE_232R, - FT_DEVICE_2232H, - FT_DEVICE_4232H -}; - - -#ifdef __cplusplus -extern "C" { -#endif - - -FTD2XX_API -FT_STATUS WINAPI FT_Open( - int deviceNumber, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_OpenEx( - PVOID pArg1, - DWORD Flags, - FT_HANDLE *pHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ListDevices( - PVOID pArg1, - PVOID pArg2, - DWORD Flags - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Close( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Read( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD dwBytesToRead, - LPDWORD lpBytesReturned - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Write( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD dwBytesToWrite, - LPDWORD lpBytesWritten - ); - -FTD2XX_API -FT_STATUS WINAPI FT_IoCtl( - FT_HANDLE ftHandle, - DWORD dwIoControlCode, - LPVOID lpInBuf, - DWORD nInBufSize, - LPVOID lpOutBuf, - DWORD nOutBufSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBaudRate( - FT_HANDLE ftHandle, - ULONG BaudRate - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDivisor( - FT_HANDLE ftHandle, - USHORT Divisor - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDataCharacteristics( - FT_HANDLE ftHandle, - UCHAR WordLength, - UCHAR StopBits, - UCHAR Parity - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetFlowControl( - FT_HANDLE ftHandle, - USHORT FlowControl, - UCHAR XonChar, - UCHAR XoffChar - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetDevice( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrDtr( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ClrRts( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetModemStatus( - FT_HANDLE ftHandle, - ULONG *pModemStatus - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetChars( - FT_HANDLE ftHandle, - UCHAR EventChar, - UCHAR EventCharEnabled, - UCHAR ErrorChar, - UCHAR ErrorCharEnabled - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Purge( - FT_HANDLE ftHandle, - ULONG Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetTimeouts( - FT_HANDLE ftHandle, - ULONG ReadTimeout, - ULONG WriteTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetQueueStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetEventNotification( - FT_HANDLE ftHandle, - DWORD Mask, - PVOID Param - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetStatus( - FT_HANDLE ftHandle, - DWORD *dwRxBytes, - DWORD *dwTxBytes, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOn( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBreakOff( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetWaitMask( - FT_HANDLE ftHandle, - DWORD Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WaitOnMask( - FT_HANDLE ftHandle, - DWORD *Mask - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetEventStatus( - FT_HANDLE ftHandle, - DWORD *dwEventDWord - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ReadEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - LPWORD lpwValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_WriteEE( - FT_HANDLE ftHandle, - DWORD dwWordOffset, - WORD wValue - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EraseEE( - FT_HANDLE ftHandle - ); - -// -// structure to hold program data for FT_Program function -// -typedef struct ft_program_data { - - DWORD Signature1; // Header - must be 0x00000000 - DWORD Signature2; // Header - must be 0xffffffff - DWORD Version; // Header - FT_PROGRAM_DATA version - // 0 = original - // 1 = FT2232C extensions - // 2 = FT232R extensions - // 3 = FT2232H extensions - // 4 = FT4232H extensions - - WORD VendorId; // 0x0403 - WORD ProductId; // 0x6001 - char *Manufacturer; // "FTDI" - char *ManufacturerId; // "FT" - char *Description; // "USB HS Serial Converter" - char *SerialNumber; // "FT000001" if fixed, or NULL - WORD MaxPower; // 0 < MaxPower <= 500 - WORD PnP; // 0 = disabled, 1 = enabled - WORD SelfPowered; // 0 = bus powered, 1 = self powered - WORD RemoteWakeup; // 0 = not capable, 1 = capable - // - // Rev4 (FT232B) extensions - // - UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise - UCHAR IsoIn; // non-zero if in endpoint is isochronous - UCHAR IsoOut; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable; // non-zero if pull down enabled - UCHAR SerNumEnable; // non-zero if serial number to be used - UCHAR USBVersionEnable; // non-zero if chip uses USBVersion - WORD USBVersion; // BCD (0x0200 => USB2) - // - // Rev 5 (FT2232) extensions - // - UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise - UCHAR IsoInA; // non-zero if in endpoint is isochronous - UCHAR IsoInB; // non-zero if in endpoint is isochronous - UCHAR IsoOutA; // non-zero if out endpoint is isochronous - UCHAR IsoOutB; // non-zero if out endpoint is isochronous - UCHAR PullDownEnable5; // non-zero if pull down enabled - UCHAR SerNumEnable5; // non-zero if serial number to be used - UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion - WORD USBVersion5; // BCD (0x0200 => USB2) - UCHAR AIsHighCurrent; // non-zero if interface is high current - UCHAR BIsHighCurrent; // non-zero if interface is high current - UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer; // non-zero if interface is Fast serial - UCHAR AIsVCP; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer; // non-zero if interface is Fast serial - UCHAR BIsVCP; // non-zero if interface is to use VCP drivers - // - // Rev 6 (FT232R) extensions - // - UCHAR UseExtOsc; // Use External Oscillator - UCHAR HighDriveIOs; // High Drive I/Os - UCHAR EndpointSize; // Endpoint size - UCHAR PullDownEnableR; // non-zero if pull down enabled - UCHAR SerNumEnableR; // non-zero if serial number to be used - UCHAR InvertTXD; // non-zero if invert TXD - UCHAR InvertRXD; // non-zero if invert RXD - UCHAR InvertRTS; // non-zero if invert RTS - UCHAR InvertCTS; // non-zero if invert CTS - UCHAR InvertDTR; // non-zero if invert DTR - UCHAR InvertDSR; // non-zero if invert DSR - UCHAR InvertDCD; // non-zero if invert DCD - UCHAR InvertRI; // non-zero if invert RI - UCHAR Cbus0; // Cbus Mux control - UCHAR Cbus1; // Cbus Mux control - UCHAR Cbus2; // Cbus Mux control - UCHAR Cbus3; // Cbus Mux control - UCHAR Cbus4; // Cbus Mux control - UCHAR RIsD2XX; // non-zero if using D2XX driver - // - // Rev 7 (FT2232H) Extensions - // - UCHAR PullDownEnable7; // non-zero if pull down enabled - UCHAR SerNumEnable7; // non-zero if serial number to be used - UCHAR ALSlowSlew; // non-zero if AL pins have slow slew - UCHAR ALSchmittInput; // non-zero if AL pins are Schmitt input - UCHAR ALDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR AHSlowSlew; // non-zero if AH pins have slow slew - UCHAR AHSchmittInput; // non-zero if AH pins are Schmitt input - UCHAR AHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BLSlowSlew; // non-zero if BL pins have slow slew - UCHAR BLSchmittInput; // non-zero if BL pins are Schmitt input - UCHAR BLDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BHSlowSlew; // non-zero if BH pins have slow slew - UCHAR BHSchmittInput; // non-zero if BH pins are Schmitt input - UCHAR BHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR IFAIsFifo7; // non-zero if interface is 245 FIFO - UCHAR IFAIsFifoTar7; // non-zero if interface is 245 FIFO CPU target - UCHAR IFAIsFastSer7; // non-zero if interface is Fast serial - UCHAR AIsVCP7; // non-zero if interface is to use VCP drivers - UCHAR IFBIsFifo7; // non-zero if interface is 245 FIFO - UCHAR IFBIsFifoTar7; // non-zero if interface is 245 FIFO CPU target - UCHAR IFBIsFastSer7; // non-zero if interface is Fast serial - UCHAR BIsVCP7; // non-zero if interface is to use VCP drivers - UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs - // - // Rev 8 (FT4232H) Extensions - // - UCHAR PullDownEnable8; // non-zero if pull down enabled - UCHAR SerNumEnable8; // non-zero if serial number to be used - UCHAR ASlowSlew; // non-zero if AL pins have slow slew - UCHAR ASchmittInput; // non-zero if AL pins are Schmitt input - UCHAR ADriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR BSlowSlew; // non-zero if AH pins have slow slew - UCHAR BSchmittInput; // non-zero if AH pins are Schmitt input - UCHAR BDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR CSlowSlew; // non-zero if BL pins have slow slew - UCHAR CSchmittInput; // non-zero if BL pins are Schmitt input - UCHAR CDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR DSlowSlew; // non-zero if BH pins have slow slew - UCHAR DSchmittInput; // non-zero if BH pins are Schmitt input - UCHAR DDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA - UCHAR ARIIsTXDEN; // non-zero if port A uses RI as RS485 TXDEN - UCHAR BRIIsTXDEN; // non-zero if port B uses RI as RS485 TXDEN - UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN - UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN - UCHAR AIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR BIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR CIsVCP8; // non-zero if interface is to use VCP drivers - UCHAR DIsVCP8; // non-zero if interface is to use VCP drivers - -} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Program( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ProgramEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_Read( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_ReadEx( - FT_HANDLE ftHandle, - PFT_PROGRAM_DATA pData, - char *Manufacturer, - char *ManufacturerId, - char *Description, - char *SerialNumber - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UASize( - FT_HANDLE ftHandle, - LPDWORD lpdwSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UAWrite( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen - ); - -FTD2XX_API -FT_STATUS WINAPI FT_EE_UARead( - FT_HANDLE ftHandle, - PUCHAR pucData, - DWORD dwDataLen, - LPDWORD lpdwBytesRead - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetLatencyTimer( - FT_HANDLE ftHandle, - UCHAR ucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLatencyTimer( - FT_HANDLE ftHandle, - PUCHAR pucLatency - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetBitMode( - FT_HANDLE ftHandle, - UCHAR ucMask, - UCHAR ucEnable - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetBitMode( - FT_HANDLE ftHandle, - PUCHAR pucMode - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetUSBParameters( - FT_HANDLE ftHandle, - ULONG ulInTransferSize, - ULONG ulOutTransferSize - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetDeadmanTimeout( - FT_HANDLE ftHandle, - ULONG ulDeadmanTimeout - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfo( - FT_HANDLE ftHandle, - FT_DEVICE *lpftDevice, - LPDWORD lpdwID, - PCHAR SerialNumber, - PCHAR Description, - LPVOID Dummy - ); - -FTD2XX_API -FT_STATUS WINAPI FT_StopInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_RestartInTask( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_SetResetPipeRetryCount( - FT_HANDLE ftHandle, - DWORD dwCount - ); - -FTD2XX_API -FT_STATUS WINAPI FT_ResetPort( - FT_HANDLE ftHandle - ); - -FTD2XX_API -FT_STATUS WINAPI FT_CyclePort( - FT_HANDLE ftHandle - ); - - -// -// Win32-type functions -// - -FTD2XX_API -FT_HANDLE WINAPI FT_W32_CreateFile( - LPCTSTR lpszName, - DWORD dwAccess, - DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreate, - DWORD dwAttrsAndFlags, - HANDLE hTemplate - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CloseHandle( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ReadFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WriteFile( - FT_HANDLE ftHandle, - LPVOID lpBuffer, - DWORD nBufferSize, - LPDWORD lpBytesWritten, - LPOVERLAPPED lpOverlapped - ); - -FTD2XX_API -DWORD WINAPI FT_W32_GetLastError( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetOverlappedResult( - FT_HANDLE ftHandle, - LPOVERLAPPED lpOverlapped, - LPDWORD lpdwBytesTransferred, - BOOL bWait - ); - -FTD2XX_API -BOOL WINAPI FT_W32_CancelIo( - FT_HANDLE ftHandle - ); - - -// -// Win32 COMM API type functions -// -typedef struct _FTCOMSTAT { - DWORD fCtsHold : 1; - DWORD fDsrHold : 1; - DWORD fRlsdHold : 1; - DWORD fXoffHold : 1; - DWORD fXoffSent : 1; - DWORD fEof : 1; - DWORD fTxim : 1; - DWORD fReserved : 25; - DWORD cbInQue; - DWORD cbOutQue; -} FTCOMSTAT, *LPFTCOMSTAT; - -typedef struct _FTDCB { - DWORD DCBlength; /* sizeof(FTDCB) */ - DWORD BaudRate; /* Baudrate at which running */ - DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ - DWORD fParity: 1; /* Enable parity checking */ - DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ - DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ - DWORD fDtrControl:2; /* DTR Flow control */ - DWORD fDsrSensitivity:1; /* DSR Sensitivity */ - DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ - DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ - DWORD fInX: 1; /* Enable input X-ON/X-OFF */ - DWORD fErrorChar: 1; /* Enable Err Replacement */ - DWORD fNull: 1; /* Enable Null stripping */ - DWORD fRtsControl:2; /* Rts Flow control */ - DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ - DWORD fDummy2:17; /* Reserved */ - WORD wReserved; /* Not currently used */ - WORD XonLim; /* Transmit X-ON threshold */ - WORD XoffLim; /* Transmit X-OFF threshold */ - BYTE ByteSize; /* Number of bits/byte, 4-8 */ - BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ - BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ - char XonChar; /* Tx and Rx X-ON character */ - char XoffChar; /* Tx and Rx X-OFF character */ - char ErrorChar; /* Error replacement char */ - char EofChar; /* End of Input character */ - char EvtChar; /* Received Event character */ - WORD wReserved1; /* Fill for now. */ -} FTDCB, *LPFTDCB; - -typedef struct _FTTIMEOUTS { - DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ - DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ - DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ - DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ -} FTTIMEOUTS,*LPFTTIMEOUTS; - - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_ClearCommError( - FT_HANDLE ftHandle, - LPDWORD lpdwErrors, - LPFTCOMSTAT lpftComstat - ); - -FTD2XX_API -BOOL WINAPI FT_W32_EscapeCommFunction( - FT_HANDLE ftHandle, - DWORD dwFunc - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommModemStatus( - FT_HANDLE ftHandle, - LPDWORD lpdwModemStatus - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_PurgeComm( - FT_HANDLE ftHandle, - DWORD dwMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommBreak( - FT_HANDLE ftHandle - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommMask( - FT_HANDLE ftHandle, - ULONG ulEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_GetCommMask( - FT_HANDLE ftHandle, - LPDWORD lpdwEventMask - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommState( - FT_HANDLE ftHandle, - LPFTDCB lpftDcb - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetCommTimeouts( - FT_HANDLE ftHandle, - FTTIMEOUTS *pTimeouts - ); - -FTD2XX_API -BOOL WINAPI FT_W32_SetupComm( - FT_HANDLE ftHandle, - DWORD dwReadBufferSize, - DWORD dwWriteBufferSize - ); - -FTD2XX_API -BOOL WINAPI FT_W32_WaitCommEvent( - FT_HANDLE ftHandle, - PULONG pulEvent, - LPOVERLAPPED lpOverlapped - ); - - -// -// Device information -// - -typedef struct _ft_device_list_info_node { - ULONG Flags; - ULONG Type; - ULONG ID; - DWORD LocId; - char SerialNumber[16]; - char Description[64]; - FT_HANDLE ftHandle; -} FT_DEVICE_LIST_INFO_NODE; - -// Device information flags -enum { - FT_FLAGS_OPENED = 1, - FT_FLAGS_HISPEED = 2 -}; - - -FTD2XX_API -FT_STATUS WINAPI FT_CreateDeviceInfoList( - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoList( - FT_DEVICE_LIST_INFO_NODE *pDest, - LPDWORD lpdwNumDevs - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetDeviceInfoDetail( - DWORD dwIndex, - LPDWORD lpdwFlags, - LPDWORD lpdwType, - LPDWORD lpdwID, - LPDWORD lpdwLocId, - LPVOID lpSerialNumber, - LPVOID lpDescription, - FT_HANDLE *pftHandle - ); - - -// -// Version information -// - -FTD2XX_API -FT_STATUS WINAPI FT_GetDriverVersion( - FT_HANDLE ftHandle, - LPDWORD lpdwVersion - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetLibraryVersion( - LPDWORD lpdwVersion - ); - - -FTD2XX_API -FT_STATUS WINAPI FT_Rescan( - void - ); - -FTD2XX_API -FT_STATUS WINAPI FT_Reload( - WORD wVid, - WORD wPid - ); - -FTD2XX_API -FT_STATUS WINAPI FT_GetComPortNumber( - FT_HANDLE ftHandle, - LPLONG lpdwComPortNumber - ); - - - -#ifdef __cplusplus -} -#endif - - -#endif /* FTD2XX_H */ - +/*++ + +Copyright (c) 2001-2007 Future Technology Devices International Ltd. + +Module Name: + + ftd2xx.h + +Abstract: + + Native USB device driver for FTDI FT8U232/245 + FTD2XX library definitions + +Environment: + + kernel & user mode + +Revision History: + + 13/03/01 awm Created. + 13/01/03 awm Added device information support. + 19/03/03 awm Added FT_W32_CancelIo. + 12/06/03 awm Added FT_StopInTask and FT_RestartInTask. + 18/09/03 awm Added FT_SetResetPipeRetryCount. + 10/10/03 awm Added FT_ResetPort. + 23/01/04 awm Added support for open-by-location. + 16/03/04 awm Added support for FT2232C. + 23/09/04 awm Added support for FT232R. + 20/10/04 awm Added FT_CyclePort. + 18/01/05 awm Added FT_DEVICE_LIST_INFO_NODE type. + 11/02/05 awm Added LocId to FT_DEVICE_LIST_INFO_NODE. + 25/08/05 awm Added FT_SetDeadmanTimeout. + 02/12/05 awm Removed obsolete references. + 05/12/05 awm Added FT_GetVersion, FT_GetVersionEx. + 08/09/06 awm Added FT_W32_GetCommMask. + 11/09/06 awm Added FT_Rescan. + 11/07/07 awm Added support for FT2232H and FT4232H. + 10/08/07 awm Added flags definitions. + 21/11/07 mja Added FT_GetComPortNumber. + 05/06/08 mja Added EEPROM extensions for FT2232H. + + +--*/ + + +#ifndef FTD2XX_H +#define FTD2XX_H + +// The following ifdef block is the standard way of creating macros +// which make exporting from a DLL simpler. All files within this DLL +// are compiled with the FTD2XX_EXPORTS symbol defined on the command line. +// This symbol should not be defined on any project that uses this DLL. +// This way any other project whose source files include this file see +// FTD2XX_API functions as being imported from a DLL, whereas this DLL +// sees symbols defined with this macro as being exported. + +#ifdef FTD2XX_EXPORTS +#define FTD2XX_API __declspec(dllexport) +#else +#define FTD2XX_API __declspec(dllimport) +#endif + + +typedef PVOID FT_HANDLE; +typedef ULONG FT_STATUS; + +// +// Device status +// +enum { + FT_OK, + FT_INVALID_HANDLE, + FT_DEVICE_NOT_FOUND, + FT_DEVICE_NOT_OPENED, + FT_IO_ERROR, + FT_INSUFFICIENT_RESOURCES, + FT_INVALID_PARAMETER, + FT_INVALID_BAUD_RATE, + + FT_DEVICE_NOT_OPENED_FOR_ERASE, + FT_DEVICE_NOT_OPENED_FOR_WRITE, + FT_FAILED_TO_WRITE_DEVICE, + FT_EEPROM_READ_FAILED, + FT_EEPROM_WRITE_FAILED, + FT_EEPROM_ERASE_FAILED, + FT_EEPROM_NOT_PRESENT, + FT_EEPROM_NOT_PROGRAMMED, + FT_INVALID_ARGS, + FT_NOT_SUPPORTED, + FT_OTHER_ERROR, + FT_DEVICE_LIST_NOT_READY, +}; + + +#define FT_SUCCESS(status) ((status) == FT_OK) + +// +// FT_OpenEx Flags +// + +#define FT_OPEN_BY_SERIAL_NUMBER 1 +#define FT_OPEN_BY_DESCRIPTION 2 +#define FT_OPEN_BY_LOCATION 4 + +// +// FT_ListDevices Flags (used in conjunction with FT_OpenEx Flags +// + +#define FT_LIST_NUMBER_ONLY 0x80000000 +#define FT_LIST_BY_INDEX 0x40000000 +#define FT_LIST_ALL 0x20000000 + +#define FT_LIST_MASK (FT_LIST_NUMBER_ONLY|FT_LIST_BY_INDEX|FT_LIST_ALL) + +// +// Baud Rates +// + +#define FT_BAUD_300 300 +#define FT_BAUD_600 600 +#define FT_BAUD_1200 1200 +#define FT_BAUD_2400 2400 +#define FT_BAUD_4800 4800 +#define FT_BAUD_9600 9600 +#define FT_BAUD_14400 14400 +#define FT_BAUD_19200 19200 +#define FT_BAUD_38400 38400 +#define FT_BAUD_57600 57600 +#define FT_BAUD_115200 115200 +#define FT_BAUD_230400 230400 +#define FT_BAUD_460800 460800 +#define FT_BAUD_921600 921600 + +// +// Word Lengths +// + +#define FT_BITS_8 (UCHAR) 8 +#define FT_BITS_7 (UCHAR) 7 +#define FT_BITS_6 (UCHAR) 6 +#define FT_BITS_5 (UCHAR) 5 + +// +// Stop Bits +// + +#define FT_STOP_BITS_1 (UCHAR) 0 +#define FT_STOP_BITS_1_5 (UCHAR) 1 +#define FT_STOP_BITS_2 (UCHAR) 2 + +// +// Parity +// + +#define FT_PARITY_NONE (UCHAR) 0 +#define FT_PARITY_ODD (UCHAR) 1 +#define FT_PARITY_EVEN (UCHAR) 2 +#define FT_PARITY_MARK (UCHAR) 3 +#define FT_PARITY_SPACE (UCHAR) 4 + +// +// Flow Control +// + +#define FT_FLOW_NONE 0x0000 +#define FT_FLOW_RTS_CTS 0x0100 +#define FT_FLOW_DTR_DSR 0x0200 +#define FT_FLOW_XON_XOFF 0x0400 + +// +// Purge rx and tx buffers +// +#define FT_PURGE_RX 1 +#define FT_PURGE_TX 2 + +// +// Events +// + +typedef void (*PFT_EVENT_HANDLER)(DWORD,DWORD); + +#define FT_EVENT_RXCHAR 1 +#define FT_EVENT_MODEM_STATUS 2 +#define FT_EVENT_LINE_STATUS 4 + +// +// Timeouts +// + +#define FT_DEFAULT_RX_TIMEOUT 300 +#define FT_DEFAULT_TX_TIMEOUT 300 + +// +// Device types +// + +typedef ULONG FT_DEVICE; + +enum { + FT_DEVICE_BM, + FT_DEVICE_AM, + FT_DEVICE_100AX, + FT_DEVICE_UNKNOWN, + FT_DEVICE_2232C, + FT_DEVICE_232R, + FT_DEVICE_2232H, + FT_DEVICE_4232H +}; + + +#ifdef __cplusplus +extern "C" { +#endif + + +FTD2XX_API +FT_STATUS WINAPI FT_Open( + int deviceNumber, + FT_HANDLE *pHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_OpenEx( + PVOID pArg1, + DWORD Flags, + FT_HANDLE *pHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ListDevices( + PVOID pArg1, + PVOID pArg2, + DWORD Flags + ); + +FTD2XX_API +FT_STATUS WINAPI FT_Close( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_Read( + FT_HANDLE ftHandle, + LPVOID lpBuffer, + DWORD dwBytesToRead, + LPDWORD lpBytesReturned + ); + +FTD2XX_API +FT_STATUS WINAPI FT_Write( + FT_HANDLE ftHandle, + LPVOID lpBuffer, + DWORD dwBytesToWrite, + LPDWORD lpBytesWritten + ); + +FTD2XX_API +FT_STATUS WINAPI FT_IoCtl( + FT_HANDLE ftHandle, + DWORD dwIoControlCode, + LPVOID lpInBuf, + DWORD nInBufSize, + LPVOID lpOutBuf, + DWORD nOutBufSize, + LPDWORD lpBytesReturned, + LPOVERLAPPED lpOverlapped + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetBaudRate( + FT_HANDLE ftHandle, + ULONG BaudRate + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetDivisor( + FT_HANDLE ftHandle, + USHORT Divisor + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetDataCharacteristics( + FT_HANDLE ftHandle, + UCHAR WordLength, + UCHAR StopBits, + UCHAR Parity + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetFlowControl( + FT_HANDLE ftHandle, + USHORT FlowControl, + UCHAR XonChar, + UCHAR XoffChar + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ResetDevice( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetDtr( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ClrDtr( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetRts( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ClrRts( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetModemStatus( + FT_HANDLE ftHandle, + ULONG *pModemStatus + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetChars( + FT_HANDLE ftHandle, + UCHAR EventChar, + UCHAR EventCharEnabled, + UCHAR ErrorChar, + UCHAR ErrorCharEnabled + ); + +FTD2XX_API +FT_STATUS WINAPI FT_Purge( + FT_HANDLE ftHandle, + ULONG Mask + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetTimeouts( + FT_HANDLE ftHandle, + ULONG ReadTimeout, + ULONG WriteTimeout + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetQueueStatus( + FT_HANDLE ftHandle, + DWORD *dwRxBytes + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetEventNotification( + FT_HANDLE ftHandle, + DWORD Mask, + PVOID Param + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetStatus( + FT_HANDLE ftHandle, + DWORD *dwRxBytes, + DWORD *dwTxBytes, + DWORD *dwEventDWord + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetBreakOn( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetBreakOff( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetWaitMask( + FT_HANDLE ftHandle, + DWORD Mask + ); + +FTD2XX_API +FT_STATUS WINAPI FT_WaitOnMask( + FT_HANDLE ftHandle, + DWORD *Mask + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetEventStatus( + FT_HANDLE ftHandle, + DWORD *dwEventDWord + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ReadEE( + FT_HANDLE ftHandle, + DWORD dwWordOffset, + LPWORD lpwValue + ); + +FTD2XX_API +FT_STATUS WINAPI FT_WriteEE( + FT_HANDLE ftHandle, + DWORD dwWordOffset, + WORD wValue + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EraseEE( + FT_HANDLE ftHandle + ); + +// +// structure to hold program data for FT_Program function +// +typedef struct ft_program_data { + + DWORD Signature1; // Header - must be 0x00000000 + DWORD Signature2; // Header - must be 0xffffffff + DWORD Version; // Header - FT_PROGRAM_DATA version + // 0 = original + // 1 = FT2232C extensions + // 2 = FT232R extensions + // 3 = FT2232H extensions + // 4 = FT4232H extensions + + WORD VendorId; // 0x0403 + WORD ProductId; // 0x6001 + char *Manufacturer; // "FTDI" + char *ManufacturerId; // "FT" + char *Description; // "USB HS Serial Converter" + char *SerialNumber; // "FT000001" if fixed, or NULL + WORD MaxPower; // 0 < MaxPower <= 500 + WORD PnP; // 0 = disabled, 1 = enabled + WORD SelfPowered; // 0 = bus powered, 1 = self powered + WORD RemoteWakeup; // 0 = not capable, 1 = capable + // + // Rev4 (FT232B) extensions + // + UCHAR Rev4; // non-zero if Rev4 chip, zero otherwise + UCHAR IsoIn; // non-zero if in endpoint is isochronous + UCHAR IsoOut; // non-zero if out endpoint is isochronous + UCHAR PullDownEnable; // non-zero if pull down enabled + UCHAR SerNumEnable; // non-zero if serial number to be used + UCHAR USBVersionEnable; // non-zero if chip uses USBVersion + WORD USBVersion; // BCD (0x0200 => USB2) + // + // Rev 5 (FT2232) extensions + // + UCHAR Rev5; // non-zero if Rev5 chip, zero otherwise + UCHAR IsoInA; // non-zero if in endpoint is isochronous + UCHAR IsoInB; // non-zero if in endpoint is isochronous + UCHAR IsoOutA; // non-zero if out endpoint is isochronous + UCHAR IsoOutB; // non-zero if out endpoint is isochronous + UCHAR PullDownEnable5; // non-zero if pull down enabled + UCHAR SerNumEnable5; // non-zero if serial number to be used + UCHAR USBVersionEnable5; // non-zero if chip uses USBVersion + WORD USBVersion5; // BCD (0x0200 => USB2) + UCHAR AIsHighCurrent; // non-zero if interface is high current + UCHAR BIsHighCurrent; // non-zero if interface is high current + UCHAR IFAIsFifo; // non-zero if interface is 245 FIFO + UCHAR IFAIsFifoTar; // non-zero if interface is 245 FIFO CPU target + UCHAR IFAIsFastSer; // non-zero if interface is Fast serial + UCHAR AIsVCP; // non-zero if interface is to use VCP drivers + UCHAR IFBIsFifo; // non-zero if interface is 245 FIFO + UCHAR IFBIsFifoTar; // non-zero if interface is 245 FIFO CPU target + UCHAR IFBIsFastSer; // non-zero if interface is Fast serial + UCHAR BIsVCP; // non-zero if interface is to use VCP drivers + // + // Rev 6 (FT232R) extensions + // + UCHAR UseExtOsc; // Use External Oscillator + UCHAR HighDriveIOs; // High Drive I/Os + UCHAR EndpointSize; // Endpoint size + UCHAR PullDownEnableR; // non-zero if pull down enabled + UCHAR SerNumEnableR; // non-zero if serial number to be used + UCHAR InvertTXD; // non-zero if invert TXD + UCHAR InvertRXD; // non-zero if invert RXD + UCHAR InvertRTS; // non-zero if invert RTS + UCHAR InvertCTS; // non-zero if invert CTS + UCHAR InvertDTR; // non-zero if invert DTR + UCHAR InvertDSR; // non-zero if invert DSR + UCHAR InvertDCD; // non-zero if invert DCD + UCHAR InvertRI; // non-zero if invert RI + UCHAR Cbus0; // Cbus Mux control + UCHAR Cbus1; // Cbus Mux control + UCHAR Cbus2; // Cbus Mux control + UCHAR Cbus3; // Cbus Mux control + UCHAR Cbus4; // Cbus Mux control + UCHAR RIsD2XX; // non-zero if using D2XX driver + // + // Rev 7 (FT2232H) Extensions + // + UCHAR PullDownEnable7; // non-zero if pull down enabled + UCHAR SerNumEnable7; // non-zero if serial number to be used + UCHAR ALSlowSlew; // non-zero if AL pins have slow slew + UCHAR ALSchmittInput; // non-zero if AL pins are Schmitt input + UCHAR ALDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR AHSlowSlew; // non-zero if AH pins have slow slew + UCHAR AHSchmittInput; // non-zero if AH pins are Schmitt input + UCHAR AHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR BLSlowSlew; // non-zero if BL pins have slow slew + UCHAR BLSchmittInput; // non-zero if BL pins are Schmitt input + UCHAR BLDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR BHSlowSlew; // non-zero if BH pins have slow slew + UCHAR BHSchmittInput; // non-zero if BH pins are Schmitt input + UCHAR BHDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR IFAIsFifo7; // non-zero if interface is 245 FIFO + UCHAR IFAIsFifoTar7; // non-zero if interface is 245 FIFO CPU target + UCHAR IFAIsFastSer7; // non-zero if interface is Fast serial + UCHAR AIsVCP7; // non-zero if interface is to use VCP drivers + UCHAR IFBIsFifo7; // non-zero if interface is 245 FIFO + UCHAR IFBIsFifoTar7; // non-zero if interface is 245 FIFO CPU target + UCHAR IFBIsFastSer7; // non-zero if interface is Fast serial + UCHAR BIsVCP7; // non-zero if interface is to use VCP drivers + UCHAR PowerSaveEnable; // non-zero if using BCBUS7 to save power for self-powered designs + // + // Rev 8 (FT4232H) Extensions + // + UCHAR PullDownEnable8; // non-zero if pull down enabled + UCHAR SerNumEnable8; // non-zero if serial number to be used + UCHAR ASlowSlew; // non-zero if AL pins have slow slew + UCHAR ASchmittInput; // non-zero if AL pins are Schmitt input + UCHAR ADriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR BSlowSlew; // non-zero if AH pins have slow slew + UCHAR BSchmittInput; // non-zero if AH pins are Schmitt input + UCHAR BDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR CSlowSlew; // non-zero if BL pins have slow slew + UCHAR CSchmittInput; // non-zero if BL pins are Schmitt input + UCHAR CDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR DSlowSlew; // non-zero if BH pins have slow slew + UCHAR DSchmittInput; // non-zero if BH pins are Schmitt input + UCHAR DDriveCurrent; // valid values are 4mA, 8mA, 12mA, 16mA + UCHAR ARIIsTXDEN; // non-zero if port A uses RI as RS485 TXDEN + UCHAR BRIIsTXDEN; // non-zero if port B uses RI as RS485 TXDEN + UCHAR CRIIsTXDEN; // non-zero if port C uses RI as RS485 TXDEN + UCHAR DRIIsTXDEN; // non-zero if port D uses RI as RS485 TXDEN + UCHAR AIsVCP8; // non-zero if interface is to use VCP drivers + UCHAR BIsVCP8; // non-zero if interface is to use VCP drivers + UCHAR CIsVCP8; // non-zero if interface is to use VCP drivers + UCHAR DIsVCP8; // non-zero if interface is to use VCP drivers + +} FT_PROGRAM_DATA, *PFT_PROGRAM_DATA; + +FTD2XX_API +FT_STATUS WINAPI FT_EE_Program( + FT_HANDLE ftHandle, + PFT_PROGRAM_DATA pData + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_ProgramEx( + FT_HANDLE ftHandle, + PFT_PROGRAM_DATA pData, + char *Manufacturer, + char *ManufacturerId, + char *Description, + char *SerialNumber + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_Read( + FT_HANDLE ftHandle, + PFT_PROGRAM_DATA pData + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_ReadEx( + FT_HANDLE ftHandle, + PFT_PROGRAM_DATA pData, + char *Manufacturer, + char *ManufacturerId, + char *Description, + char *SerialNumber + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_UASize( + FT_HANDLE ftHandle, + LPDWORD lpdwSize + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_UAWrite( + FT_HANDLE ftHandle, + PUCHAR pucData, + DWORD dwDataLen + ); + +FTD2XX_API +FT_STATUS WINAPI FT_EE_UARead( + FT_HANDLE ftHandle, + PUCHAR pucData, + DWORD dwDataLen, + LPDWORD lpdwBytesRead + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetLatencyTimer( + FT_HANDLE ftHandle, + UCHAR ucLatency + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetLatencyTimer( + FT_HANDLE ftHandle, + PUCHAR pucLatency + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetBitMode( + FT_HANDLE ftHandle, + UCHAR ucMask, + UCHAR ucEnable + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetBitMode( + FT_HANDLE ftHandle, + PUCHAR pucMode + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetUSBParameters( + FT_HANDLE ftHandle, + ULONG ulInTransferSize, + ULONG ulOutTransferSize + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetDeadmanTimeout( + FT_HANDLE ftHandle, + ULONG ulDeadmanTimeout + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetDeviceInfo( + FT_HANDLE ftHandle, + FT_DEVICE *lpftDevice, + LPDWORD lpdwID, + PCHAR SerialNumber, + PCHAR Description, + LPVOID Dummy + ); + +FTD2XX_API +FT_STATUS WINAPI FT_StopInTask( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_RestartInTask( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_SetResetPipeRetryCount( + FT_HANDLE ftHandle, + DWORD dwCount + ); + +FTD2XX_API +FT_STATUS WINAPI FT_ResetPort( + FT_HANDLE ftHandle + ); + +FTD2XX_API +FT_STATUS WINAPI FT_CyclePort( + FT_HANDLE ftHandle + ); + + +// +// Win32-type functions +// + +FTD2XX_API +FT_HANDLE WINAPI FT_W32_CreateFile( + LPCTSTR lpszName, + DWORD dwAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreate, + DWORD dwAttrsAndFlags, + HANDLE hTemplate + ); + +FTD2XX_API +BOOL WINAPI FT_W32_CloseHandle( + FT_HANDLE ftHandle + ); + +FTD2XX_API +BOOL WINAPI FT_W32_ReadFile( + FT_HANDLE ftHandle, + LPVOID lpBuffer, + DWORD nBufferSize, + LPDWORD lpBytesReturned, + LPOVERLAPPED lpOverlapped + ); + +FTD2XX_API +BOOL WINAPI FT_W32_WriteFile( + FT_HANDLE ftHandle, + LPVOID lpBuffer, + DWORD nBufferSize, + LPDWORD lpBytesWritten, + LPOVERLAPPED lpOverlapped + ); + +FTD2XX_API +DWORD WINAPI FT_W32_GetLastError( + FT_HANDLE ftHandle + ); + +FTD2XX_API +BOOL WINAPI FT_W32_GetOverlappedResult( + FT_HANDLE ftHandle, + LPOVERLAPPED lpOverlapped, + LPDWORD lpdwBytesTransferred, + BOOL bWait + ); + +FTD2XX_API +BOOL WINAPI FT_W32_CancelIo( + FT_HANDLE ftHandle + ); + + +// +// Win32 COMM API type functions +// +typedef struct _FTCOMSTAT { + DWORD fCtsHold : 1; + DWORD fDsrHold : 1; + DWORD fRlsdHold : 1; + DWORD fXoffHold : 1; + DWORD fXoffSent : 1; + DWORD fEof : 1; + DWORD fTxim : 1; + DWORD fReserved : 25; + DWORD cbInQue; + DWORD cbOutQue; +} FTCOMSTAT, *LPFTCOMSTAT; + +typedef struct _FTDCB { + DWORD DCBlength; /* sizeof(FTDCB) */ + DWORD BaudRate; /* Baudrate at which running */ + DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ + DWORD fParity: 1; /* Enable parity checking */ + DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ + DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ + DWORD fDtrControl:2; /* DTR Flow control */ + DWORD fDsrSensitivity:1; /* DSR Sensitivity */ + DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ + DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ + DWORD fInX: 1; /* Enable input X-ON/X-OFF */ + DWORD fErrorChar: 1; /* Enable Err Replacement */ + DWORD fNull: 1; /* Enable Null stripping */ + DWORD fRtsControl:2; /* Rts Flow control */ + DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ + DWORD fDummy2:17; /* Reserved */ + WORD wReserved; /* Not currently used */ + WORD XonLim; /* Transmit X-ON threshold */ + WORD XoffLim; /* Transmit X-OFF threshold */ + BYTE ByteSize; /* Number of bits/byte, 4-8 */ + BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ + BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ + char XonChar; /* Tx and Rx X-ON character */ + char XoffChar; /* Tx and Rx X-OFF character */ + char ErrorChar; /* Error replacement char */ + char EofChar; /* End of Input character */ + char EvtChar; /* Received Event character */ + WORD wReserved1; /* Fill for now. */ +} FTDCB, *LPFTDCB; + +typedef struct _FTTIMEOUTS { + DWORD ReadIntervalTimeout; /* Maximum time between read chars. */ + DWORD ReadTotalTimeoutMultiplier; /* Multiplier of characters. */ + DWORD ReadTotalTimeoutConstant; /* Constant in milliseconds. */ + DWORD WriteTotalTimeoutMultiplier; /* Multiplier of characters. */ + DWORD WriteTotalTimeoutConstant; /* Constant in milliseconds. */ +} FTTIMEOUTS,*LPFTTIMEOUTS; + + +FTD2XX_API +BOOL WINAPI FT_W32_ClearCommBreak( + FT_HANDLE ftHandle + ); + +FTD2XX_API +BOOL WINAPI FT_W32_ClearCommError( + FT_HANDLE ftHandle, + LPDWORD lpdwErrors, + LPFTCOMSTAT lpftComstat + ); + +FTD2XX_API +BOOL WINAPI FT_W32_EscapeCommFunction( + FT_HANDLE ftHandle, + DWORD dwFunc + ); + +FTD2XX_API +BOOL WINAPI FT_W32_GetCommModemStatus( + FT_HANDLE ftHandle, + LPDWORD lpdwModemStatus + ); + +FTD2XX_API +BOOL WINAPI FT_W32_GetCommState( + FT_HANDLE ftHandle, + LPFTDCB lpftDcb + ); + +FTD2XX_API +BOOL WINAPI FT_W32_GetCommTimeouts( + FT_HANDLE ftHandle, + FTTIMEOUTS *pTimeouts + ); + +FTD2XX_API +BOOL WINAPI FT_W32_PurgeComm( + FT_HANDLE ftHandle, + DWORD dwMask + ); + +FTD2XX_API +BOOL WINAPI FT_W32_SetCommBreak( + FT_HANDLE ftHandle + ); + +FTD2XX_API +BOOL WINAPI FT_W32_SetCommMask( + FT_HANDLE ftHandle, + ULONG ulEventMask + ); + +FTD2XX_API +BOOL WINAPI FT_W32_GetCommMask( + FT_HANDLE ftHandle, + LPDWORD lpdwEventMask + ); + +FTD2XX_API +BOOL WINAPI FT_W32_SetCommState( + FT_HANDLE ftHandle, + LPFTDCB lpftDcb + ); + +FTD2XX_API +BOOL WINAPI FT_W32_SetCommTimeouts( + FT_HANDLE ftHandle, + FTTIMEOUTS *pTimeouts + ); + +FTD2XX_API +BOOL WINAPI FT_W32_SetupComm( + FT_HANDLE ftHandle, + DWORD dwReadBufferSize, + DWORD dwWriteBufferSize + ); + +FTD2XX_API +BOOL WINAPI FT_W32_WaitCommEvent( + FT_HANDLE ftHandle, + PULONG pulEvent, + LPOVERLAPPED lpOverlapped + ); + + +// +// Device information +// + +typedef struct _ft_device_list_info_node { + ULONG Flags; + ULONG Type; + ULONG ID; + DWORD LocId; + char SerialNumber[16]; + char Description[64]; + FT_HANDLE ftHandle; +} FT_DEVICE_LIST_INFO_NODE; + +// Device information flags +enum { + FT_FLAGS_OPENED = 1, + FT_FLAGS_HISPEED = 2 +}; + + +FTD2XX_API +FT_STATUS WINAPI FT_CreateDeviceInfoList( + LPDWORD lpdwNumDevs + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetDeviceInfoList( + FT_DEVICE_LIST_INFO_NODE *pDest, + LPDWORD lpdwNumDevs + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetDeviceInfoDetail( + DWORD dwIndex, + LPDWORD lpdwFlags, + LPDWORD lpdwType, + LPDWORD lpdwID, + LPDWORD lpdwLocId, + LPVOID lpSerialNumber, + LPVOID lpDescription, + FT_HANDLE *pftHandle + ); + + +// +// Version information +// + +FTD2XX_API +FT_STATUS WINAPI FT_GetDriverVersion( + FT_HANDLE ftHandle, + LPDWORD lpdwVersion + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetLibraryVersion( + LPDWORD lpdwVersion + ); + + +FTD2XX_API +FT_STATUS WINAPI FT_Rescan( + void + ); + +FTD2XX_API +FT_STATUS WINAPI FT_Reload( + WORD wVid, + WORD wPid + ); + +FTD2XX_API +FT_STATUS WINAPI FT_GetComPortNumber( + FT_HANDLE ftHandle, + LPLONG lpdwComPortNumber + ); + + + +#ifdef __cplusplus +} +#endif + + +#endif /* FTD2XX_H */ + diff --git a/telldus-core/tdadmin/CMakeLists.txt b/telldus-core/tdadmin/CMakeLists.txt index 501baabe..7c72b26b 100644 --- a/telldus-core/tdadmin/CMakeLists.txt +++ b/telldus-core/tdadmin/CMakeLists.txt @@ -1,79 +1,79 @@ -PROJECT(tdadmin) - -cmake_policy(SET CMP0005 NEW) - -SET (tdadmin_DESCRIPTION - "a command line utility to edit devices and controllers for Telldus TellStick" -) - -SET(tdadmin_SRCS - main.cpp -) - -ADD_EXECUTABLE(tdadmin - ${tdadmin_SRCS} -) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/driver -) - -ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) - -IF (WIN32) - FIND_LIBRARY(TELLDUSCORE_LIBRARY TelldusCore) - TARGET_LINK_LIBRARIES(tdadmin - ${TELLDUSCORE_LIBRARY} - ) -ELSEIF (APPLE) - TARGET_LINK_LIBRARIES(tdadmin - TelldusCore - ) -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") - # FreeBSD does not have argp in base libc; port devel/argp-standalone is required. - FIND_LIBRARY(ARGP_LIBRARY argp) - TARGET_LINK_LIBRARIES(tdadmin - ${CMAKE_BINARY_DIR}/client/libtelldus-core.so - ${ARGP_LIBRARY} - ) -ELSE (WIN32) - TARGET_LINK_LIBRARIES(tdadmin - ${CMAKE_BINARY_DIR}/client/libtelldus-core.so - ) -ENDIF (WIN32) - -IF (UNIX) - IF (GENERATE_MAN) - ADD_CUSTOM_COMMAND( - TARGET tdadmin - POST_BUILD - COMMAND help2man -n ${tdadmin_DESCRIPTION} ./tdadmin > tdadmin.1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating man file tdadmin.1" - ) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdadmin.1 DESTINATION share/man/man1) - ENDIF (GENERATE_MAN) -ENDIF (UNIX) - -INSTALL(TARGETS tdadmin RUNTIME DESTINATION sbin) - -IF (UNIX AND NOT APPLE) - SET(UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "The directory where udev store its rules" ) - CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/05-tellstick.rules - ${CMAKE_BINARY_DIR}/parsed/05-tellstick.rules - @ONLY - ) - CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/udev.sh - ${CMAKE_BINARY_DIR}/parsed/udev.sh - @ONLY - ) - INSTALL(FILES ${CMAKE_BINARY_DIR}/parsed/05-tellstick.rules - DESTINATION ${UDEV_RULES_DIR} - ) - INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/parsed/udev.sh - DESTINATION share/telldus-core/helpers/ - ) -ENDIF (UNIX AND NOT APPLE) +PROJECT(tdadmin) + +cmake_policy(SET CMP0005 NEW) + +SET (tdadmin_DESCRIPTION + "a command line utility to edit devices and controllers for Telldus TellStick" +) + +SET(tdadmin_SRCS + main.cpp +) + +ADD_EXECUTABLE(tdadmin + ${tdadmin_SRCS} +) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/driver +) + +ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) + +IF (WIN32) + FIND_LIBRARY(TELLDUSCORE_LIBRARY TelldusCore) + TARGET_LINK_LIBRARIES(tdadmin + ${TELLDUSCORE_LIBRARY} + ) +ELSEIF (APPLE) + TARGET_LINK_LIBRARIES(tdadmin + TelldusCore + ) +ELSEIF (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + # FreeBSD does not have argp in base libc; port devel/argp-standalone is required. + FIND_LIBRARY(ARGP_LIBRARY argp) + TARGET_LINK_LIBRARIES(tdadmin + ${CMAKE_BINARY_DIR}/client/libtelldus-core.so + ${ARGP_LIBRARY} + ) +ELSE (WIN32) + TARGET_LINK_LIBRARIES(tdadmin + ${CMAKE_BINARY_DIR}/client/libtelldus-core.so + ) +ENDIF (WIN32) + +IF (UNIX) + IF (GENERATE_MAN) + ADD_CUSTOM_COMMAND( + TARGET tdadmin + POST_BUILD + COMMAND help2man -n ${tdadmin_DESCRIPTION} ./tdadmin > tdadmin.1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating man file tdadmin.1" + ) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdadmin.1 DESTINATION share/man/man1) + ENDIF (GENERATE_MAN) +ENDIF (UNIX) + +INSTALL(TARGETS tdadmin RUNTIME DESTINATION sbin) + +IF (UNIX AND NOT APPLE) + SET(UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "The directory where udev store its rules" ) + CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/05-tellstick.rules + ${CMAKE_BINARY_DIR}/parsed/05-tellstick.rules + @ONLY + ) + CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/udev.sh + ${CMAKE_BINARY_DIR}/parsed/udev.sh + @ONLY + ) + INSTALL(FILES ${CMAKE_BINARY_DIR}/parsed/05-tellstick.rules + DESTINATION ${UDEV_RULES_DIR} + ) + INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/parsed/udev.sh + DESTINATION share/telldus-core/helpers/ + ) +ENDIF (UNIX AND NOT APPLE) diff --git a/telldus-core/tdadmin/main.cpp b/telldus-core/tdadmin/main.cpp index 698f13b0..cb4b3b59 100644 --- a/telldus-core/tdadmin/main.cpp +++ b/telldus-core/tdadmin/main.cpp @@ -1,85 +1,85 @@ -#include "../client/telldus-core.h" -#include -#include -#include -#include - -const char *argp_program_version = "tdadmin " VERSION ; -const char *argp_program_bug_address = ""; - -static char args_doc[] = "COMMAND ACTION"; - -static char doc[] = "TellStick admin tool -- a command line utility to edit devices and controllers for Telldus TellStick"; - -const int VID = 1; -const int PID = 2; -const int SERIAL = 3; - -static struct argp_option options[] = { - {0,0,0,0, - "COMMAND: controller, ACTION: connect/disconnect\n" - "Tells the daemon to add or remove a TellStick (duo)" - }, - {"vid",VID,"VID",0, "The vendor id (1781)" }, - {"pid",PID,"PID",0,"The product id (0c30 or 0c31)" }, - {"serial",SERIAL,"SERIAL",0,"The usb serial number" }, - { 0 } -}; - -static std::string command, action; - -int vid, pid; -static std::string serial; - -static error_t parse_opt (int key, char *arg, struct argp_state *state) { - switch (key) { - case PID: - pid = strtol(arg, NULL, 16); - break; - case SERIAL: - serial = arg; - break; - case VID: - vid = strtol(arg, NULL, 16); - break; - - case ARGP_KEY_NO_ARGS: - argp_usage (state); - - case ARGP_KEY_ARG: - command = arg; - action = state->argv[state->next]; - state->next = state->argc; - - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { options, parse_opt, args_doc, doc }; - -void handle_controller(void) { - if (vid == 0 || pid == 0) { - fprintf(stderr, "Missing parameter vid or pid\n"); - } - if (action.compare("connect") == 0) { - tdConnectTellStickController(vid,pid,serial.c_str()); - - } else if (action.compare("disconnect") == 0) { - tdDisconnectTellStickController(vid,pid,serial.c_str()); - } -} - -int main(int argc, char **argv) { - - argp_parse (&argp, argc, argv, 0, 0, 0); - - if (command.compare("controller") == 0) { - handle_controller(); - } - - return 0; -} +#include "../client/telldus-core.h" +#include +#include +#include +#include + +const char *argp_program_version = "tdadmin " VERSION ; +const char *argp_program_bug_address = ""; + +static char args_doc[] = "COMMAND ACTION"; + +static char doc[] = "TellStick admin tool -- a command line utility to edit devices and controllers for Telldus TellStick"; + +const int VID = 1; +const int PID = 2; +const int SERIAL = 3; + +static struct argp_option options[] = { + {0,0,0,0, + "COMMAND: controller, ACTION: connect/disconnect\n" + "Tells the daemon to add or remove a TellStick (duo)" + }, + {"vid",VID,"VID",0, "The vendor id (1781)" }, + {"pid",PID,"PID",0,"The product id (0c30 or 0c31)" }, + {"serial",SERIAL,"SERIAL",0,"The usb serial number" }, + { 0 } +}; + +static std::string command, action; + +int vid, pid; +static std::string serial; + +static error_t parse_opt (int key, char *arg, struct argp_state *state) { + switch (key) { + case PID: + pid = strtol(arg, NULL, 16); + break; + case SERIAL: + serial = arg; + break; + case VID: + vid = strtol(arg, NULL, 16); + break; + + case ARGP_KEY_NO_ARGS: + argp_usage (state); + + case ARGP_KEY_ARG: + command = arg; + action = state->argv[state->next]; + state->next = state->argc; + + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static struct argp argp = { options, parse_opt, args_doc, doc }; + +void handle_controller(void) { + if (vid == 0 || pid == 0) { + fprintf(stderr, "Missing parameter vid or pid\n"); + } + if (action.compare("connect") == 0) { + tdConnectTellStickController(vid,pid,serial.c_str()); + + } else if (action.compare("disconnect") == 0) { + tdDisconnectTellStickController(vid,pid,serial.c_str()); + } +} + +int main(int argc, char **argv) { + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (command.compare("controller") == 0) { + handle_controller(); + } + + return 0; +} diff --git a/telldus-core/tdtool/CMakeLists.txt b/telldus-core/tdtool/CMakeLists.txt index d9016d34..c9aeb07b 100644 --- a/telldus-core/tdtool/CMakeLists.txt +++ b/telldus-core/tdtool/CMakeLists.txt @@ -1,56 +1,56 @@ -PROJECT(tdtool) - -cmake_policy(SET CMP0005 NEW) - -SET (tdtool_DESCRIPTION - "a command line utility to send commands to a Telldus TellStick" -) - -SET(tdtool_SRCS - main.cpp -) - -ADD_EXECUTABLE(tdtool - ${tdtool_SRCS} -) -SIGN(tdtool) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/driver -) - -ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) - -IF (WIN32) - TARGET_LINK_LIBRARIES(tdtool - TelldusCore - openbsd-getopt - ) - INCLUDE_DIRECTORIES( - ${CMAKE_SOURCE_DIR}/3rdparty/openbsd-getopt - ) -ELSEIF (APPLE) - TARGET_LINK_LIBRARIES(tdtool - TelldusCore - ) -ELSE (WIN32) - TARGET_LINK_LIBRARIES(tdtool - ${CMAKE_BINARY_DIR}/client/libtelldus-core.so - ) -ENDIF (WIN32) - -IF (UNIX) - IF (GENERATE_MAN) - ADD_CUSTOM_COMMAND( - TARGET tdtool - POST_BUILD - COMMAND help2man -n ${tdtool_DESCRIPTION} ./tdtool > tdtool.1 - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating man file tdtool.1" - ) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdtool.1 DESTINATION share/man/man1) - ENDIF (GENERATE_MAN) -ENDIF (UNIX) - -INSTALL(TARGETS tdtool RUNTIME DESTINATION bin) +PROJECT(tdtool) + +cmake_policy(SET CMP0005 NEW) + +SET (tdtool_DESCRIPTION + "a command line utility to send commands to a Telldus TellStick" +) + +SET(tdtool_SRCS + main.cpp +) + +ADD_EXECUTABLE(tdtool + ${tdtool_SRCS} +) +SIGN(tdtool) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/driver +) + +ADD_DEFINITIONS( -DVERSION="${DISPLAYED_VERSION}" ) + +IF (WIN32) + TARGET_LINK_LIBRARIES(tdtool + TelldusCore + openbsd-getopt + ) + INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR}/3rdparty/openbsd-getopt + ) +ELSEIF (APPLE) + TARGET_LINK_LIBRARIES(tdtool + TelldusCore + ) +ELSE (WIN32) + TARGET_LINK_LIBRARIES(tdtool + ${CMAKE_BINARY_DIR}/client/libtelldus-core.so + ) +ENDIF (WIN32) + +IF (UNIX) + IF (GENERATE_MAN) + ADD_CUSTOM_COMMAND( + TARGET tdtool + POST_BUILD + COMMAND help2man -n ${tdtool_DESCRIPTION} ./tdtool > tdtool.1 + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating man file tdtool.1" + ) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tdtool.1 DESTINATION share/man/man1) + ENDIF (GENERATE_MAN) +ENDIF (UNIX) + +INSTALL(TARGETS tdtool RUNTIME DESTINATION bin) diff --git a/telldus-core/tdtool/main.cpp b/telldus-core/tdtool/main.cpp index f9ff478d..0b75771b 100644 --- a/telldus-core/tdtool/main.cpp +++ b/telldus-core/tdtool/main.cpp @@ -1,486 +1,486 @@ -#include -#include -#include -#include -#include -#include "../client/telldus-core.h" - -#ifdef _WINDOWS -#define strcasecmp _stricmp -#define DEGREE " " -#else -#define DEGREE "°" -#endif - -const int SUPPORTED_METHODS = - TELLSTICK_TURNON | - TELLSTICK_TURNOFF | - TELLSTICK_BELL | - TELLSTICK_DIM; - -const int DATA_LENGTH = 20; - -void print_usage( char *name ) { - printf("Usage: %s [ options ]\n", name); - printf("\n"); - printf("Options:\n"); - printf(" -[bdefhlnrv] [ --list ] [ --help ]\n"); - printf(" [ --list-sensors ] [ --list-devices ]\n"); - printf(" [ --on device ] [ --off device ] [ --bell device ]\n"); - printf(" [ --learn device ]\n"); - printf(" [ --dimlevel level --dim device ]\n"); - printf(" [ --raw input ]\n"); - printf("\n"); - printf(" --list (-l short option)\n"); - printf(" List currently configured devices and all discovered sensors.\n"); - printf("\n"); - printf(" --list-sensors\n"); - printf(" --list-devices\n"); - printf(" Alternative devices/sensors listing:\n"); - printf(" Shows devices and/or sensors using key=value format (with tabs as\n"); - printf(" separators, one device/sensor per line, no header lines.)\n"); - printf("\n"); - printf(" --help (-h short option)\n"); - printf(" Shows this screen.\n"); - printf("\n"); - printf(" --on device (-n short option)\n"); - printf(" Turns on device. 'device' could either be an integer of the\n"); - printf(" device-id, or the name of the device.\n"); - printf(" Both device-id and name is outputed with the --list option\n"); - printf("\n"); - printf(" --off device (-f short option)\n"); - printf(" Turns off device. 'device' could either be an integer of the\n"); - printf(" device-id, or the name of the device.\n"); - printf(" Both device-id and name is outputed with the --list option\n"); - printf("\n"); - printf(" --dim device (-d short option)\n"); - printf(" Dims device. 'device' could either be an integer of the device-id,\n"); - printf(" or the name of the device.\n"); - printf(" Both device-id and name is outputed with the --list option\n"); - printf(" Note: The dimlevel parameter must be set before using this option.\n"); - printf("\n"); - printf(" --dimlevel level (-v short option)\n"); - printf(" Set dim level. 'level' should an integer, 0-255.\n"); - printf(" Note: This parameter must be set before using dim.\n"); - printf("\n"); - printf(" --bell device (-b short option)\n"); - printf(" Sends bell command to devices supporting this. 'device' could\n"); - printf(" either be an integer of the device-id, or the name of the device.\n"); - printf(" Both device-id and name is outputed with the --list option\n"); - printf("\n"); - printf(" --learn device (-e short option)\n"); - printf(" Sends a special learn command to devices supporting this. This is normaly\n"); - printf(" devices of 'selflearning' type. 'device' could either be an integer\n"); - printf(" of the device-id, or the name of the device.\n"); - printf(" Both device-id and name is outputed with the --list option\n"); - printf("\n"); - printf(" --raw input (-r short option)\n"); - printf(" This command sends a raw command to TellStick.\n"); - printf(" input can be either - or a filename. If input is - the data is\n"); - printf(" taken from stdin, otherwise the data is taken from the supplied filename.\n"); - printf("\n"); - printf(" Example to turn on an ArcTech codeswitch A1:\n"); - printf(" echo 'S$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$kk$$kk$$kk$$}+' | tdtool --raw -\n"); - printf("\n"); - printf("Report bugs to \n"); -} - -void print_version() { - printf("tdtool " VERSION "\n"); - printf("\n"); - printf("Copyright (C) 2011 Telldus Technologies AB\n"); - printf("\n"); - printf("Written by Micke Prag \n"); -} - -void print_device( int index ) { - tdInit(); - int intId = tdGetDeviceId(index); - char *name = tdGetName(intId); - printf("%i\t%s\t", intId, name); - tdReleaseString(name); - int lastSentCommand = tdLastSentCommand(intId, SUPPORTED_METHODS); - char *level = 0; - switch(lastSentCommand) { - case TELLSTICK_TURNON: - printf("ON"); - break; - case TELLSTICK_TURNOFF: - printf("OFF"); - break; - case TELLSTICK_DIM: - level = tdLastSentValue(intId); - printf("DIMMED:%s", level); - tdReleaseString(level); - break; - default: - printf("Unknown state"); - } - printf("\n"); -} - -int list_devices() { - tdInit(); - int intNum = tdGetNumberOfDevices(); - if (intNum < 0) { - char *errorString = tdGetErrorString(intNum); - fprintf(stderr, "Error fetching devices: %s\n", errorString); - tdReleaseString(errorString); - return intNum; - } - printf("Number of devices: %i\n", intNum); - int i = 0; - while (i < intNum) { - print_device( i ); - i++; - } - - char protocol[DATA_LENGTH], model[DATA_LENGTH]; - int sensorId = 0, dataTypes = 0; - - int sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); - if(sensorStatus == 0){ - printf("\n\nSENSORS:\n\n%-20s\t%-20s\t%-5s\t%-5s\t%-8s\t%-20s\n", "PROTOCOL", "MODEL", "ID", "TEMP", "HUMIDITY", "LAST UPDATED"); - } - while(sensorStatus == 0){ - char tempvalue[DATA_LENGTH]; - tempvalue[0] = 0; - char humidityvalue[DATA_LENGTH]; - humidityvalue[0] = 0; - char timeBuf[80]; - timeBuf[0] = 0; - time_t timestamp = 0; - - if (dataTypes & TELLSTICK_TEMPERATURE) { - tdSensorValue(protocol, model, sensorId, TELLSTICK_TEMPERATURE, tempvalue, DATA_LENGTH, (int *)×tamp); - strcat(tempvalue, DEGREE); - strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); - } - - if (dataTypes & TELLSTICK_HUMIDITY) { - tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)×tamp); - strcat(humidityvalue, "%"); - strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); - } - printf("%-20s\t%-20s\t%-5i\t%-5s\t%-8s\t%-20s\n", protocol, model, sensorId, tempvalue, humidityvalue, timeBuf); - - sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); - } - printf("\n"); - if(sensorStatus != TELLSTICK_ERROR_DEVICE_NOT_FOUND){ - char *errorString = tdGetErrorString(sensorStatus); - fprintf(stderr, "Error fetching sensors: %s\n", errorString); - tdReleaseString(errorString); - return sensorStatus; - } - return TELLSTICK_SUCCESS; -} - -/* list sensors using key=value format, one sensor/line, no header lines - * and no degree or percent signs attached to the numbers - just - * plain values. */ -int list_kv_sensors() { - char protocol[DATA_LENGTH], model[DATA_LENGTH]; - - tdInit(); - int sensorId = 0, dataTypes = 0; - time_t now = 0; - int sensorStatus; - - time(&now); - while(1) { - sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); - if (sensorStatus != 0) break; - - printf("type=sensor\tprotocol=%s\tmodel=%s\tid=%d", - protocol, model, sensorId); - - time_t timestamp = 0; - - if (dataTypes & TELLSTICK_TEMPERATURE) { - char tempvalue[DATA_LENGTH]; - tdSensorValue(protocol, model, sensorId, TELLSTICK_TEMPERATURE, tempvalue, DATA_LENGTH, (int *)×tamp); - printf("\ttemperature=%s", tempvalue); - } - - if (dataTypes & TELLSTICK_HUMIDITY) { - char humidityvalue[DATA_LENGTH]; - tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)×tamp); - printf("\thumidity=%s", humidityvalue); - } - - if (dataTypes & (TELLSTICK_TEMPERATURE | TELLSTICK_HUMIDITY)) { - /* timestamp has been set, print time & age */ - /* (age is more useful on e.g. embedded systems - * which may not have real-time clock chips => - * time is useful only as a relative value) */ - char timeBuf[80]; - strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); - printf("\ttime=%s\tage=%d", timeBuf, (int)(now - timestamp)); - } - printf("\n"); - - } - if(sensorStatus != TELLSTICK_ERROR_DEVICE_NOT_FOUND){ - char *errorString = tdGetErrorString(sensorStatus); - fprintf(stderr, "Error fetching sensors: %s\n", errorString); - tdReleaseString(errorString); - return sensorStatus; - } - return TELLSTICK_SUCCESS; -} - -/* list devices using key=value format, one device/line, no header lines */ -int list_kv_devices() { - tdInit(); - int intNum = tdGetNumberOfDevices(); - if (intNum < 0) { - char *errorString = tdGetErrorString(intNum); - fprintf(stderr, "Error fetching devices: %s\n", errorString); - tdReleaseString(errorString); - return intNum; - } - int index = 0; - while (index < intNum) { - tdInit(); - int intId = tdGetDeviceId(index); - char *name = tdGetName(intId); - printf("type=device\tid=%i\tname=%s", intId, name); - tdReleaseString(name); - - int lastSentCommand = tdLastSentCommand(intId, SUPPORTED_METHODS); - char *level = 0; - switch(lastSentCommand) { - case TELLSTICK_TURNON: - printf("\tlastsentcommand=ON"); - break; - case TELLSTICK_TURNOFF: - printf("\tlastsentcommand=OFF"); - break; - case TELLSTICK_DIM: - level = tdLastSentValue(intId); - printf("\tlastsentcommand=DIMMED\tdimlevel=%s", level); - tdReleaseString(level); - break; - /* default: state is unknown, print nothing. */ - } - printf("\n"); - index++; - } -} - - -int find_device( char *device ) { - tdInit(); - int deviceId = atoi(device); - if (deviceId == 0) { //Try to find the id from the name - int intNum = tdGetNumberOfDevices(); - int index = 0; - while (index < intNum) { - int id = tdGetDeviceId(index); - char *name = tdGetName( id ); - if (strcasecmp(name, device) == 0) { - deviceId = id; - tdReleaseString(name); - break; - } - tdReleaseString(name); - index++; - } - } - return deviceId; -} - -int switch_device( bool turnOn, char *device ) { - tdInit(); - int deviceId = find_device( device ); - if (deviceId == 0) { - printf("Device '%s', not found!\n", device); - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - char *name = tdGetName( deviceId ); - int deviceType = tdGetDeviceType( deviceId ); - printf("Turning %s %s %i, %s", - (turnOn ? "on" : "off"), - (deviceType == TELLSTICK_TYPE_DEVICE ? "device" : "group"), - deviceId, - name); - tdReleaseString(name); - - int retval = (turnOn ? tdTurnOn( deviceId ) : tdTurnOff( deviceId )); - char *errorString = tdGetErrorString(retval); - - printf(" - %s\n", errorString); - tdReleaseString(errorString); - return retval; -} - -int dim_device( char *device, int level ) { - tdInit(); - int deviceId = find_device( device ); - if (deviceId == 0) { - printf("Device '%s', not found!\n", device); - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - if (level < 0 || level > 255) { - printf("Level %i out of range!\n", level); - return TELLSTICK_ERROR_SYNTAX; - } - - char *name = tdGetName( deviceId ); - int retval = tdDim( deviceId, (unsigned char)level ); - char *errorString = tdGetErrorString(retval); - printf("Dimming device: %i %s to %i - %s\n", deviceId, name, level, errorString); - tdReleaseString(name); - tdReleaseString(errorString); - return retval; -} - -int bell_device( char *device ) { - tdInit(); - int deviceId = find_device( device ); - if (deviceId == 0) { - printf("Device '%s', not found!\n", device); - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - char *name = tdGetName( deviceId ); - int retval = tdBell( deviceId ); - char *errorString = tdGetErrorString(retval); - printf("Sending bell to: %i %s - %s\n", deviceId, name, errorString); - tdReleaseString(name); - tdReleaseString(errorString); - return retval; -} - -int learn_device( char *device ) { - tdInit(); - int deviceId = find_device( device ); - if (deviceId == 0) { - printf("Device '%s', not found!\n", device); - return TELLSTICK_ERROR_DEVICE_NOT_FOUND; - } - - char *name = tdGetName( deviceId ); - int retval = tdLearn( deviceId ); - char *errorString = tdGetErrorString(retval); - printf("Learning device: %i %s - %s\n", deviceId, name, errorString); - tdReleaseString(name); - tdReleaseString(errorString); - return retval; -} - -int send_raw_command( char *command ) { - tdInit(); - const int MAX_LENGTH = 100; - char msg[MAX_LENGTH]; - - if (strcmp(command, "-") == 0) { - fgets(msg, MAX_LENGTH, stdin); - } else { - FILE *fd; - - fd = fopen(command, "r"); - if (fd == NULL) { - printf("Error opening file %s\n", command); - return TELLSTICK_ERROR_UNKNOWN; - } - fgets(msg, MAX_LENGTH, fd); - fclose(fd); - } - - int retval = tdSendRawCommand( msg, 0 ); - char *errorString = tdGetErrorString(retval); - printf("Sending raw command: %s\n", errorString); - tdReleaseString(errorString); - return retval; -} - -#define LIST_KV_SENSORS 1 -#define LIST_KV_DEVICES 2 - -int main(int argc, char **argv) -{ - int optch, longindex; - static char optstring[] = "ln:f:d:b:v:e:r:hi"; - static struct option long_opts[] = { - { "list", 0, 0, 'l' }, - { "list-sensors", 0, 0, LIST_KV_SENSORS }, - { "list-devices", 0, 0, LIST_KV_DEVICES }, - { "on", 1, 0, 'n' }, - { "off", 1, 0, 'f' }, - { "dim", 1, 0, 'd' }, - { "bell", 1, 0, 'b' }, - { "dimlevel", 1, 0, 'v' }, - { "learn", 1, 0, 'e' }, - { "raw", 1, 0, 'r' }, - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'i'}, - { 0, 0, 0, 0} - }; - int level = -1; - - if (argc < 2) { - print_usage( argv[0] ); - return -TELLSTICK_ERROR_SYNTAX; - } - - int returnSuccess = 0; - while ( (optch = getopt_long(argc,argv,optstring,long_opts,&longindex)) != -1 ){ - int success = 0; - switch (optch) { - case 'b' : - success = bell_device( &optarg[0] ); - break; - case 'd' : - if (level >= 0) { - success = dim_device( &optarg[0], level ); - break; - } - printf("Dim level missing or incorrect value.\n"); - success = TELLSTICK_ERROR_SYNTAX; - break; - case 'f' : - success = switch_device(false, &optarg[0]); - break; - case 'h' : - print_usage( argv[0] ); - success = TELLSTICK_SUCCESS; - break; - case 'i' : - print_version( ); - success = TELLSTICK_SUCCESS; - break; - case 'l' : - success = list_devices(); - break; - case LIST_KV_SENSORS: - success = list_kv_sensors(); - break; - case LIST_KV_DEVICES: - success = list_kv_devices(); - break; - case 'n' : - success = switch_device(true, &optarg[0]); - break; - case 'e' : - success = learn_device(&optarg[0]); - break; - case 'r' : - success = send_raw_command(&optarg[0]); - break; - case 'v' : - level = atoi( &optarg[0] ); - break; - default : - print_usage( argv[0] ); - success = TELLSTICK_ERROR_SYNTAX; - } - if(success != TELLSTICK_SUCCESS){ - returnSuccess = success; //return last error message - } - } - tdClose(); //Cleaning up - return -returnSuccess; -} +#include +#include +#include +#include +#include +#include "../client/telldus-core.h" + +#ifdef _WINDOWS +#define strcasecmp _stricmp +#define DEGREE " " +#else +#define DEGREE "°" +#endif + +const int SUPPORTED_METHODS = + TELLSTICK_TURNON | + TELLSTICK_TURNOFF | + TELLSTICK_BELL | + TELLSTICK_DIM; + +const int DATA_LENGTH = 20; + +void print_usage( char *name ) { + printf("Usage: %s [ options ]\n", name); + printf("\n"); + printf("Options:\n"); + printf(" -[bdefhlnrv] [ --list ] [ --help ]\n"); + printf(" [ --list-sensors ] [ --list-devices ]\n"); + printf(" [ --on device ] [ --off device ] [ --bell device ]\n"); + printf(" [ --learn device ]\n"); + printf(" [ --dimlevel level --dim device ]\n"); + printf(" [ --raw input ]\n"); + printf("\n"); + printf(" --list (-l short option)\n"); + printf(" List currently configured devices and all discovered sensors.\n"); + printf("\n"); + printf(" --list-sensors\n"); + printf(" --list-devices\n"); + printf(" Alternative devices/sensors listing:\n"); + printf(" Shows devices and/or sensors using key=value format (with tabs as\n"); + printf(" separators, one device/sensor per line, no header lines.)\n"); + printf("\n"); + printf(" --help (-h short option)\n"); + printf(" Shows this screen.\n"); + printf("\n"); + printf(" --on device (-n short option)\n"); + printf(" Turns on device. 'device' could either be an integer of the\n"); + printf(" device-id, or the name of the device.\n"); + printf(" Both device-id and name is outputed with the --list option\n"); + printf("\n"); + printf(" --off device (-f short option)\n"); + printf(" Turns off device. 'device' could either be an integer of the\n"); + printf(" device-id, or the name of the device.\n"); + printf(" Both device-id and name is outputed with the --list option\n"); + printf("\n"); + printf(" --dim device (-d short option)\n"); + printf(" Dims device. 'device' could either be an integer of the device-id,\n"); + printf(" or the name of the device.\n"); + printf(" Both device-id and name is outputed with the --list option\n"); + printf(" Note: The dimlevel parameter must be set before using this option.\n"); + printf("\n"); + printf(" --dimlevel level (-v short option)\n"); + printf(" Set dim level. 'level' should an integer, 0-255.\n"); + printf(" Note: This parameter must be set before using dim.\n"); + printf("\n"); + printf(" --bell device (-b short option)\n"); + printf(" Sends bell command to devices supporting this. 'device' could\n"); + printf(" either be an integer of the device-id, or the name of the device.\n"); + printf(" Both device-id and name is outputed with the --list option\n"); + printf("\n"); + printf(" --learn device (-e short option)\n"); + printf(" Sends a special learn command to devices supporting this. This is normaly\n"); + printf(" devices of 'selflearning' type. 'device' could either be an integer\n"); + printf(" of the device-id, or the name of the device.\n"); + printf(" Both device-id and name is outputed with the --list option\n"); + printf("\n"); + printf(" --raw input (-r short option)\n"); + printf(" This command sends a raw command to TellStick.\n"); + printf(" input can be either - or a filename. If input is - the data is\n"); + printf(" taken from stdin, otherwise the data is taken from the supplied filename.\n"); + printf("\n"); + printf(" Example to turn on an ArcTech codeswitch A1:\n"); + printf(" echo 'S$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$k$kk$$kk$$kk$$}+' | tdtool --raw -\n"); + printf("\n"); + printf("Report bugs to \n"); +} + +void print_version() { + printf("tdtool " VERSION "\n"); + printf("\n"); + printf("Copyright (C) 2011 Telldus Technologies AB\n"); + printf("\n"); + printf("Written by Micke Prag \n"); +} + +void print_device( int index ) { + tdInit(); + int intId = tdGetDeviceId(index); + char *name = tdGetName(intId); + printf("%i\t%s\t", intId, name); + tdReleaseString(name); + int lastSentCommand = tdLastSentCommand(intId, SUPPORTED_METHODS); + char *level = 0; + switch(lastSentCommand) { + case TELLSTICK_TURNON: + printf("ON"); + break; + case TELLSTICK_TURNOFF: + printf("OFF"); + break; + case TELLSTICK_DIM: + level = tdLastSentValue(intId); + printf("DIMMED:%s", level); + tdReleaseString(level); + break; + default: + printf("Unknown state"); + } + printf("\n"); +} + +int list_devices() { + tdInit(); + int intNum = tdGetNumberOfDevices(); + if (intNum < 0) { + char *errorString = tdGetErrorString(intNum); + fprintf(stderr, "Error fetching devices: %s\n", errorString); + tdReleaseString(errorString); + return intNum; + } + printf("Number of devices: %i\n", intNum); + int i = 0; + while (i < intNum) { + print_device( i ); + i++; + } + + char protocol[DATA_LENGTH], model[DATA_LENGTH]; + int sensorId = 0, dataTypes = 0; + + int sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); + if(sensorStatus == 0){ + printf("\n\nSENSORS:\n\n%-20s\t%-20s\t%-5s\t%-5s\t%-8s\t%-20s\n", "PROTOCOL", "MODEL", "ID", "TEMP", "HUMIDITY", "LAST UPDATED"); + } + while(sensorStatus == 0){ + char tempvalue[DATA_LENGTH]; + tempvalue[0] = 0; + char humidityvalue[DATA_LENGTH]; + humidityvalue[0] = 0; + char timeBuf[80]; + timeBuf[0] = 0; + time_t timestamp = 0; + + if (dataTypes & TELLSTICK_TEMPERATURE) { + tdSensorValue(protocol, model, sensorId, TELLSTICK_TEMPERATURE, tempvalue, DATA_LENGTH, (int *)×tamp); + strcat(tempvalue, DEGREE); + strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); + } + + if (dataTypes & TELLSTICK_HUMIDITY) { + tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)×tamp); + strcat(humidityvalue, "%"); + strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); + } + printf("%-20s\t%-20s\t%-5i\t%-5s\t%-8s\t%-20s\n", protocol, model, sensorId, tempvalue, humidityvalue, timeBuf); + + sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); + } + printf("\n"); + if(sensorStatus != TELLSTICK_ERROR_DEVICE_NOT_FOUND){ + char *errorString = tdGetErrorString(sensorStatus); + fprintf(stderr, "Error fetching sensors: %s\n", errorString); + tdReleaseString(errorString); + return sensorStatus; + } + return TELLSTICK_SUCCESS; +} + +/* list sensors using key=value format, one sensor/line, no header lines + * and no degree or percent signs attached to the numbers - just + * plain values. */ +int list_kv_sensors() { + char protocol[DATA_LENGTH], model[DATA_LENGTH]; + + tdInit(); + int sensorId = 0, dataTypes = 0; + time_t now = 0; + int sensorStatus; + + time(&now); + while(1) { + sensorStatus = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); + if (sensorStatus != 0) break; + + printf("type=sensor\tprotocol=%s\tmodel=%s\tid=%d", + protocol, model, sensorId); + + time_t timestamp = 0; + + if (dataTypes & TELLSTICK_TEMPERATURE) { + char tempvalue[DATA_LENGTH]; + tdSensorValue(protocol, model, sensorId, TELLSTICK_TEMPERATURE, tempvalue, DATA_LENGTH, (int *)×tamp); + printf("\ttemperature=%s", tempvalue); + } + + if (dataTypes & TELLSTICK_HUMIDITY) { + char humidityvalue[DATA_LENGTH]; + tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)×tamp); + printf("\thumidity=%s", humidityvalue); + } + + if (dataTypes & (TELLSTICK_TEMPERATURE | TELLSTICK_HUMIDITY)) { + /* timestamp has been set, print time & age */ + /* (age is more useful on e.g. embedded systems + * which may not have real-time clock chips => + * time is useful only as a relative value) */ + char timeBuf[80]; + strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(×tamp)); + printf("\ttime=%s\tage=%d", timeBuf, (int)(now - timestamp)); + } + printf("\n"); + + } + if(sensorStatus != TELLSTICK_ERROR_DEVICE_NOT_FOUND){ + char *errorString = tdGetErrorString(sensorStatus); + fprintf(stderr, "Error fetching sensors: %s\n", errorString); + tdReleaseString(errorString); + return sensorStatus; + } + return TELLSTICK_SUCCESS; +} + +/* list devices using key=value format, one device/line, no header lines */ +int list_kv_devices() { + tdInit(); + int intNum = tdGetNumberOfDevices(); + if (intNum < 0) { + char *errorString = tdGetErrorString(intNum); + fprintf(stderr, "Error fetching devices: %s\n", errorString); + tdReleaseString(errorString); + return intNum; + } + int index = 0; + while (index < intNum) { + tdInit(); + int intId = tdGetDeviceId(index); + char *name = tdGetName(intId); + printf("type=device\tid=%i\tname=%s", intId, name); + tdReleaseString(name); + + int lastSentCommand = tdLastSentCommand(intId, SUPPORTED_METHODS); + char *level = 0; + switch(lastSentCommand) { + case TELLSTICK_TURNON: + printf("\tlastsentcommand=ON"); + break; + case TELLSTICK_TURNOFF: + printf("\tlastsentcommand=OFF"); + break; + case TELLSTICK_DIM: + level = tdLastSentValue(intId); + printf("\tlastsentcommand=DIMMED\tdimlevel=%s", level); + tdReleaseString(level); + break; + /* default: state is unknown, print nothing. */ + } + printf("\n"); + index++; + } +} + + +int find_device( char *device ) { + tdInit(); + int deviceId = atoi(device); + if (deviceId == 0) { //Try to find the id from the name + int intNum = tdGetNumberOfDevices(); + int index = 0; + while (index < intNum) { + int id = tdGetDeviceId(index); + char *name = tdGetName( id ); + if (strcasecmp(name, device) == 0) { + deviceId = id; + tdReleaseString(name); + break; + } + tdReleaseString(name); + index++; + } + } + return deviceId; +} + +int switch_device( bool turnOn, char *device ) { + tdInit(); + int deviceId = find_device( device ); + if (deviceId == 0) { + printf("Device '%s', not found!\n", device); + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + char *name = tdGetName( deviceId ); + int deviceType = tdGetDeviceType( deviceId ); + printf("Turning %s %s %i, %s", + (turnOn ? "on" : "off"), + (deviceType == TELLSTICK_TYPE_DEVICE ? "device" : "group"), + deviceId, + name); + tdReleaseString(name); + + int retval = (turnOn ? tdTurnOn( deviceId ) : tdTurnOff( deviceId )); + char *errorString = tdGetErrorString(retval); + + printf(" - %s\n", errorString); + tdReleaseString(errorString); + return retval; +} + +int dim_device( char *device, int level ) { + tdInit(); + int deviceId = find_device( device ); + if (deviceId == 0) { + printf("Device '%s', not found!\n", device); + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + if (level < 0 || level > 255) { + printf("Level %i out of range!\n", level); + return TELLSTICK_ERROR_SYNTAX; + } + + char *name = tdGetName( deviceId ); + int retval = tdDim( deviceId, (unsigned char)level ); + char *errorString = tdGetErrorString(retval); + printf("Dimming device: %i %s to %i - %s\n", deviceId, name, level, errorString); + tdReleaseString(name); + tdReleaseString(errorString); + return retval; +} + +int bell_device( char *device ) { + tdInit(); + int deviceId = find_device( device ); + if (deviceId == 0) { + printf("Device '%s', not found!\n", device); + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + char *name = tdGetName( deviceId ); + int retval = tdBell( deviceId ); + char *errorString = tdGetErrorString(retval); + printf("Sending bell to: %i %s - %s\n", deviceId, name, errorString); + tdReleaseString(name); + tdReleaseString(errorString); + return retval; +} + +int learn_device( char *device ) { + tdInit(); + int deviceId = find_device( device ); + if (deviceId == 0) { + printf("Device '%s', not found!\n", device); + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + + char *name = tdGetName( deviceId ); + int retval = tdLearn( deviceId ); + char *errorString = tdGetErrorString(retval); + printf("Learning device: %i %s - %s\n", deviceId, name, errorString); + tdReleaseString(name); + tdReleaseString(errorString); + return retval; +} + +int send_raw_command( char *command ) { + tdInit(); + const int MAX_LENGTH = 100; + char msg[MAX_LENGTH]; + + if (strcmp(command, "-") == 0) { + fgets(msg, MAX_LENGTH, stdin); + } else { + FILE *fd; + + fd = fopen(command, "r"); + if (fd == NULL) { + printf("Error opening file %s\n", command); + return TELLSTICK_ERROR_UNKNOWN; + } + fgets(msg, MAX_LENGTH, fd); + fclose(fd); + } + + int retval = tdSendRawCommand( msg, 0 ); + char *errorString = tdGetErrorString(retval); + printf("Sending raw command: %s\n", errorString); + tdReleaseString(errorString); + return retval; +} + +#define LIST_KV_SENSORS 1 +#define LIST_KV_DEVICES 2 + +int main(int argc, char **argv) +{ + int optch, longindex; + static char optstring[] = "ln:f:d:b:v:e:r:hi"; + static struct option long_opts[] = { + { "list", 0, 0, 'l' }, + { "list-sensors", 0, 0, LIST_KV_SENSORS }, + { "list-devices", 0, 0, LIST_KV_DEVICES }, + { "on", 1, 0, 'n' }, + { "off", 1, 0, 'f' }, + { "dim", 1, 0, 'd' }, + { "bell", 1, 0, 'b' }, + { "dimlevel", 1, 0, 'v' }, + { "learn", 1, 0, 'e' }, + { "raw", 1, 0, 'r' }, + { "help", 0, 0, 'h' }, + { "version", 0, 0, 'i'}, + { 0, 0, 0, 0} + }; + int level = -1; + + if (argc < 2) { + print_usage( argv[0] ); + return -TELLSTICK_ERROR_SYNTAX; + } + + int returnSuccess = 0; + while ( (optch = getopt_long(argc,argv,optstring,long_opts,&longindex)) != -1 ){ + int success = 0; + switch (optch) { + case 'b' : + success = bell_device( &optarg[0] ); + break; + case 'd' : + if (level >= 0) { + success = dim_device( &optarg[0], level ); + break; + } + printf("Dim level missing or incorrect value.\n"); + success = TELLSTICK_ERROR_SYNTAX; + break; + case 'f' : + success = switch_device(false, &optarg[0]); + break; + case 'h' : + print_usage( argv[0] ); + success = TELLSTICK_SUCCESS; + break; + case 'i' : + print_version( ); + success = TELLSTICK_SUCCESS; + break; + case 'l' : + success = list_devices(); + break; + case LIST_KV_SENSORS: + success = list_kv_sensors(); + break; + case LIST_KV_DEVICES: + success = list_kv_devices(); + break; + case 'n' : + success = switch_device(true, &optarg[0]); + break; + case 'e' : + success = learn_device(&optarg[0]); + break; + case 'r' : + success = send_raw_command(&optarg[0]); + break; + case 'v' : + level = atoi( &optarg[0] ); + break; + default : + print_usage( argv[0] ); + success = TELLSTICK_ERROR_SYNTAX; + } + if(success != TELLSTICK_SUCCESS){ + returnSuccess = success; //return last error message + } + } + tdClose(); //Cleaning up + return -returnSuccess; +} diff --git a/telldus-core/tests/common/CMakeLists.txt b/telldus-core/tests/common/CMakeLists.txt index 0386e19f..4c7fca41 100644 --- a/telldus-core/tests/common/CMakeLists.txt +++ b/telldus-core/tests/common/CMakeLists.txt @@ -1,9 +1,9 @@ -FILE(GLOB SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*Test.cpp" ) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) - -ADD_LIBRARY(TelldusCommonTests SHARED ${SRCS} ) - -TARGET_LINK_LIBRARIES( TelldusCommonTests TelldusCommon ) -ADD_DEPENDENCIES( TelldusCommonTests TelldusCommon ) - +FILE(GLOB SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*Test.cpp" ) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + +ADD_LIBRARY(TelldusCommonTests SHARED ${SRCS} ) + +TARGET_LINK_LIBRARIES( TelldusCommonTests TelldusCommon ) +ADD_DEPENDENCIES( TelldusCommonTests TelldusCommon ) +