Convert dos endings to unix in telldus-core, see #160

This commit is contained in:
Micke Prag 2012-02-27 17:37:52 +01:00
parent bdd95b8d78
commit 9500c4c898
72 changed files with 8881 additions and 8881 deletions

View file

@ -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)

View file

@ -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)

View file

@ -1,266 +1,266 @@
#include "Client.h"
#include "CallbackDispatcher.h"
#include "CallbackMainDispatcher.h"
#include "Socket.h"
#include "Strings.h"
#include "Mutex.h"
#include <list>
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 <list>
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;
}

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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} )

View file

@ -1,77 +1,77 @@
#include "Event.h"
#include "EventHandler.h"
#include "Mutex.h"
#include <list>
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<EventDataRef> 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 <list>
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<EventDataRef> 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;
}

View file

@ -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

View file

@ -1,72 +1,72 @@
#include "EventHandler.h"
#include "Event.h"
#include "Mutex.h"
#include "Thread.h"
#include <list>
#include <pthread.h>
#include <stdio.h>
using namespace TelldusCore;
class EventHandler::PrivateData {
public:
pthread_cond_t event;
pthread_mutex_t mutex;
std::list<EventRef> 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<EventRef>::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<EventRef>::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 <list>
#include <pthread.h>
#include <stdio.h>
using namespace TelldusCore;
class EventHandler::PrivateData {
public:
pthread_cond_t event;
pthread_mutex_t mutex;
std::list<EventRef> 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<EventRef>::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<EventRef>::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;
}

View file

@ -1,69 +1,69 @@
#include "EventHandler.h"
#include "Event.h"
#include "Mutex.h"
#include <windows.h>
#include <list>
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 <windows.h>
#include <list>
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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -1,128 +1,128 @@
#include "Message.h"
#include "Socket.h"
#include "Strings.h"
#include <sstream>
#include <wctype.h>
#include <stdlib.h>
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 <sstream>
#include <wctype.h>
#include <stdlib.h>
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;
}

View file

@ -1,31 +1,31 @@
#ifndef MESSAGE_H
#define MESSAGE_H
#include <string>
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 <string>
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

View file

@ -1,33 +1,33 @@
#ifndef SOCKET_H
#define SOCKET_H
#include <string>
#ifdef _WINDOWS
#include <windows.h>
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 <string>
#ifdef _WINDOWS
#include <windows.h>
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

View file

@ -1,127 +1,127 @@
#include "Socket.h"
#include "Mutex.h"
#include "Strings.h"
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <math.h>
#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 <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <math.h>
#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;
}
}

View file

@ -1,180 +1,180 @@
#include "Socket.h"
#include <windows.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#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 <windows.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#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;
}

View file

@ -1,257 +1,257 @@
#include "Strings.h"
#include <algorithm>
#include <sstream>
#include <string>
#include <string.h>
#include <stdio.h>
#ifdef _WINDOWS
#include <windows.h>
#else
#include <iconv.h>
#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 <algorithm>
#include <sstream>
#include <string>
#include <string.h>
#include <stdio.h>
#ifdef _WINDOWS
#include <windows.h>
#else
#include <iconv.h>
#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;
}
}
}

View file

@ -1,33 +1,33 @@
#ifndef STRING_H
#define STRING_H
#include <string>
#include <stdarg.h>
#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 <stdint.h>
#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 <string>
#include <stdarg.h>
#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 <stdint.h>
#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

View file

@ -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)

View file

@ -1,265 +1,265 @@
#include "ClientCommunicationHandler.h"
#include "Message.h"
#include "Strings.h"
#include <stdlib.h>
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 <stdlib.h>
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);
}

View file

@ -1,31 +1,31 @@
#ifndef CONNECTIONLISTENER_H
#define CONNECTIONLISTENER_H
#include <string>
#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 <string>
#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

View file

@ -1,91 +1,91 @@
#include "ConnectionListener.h"
#include "Socket.h"
#include <string>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
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 <string>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
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);
}

View file

@ -1,149 +1,149 @@
#include "ConnectionListener.h"
#include "Event.h"
#include "Socket.h"
#include <windows.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#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 <windows.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#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);
}

View file

@ -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<std::string> msgList = Protocol::decodeData(data);
for (std::list<std::string>::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<std::string> msgList = Protocol::decodeData(data);
for (std::list<std::string>::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);
}

View file

@ -1,32 +1,32 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "Event.h"
#include <string>
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 <string>
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

View file

@ -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 <map>
#include <stdio.h>
class ControllerDescriptor {
public:
std::wstring name, serial;
int type;
Controller *controller;
};
typedef std::map<int, ControllerDescriptor> 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<TellStick*>(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<TellStickDescriptor> list = TellStick::findAll();
std::list<TellStickDescriptor>::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<TellStick*>(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<TellStick *> 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<TellStick*>(it->second.controller);
if (tellstick) {
tellStickControllers.push_back(tellstick);
}
}
}
bool reloadControllers = false;
std::string noop = "N+";
for(std::list<TellStick *>::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<TellStick*>(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 <map>
#include <stdio.h>
class ControllerDescriptor {
public:
std::wstring name, serial;
int type;
Controller *controller;
};
typedef std::map<int, ControllerDescriptor> 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<TellStick*>(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<TellStickDescriptor> list = TellStick::findAll();
std::list<TellStickDescriptor>::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<TellStick*>(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<TellStick *> 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<TellStick*>(it->second.controller);
if (tellstick) {
tellStickControllers.push_back(tellstick);
}
}
}
bool reloadControllers = false;
std::string noop = "N+";
for(std::list<TellStick *>::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<TellStick*>(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);
}

View file

@ -1,89 +1,89 @@
#include "ControllerMessage.h"
#include "Device.h"
#include "Strings.h"
#include "common.h"
#include <map>
class ControllerMessage::PrivateData {
public:
std::map<std::string, std::string> 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<std::string, std::string>::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<std::string, std::string>::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 <map>
class ControllerMessage::PrivateData {
public:
std::map<std::string, std::string> 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<std::string, std::string>::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<std::string, std::string>::iterator it = d->parameters.find(key);
if (it == d->parameters.end()) {
return false;
}
return true;
}

View file

@ -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<std::string> 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<TellStick *>(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<std::string> 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<TellStick *>(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;
}

View file

@ -1,45 +1,45 @@
#ifndef DEVICE_H
#define DEVICE_H
#include "Controller.h"
#include "Mutex.h"
#include "Protocol.h"
#include <string>
#include <list>
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<std::string> 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 <string>
#include <list>
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<std::string> 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

File diff suppressed because it is too large Load diff

View file

@ -1,126 +1,126 @@
#include "EventUpdateManager.h"
#include "ConnectionListener.h"
#include "EventHandler.h"
#include "Message.h"
#include "Socket.h"
#include <list>
#include <memory>
typedef std::list<TelldusCore::Socket *> 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<ConnectionListenerEventData*>(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<EventUpdateData*>(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 <list>
#include <memory>
typedef std::list<TelldusCore::Socket *> 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<ConnectionListenerEventData*>(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<EventUpdateData*>(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);
}
}
}

View file

@ -1,181 +1,181 @@
#include "Log.h"
#include <stdarg.h>
#if defined(_LINUX)
#include <syslog.h>
#elif defined(_WINDOWS)
#include <windows.h>
#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 <stdarg.h>
#if defined(_LINUX)
#include <syslog.h>
#elif defined(_WINDOWS)
#include <windows.h>
#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;
}

View file

@ -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 <sstream>
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 &parameterList){
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<std::string> Protocol::getParametersForProtocol(const std::wstring &protocolName) {
std::list<std::string> 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<std::string> Protocol::decodeData(const std::string &fullData) {
std::list<std::string> 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 <sstream>
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 &parameterList){
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<std::string> Protocol::getParametersForProtocol(const std::wstring &protocolName) {
std::list<std::string> 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<std::string> Protocol::decodeData(const std::string &fullData) {
std::list<std::string> 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;
}

View file

@ -1,41 +1,41 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include <string>
#include <list>
#include <map>
#include "../client/telldus-core.h"
typedef std::map<std::wstring, std::wstring> ParameterMap;
class Controller;
class Protocol
{
public:
Protocol();
virtual ~Protocol(void);
static Protocol *getProtocolInstance(const std::wstring &protocolname);
static std::list<std::string> getParametersForProtocol(const std::wstring &protocolName);
static std::list<std::string> decodeData(const std::string &fullData);
virtual int methods() const = 0;
std::wstring model() const;
void setModel(const std::wstring &model);
void setParameters(ParameterMap &parameterList);
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 <string>
#include <list>
#include <map>
#include "../client/telldus-core.h"
typedef std::map<std::wstring, std::wstring> ParameterMap;
class Controller;
class Protocol
{
public:
Protocol();
virtual ~Protocol(void);
static Protocol *getProtocolInstance(const std::wstring &protocolname);
static std::list<std::string> getParametersForProtocol(const std::wstring &protocolName);
static std::list<std::string> decodeData(const std::string &fullData);
virtual int methods() const = 0;
std::wstring model() const;
void setModel(const std::wstring &model);
void setParameters(ParameterMap &parameterList);
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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -1,131 +1,131 @@
#include "ProtocolEverflourish.h"
#include <sstream>
#include <stdio.h>
#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 <sstream>
#include <stdio.h>
#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();
}

View file

@ -1,45 +1,45 @@
#include "ProtocolFineoffset.h"
#include "Strings.h"
#include <stdlib.h>
#include <sstream>
#include <iomanip>
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 <stdlib.h>
#include <sstream>
#include <iomanip>
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();
}

View file

@ -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;
}

View file

@ -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 "";
}

View file

@ -10,7 +10,7 @@ public:
};
#endif //PROTOCOLGROUP_H
#endif //PROTOCOLGROUP_H

View file

@ -1,66 +1,66 @@
#include "ProtocolHasta.h"
#include <sstream>
#include <stdio.h>
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 <sstream>
#include <stdio.h>
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;
}

View file

@ -1,127 +1,127 @@
#include "ProtocolIkea.h"
#include "Strings.h"
#include <stdlib.h>
#include <string.h>
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 <stdlib.h>
#include <string.h>
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;
}

View file

@ -1,38 +1,38 @@
#include "ProtocolMandolyn.h"
#include "Strings.h"
#include <stdlib.h>
#include <sstream>
#include <iomanip>
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 <stdlib.h>
#include <sstream>
#include <iomanip>
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();
}

View file

@ -1,282 +1,282 @@
#include "ProtocolNexa.h"
#include <sstream>
#include <stdio.h>
#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<TellStick *>(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<const char*>(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 <sstream>
#include <stdio.h>
#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<TellStick *>(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<const char*>(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+";
}

View file

@ -1,115 +1,115 @@
#include "ProtocolOregon.h"
#include "Strings.h"
#include <stdlib.h>
#include <sstream>
#include <iomanip>
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 <stdlib.h>
#include <sstream>
#include <iomanip>
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();
}

View file

@ -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;
}

View file

@ -1,104 +1,104 @@
#include "ProtocolSartano.h"
#include <sstream>
#include <stdio.h>
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 <sstream>
#include <stdio.h>
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();
}

View file

@ -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 "";
}

View file

@ -10,7 +10,7 @@ public:
};
#endif //PROTOCOLSCENE_H
#endif //PROTOCOLSCENE_H

View file

@ -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;
}

View file

@ -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;
}

View file

@ -1,69 +1,69 @@
#include "ProtocolWaveman.h"
#include <sstream>
#include <stdio.h>
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 <sstream>
#include <stdio.h>
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();
}

View file

@ -1,174 +1,174 @@
#include "ProtocolX10.h"
#include <stdio.h>
#include <sstream>
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<const char*>(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<const char*>(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 <stdio.h>
#include <sstream>
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<const char*>(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<const char*>(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();
}

View file

@ -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);
}

View file

@ -1,272 +1,272 @@
#include "Settings.h"
#include "Strings.h"
#include <Windows.h>
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#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 <Windows.h>
#include <sstream>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#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<LPBYTE>(&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<LPBYTE>(&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;
}

View file

@ -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;
}
}

View file

@ -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 <stdio.h>
#include <list>
#include <memory>
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<ClientCommunicationHandler *> 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<ConnectionListenerEventData*>(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<ControllerChangeEventData*>(eventDataRef.get());
if (data) {
controllerManager.deviceInsertedOrRemoved(data->vid, data->pid, "", data->inserted);
}
}
if (dataEvent->isSignaled()) {
TelldusCore::EventDataRef eventData = dataEvent->takeSignal();
ControllerEventData *data = reinterpret_cast<ControllerEventData*>(eventData.get());
if (data) {
deviceManager.handleControllerMessage(*data);
}
}
if (handlerEvent->isSignaled()) {
handlerEvent->popSignal();
for ( std::list<ClientCommunicationHandler *>::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 <stdio.h>
#include <list>
#include <memory>
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<ClientCommunicationHandler *> 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<ConnectionListenerEventData*>(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<ControllerChangeEventData*>(eventDataRef.get());
if (data) {
controllerManager.deviceInsertedOrRemoved(data->vid, data->pid, "", data->inserted);
}
}
if (dataEvent->isSignaled()) {
TelldusCore::EventDataRef eventData = dataEvent->takeSignal();
ControllerEventData *data = reinterpret_cast<ControllerEventData*>(eventData.get());
if (data) {
deviceManager.handleControllerMessage(*data);
}
}
if (handlerEvent->isSignaled()) {
handlerEvent->popSignal();
for ( std::list<ClientCommunicationHandler *>::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();
}

View file

@ -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

View file

@ -1,177 +1,177 @@
#include "TelldusWinService_win.h"
#include "TelldusMain.h"
#include "Log.h"
#include <Dbt.h>
#include <string>
#include <algorithm>
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<PDEV_BROADCAST_DEVICEINTERFACE>(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<TelldusWinService *>(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 <Dbt.h>
#include <string>
#include <algorithm>
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<PDEV_BROADCAST_DEVICEINTERFACE>(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<TelldusWinService *>(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 );
}
}

View file

@ -1,35 +1,35 @@
#ifndef TELLDUSSERVICE_WIN_H
#define TELLDUSSERVICE_WIN_H
#include <windows.h>
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 <windows.h>
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

View file

@ -1,114 +1,114 @@
#include "Timer.h"
#include "Mutex.h"
#ifdef _WINDOWS
#else
#include <sys/time.h>
#include <errno.h>
#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 <sys/time.h>
#include <errno.h>
#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
}

View file

@ -1,15 +1,15 @@
#ifdef LIBFTD2XX
#ifdef _WINDOWS
#include <windows.h>
#include "win\ftd2xx.h"
#else
#include "osx/WinTypes.h"
#include "osx/ftd2xx.h"
#endif
#endif
#ifdef LIBFTDI
#include <ftdi.h>
#endif
#ifdef LIBFTD2XX
#ifdef _WINDOWS
#include <windows.h>
#include "win\ftd2xx.h"
#else
#include "osx/WinTypes.h"
#include "osx/ftd2xx.h"
#endif
#endif
#ifdef LIBFTDI
#include <ftdi.h>
#endif

View file

@ -1,20 +1,20 @@
#include "TelldusWinService_win.h"
//#include <QCoreApplication>
#include <windows.h>
#include <Dbt.h>
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 <QCoreApplication>
#include <windows.h>
#include <Dbt.h>
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;
}

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -1,85 +1,85 @@
#include "../client/telldus-core.h"
#include <stdlib.h>
#include <errno.h>
#include <argp.h>
#include <string>
const char *argp_program_version = "tdadmin " VERSION ;
const char *argp_program_bug_address = "<info.tech@telldus.com>";
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 <stdlib.h>
#include <errno.h>
#include <argp.h>
#include <string>
const char *argp_program_version = "tdadmin " VERSION ;
const char *argp_program_bug_address = "<info.tech@telldus.com>";
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;
}

View file

@ -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)

View file

@ -1,486 +1,486 @@
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <ctime>
#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 <info.tech@telldus.se>\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 <micke.prag@telldus.se>\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 *)&timestamp);
strcat(tempvalue, DEGREE);
strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
}
if (dataTypes & TELLSTICK_HUMIDITY) {
tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)&timestamp);
strcat(humidityvalue, "%");
strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
}
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 *)&timestamp);
printf("\ttemperature=%s", tempvalue);
}
if (dataTypes & TELLSTICK_HUMIDITY) {
char humidityvalue[DATA_LENGTH];
tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)&timestamp);
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(&timestamp));
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 <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <ctime>
#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 <info.tech@telldus.se>\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 <micke.prag@telldus.se>\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 *)&timestamp);
strcat(tempvalue, DEGREE);
strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
}
if (dataTypes & TELLSTICK_HUMIDITY) {
tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)&timestamp);
strcat(humidityvalue, "%");
strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));
}
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 *)&timestamp);
printf("\ttemperature=%s", tempvalue);
}
if (dataTypes & TELLSTICK_HUMIDITY) {
char humidityvalue[DATA_LENGTH];
tdSensorValue(protocol, model, sensorId, TELLSTICK_HUMIDITY, humidityvalue, DATA_LENGTH, (int *)&timestamp);
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(&timestamp));
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;
}

View file

@ -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 )