Only in ZWave/: , Only in ZWave/: a.txt Only in ZWave/: a.txt~ Only in ZWave/: b.txt Only in ZWave/: core Only in ZWave/: log.txt Only in ZWave/: log.txt~ Only in ZWave/: Main.d Only in ZWave/: Main.o diff -ur /code/ZWave/Makefile ZWave/Makefile --- /code/ZWave/Makefile 2008-02-28 15:34:22.221387847 -0500 +++ ZWave/Makefile 2008-03-03 13:44:17.468127084 -0500 @@ -1,7 +1,7 @@ #<-dceag-mh-b-> GENDEV=../Gen_Devices -SNR_CPPFLAGS ?= <-mkr_t_compile_defines-> +SNR_CPPFLAGS ?= -DKDE_LMCE -DDEBUG -DTHREAD_LOG -DLOG_ALL_QUERIES -I/opt/libxine1-pluto/include -I/opt/linphone-1.3.5/include ROOT = .. CXXFLAGS = -Wall -fPIC -ggdb3 @@ -14,9 +14,7 @@ LDFLAGS += -lmysqlclient_r #<-mkr_B_use_mysql_wrapper_e-> -#<-mkr_b_use_mysql_wrapper_b-> -CPPFLAGS += -DUSE_MYSQL_WRAPPER -#<-mkr_b_use_mysql_wrapper_e-> +# MYNAME = ZWave VERSION = 2.0.0 @@ -59,7 +57,7 @@ cp $@ ../bin chmod +x post_make.sh ./post_make.sh $@ - + ZWave: $(sources:.cpp=.o) $(CXX) -o $(MYNAME) $(call cpath,$+) $(LDFLAGS) $(LDLIBS) cp $@ ../bin Only in /code/ZWave/: Makefile~ diff -ur /code/ZWave/make_package.sh ZWave/make_package.sh --- /code/ZWave/make_package.sh 2008-02-28 15:26:29.471873392 -0500 +++ ZWave/make_package.sh 2008-03-03 13:44:17.505125593 -0500 @@ -1,133 +1,133 @@ -#!/bin/bash - -#<-dceag-mp-b-> -#DCE_Package -#DCE_TargetDir - -if [ "$#" != 3 ]; then - echo "Syntax: $0 " - exit 1 -fi - -PACK_LOC=../Packages -ORIG_APPNAME="$1" -APPNAME=pluto-`echo "$ORIG_APPNAME" | tr 'A-Z_' 'a-z\-'` -APPVER="$2" -DEVTMPL_ID="$3" - -PACK_NAME="$APPNAME-$APPVER" -PACK_DIR="$PACK_LOC/$PACK_NAME" -DISTRO=1 # 1=Debian - -GetMySQLResult() -{ - local Q - - Q="$*" - echo "$Q;" | mysql pluto_main | tail +2 - return "$?" -} - -GetPackageDepends() -{ - local Package_Number Package_Name - local Q R - local Row - - Package_Number="$1" - - Q="SELECT PK_Package, Name -FROM Package_Package -JOIN Package ON Package.PK_Package = FK_Package_DependsOn -JOIN Package_Source ON Package_Source.FK_Package = PK_Package -JOIN RepositorySource ON FK_RepositorySource = PK_RepositorySource -JOIN Package_Source_Compat ON FK_Package_Source = PK_Package_Source -WHERE Package_Package.FK_Package='$Package_Number' AND FK_RepositoryType=1 AND Package_Source_Compat.FK_Distro='$DISTRO' AND OnlyToBuild=0" - - R=$(GetMySQLResult "$Q") # TODO: test result - - echo "$R" | - while read Row; do - [ -z "$Row" ] && break # weird thing: we have to force an exit, else it loops forever - Package_Number=$(echo "$Row" | cut -f1) - Package_Name=$(echo "$Row" | cut -sf2) - GetPackageDepends "$Package_Number" - echo -n "$Package_Name " - done -} - -# return the packages needed by the device plus their dependencies -GetDevicePackageList() -{ - local Package_Number Package_Name - local Q R - local Row - - Device_Number="$1" - - Q="SELECT Package_Source.FK_Package,Name -FROM DeviceTemplate -JOIN Package_Source ON Package_Source.FK_Package=DeviceTemplate.FK_Package -JOIN Package_Source_Compat ON FK_Package_Source=PK_Package_Source -WHERE PK_DeviceTemplate='$Device_Number' AND FK_Distro='$DISTRO'" - - R=$(GetMySQLResult "$Q") # TODO: test result - - echo "$R" | - while read Row; do - [ -z "$Row" ] && break # weird thing: we have to force an exit, else it loops forever - Package_Number=$(echo "$Row" | cut -f1) - Package_Name=$(echo "$Row" | cut -sf2) - GetPackageDepends "$Package_Number" - echo -n "$Package_Name " - done -} - -#GetDevicePackageList "$DEVTMPL_ID"; echo -PackageList=$(GetDevicePackageList "$DEVTMPL_ID") - -if [ ! -d "$PACK_LOC" ]; then - mkdir -p "$PACK_LOC" -fi - -if [ ! -d "$PACK_DIR" ]; then - cp -a "$PACK_LOC/_Package_template" "$PACK_DIR" -fi - -BIN_LOC="../../bin" -LIB_LOC="../../lib" -BIN_FILE="$BIN_LOC/$ORIG_APPNAME" -PLUGIN_FILE="$BIN_LOC/$ORIG_APPNAME.so" -LIB_FILE="$LIB_LOC/lib$ORIG_APPNAME.a" - -pushd "$PACK_DIR" - -mkdir -p root/usr/pluto/bin -mkdir -p root/usr/pluto/lib - -echo "-- $BIN_FILE" -if [ -f "$BIN_FILE" ]; then - echo "Found bin file" - cp "$BIN_FILE" root/usr/pluto/bin -fi - -echo "-- $PLUGIN_FILE" -if [ -f "$PLUGIN_FILE" ]; then - echo "Found plugin file" - cp "$PLUGIN_FILE" root/usr/pluto/bin -fi - -echo "-- $LIB_FILE" -if [ -f "$LIB_FILE" ]; then - echo "Found lib file" - cp "$LIB_FILE" root/usr/pluto/lib -fi - -popd - -pushd "$PACK_LOC" -./propagate.pl "$PACK_NAME" $PackageList -popd - -#<-dceag-mp-e-> - +#!/bin/bash + +#<-dceag-mp-b-> +#DCE_Package +#DCE_TargetDir + +if [ "$#" != 3 ]; then + echo "Syntax: $0 " + exit 1 +fi + +PACK_LOC=../Packages +ORIG_APPNAME="$1" +APPNAME=pluto-`echo "$ORIG_APPNAME" | tr 'A-Z_' 'a-z\-'` +APPVER="$2" +DEVTMPL_ID="$3" + +PACK_NAME="$APPNAME-$APPVER" +PACK_DIR="$PACK_LOC/$PACK_NAME" +DISTRO=1 # 1=Debian + +GetMySQLResult() +{ + local Q + + Q="$*" + echo "$Q;" | mysql pluto_main | tail +2 + return "$?" +} + +GetPackageDepends() +{ + local Package_Number Package_Name + local Q R + local Row + + Package_Number="$1" + + Q="SELECT PK_Package, Name +FROM Package_Package +JOIN Package ON Package.PK_Package = FK_Package_DependsOn +JOIN Package_Source ON Package_Source.FK_Package = PK_Package +JOIN RepositorySource ON FK_RepositorySource = PK_RepositorySource +JOIN Package_Source_Compat ON FK_Package_Source = PK_Package_Source +WHERE Package_Package.FK_Package='$Package_Number' AND FK_RepositoryType=1 AND Package_Source_Compat.FK_Distro='$DISTRO' AND OnlyToBuild=0" + + R=$(GetMySQLResult "$Q") # TODO: test result + + echo "$R" | + while read Row; do + [ -z "$Row" ] && break # weird thing: we have to force an exit, else it loops forever + Package_Number=$(echo "$Row" | cut -f1) + Package_Name=$(echo "$Row" | cut -sf2) + GetPackageDepends "$Package_Number" + echo -n "$Package_Name " + done +} + +# return the packages needed by the device plus their dependencies +GetDevicePackageList() +{ + local Package_Number Package_Name + local Q R + local Row + + Device_Number="$1" + + Q="SELECT Package_Source.FK_Package,Name +FROM DeviceTemplate +JOIN Package_Source ON Package_Source.FK_Package=DeviceTemplate.FK_Package +JOIN Package_Source_Compat ON FK_Package_Source=PK_Package_Source +WHERE PK_DeviceTemplate='$Device_Number' AND FK_Distro='$DISTRO'" + + R=$(GetMySQLResult "$Q") # TODO: test result + + echo "$R" | + while read Row; do + [ -z "$Row" ] && break # weird thing: we have to force an exit, else it loops forever + Package_Number=$(echo "$Row" | cut -f1) + Package_Name=$(echo "$Row" | cut -sf2) + GetPackageDepends "$Package_Number" + echo -n "$Package_Name " + done +} + +#GetDevicePackageList "$DEVTMPL_ID"; echo +PackageList=$(GetDevicePackageList "$DEVTMPL_ID") + +if [ ! -d "$PACK_LOC" ]; then + mkdir -p "$PACK_LOC" +fi + +if [ ! -d "$PACK_DIR" ]; then + cp -a "$PACK_LOC/_Package_template" "$PACK_DIR" +fi + +BIN_LOC="../../bin" +LIB_LOC="../../lib" +BIN_FILE="$BIN_LOC/$ORIG_APPNAME" +PLUGIN_FILE="$BIN_LOC/$ORIG_APPNAME.so" +LIB_FILE="$LIB_LOC/lib$ORIG_APPNAME.a" + +pushd "$PACK_DIR" + +mkdir -p root/usr/pluto/bin +mkdir -p root/usr/pluto/lib + +echo "-- $BIN_FILE" +if [ -f "$BIN_FILE" ]; then + echo "Found bin file" + cp "$BIN_FILE" root/usr/pluto/bin +fi + +echo "-- $PLUGIN_FILE" +if [ -f "$PLUGIN_FILE" ]; then + echo "Found plugin file" + cp "$PLUGIN_FILE" root/usr/pluto/bin +fi + +echo "-- $LIB_FILE" +if [ -f "$LIB_FILE" ]; then + echo "Found lib file" + cp "$LIB_FILE" root/usr/pluto/lib +fi + +popd + +pushd "$PACK_LOC" +./propagate.pl "$PACK_NAME" $PackageList +popd + +#<-dceag-mp-e-> + Only in ZWave/: make_package.sh.prep diff -ur /code/ZWave/PlutoZWSerialAPI.cpp ZWave/PlutoZWSerialAPI.cpp --- /code/ZWave/PlutoZWSerialAPI.cpp 2008-02-28 15:26:29.862859264 -0500 +++ ZWave/PlutoZWSerialAPI.cpp 2008-03-03 12:24:22.499785181 -0500 @@ -692,7 +692,7 @@ } // check the timeout, idle and closed jobs - if( d->connection->ack ) + if( d->connection->isAcknowledged() ) { iTry = 0; PLUTO_SAFETY_LOCK(am, d->asynchMutex); @@ -827,7 +827,7 @@ if( iTry > 3 ) { // let's set it since we didn't get any ack in the last time - d->connection->ack = true; + d->connection->setAcknowledged(true); } } #ifdef _WIN32 Only in ZWave/: PlutoZWSerialAPI.cpp~ Only in ZWave/: PlutoZWSerialAPI.d Only in ZWave/: PlutoZWSerialAPI.o diff -ur /code/ZWave/SerialConnection.cpp ZWave/SerialConnection.cpp --- /code/ZWave/SerialConnection.cpp 2008-02-28 15:26:29.718864402 -0500 +++ ZWave/SerialConnection.cpp 2008-03-03 15:13:54.811885641 -0500 @@ -12,13 +12,130 @@ // leave it bigger than 200 ms #define SC_READ_TIMEOUT 100 +std::string toString(const char *data, int len) +{ + std::string out_buf; + + char buf[5]; + for (unsigned int i = 0; (int)i < len; i++) + { + sprintf(buf, "0x%02x ", (unsigned char) data[i]); + for (uint j = 0; j < 5; j++) + out_buf.push_back(buf[j]); + } + + return out_buf; +} + +int zwave_check(const char *buf, int len) +{ + int i; + char ret = (char) 0xff; + + for (i = 0; buf && (i < len); i++) + ret ^= buf[i]; + + return ret & 0xff; +} + +ZWaveResponse::ZWaveResponse(std::deque::const_iterator begin, + std::deque::const_iterator end) +{ + std::deque::const_iterator it = begin; + for (; it != end; it++) + data.push_back(*it); +} + +ZWaveResponse::ZWaveResponse(std::vector thedata) : data(thedata) +{ +} + +void ZWaveResponse::print(const char *prefice) const +{ + std::string out_buf_str = toString(&data[0], data.size()); + cout << prefice << ": " << out_buf_str << endl; + if (hasStart()) + { + cout << " data.size(): " << data.size(); + cout << " getLength(): " << getLength(); + cout << " getCHK(): " << getCHK(); + cout << " calcCHK(): " << calcCHK(); + cout << " isComplete(): " << isComplete(); + cout << " isValid(): " << isValid(); + cout << endl<= 2) + return (unsigned int) data[1] & 0xff; + return -99; +} + +int ZWaveResponse::getCHK(void) const +{ + if (isComplete()) + return (unsigned int) data.back() & 0xff; + return -1; +} + +int ZWaveResponse::calcCHK(void) const +{ + if (isComplete()) + return zwave_check(&data[1], data.size() - 2); + return -99; +} + +bool ZWaveResponse::set(char *out, size_t &len) const +{ + if (!isValid()) + { + cout<<"ZWaveResponse::set -- not valid"< SerialConnection::responses; SerialConnection::SerialConnection() : serialPort(NULL) @@ -50,14 +167,14 @@ { try { - serialPort = new CSerialPort(port, 115200, epbsN81); + serialPort = new CSerialPort(port, 115200/*9600*//*38400*/, epbsN81); #ifdef PLUTO_DEBUG LoggerWrapper::GetInstance()->Write(LV_ZWAVE, "SerialConnection::connect init serial mutex"); #endif - pthread_mutex_init(&mutex_serial, NULL); - pthread_mutex_init(&mutex_buffer, NULL); + pthread_mutex_init(&mutex/*serial*/, NULL); + //pthread_mutex_init(&mutex/*buffer*/, NULL); int stat = pthread_create(&write_thread, NULL, receiveFunction, (void*)this); if( stat != 0) { @@ -111,10 +228,10 @@ #ifdef PLUTO_DEBUG LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection ------------- asa 1"); #endif - pthread_mutex_lock( &instance->mutex_serial ); + pthread_mutex_lock( &instance->mutex/*serial*/ ); delete serialPort; serialPort = NULL; - pthread_mutex_unlock( &instance->mutex_serial ); + pthread_mutex_unlock( &instance->mutex/*serial*/ ); #ifdef PLUTO_DEBUG LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection ------------- asa 2"); LoggerWrapper::GetInstance()->Flush(); @@ -131,8 +248,8 @@ LoggerWrapper::GetInstance()->Flush(); #endif - pthread_mutex_destroy(&mutex_serial); - pthread_mutex_destroy(&mutex_buffer); + pthread_mutex_destroy(&mutex/*serial*/); + //pthread_mutex_destroy(&mutex/*buffer*/); buffer.clear(); @@ -154,8 +271,7 @@ return serialPort != NULL; } -// TODO: use 'const char * buffer' -int SerialConnection::send(char *b, size_t len) +int SerialConnection::send_real(const char *b, size_t len, bool take_mutex) { if( !isConnected() ) { @@ -170,7 +286,7 @@ #ifdef PLUTO_DEBUG LoggerWrapper::GetInstance()->Write(LV_ZWAVE, "SerialConnection::send lock serial mutex"); #endif - pthread_mutex_lock( &mutex_serial ); + pthread_mutex_lock( &mutex/*serial*/ ); #ifdef PLUTO_DEBUG printDataBuffer(b, len, "SerialConnection::send"); @@ -191,9 +307,13 @@ serialPort->Write(paddedBuffer, len); serialPort->Flush(); - // this flag is set false, then we have to wait for this flag to be true to send another command + // the ack flag is set false, + // then we have to wait for this flag to + // be true to send another command // important flag - ack = false; + memcpy(last_command_data, b, len - 3); + last_command_data_len = len - 3; + last_command_ack = false; } catch(...) { @@ -202,7 +322,7 @@ } } else returnValue = -1; - pthread_mutex_unlock( &mutex_serial ); + pthread_mutex_unlock( &mutex/*serial*/ ); #ifdef PLUTO_DEBUG LoggerWrapper::GetInstance()->Write(LV_ZWAVE, "SerialConnection::send unlock serial mutex"); #endif @@ -215,73 +335,173 @@ int SerialConnection::receiveCommand(char *b, size_t *len) { #ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::begin"); + LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::begin"); #endif - if(b == NULL || !isConnected()) - { - *len = 0; - return -1; - } - - pthread_mutex_lock( &instance->mutex_buffer ); - if( !buffer.empty() ) - { + if (!b || !isConnected()) + { + *len = 0; #ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "buffer.size()= %d", buffer.size()); + LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::end nok 1"); #endif - //for(std::deque::iterator it = buffer.begin(); it != buffer.end(); ++it) - //{ - // LoggerWrapper::GetInstance()->Write(LV_WARNING, "HMM: 0x%02x ", (int)(*it)); - //} - - if( buffer.front() == SERIAL_ACK ) - buffer.pop_front(); - if( buffer.front() != SERIAL_SOF ) - { - pthread_mutex_unlock( &instance->mutex_buffer ); - *len = 0; - return -1; - } - unsigned int buffered_len = *(buffer.begin() + 1); - if(buffer.size() < buffered_len + 2 || *len < buffered_len + 2) - { - pthread_mutex_unlock( &instance->mutex_buffer ); - *len = 0; - return -1; - } - - // SOF - buffer.pop_front(); - // LEN - buffer.pop_front(); - - unsigned int i = 0; - *len = buffered_len - 1; - while(i < *len) - { -#ifdef PLUTO_DEBUG - if( i == 0 ) - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand: eat another command"); -#endif - b[i++] = buffer.front(); - buffer.pop_front(); - } - - // CHECKSUM - buffer.pop_front(); - -#ifdef PLUTO_DEBUG - printDataBuffer(b, *len, "SerialConnection : received command"); -#endif - } - else - { - *len = 0; - } + return -1; + } - pthread_mutex_unlock( &instance->mutex_buffer ); - return 0; + pthread_mutex_lock( &instance->mutex/*buffer*/ ); + if (responses.empty()) + { + pthread_mutex_unlock( &instance->mutex/*buffer*/ ); + *len = 0; +#ifdef PLUTO_DEBUG + LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::end nok 2"); +#endif + return -1; + } + + if (!responses.front().set(b, *len)) + { + responses.pop_front(); + pthread_mutex_unlock( &instance->mutex/*buffer*/ ); + *len = 0; +#ifdef PLUTO_DEBUG + LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::end nok 3"); +#endif + return -1; + } + + responses.pop_front(); + pthread_mutex_unlock( &instance->mutex/*buffer*/ ); + +#ifdef PLUTO_DEBUG + LoggerWrapper::GetInstance()->Write(LV_DEBUG, "receiveCommand::end ok"); +#endif + + return 0; +} + +std::vector getResponses(std::deque &buffer) +{ + cout< starts; + std::vector len; + std::vector valid; + for (size_t i = 0; i < buffer.size(); i++) + { + if (SERIAL_SOF == buffer[i]) + { + starts.push_back(i); + if (i + 1 < buffer.size()) + { + len.push_back((unsigned int)(buffer[i+1]&0xff)); + if (i + len.back() + 2 > buffer.size()) + { + cout<<"SOF @"< data; + for (int j = i; j < (int)i + len.back() + 2; j++) + data.push_back(buffer[j]); + ZWaveResponse tmp(data); + valid.push_back(tmp.isValid()); + + cout<<"SOF @"< responses; + vector data; + size_t last_data = 0; + for (unsigned int i = 0; i < starts.size(); i++) + { + if (!valid[i]) + continue; + + cout<<"Found valid @"<Write(LV_ZWAVE, "SerialConnection::hasCommand() is not connected"); - return -1; - } - - int returnValue = 0; - pthread_mutex_lock( &instance->mutex_buffer ); - while( 0 < buffer.size() && buffer.front() == SERIAL_ACK ) - { -#ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection::hasCommand() popping ACK"); -#endif - // we got a new ACK, we can send another command - // it's an important flag - ack = true; - - buffer.pop_front(); - } - - size_t bufferSize = buffer.size(); - if(bufferSize < 3) - { -#ifdef PLUTO_DEBUG - if( 0 < bufferSize ) - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "size too small %d", buffer.size()); -#endif - pthread_mutex_unlock( &instance->mutex_buffer ); - return 0; - } - - if( buffer.front() == SERIAL_SOF ) - { -#ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection::hasCommand() front is SOF"); -#endif - std::deque::iterator i = buffer.begin(); - unsigned int len = *(++i) ; - if(bufferSize >= len + 2) //SOF+LEN+CHECK - { - i += len; - char checkSum = *i; - char tmpSum = (char)0xff; - // checksum( Length_Byte + Command_Array_Bytes ) - std::deque::iterator endPack = buffer.begin() + len + 1; - for(i = buffer.begin() + 1; i != endPack; i++) - tmpSum ^= *i; - if(tmpSum == checkSum) - { - returnValue = 1; - char ack = SERIAL_ACK; -#ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection::hasCommand lock serial mutex"); -#endif - pthread_mutex_lock( &mutex_serial ); + if( !isConnected() ) + { + LoggerWrapper::GetInstance()->Write( + LV_ZWAVE, "SerialConnection::hasCommand() is not connected"); + return -1; + } + + pthread_mutex_lock( &instance->mutex/*buffer&serial*/ ); + bool has_data = buffer.size(); + if (!has_data) + { + pthread_mutex_unlock( &instance->mutex/*buffer&serial*/ ); + return -1; + } + + if (buffer.size() == last_buffer_size) + { + pthread_mutex_unlock( &instance->mutex/*buffer&serial*/ ); + return -1; + } + + // debugging + if (buffer.size()) + { + cout<<"SerialConnection::hasCommand():"; + for (unsigned int i = 0; i < buffer.size(); i++) + { + if (buffer[i] == SERIAL_ACK) + cout<<" ACK"; + else if (buffer[i] == SERIAL_SOF && (i>0) && + buffer[i-1] == SERIAL_ACK) + cout<<" SOF"; + else + cout< resp = getResponses(buffer); + + for (unsigned int i = 0; i < resp.size(); i++) + { + if (!resp[i].isComplete()) + { + resp[i].print("Incomplete Response"); + continue; + } + + if (!resp[i].isValid()) + { + resp[i].print("Invalid Response"); + continue; + } + + if (resp[i].isACK()) + { + std::string tmp = + toString(last_command_data, last_command_data_len); + char log_buf[1024*10]; + sprintf(log_buf, "Got ACK for %s", tmp.c_str()); + resp[i].print(log_buf); + // we got a new ACK, we can send another command + // it's an important flag + last_command_ack = true; + continue; + } + + if (resp[i].isNAK()) + { + std::string tmp = + toString(last_command_data, last_command_data_len); + char log_buf[1024*10]; + sprintf(log_buf, "Got NAK for %s", tmp.c_str()); + resp[i].print(log_buf); + + // resend last command + send_real(last_command_data, last_command_data_len, false); + + continue; + } + + // queue up response for receiveCommand + responses.push_back(resp[i]); + + // acknowledge response + if (serialPort) + { + char ack = SERIAL_ACK; + serialPort->Write(&ack, 1); + serialPort->Flush(); + } + } - if( serialPort != NULL ) - { - serialPort->Write(&ack, 1); -#ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection::hasCommand wrote ack"); -#endif - } - pthread_mutex_unlock( &mutex_serial ); -#ifdef PLUTO_DEBUG - LoggerWrapper::GetInstance()->Write(LV_DEBUG, "SerialConnection::hasCommand unlock serial mutex"); -#endif - } - } - else - { - } - } - else - returnValue = -1; - pthread_mutex_unlock( &instance->mutex_buffer ); - return returnValue; + int ret = responses.size() ? 1 : -1; + + last_buffer_size = !responses.size() ? buffer.size() : 0; + + pthread_mutex_unlock( &instance->mutex/*buffer&serial*/ ); + + return ret; } @@ -401,7 +644,7 @@ while( true ) { len = sizeof(mybuf) + 1; - pthread_mutex_lock( &instance->mutex_serial ); + pthread_mutex_lock( &instance->mutex/*serial*/ ); if( instance != NULL && instance->isConnected() ) { uRead++; @@ -412,7 +655,7 @@ // THREAD MUST STOP bDisconnect = true; } - pthread_mutex_unlock( &instance->mutex_serial ); + pthread_mutex_unlock( &instance->mutex/*serial*/ ); // THREAD MUST STOP if( bDisconnect ) @@ -422,13 +665,13 @@ if(len <= sizeof(mybuf) && len != 0 && instance != NULL) { - pthread_mutex_lock( &instance->mutex_buffer ); + pthread_mutex_lock( &instance->mutex/*buffer*/ ); for(size_t i=0; ibuffer.push_back(mybuf[i]); } //SerialConnection::printDataBuffer(mybuf, len, "Thread Read"); - pthread_mutex_unlock( &instance->mutex_buffer ); + pthread_mutex_unlock( &instance->mutex/*buffer*/ ); } #ifdef _WIN32 @@ -475,7 +718,7 @@ void SerialConnection::clearSerialBuffer() { - pthread_mutex_lock( &instance->mutex_buffer ); + pthread_mutex_lock( &instance->mutex/*buffer*/ ); buffer.clear(); - pthread_mutex_unlock( &instance->mutex_buffer ); + pthread_mutex_unlock( &instance->mutex/*buffer*/ ); } Only in ZWave/: SerialConnection.cpp~ Only in ZWave/: SerialConnection.d diff -ur /code/ZWave/SerialConnection.h ZWave/SerialConnection.h --- /code/ZWave/SerialConnection.h 2008-02-28 15:26:29.494872609 -0500 +++ ZWave/SerialConnection.h 2008-03-03 15:13:32.240918140 -0500 @@ -17,8 +17,34 @@ #include #define SERIAL_ACK 0x06 +#define SERIAL_NAK 0x18 #define SERIAL_SOF 0x01 +class ZWaveResponse +{ + public: + ZWaveResponse(std::deque::const_iterator begin, + std::deque::const_iterator end); + ZWaveResponse(std::vector thedata); + + void print(const char *prefice) const; + bool empty(void) const { return data.empty(); } + bool isACK(void) const { return data.size() && (SERIAL_ACK == data[0]); } + bool isNAK(void) const { return data.size() && (SERIAL_NAK == data[0]); } + bool hasStart(void) const { return data.size() && (SERIAL_SOF == data[0]); } + bool isValid(void) const; + bool isComplete(void) const; + + int getLength(void) const; + int getCHK(void) const; + int calcCHK(void) const; + + bool set(char *out, size_t &len) const; + + private: + std::vector data; +}; + /** * Singleton class that takes care of the serial connection interface. *Send is single thread, receive is multi thread. @@ -37,7 +63,11 @@ *@param buffer the buffer to be sent *@param len the length of the buffer *@return 0 if OK, else negative */ - virtual int send(char *buffer, size_t len); + virtual int send(char *buffer, size_t len) + { return send_real(buffer, len, true); } + virtual int send(const char *buffer, size_t len) + { return send_real(buffer, len, true); } + virtual int send_real(const char *buffer, size_t len, bool take_mutex); /**try to get the specified len from the serial buffer * @parameter buffer the buffer where the data should be found @@ -75,12 +105,22 @@ static void printDataBuffer(const char *buffer, const size_t length, const char *classID); - static pthread_mutex_t mutex_serial; - static pthread_mutex_t mutex_buffer; + static pthread_mutex_t mutex; + //static pthread_mutex_t mutex_serial; + //static pthread_mutex_t mutex_buffer; static pthread_t write_thread; - static bool ack; - + // these are protected by mutex_serial + static char last_command_data[512]; + static int last_command_data_len; + static bool last_command_ack; + static size_t last_buffer_size; + static std::deque responses; + + bool isAcknowledged(const char *command = NULL) { return last_command_ack; } + bool setAcknowledged(bool val = true, const char *command = NULL) + { return last_command_ack = val; } + private: /**static instance of this class*/ static SerialConnection* instance; Only in ZWave/: SerialConnection.h~ Only in ZWave/: SerialConnection.o Only in /code/ZWave/: .svn Only in ZWave/: tester Only in ZWave/: tester.c Only in ZWave/: tester.c~ Only in ZWave/: x Only in ZWave/: ZWave Only in ZWave/: ZWave.d Only in ZWave/: ZWaveJob.d Only in ZWave/: ZWaveJob.o Only in ZWave/: ZWaveNode.d Only in ZWave/: ZWaveNode.o Only in ZWave/: ZWave.o Only in ZWave/: ZWave.so Only in ZWave/: ZWJobAddNode.d Only in ZWave/: ZWJobAddNode.o Only in ZWave/: ZWJobAssignReturnRoute.d Only in ZWave/: ZWJobAssignReturnRoute.o Only in ZWave/: ZWJobAssociationSet.d Only in ZWave/: ZWJobAssociationSet.o Only in ZWave/: ZWJobConfig.d Only in ZWave/: ZWJobConfig.o Only in ZWave/: ZWJobDeleteRoute.d Only in ZWave/: ZWJobDeleteRoute.o Only in ZWave/: ZWJobGetID.d Only in ZWave/: ZWJobGetID.o Only in ZWave/: ZWJobGetInitData.d Only in ZWave/: ZWJobGetInitData.o Only in ZWave/: ZWJobGetNodeProtocolInfo.d Only in ZWave/: ZWJobGetNodeProtocolInfo.o Only in ZWave/: ZWJobGetSUC.d Only in ZWave/: ZWJobGetSUC.o Only in ZWave/: ZWJobGetVersion.d Only in ZWave/: ZWJobGetVersion.o Only in ZWave/: ZWJobInitialize.d Only in ZWave/: ZWJobInitialize.o Only in ZWave/: ZWJobLightLevel.d Only in ZWave/: ZWJobLightLevel.o Only in ZWave/: ZWJobPool.d Only in ZWave/: ZWJobPool.o Only in ZWave/: ZWJobReceive.d Only in ZWave/: ZWJobReceive.o Only in ZWave/: ZWJobRemoveNode.d Only in ZWave/: ZWJobRemoveNode.o Only in ZWave/: ZWJobReset.d Only in ZWave/: ZWJobReset.o Only in ZWave/: ZWJobSendData.d Only in ZWave/: ZWJobSendData.o Only in ZWave/: ZWJobSetLearnMode.d Only in ZWave/: ZWJobSetLearnMode.o Only in ZWave/: ZWJobSetLearnNodeState.d Only in ZWave/: ZWJobSetLearnNodeState.o Only in ZWave/: ZWJobSwitchBinaryGet.d Only in ZWave/: ZWJobSwitchBinaryGet.o Only in ZWave/: ZWJobSwitchChangeLevel.d Only in ZWave/: ZWJobSwitchChangeLevel.d.9839 Only in ZWave/: ZWJobSwitchChangeLevel.o Only in ZWave/: ZWJobWakeUp.d Only in ZWave/: ZWJobWakeUp.o