diff options
Diffstat (limited to 'www/domoticz/files/patch-pr6252')
| -rw-r--r-- | www/domoticz/files/patch-pr6252 | 2178 | 
1 files changed, 0 insertions, 2178 deletions
| diff --git a/www/domoticz/files/patch-pr6252 b/www/domoticz/files/patch-pr6252 deleted file mode 100644 index 34c4efd3f4e4..000000000000 --- a/www/domoticz/files/patch-pr6252 +++ /dev/null @@ -1,2178 +0,0 @@ -Fix for boost 1.87 - -Removed the diff for the msbuild project files, didn't apply cleanly and not relevant anyway. -This will merged in the next stable of domoticz. - -Pullrequest: https://github.com/domoticz/domoticz/pull/6252 -Patch: https://patch-diff.githubusercontent.com/raw/domoticz/domoticz/pull/6252.patch-diff - -diff --git hardware/ASyncSerial.cpp hardware/ASyncSerial.cpp -index 52c950d..6147cdb 100644 ---- hardware/ASyncSerial.cpp -+++ hardware/ASyncSerial.cpp -@@ -54,7 +54,7 @@ public: -   { -   } -  --    boost::asio::io_service io; ///< Io service object -+    boost::asio::io_context io; ///< Io service object -     boost::asio::serial_port port; ///< Serial port object -     boost::thread backgroundThread; ///< Thread that runs read/write operations -     bool open{ false };		    ///< True if port open -@@ -117,10 +117,10 @@ void AsyncSerial::open(const std::string& devname, unsigned int baud_rate, - 		throw; - 	} -  --	pimpl->io.reset(); -+	pimpl->io.restart(); -  --	// This gives some work to the io_service before it is started --	pimpl->io.post([this] { return doRead(); }); -+	// This gives some work to the io_context before it is started -+	boost::asio::post(pimpl->io, [this] { return doRead(); }); -  - 	boost::thread t([p = &pimpl->io] { p->run(); }); - 	pimpl->backgroundThread.swap(t); -@@ -149,10 +149,10 @@ void AsyncSerial::openOnlyBaud(const std::string& devname, unsigned int baud_rat - 		throw; - 	} -  --	pimpl->io.reset(); -+	pimpl->io.restart(); -  --	//This gives some work to the io_service before it is started --	pimpl->io.post([this] { return doRead(); }); -+	//This gives some work to the io_context before it is started -+	boost::asio::post(pimpl->io, [this] { return doRead(); }); -  - 	boost::thread t([p = &pimpl->io] { p->run(); }); - 	pimpl->backgroundThread.swap(t); -@@ -176,9 +176,9 @@ void AsyncSerial::close() -     if(!isOpen()) return; -  -     pimpl->open = false; --    pimpl->io.post([this] { doClose(); }); -+    boost::asio::post(pimpl->io, [this] { doClose(); }); -     pimpl->backgroundThread.join(); --    pimpl->io.reset(); -+    pimpl->io.restart(); -     if(errorStatus()) -     { -         throw(boost::system::system_error(boost::system::error_code(), -@@ -192,7 +192,7 @@ void AsyncSerial::write(const char *data, size_t size) -         std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); -         pimpl->writeQueue.insert(pimpl->writeQueue.end(),data,data+size); -     } --    pimpl->io.post([this] { doWrite(); }); -+    boost::asio::post(pimpl->io, [this] { doWrite(); }); - } -  - void AsyncSerial::write(const std::string &data) -@@ -201,7 +201,7 @@ void AsyncSerial::write(const std::string &data) - 		std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); - 		pimpl->writeQueue.insert(pimpl->writeQueue.end(), data.c_str(), data.c_str()+data.size()); - 	} --	pimpl->io.post([this] { doWrite(); }); -+	boost::asio::post(pimpl->io, [this] { doWrite(); }); - } -  - void AsyncSerial::write(const std::vector<char>& data) -@@ -211,7 +211,7 @@ void AsyncSerial::write(const std::vector<char>& data) -         pimpl->writeQueue.insert(pimpl->writeQueue.end(),data.begin(), -                 data.end()); -     } --    pimpl->io.post([this] { doWrite(); }); -+    boost::asio::post(pimpl->io, [this] { doWrite(); }); - } -  - void AsyncSerial::writeString(const std::string& s) -@@ -220,7 +220,7 @@ void AsyncSerial::writeString(const std::string& s) -         std::lock_guard<std::mutex> l(pimpl->writeQueueMutex); -         pimpl->writeQueue.insert(pimpl->writeQueue.end(),s.begin(),s.end()); -     } --    pimpl->io.post([this] { doWrite(); }); -+    boost::asio::post(pimpl->io, [this] { doWrite(); }); - } -  - void AsyncSerial::doRead() -diff --git hardware/ASyncSerial.h hardware/ASyncSerial.h -index 0a51ef0..de83f8a 100644 ---- hardware/ASyncSerial.h -+++ hardware/ASyncSerial.h -@@ -123,27 +123,27 @@ class AsyncSerial : private domoticz::noncopyable -  - 	/** - 	 * Callback called to start an asynchronous read operation. --	 * This callback is called by the io_service in the spawned thread. -+	 * This callback is called by the io_context in the spawned thread. - 	 */ - 	void doRead(); -  - 	/** - 	 * Callback called at the end of the asynchronous operation. --	 * This callback is called by the io_service in the spawned thread. -+	 * This callback is called by the io_context in the spawned thread. - 	 */ - 	void readEnd(const boost::system::error_code &error, size_t bytes_transferred); -  - 	/** - 	 * Callback called to start an asynchronous write operation. - 	 * If it is already in progress, does nothing. --	 * This callback is called by the io_service in the spawned thread. -+	 * This callback is called by the io_context in the spawned thread. - 	 */ - 	void doWrite(); -  - 	/** - 	 * Callback called at the end of an asynchronuous write operation, - 	 * if there is more data to write, restarts a new write operation. --	 * This callback is called by the io_service in the spawned thread. -+	 * This callback is called by the io_context in the spawned thread. - 	 */ - 	void writeEnd(const boost::system::error_code &error); -  -diff --git hardware/ASyncTCP.cpp hardware/ASyncTCP.cpp -index a375561..7c3b536 100644 ---- hardware/ASyncTCP.cpp -+++ hardware/ASyncTCP.cpp -@@ -4,213 +4,241 @@ - #include <boost/system/error_code.hpp>     // for error_code - #include "../main/Logger.h" -  --struct hostent; -- - #define MAX_TCP_BUFFER_SIZE 4096 -  --#ifndef WIN32 --	#include <unistd.h> //gethostbyname --#endif -- - #define STATUS_OK(err) !err -- --ASyncTCP::ASyncTCP(const bool secure) -+#define STATUS_ERR(err) err -+ -+ASyncTCP::ASyncTCP(const bool secure) : -+	m_Tcpwork(boost::asio::make_work_guard(m_io_context)) -+	, m_Socket(m_io_context) -+	, m_Resolver(m_io_context) -+	, m_ReconnectTimer(m_io_context) -+	, m_TimeoutTimer(m_io_context) -+	, m_SendStrand(m_io_context) - #ifdef WWW_ENABLE_SSL --	: mSecure(secure) -+	, m_bSecure(secure) - #endif - { - 	m_pRXBuffer = new uint8_t[MAX_TCP_BUFFER_SIZE]; - #ifdef WWW_ENABLE_SSL - 	mContext.set_verify_mode(boost::asio::ssl::verify_none); --	if (mSecure)  -+	if (m_bSecure) - 	{ --		mSslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(mIos, mContext)); -+		m_SslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_context, mContext)); - 	} - #endif - } -  - ASyncTCP::~ASyncTCP() - { --	assert(mTcpthread == nullptr); --	mIsTerminating = true; --	if (mTcpthread) -+	assert(m_Tcpthread == nullptr); -+	m_bIsTerminating = true; -+	if (m_Tcpthread) - 	{ - 		//This should never happen. terminate() never called!! --		_log.Log(LOG_ERROR, "ASyncTCP: Workerthread not closed. terminate() never called!!!"); --		mIos.stop(); --		if (mTcpthread) -+		_log.Log(LOG_ERROR, "ASyncTCP: Worker thread not closed. terminate() never called!!!"); -+		m_io_context.stop(); -+		if (m_Tcpthread) - 		{ --			mTcpthread->join(); --			mTcpthread.reset(); -+			m_Tcpthread->join(); -+			m_Tcpthread.reset(); - 		} - 	} - 	if (m_pRXBuffer != nullptr) - 		delete[] m_pRXBuffer; - } -  --void ASyncTCP::SetReconnectDelay(int32_t Delay) -+void ASyncTCP::SetReconnectDelay(const int32_t Delay) - { --	mReconnectDelay = Delay; -+	m_iReconnectDelay = Delay; - } -  - void ASyncTCP::connect(const std::string& ip, uint16_t port) - { --	assert(!mSocket.is_open()); --	if (mSocket.is_open()) -+	assert(!m_Socket.is_open()); -+	if (m_Socket.is_open()) - 	{ - 		_log.Log(LOG_ERROR, "ASyncTCP: connect called while socket is still open. !!!"); - 		terminate(); - 	} -  --	// RK: We reset mIos here because it might have been stopped in terminate() --	mIos.reset(); --	// RK: After the reset, we need to provide it work anew --	mTcpwork = std::make_shared<boost::asio::io_service::work>(mIos); --	if (!mTcpthread) --		mTcpthread = std::make_shared<std::thread>([p = &mIos] { p->run(); }); -- --	mIp = ip; --	mPort = port; -+	m_IP = ip; -+	m_Port = port; - 	std::string port_str = std::to_string(port); --	boost::asio::ip::tcp::resolver::query query(ip, port_str); - 	timeout_start_timer(); --	mResolver.async_resolve(query, [this](auto &&err, auto &&iter) { cb_resolve_done(err, iter); }); -+ -+	m_Resolver.async_resolve( -+		ip, port_str, -+		[this](const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type& endpoints) { -+			handle_resolve(error, endpoints); -+		} -+	); -+ -+	// RK: We restart m_io_context here because it might have been stopped in terminate() -+	m_io_context.restart(); -+	// RK: After the reset, we need to provide it work anew -+	m_Tcpwork.reset(); -+	m_Tcpwork.emplace(boost::asio::make_work_guard(m_io_context)); -+	if (!m_Tcpthread) -+		m_Tcpthread = std::make_shared<std::thread>([p = &m_io_context] { p->run(); }); - } -  --void ASyncTCP::cb_resolve_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) -+void ASyncTCP::handle_resolve(const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type &endpoints) - { --	if (mIsTerminating) return; -+	if (m_bIsTerminating) return; -  --	if (STATUS_OK(error)) --	{ --		connect_start(endpoint_iterator); --	} --	else -+	if (STATUS_ERR(error)) - 	{ - 		process_error(error); -+		return; - 	} --} -- --void ASyncTCP::connect_start(boost::asio::ip::tcp::resolver::iterator& endpoint_iterator) --{ --	if (mIsConnected) return; -- --	mEndPoint = *endpoint_iterator++; -+	if (m_bIsConnected) return; -  - 	timeout_start_timer(); -+ - #ifdef WWW_ENABLE_SSL --	if (mSecure) -+	if (m_bSecure) - 	{ - 		// we reset the ssl socket, because the ssl context needs to be reinitialized after a reconnect --		mSslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(mIos, mContext)); --		mSslSocket->lowest_layer().async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); }); -+		m_SslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_context, mContext)); -+		boost::asio::async_connect(m_SslSocket->lowest_layer(), endpoints, -+			[this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint) -+			{ -+				handle_connect(error, endpoint); -+			} -+		); - 	} - 	else - #endif - 	{ --		mSocket.async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); }); -+		boost::asio::async_connect(m_Socket, endpoints, -+			[this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint) -+			{ -+				handle_connect(error, endpoint); -+			} -+		); - 	} - } -  --void ASyncTCP::cb_connect_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) -+void ASyncTCP::handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& /*endpoint*/) - { --	if (mIsTerminating) return; -+	if (m_bIsTerminating) return; -  --	if (STATUS_OK(error)) -+	if (STATUS_ERR(error)) - 	{ -+		process_error(error); -+		return; -+	} - #ifdef WWW_ENABLE_SSL --		if (mSecure)  --		{ --			timeout_start_timer(); --			mSslSocket->async_handshake(boost::asio::ssl::stream_base::client, [this](auto &&err) { cb_handshake_done(err); }); --		} --		else --#endif --		{ --			process_connection(); --		} -+	if (m_bSecure) -+	{ -+		timeout_start_timer(); -+		m_SslSocket->async_handshake(boost::asio::ssl::stream_base::client, -+			[this](const boost::system::error_code& error) { -+				cb_handshake_done(error); -+			} -+		); - 	} --	else  -+	else -+#endif - 	{ --		if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator())  --		{ --			// The connection failed. Try the next endpoint in the list. --			connect_start(endpoint_iterator); --			return; --		} --		process_error(error); -+		process_connection(); - 	} - } -  - #ifdef WWW_ENABLE_SSL - void ASyncTCP::cb_handshake_done(const boost::system::error_code& error) - { --	if (mIsTerminating) return; -+	if (m_bIsTerminating) return; -  --	if (STATUS_OK(error)) --	{ --		process_connection(); --	} --	else -+	if (STATUS_ERR(error)) - 	{ - 		process_error(error); -+		return; - 	} -+	process_connection(); -+#endif - } -+ -+void ASyncTCP::process_connection() -+{ -+	m_bIsConnected = true; -+#ifdef WWW_ENABLE_SSL -+ -+	if (!m_bSecure) - #endif -+	{ -+		// RK: only if non-secure -+		boost::asio::socket_base::keep_alive option(true); -+		m_Socket.set_option(option); -+	} -+	OnConnect(); -+	do_read_start(); -+	do_write_start(); -+} -  - void ASyncTCP::reconnect_start_timer() - { --	if (mIsReconnecting) return; -+	if (m_bIsReconnecting) return; -  --	if (mReconnectDelay != 0) -+	if (m_iReconnectDelay != 0) - 	{ --		mIsReconnecting = true; -- --		mReconnectTimer.expires_from_now(boost::posix_time::seconds(mReconnectDelay)); --		mReconnectTimer.async_wait([this](auto &&err) { cb_reconnect_start(err); }); -+		m_bIsReconnecting = true; -+ -+		m_ReconnectTimer.expires_from_now(boost::posix_time::seconds(m_iReconnectDelay)); -+		m_ReconnectTimer.async_wait( -+			[this](const boost::system::error_code& error) { -+				cb_reconnect_start(error); -+			} -+		); - 	} - } -  - void ASyncTCP::cb_reconnect_start(const boost::system::error_code& error) - { --	mIsReconnecting = false; --	mReconnectTimer.cancel(); --	mTimeoutTimer.cancel(); -+	m_bIsReconnecting = false; -+	m_ReconnectTimer.cancel(); -+	m_TimeoutTimer.cancel(); -  --	if (mIsConnected) return; -+	if (m_bIsConnected) return; - 	if (error) return; // timer was cancelled -  - 	do_close(); --	connect(mIp, mPort); -+	connect(m_IP, m_Port); - } -  -  - void ASyncTCP::terminate(const bool silent) - { --	mIsTerminating = true; -+	m_bIsTerminating = true; - 	disconnect(silent); --	mTcpwork.reset(); --	mIos.stop(); --	if (mTcpthread) -+	m_Tcpwork.reset(); -+	m_io_context.stop(); -+	if (m_Tcpthread) - 	{ --		mTcpthread->join(); --		mTcpthread.reset(); -+		m_Tcpthread->join(); -+		m_Tcpthread.reset(); - 	} --	mIsReconnecting = false; --	mIsConnected = false; --	mWriteQ.clear(); --	mIsTerminating = false; -+	m_bIsReconnecting = false; -+	m_bIsConnected = false; -+	m_WriteQ.clear(); -+	m_bIsTerminating = false; - } -  - void ASyncTCP::disconnect(const bool silent) - { --	mReconnectTimer.cancel(); --	mTimeoutTimer.cancel(); --	if (!mTcpthread) return; -+	m_ReconnectTimer.cancel(); -+	m_TimeoutTimer.cancel(); -+	if (!m_Tcpthread) return; -  - 	try - 	{ --		mIos.post([this] { do_close(); }); -+		boost::asio::post(m_io_context,  -+			[this] { -+				do_close(); -+			} -+		); - 	} - 	catch (...) - 	{ -@@ -223,62 +251,68 @@ void ASyncTCP::disconnect(const bool silent) -  - void ASyncTCP::do_close() - { --	if (mIsReconnecting) { -+	if (m_bIsReconnecting) { - 		return; - 	} --	mReconnectTimer.cancel(); --	mTimeoutTimer.cancel(); -+	m_ReconnectTimer.cancel(); -+	m_TimeoutTimer.cancel(); - 	boost::system::error_code ec; - #ifdef WWW_ENABLE_SSL --	if (mSecure) -+	if (m_bSecure) - 	{ --		if (mSslSocket->lowest_layer().is_open()) -+		if (m_SslSocket->lowest_layer().is_open()) - 		{ --			mSslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); --			mSslSocket->lowest_layer().close(ec); -+			m_SslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); -+			m_SslSocket->lowest_layer().close(ec); - 		} - 	} - 	else - #endif - 	{ --		if (mSocket.is_open()) -+		if (m_Socket.is_open()) - 		{ --			mSocket.close(ec); -+			m_Socket.close(ec); - 		} - 	} - } -  - void ASyncTCP::do_read_start() - { --	if (mIsTerminating) return; --	if (!mIsConnected) return; -+	if (m_bIsTerminating) return; -+	if (!m_bIsConnected) return; -  - 	timeout_start_timer(); - #ifdef WWW_ENABLE_SSL --	if (mSecure) -+	if (m_bSecure) - 	{ --		mSslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); }); -+		m_SslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), -+			[this](const boost::system::error_code& error, size_t bytes_transferred) { -+				cb_read_done(error, bytes_transferred); -+			} -+		); - 	} - 	else - #endif - 	{ --		mSocket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); }); -+		m_Socket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), -+			[this](const boost::system::error_code& error, size_t bytes_transferred) { -+				cb_read_done(error, bytes_transferred); -+			} -+		); - 	} - } -  - void ASyncTCP::cb_read_done(const boost::system::error_code& error, size_t bytes_transferred) - { --	if (mIsTerminating) return; -+	if (m_bIsTerminating) return; -  --	if (STATUS_OK(error)) --	{ --		OnData(m_pRXBuffer, bytes_transferred); --		do_read_start(); --	} --	else -+	if (STATUS_ERR(error)) - 	{ - 		process_error(error); -+		return; - 	} -+	OnData(m_pRXBuffer, bytes_transferred); -+	do_read_start(); - } -  - void ASyncTCP::write(const uint8_t* pData, size_t length) -@@ -288,77 +322,66 @@ void ASyncTCP::write(const uint8_t* pData, size_t length) -  - void ASyncTCP::write(const std::string& msg) - { --	if (!mTcpthread) return; -+	if (!m_Tcpthread) return; -  --	mSendStrand.post([this, msg]() { cb_write_queue(msg); }); -+	boost::asio::post(m_SendStrand, [this, msg]() { cb_write_queue(msg); }); - } -  - void ASyncTCP::cb_write_queue(const std::string& msg) - { --	mWriteQ.push_back(msg); -+	m_WriteQ.push_back(msg); -  --	if (mWriteQ.size() == 1) -+	if (m_WriteQ.size() == 1) - 		do_write_start(); - } -  - void ASyncTCP::do_write_start() - { --	if (mIsTerminating) return; --	if (!mIsConnected) return; --	if (mWriteQ.empty()) -+	if (m_bIsTerminating) return; -+	if (!m_bIsConnected) return; -+	if (m_WriteQ.empty()) - 		return; -  - 	timeout_start_timer(); - #ifdef WWW_ENABLE_SSL --	if (mSecure)  -+	if (m_bSecure) - 	{ --		boost::asio::async_write(*mSslSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); }); -+		boost::asio::async_write(*m_SslSocket, boost::asio::buffer(m_WriteQ.front()), -+			[this](const boost::system::error_code& error, std::size_t length) { -+				cb_write_done(error, length); -+			} -+		); - 	} - 	else - #endif - 	{ --		boost::asio::async_write(mSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); }); -+		boost::asio::async_write(m_Socket, boost::asio::buffer(m_WriteQ.front()), -+			[this](const boost::system::error_code& error, std::size_t length) { -+				cb_write_done(error, length); -+			} -+		); - 	} - } -  --void ASyncTCP::cb_write_done(const boost::system::error_code& error) -+void ASyncTCP::cb_write_done(const boost::system::error_code& error, std::size_t /*length*/) - { --	if (mIsTerminating) return; -+	if (m_bIsTerminating) return; -  --	if (STATUS_OK(error)) --	{ --		mWriteQ.pop_front(); --		do_write_start(); --	} --	else -+	if (STATUS_ERR(error)) - 	{ - 		process_error(error); -+		return; - 	} --} -- --void ASyncTCP::process_connection() --{ --	mIsConnected = true; --#ifdef WWW_ENABLE_SSL -- --	if (!mSecure) --#endif --	{ --		// RK: only if non-secure --		boost::asio::socket_base::keep_alive option(true); --		mSocket.set_option(option); --	} --	OnConnect(); --	do_read_start(); -+	m_WriteQ.pop_front(); - 	do_write_start(); - } -  - void ASyncTCP::process_error(const boost::system::error_code& error) - { - 	do_close(); --	if (mIsConnected) -+	if (m_bIsConnected) - 	{ --		mIsConnected = false; -+		m_bIsConnected = false; - 		OnDisconnect(); - 	} -  -@@ -369,20 +392,23 @@ void ASyncTCP::process_error(const boost::system::error_code& error) - 	reconnect_start_timer(); - } -  --/* timeout methods */ - void ASyncTCP::timeout_start_timer() - { --	if (0 == mTimeoutDelay) { -+	if (0 == m_iTimeoutDelay) { - 		return; - 	} - 	timeout_cancel_timer(); --	mTimeoutTimer.expires_from_now(boost::posix_time::seconds(mTimeoutDelay)); --	mTimeoutTimer.async_wait([this](auto &&err) { timeout_handler(err); }); -+	m_TimeoutTimer.expires_from_now(boost::posix_time::seconds(m_iTimeoutDelay)); -+	m_TimeoutTimer.async_wait( -+		[this](const boost::system::error_code& error) { -+			timeout_handler(error); -+		} -+	); - } -  - void ASyncTCP::timeout_cancel_timer() - { --	mTimeoutTimer.cancel(); -+	m_TimeoutTimer.cancel(); - } -  - void ASyncTCP::timeout_handler(const boost::system::error_code& error) -@@ -397,5 +423,5 @@ void ASyncTCP::timeout_handler(const boost::system::error_code& error) -  - void ASyncTCP::SetTimeout(const uint32_t Timeout) - { --	mTimeoutDelay = Timeout; -+	m_iTimeoutDelay = Timeout; - } -diff --git hardware/ASyncTCP.h hardware/ASyncTCP.h -index cf859bb..a8b3ae2 100644 ---- hardware/ASyncTCP.h -+++ hardware/ASyncTCP.h -@@ -3,39 +3,31 @@ - #include <stddef.h>			 // for size_t - #include <deque>			 // for write queue - #include <boost/asio/deadline_timer.hpp> // for deadline_timer --#include <boost/asio/io_service.hpp>	 // for io_service -+#include <boost/asio/io_context.hpp>	 // for io_context - #include <boost/asio/strand.hpp>	 // for strand - #include <boost/asio/ip/tcp.hpp>	 // for tcp, tcp::endpoint, tcp::s... - #include <boost/asio/ssl.hpp>		 // for secure sockets - #include <boost/asio/ssl/stream.hpp>	 // for secure sockets - #include <exception>			  // for exception -+#include <optional>			// for optional -  - #define ASYNCTCP_THREAD_NAME "ASyncTCP" - #define DEFAULT_RECONNECT_TIME 30 - #define DEFAULT_TIMEOUT_TIME 60 -  --namespace boost --{ --	namespace system --	{ --		class error_code; --	} // namespace system --} // namespace boost -- - class ASyncTCP - { --      protected: -+protected: - 	ASyncTCP(bool secure = false); - 	virtual ~ASyncTCP(); -- --	void connect(const std::string &hostname, uint16_t port); -+	void connect(const std::string& hostname, uint16_t port); - 	void disconnect(bool silent = true); --	void write(const std::string &msg); --	void write(const uint8_t *pData, size_t length); --	void SetReconnectDelay(int32_t Delay = DEFAULT_RECONNECT_TIME); -+	void write(const std::string& msg); -+	void write(const uint8_t* pData, size_t length); -+	void SetReconnectDelay(const int32_t Delay = DEFAULT_RECONNECT_TIME); - 	bool isConnected() - 	{ --		return mIsConnected; -+		return m_bIsConnected; - 	}; - 	void terminate(bool silent = true); - 	void SetTimeout(uint32_t Timeout = DEFAULT_TIMEOUT_TIME); -@@ -43,65 +35,61 @@ class ASyncTCP - 	// Callback interface to implement in derived classes - 	virtual void OnConnect() = 0; - 	virtual void OnDisconnect() = 0; --	virtual void OnData(const uint8_t *pData, size_t length) = 0; --	virtual void OnError(const boost::system::error_code &error) = 0; -- --	boost::asio::io_service mIos; // protected to allow derived classes to attach timers etc. -+	virtual void OnData(const uint8_t* pData, size_t length) = 0; -+	virtual void OnError(const boost::system::error_code& error) = 0; -  --      private: --	void cb_resolve_done(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); --	void connect_start(boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); --	void cb_connect_done(const boost::system::error_code &error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); -+	boost::asio::io_context m_io_context; // protected to allow derived classes to attach timers etc. -+private: -+	void handle_resolve(const boost::system::error_code& ec, const boost::asio::ip::tcp::resolver::results_type &results); -+	void handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint); - #ifdef WWW_ENABLE_SSL --	void cb_handshake_done(const boost::system::error_code &error); -+	void cb_handshake_done(const boost::system::error_code& error); - #endif -  --	/* timeout methods */ - 	void timeout_start_timer(); - 	void timeout_cancel_timer(); - 	void reconnect_start_timer(); --	void timeout_handler(const boost::system::error_code &error); -+	void timeout_handler(const boost::system::error_code& error); -  --	void cb_reconnect_start(const boost::system::error_code &error); -+	void cb_reconnect_start(const boost::system::error_code& error); -  - 	void do_close(); -  - 	void do_read_start(); --	void cb_read_done(const boost::system::error_code &error, size_t bytes_transferred); -+	void cb_read_done(const boost::system::error_code& error, size_t bytes_transferred); -  --	void cb_write_queue(const std::string &msg); -+	void cb_write_queue(const std::string& msg); - 	void do_write_start(); --	void cb_write_done(const boost::system::error_code &error); -+	void cb_write_done(const boost::system::error_code& error, size_t length); -  - 	void process_connection(); --	void process_error(const boost::system::error_code &error); -+	void process_error(const boost::system::error_code& error); -  --	bool mIsConnected = false; --	bool mIsReconnecting = false; --	bool mIsTerminating = false; -+	bool m_bIsConnected = false; -+	bool m_bIsReconnecting = false; -+	bool m_bIsTerminating = false; -  --	boost::asio::io_service::strand mSendStrand{ mIos }; --	std::deque<std::string> mWriteQ; // we need a write queue to allow concurrent writes -+	boost::asio::io_context::strand m_SendStrand; -+	std::deque<std::string> m_WriteQ; // we need a write queue to allow concurrent writes -  - 	uint8_t* m_pRXBuffer = nullptr; -  --	int mReconnectDelay = DEFAULT_RECONNECT_TIME; --	int mTimeoutDelay = 0; --	boost::asio::deadline_timer mReconnectTimer{ mIos }; --	boost::asio::deadline_timer mTimeoutTimer{ mIos }; -+	int m_iReconnectDelay = DEFAULT_RECONNECT_TIME; -+	int m_iTimeoutDelay = 0; -+	boost::asio::deadline_timer m_ReconnectTimer; -+	boost::asio::deadline_timer m_TimeoutTimer; -  --	std::shared_ptr<std::thread> mTcpthread; --	std::shared_ptr<boost::asio::io_service::work> mTcpwork; -+	std::shared_ptr<std::thread> m_Tcpthread; -+	std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_Tcpwork; -  - #ifdef WWW_ENABLE_SSL --	const bool mSecure; -+	const bool m_bSecure; - 	boost::asio::ssl::context mContext{ boost::asio::ssl::context::sslv23 }; --	std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> mSslSocket; // the ssl socket -+	std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> m_SslSocket; - #endif --	boost::asio::ip::tcp::socket mSocket{ mIos }; --	boost::asio::ip::tcp::endpoint mEndPoint; --	boost::asio::ip::tcp::resolver mResolver{ mIos }; -+	boost::asio::ip::tcp::socket m_Socket; -+	boost::asio::ip::tcp::resolver m_Resolver; -  --	std::string mIp; --	uint16_t mPort; -+	std::string m_IP; -+	uint16_t m_Port; - }; -diff --git hardware/Arilux.cpp hardware/Arilux.cpp -index 400f5a3..20bc373 100644 ---- hardware/Arilux.cpp -+++ hardware/Arilux.cpp -@@ -79,7 +79,7 @@ void Arilux::InsertUpdateSwitch(const std::string &lightName, const int subType, - { - 	uint32_t sID; - 	try { --		sID = boost::asio::ip::address_v4::from_string(location).to_ulong(); -+		sID = boost::asio::ip::make_address_v4(location).to_uint(); - 	} catch (const std::exception &e) { - 		Log(LOG_ERROR, "Bad IP address: %s (%s)", location.c_str(), e.what()); - 		return; -@@ -112,8 +112,8 @@ bool Arilux::SendTCPCommand(uint32_t ip,std::vector<unsigned char> &command) - 	sum = sum & 0xFF; - 	command.push_back((unsigned char)sum); -  --	boost::asio::io_service io_service; --	boost::asio::ip::tcp::socket sendSocket(io_service); -+	boost::asio::io_context io_context; -+	boost::asio::ip::tcp::socket sendSocket(io_context); - 	boost::asio::ip::address_v4 address(ip); - 	boost::asio::ip::tcp::endpoint endpoint(address, 5577); - 	try -diff --git hardware/Kodi.cpp hardware/Kodi.cpp -index b528017..5ababf6 100644 ---- hardware/Kodi.cpp -+++ hardware/Kodi.cpp -@@ -143,14 +143,14 @@ _eNotificationTypes	CKodiNode::CKodiStatus::NotificationType() - 	} - } -  --CKodiNode::CKodiNode(boost::asio::io_service *pIos, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs, -+CKodiNode::CKodiNode(boost::asio::io_context *pIoc, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs, - 	const std::string& pID, const std::string& pName, const std::string& pIP, const std::string& pPort) - { - 	m_Busy = false; - 	m_Stoppable = false; - 	m_PlaylistPosition = 0; -  --	m_Ios = pIos; -+	m_Ioc = pIoc; - 	m_HwdID = pHwdID; - 	m_DevID = atoi(pID.c_str()); - 	sprintf(m_szDevID, "%X%02X%02X%02X", 0, 0, (m_DevID & 0xFF00) >> 8, m_DevID & 0xFF); -@@ -581,11 +581,10 @@ void CKodiNode::handleConnect() - 		{ - 			m_iMissedPongs = 0; - 			boost::system::error_code ec; --			boost::asio::ip::tcp::resolver resolver(*m_Ios); --			boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); --			auto iter = resolver.resolve(query); --			boost::asio::ip::tcp::endpoint endpoint = *iter; --			m_Socket = new boost::asio::ip::tcp::socket(*m_Ios); -+			boost::asio::ip::tcp::resolver resolver(*m_Ioc); -+			auto iter = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); -+			boost::asio::ip::tcp::endpoint endpoint = *iter.begin(); -+			m_Socket = new boost::asio::ip::tcp::socket(*m_Ioc); - 			m_Socket->connect(endpoint, ec); - 			if (!ec) - 			{ -@@ -975,19 +974,19 @@ void CKodi::Do_Work() - 					_log.Log(LOG_NORM, "Kodi: (%s) - Restarting thread.", node->m_Name.c_str()); - 					boost::thread *tAsync = new boost::thread(&CKodiNode::Do_Work, node); - 					SetThreadName(tAsync->native_handle(), "KodiNode"); --					m_ios.stop(); -+					m_ioc.stop(); - 				} - 				if (node->IsOn()) - 					bWorkToDo = true; - 			} -  --			if (bWorkToDo && m_ios.stopped())  // make sure that there is a boost thread to service i/o operations -+			if (bWorkToDo && m_ioc.stopped())  // make sure that there is a boost thread to service i/o operations - 			{ --				m_ios.reset(); -+				m_ioc.restart(); - 				// Note that this is the only thread that handles async i/o so we don't - 				// need to worry about locking or concurrency issues when processing messages - 				_log.Log(LOG_NORM, "Kodi: Restarting I/O service thread."); --				boost::thread bt([p = &m_ios] { p->run(); }); -+				boost::thread bt([p = &m_ioc] { p->run(); }); - 				SetThreadName(bt.native_handle(), "KodiIO"); - 			} - 		} -@@ -1138,7 +1137,7 @@ void CKodi::ReloadNodes() - { - 	UnloadNodes(); -  --	m_ios.reset();	// in case this is not the first time in -+	m_ioc.restart();	// in case this is not the first time in -  - 	std::vector<std::vector<std::string> > result; - 	result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID); -@@ -1149,7 +1148,7 @@ void CKodi::ReloadNodes() - 		// create a vector to hold the nodes - 		for (const auto &sd : result) - 		{ --			auto pNode = std::make_shared<CKodiNode>(&m_ios, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]); -+			auto pNode = std::make_shared<CKodiNode>(&m_ioc, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]); - 			m_pNodes.push_back(pNode); - 		} - 		// start the threads to control each kodi -@@ -1161,7 +1160,7 @@ void CKodi::ReloadNodes() - 		} - 		sleep_milliseconds(100); - 		_log.Log(LOG_NORM, "Kodi: Starting I/O service thread."); --		boost::thread bt([p = &m_ios] { p->run(); }); -+		boost::thread bt([p = &m_ioc] { p->run(); }); - 		SetThreadName(bt.native_handle(), "KodiIO"); - 	} - } -@@ -1170,10 +1169,10 @@ void CKodi::UnloadNodes() - { - 	std::lock_guard<std::mutex> l(m_mutex); -  --	m_ios.stop();	// stop the service if it is running -+	m_ioc.stop();	// stop the service if it is running - 	sleep_milliseconds(100); -  --	while (((!m_pNodes.empty()) || (!m_ios.stopped()))) -+	while (((!m_pNodes.empty()) || (!m_ioc.stopped()))) - 	{ - 		for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt) - 		{ -diff --git hardware/Kodi.h hardware/Kodi.h -index 14f331c..4435740 100644 ---- hardware/Kodi.h -+++ hardware/Kodi.h -@@ -150,7 +150,7 @@ class CKodiNode : public std::enable_shared_from_this<CKodiNode>, StoppableTask - 	}; -  -       public: --	CKodiNode(boost::asio::io_service *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &); -+	CKodiNode(boost::asio::io_context *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &); - 	~CKodiNode(); - 	void Do_Work(); - 	void SendCommand(const std::string &); -@@ -207,7 +207,7 @@ class CKodiNode : public std::enable_shared_from_this<CKodiNode>, StoppableTask - 	int m_iPollIntSec; - 	int m_iMissedPongs; - 	std::string m_sLastMessage; --	boost::asio::io_service *m_Ios; -+	boost::asio::io_context *m_Ioc; - 	boost::asio::ip::tcp::socket *m_Socket; - 	std::array<char, 256> m_Buffer; - }; -@@ -243,5 +243,5 @@ class CKodi : public CDomoticzHardwareBase - 	int m_iPingTimeoutms; - 	std::shared_ptr<std::thread> m_thread; - 	std::mutex m_mutex; --	boost::asio::io_service m_ios; -+	boost::asio::io_context m_ioc; - }; -diff --git hardware/MQTTAutoDiscover.h hardware/MQTTAutoDiscover.h -index 0832664..1501d6f 100644 ---- hardware/MQTTAutoDiscover.h -+++ hardware/MQTTAutoDiscover.h -@@ -176,7 +176,7 @@ public: - 	void on_message(const struct mosquitto_message *message) override; - 	void on_connect(int rc) override; - 	void on_disconnect(int rc) override; --	void on_going_down(); -+	void on_going_down() override; - private: - 	void InsertUpdateSwitch(_tMQTTASensor* pSensor); -  -diff --git hardware/PanasonicTV.cpp hardware/PanasonicTV.cpp -index fc57d34..ce20565 100644 ---- hardware/PanasonicTV.cpp -+++ hardware/PanasonicTV.cpp -@@ -356,18 +356,17 @@ std::string CPanasonicNode::handleWriteAndRead(const std::string& pMessageToSend - { -  - 	_log.Debug(DEBUG_HARDWARE, "Panasonic Plugin: (%s) Handling message: '%s'.", m_Name.c_str(), pMessageToSend.c_str()); --	boost::asio::io_service io_service; -+	boost::asio::io_context io_context; - 	// Get a list of endpoints corresponding to the server name. --	boost::asio::ip::tcp::resolver resolver(io_service); --	boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); --	auto iter = resolver.resolve(query); -+	boost::asio::ip::tcp::resolver resolver(io_context); -+	auto endpoints = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1))); -+	auto iter = endpoints.begin(); - 	boost::asio::ip::tcp::endpoint endpoint = *iter; --	boost::asio::ip::tcp::resolver::iterator end; -  - 	// Try each endpoint until we successfully establish a connection. --	boost::asio::ip::tcp::socket socket(io_service); -+	boost::asio::ip::tcp::socket socket(io_context); - 	boost::system::error_code error = boost::asio::error::host_not_found; --	while (error && iter != end) -+	while (error && iter != endpoints.end()) - 	{ - 		socket.close(); - 		if (handleConnect(socket, *iter, error)) -@@ -1060,7 +1059,7 @@ void CPanasonic::ReloadNodes() - { - 	UnloadNodes(); -  --	//m_ios.reset();	// in case this is not the first time in -+	//m_ioc.reset();	// in case this is not the first time in -  - 	std::vector<std::vector<std::string> > result; - 	result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID); -@@ -1088,10 +1087,10 @@ void CPanasonic::UnloadNodes() - { - 	std::lock_guard<std::mutex> l(m_mutex); -  --	m_ios.stop();	// stop the service if it is running -+	m_ioc.stop();	// stop the service if it is running - 	sleep_milliseconds(100); -  --	while (((!m_pNodes.empty()) || (!m_ios.stopped()))) -+	while (((!m_pNodes.empty()) || (!m_ioc.stopped()))) - 	{ - 		for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt) - 		{ -diff --git hardware/PanasonicTV.h hardware/PanasonicTV.h -index b0a94ff..30e1ca1 100644 ---- hardware/PanasonicTV.h -+++ hardware/PanasonicTV.h -@@ -39,7 +39,7 @@ class CPanasonic : public CDomoticzHardwareBase - 	bool m_bTryIfOff; - 	std::shared_ptr<std::thread> m_thread; - 	std::mutex m_mutex; --	boost::asio::io_service m_ios; -+	boost::asio::io_context m_ioc; -  - 	friend class CPanasonicNode;  - }; -diff --git hardware/Pinger.cpp hardware/Pinger.cpp -index a66c7a1..e070b29 100644 ---- hardware/Pinger.cpp -+++ hardware/Pinger.cpp -@@ -21,23 +21,23 @@ - #if BOOST_VERSION >= 107000 - #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) - #else --#define GET_IO_SERVICE(s) ((s).get_io_service()) -+#define GET_IO_SERVICE(s) ((s).get_io_context()) - #endif -  - class pinger - 	: private domoticz::noncopyable - { - public: --  pinger(boost::asio::io_service &io_service, const char *destination, const int iPingTimeoutms) -+  pinger(boost::asio::io_context &io_context, const char *destination, const int iPingTimeoutms) - 	  : num_replies_(0) - 	  , m_PingState(false) --	  , resolver_(io_service) --	  , socket_(io_service, boost::asio::ip::icmp::v4()) --	  , timer_(io_service) -+	  , resolver_(io_context) -+	  , socket_(io_context, boost::asio::ip::icmp::v4()) -+	  , timer_(io_context) - 	  , sequence_number_(0) -   { --	  boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), destination, ""); --	  destination_ = *resolver_.resolve(query); -+	  auto endpoints = resolver_.resolve(boost::asio::ip::icmp::v4(), destination, ""); -+	  destination_ = endpoints.begin()->endpoint(); -  - 	  num_tries_ = 1; - 	  PingTimeoutms_ = iPingTimeoutms; -@@ -332,11 +332,11 @@ void CPinger::ReloadNodes() - void CPinger::Do_Ping_Worker(const PingNode &Node) - { - 	bool bPingOK = false; --	boost::asio::io_service io_service; -+	boost::asio::io_context io_context; - 	try - 	{ --		pinger p(io_service, Node.IP.c_str(), m_iPingTimeoutms); --		io_service.run(); -+		pinger p(io_context, Node.IP.c_str(), m_iPingTimeoutms); -+		io_context.run(); - 		if (p.m_PingState == true) - 		{ - 			bPingOK = true; -diff --git hardware/RFLinkMQTT.h hardware/RFLinkMQTT.h -index e938328..72433b8 100644 ---- hardware/RFLinkMQTT.h -+++ hardware/RFLinkMQTT.h -@@ -46,7 +46,7 @@ protected: - 	boost::signals2::connection m_sDeviceReceivedConnection; - 	boost::signals2::connection m_sSwitchSceneConnection; - 	void selectNextIPAdress( void ); --	virtual bool WriteInt(const std::string &sendString); // override; -+	bool WriteInt(const std::string &sendString) override; - 	void Do_Work(); - 	virtual void SendHeartbeat(); - 	void StopMQTT(); -diff --git hardware/TCPProxy/tcpproxy_server.cpp hardware/TCPProxy/tcpproxy_server.cpp -index 8aceb0b..d77d4bf 100644 ---- hardware/TCPProxy/tcpproxy_server.cpp -+++ hardware/TCPProxy/tcpproxy_server.cpp -@@ -18,12 +18,12 @@ - #if BOOST_VERSION >= 107000 - #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) - #else --#define GET_IO_SERVICE(s) ((s).get_io_service()) -+#define GET_IO_SERVICE(s) ((s).get_io_context()) - #endif -  - namespace tcp_proxy - { --	bridge::bridge(boost::asio::io_service& ios) -+	bridge::bridge(boost::asio::io_context& ios) -       : downstream_socket_(ios), -         upstream_socket_(ios) - 	{ -@@ -44,7 +44,7 @@ namespace tcp_proxy - 		boost::asio::ip::tcp::endpoint end; -  -  --		boost::asio::io_service &ios= GET_IO_SERVICE(downstream_socket_); -+		boost::asio::io_context &ios= GET_IO_SERVICE(downstream_socket_); - 		boost::asio::ip::tcp::resolver resolver(ios); - 		boost::asio::ip::tcp::resolver::query query(upstream_host, upstream_port, boost::asio::ip::resolver_query_base::numeric_service); - 		auto i = resolver.resolve(query); -@@ -137,10 +137,10 @@ namespace tcp_proxy - 	} - //Acceptor Class - 	acceptor::acceptor(const std::string &local_host, unsigned short local_port, const std::string &upstream_host, const std::string &upstream_port) --		: io_service_() -+		: io_context_() - 		, m_bDoStop(false) - 		, localhost_address(boost::asio::ip::address_v4::from_string(local_host)) --		, acceptor_(io_service_, boost::asio::ip::tcp::endpoint(localhost_address, local_port)) -+		, acceptor_(io_context_, boost::asio::ip::tcp::endpoint(localhost_address, local_port)) - 		, upstream_host_(upstream_host) - 		, upstream_port_(upstream_port) - 	{ -@@ -151,7 +151,7 @@ namespace tcp_proxy - 	{ - 		try - 		{ --			session_ = std::make_shared<bridge>(io_service_); -+			session_ = std::make_shared<bridge>(io_context_); - 			session_->sDownstreamData.connect([this](auto d, auto l) { OnDownstreamData(d, l); }); - 			session_->sUpstreamData.connect([this](auto d, auto l) { OnUpstreamData(d, l); }); -  -@@ -169,11 +169,11 @@ namespace tcp_proxy - 		m_bDoStop=false; -  - 		accept_connections(); --		// The io_service::run() call will block until all asynchronous operations -+		// The io_context::run() call will block until all asynchronous operations - 		// have finished. While the server is running, there is always at least one - 		// asynchronous operation outstanding: the asynchronous accept call waiting - 		// for new incoming connections. --		io_service_.run(); -+		io_context_.run(); - 		return true; - 	} - 	bool acceptor::stop() -@@ -181,14 +181,14 @@ namespace tcp_proxy - 		m_bDoStop=true; - 		// Post a call to the stop function so that server::stop() is safe to call - 		// from any thread. --		io_service_.post([this] { handle_stop(); }); -+		io_context_.post([this] { handle_stop(); }); - 		return true; - 	} -  - 	void acceptor::handle_stop() - 	{ - 		// The server is stopped by canceling all outstanding asynchronous --		// operations. Once all operations have finished the io_service::run() call -+		// operations. Once all operations have finished the io_context::run() call - 		// will exit. - 		acceptor_.close(); - 		//connection_manager_.stop_all(); -diff --git hardware/TCPProxy/tcpproxy_server.h hardware/TCPProxy/tcpproxy_server.h -index 3d1a150..148e65f 100644 ---- hardware/TCPProxy/tcpproxy_server.h -+++ hardware/TCPProxy/tcpproxy_server.h -@@ -10,7 +10,7 @@ namespace tcp_proxy - 	class bridge : public std::enable_shared_from_this<bridge> - 	{ - 	public: --		explicit bridge(boost::asio::io_service& ios); -+		explicit bridge(boost::asio::io_context& ios); - 		boost::asio::ip::tcp::socket& downstream_socket(); - 		boost::asio::ip::tcp::socket& upstream_socket(); -  -@@ -52,8 +52,8 @@ namespace tcp_proxy - 		void OnUpstreamData(const unsigned char *pData, size_t Len); - 		void OnDownstreamData(const unsigned char *pData, size_t Len); -  --		/// The io_service used to perform asynchronous operations. --		boost::asio::io_service io_service_; -+		/// The io_context used to perform asynchronous operations. -+		boost::asio::io_context io_context_; - 		bool m_bDoStop; - 		boost::asio::ip::address_v4 localhost_address; - 		boost::asio::ip::tcp::acceptor acceptor_; -diff --git hardware/XiaomiDeviceSupport.h hardware/XiaomiDeviceSupport.h -index fad7884..4a76d96 100644 ---- hardware/XiaomiDeviceSupport.h -+++ hardware/XiaomiDeviceSupport.h -@@ -15,6 +15,7 @@ - class XiaomiDeviceSupport - { -       public: -+	virtual ~XiaomiDeviceSupport() = default; - 	/** - 	 * Method to get 'model' corresponding to the ID of the device in case the Gateway API didn't provide it. - 	 * -diff --git hardware/XiaomiGateway.cpp hardware/XiaomiGateway.cpp -index 66acdc5..fb4387a 100644 ---- hardware/XiaomiGateway.cpp -+++ hardware/XiaomiGateway.cpp -@@ -538,12 +538,12 @@ bool XiaomiGateway::SendMessageToGateway(const std::string &controlmessage) - { - 	std::string message = controlmessage; - 	bool result = true; --	boost::asio::io_service io_service; --	boost::asio::ip::udp::socket socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)); -+	boost::asio::io_context io_context; -+	boost::asio::ip::udp::socket socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)); - 	stdreplace(message, "@gatewaykey", GetGatewayKey()); - 	std::shared_ptr<std::string> message1(new std::string(message)); - 	boost::asio::ip::udp::endpoint remote_endpoint_; --	remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(m_GatewayIp), 9898); -+	remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(m_GatewayIp), 9898); - 	socket_.send_to(boost::asio::buffer(*message1), remote_endpoint_); - 	sleep_milliseconds(150); // TODO: reduce or remove sleep - 	std::array<char, 512> recv_buffer_; -@@ -1015,15 +1015,14 @@ bool XiaomiGateway::StopHardware() - void XiaomiGateway::Do_Work() - { - 	Log(LOG_STATUS, "XiaomiGateway (ID=%d): Worker started...", m_HwdID); --	boost::asio::io_service io_service; -+	boost::asio::io_context io_context; - 	// Find the local ip address that is similar to the xiaomi gateway - 	try - 	{ --		boost::asio::ip::udp::resolver resolver(io_service); --		boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), m_GatewayIp, ""); --		auto endpoints = resolver.resolve(query); --		boost::asio::ip::udp::endpoint ep = *endpoints; --		boost::asio::ip::udp::socket socket(io_service); -+		boost::asio::ip::udp::resolver resolver(io_context); -+		auto endpoints = resolver.resolve(boost::asio::ip::udp::v4(), m_GatewayIp, ""); -+		boost::asio::ip::udp::endpoint ep = *endpoints.begin(); -+		boost::asio::ip::udp::socket socket(io_context); - 		socket.connect(ep); - 		boost::asio::ip::address addr = socket.local_endpoint().address(); - 		std::string compareIp = m_GatewayIp.substr(0, (m_GatewayIp.length() - 3)); -@@ -1073,11 +1072,11 @@ void XiaomiGateway::Do_Work() - 		} - 	} -  --	XiaomiGateway::xiaomi_udp_server udp_server(io_service, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this); -+	XiaomiGateway::xiaomi_udp_server udp_server(io_context, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this); - 	boost::thread bt; - 	if (m_ListenPort9898) - 	{ --		bt = boost::thread([p = &io_service] { p->run(); }); -+		bt = boost::thread([p = &io_context] { p->run(); }); - 		SetThreadName(bt.native_handle(), "XiaomiGatewayIO"); - 	} -  -@@ -1094,7 +1093,7 @@ void XiaomiGateway::Do_Work() - 			// Log(LOG_STATUS, "sec_counter %d", sec_counter); - 		} - 	} --	io_service.stop(); -+	io_context.stop(); - 	if (bt.joinable()) - 	{ - 		bt.join(); -@@ -1178,9 +1177,9 @@ unsigned int XiaomiGateway::GetShortID(const std::string &nodeid) - 	return sID; - } -  --XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898, -+XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898, - 						    const bool outputMessage, const bool includeVoltage, XiaomiGateway *parent) --	: socket_(io_service, boost::asio::ip::udp::v4()) -+	: socket_(io_context, boost::asio::ip::udp::v4()) - { - 	m_HardwareID = m_HwdID; - 	m_XiaomiGateway = parent; -@@ -1196,8 +1195,8 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_ - 			if (!m_localip.empty()) - 			{ - 				boost::system::error_code ec; --				boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(m_localip, ec); --				boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string("224.0.0.50", ec); -+				boost::asio::ip::address listen_addr = boost::asio::ip::make_address_v4(m_localip, ec); -+				boost::asio::ip::address mcast_addr = boost::asio::ip::make_address_v4("224.0.0.50", ec); - 				boost::asio::ip::udp::endpoint listen_endpoint(mcast_addr, 9898); -  - 				socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898)); -@@ -1213,9 +1212,9 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_ - 				socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898)); - 				std::shared_ptr<std::string> message(new std::string(R"({"cmd":"whois"})")); - 				boost::asio::ip::udp::endpoint remote_endpoint; --				remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("224.0.0.50"), 4321); -+				remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("224.0.0.50"), 4321); - 				socket_.send_to(boost::asio::buffer(*message), remote_endpoint); --				socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string("224.0.0.50"))); -+				socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4("224.0.0.50"))); - 			} - 		} - 		catch (const boost::system::system_error &ex) -@@ -1720,7 +1719,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error - 					message.append("\"}"); - 					std::shared_ptr<std::string> message1(new std::string(message)); - 					boost::asio::ip::udp::endpoint remote_endpoint; --					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898); -+					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898); - 					socket_.send_to(boost::asio::buffer(*message1), remote_endpoint); - 				} - 			} -@@ -1746,7 +1745,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error - 					std::string message = R"({"cmd" : "get_id_list"})"; - 					std::shared_ptr<std::string> message2(new std::string(message)); - 					boost::asio::ip::udp::endpoint remote_endpoint; --					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898); -+					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898); - 					socket_.send_to(boost::asio::buffer(*message2), remote_endpoint); - 				} - 			} -diff --git hardware/XiaomiGateway.h hardware/XiaomiGateway.h -index dce4b34..1f552f3 100644 ---- hardware/XiaomiGateway.h -+++ hardware/XiaomiGateway.h -@@ -100,7 +100,7 @@ class XiaomiGateway : public CDomoticzHardwareBase - 	class xiaomi_udp_server - 	{ - 	      public: --		xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage, -+		xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage, - 				  bool includeVolage, XiaomiGateway *parent); - 		~xiaomi_udp_server() = default; -  -diff --git hardware/Yeelight.cpp hardware/Yeelight.cpp -index cdb7889..e5fe8fc 100644 ---- hardware/Yeelight.cpp -+++ hardware/Yeelight.cpp -@@ -93,8 +93,8 @@ void Yeelight::Do_Work() -  - 	try - 	{ --		boost::asio::io_service io_service; --		udp_server server(io_service, m_HwdID); -+		boost::asio::io_context io_context; -+		udp_server server(io_context, m_HwdID); - 		int sec_counter = YEELIGHT_POLL_INTERVAL - 5; - 		while (!IsStopRequested(1000)) - 		{ -@@ -105,7 +105,7 @@ void Yeelight::Do_Work() - 			if (sec_counter % 60 == 0) //poll YeeLights every minute - 			{ - 				server.start_send(); --				io_service.run(); -+				io_context.run(); - 			} - 		} - 	} -@@ -227,12 +227,11 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length) -  - 	try - 	{ --		boost::asio::io_service io_service; --		boost::asio::ip::tcp::socket sendSocket(io_service); --		boost::asio::ip::tcp::resolver resolver(io_service); --		boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), szTmp, "55443"); --		auto iterator = resolver.resolve(query); --		boost::asio::connect(sendSocket, iterator); -+		boost::asio::io_context io_context; -+		boost::asio::ip::tcp::socket sendSocket(io_context); -+		boost::asio::ip::tcp::resolver resolver(io_context); -+		auto endpoints = resolver.resolve(boost::asio::ip::tcp::v4(), szTmp, "55443"); -+		boost::asio::connect(sendSocket, endpoints); -  - 		std::string message; - 		std::string message2; -@@ -404,8 +403,8 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length) - std::array<char, 1024> recv_buffer_; - int hardwareId; -  --Yeelight::udp_server::udp_server(boost::asio::io_service& io_service, int m_HwdID) --	: socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) -+Yeelight::udp_server::udp_server(boost::asio::io_context& io_context, int m_HwdID) -+	: socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) - { - 	socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true)); - 	socket_.set_option(boost::asio::socket_base::broadcast(true)); -@@ -421,7 +420,7 @@ void Yeelight::udp_server::start_send() - 		//Log(LOG_STATUS, "start_send.................."); - 		std::shared_ptr<std::string> message( - 			new std::string(testMessage)); --		remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("239.255.255.250"), 1982); -+		remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("239.255.255.250"), 1982); - 		socket_.send_to(boost::asio::buffer(*message), remote_endpoint_); - 		sleep_milliseconds(150); - 		start_receive(); -diff --git hardware/Yeelight.h hardware/Yeelight.h -index fb03c28..3b7b4c3 100644 ---- hardware/Yeelight.h -+++ hardware/Yeelight.h -@@ -25,7 +25,7 @@ class Yeelight : public CDomoticzHardwareBase - 	class udp_server - 	{ - 	      public: --		udp_server(boost::asio::io_service &io_service, int m_HwdID); -+		udp_server(boost::asio::io_context &io_context, int m_HwdID); - 		boost::asio::ip::udp::socket socket_; - 		boost::asio::ip::udp::endpoint remote_endpoint_; - 		void start_send(); -diff --git hardware/plugins/PluginManager.cpp hardware/plugins/PluginManager.cpp -index 2813112..423edbb 100644 ---- hardware/plugins/PluginManager.cpp -+++ hardware/plugins/PluginManager.cpp -@@ -64,7 +64,7 @@ namespace Plugins { - 	// PyMODINIT_FUNC PyInit_DomoticzEvents(void); -  - 	std::mutex PluginMutex;	// controls accessto the message queue and m_pPlugins map --	boost::asio::io_service ios; -+	boost::asio::io_context ios; -  - 	std::map<int, CDomoticzHardwareBase*>	CPluginSystem::m_pPlugins; - 	std::map<std::string, std::string>		CPluginSystem::m_PluginXml; -@@ -315,7 +315,7 @@ namespace Plugins { - 		// Create initial IO Service thread - 		ios.restart(); - 		// Create some work to keep IO Service alive --		auto work = boost::asio::io_service::work(ios); -+		auto work = boost::asio::make_work_guard(ios); - 		boost::thread_group BoostThreads; - 		for (int i = 0; i < 1; i++) - 		{ -diff --git hardware/plugins/PluginTransports.cpp hardware/plugins/PluginTransports.cpp -index 52d14e7..f7ace0f 100644 ---- hardware/plugins/PluginTransports.cpp -+++ hardware/plugins/PluginTransports.cpp -@@ -116,15 +116,14 @@ namespace Plugins { - 				m_bConnected = false; - 				m_Socket = new boost::asio::ip::tcp::socket(ios); -  --				boost::system::error_code ec; --				boost::asio::ip::tcp::resolver::query query(m_IP, m_Port); --				auto iter = m_Resolver.resolve(query); --				boost::asio::ip::tcp::endpoint endpoint = *iter; -- - 				// - 				//	Async resolve/connect based on http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/http/client/async_client.cpp - 				// --				m_Resolver.async_resolve(query, [this](auto &&err, auto end) { handleAsyncResolve(err, end); }); -+				m_Resolver.async_resolve(m_IP, m_Port, -+					[this](auto &&err, auto endpoints) { -+						handleAsyncResolve(err, endpoints); -+					} -+				); - 			} - 		} - 		catch (std::exception& e) -@@ -139,15 +138,14 @@ namespace Plugins { - 		return true; - 	} -  --	void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) -+	void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::results_type endpoints) - 	{ - 		CPlugin*		pPlugin = ((CConnection*)m_pConnection)->pPlugin; - 		AccessPython	Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve"); -  - 		if (!err) - 		{ --			boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator; --			m_Socket->async_connect(endpoint, [this, endpoint_iterator](auto &&err) mutable { handleAsyncConnect(err, ++endpoint_iterator); }); -+			boost::asio::async_connect(*m_Socket, endpoints, [this](auto &&err, const boost::asio::ip::tcp::endpoint &endpoint) mutable { handleAsyncConnect(err, endpoint); }); - 		} - 		else - 		{ -@@ -169,7 +167,7 @@ namespace Plugins { - 		} - 	} -  --	void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) -+	void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) - 	{ - 		CPlugin*		pPlugin = ((CConnection*)m_pConnection)->pPlugin; - 		AccessPython	Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve"); -@@ -481,7 +479,7 @@ namespace Plugins { - 		} - 	}; -  --	void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) -+	void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) - 	{ - 		CPlugin* pPlugin = ((CConnection*)m_pConnection)->pPlugin; - 		if (!pPlugin) return; -@@ -498,7 +496,7 @@ namespace Plugins { - 			SSL_set_tlsext_host_name(m_TLSSock->native_handle(), m_IP.c_str());			// Enable SNI -  - 			m_TLSSock->set_verify_mode(boost::asio::ssl::verify_none); --			m_TLSSock->set_verify_callback(boost::asio::ssl::rfc2818_verification(m_IP)); -+			m_TLSSock->set_verify_callback(boost::asio::ssl::host_name_verification(m_IP)); - 			// m_TLSSock->set_verify_callback([this](auto v, auto &c){ VerifyCertificate(v, c);}); - 			try - 			{ -@@ -648,7 +646,7 @@ namespace Plugins { - 					// Hanlde multicast - 					if (((m_IP.substr(0, 4) >= "224.") && (m_IP.substr(0, 4) <= "239.")) || (m_IP.substr(0, 4) == "255.")) - 					{ --						m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(m_IP.c_str())), ec); -+						m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4(m_IP.c_str())), ec); - 						m_Socket->set_option(boost::asio::ip::multicast::hops(2), ec); - 					} - 				} -@@ -764,7 +762,7 @@ namespace Plugins { - 			} - 			else - 			{ --				boost::asio::ip::udp::endpoint destination(boost::asio::ip::address::from_string(m_IP.c_str()), atoi(m_Port.c_str())); -+				boost::asio::ip::udp::endpoint destination(boost::asio::ip::make_address_v4(m_IP.c_str()), atoi(m_Port.c_str())); - 				size_t bytes_transferred = m_Socket->send_to(boost::asio::buffer(pMessage, pMessage.size()), destination); - 			} - 		} -@@ -825,12 +823,14 @@ namespace Plugins { - 		} - 	}; -  --	void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator) -+	void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, boost::asio::ip::icmp::resolver::results_type endpoints) - 	{ - 		if (!ec) - 		{ -+			m_Endpoint = endpoints.begin()->endpoint(); -+			m_IP = m_Endpoint.address().to_string(); -+ - 			m_bConnected = true; --			m_IP = endpoint_iterator->endpoint().address().to_string(); -  - 			// Listen will fail (10022 - bad parameter) unless something has been sent(?) - 			std::string body("ping"); -@@ -857,15 +857,11 @@ namespace Plugins { - 				m_bConnecting = true; - 				m_Socket = new boost::asio::ip::icmp::socket(ios, boost::asio::ip::icmp::v4()); -  --				boost::system::error_code ec; --				boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), m_IP, ""); --				auto iter = m_Resolver.resolve(query); --				m_Endpoint = *iter; -- --				// --				//	Async resolve/connect based on http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/example/icmp/ping.cpp --				// --				m_Resolver.async_resolve(query, [this](auto &&err, auto i) { handleAsyncResolve(err, i); }); -+				m_Resolver.async_resolve(boost::asio::ip::icmp::v4(), m_IP, "", -+					[this](auto &&err, auto endpoints) { -+						handleAsyncResolve(err, endpoints); -+					} -+				); - 			} - 			else - 			{ -diff --git hardware/plugins/PluginTransports.h hardware/plugins/PluginTransports.h -index c1cc1e3..79d5725 100644 ---- hardware/plugins/PluginTransports.h -+++ hardware/plugins/PluginTransports.h -@@ -6,7 +6,7 @@ -  - namespace Plugins { -  --	extern boost::asio::io_service ios; -+	extern boost::asio::io_context ios; -  - 	class CPluginTransport - 	{ -@@ -85,8 +85,8 @@ namespace Plugins { - 		  , m_Socket(nullptr){}; - 	  bool handleConnect() override; - 	  bool handleListen() override; --	  virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); --	  virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator); -+	  virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::results_type endpoints); -+	  virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint); - 	  virtual void handleAsyncAccept(boost::asio::ip::tcp::socket *pSocket, const boost::system::error_code &error); - 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; - 	  void handleWrite(const std::vector<byte> &pMessage) override; -@@ -111,7 +111,7 @@ namespace Plugins { - 		  : CPluginTransportTCP(HwdID, pConnection, Address, Port) - 		  , m_Context(nullptr) - 		  , m_TLSSock(nullptr){}; --	  void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) override; -+	  void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) override; - 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; - 	  void handleWrite(const std::vector<byte> &pMessage) override; - 	  ~CPluginTransportTCPSecure() override; -@@ -151,7 +151,7 @@ namespace Plugins { - 		  , m_Socket(nullptr) - 		  , m_Timer(nullptr) - 		  , m_SequenceNo(-1){}; --	  void handleAsyncResolve(const boost::system::error_code &err, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator); -+	  void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::icmp::resolver::results_type endpoints); - 	  bool handleListen() override; - 	  void handleTimeout(const boost::system::error_code &) override; - 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override; -diff --git main/WebServerCmds.cpp main/WebServerCmds.cpp -index 7d4a9f2..3586373 100644 ---- main/WebServerCmds.cpp -+++ main/WebServerCmds.cpp -@@ -1632,7 +1632,7 @@ namespace http - 			ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision)); - 			ExtraHeaders.push_back("System_Name: " + systemname); - 			ExtraHeaders.push_back("Machine: " + machine); --			ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta"); -+			ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta")); -  - 			if (!HTTPClient::GET(szHistoryURL, ExtraHeaders, historyfile)) - 			{ -diff --git main/mainworker.cpp main/mainworker.cpp -index b5027eb..b8f8dc7 100644 ---- main/mainworker.cpp -+++ main/mainworker.cpp -@@ -1318,7 +1318,7 @@ bool MainWorker::IsUpdateAvailable(const bool bIsForced) - 	ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision)); - 	ExtraHeaders.push_back("System_Name: " + m_szSystemName); - 	ExtraHeaders.push_back("Machine: " + machine); --	ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta"); -+	ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta")); -  - 	if (!HTTPClient::GET(szURL, ExtraHeaders, revfile)) - 		return false; -diff --git plugins/examples/Pinger.py plugins/examples/Pinger.py -index 6b54559..c7a776d 100644 ---- plugins/examples/Pinger.py -+++ plugins/examples/Pinger.py -@@ -3,7 +3,7 @@ - #           Author:     Dnpwwo, 2017 - 2018 - # - """ --<plugin key="ICMP" name="Pinger (ICMP)" author="dnpwwo" version="3.1.4"> -+<plugin key="ICMP" name="Pinger (ICMP)" author="dnpwwo" version="3.1.5"> -     <description> - ICMP Pinger Plugin.<br/><br/> - Specify comma delimted addresses (IP or DNS names) of devices that are to be pinged.<br/> -@@ -144,8 +144,9 @@ class BasePlugin: -             for Device in Devices: -                 if (("Name" in Devices[Device].Options) and (Devices[Device].Options["Name"] == Connection.Name)): -                     UpdateDevice(Device, 0, "Off", TimedOut) --        self.icmpConn.Close() --        self.icmpConn = None -+        if (self.icmpConn != None): -+            self.icmpConn.Close() -+            self.icmpConn = None -  -     def onHeartbeat(self): -         Domoticz.Debug("Heartbeating...") -diff --git push/MQTTPush.h push/MQTTPush.h -index 0773b43..d9f9332 100644 ---- push/MQTTPush.h -+++ push/MQTTPush.h -@@ -14,7 +14,7 @@ public: - 	void on_message(const struct mosquitto_message* message) override; - 	void on_connect(int rc) override; - 	void on_disconnect(int rc) override; --	void on_going_down(); -+	void on_going_down() override; - private: - 	struct _tPushItem - 	{ -diff --git tcpserver/TCPClient.cpp tcpserver/TCPClient.cpp -index d55da10..3eee093 100644 ---- tcpserver/TCPClient.cpp -+++ tcpserver/TCPClient.cpp -@@ -19,7 +19,7 @@ namespace tcp { - 			delete socket_; - 		} -  --		CTCPClient::CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase* pManager) -+		CTCPClient::CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase* pManager) - 			: CTCPClientBase(pManager) - 		{ - 			socket_ = new boost::asio::ip::tcp::socket(ios); -diff --git tcpserver/TCPClient.h tcpserver/TCPClient.h -index df4350d..e7a882b 100644 ---- tcpserver/TCPClient.h -+++ tcpserver/TCPClient.h -@@ -38,7 +38,7 @@ class CTCPClient : public CTCPClientBase, - 	public std::enable_shared_from_this<CTCPClient> - { - public: --	CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase *pManager); -+	CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase *pManager); - 	~CTCPClient() = default; - 	void start() override; - 	void stop() override; -diff --git tcpserver/TCPServer.cpp tcpserver/TCPServer.cpp -index 91fdc7e..57f8709 100644 ---- tcpserver/TCPServer.cpp -+++ tcpserver/TCPServer.cpp -@@ -18,14 +18,14 @@ namespace tcp { -  - 		CTCPServerInt::CTCPServerInt(const std::string& address, const std::string& port, CTCPServer* pRoot) : - 			CTCPServerIntBase(pRoot), --			io_service_(), --			acceptor_(io_service_) -+			io_context_(), -+			acceptor_(io_context_) - 		{ - 			// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). --			boost::asio::ip::tcp::resolver resolver(io_service_); --			boost::asio::ip::tcp::resolver::query query(address, port); --			boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); --			acceptor_.open(endpoint.protocol()); -+			boost::asio::ip::tcp::resolver resolver(io_context_); -+			boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type endpoints = resolver.resolve(address, port); -+			auto endpoint = *endpoints.begin(); -+			acceptor_.open(endpoint.endpoint().protocol()); - 			acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - 			// bind to both ipv6 and ipv4 sockets for the "::" address only - 			if (address == "::") -@@ -35,7 +35,7 @@ namespace tcp { - 			acceptor_.bind(endpoint); - 			acceptor_.listen(); -  --			new_connection_ = std::make_shared<CTCPClient>(io_service_, this); -+			new_connection_ = std::make_shared<CTCPClient>(io_context_, this); - 			if (new_connection_ == nullptr) - 			{ - 				_log.Log(LOG_ERROR, "Error creating new client!"); -@@ -47,24 +47,24 @@ namespace tcp { -  - 		void CTCPServerInt::start() - 		{ --			// The io_service::run() call will block until all asynchronous operations -+			// The io_context::run() call will block until all asynchronous operations - 			// have finished. While the server is running, there is always at least one - 			// asynchronous operation outstanding: the asynchronous accept call waiting - 			// for new incoming connections. --			io_service_.run(); -+			io_context_.run(); - 		} -  - 		void CTCPServerInt::stop() - 		{ - 			// Post a call to the stop function so that server::stop() is safe to call - 			// from any thread. --			io_service_.post([this] { handle_stop(); }); -+			boost::asio::post([this] { handle_stop(); }); - 		} -  - 		void CTCPServerInt::handle_stop() - 		{ - 			// The server is stopped by cancelling all outstanding asynchronous --			// operations. Once all operations have finished the io_service::run() call -+			// operations. Once all operations have finished the io_context::run() call - 			// will exit. - 			acceptor_.close(); - 			stopAllClients(); -@@ -88,7 +88,7 @@ namespace tcp { - 			connections_.insert(new_connection_); - 			new_connection_->start(); -  --			new_connection_.reset(new CTCPClient(io_service_, this)); -+			new_connection_.reset(new CTCPClient(io_context_, this)); -  - 			acceptor_.async_accept(*(new_connection_->socket()), [this](auto&& err) { handleAccept(err); }); - 		} -diff --git tcpserver/TCPServer.h tcpserver/TCPServer.h -index ca611b1..17284ca 100644 ---- tcpserver/TCPServer.h -+++ tcpserver/TCPServer.h -@@ -70,8 +70,8 @@ private: - 	/// Handle a request to stop the server. - 	void handle_stop(); -  --	/// The io_service used to perform asynchronous operations. --	boost::asio::io_service io_service_; -+	/// The io_context used to perform asynchronous operations. -+	boost::asio::io_context io_context_; -  - 	boost::asio::ip::tcp::acceptor acceptor_; -  -diff --git webserver/cWebem.cpp webserver/cWebem.cpp -index 57d9683..c0d292d 100644 ---- webserver/cWebem.cpp -+++ webserver/cWebem.cpp -@@ -47,13 +47,13 @@ namespace http { - 			, myRequestHandler(doc_root, this) - 			// Rene, make sure we initialize m_sessions first, before starting a server - 			, myServer(server_factory::create(settings, myRequestHandler)) --			, m_io_service() --			, m_session_clean_timer(m_io_service, boost::posix_time::minutes(1)) -+			, m_io_context() -+			, m_session_clean_timer(m_io_context, boost::posix_time::minutes(1)) - 		{ - 			// associate handler to timer and schedule the first iteration - 			m_session_clean_timer.async_wait([this](auto &&) { CleanSessions(); }); --			m_io_service_thread = std::make_shared<std::thread>([p = &m_io_service] { p->run(); }); --			SetThreadName(m_io_service_thread->native_handle(), "Webem_ssncleaner"); -+			m_io_context_thread = std::make_shared<std::thread>([p = &m_io_context] { p->run(); }); -+			SetThreadName(m_io_context_thread->native_handle(), "Webem_ssncleaner"); - 		} -  - 		cWebem::~cWebem() -@@ -93,14 +93,14 @@ namespace http { - 			// Stop session cleaner - 			try - 			{ --				if (!m_io_service.stopped()) -+				if (!m_io_context.stopped()) - 				{ --					m_io_service.stop(); -+					m_io_context.stop(); - 				} --				if (m_io_service_thread) -+				if (m_io_context_thread) - 				{ --					m_io_service_thread->join(); --					m_io_service_thread.reset(); -+					m_io_context_thread->join(); -+					m_io_context_thread.reset(); - 				} - 			} - 			catch (...) -diff --git webserver/cWebem.h webserver/cWebem.h -index 6e3b899..7905c45 100644 ---- webserver/cWebem.h -+++ webserver/cWebem.h -@@ -259,9 +259,9 @@ namespace http - 			std::string m_webRoot; - 			/// sessions management - 			std::mutex m_sessionsMutex; --			boost::asio::io_service m_io_service; -+			boost::asio::io_context m_io_context; - 			boost::asio::deadline_timer m_session_clean_timer; --			std::shared_ptr<std::thread> m_io_service_thread; -+			std::shared_ptr<std::thread> m_io_context_thread; - 		}; -  - 	} // namespace server -diff --git webserver/connection.cpp webserver/connection.cpp -index 40f9788..3a70924 100644 ---- webserver/connection.cpp -+++ webserver/connection.cpp -@@ -22,13 +22,13 @@ namespace http { - 		extern time_t last_write_time(const std::string& path); -  - 		// this is the constructor for plain connections --		connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout) -+		connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout) - 			: send_buffer_(nullptr) - 			, read_timeout_(read_timeout) --			, read_timer_(io_service, boost::posix_time::seconds(read_timeout)) -+			, read_timer_(io_context, boost::posix_time::seconds(read_timeout)) - 			, default_abandoned_timeout_(20 * 60) - 			// 20mn before stopping abandoned connection --			, abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_)) -+			, abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_)) - 			, connection_manager_(manager) - 			, request_handler_(handler) - 			, status_(INITIALIZING) -@@ -39,18 +39,18 @@ namespace http { - 			keepalive_ = false; - 			write_in_progress = false; - 			connection_type = ConnectionType::connection_http; --			socket_ = std::make_unique<boost::asio::ip::tcp::socket>(io_service); -+			socket_ = std::make_unique<boost::asio::ip::tcp::socket>(io_context); - 		} -  - #ifdef WWW_ENABLE_SSL - 		// this is the constructor for secure connections --		connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context) -+		connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context) - 			: send_buffer_(nullptr) - 			, read_timeout_(read_timeout) --			, read_timer_(io_service, boost::posix_time::seconds(read_timeout)) -+			, read_timer_(io_context, boost::posix_time::seconds(read_timeout)) - 			, default_abandoned_timeout_(20 * 60) - 			// 20mn before stopping abandoned connection --			, abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_)) -+			, abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_)) - 			, connection_manager_(manager) - 			, request_handler_(handler) - 			, status_(INITIALIZING) -@@ -62,7 +62,7 @@ namespace http { - 			write_in_progress = false; - 			connection_type = ConnectionType::connection_http; - 			socket_ = nullptr; --			sslsocket_ = std::make_unique<ssl_socket>(io_service, context); -+			sslsocket_ = std::make_unique<ssl_socket>(io_context, context); - 		} - #endif -  -@@ -152,9 +152,9 @@ namespace http { - 			if (error != boost::asio::error::operation_aborted) { - 				switch (connection_type) { - 				case ConnectionType::connection_http: --					// Timers should be cancelled before stopping to remove tasks from the io_service. --					// The io_service will stop naturally when every tasks are removed. --					// If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_service::run() caller. -+					// Timers should be cancelled before stopping to remove tasks from the io_context. -+					// The io_context will stop naturally when every tasks are removed. -+					// If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_context::run() caller. - 					cancel_abandoned_timeout(); - 					cancel_read_timeout(); -  -@@ -372,7 +372,7 @@ namespace http { - 				switch (connection_type) - 				{ - 				case ConnectionType::connection_http: --					begin = boost::asio::buffer_cast<const char*>(_buf.data()); -+					begin = static_cast<const char*>(_buf.data().data()); - 					try - 					{ - 						request_parser_.reset(); -@@ -404,7 +404,7 @@ namespace http { - 							newt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - 						} -  --						size_t sizeread = begin - boost::asio::buffer_cast<const char*>(_buf.data()); -+						size_t sizeread = begin - static_cast<const char*>(_buf.data().data()); - 						_buf.consume(sizeread); - 						reply_.reset(); - 						const char* pConnection = request_.get_req_header(&request_, "Connection"); -@@ -520,7 +520,7 @@ namespace http { - 					break; - 				case ConnectionType::connection_websocket: - 				case ConnectionType::connection_websocket_closing: --					begin = boost::asio::buffer_cast<const char*>(_buf.data()); -+					begin = static_cast<const char*>(_buf.data().data()); - 					result = websocket_parser.parse((const unsigned char*)begin, _buf.size(), bytes_consumed, keepalive_); - 					_buf.consume(bytes_consumed); - 					if (result) { -diff --git webserver/connection.hpp webserver/connection.hpp -index ce452b5..c1a82c5 100644 ---- webserver/connection.hpp -+++ webserver/connection.hpp -@@ -43,11 +43,11 @@ namespace http { - 				std::string host_local_endpoint_port_; - 				std::string host_last_request_uri_; - 			}; --			/// Construct a connection with the given io_service. --			explicit connection(boost::asio::io_service& io_service, -+			/// Construct a connection with the given io_context. -+			explicit connection(boost::asio::io_context& io_context, - 				connection_manager& manager, request_handler& handler, int timeout); - #ifdef WWW_ENABLE_SSL --			explicit connection(boost::asio::io_service& io_service, -+			explicit connection(boost::asio::io_context& io_context, - 				connection_manager& manager, request_handler& handler, int timeout, boost::asio::ssl::context& context); - #endif - 			~connection() = default; -diff --git webserver/server.cpp webserver/server.cpp -index da15887..8bdfc13 100644 ---- webserver/server.cpp -+++ webserver/server.cpp -@@ -13,15 +13,15 @@ namespace http { - namespace server { -  - 	server_base::server_base(const server_settings &settings, request_handler &user_request_handler) --		: io_service_() --		, acceptor_(io_service_) -+		: io_context_() -+		, acceptor_(io_context_) - 		, request_handler_(user_request_handler) - 		, settings_(settings) - 		, timeout_(20) - 		, // default read timeout in seconds - 		is_running(false) - 		, is_stop_complete(false) --		, m_heartbeat_timer(io_service_) -+		, m_heartbeat_timer(io_context_) - 	{ - 		if (!settings.is_enabled()) - 		{ -@@ -39,10 +39,10 @@ namespace server { - 		} -  - 		// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). --		boost::asio::ip::tcp::resolver resolver(io_service_); --		boost::asio::ip::tcp::resolver::query query(settings_.listening_address, settings_.listening_port); --		boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); --		acceptor_.open(endpoint.protocol()); -+		boost::asio::ip::tcp::resolver resolver(io_context_); -+		boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type endpoints = resolver.resolve(settings_.listening_address, settings_.listening_port); -+		auto endpoint = *endpoints.begin(); -+		acceptor_.open(endpoint.endpoint().protocol()); - 		acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - 		// bind to both ipv6 and ipv4 sockets for the "::" address only - 		if (settings_.listening_address == "::") -@@ -59,28 +59,28 @@ namespace server { - 	} -  - void server_base::run() { --	// The io_service::run() call will block until all asynchronous operations -+	// The io_context::run() call will block until all asynchronous operations - 	// have finished. While the server is running, there is always at least one - 	// asynchronous operation outstanding: the asynchronous accept call waiting - 	// for new incoming connections. - 	try { - 		is_running = true; - 		heart_beat(boost::system::error_code()); --		io_service_.run(); -+		io_context_.run(); - 		is_running = false; - 	} catch (std::exception& e) { - 		_log.Log(LOG_ERROR, "[web:%s] exception occurred : '%s' (need to run again)", settings_.listening_port.c_str(), e.what()); - 		is_running = false; - 		// Note: if acceptor is up everything is OK, we can call run() again - 		//       but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly. --		io_service_.reset(); // this call is needed before calling run() again -+		io_context_.restart(); // this call is needed before calling run() again - 		throw; - 	} catch (...) { - 		_log.Log(LOG_ERROR, "[web:%s] unknown exception occurred (need to run again)", settings_.listening_port.c_str()); - 		is_running = false; - 		// Note: if acceptor is up everything is OK, we can call run() again - 		//       but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly. --		io_service_.reset(); // this call is needed before calling run() again -+		io_context_.restart(); // this call is needed before calling run() again - 		throw; - 	} - } -@@ -89,12 +89,12 @@ void server_base::run() { - void server_base::stop() { - 	if (is_running) { - 		// Post a call to the stop function so that server_base::stop() is safe to call from any thread. --		// Rene, set is_running to false, because the following is an io_service call, which makes is_running -+		// Rene, set is_running to false, because the following is an io_context call, which makes is_running - 		// never set to false whilst in the call itself - 		is_running = false; --		io_service_.post([this] { handle_stop(); }); -+		boost::asio::post(io_context_, [this] { handle_stop(); }); - 	} else { --		// if io_service is not running then the post call will not be performed -+		// if io_context is not running then the post call will not be performed - 		handle_stop(); - 	} -  -@@ -112,7 +112,7 @@ void server_base::stop() { - 		} - 		sleep_milliseconds(500); - 	} --	io_service_.stop(); -+	io_context_.stop(); -  - 	// Deregister heartbeat - 	m_mainworker.HeartbeatRemove(std::string("WebServer:") + settings_.listening_port); -@@ -136,7 +136,7 @@ void server_base::heart_beat(const boost::system::error_code& error) - 		m_mainworker.HeartbeatUpdate(std::string("WebServer:") + settings_.listening_port); -  - 		// Schedule next heartbeat --		m_heartbeat_timer.expires_from_now(std::chrono::seconds(4)); -+		m_heartbeat_timer.expires_after(std::chrono::seconds(4)); - 		m_heartbeat_timer.async_wait([this](auto &&err) { heart_beat(err); }); - 	} - } -@@ -148,7 +148,7 @@ server::server(const server_settings &settings, request_handler &user_request_ha - } -  - void server::init_connection() { --	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_)); -+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_)); - } -  - /** -@@ -157,7 +157,7 @@ void server::init_connection() { - void server::handle_accept(const boost::system::error_code& e) { - 	if (!e) { - 		connection_manager_.start(new_connection_); --		new_connection_.reset(new connection(io_service_, -+		new_connection_.reset(new connection(io_context_, - 				connection_manager_, request_handler_, timeout_)); - 		// listen for a subsequent request - 		acceptor_.async_accept(new_connection_->socket(), [this](auto &&err) { handle_accept(err); }); -@@ -267,7 +267,7 @@ void ssl_server::init_connection() { - 	} else { - 		_log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters file %s!", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str()); - 	} --	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_)); -+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_)); - } -  - void ssl_server::reinit_connection() -@@ -305,7 +305,7 @@ void ssl_server::reinit_connection() - 			_log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters from file %s", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str()); - 		} - 	} --	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_)); -+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_)); - } -  - /** -diff --git webserver/server.hpp webserver/server.hpp -index f9e71c5..bd7132a 100644 ---- webserver/server.hpp -+++ webserver/server.hpp -@@ -31,7 +31,7 @@ namespace http - 			explicit server_base(const server_settings &settings, request_handler &user_request_handler); - 			virtual ~server_base() = default; -  --			/// Run the server's io_service loop. -+			/// Run the server's io_context loop. - 			void run(); -  - 			/// Stop the server. -@@ -46,8 +46,8 @@ namespace http - 		      protected: - 			void init(const init_connectionhandler_func &init_connection_handler, accept_handler_func accept_handler); -  --			/// The io_service used to perform asynchronous operations. --			boost::asio::io_service io_service_; -+			/// The io_context used to perform asynchronous operations. -+			boost::asio::io_context io_context_; -  - 			/// Acceptor used to listen for incoming connections. - 			boost::asio::ip::tcp::acceptor acceptor_; | 
