1 //-----------------------------------------------------------------------------
2 //
3 //	CommandClass.h
4 //
5 //	Base class for all Z-Wave Command Classes
6 //
7 //	Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
8 //
9 //	SOFTWARE NOTICE AND LICENSE
10 //
11 //	This file is part of OpenZWave.
12 //
13 //	OpenZWave is free software: you can redistribute it and/or modify
14 //	it under the terms of the GNU Lesser General Public License as published
15 //	by the Free Software Foundation, either version 3 of the License,
16 //	or (at your option) any later version.
17 //
18 //	OpenZWave is distributed in the hope that it will be useful,
19 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
20 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 //	GNU Lesser General Public License for more details.
22 //
23 //	You should have received a copy of the GNU Lesser General Public License
24 //	along with OpenZWave.  If not, see <http://www.gnu.org/licenses/>.
25 //
26 //-----------------------------------------------------------------------------
27 
28 #ifndef _CommandClass_H
29 #define _CommandClass_H
30 
31 #include <string>
32 #include <vector>
33 #include <map>
34 #include "Defs.h"
35 #include "Bitfield.h"
36 #include "Driver.h"
37 
38 namespace OpenZWave
39 {
40 	class Msg;
41 	class Node;
42 	class Value;
43 
44 	/** \brief Base class for all Z-Wave command classes.
45 	 */
46 	class OPENZWAVE_EXPORT CommandClass
47 	{
48 
49 	public:
50 		enum
51 		{
52 			RequestFlag_Static		= 0x00000001,	/**< Values that never change. */
53 			RequestFlag_Session		= 0x00000002,	/**< Values that change infrequently, and so only need to be requested at start up, or via a manual refresh. */
54 			RequestFlag_Dynamic		= 0x00000004,	/**< Values that change and will be requested if polling is enabled on the node. */
55 			RequestFlag_AfterMark	= 0x00000008	/**< Values relevent to Controlling CC, not Controlled CC. */
56 		};
57 
58 		CommandClass( uint32 const _homeId, uint8 const _nodeId );
59 		virtual ~CommandClass();
60 
61 		virtual void ReadXML( TiXmlElement const* _ccElement );
62 		virtual void WriteXML( TiXmlElement* _ccElement );
RequestState(uint32 const _requestFlags,uint8 const _instance,Driver::MsgQueue const _queue)63 		virtual bool RequestState( uint32 const _requestFlags, uint8 const _instance, Driver::MsgQueue const _queue ){ return false; }
RequestValue(uint32 const _requestFlags,uint8 const _index,uint8 const _instance,Driver::MsgQueue const _queue)64 		virtual bool RequestValue( uint32 const _requestFlags, uint8 const _index, uint8 const _instance, Driver::MsgQueue const _queue ) { return false; }
65 
66 		virtual uint8 const GetCommandClassId()const = 0;
67 		virtual string const GetCommandClassName()const = 0;
68 		virtual bool HandleMsg( uint8 const* _data, uint32 const _length, uint32 const _instance = 1 ) = 0;
SetValue(Value const & _value)69 		virtual bool SetValue( Value const& _value ){ return false; }
SetValueBasic(uint8 const _instance,uint8 const _level)70 		virtual void SetValueBasic( uint8 const _instance, uint8 const _level ){}		// Class specific handling of BASIC value mapping
SetVersion(uint8 const _version)71 		virtual void SetVersion( uint8 const _version ){ m_version = _version; }
72 
73 		bool RequestStateForAllInstances( uint32 const _requestFlags, Driver::MsgQueue const _queue );
74 		bool CheckForRefreshValues(Value const* _value );
75 
76 		// The highest version number of the command class implemented by OpenZWave.  We only need
77 		// to do version gets on command classes that override this with a number greater than one.
GetMaxVersion()78 		virtual uint8 GetMaxVersion(){ return 1; }
79 
GetVersion()80 		uint8 GetVersion()const{ return m_version; }
GetInstances()81 		Bitfield const* GetInstances()const{ return &m_instances; }
GetHomeId()82 		uint32 GetHomeId()const{ return m_homeId; }
GetNodeId()83 		uint8 GetNodeId()const{ return m_nodeId; }
84 		Driver* GetDriver()const;
85 		Node* GetNodeUnsafe()const;
86 		Value* GetValue( uint8 const _instance, uint8 const _index );
87 		bool RemoveValue( uint8 const _instance, uint8 const _index );
GetEndPoint(uint8 const _instance)88 		uint8 GetEndPoint( uint8 const _instance )
89 		{
90 			map<uint8,uint8>::iterator it = m_endPointMap.find( _instance );
91 			return( it == m_endPointMap.end() ? 0 : it->second );
92 		}
GetInstance(uint8 const _endPoint)93 		uint8 GetInstance( uint8 const _endPoint )
94 		{
95 			for( map<uint8,uint8>::iterator it = m_endPointMap.begin(); it != m_endPointMap.end(); ++it )
96 			{
97 				if( _endPoint == it->second )
98 				{
99 					return it->first;
100 				}
101 			}
102 			return 0;
103 		}
104 
105 		void SetInstances( uint8 const _instances );
106 		void SetInstance( uint8 const _endPoint );
SetAfterMark()107 		void SetAfterMark(){ m_afterMark = true; }
SetEndPoint(uint8 const _instance,uint8 const _endpoint)108 		void SetEndPoint( uint8 const _instance, uint8 const _endpoint){ m_endPointMap[_instance] = _endpoint; }
IsAfterMark()109 		bool IsAfterMark()const{ return m_afterMark; }
IsCreateVars()110 		bool IsCreateVars()const{ return m_createVars; }
IsGetSupported()111 		bool IsGetSupported()const{ return m_getSupported; }
IsSecured()112 		bool IsSecured()const{ return m_isSecured; }
SetSecured()113 		void SetSecured(){ m_isSecured = true; }
IsSecureSupported()114 		bool IsSecureSupported()const { return m_SecureSupport; }
ClearSecureSupport()115 		void ClearSecureSupport() { m_SecureSupport = false; }
SetSecureSupport()116 		void SetSecureSupport() { m_SecureSupport = true; }
SetInNIF()117 		void SetInNIF() { m_inNIF = true; }
IsInNIF()118 		bool IsInNIF() { return m_inNIF; }
119 
120 		// Helper methods
121 		string ExtractValue( uint8 const* _data, uint8* _scale, uint8* _precision, uint8 _valueOffset = 1 )const;
122 
123 		/**
124 		 *  Append a floating-point value to a message.
125 		 *  \param _msg The message to which the value should be appended.
126 		 *  \param _value A string containing a decimal number to be appended.
127 		 *  \param _scale A byte indicating the scale corresponding to this value (e.g., 1=F and 0=C for temperatures).
128 		 *  \see Msg
129 		 */
130 		void AppendValue( Msg* _msg, string const& _value, uint8 const _scale )const;
131 		uint8 const GetAppendValueSize( string const& _value )const;
132 		int32 ValueToInteger( string const& _value, uint8* o_precision, uint8* o_size )const;
133 
134 		void UpdateMappedClass( uint8 const _instance, uint8 const _classId, uint8 const _value );		// Update mapped class's value from BASIC class
135 
136 		typedef struct RefreshValue {
137 			uint8 cc;
138 			uint8 genre;
139 			uint8 instance;
140 			uint8 index;
141 			std::vector<RefreshValue *> RefreshClasses;
142 		} RefreshValue;
143 
144 	protected:
CreateVars(uint8 const _instance)145 		virtual void CreateVars( uint8 const _instance ){}
146 		void ReadValueRefreshXML ( TiXmlElement const* _ccElement );
147 
148 	public:
CreateVars(uint8 const _instance,uint8 const _index)149 		virtual void CreateVars( uint8 const _instance, uint8 const _index ){}
150 
151 	private:
152 		uint32		m_homeId;
153 		uint8		m_nodeId;
154 		uint8		m_version;
155 		Bitfield	m_instances;
156 OPENZWAVE_EXPORT_WARNINGS_OFF
157 		map<uint8,uint8> m_endPointMap;
158 OPENZWAVE_EXPORT_WARNINGS_ON
159 		bool		m_afterMark;		// Set to true if the command class is listed after COMMAND_CLASS_MARK, and should not create any values.
160 		bool		m_createVars;		// Do we want to create variables
161 		int8		m_overridePrecision;	// Override precision when writing values if >=0
162 		bool		m_getSupported;	    	// Get operation supported
163 		bool		m_isSecured;		// is this command class secured with the Security Command Class
164 		bool		m_SecureSupport; 	// Does this commandclass support secure encryption (eg, the Security CC doesn't encrypt itself, so it doesn't support encryption)
165 		std::vector<RefreshValue *> m_RefreshClassValues; // what Command Class Values should we refresh ?
166 		bool		m_inNIF; 			// Was this command class present in the NIF Frame we recieved (or was it created from our device_classes.xml file, or because it was in the Security SupportedReport message
167 	//-----------------------------------------------------------------------------
168 	// Record which items of static data have been read from the device
169 	//-----------------------------------------------------------------------------
170 	public:
171 		enum StaticRequest
172 		{
173 			StaticRequest_Instances		= 0x01,
174 			StaticRequest_Values		= 0x02,
175 			StaticRequest_Version		= 0x04
176 		};
177 
HasStaticRequest(uint8 _request)178 		bool HasStaticRequest( uint8 _request )const{ return( (m_staticRequests & _request) != 0 ); }
SetStaticRequest(uint8 _request)179 		void SetStaticRequest( uint8 _request ){ m_staticRequests |= _request; }
180 		void ClearStaticRequest( uint8 _request );
181 
182 	private:
183 		uint8   m_staticRequests;
184 
185 	//-----------------------------------------------------------------------------
186 	//	Statistics
187 	//-----------------------------------------------------------------------------
188 	public:
GetSentCnt()189 		uint32 GetSentCnt()const{ return m_sentCnt; }
GetReceivedCnt()190 		uint32 GetReceivedCnt()const{ return m_receivedCnt; }
SentCntIncr()191 		void SentCntIncr(){ m_sentCnt++; }
ReceivedCntIncr()192 		void ReceivedCntIncr(){ m_receivedCnt++; }
193 
194 	private:
195 		uint32 m_sentCnt;				// Number of messages sent from this command class.
196 		uint32 m_receivedCnt;				// Number of messages received from this commandclass.
197 	};
198 
199 } // namespace OpenZWave
200 
201 #endif
202