File 03-add_ireciever_events.patch of Package hidpp

Add IReciever events

diff --git a/src/libhidpp/hidpp/Report.cpp b/src/libhidpp/hidpp/Report.cpp
index a24f310..7946d6c 100644
--- a/src/libhidpp/hidpp/Report.cpp
+++ b/src/libhidpp/hidpp/Report.cpp
@@ -50,6 +50,7 @@ static constexpr unsigned int DeviceIndex = 1;
 static constexpr unsigned int SubID = 2;
 static constexpr unsigned int Address = 3;
 static constexpr unsigned int Parameters = 4;
+static constexpr unsigned int DJParameters = 3;
 }
 
 Report::Report (uint8_t report_id, const uint8_t *data, std::size_t length)
@@ -94,7 +95,7 @@ Report::Report (HIDPP::DeviceIndex device_index,
 		std::vector<uint8_t>::const_iterator param_end)
 {
 	std::size_t param_len = std::distance (param_begin, param_end);
-	for (auto type: { Short, Long, VeryLong }) {
+	for (auto type: { Short, Long, VeryLong, ShortDJ, LongDJ }) {
 		if (param_len == parameterLength (type)) {
 			_data.resize (reportLength (type));
 			_data[Offset::Type] = type;
@@ -130,7 +131,7 @@ Report::Report (DeviceIndex device_index,
 		std::vector<uint8_t>::const_iterator param_end)
 {
 	std::size_t param_len = std::distance (param_begin, param_end);
-	for (auto type: { Short, Long, VeryLong }) {
+	for (auto type: { Short, Long, VeryLong, ShortDJ, LongDJ }) {
 		if (param_len == parameterLength (type)) {
 			_data.resize (reportLength (type));
 			_data[Offset::Type] = type;
@@ -142,7 +143,15 @@ Report::Report (DeviceIndex device_index,
 	_data[Offset::DeviceIndex] = device_index;
 	_data[Offset::SubID] = feature_index;
 	_data[Offset::Address] = (function & 0x0f) << 4 | (sw_id & 0x0f);
-	std::copy (param_begin, param_end, &_data[Offset::Parameters]);
+	switch (_data[Offset::Type]) {
+		case Type::ShortDJ:
+		case Type::LongDJ:
+			std::copy (param_begin, param_end, &_data[Offset::DJParameters]);
+			break;
+		default:
+			std::copy (param_begin, param_end, &_data[Offset::Parameters]);
+			break;
+	}
 }
 
 Report::Type Report::type () const
@@ -212,12 +221,24 @@ std::size_t Report::parameterLength () const
 
 std::vector<uint8_t>::iterator Report::parameterBegin ()
 {
-	return _data.begin () + Offset::Parameters;
+	switch (_data[Offset::Type]) {
+		case ShortDJ:
+		case LongDJ:
+			return _data.begin () + Offset::DJParameters;
+		default:
+			return _data.begin () + Offset::Parameters;
+	}
 }
 
 std::vector<uint8_t>::const_iterator Report::parameterBegin () const
 {
-	return _data.begin () + Offset::Parameters;
+	switch (_data[Offset::Type]) {
+		case ShortDJ:
+		case LongDJ:
+			return _data.begin () + Offset::DJParameters;
+		default:
+			return _data.begin () + Offset::Parameters;
+	}
 }
 
 std::vector<uint8_t>::iterator Report::parameterEnd ()
diff --git a/src/libhidpp/hidpp/Report.h b/src/libhidpp/hidpp/Report.h
index 8102a42..bae539c 100644
--- a/src/libhidpp/hidpp/Report.h
+++ b/src/libhidpp/hidpp/Report.h
@@ -52,24 +52,35 @@ namespace HIDPP
 class Report
 {
 	static constexpr std::size_t HeaderLength = 4;
+	static constexpr std::size_t DJHeaderLength = 3;
 public:
 	enum Type: uint8_t {
 		Short = 0x10,
 		Long = 0x11,
 		VeryLong = 0x12,
+		ShortDJ = 0x20,
+		LongDJ = 0x21,
 	};
 
 	static inline constexpr std::size_t reportLength (Type type) noexcept {
 		switch (type) {
 		case Type::Short: return 7;
+		case Type::ShortDJ: return 15;
 		case Type::Long: return 20;
+		case Type::LongDJ: return 32;
 		case Type::VeryLong: return 64;
 		default: return 0;
 		}
 	}
 
 	inline static constexpr std::size_t parameterLength (Type type) noexcept {
-		return reportLength (type) - HeaderLength;
+		switch (type) {
+		case Type::ShortDJ:
+		case Type::LongDJ:
+			return reportLength (type) - DJHeaderLength;
+		default:
+			return reportLength (type) - HeaderLength;
+		}
 	}
 
 	/**
@@ -294,6 +305,8 @@ inline constexpr auto MaxReportLength = Report::reportLength (Report::VeryLong);
 inline constexpr auto ShortParamLength = Report::parameterLength (Report::Short);
 inline constexpr auto LongParamLength = Report::parameterLength (Report::Long);
 inline constexpr auto VeryLongParamLength = Report::parameterLength (Report::VeryLong);
+inline constexpr auto ShortDJParamLength = Report::parameterLength (Report::ShortDJ);
+inline constexpr auto LongDJParamLength = Report::parameterLength (Report::LongDJ);
 
 }
 
diff --git a/src/libhidpp/hidpp10/IReceiver.cpp b/src/libhidpp/hidpp10/IReceiver.cpp
index 06261be..1dc8df2 100644
--- a/src/libhidpp/hidpp10/IReceiver.cpp
+++ b/src/libhidpp/hidpp10/IReceiver.cpp
@@ -23,25 +23,34 @@
 
 #include <misc/Endian.h>
 #include <stdexcept>
+#include <cassert>
 
 using namespace HIDPP10;
 
+const std::vector<uint8_t> IReceiver::Events
+({
+			IReceiver::DeviceUnpaired,
+			IReceiver::DevicePaired,
+			IReceiver::ConnectionStatus,
+			IReceiver::Error
+});
+
 IReceiver::IReceiver (Device *dev):
 	_dev (dev)
 {
 }
 
 void IReceiver::getDeviceInformation (unsigned int device,
-				      uint8_t *destination_id,
-				      uint8_t *report_interval,
-				      uint16_t *wpid,
-				      DeviceType *type)
+					uint8_t *destination_id,
+					uint8_t *report_interval,
+					uint16_t *wpid,
+					DeviceType *type)
 {
 	if (device >= 16)
 		throw std::out_of_range ("Device index too big");
 
 	std::vector<uint8_t> params (HIDPP::ShortParamLength),
-			     results (HIDPP::LongParamLength);
+				results (HIDPP::LongParamLength);
 
 	params[0] = DeviceInformation | (device & 0x0F);
 
@@ -61,15 +70,15 @@ void IReceiver::getDeviceInformation (unsigned int device,
 }
 
 void IReceiver::getDeviceExtendedInformation (unsigned int device,
-					      uint32_t *serial,
-					      uint32_t *report_types,
-					      PowerSwitchLocation *ps_loc)
+						uint32_t *serial,
+						uint32_t *report_types,
+						PowerSwitchLocation *ps_loc)
 {
 	if (device >= 16)
 		throw std::out_of_range ("Device index too big");
 
 	std::vector<uint8_t> params (HIDPP::ShortParamLength),
-			     results (HIDPP::LongParamLength);
+				results (HIDPP::LongParamLength);
 
 	params[0] = ExtendedDeviceInformation | (device & 0x0F);
 
@@ -92,7 +101,7 @@ std::string IReceiver::getDeviceName (unsigned int device)
 		throw std::out_of_range ("Device index too big");
 
 	std::vector<uint8_t> params (HIDPP::ShortParamLength),
-			     results (HIDPP::LongParamLength);
+				results (HIDPP::LongParamLength);
 
 	params[0] = DeviceName | (device & 0x0F);
 
@@ -104,3 +113,35 @@ std::string IReceiver::getDeviceName (unsigned int device)
 	std::size_t length = results[1];
 	return std::string (reinterpret_cast<char *> (&results[2]), std::min (length, std::size_t {14}));
 }
+
+IReceiver::DevicePairedEvent IReceiver::devicePairedEvent (const HIDPP::Report &event)
+{
+	assert (event.featureIndex() == DevicePaired);
+	DevicePairedEvent dpe {};
+
+	auto params = event.parameterBegin();
+	dpe.moreEvents = params[0] & 1;
+	dpe.empty = params[0] & 2;
+	dpe.pid = params[1] << 8 | params[2];
+
+	uint32_t bitfield = params[3] << 24 | params[4] << 16 | params[5] << 8 | params[6];
+	for(int i = 0; i < 32; i++)
+		if(bitfield & (1 << i))
+			dpe.reportBitfield.push_back(i);
+
+	return dpe;
+}
+
+uint8_t IReceiver::connectionStatusEvent (const HIDPP::Report &event)
+{
+	assert (event.featureIndex() == ConnectionStatus);
+	auto params = event.parameterBegin();
+	return params[0];
+}
+
+uint8_t IReceiver::errorEvent (const HIDPP::Report &event)
+{
+	assert (event.featureIndex() == Error);
+	auto params = event.parameterBegin();
+	return params[0];
+}
diff --git a/src/libhidpp/hidpp10/IReceiver.h b/src/libhidpp/hidpp10/IReceiver.h
index ab983ba..c6e19dc 100644
--- a/src/libhidpp/hidpp10/IReceiver.h
+++ b/src/libhidpp/hidpp10/IReceiver.h
@@ -21,6 +21,7 @@
 
 #include <cstdint>
 #include <string>
+#include "Device.h"
 
 namespace HIDPP10
 {
@@ -61,6 +62,47 @@ public:
 		BottomEdge = 0xC,
 	};
 
+	enum Event : uint8_t
+	{
+		DeviceUnpaired = 0x40,
+		DevicePaired = 0x41,
+		ConnectionStatus = 0x42,
+		Error = 0x7F
+	};
+
+	static const std::vector<uint8_t> Events;
+
+	enum ConnectionStatus : uint8_t
+	{
+		ConnectionEstablished = 0,
+		LinkLoss = 1
+	};
+
+	enum class RFReport : uint8_t
+	{
+		StandardKeyboard = 1,
+		Mouse = 2,
+		Multimedia = 3,
+		PowerKeys = 4,
+		MediaCenter = 8,
+		KeyboardLEDs = 14,
+		ShortHIDPP = 16,
+		LongHIDPP = 17
+	};
+
+	enum ErrorType : uint8_t
+	{
+		KeepAliveTimeout = 1
+	};
+
+	struct DevicePairedEvent
+	{
+		bool moreEvents;
+		bool empty;
+		uint16_t pid;
+		std::vector<uint8_t> reportBitfield;
+	};
+
 	IReceiver (Device *dev);
 
 	void getDeviceInformation (unsigned int device,
@@ -73,6 +115,9 @@ public:
 					   uint32_t *report_types,
 					   PowerSwitchLocation *ps_loc);
 	std::string getDeviceName (unsigned int device);
+	static DevicePairedEvent devicePairedEvent (const HIDPP::Report &event);
+	static uint8_t connectionStatusEvent (const HIDPP::Report &event);
+	static uint8_t errorEvent (const HIDPP::Report &event);
 
 private:
 	Device *_dev;
openSUSE Build Service is sponsored by