Rewrote the TellStick controller
This commit is contained in:
parent
7cfc12d8fa
commit
008feec1c3
5 changed files with 128 additions and 426 deletions
|
@ -12,7 +12,6 @@ SET( telldus-service_SRCS
|
|||
Event.cpp
|
||||
Settings.cpp
|
||||
TelldusMain.cpp
|
||||
TellStick.cpp
|
||||
)
|
||||
SET( telldus-service_protocol_SRCS
|
||||
Protocol.h
|
||||
|
@ -98,6 +97,7 @@ ELSE (APPLE) #### Linux ####
|
|||
EventHandler_unix.cpp
|
||||
main_unix.cpp
|
||||
SettingsConfuse.cpp
|
||||
TellStick_libftdi.cpp
|
||||
)
|
||||
LIST(APPEND telldus-service_LIBRARIES
|
||||
${CONFUSE_LIBRARY}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "TellStick.h"
|
||||
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef std::map<int, Controller *> ControllerMap;
|
||||
|
||||
|
@ -38,27 +39,17 @@ Controller *ControllerManager::getBestControllerById(int id) {
|
|||
}
|
||||
|
||||
void ControllerManager::loadControllers() {
|
||||
while(1) {
|
||||
TellStick *controller = TellStick::findFirstDevice();
|
||||
if (!controller) {
|
||||
break; //All TellStick loaded
|
||||
}
|
||||
//Make sure this isn't already loaded
|
||||
bool found = false;
|
||||
for(ControllerMap::iterator it = d->controllers.begin(); it != d->controllers.end(); ++it) {
|
||||
TellStick *tellstick = reinterpret_cast<TellStick *>(it->second);
|
||||
if (!tellstick) { //No TellStick controller
|
||||
std::list<TellStickDescriptor> list = TellStick::findAll();
|
||||
std::list<TellStickDescriptor>::iterator it = list.begin();
|
||||
for(; it != list.end(); ++it) {
|
||||
printf("Found (%i/%i): %s\n", (*it).vid, (*it).pid, (*it).serial.c_str());
|
||||
TellStick *controller = new TellStick(*it);
|
||||
if (!controller->isOpen()) {
|
||||
delete controller;
|
||||
continue;
|
||||
}
|
||||
if (tellstick->serial().compare(controller->serial()) == 0) { //Found a duplicate
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
d->lastControllerId--;
|
||||
d->controllers[d->lastControllerId] = controller;
|
||||
}
|
||||
printf("List containing %i controllers\n", (int)d->controllers.size());
|
||||
}
|
||||
|
|
|
@ -1,385 +0,0 @@
|
|||
//
|
||||
// C++ Implementation: TellStick
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "TellStick.h"
|
||||
#include "../client/telldus-core.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
class TellStick::TellStickDescriptor {
|
||||
public:
|
||||
bool found;
|
||||
std::string serial;
|
||||
int vid, pid;
|
||||
};
|
||||
|
||||
class TellStick::PrivateData {
|
||||
public:
|
||||
bool open;
|
||||
TellStickHandle ftHandle;
|
||||
TellStickDescriptor descriptor;
|
||||
};
|
||||
|
||||
TellStick::TellStick( const TellStickDescriptor &td ) {
|
||||
d = new PrivateData;
|
||||
d->open = false;
|
||||
d->descriptor = td;
|
||||
|
||||
#ifdef LIBFTDI
|
||||
ftdi_init(&d->ftHandle);
|
||||
|
||||
int ret = ftdi_usb_open_desc(&d->ftHandle, td.vid, td.pid, NULL, td.serial.c_str());
|
||||
if (ret < 0) {
|
||||
ftdi_deinit(&d->ftHandle);
|
||||
return;
|
||||
}
|
||||
d->open = true;
|
||||
ftdi_usb_reset( &d->ftHandle );
|
||||
ftdi_disable_bitbang( &d->ftHandle );
|
||||
#else
|
||||
|
||||
char *tempSerial = new char[td.serial.size()+1];
|
||||
#ifdef _WINDOWS
|
||||
strcpy_s(tempSerial, td.serial.size()+1, td.serial.c_str());
|
||||
#else
|
||||
strcpy(tempSerial, td.serial.c_str());
|
||||
FT_SetVIDPID(td.vid, td.pid);
|
||||
#endif
|
||||
FT_STATUS ftStatus = FT_OpenEx(tempSerial, FT_OPEN_BY_SERIAL_NUMBER, &d->ftHandle);
|
||||
delete tempSerial;
|
||||
if (ftStatus == FT_OK) {
|
||||
d->open = true;
|
||||
FT_SetFlowControl(d->ftHandle, FT_FLOW_NONE, 0, 0);
|
||||
FT_SetTimeouts(d->ftHandle,5000,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (d->open) {
|
||||
setBaud(4800);
|
||||
}
|
||||
}
|
||||
|
||||
TellStick::~TellStick() {
|
||||
if (d->open) {
|
||||
#ifdef LIBFTDI
|
||||
ftdi_usb_close(&d->ftHandle);
|
||||
ftdi_deinit(&d->ftHandle);
|
||||
#else
|
||||
FT_Close(d->ftHandle);
|
||||
#endif
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
int TellStick::vid() const {
|
||||
return d->descriptor.vid;
|
||||
}
|
||||
|
||||
int TellStick::pid() const {
|
||||
return d->descriptor.pid;
|
||||
}
|
||||
|
||||
std::string TellStick::serial() const {
|
||||
return d->descriptor.serial;
|
||||
}
|
||||
|
||||
bool TellStick::open() const {
|
||||
return d->open;
|
||||
}
|
||||
|
||||
TellStick *TellStick::findFirstDevice(int vid, int pid) {
|
||||
TellStick *tellstick = 0;
|
||||
|
||||
if (vid == 0 && pid == 0) {
|
||||
tellstick = findFirstDevice(0x1781, 0x0C30);
|
||||
if (tellstick) {
|
||||
return tellstick;
|
||||
}
|
||||
#ifdef TELLSTICK_DUO
|
||||
tellstick = findFirstDevice(0x1781, 0x0C31);
|
||||
#endif
|
||||
return tellstick;
|
||||
|
||||
}
|
||||
|
||||
TellStickDescriptor d = findByVIDPID(vid, pid);
|
||||
if (d.found) {
|
||||
#ifdef TELLSTICK_DUO
|
||||
if (pid == 0x0C31) {
|
||||
return new TellStickDuo(d);
|
||||
}
|
||||
#endif
|
||||
return new TellStick(d);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TellStick *TellStick::loadBy(int vid, int pid, const std::string &serial) {
|
||||
if (vid != 0x1781) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TellStick *tellstick = 0;
|
||||
|
||||
if (serial.length() == 0) {
|
||||
tellstick = TellStick::findFirstDevice();
|
||||
} else {
|
||||
TellStickDescriptor d;
|
||||
d.vid = vid;
|
||||
d.pid = pid;
|
||||
d.serial = serial;
|
||||
|
||||
if (pid == 0x0C30) {
|
||||
tellstick = new TellStick(d);
|
||||
#ifdef TELLSTICK_DUO
|
||||
} else if (pid == 0x0C31) {
|
||||
tellstick = new TellStickDuo(d);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!tellstick) {
|
||||
return 0;
|
||||
}
|
||||
if (tellstick->open()) {
|
||||
return tellstick;
|
||||
}
|
||||
delete tellstick;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TellStick::TellStickDescriptor TellStick::findByVIDPID( int vid, int pid ) {
|
||||
TellStickDescriptor retval;
|
||||
retval.found = false;
|
||||
retval.vid = vid;
|
||||
retval.pid = pid;
|
||||
|
||||
#ifdef LIBFTDI
|
||||
ftdi_context ftdic;
|
||||
struct ftdi_device_list *devlist, *curdev;
|
||||
char serialBuffer[10];
|
||||
ftdi_init(&ftdic);
|
||||
|
||||
int ret = ftdi_usb_find_all(&ftdic, &devlist, vid, pid);
|
||||
if (ret > 0) {
|
||||
for (curdev = devlist; curdev != NULL; curdev = curdev->next) {
|
||||
ret = ftdi_usb_get_strings(&ftdic, curdev->dev, NULL, 0, NULL, 0, serialBuffer, 10);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
retval.serial = serialBuffer;
|
||||
break;
|
||||
}
|
||||
retval.found = true;
|
||||
}
|
||||
|
||||
ftdi_list_free(&devlist);
|
||||
ftdi_deinit(&ftdic);
|
||||
#else
|
||||
FT_HANDLE fthHandle = 0;
|
||||
FT_STATUS ftStatus = FT_OK;
|
||||
|
||||
try{
|
||||
DWORD dwNumberOfDevices = 0;
|
||||
|
||||
#ifndef _WINDOWS
|
||||
FT_SetVIDPID(vid, pid);
|
||||
#endif
|
||||
ftStatus = FT_CreateDeviceInfoList(&dwNumberOfDevices);
|
||||
if (ftStatus == FT_OK) {
|
||||
for (int i = 0; i < (int)dwNumberOfDevices; i++) {
|
||||
|
||||
FT_PROGRAM_DATA pData;
|
||||
char ManufacturerBuf[32];
|
||||
char ManufacturerIdBuf[16];
|
||||
char DescriptionBuf[64];
|
||||
char SerialNumberBuf[16];
|
||||
|
||||
pData.Signature1 = 0x00000000;
|
||||
pData.Signature2 = 0xffffffff;
|
||||
pData.Version = 0x00000002; // EEPROM structure with FT232R extensions
|
||||
pData.Manufacturer = ManufacturerBuf;
|
||||
pData.ManufacturerId = ManufacturerIdBuf;
|
||||
pData.Description = DescriptionBuf;
|
||||
pData.SerialNumber = SerialNumberBuf;
|
||||
|
||||
ftStatus = FT_Open(i, &fthHandle);
|
||||
ftStatus = FT_EE_Read(fthHandle, &pData);
|
||||
if(ftStatus == FT_OK){
|
||||
if(pData.VendorId == vid && pData.ProductId == pid){
|
||||
ftStatus = FT_Close(fthHandle);
|
||||
retval.found = true;
|
||||
retval.serial = pData.SerialNumber;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftStatus = FT_Close(fthHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int TellStick::firmwareVersion() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TellStick::send(const std::string & strMessage) {
|
||||
if (!d->open) {
|
||||
return TELLSTICK_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
bool c = true;
|
||||
#ifdef LIBFTDI
|
||||
unsigned char *tempMessage = new unsigned char[strMessage.size()];
|
||||
memcpy(tempMessage, strMessage.c_str(), strMessage.size());
|
||||
|
||||
int ret;
|
||||
ret = ftdi_write_data( &d->ftHandle, tempMessage, strMessage.length() ) ;
|
||||
if(ret < 0) {
|
||||
c = false;
|
||||
} else if(ret != strMessage.length()) {
|
||||
fprintf(stderr, "wierd send length? retval %i instead of %d\n",
|
||||
ret, (int)strMessage.length());
|
||||
}
|
||||
|
||||
delete[] tempMessage;
|
||||
|
||||
int retrycnt = 500;
|
||||
unsigned char in;
|
||||
while(c && --retrycnt) {
|
||||
ret = ftdi_read_data( &d->ftHandle, &in, 1);
|
||||
if (ret > 0) {
|
||||
if (in == '\n') {
|
||||
break;
|
||||
}
|
||||
} else if(ret == 0) { // No data available
|
||||
usleep(100);
|
||||
} else { //Error
|
||||
c = false;
|
||||
}
|
||||
}
|
||||
if (!retrycnt) {
|
||||
c = false;
|
||||
}
|
||||
#else
|
||||
char *tempMessage = (char *)malloc(sizeof(char) * (strMessage.size()+1));
|
||||
#ifdef _WINDOWS
|
||||
strcpy_s(tempMessage, strMessage.size()+1, strMessage.c_str());
|
||||
#else
|
||||
strcpy(tempMessage, strMessage.c_str());
|
||||
#endif
|
||||
ULONG bytesWritten, bytesRead;
|
||||
char in;
|
||||
FT_STATUS ftStatus;
|
||||
ftStatus = FT_Write(d->ftHandle, tempMessage, (DWORD)strMessage.length(), &bytesWritten);
|
||||
free(tempMessage);
|
||||
|
||||
while(c) {
|
||||
ftStatus = FT_Read(d->ftHandle,&in,1,&bytesRead);
|
||||
if (ftStatus == FT_OK) {
|
||||
if (bytesRead == 1) {
|
||||
if (in == '\n') {
|
||||
break;
|
||||
}
|
||||
} else { //Timeout
|
||||
c = false;
|
||||
}
|
||||
} else { //Error
|
||||
c = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!c) {
|
||||
return TELLSTICK_ERROR_COMMUNICATION;
|
||||
}
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
void TellStick::setBaud(int baud) {
|
||||
#ifdef LIBFTDI
|
||||
int ret = ftdi_set_baudrate(&d->ftHandle, baud);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "set Baud failed, retval %i\n", ret);
|
||||
}
|
||||
#else
|
||||
FT_SetBaudRate(d->ftHandle, baud);
|
||||
#endif
|
||||
}
|
||||
|
||||
TellStickHandle TellStick::handle() const {
|
||||
return d->ftHandle;
|
||||
}
|
||||
|
||||
bool TellStick::stillConnected() const {
|
||||
std::string serial = this->serial();
|
||||
|
||||
#ifdef LIBFTDI
|
||||
ftdi_context ftdic;
|
||||
struct ftdi_device_list *devlist, *curdev;
|
||||
char serialBuffer[10];
|
||||
ftdi_init(&ftdic);
|
||||
bool found = false;
|
||||
|
||||
int ret = ftdi_usb_find_all(&ftdic, &devlist, this->vid(), this->pid());
|
||||
if (ret > 0) {
|
||||
for (curdev = devlist; curdev != NULL; curdev = curdev->next) {
|
||||
ret = ftdi_usb_get_strings(&ftdic, curdev->dev, NULL, 0, NULL, 0, serialBuffer, 10);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
if (serial.compare(serialBuffer) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ftdi_list_free(&devlist);
|
||||
ftdi_deinit(&ftdic);
|
||||
return found;
|
||||
#else
|
||||
FT_STATUS ftStatus;
|
||||
DWORD numDevs;
|
||||
// create the device information list
|
||||
ftStatus = FT_CreateDeviceInfoList(&numDevs);
|
||||
if (ftStatus != FT_OK) {
|
||||
return false;
|
||||
}
|
||||
if (numDevs <= 0) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < (int)numDevs; i++) {
|
||||
FT_HANDLE ftHandleTemp;
|
||||
DWORD flags;
|
||||
DWORD id;
|
||||
DWORD type;
|
||||
DWORD locId;
|
||||
char serialNumber[16];
|
||||
char description[64];
|
||||
// get information for device 0
|
||||
ftStatus = FT_GetDeviceInfoDetail(i, &flags, &type, &id, &locId, serialNumber, description, &ftHandleTemp);
|
||||
if (ftStatus != FT_OK) {
|
||||
continue;
|
||||
}
|
||||
if (serial.compare(serialNumber) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
|
@ -13,39 +13,31 @@
|
|||
#define TELLSTICK_H
|
||||
|
||||
#include "Controller.h"
|
||||
#include <list>
|
||||
|
||||
#include "ftd2xx.h"
|
||||
#ifdef LIBFTDI
|
||||
typedef ftdi_context TellStickHandle;
|
||||
#else
|
||||
typedef FT_HANDLE TellStickHandle;
|
||||
#endif
|
||||
class TellStickDescriptor {
|
||||
public:
|
||||
std::string serial;
|
||||
int vid, pid;
|
||||
};
|
||||
|
||||
class TellStick : public Controller {
|
||||
public:
|
||||
TellStick(const TellStickDescriptor &d);
|
||||
virtual ~TellStick();
|
||||
|
||||
virtual int firmwareVersion();
|
||||
bool isOpen() const;
|
||||
virtual int send( const std::string &message );
|
||||
|
||||
int vid() const;
|
||||
int pid() const;
|
||||
std::string serial() const;
|
||||
bool open() const;
|
||||
bool stillConnected() const;
|
||||
|
||||
static TellStick *findFirstDevice(int vid = 0, int pid = 0);
|
||||
static TellStick *loadBy(int vid, int pid, const std::string &serial);
|
||||
static std::list<TellStickDescriptor> findAll();
|
||||
|
||||
protected:
|
||||
class TellStickDescriptor;
|
||||
|
||||
TellStick(const TellStickDescriptor &d);
|
||||
void setBaud( int baud );
|
||||
TellStickHandle handle() const;
|
||||
|
||||
|
||||
private:
|
||||
static TellStickDescriptor findByVIDPID( int vid, int pid );
|
||||
static std::list<TellStickDescriptor> findAllByVIDPID( int vid, int pid );
|
||||
|
||||
class PrivateData;
|
||||
PrivateData *d;
|
||||
|
|
104
telldus-core/service/TellStick_libftdi.cpp
Normal file
104
telldus-core/service/TellStick_libftdi.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
//
|
||||
// C++ Implementation: TellStick
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
//
|
||||
// Author: Micke Prag <micke.prag@telldus.se>, (C) 2009
|
||||
//
|
||||
// Copyright: See COPYING file that comes with this distribution
|
||||
//
|
||||
//
|
||||
#include "TellStick.h"
|
||||
#include "../client/telldus-core.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ftdi.h>
|
||||
|
||||
class TellStick::PrivateData {
|
||||
public:
|
||||
bool open;
|
||||
ftdi_context ftHandle;
|
||||
};
|
||||
|
||||
TellStick::TellStick( const TellStickDescriptor &td ) {
|
||||
d = new PrivateData;
|
||||
d->open = false;
|
||||
|
||||
ftdi_init(&d->ftHandle);
|
||||
|
||||
int ret = ftdi_usb_open_desc(&d->ftHandle, td.vid, td.pid, NULL, td.serial.c_str());
|
||||
if (ret < 0) {
|
||||
ftdi_deinit(&d->ftHandle);
|
||||
return;
|
||||
}
|
||||
d->open = true;
|
||||
ftdi_usb_reset( &d->ftHandle );
|
||||
ftdi_disable_bitbang( &d->ftHandle );
|
||||
|
||||
if (d->open) {
|
||||
// setBaud(4800);
|
||||
}
|
||||
}
|
||||
|
||||
TellStick::~TellStick() {
|
||||
if (d->open) {
|
||||
ftdi_usb_close(&d->ftHandle);
|
||||
ftdi_deinit(&d->ftHandle);
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
int TellStick::firmwareVersion() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool TellStick::isOpen() const {
|
||||
return d->open;
|
||||
}
|
||||
|
||||
int TellStick::send( const std::string &message ) {
|
||||
return TELLSTICK_SUCCESS;
|
||||
}
|
||||
|
||||
std::list<TellStickDescriptor> TellStick::findAll() {
|
||||
std::list<TellStickDescriptor> tellstick = findAllByVIDPID(0x1781, 0x0C30);
|
||||
|
||||
std::list<TellStickDescriptor> duo = findAllByVIDPID(0x1781, 0x0C31);
|
||||
for(std::list<TellStickDescriptor>::const_iterator it = duo.begin(); it != duo.end(); ++it) {
|
||||
tellstick.push_back(*it);
|
||||
}
|
||||
|
||||
return tellstick;
|
||||
|
||||
}
|
||||
|
||||
std::list<TellStickDescriptor> TellStick::findAllByVIDPID( int vid, int pid ) {
|
||||
std::list<TellStickDescriptor> retval;
|
||||
|
||||
ftdi_context ftdic;
|
||||
struct ftdi_device_list *devlist, *curdev;
|
||||
char serialBuffer[10];
|
||||
ftdi_init(&ftdic);
|
||||
|
||||
int ret = ftdi_usb_find_all(&ftdic, &devlist, vid, pid);
|
||||
if (ret > 0) {
|
||||
for (curdev = devlist; curdev != NULL; curdev = curdev->next) {
|
||||
ret = ftdi_usb_get_strings(&ftdic, curdev->dev, NULL, 0, NULL, 0, serialBuffer, 10);
|
||||
if (ret != 0) {
|
||||
continue;
|
||||
}
|
||||
TellStickDescriptor td;
|
||||
td.vid = vid;
|
||||
td.pid = pid;
|
||||
td.serial = serialBuffer;
|
||||
retval.push_back(td);
|
||||
}
|
||||
}
|
||||
ftdi_list_free(&devlist);
|
||||
ftdi_deinit(&ftdic);
|
||||
|
||||
return retval;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue