From 257a15130ff2a3386984ea96405ca50707c23237 Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Sun, 26 Mar 2017 22:32:55 +0200 Subject: [PATCH 1/2] Fix calculation of pause length in LEGO PF protocol Fix #384 Integer overflow in LEGO Power Functions affects pause between messages Is rebased version of PR #385 --- .../LegoPowerFunctionsTests.ino | 18 +++---- ir_Lego_PF_BitStreamEncoder.h | 54 +++++++++---------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino index 6a2bda5..65760e2 100644 --- a/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino +++ b/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino @@ -1,6 +1,6 @@ /* * LegoPowerFunctionsTest: LEGO Power Functions Tests - * Copyright (c) 2016 Philipp Henkel + * Copyright (c) 2016, 2017 Philipp Henkel */ #include @@ -78,14 +78,14 @@ void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { logTestResult(bitCount == 18); } -boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { +boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { bool result = true; result = result && bitStreamEncoder.getMarkDuration() == markDuration; result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; return result; } -boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, int markDuration, int pauseDuration) { +boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { bool result = bitStreamEncoder.next(); result = result && check(bitStreamEncoder, markDuration, pauseDuration); return result; @@ -129,16 +129,16 @@ void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { bool result = true; result = result && check(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 5 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); - result = result && checkNext(bitStreamEncoder, 158, 1026 + 8 * 16000 - 10844); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); result = result && checkNext(bitStreamEncoder, 158, 1026); result = result && checkDataBitsOfMessage407(bitStreamEncoder); result = result && checkNext(bitStreamEncoder, 158, 1026); @@ -191,7 +191,3 @@ void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { bitStreamEncoder.reset(0x0, false); logTestResult(bitStreamEncoder.getMessageLength() == 9104); } - - - - diff --git a/ir_Lego_PF_BitStreamEncoder.h b/ir_Lego_PF_BitStreamEncoder.h index 7689cde..e5a3d66 100644 --- a/ir_Lego_PF_BitStreamEncoder.h +++ b/ir_Lego_PF_BitStreamEncoder.h @@ -4,7 +4,7 @@ // L E E O O // L EEEE E EEE O O // L E E E O O LEGO Power Functions -// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016, 2017 Philipp Henkel //============================================================================== //+============================================================================= @@ -14,25 +14,25 @@ class LegoPfBitStreamEncoder { private: uint16_t data; bool repeatMessage; - int messageBitIdx; - int repeatCount; - int messageLength; - - // HIGH data bit = IR mark + high pause - // LOW data bit = IR mark + low pause - static const int LOW_BIT_DURATION = 421; - static const int HIGH_BIT_DURATION = 711; - static const int START_BIT_DURATION = 1184; - static const int STOP_BIT_DURATION = 1184; - static const int IR_MARK_DURATION = 158; - static const int HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; - static const int LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; - static const int START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; - static const int STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; - static const int MESSAGE_BITS = 18; - static const int MAX_MESSAGE_LENGTH = 16000; + uint8_t messageBitIdx; + uint8_t repeatCount; + uint16_t messageLength; public: + // HIGH data bit = IR mark + high pause + // LOW data bit = IR mark + low pause + static const uint16_t LOW_BIT_DURATION = 421; + static const uint16_t HIGH_BIT_DURATION = 711; + static const uint16_t START_BIT_DURATION = 1184; + static const uint16_t STOP_BIT_DURATION = 1184; + static const uint8_t IR_MARK_DURATION = 158; + static const uint16_t HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const uint8_t MESSAGE_BITS = 18; + static const uint16_t MAX_MESSAGE_LENGTH = 16000; + void reset(uint16_t data, bool repeatMessage) { this->data = data; this->repeatMessage = repeatMessage; @@ -43,9 +43,9 @@ class LegoPfBitStreamEncoder { int getChannelId() const { return 1 + ((data >> 12) & 0x3); } - int getMessageLength() const { + uint16_t getMessageLength() const { // Sum up all marks - int length = MESSAGE_BITS * IR_MARK_DURATION; + uint16_t length = MESSAGE_BITS * IR_MARK_DURATION; // Sum up all pauses length += START_PAUSE_DURATION; @@ -75,9 +75,9 @@ class LegoPfBitStreamEncoder { } } - int getMarkDuration() const { return IR_MARK_DURATION; } + uint8_t getMarkDuration() const { return IR_MARK_DURATION; } - int getPauseDuration() const { + uint32_t getPauseDuration() const { if (messageBitIdx == 0) return START_PAUSE_DURATION; else if (messageBitIdx < MESSAGE_BITS - 1) { @@ -88,13 +88,13 @@ class LegoPfBitStreamEncoder { } private: - int getDataBitPause() const { + uint16_t getDataBitPause() const { const int pos = MESSAGE_BITS - 2 - messageBitIdx; const bool isHigh = data & (1 << pos); return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; } - int getStopPause() const { + uint32_t getStopPause() const { if (repeatMessage) { return getRepeatStopPause(); } else { @@ -102,12 +102,12 @@ class LegoPfBitStreamEncoder { } } - int getRepeatStopPause() const { + uint32_t getRepeatStopPause() const { if (repeatCount == 0 || repeatCount == 1) { - return STOP_PAUSE_DURATION + 5 * MAX_MESSAGE_LENGTH - messageLength; + return STOP_PAUSE_DURATION + (uint32_t)5 * MAX_MESSAGE_LENGTH - messageLength; } else if (repeatCount == 2 || repeatCount == 3) { return STOP_PAUSE_DURATION - + (6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + + (uint32_t)(6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; } else { return STOP_PAUSE_DURATION; } From ccc9d0135cd5d4786b5b1ccc8b2a5056a9900e4c Mon Sep 17 00:00:00 2001 From: Philipp Henkel Date: Mon, 27 Mar 2017 19:57:25 +0200 Subject: [PATCH 2/2] Add Lego fix to change and bump version up to 2.2.3 --- Contributors.md | 2 +- README.md | 4 ++-- changelog.md | 3 +++ library.json | 2 +- library.properties | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Contributors.md b/Contributors.md index 36ec806..ae24890 100644 --- a/Contributors.md +++ b/Contributors.md @@ -16,7 +16,7 @@ These are the active contributors of this project that you may contact if there - [Sebazzz](https://github.com/sebazz): Contributor - [lumbric](https://github.com/lumbric): Contributor - [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor -- [henkel](https://github.com/henkel): Contributor +- [philipphenkel](https://github.com/philipphenkel): Active Contributor - [MCUdude](https://github.com/MCUdude): Contributor Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/README.md b/README.md index c8e074c..2ec302c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This library enables you to send and receive using infra-red signals on an Ardui Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). -## Version - 2.2.1 +## Version - 2.2.3 ## Installation 1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. @@ -65,7 +65,7 @@ Check [here](Contributing.md) for some guidelines. ## Contact Email: zetoslab@gmail.com -Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. +Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. ## Contributors Check [here](Contributors.md) diff --git a/changelog.md b/changelog.md index cb2b7e2..0702ddc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +## 2.2.3 - 2017/03/27 +- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427) + ## 2.2.2 - 2017/01/20 - Fixed naming bug [PR #398](https://github.com/z3t0/Arduino-IRremote/pull/398) diff --git a/library.json b/library.json index 090578d..de93d16 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/z3t0/Arduino-IRremote.git" }, - "version": "2.2.1", + "version": "2.2.3", "frameworks": "arduino", "platforms": "atmelavr", "authors" : diff --git a/library.properties b/library.properties index 15aabee..39fd814 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=IRremote -version=2.2.1 +version=2.2.3 author=shirriff maintainer=shirriff sentence=Send and receive infrared signals with multiple protocols