Windows service, 2.1.0a and new changes for possible new version.

This commit is contained in:
Stefan Persson 2011-11-04 14:32:22 +01:00
parent 4b37109f27
commit 24586433d9
12 changed files with 226 additions and 42 deletions

View file

@ -8,6 +8,7 @@
*/
#include "CallbackDispatcher.h"
#include "common.h"
using namespace TelldusCore;
@ -28,7 +29,9 @@ bool TDDeviceEventDispatcher::done() const {
}
void TDDeviceEventDispatcher::run() {
char *str = wrapStdString(strData);
d->event(deviceId, method, strData.c_str(), d->id, d->context);
doneRunning = true;
}

View file

@ -130,6 +130,7 @@ int Client::registerDeviceEvent( TDDeviceEvent eventFunction, void *context ) {
callback->id = id;
callback->context = context;
d->deviceEventList.push_back(callback);
//debuglog(id, "deviceeventadded");
return id;
}
@ -141,6 +142,7 @@ int Client::registerDeviceChangeEvent( TDDeviceChangeEvent eventFunction, void *
callback->id = id;
callback->context = context;
d->deviceChangeEventList.push_back(callback);
//debuglog(id, "devicechangeeventadded");
return id;
}
@ -176,13 +178,24 @@ void Client::run(){
d->eventSocket.connect(L"TelldusEvents"); //try to reconnect to service
if(!d->eventSocket.isConnected()){
//reconnect didn't succeed, wait a while and try again
//debuglog(0, "Reconnecting");
msleep(2000);
continue;
}
}
std::wstring clientMessage = d->eventSocket.read(5000); //testing 5 second timeout
//int test = 0;
/*if(clientMessage != L""){
debuglog(88, "Clientmessage nothing after read");
}*/
while(clientMessage != L""){
//debuglog(99, TelldusCore::wideToString(clientMessage));
//test++;
/*if(test > 5){
debuglog(test, "Test is getting big");
}*/
//a message arrived
std::wstring type = Message::takeString(&clientMessage);
if(type == L"TDDeviceChangeEvent"){
@ -282,16 +295,53 @@ void Client::cleanupCallbacks() {
}
std::wstring Client::sendToService(const Message &msg) {
Socket s;
s.connect(L"TelldusClient");
if (!s.isConnected()) { //Connection failed
TelldusCore::Message msg;
msg.addArgument(TELLSTICK_ERROR_CONNECTING_SERVICE);
return msg;
int tries = 0;
std::wstring readData;
//debuglog(3, "PRETEST");
while(tries < 20){
//debuglog(3, "PRETESTINNE");
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
//debuglog(3, "Ett)"); //deviceeventscallbacks verkar sluta fungera vid/med ett sådant här!? njä, bara ngn ggn...
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)
//debuglog(3, "Två");
msleep(500);
continue; //retry
}
readData = s.read(5000); //500
if(readData == L""){
//debuglog(3, "Empty result (may be ok?)");
/*
if this is enabled, all "send" will run 20 times... - NO! That was due to too short timeout in s.read, turnOn didn't havee titme otecxeu
if it's NOT enabled, tdGetName will often return empty...
*/
msleep(500);
continue; //TODO cannot be sure it SHOULD be anything... right?
}
if (!s.isConnected()) { //Connection failed sometime during operation...
//debuglog(3, "Not connected");
msleep(500);
continue; //retry
}
break;
}
s.write(msg.data());
return s.read(5000);
//debuglog(3, "POSTTEST");
return readData;
}
void Client::stopThread(){
@ -300,6 +350,7 @@ void Client::stopThread(){
}
bool Client::unregisterCallback( int callbackId ) {
//debuglog(callbackId, "unregistering");
DeviceEventList newDEList;
{
TelldusCore::MutexLocker locker(&d->mutex);

View file

@ -23,21 +23,70 @@ Message::~Message(void) {
}
void Message::addArgument(const std::wstring &value) {
std::wstringstream st;
st << (int)value.size();
this->append(st.str());
//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;
//std::wstringstream st;
//st << (int)value;
this->append(L"i");
this->append(st.str());
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));
}

View file

@ -11,6 +11,9 @@ namespace TelldusCore {
~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 *);

View file

@ -1,4 +1,5 @@
#include "Socket.h"
#include "common.h"
#include <windows.h>
#include <AccCtrl.h>
@ -102,18 +103,24 @@ std::wstring Socket::read(int timeout){
if(!d->running){
CancelIo(d->hPipe);
CloseHandle(d->readEvent);
//debuglog(1, "Not running");
return L"";
}
if (result == WAIT_TIMEOUT) {
CancelIo(d->hPipe);
CloseHandle(d->readEvent);
//debuglog(1, "Wait timeout");
return L"";
}
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &cbBytesRead, false);
if (!fSuccess) {
DWORD err = GetLastError();
//debuglog(result, "This then?");
//debuglog(1, "Unsuccessful");
if (err == ERROR_BROKEN_PIPE) {
//debuglog(1, "Broken pipe");
d->connected = false;
}
buf[0] = 0;
@ -143,6 +150,7 @@ void Socket::write(const std::wstring &msg){
CancelIo(d->hPipe);
CloseHandle(writeEvent);
d->connected = false;
//debuglog(2, "Wait timeout");
return;
}
fSuccess = GetOverlappedResult(d->hPipe, &oOverlap, &bytesWritten, TRUE);
@ -150,6 +158,7 @@ void Socket::write(const std::wstring &msg){
if (!fSuccess) {
CancelIo(d->hPipe);
d->connected = false;
//debuglog(2, "Unsuccessful");
return;
}
}

View file

@ -91,17 +91,58 @@ bool TelldusCore::comparei(std::wstring stringA, std::wstring 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
}
*/
int TelldusCore::wideToInteger(const std::wstring &input){
std::wstringstream inputstream;
inputstream << input;

View file

@ -10,6 +10,7 @@ namespace TelldusCore {
bool comparei(std::wstring stringA, std::wstring stringB);
std::wstring intToWstring(int value);
//std::wstring intToWStringSafe(int value);
std::string intToString(int value);
std::string wideToString(const std::wstring &input);

View file

@ -81,6 +81,10 @@ void ClientCommunicationHandler::parseMessage(const std::wstring &clientMessage,
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_TURNOFF, 0);
} else if (function == L"tdBell") {
//TelldusCore::Message msg2;
//msg2.addSpecialArgument(18);
//msg2.addSpecialArgument("testgrej");
int deviceId = TelldusCore::Message::takeInt(&msg);
(*intReturn) = d->deviceManager->doAction(deviceId, TELLSTICK_BELL, 0);

View file

@ -51,15 +51,19 @@ void EventHandler::signal(Event *) {
}
bool EventHandler::waitForAny() {
int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, INFINITE);
TelldusCore::MutexLocker locker(&d->mutex);
if (result == WAIT_TIMEOUT) {
return false;
while(1){
int result = WaitForMultipleObjects(d->eventCount, d->eventArray, FALSE, 1000); //FALSE, INFINITE);
//TODO KANSE ÄNDRA HÄR... Svårt att se effekten säkert, men lite nytta verkade det göra...
if (result == WAIT_TIMEOUT) {
//return false;
continue;
}
TelldusCore::MutexLocker locker(&d->mutex);
int eventIndex = result - WAIT_OBJECT_0;
if (eventIndex >= d->eventCount) {
return false;
}
return true;
}
int eventIndex = result - WAIT_OBJECT_0;
if (eventIndex >= d->eventCount) {
return false;
}
return true;
}

View file

@ -4,6 +4,7 @@
#include "EventHandler.h"
#include "Message.h"
#include "Socket.h"
//#include "common.h" //debug
#include <list>
#include <memory>
@ -73,10 +74,10 @@ void EventUpdateManager::run(){
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"){
@ -116,4 +117,6 @@ void EventUpdateManager::sendMessageToClients(EventUpdateData *data){
it = d->clients.erase(it);
}
}
//debuglog(connected, " - number of clients");
//debuglog(temp2, " - number of clients total");
}

View file

@ -3,7 +3,6 @@
#include <stdio.h>
#include "TellStick.h"
#include "Strings.h"
#include "common.h"
int ProtocolNexa::lastArctecCodeSwitchWasTurnOff=0; //TODO, always removing first turnon now, make more flexible (waveman too)

View file

@ -1,10 +1,12 @@
#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"
@ -93,9 +95,11 @@ int Settings::addDevice() {
DWORD dwDisp;
intDeviceId = getNextDeviceId();
std::wostringstream ssRegPath;
ssRegPath << d->strRegPathDevice << intDeviceId;
std::wstring strCompleteRegPath = ssRegPath.str();
//std::wostringstream ssRegPath;
//ssRegPath << d->strRegPathDevice << intDeviceId;
//std::wstring strCompleteRegPath = ssRegPath.str();
std::wstring strCompleteRegPath = d->strRegPathDevice;
strCompleteRegPath.append(TelldusCore::intToWstring(intDeviceId));
if (RegCreateKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hk, &dwDisp)) {
//fail
@ -143,9 +147,11 @@ int Settings::getNextDeviceId() const {
int Settings::removeDevice(int intDeviceId) {
TelldusCore::MutexLocker locker(&mutex);
std::wostringstream ssRegPath;
ssRegPath << d->strRegPathDevice << intDeviceId;
std::wstring strCompleteRegPath = ssRegPath.str();
//std::wostringstream ssRegPath;
//ssRegPath << d->strRegPathDevice << intDeviceId;
//std::wstring strCompleteRegPath = ssRegPath.str();
std::wstring strCompleteRegPath = d->strRegPathDevice;
strCompleteRegPath.append(TelldusCore::intToWstring(intDeviceId));
long lngSuccess = RegDeleteKey(d->rootKey, strCompleteRegPath.c_str());
@ -161,9 +167,11 @@ std::wstring Settings::getStringSetting(int intDeviceId, const std::wstring &nam
std::wstring strReturn;
HKEY hk;
std::wostringstream ssRegPath;
ssRegPath << d->strRegPathDevice << intDeviceId;
std::wstring strCompleteRegPath = ssRegPath.str();
//std::wostringstream ssRegPath;
//ssRegPath << d->strRegPathDevice << intDeviceId;
//std::wstring strCompleteRegPath = ssRegPath.str();
std::wstring strCompleteRegPath = d->strRegPathDevice;
strCompleteRegPath.append(TelldusCore::intToWstring(intDeviceId));
long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_QUERY_VALUE, &hk);
if(lnExists == ERROR_SUCCESS){
@ -191,9 +199,16 @@ int Settings::setStringSetting(int intDeviceId, const std::wstring &name, const
HKEY hk;
int ret = TELLSTICK_SUCCESS;
std::wostringstream ssRegPath;
ssRegPath << d->strRegPathDevice << intDeviceId;
std::wstring strCompleteRegPath = ssRegPath.str();
//std::wostringstream ssRegPath;
//ssRegPath << d->strRegPathDevice << intDeviceId;
//std::wstring strCompleteRegPath = ssRegPath.str();
//debuglog(intDeviceId, "Device id");
std::wstring bla = TelldusCore::intToWstring(intDeviceId);
//debuglog(888, TelldusCore::wideToString(bla));
//debuglog(555, TelldusCore::wideToString(d->strRegPathDevice));
std::wstring strCompleteRegPath = d->strRegPathDevice;
strCompleteRegPath.append(bla);
//debuglog(999, TelldusCore::wideToString(strCompleteRegPath));
long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk);
if (lnExists == ERROR_SUCCESS){
@ -223,9 +238,11 @@ int Settings::setIntSetting(int intDeviceId, const std::wstring &name, int value
int intReturn = TELLSTICK_ERROR_UNKNOWN;
HKEY hk;
std::wostringstream ssRegPath;
ssRegPath << d->strRegPathDevice << intDeviceId;
std::wstring strCompleteRegPath = ssRegPath.str();
//std::wostringstream ssRegPath;
//ssRegPath << d->strRegPathDevice << intDeviceId;
//std::wstring strCompleteRegPath = ssRegPath.str();
std::wstring strCompleteRegPath = d->strRegPathDevice;
strCompleteRegPath.append(TelldusCore::intToWstring(intDeviceId));
long lnExists = RegOpenKeyEx(d->rootKey, strCompleteRegPath.c_str(), 0, KEY_WRITE, &hk);
if (lnExists == ERROR_SUCCESS) {
DWORD dwVal = value;