All pastes #935581 Raw Edit

Mine

public text v1 · immutable
·published 2008-03-09 19:17 UTC
rendered paste body
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 <application name> <version> <device template id>"
-	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 <application name> <version> <device template id>"
+	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<char>::const_iterator begin,
+                             std::deque<char>::const_iterator end)
+{
+    std::deque<char>::const_iterator it = begin;
+    for (; it != end; it++)
+        data.push_back(*it);
+}
+
+ZWaveResponse::ZWaveResponse(std::vector<char> 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<<flush;
+    }
+}
+
+bool ZWaveResponse::isValid(void) const
+{
+    return isACK() || isNAK() || (hasStart() && (getCHK() == calcCHK()));
+}
+
+bool ZWaveResponse::isComplete(void) const
+{
+    return isACK() || isNAK() || ((size_t) (getLength() + 2)) == data.size();
+}
+
+int ZWaveResponse::getLength(void) const
+{
+    if (data.size() >= 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"<<endl;
+        return false;
+    }
+
+    if (len + 2 < data.size())
+    {
+        cout<<"ZWaveResponse::set -- external buffer too small"<<endl;
+        return false;
+    }
+
+    if (data.size() <= 3)
+    {
+        cout<<"ZWaveResponse::set -- internal buffer too small"<<endl;
+        return false;
+    }
+
+    len = data.size() - 3;
+    memcpy(out, &data[2], len);
+
+    return true;
+}
+
+
 SerialConnection* SerialConnection::instance = NULL;
 
-pthread_mutex_t SerialConnection::mutex_serial;
-pthread_mutex_t SerialConnection::mutex_buffer;
+pthread_mutex_t SerialConnection::mutex;
+//pthread_mutex_t SerialConnection::mutex_serial;
+//pthread_mutex_t SerialConnection::mutex_buffer;
 pthread_t SerialConnection::write_thread;
 
-bool SerialConnection::ack = true;
+char   SerialConnection::last_command_data[512];
+int    SerialConnection::last_command_data_len = 0;
+bool   SerialConnection::last_command_ack      = true;
+size_t SerialConnection::last_buffer_size      = 0;
+std::deque<ZWaveResponse> 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<char>::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<ZWaveResponse> getResponses(std::deque<char> &buffer)
+{
+    cout<<endl<<endl<<"getResponses() -- begin"<<endl;
+
+    std::vector<int>  starts;
+    std::vector<int>  len;
+    std::vector<bool> 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 @"<<i<<" len("<<len.back()
+                        <<") too long.."<<endl;
+                    valid.push_back(false);
+                }
+                else
+                {
+                    vector<char> 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 @"<<i<<endl;
+                    tmp.print("");
+                }
+            }
+            else
+            {
+                cout<<"SOF @"<<i<<" too short for len"<<endl;
+                len.push_back(-1);
+                valid.push_back(false);
+            }
+        }
+        else if (SERIAL_ACK == buffer[i])
+        {
+            cout<<"ACK @"<<i<<endl;
+            starts.push_back(i);
+            len.push_back(0);
+            valid.push_back(true);
+        }
+        else if (SERIAL_NAK == buffer[i])
+        {
+            cout<<"NAK @"<<i<<endl;
+            starts.push_back(i);
+            len.push_back(0);
+            valid.push_back(true);
+        }
+    }
+
+    std::vector<ZWaveResponse> responses;
+    vector<char> data;
+    size_t last_data = 0;
+    for (unsigned int i = 0; i < starts.size(); i++)
+    {
+        if (!valid[i])
+            continue;
+
+        cout<<"Found valid @"<<starts[i]<<endl;
+
+        // start contains a complete valid response..
+        data.clear();
+        
+        // add any previous cruft as an [invalid] response
+        for (int j = last_data; j < starts[i]; j++)
+            data.push_back(buffer[j]);
+        if (data.size())
+        {
+            responses.push_back(ZWaveResponse(data));
+            responses.back().print("Added invalid");
+        }
+
+        // add valid response to responses to list
+        if (len[i] == 0)
+        {
+            last_data = starts[i] + 1;
+            data.push_back(buffer[starts[i]]);
+            responses.push_back(ZWaveResponse(data));
+            responses.back().print("Added valid 1");
+        }
+        else
+        {
+            last_data = starts[i] + len[i] + 2;
+            for (int j = starts[i]; j < starts[i] + len[i] + 2; j++)
+                data.push_back(buffer[j]);
+            responses.push_back(ZWaveResponse(data));
+            responses.back().print("Added valid 2");
+        }
+
+        // invalidate all other responses that start before we end.
+        for (size_t j = i; j < starts.size(); j++)
+        {
+            if (starts[j] < (int) last_data)
+            {
+                cout<<"invalidating #"<<j<<endl;
+                valid[j] = false;
+            }
+        }
+    }
+
+    // pop off all buffer data up until end of last complete valid response
+    if (responses.size() && responses.back().isValid())
+    {
+        for (unsigned int i = 0; i < last_data; i++)
+            buffer.pop_front();
+    }
+
+    // add any remaining cruft as response on the list
+    if (buffer.size())
+        responses.push_back(ZWaveResponse(buffer.begin(), buffer.end()));
+
+    for (uint i = 0; i < responses.size(); i++)
+        responses[i].print("Actual added response");
+
+    cout<<"getResponses() -- end"<<endl;
+
+    return responses;
 }
 
 /**
@@ -290,83 +510,106 @@
  */
 int SerialConnection::hasCommand()
 {
-	if( !isConnected() )
-	{
-		LoggerWrapper::GetInstance()->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<char>::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<char>::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<<hex<<" x"<<((int)buffer[i]&0xff)<<dec;
+        }
+        cout<<endl<<flush;
+    }
+
+    std::vector<ZWaveResponse> 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; i<len; i++)
 				{
 					instance->buffer.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 <pthread.h>
 
 #define SERIAL_ACK 0x06
+#define SERIAL_NAK 0x18
 #define SERIAL_SOF 0x01
 
+class ZWaveResponse
+{
+  public:
+    ZWaveResponse(std::deque<char>::const_iterator begin,
+                  std::deque<char>::const_iterator end);
+    ZWaveResponse(std::vector<char> 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<char> 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<ZWaveResponse> 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