update esppilight lib
content of the library is not filtered on 433mhz only
This commit is contained in:
1 parent
a275e48ee1
commit
67dd7ac078
1030 files changed
+203335
-116
No files matched your search
@@ -0,0 +1,15 @@
|
||||
project(openzwave_platform)
|
||||
|
||||
file(GLOB ${PROJECT_NAME}_sources "${PROJECT_SOURCE_DIR}/*.cpp")
|
||||
file(GLOB ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/*.h")
|
||||
|
||||
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_sources} ${${PROJECT_NAME}_headers} CACHE INTERNAL "")
|
||||
|
||||
if(WIN32)
|
||||
add_subdirectory(windows)
|
||||
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_windows_files} ${${PROJECT_NAME}_files} CACHE INTERNAL "")
|
||||
else()
|
||||
add_subdirectory(unix)
|
||||
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_unix_files} ${${PROJECT_NAME}_files} CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Controller.cpp
|
||||
//
|
||||
// Cross-platform, hardware-abstracted controller data interface
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../Defs.h"
|
||||
#include "../Driver.h"
|
||||
#include "Controller.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Controller::PlayInitSequence>
|
||||
// Queues up the controller's initialization commands.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Controller::PlayInitSequence
|
||||
(
|
||||
Driver* _driver
|
||||
)
|
||||
{
|
||||
_driver->SendMsg( new Msg( "FUNC_ID_ZW_GET_VERSION", 0xff, REQUEST, FUNC_ID_ZW_GET_VERSION, false ), Driver::MsgQueue_Command );
|
||||
_driver->SendMsg( new Msg( "FUNC_ID_ZW_MEMORY_GET_ID", 0xff, REQUEST, FUNC_ID_ZW_MEMORY_GET_ID, false ), Driver::MsgQueue_Command );
|
||||
_driver->SendMsg( new Msg( "FUNC_ID_ZW_GET_CONTROLLER_CAPABILITIES", 0xff, REQUEST, FUNC_ID_ZW_GET_CONTROLLER_CAPABILITIES, false ), Driver::MsgQueue_Command );
|
||||
_driver->SendMsg( new Msg( "FUNC_ID_SERIAL_API_GET_CAPABILITIES", 0xff, REQUEST, FUNC_ID_SERIAL_API_GET_CAPABILITIES, false ), Driver::MsgQueue_Command );
|
||||
_driver->SendMsg( new Msg( "FUNC_ID_ZW_GET_SUC_NODE_ID", 0xff, REQUEST, FUNC_ID_ZW_GET_SUC_NODE_ID, false ), Driver::MsgQueue_Command );
|
||||
// FUNC_ID_ZW_GET_VIRTUAL_NODES & FUNC_ID_SERIAL_API_GET_INIT_DATA has moved into the handler for FUNC_ID_SERIAL_API_GET_CAPABILITIES
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Controller::Read>
|
||||
// Read from a controller
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 Controller::Read
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _length
|
||||
)
|
||||
{
|
||||
// Fetch the data from the ring buffer (which is an all or nothing read)
|
||||
if( Get( _buffer, _length ) )
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Controller.h
|
||||
//
|
||||
// Cross-platform, hardware-abstracted controller data interface
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _Controller_H
|
||||
#define _Controller_H
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "../Defs.h"
|
||||
#include "../Driver.h"
|
||||
#include "Stream.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Driver;
|
||||
|
||||
class Controller: public Stream
|
||||
{
|
||||
// Controller is derived from Stream rather than containing one, so that
|
||||
// we can use its Wait abilities without having to duplicate them here.
|
||||
// The stream is used for input. Buffering of output is handled by the OS.
|
||||
|
||||
public:
|
||||
/**
|
||||
* Consructor.
|
||||
* Creates the controller object.
|
||||
*/
|
||||
Controller():Stream( 2048 ){}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the controller object.
|
||||
*/
|
||||
virtual ~Controller(){}
|
||||
|
||||
/**
|
||||
* Queues a set of Z-Wave messages in the correct order needed to initialize the Controller implementation.
|
||||
* @param Pointer to the driver object that will handle the messages.
|
||||
* @see Driver::Init
|
||||
*/
|
||||
void PlayInitSequence( Driver* _driver );
|
||||
|
||||
/**
|
||||
* Open a controller.
|
||||
* Attempts to open a controller and initialize it with the specified paramters.
|
||||
* @param _controllerName The name of the port to open. For example, ttyS1 on Linux, or \\.\COM2 in Windows.
|
||||
* @see Close, Read, Write
|
||||
*/
|
||||
virtual bool Open( string const& _controllerName ) = 0;
|
||||
|
||||
/**
|
||||
* Close a controller.
|
||||
* Closes the controller.
|
||||
* @return True if the controller was closed successfully, or false if the controller was already closed, or an error occurred.
|
||||
* @see Open
|
||||
*/
|
||||
virtual bool Close() = 0;
|
||||
|
||||
/**
|
||||
* Write to a controller.
|
||||
* Attempts to write data to an open controller.
|
||||
* @param _buffer Pointer to a block of memory containing the data to be written.
|
||||
* @param _length Length in bytes of the data.
|
||||
* @return The number of bytes written.
|
||||
* @see Read, Open, Close
|
||||
*/
|
||||
virtual uint32 Write( uint8* _buffer, uint32 _length ) = 0;
|
||||
|
||||
/**
|
||||
* Read from a controller.
|
||||
* Attempts to read data from an open controller.
|
||||
* @param _buffer Pointer to a block of memory large enough to hold the requested data.
|
||||
* @param _length Length in bytes of the data to be read.
|
||||
* @return The number of bytes read.
|
||||
* @see Write, Open, Close
|
||||
*/
|
||||
uint32 Read( uint8* _buffer, uint32 _length );
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Controller_H
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Event.cpp
|
||||
//
|
||||
// Cross-platform event
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../Defs.h"
|
||||
#include "Event.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/EventImpl.h" // Platform-specific implementation of an event
|
||||
#else
|
||||
#include "unix/EventImpl.h" // Platform-specific implementation of an event
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::Event>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Event::Event
|
||||
(
|
||||
):
|
||||
m_pImpl( new EventImpl() )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::~Event>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Event::~Event
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::Set>
|
||||
// Set the event to signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void Event::Set
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl->Set();
|
||||
Notify(); // Notify any watchers that the event is now set
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::Reset>
|
||||
// Set the event to not signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void Event::Reset
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl->Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::IsSignalled>
|
||||
// Test whether the event is set
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Event::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_pImpl->IsSignalled();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Event::Wait>
|
||||
// Wait for the event to become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Event::Wait
|
||||
(
|
||||
int32 const _timeout
|
||||
)
|
||||
{
|
||||
return m_pImpl->Wait( _timeout );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Event.h
|
||||
//
|
||||
// Cross-platform manual-reset event
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Event_H
|
||||
#define _Event_H
|
||||
|
||||
#include "Wait.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class EventImpl;
|
||||
|
||||
/** \brief Platform-independent definition of event objects.
|
||||
*/
|
||||
class Event: public Wait
|
||||
{
|
||||
friend class SerialControllerImpl;
|
||||
friend class Wait;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a cross-platform event object equivalent to the Windows manual-reset event
|
||||
*/
|
||||
Event();
|
||||
|
||||
/**
|
||||
* Set the event to signalled.
|
||||
* \see Reset, Wait
|
||||
*/
|
||||
void Set();
|
||||
|
||||
/**
|
||||
* Set the event to not signalled.
|
||||
* \see Set, Wait
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Used by the Wait class to test whether the event is set.
|
||||
*/
|
||||
virtual bool IsSignalled();
|
||||
|
||||
/**
|
||||
* Used by the Wait::Multiple method.
|
||||
* returns true if the event signalled, false if it timed out
|
||||
*/
|
||||
bool Wait( int32 _timeout );
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the event object.
|
||||
*/
|
||||
~Event();
|
||||
|
||||
private:
|
||||
Event( Event const& ); // prevent copy
|
||||
Event& operator = ( Event const& ); // prevent assignment
|
||||
|
||||
EventImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of a event.
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Event_H
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOps.cpp
|
||||
//
|
||||
// Cross-platform File Operations
|
||||
//
|
||||
// Copyright (c) 2012 Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
#include "FileOps.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/FileOpsImpl.h" // Platform-specific implementation of a File Operations
|
||||
#else
|
||||
#include "unix/FileOpsImpl.h" // Platform-specific implementation of a File Operations
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
FileOps* FileOps::s_instance = NULL;
|
||||
FileOpsImpl* FileOps::m_pImpl = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOps::Create>
|
||||
// Static creation of the singleton
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOps* FileOps::Create
|
||||
(
|
||||
)
|
||||
{
|
||||
if( s_instance == NULL )
|
||||
{
|
||||
s_instance = new FileOps();
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOps::Destroy>
|
||||
// Static method to destroy the fileops singleton.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FileOps::Destroy
|
||||
(
|
||||
)
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOps::FolderExists>
|
||||
// Static method to check for existance of a folder
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FileOps::FolderExists
|
||||
(
|
||||
const string &_folderName
|
||||
)
|
||||
{
|
||||
if( s_instance != NULL )
|
||||
{
|
||||
return s_instance->m_pImpl->FolderExists( _folderName );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOps::FileOps>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOps::FileOps
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl = new FileOpsImpl();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOps::~FileOps>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOps::~FileOps
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOps.h
|
||||
//
|
||||
// Cross-platform File Operations
|
||||
//
|
||||
// Copyright (c) 2012 Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _FileOps_H
|
||||
#define _FileOps_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class FileOpsImpl;
|
||||
|
||||
/** \brief Implements platform-independent File Operations.
|
||||
*/
|
||||
class FileOps
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a FileOps cross-platform singleton.
|
||||
* \return a pointer to the file operations object.
|
||||
* \see Destroy.
|
||||
*/
|
||||
static FileOps* Create();
|
||||
|
||||
/**
|
||||
* Destroys the FileOps singleton.
|
||||
* \see Create.
|
||||
*/
|
||||
static void Destroy();
|
||||
|
||||
/**
|
||||
* FolderExists. Check for the existance of a folder.
|
||||
* \param string. Folder name.
|
||||
* \return Bool value indicating existance.
|
||||
*/
|
||||
static bool FolderExists( const string &_folderName );
|
||||
|
||||
private:
|
||||
FileOps();
|
||||
~FileOps();
|
||||
|
||||
static FileOpsImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of the FileOps.
|
||||
static FileOps* s_instance;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_FileOps_H
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Log.cpp
|
||||
//
|
||||
// Cross-platform message and error logging
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../Defs.h"
|
||||
#include "Mutex.h"
|
||||
#include "Log.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/LogImpl.h" // Platform-specific implementation of a log
|
||||
#else
|
||||
#include "unix/LogImpl.h" // Platform-specific implementation of a log
|
||||
#endif
|
||||
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
char const *OpenZWave::LogLevelString[] =
|
||||
{
|
||||
"None", /**< LogLevel_None Disable all logging */
|
||||
"Always", /**< LogLevel_Always These messages should always be shown */
|
||||
"Fatal", /**< LogLevel_Fatal A likely fatal issue in the library */
|
||||
"Error", /**< LogLevel_Error A serious issue with the library or the network */
|
||||
"Warning", /**< LogLevel_Warning A minor issue from which the library should be able to recover */
|
||||
"Alert", /**< LogLevel_Alert Something unexpected by the library about which the controlling application should be aware */
|
||||
"Info", /**< LogLevel_Info Everything's working fine...these messages provide streamlined feedback on each message */
|
||||
"Detail", /**< LogLevel_Detail Detailed information on the progress of each message */
|
||||
"Debug", /**< LogLevel_Debug Very detailed information on progress that will create a huge log file quickly
|
||||
But this level (as others) can be queued and sent to the log only on an error or warning */
|
||||
"StreamDetail", /**< LogLevel_StreamDetail Will include low-level byte transfers from controller to buffer to application and back */
|
||||
"Internal" /**< LogLevel_Internal Used only within the log class (uses existing timestamp, etc.) */
|
||||
};
|
||||
|
||||
|
||||
|
||||
Log* Log::s_instance = NULL;
|
||||
i_LogImpl* Log::m_pImpl = NULL;
|
||||
static bool s_dologging;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Create>
|
||||
// Static creation of the singleton
|
||||
//-----------------------------------------------------------------------------
|
||||
Log* Log::Create
|
||||
(
|
||||
string const& _filename,
|
||||
bool const _bAppend,
|
||||
bool const _bConsoleOutput,
|
||||
LogLevel const _saveLevel,
|
||||
LogLevel const _queueLevel,
|
||||
LogLevel const _dumpTrigger
|
||||
)
|
||||
{
|
||||
if( NULL == s_instance )
|
||||
{
|
||||
s_instance = new Log( _filename, _bAppend, _bConsoleOutput, _saveLevel, _queueLevel, _dumpTrigger );
|
||||
s_dologging = true; // default logging to true so no change to what people experience now
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Create>
|
||||
// Static creation of the singleton
|
||||
//-----------------------------------------------------------------------------
|
||||
/* It isn't clear this is ever called or used. If no one complains, consider
|
||||
deleting this code in April 2012.
|
||||
Log* Log::Create
|
||||
(
|
||||
i_LogImpl *LogClass
|
||||
)
|
||||
{
|
||||
if (NULL == s_instance )
|
||||
{
|
||||
s_instance = new Log( "" );
|
||||
s_dologging = true;
|
||||
}
|
||||
SetLoggingClass( LogClass );
|
||||
return s_instance;
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Destroy>
|
||||
// Static method to destroy the logging singleton.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::Destroy
|
||||
(
|
||||
)
|
||||
{
|
||||
delete s_instance;
|
||||
s_instance = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::SetLoggingClass>
|
||||
// Set log class
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Log::SetLoggingClass
|
||||
(
|
||||
i_LogImpl *LogClass
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
m_pImpl = LogClass;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::SetLoggingState>
|
||||
// Set flag to actually write to log or skip it (legacy version)
|
||||
// If logging is enabled, the default log detail settings will be used
|
||||
// Write to file/screen LogLevel_Detail
|
||||
// Save in queue for errors LogLevel_Debug
|
||||
// Trigger for dumping queue LogLevel_Warning
|
||||
// Console output? Yes
|
||||
// Append to an existing log? No (overwrite)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::SetLoggingState
|
||||
(
|
||||
bool _dologging
|
||||
)
|
||||
{
|
||||
bool prevLogging = s_dologging;
|
||||
s_dologging = _dologging;
|
||||
|
||||
if (!prevLogging && s_dologging) Log::Write(LogLevel_Always, "Logging started\n\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::SetLoggingState>
|
||||
// Set flag to actually write to log or skip it
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::SetLoggingState
|
||||
(
|
||||
LogLevel _saveLevel,
|
||||
LogLevel _queueLevel,
|
||||
LogLevel _dumpTrigger
|
||||
)
|
||||
{
|
||||
// parameter checking:
|
||||
// _queueLevel cannot be less than or equal to _saveLevel (where lower ordinals are more severe conditions)
|
||||
// _dumpTrigger cannot be greater than or equal to _queueLevel
|
||||
if( _queueLevel <= _saveLevel )
|
||||
Log::Write( LogLevel_Warning, "Only lower priority messages may be queued for error-driven display." );
|
||||
if( _dumpTrigger >= _queueLevel )
|
||||
Log::Write( LogLevel_Warning, "The trigger for dumping queued messages must be a higher-priority message than the level that is queued." );
|
||||
|
||||
bool prevLogging = s_dologging;
|
||||
// s_dologging is true if any messages are to be saved in file or queue
|
||||
if( (_saveLevel > LogLevel_Always) ||
|
||||
(_queueLevel > LogLevel_Always) )
|
||||
{
|
||||
s_dologging = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_dologging = false;
|
||||
}
|
||||
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
s_instance->m_logMutex->Lock();
|
||||
s_instance->m_pImpl->SetLoggingState( _saveLevel, _queueLevel, _dumpTrigger );
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
|
||||
if (!prevLogging && s_dologging) Log::Write(LogLevel_Always, "Logging started\n\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::GetLoggingState>
|
||||
// Return a flag to indicate whether logging is enabled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Log::GetLoggingState
|
||||
(
|
||||
)
|
||||
{
|
||||
return s_dologging;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Write>
|
||||
// Write to the log
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::Write
|
||||
(
|
||||
LogLevel _level,
|
||||
char const* _format,
|
||||
...
|
||||
)
|
||||
{
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
s_instance->m_logMutex->Lock(); // double locks if recursive
|
||||
va_list args;
|
||||
va_start( args, _format );
|
||||
s_instance->m_pImpl->Write( _level, 0, _format, args );
|
||||
va_end( args );
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Write>
|
||||
// Write to the log
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::Write
|
||||
(
|
||||
LogLevel _level,
|
||||
uint8 const _nodeId,
|
||||
char const* _format,
|
||||
...
|
||||
)
|
||||
{
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
if( _level != LogLevel_Internal )
|
||||
s_instance->m_logMutex->Lock();
|
||||
va_list args;
|
||||
va_start( args, _format );
|
||||
s_instance->m_pImpl->Write( _level, _nodeId, _format, args );
|
||||
va_end( args );
|
||||
if( _level != LogLevel_Internal )
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::QueueDump>
|
||||
// Send queued messages to the log (and empty the queue)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::QueueDump
|
||||
(
|
||||
)
|
||||
{
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
s_instance->m_logMutex->Lock();
|
||||
s_instance->m_pImpl->QueueDump();
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::QueueClear>
|
||||
// Empty the queued message queue
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::QueueClear
|
||||
(
|
||||
)
|
||||
{
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
s_instance->m_logMutex->Lock();
|
||||
s_instance->m_pImpl->QueueClear();
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::SetLogFileName>
|
||||
// Change the name of the log file (will start writing a new file)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Log::SetLogFileName
|
||||
(
|
||||
const string &_filename
|
||||
)
|
||||
{
|
||||
if( s_instance && s_dologging && s_instance->m_pImpl )
|
||||
{
|
||||
s_instance->m_logMutex->Lock();
|
||||
s_instance->m_pImpl->SetLogFileName( _filename );
|
||||
s_instance->m_logMutex->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::Log>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Log::Log
|
||||
(
|
||||
string const& _filename,
|
||||
bool const _bAppend,
|
||||
bool const _bConsoleOutput,
|
||||
LogLevel const _saveLevel,
|
||||
LogLevel const _queueLevel,
|
||||
LogLevel const _dumpTrigger
|
||||
):
|
||||
m_logMutex( new Mutex() )
|
||||
{
|
||||
if (NULL == m_pImpl)
|
||||
m_pImpl = new LogImpl( _filename, _bAppend, _bConsoleOutput, _saveLevel, _queueLevel, _dumpTrigger );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Log::~Log>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Log::~Log
|
||||
(
|
||||
)
|
||||
{
|
||||
m_logMutex->Release();
|
||||
delete m_pImpl;
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Log.h
|
||||
//
|
||||
// Cross-platform message and error logging
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Log_H
|
||||
#define _Log_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "../Defs.h"
|
||||
|
||||
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Mutex;
|
||||
extern char const *LogLevelString[];
|
||||
enum LogLevel
|
||||
{
|
||||
LogLevel_None, /**< Disable all logging */
|
||||
LogLevel_Always, /**< These messages should always be shown */
|
||||
LogLevel_Fatal, /**< A likely fatal issue in the library */
|
||||
LogLevel_Error, /**< A serious issue with the library or the network */
|
||||
LogLevel_Warning, /**< A minor issue from which the library should be able to recover */
|
||||
LogLevel_Alert, /**< Something unexpected by the library about which the controlling application should be aware */
|
||||
LogLevel_Info, /**< Everything's working fine...these messages provide streamlined feedback on each message */
|
||||
LogLevel_Detail, /**< Detailed information on the progress of each message */
|
||||
LogLevel_Debug, /**< Very detailed information on progress that will create a huge log file quickly
|
||||
But this level (as others) can be queued and sent to the log only on an error or warning */
|
||||
LogLevel_StreamDetail, /**< Will include low-level byte transfers from controller to buffer to application and back */
|
||||
LogLevel_Internal /**< Used only within the log class (uses existing timestamp, etc.) */
|
||||
};
|
||||
|
||||
class i_LogImpl
|
||||
{
|
||||
public:
|
||||
i_LogImpl() { } ;
|
||||
virtual ~i_LogImpl() { } ;
|
||||
virtual void Write( LogLevel _level, uint8 const _nodeId, char const* _format, va_list _args ) = 0;
|
||||
virtual void QueueDump() = 0;
|
||||
virtual void QueueClear() = 0;
|
||||
virtual void SetLoggingState( LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger ) = 0;
|
||||
virtual void SetLogFileName( const string &_filename ) = 0;
|
||||
};
|
||||
|
||||
/** \brief Implements a platform-independent log...written to the console and, optionally, a file.
|
||||
*/
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a log.
|
||||
* Creates the cross-platform logging singleton.
|
||||
* Any previous log will be cleared.
|
||||
* \return a pointer to the logging object.
|
||||
* \see Destroy, Write
|
||||
*/
|
||||
static Log* Create( string const& _filename, bool const _bAppend, bool const _bConsoleOutput, LogLevel const _saveLevel, LogLevel const _queueLevel, LogLevel const _dumpTrigger );
|
||||
|
||||
/**
|
||||
* Create a log.
|
||||
* Creates the cross-platform logging singleton.
|
||||
* Any previous log will be cleared.
|
||||
* \param LogClass a Logging Class that inherits the i_LogImpl Class to use to Log
|
||||
* \return a pointer to the logging object.
|
||||
* \see Destroy, Write
|
||||
*/
|
||||
|
||||
static Log* Create( i_LogImpl *LogClass );
|
||||
|
||||
/**
|
||||
* Destroys the log.
|
||||
* Destroys the logging singleton. The log can no longer
|
||||
* be written to without another call to Create.
|
||||
* \see Create, Write
|
||||
*/
|
||||
static void Destroy();
|
||||
|
||||
/**
|
||||
* \brief Set the Logging Implmentation Class to replace the standard File/Console Loggin
|
||||
* \param LogClass A Logging Class that inherits the i_LogImpl Class used to Log to
|
||||
* \return Bool Value indicating success or failure
|
||||
*/
|
||||
static bool SetLoggingClass(i_LogImpl *LogClass );
|
||||
|
||||
/**
|
||||
* \brief Enable or disable library logging (retained for backward compatibility)
|
||||
* \param _dologging If true, logging is enabled; if false, disabled
|
||||
*/
|
||||
static void SetLoggingState(bool _dologging);
|
||||
|
||||
/**
|
||||
* \brief Enable or disable library logging. To disable, set _saveLevel and _queueLevel
|
||||
* to LogLevel_None.
|
||||
* \param _saveLevel LogLevel of messages to write in real-time
|
||||
* \param _queueLevel LogLevel of messages to queue to be dumped in case of an error
|
||||
* \param _dumpTrigger LogLevel of message that triggers a queue dump (probably LogLevel_Error or LogLevel_Warning)
|
||||
*/
|
||||
static void SetLoggingState( LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger );
|
||||
|
||||
/**
|
||||
* \brief Determine whether logging is enabled or not (retained for backward compatibility)
|
||||
* \param _dologging If true, logging is enabled; if false, disabled
|
||||
*/
|
||||
static bool GetLoggingState();
|
||||
|
||||
/**
|
||||
* \brief Obtain the various logging levels.
|
||||
* \param _saveLevel LogLevel of messages to write in real-time
|
||||
* \param _queueLevel LogLevel of messages to queue to be dumped in case of an error
|
||||
* \param _dumpTrigger LogLevel of message that triggers a queue dump (probably LogLevel_Error or LogLevel_Warning)
|
||||
*/
|
||||
static void GetLoggingState( LogLevel* _saveLevel, LogLevel* _queueLevel, LogLevel* _dumpTrigger );
|
||||
|
||||
/**
|
||||
* \brief Change the log file name. This will start a new log file (or potentially start appending
|
||||
* information to an existing one. Developers might want to use this function, together with a timer
|
||||
* in the controlling application, to create timestamped log file names.
|
||||
* \param _filename Name of the new (or existing) file to use for log output.
|
||||
*/
|
||||
static void SetLogFileName( const string &_filename );
|
||||
|
||||
/**
|
||||
* Write an entry to the log.
|
||||
* Writes a formatted string to the log.
|
||||
* \param _level Specifies the type of log message (Error, Warning, Debug, etc.)
|
||||
* \param _format. A string formatted in the same manner as used with printf etc.
|
||||
* \param ... a variable number of arguments, to be included in the formatted string.
|
||||
* \see Create, Destroy
|
||||
*/
|
||||
static void Write( LogLevel _level, char const* _format, ... );
|
||||
|
||||
/**
|
||||
* Write an entry to the log.
|
||||
* Writes a formatted string to the log.
|
||||
* \param _level Specifies the type of log message (Error, Warning, Debug, etc.)
|
||||
* \param _nodeId Node Id this entry is about.
|
||||
* \param _format. A string formatted in the same manner as used with printf etc.
|
||||
* \param ... a variable number of arguments, to be included in the formatted string.
|
||||
* \see Create, Destroy
|
||||
*/
|
||||
static void Write( LogLevel _level, uint8 const _nodeId, char const* _format, ... );
|
||||
|
||||
/**
|
||||
* Send the queued log messages to the log output.
|
||||
*/
|
||||
static void QueueDump();
|
||||
|
||||
/**
|
||||
* Clear the log message queue
|
||||
*/
|
||||
static void QueueClear();
|
||||
|
||||
private:
|
||||
Log( string const& _filename, bool const _bAppend, bool const _bConsoleOutput, LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger );
|
||||
~Log();
|
||||
|
||||
static i_LogImpl* m_pImpl; /**< Pointer to an object that encapsulates the platform-specific logging implementation. */
|
||||
static Log* s_instance;
|
||||
Mutex* m_logMutex;
|
||||
};
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Log_H
|
||||
@@ -0,0 +1,101 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Mutex.cpp
|
||||
//
|
||||
// Cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../Defs.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/MutexImpl.h" // Platform-specific implementation of a mutex
|
||||
#else
|
||||
#include "unix/MutexImpl.h" // Platform-specific implementation of a mutex
|
||||
#endif
|
||||
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Mutex::Mutex>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Mutex::Mutex
|
||||
(
|
||||
):
|
||||
m_pImpl( new MutexImpl() )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Mutex::~Mutex>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Mutex::~Mutex
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Mutex::Lock>
|
||||
// Lock the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Mutex::Lock
|
||||
(
|
||||
bool const _bWait // = true;
|
||||
)
|
||||
{
|
||||
return m_pImpl->Lock( _bWait );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Mutex::Unlock>
|
||||
// Release our lock on the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
void Mutex::Unlock
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl->Unlock();
|
||||
|
||||
if( IsSignalled() )
|
||||
{
|
||||
// The mutex has no owners, so notify the watchers
|
||||
Notify();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Mutex::IsSignalled>
|
||||
// Test whether the event is set
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Mutex::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_pImpl->IsSignalled();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Mutex.h
|
||||
//
|
||||
// Cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Mutex_H
|
||||
#define _Mutex_H
|
||||
|
||||
#include "Wait.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class MutexImpl;
|
||||
|
||||
/** \brief Implements a platform-independent mutex--for serializing access to a shared resource.
|
||||
*/
|
||||
class Mutex: public Wait
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a mutex object that can be used to serialize access to a shared resource.
|
||||
*/
|
||||
Mutex();
|
||||
|
||||
/**
|
||||
* Lock the mutex.
|
||||
* Attempts to lock the mutex.
|
||||
* There must be a matching call to Release for every call to Lock.
|
||||
* \param _bWait Defaults to true. Set this argument to false if the method should return
|
||||
* immediately, even if the lock is not available.
|
||||
* \return True if the lock was obtained.
|
||||
* \see Release
|
||||
*/
|
||||
bool Lock( bool const _bWait = true );
|
||||
|
||||
/**
|
||||
* Releases the lock on the mutex.
|
||||
* There must be a matching call to Release for every call to Lock.
|
||||
* \see Lock
|
||||
*/
|
||||
void Unlock();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Used by the Wait class to test whether the mutex is free.
|
||||
*/
|
||||
virtual bool IsSignalled();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the mutex object.
|
||||
*/
|
||||
~Mutex();
|
||||
|
||||
private:
|
||||
Mutex( Mutex const& ); // prevent copy
|
||||
Mutex& operator = ( Mutex const& ); // prevent assignment
|
||||
|
||||
MutexImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of a mutex.
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Mutex_H
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Ref.h
|
||||
//
|
||||
// Reference counting for objects.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Ref_H
|
||||
#define _Ref_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/**
|
||||
* Provides reference counting for objects.
|
||||
* Any class wishing to include reference counting should be derived from Ref.
|
||||
* Derived classes must declare their destructor as protected virtual.
|
||||
* On construction, the reference count is set to one. Calls to AddRef increment
|
||||
* the count. Calls to Release decrement the count. When the count reaches
|
||||
* zero, the object is deleted.
|
||||
*/
|
||||
class Ref
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes the RefCount to one. The object
|
||||
* can only be deleted through a call to Release.
|
||||
* \see AddRef, Release
|
||||
*/
|
||||
Ref(){ m_refs = 1; }
|
||||
|
||||
/**
|
||||
* Increases the reference count of the object.
|
||||
* Every call to AddRef requires a matching call
|
||||
* to Release before the object will be deleted.
|
||||
* \see Release
|
||||
*/
|
||||
void AddRef(){ ++m_refs; }
|
||||
|
||||
/**
|
||||
* Removes a reference to an object.
|
||||
* If this was the last reference to the message, the
|
||||
* object is deleted.
|
||||
* \see AddRef
|
||||
*/
|
||||
int32 Release()
|
||||
{
|
||||
if( 0 >= ( --m_refs ) )
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_refs;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~Ref(){}
|
||||
|
||||
private:
|
||||
// Reference counting
|
||||
int32 m_refs;
|
||||
|
||||
}; // class Ref
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif // _Ref_H
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SerialController.h
|
||||
//
|
||||
// Cross-platform serial port handler
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../Msg.h"
|
||||
#include "Event.h"
|
||||
#include "Thread.h"
|
||||
#include "SerialController.h"
|
||||
#include "Log.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/SerialControllerImpl.h" // Platform-specific implementation of a serial port
|
||||
#else
|
||||
#include "unix/SerialControllerImpl.h" // Platform-specific implementation of a serial port
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::SerialController>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialController::SerialController
|
||||
(
|
||||
):
|
||||
m_baud ( 115200 ),
|
||||
m_parity ( SerialController::Parity_None ),
|
||||
m_stopBits ( SerialController::StopBits_One ),
|
||||
m_bOpen( false )
|
||||
{
|
||||
m_pImpl = new SerialControllerImpl( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::~SerialController>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialController::~SerialController
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::SetBaud>
|
||||
// Set the serial port baud rate.
|
||||
// The serial port must be closed for the setting to be accepted.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialController::SetBaud
|
||||
(
|
||||
uint32 const _baud
|
||||
)
|
||||
{
|
||||
if( m_bOpen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_baud = _baud;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::SetParity>
|
||||
// Set the serial port parity.
|
||||
// The serial port must be closed for the setting to be accepted.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialController::SetParity
|
||||
(
|
||||
Parity const _parity
|
||||
)
|
||||
{
|
||||
if( m_bOpen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_parity = _parity;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::SetStopBits>
|
||||
// Set the serial port stop bits.
|
||||
// The serial port must be closed for the setting to be accepted.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialController::SetStopBits
|
||||
(
|
||||
StopBits const _stopBits
|
||||
)
|
||||
{
|
||||
if( m_bOpen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stopBits = _stopBits;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::Open>
|
||||
// Open and configure a serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialController::Open
|
||||
(
|
||||
string const& _serialControllerName
|
||||
)
|
||||
{
|
||||
if( m_bOpen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_serialControllerName = _serialControllerName;
|
||||
m_bOpen = m_pImpl->Open();
|
||||
return m_bOpen;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::Close>
|
||||
// Close a serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialController::Close
|
||||
(
|
||||
)
|
||||
{
|
||||
if( !m_bOpen )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pImpl->Close();
|
||||
m_bOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialController::Write>
|
||||
// Write data to an open serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 SerialController::Write
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _length
|
||||
)
|
||||
{
|
||||
if( !m_bOpen )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Log::Write( LogLevel_StreamDetail, " SerialController::Write (sent to controller)" );
|
||||
LogData(_buffer, _length, " Write: ");
|
||||
|
||||
return( m_pImpl->Write( _buffer, _length ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SerialController.h
|
||||
//
|
||||
// Cross-platform serial port handler
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SerialController_H
|
||||
#define _SerialController_H
|
||||
|
||||
#include <string>
|
||||
#include "../Defs.h"
|
||||
#include "Controller.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Driver;
|
||||
class Msg;
|
||||
class SerialControllerImpl;
|
||||
|
||||
class SerialController: public Controller
|
||||
{
|
||||
friend class SerialControllerImpl;
|
||||
|
||||
public:
|
||||
enum Parity
|
||||
{
|
||||
Parity_None = 0,
|
||||
Parity_Odd,
|
||||
Parity_Even,
|
||||
Parity_Mark,
|
||||
Parity_Space
|
||||
};
|
||||
|
||||
enum StopBits
|
||||
{
|
||||
StopBits_One = 0,
|
||||
StopBits_OneAndAHalf = 1,
|
||||
StopBits_Two = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates an object that represents a serial port.
|
||||
*/
|
||||
SerialController();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the serial port object.
|
||||
*/
|
||||
virtual ~SerialController();
|
||||
|
||||
/**
|
||||
* Set the serial port baud rate. The serial port must be closed for the setting to be accepted.
|
||||
* @param _baud Integer containing the expected baud-rate of the serial connection. Most Z-Wave interfaces run at 115200 baud.
|
||||
* @return True if the baud value was accepted.
|
||||
* @see Open, Close
|
||||
*/
|
||||
bool SetBaud( uint32 const _baud );
|
||||
|
||||
/**
|
||||
* Set the serial port parity. The serial port must be closed for the setting to be accepted.
|
||||
* @param _parity Parity enum value indicating the serial data's expected type of parity bits, if any.
|
||||
* @return True if the parity value was accepted.
|
||||
* @see Open, Close
|
||||
*/
|
||||
bool SetParity( Parity const _parity );
|
||||
|
||||
/**
|
||||
* Set the serial port stop bits. The serial port must be closed for the setting to be accepted.
|
||||
* @param _stopBits StopBits enum value indicating the serial data's expected number of stop-bits.
|
||||
* @return True if the stop bits value was accepted.
|
||||
* @see Open, Close
|
||||
*/
|
||||
bool SetStopBits( StopBits const _stopBits );
|
||||
|
||||
/**
|
||||
* Open a serial port.
|
||||
* Attempts to open a serial port and initialize it with the specified paramters.
|
||||
* @param _SerialControllerName The name of the port to open. For example, ttyS1 on Linux, or \\.\COM2 in Windows.
|
||||
* @return True if the port was opened and configured successfully.
|
||||
* @see Close, Read, Write
|
||||
*/
|
||||
bool Open( string const& _SerialControllerName );
|
||||
|
||||
/**
|
||||
* Close a serial port.
|
||||
* Closes the serial port.
|
||||
* @return True if the port was closed successfully, or false if the port was already closed, or an error occurred.
|
||||
* @see Open
|
||||
*/
|
||||
bool Close();
|
||||
|
||||
/**
|
||||
* Write to a serial port.
|
||||
* Attempts to write data to an open serial port.
|
||||
* @param _buffer Pointer to a block of memory containing the data to be written.
|
||||
* @param _length Length in bytes of the data.
|
||||
* @return The number of bytes written.
|
||||
* @see Read, Open, Close
|
||||
*/
|
||||
uint32 Write( uint8* _buffer, uint32 _length );
|
||||
|
||||
private:
|
||||
uint32 m_baud;
|
||||
SerialController::Parity m_parity;
|
||||
SerialController::StopBits m_stopBits;
|
||||
string m_serialControllerName;
|
||||
|
||||
SerialControllerImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of the serial port.
|
||||
bool m_bOpen;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_SerialController_H
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Stream.h
|
||||
//
|
||||
// Cross-platform circular buffer with signalling
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "Stream.h"
|
||||
#include "Mutex.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::Stream>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Stream::Stream
|
||||
(
|
||||
uint32 _bufferSize
|
||||
):
|
||||
m_bufferSize( _bufferSize ),
|
||||
m_signalSize(1),
|
||||
m_dataSize(0),
|
||||
m_head(0),
|
||||
m_tail(0),
|
||||
m_mutex( new Mutex() )
|
||||
{
|
||||
m_buffer = new uint8[m_bufferSize];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::~Stream>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Stream::~Stream
|
||||
(
|
||||
)
|
||||
{
|
||||
m_mutex->Release();
|
||||
delete [] m_buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::SetSignalThreshold>
|
||||
// Set the amount of data that must be in the buffer for to to be signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void Stream::SetSignalThreshold
|
||||
(
|
||||
uint32 _size
|
||||
)
|
||||
{
|
||||
m_signalSize = _size;
|
||||
if( IsSignalled() )
|
||||
{
|
||||
// We have more data than we are waiting for, so notify the watchers
|
||||
Notify();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::Get>
|
||||
// Remove data from the buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Stream::Get
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _size
|
||||
)
|
||||
{
|
||||
if( m_dataSize < _size )
|
||||
{
|
||||
// There is not enough data in the buffer to fulfill the request
|
||||
Log::Write( LogLevel_Error, "ERROR: Not enough data in stream buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mutex->Lock();
|
||||
if( (m_tail + _size) > m_bufferSize )
|
||||
{
|
||||
// We will have to wrap around
|
||||
uint32 block1 = m_bufferSize - m_tail;
|
||||
uint32 block2 = _size - block1;
|
||||
|
||||
memcpy( _buffer, &m_buffer[m_tail], block1 );
|
||||
memcpy( &_buffer[block1], m_buffer, block2 );
|
||||
m_tail = block2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Requested data is in a contiguous block
|
||||
memcpy( _buffer, &m_buffer[m_tail], _size );
|
||||
m_tail += _size;
|
||||
}
|
||||
|
||||
LogData( _buffer, _size, " Read (buffer->application): ");
|
||||
|
||||
m_dataSize -= _size;
|
||||
m_mutex->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::Put>
|
||||
// Add data to the buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Stream::Put
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _size
|
||||
)
|
||||
{
|
||||
if( (m_bufferSize-m_dataSize) < _size )
|
||||
{
|
||||
// There is not enough space left in the buffer for the data
|
||||
Log::Write( LogLevel_Error, "ERROR: Not enough space in stream buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mutex->Lock();
|
||||
if( (m_head + _size) > m_bufferSize )
|
||||
{
|
||||
// We will have to wrap around
|
||||
uint32 block1 = m_bufferSize - m_head;
|
||||
uint32 block2 = _size - block1;
|
||||
|
||||
memcpy( &m_buffer[m_head], _buffer, block1 );
|
||||
memcpy( m_buffer, &_buffer[block1], block2 );
|
||||
m_head = block2;
|
||||
LogData( m_buffer + m_head - block1, block1, " Read (controller->buffer): ");
|
||||
LogData( m_buffer, block2, " Read (controller->buffer): ");
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is enough space before we reach the end of the buffer
|
||||
memcpy( &m_buffer[m_head], _buffer, _size );
|
||||
m_head += _size;
|
||||
LogData(m_buffer+m_head-_size, _size, " Read (controller->buffer): ");
|
||||
}
|
||||
|
||||
m_dataSize += _size;
|
||||
|
||||
if( IsSignalled() )
|
||||
{
|
||||
// We now have more data than we are waiting for, so notify the watchers
|
||||
Notify();
|
||||
}
|
||||
|
||||
m_mutex->Unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::Purge>
|
||||
// Empty the data buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
void Stream::Purge
|
||||
(
|
||||
)
|
||||
{
|
||||
m_tail = 0;
|
||||
m_head = 0;
|
||||
m_dataSize = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::IsSignalled>
|
||||
// Test whether there is enough data to be signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Stream::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return( m_dataSize >= m_signalSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Stream::LogData>
|
||||
// Format the stream buffer data for log output
|
||||
//-----------------------------------------------------------------------------
|
||||
void Stream::LogData
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _length,
|
||||
const string &_function
|
||||
)
|
||||
{
|
||||
if( !_length ) return;
|
||||
|
||||
string str = "";
|
||||
for( uint32 i=0; i<_length; ++i )
|
||||
{
|
||||
if( i )
|
||||
{
|
||||
str += ", ";
|
||||
}
|
||||
|
||||
char byteStr[8];
|
||||
snprintf( byteStr, sizeof(byteStr), "0x%.2x", _buffer[i] );
|
||||
str += byteStr;
|
||||
}
|
||||
Log::Write( LogLevel_StreamDetail, "%s%s", _function.c_str(), str.c_str() );
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Stream.h
|
||||
//
|
||||
// Cross-platform circular buffer with signalling
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Stream_H
|
||||
#define _Stream_H
|
||||
|
||||
#include "../Defs.h"
|
||||
#include "Wait.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Mutex;
|
||||
|
||||
/** \brief Platform-independent definition of a circular buffer.
|
||||
*/
|
||||
class Stream: public Wait
|
||||
{
|
||||
friend class Wait;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a cross-platform ring buffer object
|
||||
*/
|
||||
Stream( uint32 _bufferSize );
|
||||
|
||||
/**
|
||||
* Set the number of bytes the buffer must contain before it becomes signalled.
|
||||
* Once the threshold is set, the application can use Wait::Single or Wait::Multiple
|
||||
* to wait until the buffer has been filled with the desired amount of data.
|
||||
* \param _size the amoutn of data in bytes that the buffer must contain for it to become signalled.
|
||||
* \see Wait::Single, Wait::Multiple
|
||||
*/
|
||||
void SetSignalThreshold( uint32 _size );
|
||||
|
||||
|
||||
/**
|
||||
* Copies the requested amount of data from the stream, removing it from the stream as it does so.
|
||||
* If there is insufficient data available, the method returns false, and no data is transferred.
|
||||
* \param _buffer pointer to a block of memory that will be filled with the stream data.
|
||||
* \param _size the amount of data in bytes to copy from the stream.
|
||||
* \return true if all the requested data has been copied. False if there was not enough data in
|
||||
* the stream.
|
||||
* \see GetDataSize, Put
|
||||
*/
|
||||
bool Get( uint8* _buffer, uint32 _size );
|
||||
|
||||
/**
|
||||
* Copies the requested amount of data from the buffer into the stream.
|
||||
* If there is insufficient room available in the stream's circular buffer, and no data is transferred.
|
||||
* \param _buffer pointer to a block of memory that will be copied into the stream.
|
||||
* \param _size the amount of data in bytes to copy to the stream.
|
||||
* \return true if all the requested data has been copied. False if there was not enough space in
|
||||
* the stream's circular buffer.
|
||||
* \see Get, GetDataSize
|
||||
*/
|
||||
bool Put( uint8* _buffer, uint32 _size );
|
||||
|
||||
/**
|
||||
* Returns the amount of data in bytes that is stored in the stream.
|
||||
* \return the number of bytes of data in the stream.
|
||||
* \see Get, GetDataSize
|
||||
*/
|
||||
uint32 GetDataSize()const{ return m_dataSize; }
|
||||
|
||||
/**
|
||||
* Empties the stream bytes held in the buffer.
|
||||
* This is called when the library gets out of sync with the controller and sends a "NAK"
|
||||
* to the controller.
|
||||
*/
|
||||
void Purge();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Formats stream buffer data for output to the log.
|
||||
* \param _buffer pointer to the stream buffer "head" location
|
||||
* \param _size number of valid bytes currently in the buffer
|
||||
* \param _function string containing text to display before the data
|
||||
*/
|
||||
void LogData( uint8* _buffer, uint32 _size, const string &_function );
|
||||
|
||||
/**
|
||||
* Used by the Wait class to test whether the buffer contains sufficient data.
|
||||
*/
|
||||
virtual bool IsSignalled();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the ring buffer object.
|
||||
*/
|
||||
~Stream();
|
||||
|
||||
private:
|
||||
Stream( Stream const& ); // prevent copy
|
||||
Stream& operator = ( Stream const& ); // prevent assignment
|
||||
|
||||
uint8* m_buffer;
|
||||
uint32 m_bufferSize;
|
||||
uint32 m_signalSize;
|
||||
uint32 m_dataSize;
|
||||
uint32 m_head;
|
||||
uint32 m_tail;
|
||||
Mutex* m_mutex;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Event_H
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Thread.cpp
|
||||
//
|
||||
// Cross-platform threads
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../Defs.h"
|
||||
#include "Event.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/ThreadImpl.h" // Platform-specific implementation of a thread
|
||||
#else
|
||||
#include "unix/ThreadImpl.h" // Platform-specific implementation of a thread
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::Thread>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Thread::Thread
|
||||
(
|
||||
string const& _name
|
||||
)
|
||||
{
|
||||
m_exitEvent = new Event();
|
||||
m_pImpl = new ThreadImpl( this, _name );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::~Thread>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Thread::~Thread
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
m_exitEvent->Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::Start>
|
||||
// Start a function running on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Thread::Start
|
||||
(
|
||||
pfnThreadProc_t _pfnThreadProc,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
return( m_pImpl->Start( _pfnThreadProc, m_exitEvent, _context ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::Stop>
|
||||
// Stop a function running on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Thread::Stop
|
||||
(
|
||||
)
|
||||
{
|
||||
int32 timeout = 2000; // Give the thread 2 seconds to exit
|
||||
m_exitEvent->Set();
|
||||
|
||||
if( Wait::Single( this, timeout ) < 0 )
|
||||
{
|
||||
// Timed out
|
||||
m_pImpl->Terminate();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::Sleep>
|
||||
// Causes the thread to sleep for the specified number of milliseconds.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Thread::Sleep
|
||||
(
|
||||
uint32 _milliseconds
|
||||
)
|
||||
{
|
||||
return( m_pImpl->Sleep( _milliseconds ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Thread::IsSignalled>
|
||||
// Test whether the event is set
|
||||
//-----------------------------------------------------------------------------
|
||||
bool Thread::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_pImpl->IsSignalled();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Thread.h
|
||||
//
|
||||
// Cross-platform threads
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Thread_H
|
||||
#define _Thread_H
|
||||
|
||||
#include <string>
|
||||
#include "../Defs.h"
|
||||
#include "Wait.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class ThreadImpl;
|
||||
class Event;
|
||||
|
||||
/** \brief Implements a platform-independent thread management class.
|
||||
*/
|
||||
class Thread: public Wait
|
||||
{
|
||||
public:
|
||||
typedef void (*pfnThreadProc_t)( Event* _exitEvent, void* _context );
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a thread object that can be used to serialize access to a shared resource.
|
||||
*/
|
||||
Thread( string const& _name );
|
||||
|
||||
/**
|
||||
* Start running a function on this thread.
|
||||
* Attempts to start a function running on this thread. The call will fail if another
|
||||
* function is already running.
|
||||
* \param _pThreadProc pointer to the function to be run. The function must take a
|
||||
* single void pointer as its only argument, and return void. On entry, the pointer
|
||||
* will be set to the context provided to this Start method.
|
||||
* \param _context pointer allowing any relevant data to be passed to the thread function.
|
||||
* \return True if the function was successfully started.
|
||||
* \see Stop, IsRunning
|
||||
*/
|
||||
bool Start( pfnThreadProc_t _pfnThreadProc, void* _context );
|
||||
|
||||
/**
|
||||
* Stop a function running on this thread.
|
||||
* Attempts to stop a function running on this thread. The call will fail if no
|
||||
* function is running.
|
||||
* \return True if the function was successfully stopped.
|
||||
* \see Start, IsRunning
|
||||
*/
|
||||
bool Stop();
|
||||
|
||||
/**
|
||||
* Causes the thread to sleep for the specified number of milliseconds.
|
||||
* \param _millisecs Number of milliseconds to sleep.
|
||||
*/
|
||||
void Sleep( uint32 _millisecs );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Used by the Wait class to test whether the thread has been completed.
|
||||
*/
|
||||
virtual bool IsSignalled();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the Thread object.
|
||||
*/
|
||||
virtual ~Thread();
|
||||
|
||||
private:
|
||||
ThreadImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of a thread.
|
||||
Event* m_exitEvent;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Thread_H
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStamp.h
|
||||
//
|
||||
// Cross-platform TimeStamp
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
#include "../Defs.h"
|
||||
#include "TimeStamp.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/TimeStampImpl.h" // Platform-specific implementation of a TimeStamp
|
||||
#else
|
||||
#include "unix/TimeStampImpl.h" // Platform-specific implementation of a TimeStamp
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::TimeStamp>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStamp::TimeStamp
|
||||
(
|
||||
):
|
||||
m_pImpl( new TimeStampImpl() )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::~TimeStamp>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStamp::~TimeStamp
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::SetTime>
|
||||
// Sets the timestamp to now, plus an offset in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void TimeStamp::SetTime
|
||||
(
|
||||
int32 _milliseconds // = 0
|
||||
)
|
||||
{
|
||||
m_pImpl->SetTime( _milliseconds );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::TimeRemaining>
|
||||
// Gets the difference between now and the timestamp time in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStamp::TimeRemaining
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_pImpl->TimeRemaining();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::GetAsString>
|
||||
// Return object as a string
|
||||
//-----------------------------------------------------------------------------
|
||||
string TimeStamp::GetAsString
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_pImpl->GetAsString();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStamp::operator->
|
||||
// Overload the subtract operator to get the difference between two
|
||||
// timestamps in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStamp::operator-
|
||||
(
|
||||
TimeStamp const& _other
|
||||
)
|
||||
{
|
||||
return (int32)(m_pImpl - _other.m_pImpl);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStamp.h
|
||||
//
|
||||
// Cross-platform TimeStamp
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _TimeStamp_H
|
||||
#define _TimeStamp_H
|
||||
|
||||
#include "../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class TimeStampImpl;
|
||||
|
||||
/** \brief Implements a platform-independent TimeStamp.
|
||||
*/
|
||||
class OPENZWAVE_EXPORT TimeStamp
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a TimeStamp object.
|
||||
*/
|
||||
TimeStamp();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the TimeStamp object.
|
||||
*/
|
||||
~TimeStamp();
|
||||
|
||||
/**
|
||||
* SetTime. Sets the timestamp to now, plus the offset in milliseconds.
|
||||
* \param _milliseconds optional positive or negative offset from
|
||||
* now in milliseconds. Defaults to zero.
|
||||
*/
|
||||
void SetTime( int32 _milliseconds = 0 );
|
||||
|
||||
/**
|
||||
* TimeRemaining. Gets the difference between now and the timestamp
|
||||
* time in milliseconds.
|
||||
* \return milliseconds remaining until we reach the timestamp. The
|
||||
* return value is negative if the timestamp is in the past.
|
||||
*/
|
||||
int32 TimeRemaining();
|
||||
|
||||
/**
|
||||
* Return as a string for output.
|
||||
* \return string
|
||||
*/
|
||||
string GetAsString();
|
||||
|
||||
/**
|
||||
* Overload the subtract operator to get the difference between
|
||||
* two timestamps in milliseconds.
|
||||
*/
|
||||
int32 operator- ( TimeStamp const& _other );
|
||||
|
||||
private:
|
||||
TimeStamp( TimeStamp const& ); // prevent copy
|
||||
TimeStamp& operator = ( TimeStamp const& ); // prevent assignment
|
||||
|
||||
TimeStampImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of the TimeStamp.
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_TimeStamp_H
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Wait.cpp
|
||||
//
|
||||
// Base class for objects we want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include "../Defs.h"
|
||||
#include "Wait.h"
|
||||
#include "Event.h"
|
||||
#include "Log.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows/WaitImpl.h" // Platform-specific implementation of a Wait object
|
||||
#else
|
||||
#include "unix/WaitImpl.h" // Platform-specific implementation of a Wait object
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
void WaitMultipleCallback( void* _context );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::Wait>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Wait::Wait
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl = new WaitImpl( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::~Wait>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
Wait::~Wait
|
||||
(
|
||||
)
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::AddWatcher>
|
||||
// Add a watcher to our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Wait::AddWatcher
|
||||
(
|
||||
pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
if( !_callback )
|
||||
{
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a ref so our object cannot disappear while being watched
|
||||
AddRef();
|
||||
|
||||
// Add the watcher (platform specific code required here for thread safety)
|
||||
m_pImpl->AddWatcher( _callback, _context );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::RemoveWatcher>
|
||||
// Remove a watcher from our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
void Wait::RemoveWatcher
|
||||
(
|
||||
pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
if( m_pImpl->RemoveWatcher( _callback, _context ) )
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::Notify>
|
||||
// Notify all the watchers that the object has become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void Wait::Notify
|
||||
(
|
||||
)
|
||||
{
|
||||
m_pImpl->Notify();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <Wait::Multiple>
|
||||
// Wait for one of multiple objects to become signalled.
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 Wait::Multiple
|
||||
(
|
||||
Wait** _objects,
|
||||
uint32 _numObjects,
|
||||
int32 _timeout // = -1
|
||||
)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
// Create an event that will be set when any of the objects in the list becomes signalled.
|
||||
Event* waitEvent = new Event();
|
||||
|
||||
// Add a watcher to each object in the list, passing in the event as the context.
|
||||
for( i=0; i<_numObjects; ++i )
|
||||
{
|
||||
_objects[i]->AddWatcher( WaitMultipleCallback, waitEvent );
|
||||
}
|
||||
|
||||
int32 res = -1; // Default to timeout result
|
||||
string str = "";
|
||||
if( waitEvent->Wait( _timeout ) )
|
||||
{
|
||||
// An object was signalled. Run through the list
|
||||
// and see which one it was.
|
||||
for( i=0; i<_numObjects; ++i )
|
||||
{
|
||||
if( _objects[i]->IsSignalled() )
|
||||
{
|
||||
if( res == -1 )
|
||||
res = (int32)i;
|
||||
char buf[15];
|
||||
snprintf(buf, sizeof(buf), "%d, ", i);
|
||||
str += buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Log::Write( LogLevel_Debug, "Wait::Multiple res=%d num=%d >%s", res, _numObjects, str.c_str() );
|
||||
|
||||
// Remove the watchers
|
||||
for( i=0; i<_numObjects; ++i )
|
||||
{
|
||||
_objects[i]->RemoveWatcher( WaitMultipleCallback, waitEvent );
|
||||
}
|
||||
|
||||
// We're done with the event now
|
||||
waitEvent->Release();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitMultipleCallback>
|
||||
// Callback handler for the watchers added during WaitImpl::Multiple
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitMultipleCallback
|
||||
(
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
Event* waitEvent = (Event*)_context;
|
||||
waitEvent->Set();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Wait.h
|
||||
//
|
||||
// Cross-platform abstract base class for objects we
|
||||
// want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _Wait_H
|
||||
#define _Wait_H
|
||||
|
||||
#include <list>
|
||||
#include "Ref.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class WaitImpl;
|
||||
|
||||
/** \brief Platform-independent definition of Wait objects.
|
||||
*/
|
||||
class Wait: public Ref
|
||||
{
|
||||
friend class WaitImpl;
|
||||
friend class ThreadImpl;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
Timeout_Immediate = 0,
|
||||
Timeout_Infinite = -1
|
||||
};
|
||||
|
||||
typedef void (*pfnWaitNotification_t)( void* _context );
|
||||
|
||||
/**
|
||||
* Add a watcher to our object. The watcher will be triggered
|
||||
* by the derived class, when it enters a certain state.
|
||||
* \param _callback pointer to the function that will be called when the wait is over.
|
||||
* \param _context pointer to custom data that will be sent with the callback.
|
||||
*/
|
||||
void AddWatcher( pfnWaitNotification_t _callback, void* _context );
|
||||
|
||||
/**
|
||||
* Remove a watcher from our object. Both the _callback and _context pointers
|
||||
* must match those used in a previous call to AddWatcher.
|
||||
* \param _callback pointer to the function that will be called when the wait is over.
|
||||
* \param _context pointer to custom data that will be sent with the callback.
|
||||
*/
|
||||
void RemoveWatcher( pfnWaitNotification_t _callback, void* _context );
|
||||
|
||||
/**
|
||||
* Wait for a single object to become signalled.
|
||||
* \param _object pointer to the object to wait on.
|
||||
* \param _timeout optional maximum time to wait. Defaults to -1, which means wait forever.
|
||||
* \return zero if the object was signalled, -1 if the wait timed out.
|
||||
*/
|
||||
static int32 Single( Wait* _object, int32 _timeout = -1 ){ return Multiple( &_object, 1, _timeout ); }
|
||||
|
||||
/**
|
||||
* Wait for one of multiple objects to become signalled. If more than one object is in
|
||||
* a signalled state, the lowest array index will be returned.
|
||||
* \param _objects array of pointers to objects to wait on.
|
||||
* \param _numObjects number of objects in the array.
|
||||
* \param _timeout optional maximum time to wait. Defaults to -1, which means wait forever.
|
||||
* \return index into the array of the object that was signalled, -1 if the wait timed out.
|
||||
*/
|
||||
static int32 Multiple( Wait** _objects, uint32 _numObjects, int32 _timeout = -1 );
|
||||
|
||||
protected:
|
||||
Wait();
|
||||
virtual ~Wait();
|
||||
|
||||
/**
|
||||
* Notify the watchers that the object is signalled.
|
||||
*/
|
||||
void Notify();
|
||||
|
||||
/**
|
||||
* Test whether an object is signalled.
|
||||
*/
|
||||
virtual bool IsSignalled() = 0;
|
||||
|
||||
private:
|
||||
Wait( Wait const& ); // prevent copy
|
||||
Wait& operator = ( Wait const& ); // prevent assignment
|
||||
|
||||
WaitImpl* m_pImpl; // Pointer to an object that encapsulates the platform-specific implementation of a Wait object.
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_Wait_H
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
project(openzwave_platform_unix)
|
||||
|
||||
file(GLOB ${PROJECT_NAME}_sources "${PROJECT_SOURCE_DIR}/*.cpp")
|
||||
file(GLOB ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/*.h")
|
||||
|
||||
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_sources} ${${PROJECT_NAME}_headers} CACHE INTERNAL "")
|
||||
@@ -0,0 +1,262 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// EventImpl.cpp
|
||||
//
|
||||
// POSIX implementation of a cross-platform event
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../../Defs.h"
|
||||
#include "EventImpl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::EventImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
EventImpl::EventImpl
|
||||
(
|
||||
):
|
||||
m_manualReset( true ),
|
||||
m_isSignaled( false ),
|
||||
m_waitingThreads( 0 )
|
||||
{
|
||||
pthread_mutexattr_t ma;
|
||||
pthread_mutexattr_init( &ma );
|
||||
pthread_mutexattr_settype( &ma, PTHREAD_MUTEX_ERRORCHECK );
|
||||
pthread_mutex_init( &m_lock, &ma );
|
||||
pthread_mutexattr_destroy( &ma );
|
||||
|
||||
pthread_condattr_t ca;
|
||||
pthread_condattr_init( &ca );
|
||||
pthread_condattr_setpshared( &ca, PTHREAD_PROCESS_PRIVATE );
|
||||
pthread_cond_init( &m_condition, &ca );
|
||||
pthread_condattr_destroy( &ca );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::~EventImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
EventImpl::~EventImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
pthread_mutex_destroy( &m_lock );
|
||||
pthread_cond_destroy( &m_condition );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Set>
|
||||
// Set the event to signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void EventImpl::Set
|
||||
(
|
||||
)
|
||||
{
|
||||
int err = pthread_mutex_lock( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Set lock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
if( m_manualReset )
|
||||
{
|
||||
m_isSignaled = true;
|
||||
err = pthread_cond_broadcast( &m_condition );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Set cond broadcast error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !m_waitingThreads )
|
||||
{
|
||||
m_isSignaled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = pthread_cond_signal( &m_condition );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Set cond signal error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
err = pthread_mutex_unlock( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Set unlock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Reset>
|
||||
// Set the event to not signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void EventImpl::Reset
|
||||
(
|
||||
)
|
||||
{
|
||||
int err = pthread_mutex_lock ( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Reset lock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
m_isSignaled = false;
|
||||
err = pthread_mutex_unlock( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Reset unlock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::IsSignalled>
|
||||
// Test whether the event is set
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EventImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return m_isSignaled;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Wait>
|
||||
// Wait for the event to become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EventImpl::Wait
|
||||
(
|
||||
int32 const _timeout /* milliseconds */
|
||||
)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
int err = pthread_mutex_lock( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Wait lock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
if( m_isSignaled )
|
||||
{
|
||||
if ( !m_manualReset )
|
||||
{
|
||||
m_isSignaled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_waitingThreads;
|
||||
if( _timeout == 0 )
|
||||
{
|
||||
result = m_isSignaled;
|
||||
}
|
||||
else if( _timeout > 0 )
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec abstime;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
abstime.tv_sec = now.tv_sec + (_timeout / 1000);
|
||||
|
||||
// Now add the remainder of our timeout to the microseconds part of 'now'
|
||||
now.tv_usec += (_timeout % 1000) * 1000;
|
||||
|
||||
// Careful now! Did it wrap?
|
||||
while( now.tv_usec >= ( 1000 * 1000 ) )
|
||||
{
|
||||
// Yes it did so bump our seconds and subtract
|
||||
now.tv_usec -= (1000 * 1000);
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
|
||||
abstime.tv_nsec = now.tv_usec * 1000;
|
||||
|
||||
while( !m_isSignaled )
|
||||
{
|
||||
int oldstate;
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
err = pthread_cond_timedwait( &m_condition, &m_lock, &abstime );
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
|
||||
if( err == ETIMEDOUT )
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if( err == 0 )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Wait cond timedwait error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( !m_isSignaled )
|
||||
{
|
||||
int oldstate;
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
err = pthread_cond_wait( &m_condition, &m_lock );
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Wait cond wait error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
--m_waitingThreads;
|
||||
}
|
||||
|
||||
err = pthread_mutex_unlock( &m_lock );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "EventImpl::Wait unlock error %d (%d)\n", errno, err );
|
||||
assert( 0 );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// EventImpl.h
|
||||
//
|
||||
// POSIX implementation of a cross-platform event
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _EventImpl_H
|
||||
#define _EventImpl_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class EventImpl
|
||||
{
|
||||
private:
|
||||
friend class Event;
|
||||
friend class SocketImpl;
|
||||
friend class Wait;
|
||||
|
||||
EventImpl();
|
||||
~EventImpl();
|
||||
|
||||
void Set();
|
||||
void Reset();
|
||||
|
||||
bool Wait( int32 _timeout ); // The wait method is to be used only by the Wait::Multiple method
|
||||
bool IsSignalled();
|
||||
|
||||
pthread_mutex_t m_lock;
|
||||
pthread_cond_t m_condition;
|
||||
bool m_manualReset;
|
||||
bool m_isSignaled;
|
||||
unsigned int m_waitingThreads;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_EventImpl_H
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOpsImpl.cpp
|
||||
//
|
||||
// Unix implementation of file operations
|
||||
//
|
||||
// Copyright (c) 2012, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <dirent.h>
|
||||
#include "FileOpsImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::FileOpsImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOpsImpl::FileOpsImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::~FileOpsImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOpsImpl::~FileOpsImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::FolderExists>
|
||||
// Determine if a folder exists
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FileOpsImpl::FolderExists
|
||||
(
|
||||
string _folderName
|
||||
)
|
||||
{
|
||||
DIR *dirp = opendir( _folderName.c_str() );
|
||||
if( dirp != NULL )
|
||||
{
|
||||
closedir( dirp );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOpsImpl.h
|
||||
//
|
||||
// Unix implementation of file operations
|
||||
//
|
||||
// Copyright (c) 2012, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _FileOpsImpl_H
|
||||
#define _FileOpsImpl_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "../../Defs.h"
|
||||
#include "../FileOps.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class FileOpsImpl
|
||||
{
|
||||
friend class FileOps;
|
||||
|
||||
private:
|
||||
FileOpsImpl();
|
||||
~FileOpsImpl();
|
||||
|
||||
bool FolderExists( string _filename );
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_FileOpsImpl_H
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// LogImpl.cpp
|
||||
//
|
||||
// Unix implementation of message and error logging
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include "../../Defs.h"
|
||||
#include "LogImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::LogImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LogImpl::LogImpl
|
||||
(
|
||||
string const& _filename,
|
||||
bool const _bAppendLog,
|
||||
bool const _bConsoleOutput,
|
||||
LogLevel const _saveLevel,
|
||||
LogLevel const _queueLevel,
|
||||
LogLevel const _dumpTrigger
|
||||
):
|
||||
m_filename( _filename ), // name of log file
|
||||
m_bConsoleOutput( _bConsoleOutput ), // true to provide a copy of output to console
|
||||
m_bAppendLog( _bAppendLog ), // true to append (and not overwrite) any existing log
|
||||
m_saveLevel( _saveLevel ), // level of messages to log to file
|
||||
m_queueLevel( _queueLevel ), // level of messages to log to queue
|
||||
m_dumpTrigger( _dumpTrigger ) // dump queued messages when this level is seen
|
||||
{
|
||||
if ( !m_bAppendLog )
|
||||
{
|
||||
this->pFile = fopen( m_filename.c_str(), "w" );
|
||||
} else {
|
||||
this->pFile = fopen( m_filename.c_str(), "a" );
|
||||
}
|
||||
if( this->pFile == NULL )
|
||||
{
|
||||
std::cerr << "Could Not Open OZW Log File." << std::endl;
|
||||
}
|
||||
setlinebuf(stdout); // To prevent buffering and lock contention issues
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::~LogImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LogImpl::~LogImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
fclose( this->pFile );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Write>
|
||||
// Write to the log
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::Write
|
||||
(
|
||||
LogLevel _logLevel,
|
||||
uint8 const _nodeId,
|
||||
char const* _format,
|
||||
va_list _args
|
||||
)
|
||||
{
|
||||
// create a timestamp string
|
||||
string timeStr = GetTimeStampString();
|
||||
string nodeStr = GetNodeString( _nodeId );
|
||||
string loglevelStr = GetLogLevelString(_logLevel);
|
||||
|
||||
// handle this message
|
||||
if( (_logLevel <= m_queueLevel) || (_logLevel == LogLevel_Internal) ) // we're going to do something with this message...
|
||||
{
|
||||
char lineBuf[1024] = {0};
|
||||
//int lineLen = 0;
|
||||
if( _format != NULL && _format[0] != '\0' )
|
||||
{
|
||||
va_list saveargs;
|
||||
va_copy( saveargs, _args );
|
||||
|
||||
vsnprintf( lineBuf, sizeof(lineBuf), _format, _args );
|
||||
va_end( saveargs );
|
||||
}
|
||||
|
||||
// should this message be saved to file (and possibly written to console?)
|
||||
if( (_logLevel <= m_saveLevel) || (_logLevel == LogLevel_Internal) )
|
||||
{
|
||||
std::string outBuf;
|
||||
|
||||
if ( this->pFile != NULL || m_bConsoleOutput )
|
||||
{
|
||||
if( _logLevel != LogLevel_Internal ) // don't add a second timestamp to display of queued messages
|
||||
{
|
||||
outBuf.append(timeStr);
|
||||
outBuf.append(loglevelStr);
|
||||
outBuf.append(nodeStr);
|
||||
outBuf.append(lineBuf);
|
||||
outBuf.append("\n");
|
||||
|
||||
}
|
||||
|
||||
// print message to file (and possibly screen)
|
||||
if( this->pFile != NULL )
|
||||
{
|
||||
fputs( outBuf.c_str(), pFile );
|
||||
}
|
||||
if( m_bConsoleOutput )
|
||||
{
|
||||
fputs( outBuf.c_str(), stdout );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( _logLevel != LogLevel_Internal )
|
||||
{
|
||||
char queueBuf[1024];
|
||||
string threadStr = GetThreadId();
|
||||
snprintf( queueBuf, sizeof(queueBuf), "%s%s%s", timeStr.c_str(), threadStr.c_str(), lineBuf );
|
||||
Queue( queueBuf );
|
||||
}
|
||||
}
|
||||
|
||||
// now check to see if the _dumpTrigger has been hit
|
||||
if( (_logLevel <= m_dumpTrigger) && (_logLevel != LogLevel_Internal) && (_logLevel != LogLevel_Always) )
|
||||
QueueDump();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Queue>
|
||||
// Write to the log queue
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::Queue
|
||||
(
|
||||
char const* _buffer
|
||||
)
|
||||
{
|
||||
string bufStr = _buffer;
|
||||
m_logQueue.push_back( bufStr );
|
||||
|
||||
// rudimentary queue size management
|
||||
if( m_logQueue.size() > 500 )
|
||||
{
|
||||
m_logQueue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::QueueDump>
|
||||
// Dump the LogQueue to output device
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::QueueDump
|
||||
(
|
||||
)
|
||||
{
|
||||
Log::Write( LogLevel_Always, "" );
|
||||
Log::Write( LogLevel_Always, "Dumping queued log messages");
|
||||
Log::Write( LogLevel_Always, "" );
|
||||
list<string>::iterator it = m_logQueue.begin();
|
||||
while( it != m_logQueue.end() )
|
||||
{
|
||||
string strTemp = *it;
|
||||
Log::Write( LogLevel_Internal, strTemp.c_str() );
|
||||
it++;
|
||||
}
|
||||
m_logQueue.clear();
|
||||
Log::Write( LogLevel_Always, "" );
|
||||
Log::Write( LogLevel_Always, "End of queued log message dump");
|
||||
Log::Write( LogLevel_Always, "" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Clear>
|
||||
// Clear the LogQueue
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::QueueClear
|
||||
(
|
||||
)
|
||||
{
|
||||
m_logQueue.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::SetLoggingState>
|
||||
// Sets the various log state variables
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::SetLoggingState
|
||||
(
|
||||
LogLevel _saveLevel,
|
||||
LogLevel _queueLevel,
|
||||
LogLevel _dumpTrigger
|
||||
)
|
||||
{
|
||||
m_saveLevel = _saveLevel;
|
||||
m_queueLevel = _queueLevel;
|
||||
m_dumpTrigger = _dumpTrigger;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetTimeStampString>
|
||||
// Generate a string with formatted current time
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetTimeStampString
|
||||
(
|
||||
)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
char fmt[64], buf[64], line[256];
|
||||
gettimeofday(&tv, NULL);
|
||||
#ifdef _WIN32
|
||||
struct tm *tm1;
|
||||
if((tm1 = gmtime(&tv.tv_sec)) != 0) {
|
||||
memcpy(&tm, tm1, sizeof(struct tm));
|
||||
#else
|
||||
if((gmtime_r(&tv.tv_sec, &tm)) != 0) {
|
||||
#endif
|
||||
strftime(fmt, sizeof(fmt), "%b %d %H:%M:%S", &tm);
|
||||
snprintf(buf, sizeof(buf), "%s:%03u", fmt, (unsigned int)tv.tv_usec);
|
||||
}
|
||||
sprintf(line, "[%22.22s] %s: [Z-Wave]: ", buf, "pilight-daemon");
|
||||
|
||||
string str = line;
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetNodeString>
|
||||
// Generate a string with formatted node id
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetNodeString
|
||||
(
|
||||
uint8 const _nodeId
|
||||
)
|
||||
{
|
||||
if( _nodeId == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
if( _nodeId == 255 ) // should make distinction between broadcast and controller better for SwitchAll broadcast
|
||||
{
|
||||
return "contrlr, ";
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[20];
|
||||
snprintf( buf, sizeof(buf), "Node%03d, ", _nodeId );
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetThreadId>
|
||||
// Generate a string with formatted thread id
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetThreadId
|
||||
(
|
||||
)
|
||||
{
|
||||
char buf[20];
|
||||
snprintf( buf, sizeof(buf), "%08lx ", (long unsigned int)pthread_self() );
|
||||
string str = buf;
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::SetLogFileName>
|
||||
// Provide a new log file name (applicable to future writes)
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::SetLogFileName
|
||||
(
|
||||
const string &_filename
|
||||
)
|
||||
{
|
||||
m_filename = _filename;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetLogLevelString>
|
||||
// Provide a new log file name (applicable to future writes)
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetLogLevelString
|
||||
(
|
||||
LogLevel _level
|
||||
)
|
||||
{
|
||||
if ((_level >= LogLevel_None) && (_level <= LogLevel_Internal)) {
|
||||
char buf[20];
|
||||
snprintf( buf, sizeof(buf), "%s, ", LogLevelString[_level] );
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
return "Unknown, ";
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// LogImpl.h
|
||||
//
|
||||
// Unix implementation of message and error logging
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _LogImpl_H
|
||||
#define _LogImpl_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <list>
|
||||
#include "../Log.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class LogImpl : public i_LogImpl
|
||||
{
|
||||
private:
|
||||
friend class Log;
|
||||
|
||||
LogImpl( string const& _filename, bool const _bAppendLog, bool const _bConsoleOutput, LogLevel const _saveLevel, LogLevel const _queueLevel, LogLevel const _dumpTrigger );
|
||||
~LogImpl();
|
||||
|
||||
void Write( LogLevel _level, uint8 const _nodeId, char const* _format, va_list _args );
|
||||
void Queue( char const* _buffer );
|
||||
void QueueDump();
|
||||
void QueueClear();
|
||||
void SetLoggingState( LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger );
|
||||
void SetLogFileName( const string &_filename );
|
||||
|
||||
string GetTimeStampString();
|
||||
string GetNodeString( uint8 const _nodeId );
|
||||
string GetThreadId();
|
||||
string GetLogLevelString(LogLevel _level);
|
||||
|
||||
string m_filename; /**< filename specified by user (default is ozw_log.txt) */
|
||||
bool m_bConsoleOutput; /**< if true, send log output to console as well as to the file */
|
||||
bool m_bAppendLog; /**< if true, the log file should be appended to any with the same name */
|
||||
list<string> m_logQueue; /**< list of queued log messages */
|
||||
LogLevel m_saveLevel;
|
||||
LogLevel m_queueLevel;
|
||||
LogLevel m_dumpTrigger;
|
||||
FILE* pFile;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_LogImpl_H
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// MutexImpl.cpp
|
||||
//
|
||||
// POSIX implementation of the cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "../Log.h"
|
||||
#include "MutexImpl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::MutexImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MutexImpl::MutexImpl
|
||||
(
|
||||
):
|
||||
m_lockCount( 0 )
|
||||
{
|
||||
pthread_mutexattr_t ma;
|
||||
|
||||
pthread_mutexattr_init ( &ma );
|
||||
pthread_mutexattr_settype( &ma, PTHREAD_MUTEX_RECURSIVE );
|
||||
int err = pthread_mutex_init( &m_criticalSection, &ma );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "MutexImpl::MutexImpl error %d (%d)\n", errno, err );
|
||||
}
|
||||
pthread_mutexattr_destroy( &ma );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::~MutexImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MutexImpl::~MutexImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
pthread_mutex_destroy( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::Lock>
|
||||
// Lock the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MutexImpl::Lock
|
||||
(
|
||||
bool const _bWait
|
||||
)
|
||||
{
|
||||
if( _bWait )
|
||||
{
|
||||
// We will wait for the lock
|
||||
int err = pthread_mutex_lock( &m_criticalSection );
|
||||
if( err == 0 )
|
||||
{
|
||||
++m_lockCount;
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr, "MutexImpl::Lock error %d (%d)\n", errno, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns immediately, even if the lock was not available.
|
||||
if( pthread_mutex_trylock( &m_criticalSection ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++m_lockCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::Unlock>
|
||||
// Release our lock on the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
void MutexImpl::Unlock
|
||||
(
|
||||
)
|
||||
{
|
||||
if( !m_lockCount )
|
||||
{
|
||||
// No locks - we have a mismatched lock/release pair
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
--m_lockCount;
|
||||
int err = pthread_mutex_unlock( &m_criticalSection );
|
||||
if( err != 0 )
|
||||
{
|
||||
fprintf(stderr, "MutexImpl::Unlock error %d (%d)\n", errno, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::IsSignalled>
|
||||
// Test whether the mutex is free
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MutexImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return( 0 == m_lockCount );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// MutexImpl.h
|
||||
//
|
||||
// POSIX implementation of the cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MutexImpl_H
|
||||
#define _MutexImpl_H
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class MutexImpl
|
||||
{
|
||||
private:
|
||||
friend class Mutex;
|
||||
|
||||
MutexImpl();
|
||||
~MutexImpl();
|
||||
|
||||
bool Lock( bool const _bWait = true );
|
||||
void Unlock();
|
||||
|
||||
bool IsSignalled();
|
||||
|
||||
uint32 m_lockCount; // Keep track of the locks (there can be more than one if they occur on the same thread.
|
||||
pthread_mutex_t m_criticalSection;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_MutexIF_H
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SerialControllerImpl.cpp
|
||||
//
|
||||
// POSIX implementation of a cross-platform serial port
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include "../../Defs.h"
|
||||
#include "../Thread.h"
|
||||
#include "../Event.h"
|
||||
#include "SerialControllerImpl.h"
|
||||
#include "../Log.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include "../../libudev.h"
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::SerialControllerImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialControllerImpl::SerialControllerImpl
|
||||
(
|
||||
SerialController* _owner
|
||||
):
|
||||
m_owner( _owner ),
|
||||
m_hSerialController( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::~SerialControllerImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialControllerImpl::~SerialControllerImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
flock(m_hSerialController, LOCK_UN);
|
||||
if(m_hSerialController >= 0)
|
||||
close( m_hSerialController );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Open>
|
||||
// Open the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialControllerImpl::Open
|
||||
(
|
||||
)
|
||||
{
|
||||
// Try to init the serial port
|
||||
if( !Init( 1 ) )
|
||||
{
|
||||
// Failed. We bail to allow the app a chance to take over, rather than retry
|
||||
// automatically. Automatic retries only occur after a successful init.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the read thread
|
||||
m_pThread = new Thread( "SerialController" );
|
||||
m_pThread->Start( SerialReadThreadEntryPoint, this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Close>
|
||||
// Close the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::Close
|
||||
(
|
||||
)
|
||||
{
|
||||
if( m_pThread )
|
||||
{
|
||||
m_pThread->Stop();
|
||||
m_pThread->Release();
|
||||
m_pThread = NULL;
|
||||
}
|
||||
close( m_hSerialController );
|
||||
m_hSerialController = -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialReadThreadEntryPoint>
|
||||
// Entry point of the thread for receiving data from the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::SerialReadThreadEntryPoint
|
||||
(
|
||||
Event* _exitEvent,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
SerialControllerImpl* impl = (SerialControllerImpl*)_context;
|
||||
if( impl )
|
||||
{
|
||||
impl->ReadThreadProc( _exitEvent );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::ReadThreadProc>
|
||||
// Handle receiving data
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::ReadThreadProc
|
||||
(
|
||||
Event* _exitEvent
|
||||
)
|
||||
{
|
||||
uint32 attempts = 0;
|
||||
while( true )
|
||||
{
|
||||
// Init must have been called successfully during Open, so we
|
||||
// don't do it again until the end of the loop
|
||||
if( -1 != m_hSerialController )
|
||||
{
|
||||
// Enter read loop. Call will only return if
|
||||
// an exit is requested or an error occurs
|
||||
Read();
|
||||
|
||||
// Reset the attempts, so we get a rapid retry for temporary errors
|
||||
attempts = 0;
|
||||
}
|
||||
|
||||
if( attempts < 25 )
|
||||
{
|
||||
// Retry every 5 seconds for the first two minutes...
|
||||
if( Wait::Single( _exitEvent, 5000 ) >= 0 )
|
||||
{
|
||||
// Exit signalled.
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...retry every 30 seconds after that
|
||||
if( Wait::Single( _exitEvent, 30000 ) >= 0 )
|
||||
{
|
||||
// Exit signalled.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Init( ++attempts );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Init>
|
||||
// Initialize the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialControllerImpl::Init
|
||||
(
|
||||
uint32 const _attempts
|
||||
)
|
||||
{
|
||||
|
||||
string device = m_owner->m_serialControllerName;
|
||||
|
||||
Log::Write( LogLevel_Info, "Trying to open serial port %s (attempt %d)", device.c_str(), _attempts );
|
||||
|
||||
m_hSerialController = open( device.c_str(), O_RDWR | O_NOCTTY, 0 );
|
||||
|
||||
if( -1 == m_hSerialController )
|
||||
{
|
||||
//Error
|
||||
Log::Write( LogLevel_Error, "ERROR: Cannot open serial port %s. Error code %d", device.c_str(), errno );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
if( flock( m_hSerialController, LOCK_EX | LOCK_NB) == -1 )
|
||||
{
|
||||
Log::Write( LogLevel_Error, "ERROR: Cannot get exclusive lock for serial port %s. Error code %d", device.c_str(), errno );
|
||||
}
|
||||
|
||||
int bits;
|
||||
bits = 0;
|
||||
ioctl( m_hSerialController, TIOCMSET, &bits );
|
||||
|
||||
// Configure the serial device parameters
|
||||
// Build on the current configuration
|
||||
struct termios tios;
|
||||
|
||||
bzero( &tios, sizeof(tios) );
|
||||
tcgetattr( m_hSerialController, &tios );
|
||||
switch( m_owner->m_parity )
|
||||
{
|
||||
case SerialController::Parity_None:
|
||||
tios.c_iflag = IGNPAR;
|
||||
break;
|
||||
case SerialController::Parity_Odd:
|
||||
tios.c_iflag = INPCK;
|
||||
tios.c_cflag = PARENB | PARODD;
|
||||
break;
|
||||
default:
|
||||
Log::Write( LogLevel_Error, "ERROR: Parity not supported" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
switch( m_owner->m_stopBits )
|
||||
{
|
||||
case SerialController::StopBits_One:
|
||||
break; // default
|
||||
case SerialController::StopBits_Two:
|
||||
tios.c_cflag |= CSTOPB;
|
||||
break;
|
||||
default:
|
||||
Log::Write( LogLevel_Error, "ERROR: Stopbits not supported" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
tios.c_iflag |= IGNBRK;
|
||||
tios.c_cflag |= CS8 | CREAD | CLOCAL;
|
||||
tios.c_oflag = 0;
|
||||
tios.c_lflag = 0;
|
||||
for( int i = 0; i < NCCS; i++ )
|
||||
tios.c_cc[i] = 0;
|
||||
tios.c_cc[VMIN] = 0;
|
||||
tios.c_cc[VTIME] = 1;
|
||||
switch( m_owner->m_baud )
|
||||
{
|
||||
case 300:
|
||||
cfsetspeed( &tios, B300 );
|
||||
break;
|
||||
case 1200:
|
||||
cfsetspeed( &tios, B1200 );
|
||||
break;
|
||||
case 2400:
|
||||
cfsetspeed( &tios, B2400 );
|
||||
break;
|
||||
case 4800:
|
||||
cfsetspeed( &tios, B4800 );
|
||||
break;
|
||||
case 9600:
|
||||
cfsetspeed( &tios, B9600 );
|
||||
break;
|
||||
case 19200:
|
||||
cfsetspeed( &tios, B19200 );
|
||||
break;
|
||||
case 38400:
|
||||
cfsetspeed( &tios, B38400 );
|
||||
break;
|
||||
case 57600:
|
||||
cfsetspeed( &tios, B57600 );
|
||||
break;
|
||||
#ifdef DARWIN
|
||||
case 76800:
|
||||
cfsetspeed( &tios, B76800 );
|
||||
break;
|
||||
#endif
|
||||
case 115200:
|
||||
cfsetspeed( &tios, B115200 );
|
||||
break;
|
||||
case 230400:
|
||||
cfsetspeed( &tios, B230400 );
|
||||
break;
|
||||
default:
|
||||
Log::Write( LogLevel_Error, "Baud rate not supported" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
if ( tcsetattr( m_hSerialController, TCSANOW, &tios ) == -1 )
|
||||
{
|
||||
// Error. Clean up and exit
|
||||
Log::Write( LogLevel_Error, "ERROR: Failed to set serial port parameters" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
tcflush( m_hSerialController, TCIOFLUSH );
|
||||
|
||||
// Open successful
|
||||
Log::Write( LogLevel_Info, "Serial port %s opened (attempt %d)", device.c_str(), _attempts );
|
||||
return true;
|
||||
|
||||
SerialOpenFailure:
|
||||
Log::Write( LogLevel_Error, "ERROR: Failed to open serial port %s", device.c_str() );
|
||||
if(m_hSerialController >= 0)
|
||||
{
|
||||
close( m_hSerialController );
|
||||
m_hSerialController = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Read>
|
||||
// Read data from the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::Read
|
||||
(
|
||||
)
|
||||
{
|
||||
uint8 buffer[256];
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int32 bytesRead;
|
||||
int err;
|
||||
|
||||
do
|
||||
{
|
||||
bytesRead = read( m_hSerialController, buffer, sizeof(buffer) );
|
||||
if( bytesRead > 0 )
|
||||
m_owner->Put( buffer, bytesRead );
|
||||
} while( bytesRead > 0 );
|
||||
|
||||
do
|
||||
{
|
||||
struct timeval *whenp;
|
||||
fd_set rds, eds;
|
||||
int oldstate;
|
||||
|
||||
FD_ZERO( &rds );
|
||||
FD_SET( m_hSerialController, &rds );
|
||||
FD_ZERO( &eds );
|
||||
FD_SET( m_hSerialController, &eds );
|
||||
whenp = NULL;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
err = select( m_hSerialController + 1, &rds, NULL, &eds, whenp );
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
} while( err <= 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Write>
|
||||
// Send data to the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 SerialControllerImpl::Write
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _length
|
||||
)
|
||||
{
|
||||
if( -1 == m_hSerialController )
|
||||
{
|
||||
//Error
|
||||
Log::Write( LogLevel_Error, "ERROR: Serial port must be opened before writing" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write the data
|
||||
uint32 bytesWritten;
|
||||
bytesWritten = write( m_hSerialController, _buffer, _length);
|
||||
return bytesWritten;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// SerialControllerImpl.h
|
||||
//
|
||||
// POSIX implementation of a cross-platform serial port
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SerialControllerImpl_H
|
||||
#define _SerialControllerImpl_H
|
||||
|
||||
#include <strings.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "../SerialController.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class SerialControllerImpl
|
||||
{
|
||||
public:
|
||||
void ReadThreadProc( Event* _exitEvent );
|
||||
|
||||
private:
|
||||
friend class SerialController;
|
||||
|
||||
SerialControllerImpl( SerialController* _owner );
|
||||
~SerialControllerImpl();
|
||||
|
||||
bool Open();
|
||||
void Close();
|
||||
|
||||
uint32 Write( uint8* _buffer, uint32 _length );
|
||||
|
||||
bool Init( uint32 const _attempts );
|
||||
void Read();
|
||||
|
||||
SerialController* m_owner;
|
||||
int m_hSerialController;
|
||||
Thread* m_pThread;
|
||||
|
||||
static void SerialReadThreadEntryPoint( Event* _exitEvent, void* _content );
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_SerialControllerImpl_H
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// ThreadImpl.h
|
||||
//
|
||||
// POSIX implementation of a cross-platform thread
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <unistd.h>
|
||||
#include "../../Defs.h"
|
||||
#include "../Event.h"
|
||||
#include "../Thread.h"
|
||||
#include "ThreadImpl.h"
|
||||
|
||||
#ifdef DARWIN
|
||||
#define pthread_yield pthread_yield_np
|
||||
#endif
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::ThreadImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ThreadImpl::ThreadImpl
|
||||
(
|
||||
Thread* _owner,
|
||||
string const& _tname
|
||||
):
|
||||
m_owner( _owner ),
|
||||
// m_hThread( NULL ), /* p_thread_t isn't a pointer in Linux, so can't do this */
|
||||
m_bIsRunning( false ),
|
||||
m_name( _tname )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::~ThreadImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ThreadImpl::~ThreadImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Start>
|
||||
// Start a function running on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::Start
|
||||
(
|
||||
Thread::pfnThreadProc_t _pfnThreadProc,
|
||||
Event* _exitEvent,
|
||||
void* _pContext
|
||||
)
|
||||
{
|
||||
pthread_attr_t ta;
|
||||
|
||||
pthread_attr_init( &ta );
|
||||
pthread_attr_setstacksize ( &ta, 0 );
|
||||
pthread_attr_setdetachstate ( &ta, PTHREAD_CREATE_JOINABLE );
|
||||
|
||||
// Create a thread to run the specified function
|
||||
m_pfnThreadProc = _pfnThreadProc;
|
||||
m_pContext = _pContext;
|
||||
m_exitEvent = _exitEvent;
|
||||
m_exitEvent->Reset();
|
||||
|
||||
pthread_create ( &m_hThread, &ta, ThreadImpl::ThreadProc, this );
|
||||
pthread_detach( m_hThread );
|
||||
//fprintf(stderr, "thread %s starting %08x\n", m_name.c_str(), m_hThread);
|
||||
//fflush(stderr);
|
||||
|
||||
pthread_attr_destroy ( &ta );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Terminate>
|
||||
// End this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::Terminate
|
||||
(
|
||||
)
|
||||
{
|
||||
// void* data = NULL;
|
||||
|
||||
//fprintf(stderr, "thread %s stopping %08x running %d\n", m_name.c_str(), m_hThread, m_bIsRunning );
|
||||
//fflush(stderr);
|
||||
if( !m_bIsRunning )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This will kill an app that doesn't catch and ignore it.
|
||||
// We need to find another way to interrupt select.
|
||||
// thread_kill( m_hThread, SIGALRM );
|
||||
|
||||
//m_hThread = NULL;
|
||||
m_bIsRunning = false;
|
||||
|
||||
// pthread_cancel( m_hThread );
|
||||
// pthread_join( m_hThread, &data );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::msSleep>
|
||||
// Cause thread to sleep for the specified number of milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreadImpl::Sleep
|
||||
(
|
||||
uint32 _millisecs
|
||||
)
|
||||
{
|
||||
usleep( _millisecs*1000 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::IsSignalled>
|
||||
// Test whether the thread has completed
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return !m_bIsRunning;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::ThreadProc>
|
||||
// Entry point for running a function on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void *ThreadImpl::ThreadProc
|
||||
(
|
||||
void* _pArg
|
||||
)
|
||||
{
|
||||
ThreadImpl* pImpl = (ThreadImpl*)_pArg;
|
||||
//fprintf(stderr, "thread %s run begin %08x running %d\n", pImpl->m_name.c_str(), pImpl->m_hThread, pImpl->m_bIsRunning );
|
||||
//fflush(stderr);
|
||||
pImpl->Run();
|
||||
//fprintf(stderr, "thread %s run end %08x running %d\n", pImpl->m_name.c_str(), pImpl->m_hThread, pImpl->m_bIsRunning );
|
||||
//fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Run>
|
||||
// Entry point for running a function on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreadImpl::Run
|
||||
(
|
||||
)
|
||||
{
|
||||
m_bIsRunning = true;
|
||||
m_pfnThreadProc( m_exitEvent, m_pContext );
|
||||
m_bIsRunning = false;
|
||||
|
||||
// Let any watchers know that the thread has finished running
|
||||
m_owner->Notify();
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// ThreadImpl.h
|
||||
//
|
||||
// POSIX implementation of a cross-platform thread
|
||||
//
|
||||
// Copyright (c) 2010, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _ThreadImpl_H
|
||||
#define _ThreadImpl_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Thread;
|
||||
class Event;
|
||||
|
||||
class ThreadImpl
|
||||
{
|
||||
private:
|
||||
friend class Thread;
|
||||
|
||||
ThreadImpl( Thread* _owner, string const& _tname );
|
||||
~ThreadImpl();
|
||||
|
||||
bool Start( Thread::pfnThreadProc_t _pfnThreadProc, Event* _exitEvent, void* _context );
|
||||
void Sleep( uint32 _millisecs );
|
||||
bool IsSignalled();
|
||||
bool Terminate();
|
||||
|
||||
void Run();
|
||||
static void* ThreadProc( void *parg);
|
||||
|
||||
Thread* m_owner;
|
||||
Event* m_exitEvent;
|
||||
pthread_t m_hThread;
|
||||
Thread::pfnThreadProc_t m_pfnThreadProc;
|
||||
void* m_pContext;
|
||||
bool m_bIsRunning;
|
||||
string m_name;
|
||||
};
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_ThreadImpl_H
|
||||
@@ -0,0 +1,141 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStampImpl.cpp
|
||||
//
|
||||
// OSX implementation of a TimeStamp
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "../../Defs.h"
|
||||
#include "TimeStampImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::TimeStampImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStampImpl::TimeStampImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
SetTime(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::~TimeStampImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStampImpl::~TimeStampImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::SetTime>
|
||||
// Sets the timestamp to now, plus an offset in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void TimeStampImpl::SetTime
|
||||
(
|
||||
int32 _milliseconds // = 0
|
||||
)
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
m_stamp.tv_sec = now.tv_sec + (_milliseconds / 1000);
|
||||
|
||||
// Now add the remainder of our timeout to the microseconds part of 'now'
|
||||
now.tv_usec += ((_milliseconds % 1000) * 1000);
|
||||
|
||||
// Careful now! Did it wrap?
|
||||
if(now.tv_usec >= 1000000)
|
||||
{
|
||||
// Yes it did so bump our seconds and modulo
|
||||
now.tv_usec %= 1000000;
|
||||
m_stamp.tv_sec++;
|
||||
}
|
||||
|
||||
m_stamp.tv_nsec = now.tv_usec * 1000;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::TimeRemaining>
|
||||
// Gets the difference between now and the timestamp time in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStampImpl::TimeRemaining
|
||||
(
|
||||
)
|
||||
{
|
||||
int32 diff;
|
||||
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
// Seconds
|
||||
diff = (int32)((m_stamp.tv_sec - now.tv_sec)*1000);
|
||||
|
||||
// Milliseconds
|
||||
diff += (((m_stamp.tv_nsec/1000)-now.tv_usec)/1000);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::GetAsString>
|
||||
// Return a string representation
|
||||
//-----------------------------------------------------------------------------
|
||||
string TimeStampImpl::GetAsString
|
||||
(
|
||||
)
|
||||
{
|
||||
char str[100];
|
||||
struct tm *tm;
|
||||
tm = localtime( &m_stamp.tv_sec );
|
||||
|
||||
snprintf( str, sizeof(str), "%04d-%02d-%02d %02d:%02d:%02d:%03d ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(m_stamp.tv_nsec / (1000*1000)) );
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::operator->
|
||||
// Overload the subtract operator to get the difference between two
|
||||
// timestamps in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStampImpl::operator-
|
||||
(
|
||||
TimeStampImpl const& _other
|
||||
)
|
||||
{
|
||||
// Seconds
|
||||
int32 diff = (int32)((m_stamp.tv_sec-_other.m_stamp.tv_sec)*1000);
|
||||
|
||||
// Milliseconds
|
||||
diff += ((m_stamp.tv_nsec - _other.m_stamp.tv_nsec)/1000000);
|
||||
|
||||
return diff;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStampImpl.h
|
||||
//
|
||||
// OSX implementation of a TimeStamp
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _TimeStampImpl_H
|
||||
#define _TimeStampImpl_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "../../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows implementation of a timestamp.
|
||||
*/
|
||||
class TimeStampImpl
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a TimeStampImpl object.
|
||||
*/
|
||||
TimeStampImpl();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the TimeStampImpl object.
|
||||
*/
|
||||
~TimeStampImpl();
|
||||
|
||||
/**
|
||||
* SetTime. Sets the timestamp to now, plus the offset in milliseconds.
|
||||
* \param _milliseconds positive or negative offset from
|
||||
* now in milliseconds.
|
||||
*/
|
||||
void SetTime( int32 _milliseconds );
|
||||
|
||||
/**
|
||||
* TimeRemaining. Gets the difference between now and the timestamp
|
||||
* time in milliseconds.
|
||||
* \return milliseconds remaining until we reach the timestamp. The
|
||||
* return value is negative if the timestamp is in the past.
|
||||
*/
|
||||
int32 TimeRemaining();
|
||||
|
||||
/**
|
||||
* Return as as string
|
||||
*/
|
||||
string GetAsString();
|
||||
|
||||
/**
|
||||
* Overload the subtract operator to get the difference between
|
||||
* two timestamps in milliseconds.
|
||||
*/
|
||||
int32 operator- ( TimeStampImpl const& _other );
|
||||
|
||||
private:
|
||||
TimeStampImpl( TimeStampImpl const& ); // prevent copy
|
||||
TimeStampImpl& operator = ( TimeStampImpl const& ); // prevent assignment
|
||||
|
||||
struct timespec m_stamp;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_TimeStampImpl_H
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// WaitImpl.cpp
|
||||
//
|
||||
// POSIX implementation of an abstract base class for objects we
|
||||
// want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../../Defs.h"
|
||||
#include "../Wait.h"
|
||||
#include "WaitImpl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::WaitImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
WaitImpl::WaitImpl
|
||||
(
|
||||
Wait* _owner
|
||||
):
|
||||
m_owner( _owner )
|
||||
{
|
||||
pthread_mutexattr_t ma;
|
||||
pthread_mutexattr_init ( &ma );
|
||||
pthread_mutexattr_settype( &ma, PTHREAD_MUTEX_RECURSIVE );
|
||||
pthread_mutex_init( &m_criticalSection, &ma );
|
||||
pthread_mutexattr_destroy( &ma );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::~WaitImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
WaitImpl::~WaitImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
pthread_mutex_destroy( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::AddWatcher>
|
||||
// Add a watcher to our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitImpl::AddWatcher
|
||||
(
|
||||
Wait::pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
// Add the watcher to our list
|
||||
Watcher watcher;
|
||||
watcher.m_callback = _callback;
|
||||
watcher.m_context = _context;
|
||||
|
||||
if( pthread_mutex_lock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::AddWatcher lock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
m_watchers.push_back( watcher );
|
||||
if( pthread_mutex_unlock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::AddWatcher unlock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
// If the object is already in a signalled state, notify the watcher immediately
|
||||
if( m_owner->IsSignalled() )
|
||||
{
|
||||
_callback( _context );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::RemoveWatcher>
|
||||
// Remove a watcher from our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool WaitImpl::RemoveWatcher
|
||||
(
|
||||
Wait::pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
bool res = false;
|
||||
|
||||
if( pthread_mutex_lock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::RemoveWatcher lock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
for( list<Watcher>::iterator it=m_watchers.begin(); it!=m_watchers.end(); ++it )
|
||||
{
|
||||
Watcher const& watcher = *it;
|
||||
if( ( watcher.m_callback == _callback ) && ( watcher.m_context == _context ) )
|
||||
{
|
||||
m_watchers.erase( it );
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pthread_mutex_unlock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::RemoveWatcher unlock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::Notify>
|
||||
// Notify all the watchers that the object has become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitImpl::Notify
|
||||
(
|
||||
)
|
||||
{
|
||||
if( pthread_mutex_lock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::Notify lock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
for( list<Watcher>::iterator it=m_watchers.begin(); it!=m_watchers.end(); ++it )
|
||||
{
|
||||
Watcher const& watcher = *it;
|
||||
watcher.m_callback( watcher.m_context );
|
||||
}
|
||||
if( pthread_mutex_unlock( &m_criticalSection ) != 0 )
|
||||
{
|
||||
fprintf(stderr, "WaitImpl::Notify unlock error %d\n", errno );
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// WaitImpl.h
|
||||
//
|
||||
// POSIX implementation of a base class for objects we
|
||||
// want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _WaitImpl_H
|
||||
#define _WaitImpl_H
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include "../../libs/pthreadw32/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <list>
|
||||
#include "../../Defs.h"
|
||||
#include "../Ref.h"
|
||||
#include "../Wait.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows specific implementation of Wait objects.
|
||||
*/
|
||||
class WaitImpl
|
||||
{
|
||||
private:
|
||||
friend class Wait;
|
||||
|
||||
WaitImpl( Wait* _owner );
|
||||
virtual ~WaitImpl();
|
||||
|
||||
void AddWatcher( Wait::pfnWaitNotification_t _callback, void* _context );
|
||||
bool RemoveWatcher( Wait::pfnWaitNotification_t _callback, void* _context );
|
||||
void Notify();
|
||||
|
||||
static int32 Multiple( Wait** _objects, uint32 _numObjects, int32 _timeout = -1 );
|
||||
|
||||
WaitImpl( Wait const& ); // prevent copy
|
||||
WaitImpl& operator = ( WaitImpl const& ); // prevent assignment
|
||||
|
||||
struct Watcher
|
||||
{
|
||||
Wait::pfnWaitNotification_t m_callback;
|
||||
void* m_context;
|
||||
};
|
||||
|
||||
list<Watcher> m_watchers;
|
||||
Wait* m_owner;
|
||||
pthread_mutex_t m_criticalSection;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_WaitImpl_H
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
project(openzwave_platform_windows)
|
||||
|
||||
file(GLOB ${PROJECT_NAME}_sources "${PROJECT_SOURCE_DIR}/*.cpp")
|
||||
file(GLOB ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/*.h")
|
||||
|
||||
set(${PROJECT_NAME}_files ${${PROJECT_NAME}_sources} ${${PROJECT_NAME}_headers} CACHE INTERNAL "")
|
||||
@@ -0,0 +1,102 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// EventImpl.cpp
|
||||
//
|
||||
// Windows implementation of a cross-platform event
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "EventImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::EventImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
EventImpl::EventImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
// Create a manual reset event
|
||||
m_hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::~EventImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
EventImpl::~EventImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
::CloseHandle( m_hEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Set>
|
||||
// Set the event to signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void EventImpl::Set
|
||||
(
|
||||
)
|
||||
{
|
||||
::SetEvent( m_hEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Reset>
|
||||
// Set the event to not signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void EventImpl::Reset
|
||||
(
|
||||
)
|
||||
{
|
||||
::ResetEvent( m_hEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::IsSignalled>
|
||||
// Test whether the event is set
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EventImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return( WAIT_OBJECT_0 == WaitForSingleObject( m_hEvent, 0 ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <EventImpl::Wait>
|
||||
// Wait for the event to become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
bool EventImpl::Wait
|
||||
(
|
||||
int32 const _timeout
|
||||
)
|
||||
{
|
||||
return( WAIT_TIMEOUT != ::WaitForSingleObject( m_hEvent, (DWORD)_timeout ) );
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// EventImpl.h
|
||||
//
|
||||
// Windows implementation of a cross-platform event
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _EventImpl_H
|
||||
#define _EventImpl_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows-specific implementation of the Event class.
|
||||
*/
|
||||
class EventImpl
|
||||
{
|
||||
private:
|
||||
friend class Event;
|
||||
friend class SocketImpl;
|
||||
friend class Wait;
|
||||
|
||||
EventImpl();
|
||||
~EventImpl();
|
||||
|
||||
void Set();
|
||||
void Reset();
|
||||
|
||||
bool Wait( int32 _timeout ); // The wait method is to be used only by the Wait::Multiple method
|
||||
bool IsSignalled();
|
||||
|
||||
HANDLE m_hEvent;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_EventImpl_H
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOpsImpl.cpp
|
||||
//
|
||||
// Unix implementation of file operations
|
||||
//
|
||||
// Copyright (c) 2012, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <windows.h>
|
||||
#include "FileOpsImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::FileOpsImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOpsImpl::FileOpsImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::~FileOpsImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
FileOpsImpl::~FileOpsImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <FileOpsImpl::FolderExists>
|
||||
// Determine if a folder exists
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FileOpsImpl::FolderExists(
|
||||
const string &_folderName
|
||||
)
|
||||
{
|
||||
int32 ftype = GetFileAttributesA(_folderName.c_str());
|
||||
if( ftype == INVALID_FILE_ATTRIBUTES )
|
||||
return false; // something is wrong with _foldername path
|
||||
if( ftype & FILE_ATTRIBUTE_DIRECTORY )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// FileOpsImpl.h
|
||||
//
|
||||
// Unix implementation of file operations
|
||||
//
|
||||
// Copyright (c) 2012, Greg Satz <satz@iranger.com>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _FileOpsImpl_H
|
||||
#define _FileOpsImpl_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include "../../Defs.h"
|
||||
#include "../FileOps.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class FileOpsImpl
|
||||
{
|
||||
friend class FileOps;
|
||||
|
||||
private:
|
||||
FileOpsImpl();
|
||||
~FileOpsImpl();
|
||||
|
||||
bool FolderExists( const string &_filename );
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_FileOpsImpl_H
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// LogImpl.cpp
|
||||
//
|
||||
// Windows implementation of message and error logging
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <windows.h>
|
||||
#include <list>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "LogImpl.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define vsprintf_s vsnprintf
|
||||
#define sprintf_s snprintf
|
||||
|
||||
#define strcpy_s(DEST, NUM, SOURCE) strncpy(DEST, SOURCE, NUM)
|
||||
|
||||
errno_t fopen_s(FILE** pFile, const char *filename, const char *mode)
|
||||
{
|
||||
if (!pFile)
|
||||
{
|
||||
_set_errno(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*pFile = fopen(filename, mode);
|
||||
|
||||
if (!*pFile)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::LogImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LogImpl::LogImpl
|
||||
(
|
||||
string const& _filename,
|
||||
bool const _bAppendLog,
|
||||
bool const _bConsoleOutput,
|
||||
LogLevel const _saveLevel,
|
||||
LogLevel const _queueLevel,
|
||||
LogLevel const _dumpTrigger
|
||||
):
|
||||
m_filename( _filename ), // name of log file
|
||||
m_bAppendLog( _bAppendLog ), // true to append (and not overwrite) any existing log
|
||||
m_bConsoleOutput( _bConsoleOutput ), // true to provide a copy of output to console
|
||||
m_saveLevel( _saveLevel ), // level of messages to log to file
|
||||
m_queueLevel( _queueLevel ), // level of messages to log to queue
|
||||
m_dumpTrigger( _dumpTrigger ) // dump queued messages when this level is seen
|
||||
{
|
||||
string accessType;
|
||||
|
||||
// create an adjusted file name and timestamp string
|
||||
string timeStr = GetTimeStampString();
|
||||
|
||||
if ( m_bAppendLog )
|
||||
{
|
||||
accessType = "a";
|
||||
}
|
||||
else
|
||||
{
|
||||
accessType = "w";
|
||||
}
|
||||
|
||||
FILE* pFile;
|
||||
if( !fopen_s( &pFile, _filename.c_str(), accessType.c_str() ) )
|
||||
{
|
||||
fprintf( pFile, "\nLogging started %s\n\n", timeStr.c_str() );
|
||||
fclose( pFile );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::~LogImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
LogImpl::~LogImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Write>
|
||||
// Write to the log
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::Write
|
||||
(
|
||||
LogLevel _logLevel,
|
||||
uint8 const _nodeId,
|
||||
char const* _format,
|
||||
va_list _args
|
||||
)
|
||||
{
|
||||
// create a timestamp string
|
||||
string timeStr = GetTimeStampString();
|
||||
string nodeStr = GetNodeString( _nodeId );
|
||||
string logLevelStr = GetLogLevelString(_logLevel);
|
||||
|
||||
// handle this message
|
||||
if( (_logLevel <= m_queueLevel) || (_logLevel == LogLevel_Internal) ) // we're going to do something with this message...
|
||||
{
|
||||
char lineBuf[1024];
|
||||
if( !_format || ( _format[0] == 0 ) )
|
||||
{
|
||||
strcpy_s( lineBuf, 1024, "" );
|
||||
}
|
||||
else
|
||||
{
|
||||
vsprintf_s( lineBuf, sizeof(lineBuf), _format, _args );
|
||||
}
|
||||
|
||||
// should this message be saved to file (and possibly written to console?)
|
||||
if( (_logLevel <= m_saveLevel) || (_logLevel == LogLevel_Internal) )
|
||||
{
|
||||
// save to file
|
||||
FILE* pFile = NULL;
|
||||
if( !fopen_s( &pFile, m_filename.c_str(), "a" ) || m_bConsoleOutput )
|
||||
{
|
||||
if( _logLevel != LogLevel_Internal ) // don't add a second timestamp to display of queued messages
|
||||
{
|
||||
if( pFile != NULL )
|
||||
{
|
||||
fprintf( pFile, "%s%s%s", timeStr.c_str(), logLevelStr.c_str(), nodeStr.c_str() );
|
||||
}
|
||||
if( m_bConsoleOutput )
|
||||
{
|
||||
printf( "%s%s%s", timeStr.c_str(), logLevelStr.c_str(), nodeStr.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
// print message to file (and possibly screen)
|
||||
if( pFile != NULL )
|
||||
{
|
||||
fprintf( pFile, "%s", lineBuf );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
if( m_bConsoleOutput )
|
||||
{
|
||||
printf( "%s", lineBuf );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( _logLevel != LogLevel_Internal )
|
||||
{
|
||||
char queueBuf[1024];
|
||||
string threadStr = GetThreadId();
|
||||
sprintf_s( queueBuf, sizeof(queueBuf), "%s%s%s", timeStr.c_str(), threadStr.c_str(), lineBuf );
|
||||
Queue( queueBuf );
|
||||
}
|
||||
}
|
||||
|
||||
// now check to see if the _dumpTrigger has been hit
|
||||
if( (_logLevel <= m_dumpTrigger) && (_logLevel != LogLevel_Internal) && (_logLevel != LogLevel_Always) )
|
||||
{
|
||||
QueueDump();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Queue>
|
||||
// Write to the log queue
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::Queue
|
||||
(
|
||||
char const* _buffer
|
||||
)
|
||||
{
|
||||
string bufStr = _buffer;
|
||||
m_logQueue.push_back( bufStr );
|
||||
|
||||
// rudimentary queue size management
|
||||
if( m_logQueue.size() > 500 )
|
||||
{
|
||||
m_logQueue.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::QueueDump>
|
||||
// Dump the LogQueue to output device
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::QueueDump
|
||||
(
|
||||
)
|
||||
{
|
||||
Log::Write( LogLevel_Internal, "\n\nDumping queued log messages\n");
|
||||
list<string>::iterator it = m_logQueue.begin();
|
||||
while( it != m_logQueue.end() )
|
||||
{
|
||||
string strTemp = *it;
|
||||
Log::Write( LogLevel_Internal, strTemp.c_str() );
|
||||
++it;
|
||||
}
|
||||
m_logQueue.clear();
|
||||
Log::Write( LogLevel_Internal, "\nEnd of queued log message dump\n\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::Clear>
|
||||
// Clear the LogQueue
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::QueueClear
|
||||
(
|
||||
)
|
||||
{
|
||||
m_logQueue.clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::SetLoggingState>
|
||||
// Sets the various log state variables
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::SetLoggingState
|
||||
(
|
||||
LogLevel _saveLevel,
|
||||
LogLevel _queueLevel,
|
||||
LogLevel _dumpTrigger
|
||||
)
|
||||
{
|
||||
m_saveLevel = _saveLevel;
|
||||
m_queueLevel = _queueLevel;
|
||||
m_dumpTrigger = _dumpTrigger;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetTimeStampAndThreadId>
|
||||
// Generate a string with formatted current time
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetTimeStampString
|
||||
(
|
||||
)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
char fmt[64], buf[64], line[256];
|
||||
gettimeofday(&tv, NULL);
|
||||
#ifdef _WIN32
|
||||
struct tm *tm1;
|
||||
if((tm1 = gmtime(&tv.tv_sec)) != 0) {
|
||||
memcpy(&tm, tm1, sizeof(struct tm));
|
||||
#else
|
||||
if((gmtime_r(&tv.tv_sec, &tm)) != 0) {
|
||||
#endif
|
||||
strftime(fmt, sizeof(fmt), "%b %d %H:%M:%S", &tm);
|
||||
snprintf(buf, sizeof(buf), "%s:%03u", fmt, (unsigned int)tv.tv_usec);
|
||||
}
|
||||
sprintf(line, "[%22.22s] %s: [Z-Wave]: ", buf, "pilight-daemon");
|
||||
|
||||
string str = line;
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetNodeString>
|
||||
// Generate a string with formatted node id
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetNodeString
|
||||
(
|
||||
uint8 const _nodeId
|
||||
)
|
||||
{
|
||||
if( _nodeId == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
if( _nodeId == 255 ) // should make distinction between broadcast and controller better for SwitchAll broadcast
|
||||
{
|
||||
return "contrlr, ";
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[20];
|
||||
snprintf( buf, sizeof(buf), "Node%03d, ", _nodeId );
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetThreadId>
|
||||
// Generate a string with formatted thread id
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetThreadId
|
||||
(
|
||||
)
|
||||
{
|
||||
char buf[20];
|
||||
DWORD dwThread = ::GetCurrentThreadId();
|
||||
sprintf_s( buf, sizeof(buf), "%04d ", dwThread );
|
||||
string str = buf;
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::SetLogFileName>
|
||||
// Provide a new log file name (applicable to future writes)
|
||||
//-----------------------------------------------------------------------------
|
||||
void LogImpl::SetLogFileName
|
||||
(
|
||||
const string &_filename
|
||||
)
|
||||
{
|
||||
m_filename = _filename;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// <LogImpl::GetLogLevelString>
|
||||
// Provide a new log file name (applicable to future writes)
|
||||
//-----------------------------------------------------------------------------
|
||||
string LogImpl::GetLogLevelString
|
||||
(
|
||||
LogLevel _level
|
||||
)
|
||||
{
|
||||
if ((_level >= LogLevel_None) && (_level <= LogLevel_Internal)) {
|
||||
char buf[20];
|
||||
snprintf( buf, sizeof(buf), "%s, ", LogLevelString[_level] );
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
return "Unknown, ";
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// LogImpl.h
|
||||
//
|
||||
// Windows implementation of message and error logging
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _LogImpl_H
|
||||
#define _LogImpl_H
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include <string>
|
||||
#include "../Log.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows-specific implementation of the Log class.
|
||||
*/
|
||||
class LogImpl : public i_LogImpl
|
||||
{
|
||||
private:
|
||||
friend class Log;
|
||||
|
||||
LogImpl( string const& _filename, bool const _bAppendLog, bool const _bConsoleOutput, LogLevel const _saveLevel, LogLevel const _queueLevel, LogLevel const _dumpTrigger );
|
||||
~LogImpl();
|
||||
|
||||
void Write( LogLevel _level, uint8 const _nodeId, char const* _format, va_list _args );
|
||||
void Queue( char const* _buffer );
|
||||
void QueueDump();
|
||||
void QueueClear();
|
||||
void SetLoggingState( LogLevel _saveLevel, LogLevel _queueLevel, LogLevel _dumpTrigger );
|
||||
void SetLogFileName( const string &_filename );
|
||||
|
||||
string GetTimeStampString();
|
||||
string GetNodeString( uint8 const _nodeId );
|
||||
string GetThreadId();
|
||||
string GetLogLevelString(LogLevel _level);
|
||||
|
||||
string m_filename; /**< filename specified by user (default is ozw_log.txt) */
|
||||
bool m_bConsoleOutput; /**< if true, send log output to console as well as to the file */
|
||||
bool m_bAppendLog; /**< if true, the log file should be appended to any with the same name */
|
||||
list<string> m_logQueue; /**< list of queued log messages */
|
||||
LogLevel m_saveLevel;
|
||||
LogLevel m_queueLevel;
|
||||
LogLevel m_dumpTrigger;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_LogImpl_H
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// MutexImpl.cpp
|
||||
//
|
||||
// Windows Implementation of the cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../../Defs.h"
|
||||
#include "MutexImpl.h"
|
||||
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::MutexImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MutexImpl::MutexImpl
|
||||
(
|
||||
):
|
||||
m_lockCount( 0 )
|
||||
{
|
||||
InitializeCriticalSection( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::~MutexImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
MutexImpl::~MutexImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
DeleteCriticalSection( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::Lock>
|
||||
// Lock the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MutexImpl::Lock
|
||||
(
|
||||
bool const _bWait // = true;
|
||||
)
|
||||
{
|
||||
if( _bWait )
|
||||
{
|
||||
// We will wait for the lock
|
||||
EnterCriticalSection( &m_criticalSection );
|
||||
++m_lockCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns immediately, even if the lock was not available.
|
||||
if( TryEnterCriticalSection( &m_criticalSection ) )
|
||||
{
|
||||
++m_lockCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::Unlock>
|
||||
// Release our lock on the mutex
|
||||
//-----------------------------------------------------------------------------
|
||||
void MutexImpl::Unlock
|
||||
(
|
||||
)
|
||||
{
|
||||
if( !m_lockCount )
|
||||
{
|
||||
// No locks - we have a mismatched lock/release pair
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
--m_lockCount;
|
||||
LeaveCriticalSection( &m_criticalSection );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <MutexImpl::IsSignalled>
|
||||
// Test whether the mutex is free
|
||||
//-----------------------------------------------------------------------------
|
||||
bool MutexImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return( 0 == m_lockCount );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// MutexImpl.h
|
||||
//
|
||||
// Windows Implementation of the cross-platform mutex
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MutexImpl_H
|
||||
#define _MutexImpl_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows-specific implementation of the Mutex class.
|
||||
*/
|
||||
class MutexImpl
|
||||
{
|
||||
private:
|
||||
friend class Mutex;
|
||||
|
||||
MutexImpl();
|
||||
~MutexImpl();
|
||||
|
||||
bool Lock( bool const _bWait = true );
|
||||
void Unlock();
|
||||
|
||||
bool IsSignalled();
|
||||
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
uint32 m_lockCount; // Keep track of the locks (there can be more than one if they occur on the same thread.
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_MutexIF_H
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SerialControllerImpl.cpp
|
||||
//
|
||||
// Windows Implementation of the cross-platform serial port
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "SerialControllerImpl.h"
|
||||
|
||||
#include "../Log.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
DWORD WINAPI SerialReadThreadEntryPoint( void* _context );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::SerialControllerImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialControllerImpl::SerialControllerImpl
|
||||
(
|
||||
SerialController* _owner
|
||||
):
|
||||
m_owner( _owner )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::~SerialControllerImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
SerialControllerImpl::~SerialControllerImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
CloseHandle( m_hSerialController );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Open>
|
||||
// Open the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialControllerImpl::Open
|
||||
(
|
||||
)
|
||||
{
|
||||
// Try to init the serial port
|
||||
if( !Init( 1 ) )
|
||||
{
|
||||
// Failed. We bail to allow the app a chance to take over, rather than retry
|
||||
// automatically. Automatic retries only occur after a successful init.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create an event to trigger exiting the read thread
|
||||
m_hExit = ::CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
|
||||
// Start the read thread
|
||||
m_hThread = ::CreateThread( NULL, 0, SerialReadThreadEntryPoint, this, CREATE_SUSPENDED, NULL );
|
||||
::ResumeThread( m_hThread );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Close>
|
||||
// Close the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::Close
|
||||
(
|
||||
)
|
||||
{
|
||||
::SetEvent( m_hExit );
|
||||
::WaitForSingleObject( m_hThread, INFINITE );
|
||||
|
||||
CloseHandle( m_hThread );
|
||||
m_hThread = INVALID_HANDLE_VALUE;
|
||||
|
||||
CloseHandle( m_hExit );
|
||||
m_hExit = INVALID_HANDLE_VALUE;
|
||||
|
||||
CloseHandle( m_hSerialController );
|
||||
m_hSerialController = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialReadThreadEntryPoint>
|
||||
// Entry point of the thread for receiving data from the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD WINAPI SerialReadThreadEntryPoint
|
||||
(
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
SerialControllerImpl* impl = (SerialControllerImpl*)_context;
|
||||
if( impl )
|
||||
{
|
||||
impl->ReadThreadProc();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::ReadThreadProc>
|
||||
// Handle receiving data
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::ReadThreadProc
|
||||
(
|
||||
)
|
||||
{
|
||||
uint32 attempts = 0;
|
||||
while( true )
|
||||
{
|
||||
// Init must have been called successfully during Open, so we
|
||||
// don't do it again until the end of the loop
|
||||
if( INVALID_HANDLE_VALUE != m_hSerialController )
|
||||
{
|
||||
// Enter read loop. Call will only return if
|
||||
// an exit is requested or an error occurs
|
||||
Read();
|
||||
|
||||
// Reset the attempts, so we get a rapid retry for temporary errors
|
||||
attempts = 0;
|
||||
}
|
||||
|
||||
if( attempts < 25 )
|
||||
{
|
||||
// Retry every 5 seconds for the first two minutes...
|
||||
if( WAIT_OBJECT_0 == ::WaitForSingleObject( m_hExit, 5000 ) )
|
||||
{
|
||||
// Exit signalled.
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...retry every 30 seconds after that
|
||||
if( WAIT_OBJECT_0 == ::WaitForSingleObject( m_hExit, 30000 ) )
|
||||
{
|
||||
// Exit signalled.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Init( ++attempts );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Init>
|
||||
// Initialize the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SerialControllerImpl::Init
|
||||
(
|
||||
uint32 const _attempts
|
||||
)
|
||||
{
|
||||
Log::Write( LogLevel_Info, " Trying to open serial port %s (Attempt %d)", m_owner->m_serialControllerName.c_str(), _attempts );
|
||||
|
||||
m_hSerialController = CreateFileA( m_owner->m_serialControllerName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL );
|
||||
|
||||
if( INVALID_HANDLE_VALUE == m_hSerialController )
|
||||
{
|
||||
//Error
|
||||
Log::Write( LogLevel_Error, "ERROR: Cannot open serial port %s. Error code %d\n", m_owner->m_serialControllerName.c_str(), GetLastError() );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
// Configure the serial device parameters
|
||||
// Build on the current configuration
|
||||
DCB dcb;
|
||||
if( !GetCommState( m_hSerialController, &dcb ) )
|
||||
{
|
||||
//Error. Clean up and exit
|
||||
Log::Write( LogLevel_Error, "ERROR: Failed to read serial port state" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
// Fill in the Device Control Block
|
||||
dcb.BaudRate = (DWORD)m_owner->m_baud;
|
||||
dcb.ByteSize = 8;
|
||||
dcb.Parity = (BYTE)m_owner->m_parity;
|
||||
dcb.StopBits = (BYTE)m_owner->m_stopBits;
|
||||
|
||||
if( !SetCommState( m_hSerialController, &dcb) )
|
||||
{
|
||||
//Error. Clean up and exit
|
||||
Log::Write( LogLevel_Error, "ERROR: Failed to set serial port state" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
// Set the timeouts for the serial port
|
||||
COMMTIMEOUTS commTimeouts;
|
||||
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.WriteTotalTimeoutConstant = 0;
|
||||
commTimeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
if( !SetCommTimeouts( m_hSerialController, &commTimeouts ) )
|
||||
{
|
||||
// Error. Clean up and exit
|
||||
Log::Write( LogLevel_Error, "ERROR: Failed to set serial port timeouts" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
// Set the serial port to signal when data is received
|
||||
if( !SetCommMask( m_hSerialController, EV_RXCHAR ) )
|
||||
{
|
||||
//Error. Clean up and exit
|
||||
Log::Write( LogLevel_Info, "ERROR: Failed to set serial port mask" );
|
||||
goto SerialOpenFailure;
|
||||
}
|
||||
|
||||
// Clear any residual data from the serial port
|
||||
PurgeComm( m_hSerialController, PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR );
|
||||
|
||||
// Open successful
|
||||
Log::Write( LogLevel_Info, " Serial port %s opened (attempt %d)", m_owner->m_serialControllerName.c_str(), _attempts );
|
||||
return true;
|
||||
|
||||
SerialOpenFailure:
|
||||
Log::Write( LogLevel_Info, "ERROR: Failed to open serial port %s (attempt %d)", m_owner->m_serialControllerName.c_str(), _attempts );
|
||||
CloseHandle( m_hSerialController );
|
||||
m_hSerialController = INVALID_HANDLE_VALUE;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Read>
|
||||
// Read data from the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
void SerialControllerImpl::Read
|
||||
(
|
||||
)
|
||||
{
|
||||
uint8 buffer[256];
|
||||
|
||||
OVERLAPPED overlapped;
|
||||
memset( &overlapped, 0, sizeof(overlapped) );
|
||||
overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
|
||||
while( true )
|
||||
{
|
||||
// Try to read all available data from the serial port
|
||||
DWORD bytesRead = 0;
|
||||
do
|
||||
{
|
||||
if( ::ReadFile( m_hSerialController, buffer, 256, NULL, &overlapped ) )
|
||||
{
|
||||
// Read completed
|
||||
GetOverlappedResult( m_hSerialController, &overlapped, &bytesRead, TRUE );
|
||||
|
||||
// Copy to the stream buffer
|
||||
if( bytesRead > 0 )
|
||||
m_owner->Put( buffer, bytesRead );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Wait for the read to complete
|
||||
if( ERROR_IO_PENDING == GetLastError() )
|
||||
{
|
||||
// Wait for the read to complete or the
|
||||
// signal that this thread should exit.
|
||||
HANDLE handles[2];
|
||||
handles[0] = overlapped.hEvent;
|
||||
handles[1] = m_hExit;
|
||||
DWORD res = WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
|
||||
|
||||
if( (WAIT_OBJECT_0+1) == res )
|
||||
{
|
||||
// Exit signalled. Cancel the read.
|
||||
goto exitRead;
|
||||
}
|
||||
|
||||
if( WAIT_TIMEOUT == res )
|
||||
{
|
||||
// Timed out - should never happen
|
||||
goto exitRead;
|
||||
}
|
||||
|
||||
// Read completed
|
||||
GetOverlappedResult( m_hSerialController, &overlapped, &bytesRead, TRUE );
|
||||
|
||||
// Copy to the stream buffer
|
||||
if( bytesRead > 0 )
|
||||
m_owner->Put( buffer, bytesRead );
|
||||
}
|
||||
else
|
||||
{
|
||||
// An error has occurred
|
||||
goto exitRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
while( bytesRead > 0 );
|
||||
|
||||
// Clear the event
|
||||
ResetEvent( overlapped.hEvent );
|
||||
|
||||
// Nothing available to read, so wait for the next rx char event
|
||||
DWORD dwEvtMask;
|
||||
if( !WaitCommEvent( m_hSerialController, &dwEvtMask, &overlapped ) )
|
||||
{
|
||||
if( ERROR_IO_PENDING == GetLastError() )
|
||||
{
|
||||
// Wait for either some data to arrive or
|
||||
// the signal that this thread should exit.
|
||||
HANDLE handles[2];
|
||||
handles[0] = overlapped.hEvent;
|
||||
handles[1] = m_hExit;
|
||||
|
||||
DWORD res = WaitForMultipleObjects( 2, handles, FALSE, INFINITE );
|
||||
|
||||
if( (WAIT_OBJECT_0+1) == res )
|
||||
{
|
||||
// Exit signalled. Prevent WaitCommEvent from corrupting the
|
||||
// stack by forcing it to exit.
|
||||
goto exitRead;
|
||||
}
|
||||
|
||||
if( WAIT_TIMEOUT == res )
|
||||
{
|
||||
// Timed out - should never happen
|
||||
goto exitRead;
|
||||
}
|
||||
|
||||
GetOverlappedResult( m_hSerialController, &overlapped, &bytesRead, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the event
|
||||
ResetEvent( overlapped.hEvent );
|
||||
|
||||
// Loop back to the top to read the waiting data
|
||||
}
|
||||
|
||||
exitRead:
|
||||
// Exit event has been signalled, or an error has occurred
|
||||
SetCommMask( m_hSerialController, 0 );
|
||||
CancelIo( m_hSerialController );
|
||||
CloseHandle( overlapped.hEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <SerialControllerImpl::Write>
|
||||
// Send data to the serial port
|
||||
//-----------------------------------------------------------------------------
|
||||
uint32 SerialControllerImpl::Write
|
||||
(
|
||||
uint8* _buffer,
|
||||
uint32 _length
|
||||
)
|
||||
{
|
||||
if( INVALID_HANDLE_VALUE == m_hSerialController )
|
||||
{
|
||||
//Error
|
||||
Log::Write( LogLevel_Error, "ERROR: Serial port must be opened before writing\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write the data
|
||||
OVERLAPPED overlapped;
|
||||
memset( &overlapped, 0, sizeof(overlapped) );
|
||||
overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||
|
||||
DWORD bytesWritten;
|
||||
if( !::WriteFile( m_hSerialController, _buffer, _length, &bytesWritten, &overlapped ) )
|
||||
{
|
||||
//Wait for the write to complete
|
||||
if( ERROR_IO_PENDING == GetLastError() )
|
||||
{
|
||||
GetOverlappedResult( m_hSerialController, &overlapped, &bytesWritten, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Write( LogLevel_Error, "ERROR: Serial port write (0x%.8x)", GetLastError() );
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle( overlapped.hEvent );
|
||||
return (uint32)bytesWritten;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// SerialControllerImpl.h
|
||||
//
|
||||
// Windows Implementation of the cross-platform serial port
|
||||
//
|
||||
// Copyright (c) 2010 Jason Frazier <frazierjason@gmail.com>
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SerialControllerImpl_H
|
||||
#define _SerialControllerImpl_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "../../Defs.h"
|
||||
#include "../SerialController.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class SerialControllerImpl
|
||||
{
|
||||
public:
|
||||
void ReadThreadProc();
|
||||
|
||||
private:
|
||||
friend class SerialController;
|
||||
|
||||
SerialControllerImpl( SerialController* _owner );
|
||||
~SerialControllerImpl();
|
||||
|
||||
bool Open();
|
||||
void Close();
|
||||
|
||||
uint32 Write( uint8* _buffer, uint32 _length );
|
||||
|
||||
bool Init( uint32 const _attempts );
|
||||
void Read();
|
||||
|
||||
SerialController* m_owner;
|
||||
HANDLE m_hThread;
|
||||
HANDLE m_hExit;
|
||||
HANDLE m_hSerialController;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_SerialControllerImpl_H
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ThreadImpl.cpp
|
||||
//
|
||||
// Windows implementation of a cross-platform thread
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../../Defs.h"
|
||||
#include "../Event.h"
|
||||
#include "../Thread.h"
|
||||
#include "ThreadImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::ThreadImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ThreadImpl::ThreadImpl
|
||||
(
|
||||
Thread* _owner,
|
||||
string const& _name
|
||||
):
|
||||
m_owner( _owner ),
|
||||
m_hThread( INVALID_HANDLE_VALUE ),
|
||||
m_bIsRunning( false ),
|
||||
m_name( _name )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::~ThreadImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
ThreadImpl::~ThreadImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Start>
|
||||
// Start a function running on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::Start
|
||||
(
|
||||
Thread::pfnThreadProc_t _pfnThreadProc,
|
||||
Event* _exitEvent,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
// Create a thread to run the specified function
|
||||
m_pfnThreadProc = _pfnThreadProc;
|
||||
m_context = _context;
|
||||
m_exitEvent = _exitEvent;
|
||||
m_exitEvent->Reset();
|
||||
|
||||
HANDLE hThread = ::CreateThread( NULL, 0, ThreadImpl::ThreadProc, this, CREATE_SUSPENDED, NULL );
|
||||
m_hThread = hThread;
|
||||
|
||||
::ResumeThread( hThread );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Sleep>
|
||||
// Cause thread to sleep for the specified number of milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreadImpl::Sleep
|
||||
(
|
||||
uint32 _millisecs
|
||||
)
|
||||
{
|
||||
::Sleep(_millisecs);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Terminate>
|
||||
// Force the thread to stop
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::Terminate
|
||||
(
|
||||
)
|
||||
{
|
||||
if( !m_bIsRunning )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This can cause all sorts of trouble if the thread is holding a lock.
|
||||
TerminateThread( m_hThread, 0 );
|
||||
m_hThread = INVALID_HANDLE_VALUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::IsSignalled>
|
||||
// Test whether the thread has completed
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ThreadImpl::IsSignalled
|
||||
(
|
||||
)
|
||||
{
|
||||
return !m_bIsRunning;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::ThreadProc>
|
||||
// Entry point for running a function on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
DWORD WINAPI ThreadImpl::ThreadProc
|
||||
(
|
||||
void* _pArg
|
||||
)
|
||||
{
|
||||
ThreadImpl* pImpl = (ThreadImpl*)_pArg;
|
||||
pImpl->Run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <ThreadImpl::Run>
|
||||
// Entry point for running a function on this thread
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThreadImpl::Run
|
||||
(
|
||||
)
|
||||
{
|
||||
m_bIsRunning = true;
|
||||
m_pfnThreadProc( m_exitEvent, m_context );
|
||||
m_bIsRunning = false;
|
||||
|
||||
// Let any watchers know that the thread has finished running.
|
||||
m_owner->Notify();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ThreadImpl.h
|
||||
//
|
||||
// Windows implementation of a cross-platform thread
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _ThreadImpl_H
|
||||
#define _ThreadImpl_H
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include "../Thread.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
class Thread;
|
||||
class Event;
|
||||
|
||||
/** \brief Windows-specific implementation of the Thread class.
|
||||
*/
|
||||
class ThreadImpl
|
||||
{
|
||||
private:
|
||||
friend class Thread;
|
||||
|
||||
ThreadImpl( Thread* _owner, string const& _name );
|
||||
~ThreadImpl();
|
||||
|
||||
bool Start( Thread::pfnThreadProc_t _pfnThreadProc, Event* _exitEvent, void* _context );
|
||||
void Sleep( uint32 _milliseconds );
|
||||
bool Terminate();
|
||||
|
||||
bool IsSignalled();
|
||||
|
||||
void Run();
|
||||
static DWORD WINAPI ThreadProc( void* _pArg );
|
||||
|
||||
Thread* m_owner;
|
||||
HANDLE m_hThread;
|
||||
Event* m_exitEvent;
|
||||
Thread::pfnThreadProc_t m_pfnThreadProc;
|
||||
void* m_context;
|
||||
bool m_bIsRunning;
|
||||
string m_name;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_ThreadImpl_H
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStampImpl.h
|
||||
//
|
||||
// Cross-platform TimeStampImpl
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include "../../Defs.h"
|
||||
#include "TimeStampImpl.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::TimeStampImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStampImpl::TimeStampImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
SetTime(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::~TimeStampImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
TimeStampImpl::~TimeStampImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::SetTime>
|
||||
// Sets the timestamp to now, plus an offset in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
void TimeStampImpl::SetTime
|
||||
(
|
||||
int32 _milliseconds // = 0
|
||||
)
|
||||
{
|
||||
int64 offset = ((int64)_milliseconds) * 10000LL; // Timestamp is stored in 100ns steps.
|
||||
|
||||
GetSystemTimeAsFileTime( (FILETIME*)&m_stamp );
|
||||
m_stamp += offset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::TimeRemaining>
|
||||
// Gets the difference between now and the timestamp time in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStampImpl::TimeRemaining
|
||||
(
|
||||
)
|
||||
{
|
||||
int64 now;
|
||||
GetSystemTimeAsFileTime( (FILETIME*)&now );
|
||||
|
||||
return (int32)( ( m_stamp - now ) / 10000LL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::GetAsString>
|
||||
// Return a string representation
|
||||
//-----------------------------------------------------------------------------
|
||||
string TimeStampImpl::GetAsString
|
||||
(
|
||||
)
|
||||
{
|
||||
// Convert m_stamp (FILETIME) to SYSTEMTIME for ease of use
|
||||
SYSTEMTIME time;
|
||||
::FileTimeToSystemTime( (FILETIME*)m_stamp, &time );
|
||||
|
||||
char buf[100];
|
||||
sprintf_s( buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d:%03d ", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds );
|
||||
string str = buf;
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <TimeStampImpl::operator->
|
||||
// Overload the subtract operator to get the difference between two
|
||||
// timestamps in milliseconds
|
||||
//-----------------------------------------------------------------------------
|
||||
int32 TimeStampImpl::operator-
|
||||
(
|
||||
TimeStampImpl const& _other
|
||||
)
|
||||
{
|
||||
return (int32)( ( m_stamp - _other.m_stamp ) / 10000LL );
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// TimeStampImpl.h
|
||||
//
|
||||
// Windows implementation of a TimeStamp
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _TimeStampImpl_H
|
||||
#define _TimeStampImpl_H
|
||||
|
||||
#include "../../Defs.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows implementation of a timestamp.
|
||||
*/
|
||||
class TimeStampImpl
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* Creates a TimeStampImpl object.
|
||||
*/
|
||||
TimeStampImpl();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Destroys the TimeStampImpl object.
|
||||
*/
|
||||
~TimeStampImpl();
|
||||
|
||||
/**
|
||||
* SetTime. Sets the timestamp to now, plus the offset in milliseconds.
|
||||
* \param _milliseconds positive or negative offset from
|
||||
* now in milliseconds.
|
||||
*/
|
||||
void SetTime( int32 _milliseconds );
|
||||
|
||||
/**
|
||||
* TimeRemaining. Gets the difference between now and the timestamp
|
||||
* time in milliseconds.
|
||||
* \return milliseconds remaining until we reach the timestamp. The
|
||||
* return value is negative if the timestamp is in the past.
|
||||
*/
|
||||
int32 TimeRemaining();
|
||||
|
||||
/**
|
||||
* Return as as string
|
||||
*/
|
||||
string GetAsString();
|
||||
|
||||
/**
|
||||
* Overload the subtract operator to get the difference between
|
||||
* two timestamps in milliseconds.
|
||||
*/
|
||||
int32 operator- ( TimeStampImpl const& _other );
|
||||
|
||||
private:
|
||||
TimeStampImpl( TimeStampImpl const& ); // prevent copy
|
||||
TimeStampImpl& operator = ( TimeStampImpl const& ); // prevent assignment
|
||||
|
||||
int64 m_stamp;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_TimeStampImpl_H
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// WaitImpl.cpp
|
||||
//
|
||||
// Windows implementation of an abstract base class for objects we
|
||||
// want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../../Defs.h"
|
||||
#include "../Wait.h"
|
||||
#include "WaitImpl.h"
|
||||
#include "../Log.h"
|
||||
|
||||
using namespace OpenZWave;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::WaitImpl>
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
WaitImpl::WaitImpl
|
||||
(
|
||||
Wait* _owner
|
||||
):
|
||||
m_owner( _owner )
|
||||
{
|
||||
InitializeCriticalSection( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::~WaitImpl>
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
WaitImpl::~WaitImpl
|
||||
(
|
||||
)
|
||||
{
|
||||
DeleteCriticalSection( &m_criticalSection );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::AddWatcher>
|
||||
// Add a watcher to our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitImpl::AddWatcher
|
||||
(
|
||||
Wait::pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
// Add the watcher to our list
|
||||
Watcher watcher;
|
||||
watcher.m_callback = _callback;
|
||||
watcher.m_context = _context;
|
||||
|
||||
EnterCriticalSection( &m_criticalSection );
|
||||
|
||||
m_watchers.push_back( watcher );
|
||||
|
||||
LeaveCriticalSection( &m_criticalSection );
|
||||
|
||||
// If the object is already in a signalled state, notify the watcher immediately
|
||||
if( m_owner->IsSignalled() )
|
||||
{
|
||||
_callback( _context );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::RemoveWatcher>
|
||||
// Remove a watcher from our object.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool WaitImpl::RemoveWatcher
|
||||
(
|
||||
Wait::pfnWaitNotification_t _callback,
|
||||
void* _context
|
||||
)
|
||||
{
|
||||
bool res = false;
|
||||
EnterCriticalSection( &m_criticalSection );
|
||||
|
||||
for( list<Watcher>::iterator it=m_watchers.begin(); it!=m_watchers.end(); ++it )
|
||||
{
|
||||
Watcher const& watcher = *it;
|
||||
if( ( watcher.m_callback == _callback ) && ( watcher.m_context == _context ) )
|
||||
{
|
||||
m_watchers.erase( it );
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &m_criticalSection );
|
||||
return res;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// <WaitImpl::Notify>
|
||||
// Notify all the watchers that the object has become signalled
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitImpl::Notify
|
||||
(
|
||||
)
|
||||
{
|
||||
EnterCriticalSection( &m_criticalSection );
|
||||
|
||||
for( list<Watcher>::iterator it=m_watchers.begin(); it!=m_watchers.end(); ++it )
|
||||
{
|
||||
Watcher const& watcher = *it;
|
||||
watcher.m_callback( watcher.m_context );
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &m_criticalSection );
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// WaitImpl.h
|
||||
//
|
||||
// Windows implementation of a base class for objects we
|
||||
// want to be able to wait for.
|
||||
//
|
||||
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// SOFTWARE NOTICE AND LICENSE
|
||||
//
|
||||
// This file is part of OpenZWave.
|
||||
//
|
||||
// OpenZWave is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License,
|
||||
// or (at your option) any later version.
|
||||
//
|
||||
// OpenZWave is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _WaitImpl_H
|
||||
#define _WaitImpl_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <list>
|
||||
#include "../../Defs.h"
|
||||
#include "../Ref.h"
|
||||
#include "../Wait.h"
|
||||
|
||||
namespace OpenZWave
|
||||
{
|
||||
/** \brief Windows specific implementation of Wait objects.
|
||||
*/
|
||||
class WaitImpl
|
||||
{
|
||||
private:
|
||||
friend class Wait;
|
||||
|
||||
WaitImpl( Wait* _owner );
|
||||
virtual ~WaitImpl();
|
||||
|
||||
void AddWatcher( Wait::pfnWaitNotification_t _callback, void* _context );
|
||||
bool RemoveWatcher( Wait::pfnWaitNotification_t _callback, void* _context );
|
||||
void Notify();
|
||||
|
||||
static int32 Multiple( Wait** _objects, uint32 _numObjects, int32 _timeout = -1 );
|
||||
|
||||
WaitImpl( Wait const& ); // prevent copy
|
||||
WaitImpl& operator = ( WaitImpl const& ); // prevent assignment
|
||||
|
||||
struct Watcher
|
||||
{
|
||||
Wait::pfnWaitNotification_t m_callback;
|
||||
void* m_context;
|
||||
};
|
||||
|
||||
list<Watcher> m_watchers;
|
||||
Wait* m_owner;
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
};
|
||||
|
||||
} // namespace OpenZWave
|
||||
|
||||
#endif //_WaitImpl_H
|
||||
|
||||
Reference in new issue
Block a user