1 //----------------------------------------------------------------------------- 2 // 3 // Driver.h 4 // 5 // Communicates with a Z-Wave network 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 _Driver_H 29 #define _Driver_H 30 31 #include <string> 32 #include <map> 33 #include <list> 34 35 #include "Defs.h" 36 #include "Group.h" 37 #include "value_classes/ValueID.h" 38 #include "Node.h" 39 #include "platform/Event.h" 40 #include "platform/Mutex.h" 41 #include "platform/TimeStamp.h" 42 #include "aes/aescpp.h" 43 44 namespace OpenZWave 45 { 46 class Msg; 47 class Value; 48 class Event; 49 class Mutex; 50 class Controller; 51 class Thread; 52 class ControllerReplication; 53 class Notification; 54 55 /** \brief The Driver class handles communication between OpenZWave 56 * and a device attached via a serial port (typically a controller). 57 */ 58 class OPENZWAVE_EXPORT Driver 59 { 60 friend class Manager; 61 friend class Node; 62 friend class Group; 63 friend class CommandClass; 64 friend class ControllerReplication; 65 friend class Value; 66 friend class ValueStore; 67 friend class ValueButton; 68 friend class Association; 69 friend class Basic; 70 friend class ManufacturerSpecific; 71 friend class MultiChannelAssociation; 72 friend class NodeNaming; 73 friend class NoOperation; 74 friend class SceneActivation; 75 friend class WakeUp; 76 friend class Security; 77 friend class Msg; 78 79 //----------------------------------------------------------------------------- 80 // Controller Interfaces 81 //----------------------------------------------------------------------------- 82 public: 83 enum ControllerInterface 84 { 85 ControllerInterface_Unknown = 0, 86 ControllerInterface_Serial, 87 ControllerInterface_Hid 88 }; 89 90 //----------------------------------------------------------------------------- 91 // Construction / Destruction 92 //----------------------------------------------------------------------------- 93 private: 94 /** 95 * Creates threads, events and initializes member variables and the node array. 96 */ 97 Driver( string const& _controllerPath, ControllerInterface const& _interface ); 98 /** Sets "exit" flags and stops the three background threads (pollThread, serialThread 99 * and driverThread). Then clears out the send queue and node array. Notifies 100 * watchers and exits. 101 */ 102 virtual ~Driver(); 103 104 /** 105 * Start the driverThread 106 */ 107 void Start(); 108 /** 109 * Entry point for driverThread 110 */ 111 static void DriverThreadEntryPoint( Event* _exitEvent, void* _context ); 112 /** 113 * ThreadProc for driverThread. This is where all the "action" takes place. 114 * <p> 115 * First, the thread is initialized by calling Init(). If Init() fails, it will be retried 116 * every 5 seconds for the first two minutes and every 30 seconds thereafter. 117 * <p> 118 * After the thread is successfully initialized, the thread enters a loop with the 119 * following elements: 120 * - Confirm that m_exit is still false (or exit from the thread if it is true) 121 * - Call ReadMsg() to consume any available messages from the controller 122 * - Call NotifyWatchers() to send any pending notifications 123 * - If the thread is not waiting for an ACK, a callback or a message reply, send [any][the next] queued message[s] 124 * - If there was no message read or sent (workDone=false), sleep for 5 seconds. If nothing happened 125 * within this time frame and something was expected (ACK, callback or reply), retrieve the 126 * last message from the send queue and examine GetSendAttempts(). If greater than 2, give up 127 * and remove the message from the queue. Otherwise, resend the message. 128 * - If something did happen [reset m_wakeEvent] 129 */ 130 void DriverThreadProc( Event* _exitEvent ); 131 /** 132 * Initialize the controller. Open the specified serial port, start the serialThread 133 * and pollThread, then send a NAK to the device [presumably to flush it]. 134 * <p> 135 * Then queue the commands to retrieve the Z-Wave interface: 136 * - Get version 137 * - Get home and node IDs 138 * - Get controller capabilities 139 * - Get serial API capabilities 140 * - [Get SUC node ID] 141 * - Get init data [identifying the nodes on the network] 142 * Init() will return false if the serial port could not be opened. 143 */ 144 bool Init( uint32 _attempts ); 145 146 /** 147 * Remove any messages to a node on the queues 148 * Used when deleting a node. 149 */ 150 void RemoveQueues( uint8 const _nodeId ); 151 152 Thread* m_driverThread; /**< Thread for reading from the Z-Wave controller, and for creating and managing the other threads for sending, polling etc. */ 153 Mutex* m_initMutex; /**< Mutex to ensure proper ordering of initialization/deinitialization */ 154 bool m_exit; /**< Flag that is set when the application is exiting. */ 155 bool m_init; /**< Set to true once the driver has been initialised */ 156 bool m_awakeNodesQueried; /**< Set to true once the driver has polled all awake nodes */ 157 bool m_allNodesQueried; /**< Set to true once the driver has polled all nodes */ 158 bool m_notifytransactions; 159 TimeStamp m_startTime; /**< Time this driver started (for log report purposes) */ 160 161 //----------------------------------------------------------------------------- 162 // Configuration 163 //----------------------------------------------------------------------------- 164 private: 165 void RequestConfig(); // Get the network configuration from the Z-Wave network 166 bool ReadConfig(); // Read the configuration from a file 167 void WriteConfig(); // Save the configuration to a file 168 169 //----------------------------------------------------------------------------- 170 // Controller 171 //----------------------------------------------------------------------------- 172 private: 173 // Controller Capabilities (return in FUNC_ID_ZW_GET_CONTROLLER_CAPABILITIES) 174 enum 175 { 176 ControllerCaps_Secondary = 0x01, /**< The controller is a secondary. */ 177 ControllerCaps_OnOtherNetwork = 0x02, /**< The controller is not using its default HomeID. */ 178 ControllerCaps_SIS = 0x04, /**< There is a SUC ID Server on the network. */ 179 ControllerCaps_RealPrimary = 0x08, /**< Controller was the primary before the SIS was added. */ 180 ControllerCaps_SUC = 0x10 /**< Controller is a static update controller. */ 181 }; 182 183 // Init Capabilities (return in FUNC_ID_SERIAL_API_GET_INIT_DATA) 184 enum 185 { 186 InitCaps_Slave = 0x01, /**< */ 187 InitCaps_TimerSupport = 0x02, /**< Controller supports timers. */ 188 InitCaps_Secondary = 0x04, /**< Controller is a secondary. */ 189 InitCaps_SUC = 0x08 /**< Controller is a static update controller. */ 190 }; 191 IsPrimaryController()192 bool IsPrimaryController()const{ return ((m_initCaps & InitCaps_Secondary) == 0); } IsStaticUpdateController()193 bool IsStaticUpdateController()const{ return ((m_initCaps & InitCaps_SUC) != 0); } IsBridgeController()194 bool IsBridgeController()const{ return (m_libraryType == 7); } IsInclusionController()195 bool IsInclusionController()const{ return ((m_controllerCaps & ControllerCaps_SIS) != 0); } 196 197 GetHomeId()198 uint32 GetHomeId()const{ return m_homeId; } GetControllerNodeId()199 uint8 GetControllerNodeId()const{ return m_Controller_nodeId; } GetSUCNodeId()200 uint8 GetSUCNodeId()const{ return m_SUCNodeId; } GetManufacturerId()201 uint16 GetManufacturerId()const{ return m_manufacturerId; } GetProductType()202 uint16 GetProductType()const{ return m_productType; } GetProductId()203 uint16 GetProductId()const{ return m_productId; } GetControllerPath()204 string GetControllerPath()const{ return m_controllerPath; } GetControllerInterfaceType()205 ControllerInterface GetControllerInterfaceType()const{ return m_controllerInterfaceType; } GetLibraryVersion()206 string GetLibraryVersion()const{ return m_libraryVersion; } GetLibraryTypeName()207 string GetLibraryTypeName()const{ return m_libraryTypeName; } GetSendQueueCount()208 int32 GetSendQueueCount()const 209 { 210 int32 count = 0; 211 for( int32 i=0; i<MsgQueue_Count; ++i ) 212 { 213 count += (int32) (m_msgQueue[i].size()); 214 } 215 return count; 216 } 217 218 /** 219 * A version of GetNode that does not have the protective "lock" and "release" requirement. 220 * This function can be used within driverThread, which "knows" that the node will not be 221 * changed or deleted while it is being used. 222 * \param _nodeId The nodeId (index into the node array) identifying the node to be returned 223 * \return 224 * A pointer to the specified node (if it exists) or NULL if not. 225 * \see GetNode 226 */ 227 Node* GetNodeUnsafe( uint8 _nodeId ); 228 /** 229 * Locks the node array and returns the specified node (if it exists). If a node is returned, 230 * the lock must be released after the node has been processed via a call to ReleaseNodes(). 231 * If the node specified by _nodeId does not exist, the lock is released and NULL is returned. 232 * \param _nodeId The nodeId (index into the node array) identifying the node to be returned 233 * \return 234 * A pointer to the specified node (if it exists) or NULL if not. 235 * \see LockNodes, ReleaseNodes 236 */ 237 Node* GetNode( uint8 _nodeId ); 238 /** 239 * Lock the nodes so no other thread can modify them. 240 */ 241 //void LockNodes(); 242 /** 243 * Release the lock on the nodes so other threads can modify them. 244 */ 245 //void ReleaseNodes(); 246 247 ControllerInterface m_controllerInterfaceType; // Specifies the controller's hardware interface 248 string m_controllerPath; // name or path used to open the controller hardware. 249 Controller* m_controller; // Handles communications with the controller hardware. 250 uint32 m_homeId; // Home ID of the Z-Wave controller. Not valid until the DriverReady notification has been received. 251 252 string m_libraryVersion; // Version of the Z-Wave Library used by the controller. 253 string m_libraryTypeName; // Name describing the library type. 254 uint8 m_libraryType; // Type of library used by the controller. 255 256 uint8 m_serialAPIVersion[2]; 257 uint16 m_manufacturerId; 258 uint16 m_productType; 259 uint16 m_productId; 260 uint8 m_apiMask[32]; 261 262 uint8 m_initVersion; // Version of the Serial API used by the controller. 263 uint8 m_initCaps; // Set of flags indicating the serial API capabilities (See IsSlave, HasTimerSupport, IsPrimaryController and IsStaticUpdateController above). 264 uint8 m_controllerCaps; // Set of flags indicating the controller's capabilities (See IsInclusionController above). 265 uint8 m_Controller_nodeId; // Z-Wave Controller's own node ID. 266 Node* m_nodes[256]; // Array containing all the node objects. 267 Mutex* m_nodeMutex; // Serializes access to node data 268 269 ControllerReplication* m_controllerReplication; // Controller replication is handled separately from the other command classes, due to older hand-held controllers using invalid node IDs. 270 271 uint8 m_transmitOptions; 272 273 //----------------------------------------------------------------------------- 274 // Receiving Z-Wave messages 275 //----------------------------------------------------------------------------- 276 private: 277 bool ReadMsg(); 278 void ProcessMsg( uint8* _data ); 279 280 void HandleGetVersionResponse( uint8* _data ); 281 void HandleGetRandomResponse( uint8* _data ); 282 void HandleGetControllerCapabilitiesResponse( uint8* _data ); 283 void HandleGetSerialAPICapabilitiesResponse( uint8* _data ); 284 void HandleSerialAPISoftResetResponse( uint8* _data ); 285 void HandleEnableSUCResponse( uint8* _data ); 286 void HandleSetSUCNodeIdResponse( uint8* _data ); 287 void HandleGetSUCNodeIdResponse( uint8* _data ); 288 void HandleMemoryGetIdResponse( uint8* _data ); 289 /** 290 * Process a response to a FUNC_ID_SERIAL_API_GET_INIT_DATA request. 291 * <p> 292 * The response message contains a bitmap identifying which of the 232 possible nodes 293 * in the network are actually present. These bitmap values are compared with the 294 * node map (read in from zwcfg_0x[homeid].xml) to see if the node has already been registered 295 * by the OpenZWave library. If it has (the log will show it as "Known") and this is 296 * the first time this message was sent (m_init is false), then AddNodeQuery() is called 297 * to retrieve its current state. If this is a "New" node to OpenZWave, then InitNode() 298 * is called. 299 * \see AddNodeQuery, InitNode, GetNode, ReleaseNodes 300 */ 301 void HandleSerialAPIGetInitDataResponse( uint8* _data ); 302 void HandleGetNodeProtocolInfoResponse( uint8* _data ); 303 bool HandleRemoveFailedNodeResponse( uint8* _data ); 304 void HandleIsFailedNodeResponse( uint8* _data ); 305 bool HandleReplaceFailedNodeResponse( uint8* _data ); 306 bool HandleAssignReturnRouteResponse( uint8* _data ); 307 bool HandleDeleteReturnRouteResponse( uint8* _data ); 308 void HandleSendNodeInformationRequest( uint8* _data ); 309 void HandleSendDataResponse( uint8* _data, bool _replication ); 310 bool HandleNetworkUpdateResponse( uint8* _data ); 311 void HandleGetRoutingInfoResponse( uint8* _data ); 312 313 void HandleSendDataRequest( uint8* _data, bool _replication ); 314 void HandleAddNodeToNetworkRequest( uint8* _data ); 315 void HandleCreateNewPrimaryRequest( uint8* _data ); 316 void HandleControllerChangeRequest( uint8* _data ); 317 void HandleSetLearnModeRequest( uint8* _data ); 318 void HandleRemoveFailedNodeRequest( uint8* _data ); 319 void HandleReplaceFailedNodeRequest( uint8* _data ); 320 void HandleRemoveNodeFromNetworkRequest( uint8* _data ); 321 void HandleApplicationCommandHandlerRequest( uint8* _data, bool encrypted ); 322 void HandlePromiscuousApplicationCommandHandlerRequest( uint8* _data ); 323 void HandleAssignReturnRouteRequest( uint8* _data ); 324 void HandleDeleteReturnRouteRequest( uint8* _data ); 325 void HandleNodeNeighborUpdateRequest( uint8* _data ); 326 void HandleNetworkUpdateRequest( uint8* _data ); 327 bool HandleApplicationUpdateRequest( uint8* _data ); 328 bool HandleRfPowerLevelSetResponse( uint8* _data ); 329 bool HandleSerialApiSetTimeoutsResponse( uint8* _data ); 330 bool HandleMemoryGetByteResponse( uint8* _data ); 331 bool HandleReadMemoryResponse( uint8* _data ); 332 void HandleGetVirtualNodesResponse( uint8* _data ); 333 bool HandleSetSlaveLearnModeResponse( uint8* _data ); 334 void HandleSetSlaveLearnModeRequest( uint8* _data ); 335 bool HandleSendSlaveNodeInfoResponse( uint8* _data ); 336 void HandleSendSlaveNodeInfoRequest( uint8* _data ); 337 void HandleApplicationSlaveCommandRequest( uint8* _data ); 338 void HandleSerialAPIResetRequest( uint8* _data ); 339 340 void CommonAddNodeStatusRequestHandler( uint8 _funcId, uint8* _data ); 341 342 bool m_waitingForAck; // True when we are waiting for an ACK from the dongle 343 uint8 m_expectedCallbackId; // If non-zero, we wait for a message with this callback Id 344 uint8 m_expectedReply; // If non-zero, we wait for a message with this function Id 345 uint8 m_expectedCommandClassId; // If the expected reply is FUNC_ID_APPLICATION_COMMAND_HANDLER, this value stores the command class we're waiting to hear from 346 uint8 m_expectedNodeId; // If we are waiting for a FUNC_ID_APPLICATION_COMMAND_HANDLER, make sure we only accept it from this node. 347 348 //----------------------------------------------------------------------------- 349 // Polling Z-Wave devices 350 //----------------------------------------------------------------------------- 351 private: GetPollInterval()352 int32 GetPollInterval(){ return m_pollInterval ; } SetPollInterval(int32 _milliseconds,bool _bIntervalBetweenPolls)353 void SetPollInterval( int32 _milliseconds, bool _bIntervalBetweenPolls ){ m_pollInterval = _milliseconds; m_bIntervalBetweenPolls = _bIntervalBetweenPolls; } 354 bool EnablePoll( const ValueID &_valueId, uint8 _intensity = 1 ); 355 bool DisablePoll( const ValueID &_valueId ); 356 bool isPolled( const ValueID &_valueId ); 357 void SetPollIntensity( const ValueID &_valueId, uint8 _intensity ); 358 static void PollThreadEntryPoint( Event* _exitEvent, void* _context ); 359 void PollThreadProc( Event* _exitEvent ); 360 361 Thread* m_pollThread; // Thread for polling devices on the Z-Wave network 362 struct PollEntry 363 { 364 ValueID m_id; 365 uint8 m_pollCounter; 366 }; 367 OPENZWAVE_EXPORT_WARNINGS_OFF 368 list<PollEntry> m_pollList; // List of nodes that need to be polled 369 OPENZWAVE_EXPORT_WARNINGS_ON 370 Mutex* m_pollMutex; // Serialize access to the polling list 371 int32 m_pollInterval; // Time interval during which all nodes must be polled 372 bool m_bIntervalBetweenPolls; // if true, the library intersperses m_pollInterval between polls; if false, the library attempts to complete all polls within m_pollInterval 373 374 //----------------------------------------------------------------------------- 375 // Retrieving Node information 376 //----------------------------------------------------------------------------- 377 public: GetNodeNumber(Msg const * _msg)378 uint8 GetNodeNumber( Msg const* _msg )const{ return ( _msg == NULL ? 0 : _msg->GetTargetNodeId() ); } 379 380 private: 381 /** 382 * Creates a new Node object (deleting any previous Node object with the same nodeId) and 383 * queues a full query of the node's parameters (starting at the beginning of the query 384 * stages--Node::QueryStage_None). This function will send Notification::Type_NodeAdded 385 * and Notification::Type_NodeRemoved messages to identify these modifications. 386 * \param _nodeId The node ID of the node to create and query. 387 * \param newNode If this is a new Node added to the network, or we are just creating when we reload. 388 * \param _protocolInfo if this is called via a AddNode command, then this would be the Device Classes, and CommandClass list 389 * \param _length The length of the _protocolInfo field 390 * \see Notification::Type_NodeAdded, Notification::Type_NodeRemoved, Node::QueryStage_None, 391 */ 392 void InitNode( uint8 const _nodeId, bool newNode = false, bool secure = false, uint8 const *_protocolInfo = NULL, uint8 const _length = 0); 393 394 void InitAllNodes(); // Delete all nodes and fetch the data from the Z-Wave network again. 395 396 bool IsNodeListeningDevice( uint8 const _nodeId ); 397 bool IsNodeFrequentListeningDevice( uint8 const _nodeId ); 398 bool IsNodeBeamingDevice( uint8 const _nodeId ); 399 bool IsNodeRoutingDevice( uint8 const _nodeId ); 400 bool IsNodeSecurityDevice( uint8 const _nodeId ); 401 uint32 GetNodeMaxBaudRate( uint8 const _nodeId ); 402 uint8 GetNodeVersion( uint8 const _nodeId ); 403 uint8 GetNodeSecurity( uint8 const _nodeId ); 404 uint8 GetNodeBasic( uint8 const _nodeId ); 405 uint8 GetNodeGeneric( uint8 const _nodeId ); 406 uint8 GetNodeSpecific( uint8 const _nodeId ); 407 string GetNodeType( uint8 const _nodeId ); 408 uint32 GetNodeNeighbors( uint8 const _nodeId, uint8** o_neighbors ); 409 410 string GetNodeManufacturerName( uint8 const _nodeId ); 411 string GetNodeProductName( uint8 const _nodeId ); 412 string GetNodeName( uint8 const _nodeId ); 413 string GetNodeLocation( uint8 const _nodeId ); 414 uint16 GetNodeDeviceType( uint8 const _nodeId ); 415 string GetNodeDeviceTypeString( uint8 const _nodeId ); 416 uint8 GetNodeRole( uint8 const _nodeId ); 417 string GetNodeRoleString( uint8 const _nodeId ); 418 uint8 GetNodePlusType( uint8 const _nodeId ); 419 string GetNodePlusTypeString ( uint8 const _nodeId ); 420 bool IsNodeZWavePlus( uint8 const _nodeId ); 421 422 423 uint16 GetNodeManufacturerId( uint8 const _nodeId ); 424 uint16 GetNodeProductType( uint8 const _nodeId ); 425 uint16 GetNodeProductId( uint8 const _nodeId ); 426 void SetNodeManufacturerName( uint8 const _nodeId, string const& _manufacturerName ); 427 void SetNodeProductName( uint8 const _nodeId, string const& _productName ); 428 void SetNodeName( uint8 const _nodeId, string const& _nodeName ); 429 void SetNodeLocation( uint8 const _nodeId, string const& _location ); 430 void SetNodeLevel( uint8 const _nodeId, uint8 const _level ); 431 void SetNodeOn( uint8 const _nodeId ); 432 void SetNodeOff( uint8 const _nodeId ); 433 434 Value* GetValue( ValueID const& _id ); 435 IsAPICallSupported(uint8 const _apinum)436 bool IsAPICallSupported( uint8 const _apinum )const{ return (( m_apiMask[( _apinum - 1 ) >> 3] & ( 1 << (( _apinum - 1 ) & 0x07 ))) != 0 ); } SetAPICall(uint8 const _apinum,bool _toSet)437 void SetAPICall( uint8 const _apinum, bool _toSet ) 438 { 439 if( _toSet ) 440 { 441 m_apiMask[( _apinum - 1 ) >> 3] |= ( 1 << (( _apinum - 1 ) & 0x07 )); 442 } 443 else 444 { 445 m_apiMask[( _apinum - 1 ) >> 3] &= ~( 1 << (( _apinum - 1 ) & 0x07 )); 446 } 447 } 448 uint8 NodeFromMessage( uint8 const* buffer ); 449 450 //----------------------------------------------------------------------------- 451 // Controller commands 452 //----------------------------------------------------------------------------- 453 public: 454 /** 455 * Controller Commands. 456 * Commands to be used with the BeginControllerCommand method. 457 * \see Manager::BeginControllerCommand 458 */ 459 enum ControllerCommand 460 { 461 ControllerCommand_None = 0, /**< No command. */ 462 ControllerCommand_AddDevice, /**< Add a new device or controller to the Z-Wave network. */ 463 ControllerCommand_CreateNewPrimary, /**< Add a new controller to the Z-Wave network. Used when old primary fails. Requires SUC. */ 464 ControllerCommand_ReceiveConfiguration, /**< Receive Z-Wave network configuration information from another controller. */ 465 ControllerCommand_RemoveDevice, /**< Remove a device or controller from the Z-Wave network. */ 466 ControllerCommand_RemoveFailedNode, /**< Move a node to the controller's failed nodes list. This command will only work if the node cannot respond. */ 467 ControllerCommand_HasNodeFailed, /**< Check whether a node is in the controller's failed nodes list. */ 468 ControllerCommand_ReplaceFailedNode, /**< Replace a non-responding node with another. The node must be in the controller's list of failed nodes for this command to succeed. */ 469 ControllerCommand_TransferPrimaryRole, /**< Make a different controller the primary. */ 470 ControllerCommand_RequestNetworkUpdate, /**< Request network information from the SUC/SIS. */ 471 ControllerCommand_RequestNodeNeighborUpdate, /**< Get a node to rebuild its neighbour list. This method also does RequestNodeNeighbors */ 472 ControllerCommand_AssignReturnRoute, /**< Assign a network return routes to a device. */ 473 ControllerCommand_DeleteAllReturnRoutes, /**< Delete all return routes from a device. */ 474 ControllerCommand_SendNodeInformation, /**< Send a node information frame */ 475 ControllerCommand_ReplicationSend, /**< Send information from primary to secondary */ 476 ControllerCommand_CreateButton, /**< Create an id that tracks handheld button presses */ 477 ControllerCommand_DeleteButton /**< Delete id that tracks handheld button presses */ 478 }; 479 480 /** 481 * Controller States. 482 * States reported via the callback handler passed into the BeginControllerCommand method. 483 * \see Manager::BeginControllerCommand 484 */ 485 enum ControllerState 486 { 487 ControllerState_Normal = 0, /**< No command in progress. */ 488 ControllerState_Starting, /**< The command is starting. */ 489 ControllerState_Cancel, /**< The command was canceled. */ 490 ControllerState_Error, /**< Command invocation had error(s) and was aborted */ 491 ControllerState_Waiting, /**< Controller is waiting for a user action. */ 492 ControllerState_Sleeping, /**< Controller command is on a sleep queue wait for device. */ 493 ControllerState_InProgress, /**< The controller is communicating with the other device to carry out the command. */ 494 ControllerState_Completed, /**< The command has completed successfully. */ 495 ControllerState_Failed, /**< The command has failed. */ 496 ControllerState_NodeOK, /**< Used only with ControllerCommand_HasNodeFailed to indicate that the controller thinks the node is OK. */ 497 ControllerState_NodeFailed /**< Used only with ControllerCommand_HasNodeFailed to indicate that the controller thinks the node has failed. */ 498 }; 499 500 /** 501 * Controller Errors 502 * Provide some more information about controller failures. 503 */ 504 enum ControllerError 505 { 506 ControllerError_None = 0, 507 ControllerError_ButtonNotFound, /**< Button */ 508 ControllerError_NodeNotFound, /**< Button */ 509 ControllerError_NotBridge, /**< Button */ 510 ControllerError_NotSUC, /**< CreateNewPrimary */ 511 ControllerError_NotSecondary, /**< CreateNewPrimary */ 512 ControllerError_NotPrimary, /**< RemoveFailedNode, AddNodeToNetwork */ 513 ControllerError_IsPrimary, /**< ReceiveConfiguration */ 514 ControllerError_NotFound, /**< RemoveFailedNode */ 515 ControllerError_Busy, /**< RemoveFailedNode, RequestNetworkUpdate */ 516 ControllerError_Failed, /**< RemoveFailedNode, RequestNetworkUpdate */ 517 ControllerError_Disabled, /**< RequestNetworkUpdate error */ 518 ControllerError_Overflow /**< RequestNetworkUpdate error */ 519 }; 520 521 typedef void (*pfnControllerCallback_t)( ControllerState _state, ControllerError _err, void* _context ); 522 523 private: 524 // The public interface is provided via the wrappers in the Manager class 525 void ResetController( Event* _evt ); 526 void SoftReset(); 527 void RequestNodeNeighbors( uint8 const _nodeId, uint32 const _requestFlags ); 528 529 bool BeginControllerCommand( ControllerCommand _command, pfnControllerCallback_t _callback, void* _context, bool _highPower, uint8 _nodeId, uint8 _arg ); 530 bool CancelControllerCommand(); 531 void AddNodeStop( uint8 const _funcId ); // Handle different controller behaviors 532 533 struct ControllerCommandItem 534 { 535 ControllerState m_controllerState; 536 bool m_controllerStateChanged; 537 bool m_controllerCommandDone; 538 ControllerCommand m_controllerCommand; 539 pfnControllerCallback_t m_controllerCallback; 540 ControllerError m_controllerReturnError; 541 void* m_controllerCallbackContext; 542 bool m_highPower; 543 bool m_controllerAdded; 544 uint8 m_controllerCommandNode; 545 uint8 m_controllerCommandArg; 546 uint8 m_controllerDeviceProtocolInfo[254]; 547 uint8 m_controllerDeviceProtocolInfoLength; 548 }; 549 550 ControllerCommandItem* m_currentControllerCommand; 551 552 void DoControllerCommand(); 553 void UpdateControllerState( ControllerState const _state, ControllerError const _error = ControllerError_None ); 554 555 uint8 m_SUCNodeId; 556 557 void UpdateNodeRoutes( uint8 const_nodeId, bool _doUpdate = false ); 558 559 Event* m_controllerResetEvent; 560 561 //----------------------------------------------------------------------------- 562 // Sending Z-Wave messages 563 //----------------------------------------------------------------------------- 564 public: 565 enum MsgQueue 566 { 567 MsgQueue_Command = 0, 568 MsgQueue_Security, 569 MsgQueue_NoOp, 570 MsgQueue_Controller, 571 MsgQueue_WakeUp, 572 MsgQueue_Send, 573 MsgQueue_Query, 574 MsgQueue_Poll, 575 MsgQueue_Count // Number of message queues 576 }; 577 578 void SendMsg( Msg* _msg, MsgQueue const _queue ); 579 580 /** 581 * Fetch the transmit options 582 */ GetTransmitOptions()583 uint8 GetTransmitOptions()const{ return m_transmitOptions; } 584 585 private: 586 /** 587 * If there are messages in the send queue (m_sendQueue), gets the next message in the 588 * queue and writes it to the serial port. In sending the message, SendMsg also initializes 589 * variables tracking the message's callback ID (m_expectedCallbackId), expected reply 590 * (m_expectedReply) and expected command class ID (m_expectedCommandClassId). It also 591 * sets m_waitingForAck to true and increments the message's send attempts counter. 592 * <p> 593 * If there are no messages in the send queue, then SendMsg checks the query queue to 594 * see if there are any outstanding queries that can be processed (target node not asleep). 595 * If so, it retrieves the Node object that needs to be queried and calls that node's 596 * AdvanceQueries member function. If this call results in all of the node's queries to be 597 * completed, SendMsg will remove the node query item from the query queue. 598 * \return TRUE if data was written, FALSE if not 599 * \see Msg, m_sendQueue, m_expectedCallbackId, m_expectedReply, m_expectedCommandClassId, 600 * m_waitingForAck, Msg::GetSendAttempts, Node::AdvanceQueries, GetCurrentNodeQuery, 601 * RemoveNodeQuery, Node::AllQueriesCompleted 602 */ 603 bool WriteNextMsg( MsgQueue const _queue ); // Extracts the first message from the queue, and makes it the current one. 604 bool WriteMsg( string const &str); // Sends the current message to the Z-Wave network 605 void RemoveCurrentMsg(); // Deletes the current message and cleans up the callback etc states 606 bool MoveMessagesToWakeUpQueue( uint8 const _targetNodeId, bool const _move ); // If a node does not respond, and is of a type that can sleep, this method is used to move all its pending messages to another queue ready for when it wakes up next. 607 bool HandleErrorResponse( uint8 const _error, uint8 const _nodeId, char const* _funcStr, bool _sleepCheck = false ); // Handle data errors and process consistently. If message is moved to wake-up queue, return true. 608 bool IsExpectedReply( uint8 const _nodeId ); // Determine if reply message is the one we are expecting 609 void SendQueryStageComplete( uint8 const _nodeId, Node::QueryStage const _stage ); 610 void RetryQueryStageComplete( uint8 const _nodeId, Node::QueryStage const _stage ); 611 void CheckCompletedNodeQueries(); // Send notifications if all awake and/or sleeping nodes have completed their queries 612 613 // Requests to be sent to nodes are assigned to one of five queues. 614 // From highest to lowest priority, these are 615 // 616 // 0) The security queue, for handling encrypted messages. This is the 617 // highest priority send queue, because the security process inserts 618 // messages to handle the encryption process that must be sent before 619 // a new message can be wrapped. 620 // 621 // 1) The command queue, for controller commands. This is the 2nd highest 622 // priority send queue, because the controller command processes are not 623 // permitted to be interrupted by other requests. 624 // 625 // 2) The controller queue exists to handle multi-step controller commands. These 626 // typically require user interaction or affect the network in some way. 627 // 628 // 3) The No Operation command class queue. This is used for device probing 629 // at startup as well as network diagnostics. 630 // 631 // 4) The wakeup queue. This holds messages that have been held for a 632 // sleeping device that has now woken up. These get a high priority 633 // because such devices do not stay awake for very long. 634 // 635 // 5) The send queue. This is for normal messages, usually triggered by 636 // a user interaction with the application. 637 // 638 // 6) The query queue. For node query messages sent when a new node is 639 // discovered. The query process generates a large number of requests, 640 // so the query queue has a low priority to avoid making the system 641 // unresponsive. 642 // 643 // 7) The poll queue. Requests to devices that need their state polling 644 // at regular intervals. These are of the lowest priority, and are only 645 // sent when nothing else is going on 646 // 647 enum MsgQueueCmd 648 { 649 MsgQueueCmd_SendMsg = 0, 650 MsgQueueCmd_QueryStageComplete, 651 MsgQueueCmd_Controller 652 }; 653 654 class MsgQueueItem 655 { 656 public: MsgQueueItem()657 MsgQueueItem() : 658 m_msg(NULL), 659 m_nodeId(0), 660 m_queryStage(Node::QueryStage_None), 661 m_retry(false), 662 m_cci(NULL) 663 {} 664 665 bool operator == ( MsgQueueItem const& _other )const 666 { 667 if( _other.m_command == m_command ) 668 { 669 if( m_command == MsgQueueCmd_SendMsg ) 670 { 671 return( (*_other.m_msg) == (*m_msg) ); 672 } 673 else if( m_command == MsgQueueCmd_QueryStageComplete ) 674 { 675 return( (_other.m_nodeId == m_nodeId) && (_other.m_queryStage == m_queryStage) ); 676 } 677 else if( m_command == MsgQueueCmd_Controller ) 678 { 679 return( (_other.m_cci->m_controllerCommand == m_cci->m_controllerCommand) && (_other.m_cci->m_controllerCallback == m_cci->m_controllerCallback) ); 680 } 681 } 682 683 return false; 684 } 685 686 MsgQueueCmd m_command; 687 Msg* m_msg; 688 uint8 m_nodeId; 689 Node::QueryStage m_queryStage; 690 bool m_retry; 691 ControllerCommandItem* m_cci; 692 }; 693 694 OPENZWAVE_EXPORT_WARNINGS_OFF 695 list<MsgQueueItem> m_msgQueue[MsgQueue_Count]; 696 OPENZWAVE_EXPORT_WARNINGS_ON 697 Event* m_queueEvent[MsgQueue_Count]; // Events for each queue, which are signaled when the queue is not empty 698 Mutex* m_sendMutex; // Serialize access to the queues 699 Msg* m_currentMsg; 700 MsgQueue m_currentMsgQueueSource; // identifies which queue held m_currentMsg 701 TimeStamp m_resendTimeStamp; 702 703 //----------------------------------------------------------------------------- 704 // Network functions 705 //----------------------------------------------------------------------------- 706 private: 707 void TestNetwork( uint8 const _nodeId, uint32 const _count ); 708 709 //----------------------------------------------------------------------------- 710 // Virtual Node commands 711 //----------------------------------------------------------------------------- 712 public: 713 /** 714 * Virtual Node Commands. 715 * Commands to be used with virtual nodes. 716 */ 717 private: 718 uint32 GetVirtualNeighbors( uint8** o_neighbors ); 719 void RequestVirtualNeighbors( MsgQueue const _queue ); IsVirtualNode(uint8 const _nodeId)720 bool IsVirtualNode( uint8 const _nodeId )const{ return (( m_virtualNeighbors[( _nodeId - 1 ) >> 3] & 1 << (( _nodeId - 1 ) & 0x07 )) != 0 ); } 721 void SendVirtualNodeInfo( uint8 const _fromNodeId, uint8 const _ToNodeId ); 722 void SendSlaveLearnModeOff(); 723 void SaveButtons(); 724 void ReadButtons( uint8 const _nodeId ); 725 726 bool m_virtualNeighborsReceived; 727 uint8 m_virtualNeighbors[NUM_NODE_BITFIELD_BYTES]; // Bitmask containing virtual neighbors 728 729 //----------------------------------------------------------------------------- 730 // SwitchAll 731 //----------------------------------------------------------------------------- 732 private: 733 // The public interface is provided via the wrappers in the Manager class 734 void SwitchAllOn(); 735 void SwitchAllOff(); 736 737 //----------------------------------------------------------------------------- 738 // Configuration Parameters (wrappers for the Node methods) 739 //----------------------------------------------------------------------------- 740 private: 741 // The public interface is provided via the wrappers in the Manager class 742 bool SetConfigParam( uint8 const _nodeId, uint8 const _param, int32 _value, uint8 const _size ); 743 void RequestConfigParam( uint8 const _nodeId, uint8 const _param ); 744 745 //----------------------------------------------------------------------------- 746 // Groups (wrappers for the Node methods) 747 //----------------------------------------------------------------------------- 748 private: 749 // The public interface is provided via the wrappers in the Manager class 750 uint8 GetNumGroups( uint8 const _nodeId ); 751 uint32 GetAssociations( uint8 const _nodeId, uint8 const _groupIdx, uint8** o_associations ); 752 uint32 GetAssociations( uint8 const _nodeId, uint8 const _groupIdx, InstanceAssociation** o_associations ); 753 uint8 GetMaxAssociations( uint8 const _nodeId, uint8 const _groupIdx ); 754 string GetGroupLabel( uint8 const _nodeId, uint8 const _groupIdx ); 755 void AddAssociation( uint8 const _nodeId, uint8 const _groupIdx, uint8 const _targetNodeId, uint8 const _instance = 0x00 ); 756 void RemoveAssociation( uint8 const _nodeId, uint8 const _groupIdx, uint8 const _targetNodeId, uint8 const _instance = 0x00 ); 757 758 //----------------------------------------------------------------------------- 759 // Notifications 760 //----------------------------------------------------------------------------- 761 private: 762 void QueueNotification( Notification* _notification ); // Adds a notification to the list. Notifications are queued until a point in the thread where we know we do not have any nodes locked. 763 void NotifyWatchers(); // Passes the notifications to all the registered watcher callbacks in turn. 764 765 OPENZWAVE_EXPORT_WARNINGS_OFF 766 list<Notification*> m_notifications; 767 OPENZWAVE_EXPORT_WARNINGS_ON 768 Event* m_notificationsEvent; 769 770 //----------------------------------------------------------------------------- 771 // Statistics 772 //----------------------------------------------------------------------------- 773 public: 774 struct DriverData 775 { 776 uint32 m_SOFCnt; // Number of SOF bytes received 777 uint32 m_ACKWaiting; // Number of unsolicited messages while waiting for an ACK 778 uint32 m_readAborts; // Number of times read were aborted due to timeouts 779 uint32 m_badChecksum; // Number of bad checksums 780 uint32 m_readCnt; // Number of messages successfully read 781 uint32 m_writeCnt; // Number of messages successfully sent 782 uint32 m_CANCnt; // Number of CAN bytes received 783 uint32 m_NAKCnt; // Number of NAK bytes received 784 uint32 m_ACKCnt; // Number of ACK bytes received 785 uint32 m_OOFCnt; // Number of bytes out of framing 786 uint32 m_dropped; // Number of messages dropped & not delivered 787 uint32 m_retries; // Number of messages retransmitted 788 uint32 m_callbacks; // Number of unexpected callbacks 789 uint32 m_badroutes; // Number of failed messages due to bad route response 790 uint32 m_noack; // Number of no ACK returned errors 791 uint32 m_netbusy; // Number of network busy/failure messages 792 uint32 m_notidle; 793 uint32 m_nondelivery; // Number of messages not delivered to network 794 uint32 m_routedbusy; // Number of messages received with routed busy status 795 uint32 m_broadcastReadCnt; // Number of broadcasts read 796 uint32 m_broadcastWriteCnt; // Number of broadcasts sent 797 }; 798 799 void LogDriverStatistics(); 800 801 private: 802 void GetDriverStatistics( DriverData* _data ); 803 void GetNodeStatistics( uint8 const _nodeId, Node::NodeData* _data ); 804 805 uint32 m_SOFCnt; // Number of SOF bytes received 806 uint32 m_ACKWaiting; // Number of unsolicited messages while waiting for an ACK 807 uint32 m_readAborts; // Number of times read were aborted due to timeouts 808 uint32 m_badChecksum; // Number of bad checksums 809 uint32 m_readCnt; // Number of messages successfully read 810 uint32 m_writeCnt; // Number of messages successfully sent 811 uint32 m_CANCnt; // Number of CAN bytes received 812 uint32 m_NAKCnt; // Number of NAK bytes received 813 uint32 m_ACKCnt; // Number of ACK bytes received 814 uint32 m_OOFCnt; // Number of bytes out of framing 815 uint32 m_dropped; // Number of messages dropped & not delivered 816 uint32 m_retries; // Number of retransmitted messages 817 uint32 m_callbacks; // Number of unexpected callbacks 818 uint32 m_badroutes; // Number of failed messages due to bad route response 819 uint32 m_noack; // Number of no ACK returned errors 820 uint32 m_netbusy; // Number of network busy/failure messages 821 uint32 m_notidle; // Number of not idle messages 822 uint32 m_nondelivery; // Number of messages not delivered to network 823 uint32 m_routedbusy; // Number of messages received with routed busy status 824 uint32 m_broadcastReadCnt; // Number of broadcasts read 825 uint32 m_broadcastWriteCnt; // Number of broadcasts sent 826 //time_t m_commandStart; // Start time of last command 827 //time_t m_timeoutLost; // Cumulative time lost to timeouts 828 829 830 //----------------------------------------------------------------------------- 831 // Security Command Class Related (Version 1.1) 832 //----------------------------------------------------------------------------- 833 public: 834 aes_encrypt_ctx *GetAuthKey(); 835 aes_encrypt_ctx *GetEncKey(); 836 bool isNetworkKeySet(); 837 838 private: 839 bool initNetworkKeys(bool newnode); 840 uint8 *GetNetworkKey(); 841 bool SendEncryptedMessage(); 842 bool SendNonceRequest(string logmsg); 843 void SendNonceKey(uint8 nodeId, uint8 *nonce); 844 aes_encrypt_ctx *AuthKey; 845 aes_encrypt_ctx *EncryptKey; 846 uint8 m_nonceReportSent; 847 uint8 m_nonceReportSentAttempt; 848 bool m_inclusionkeySet; 849 850 }; 851 852 } // namespace OpenZWave 853 854 #endif // _Driver_H 855