Skip to content

Conversation

@Darthyson
Copy link
Member

This PR contains improvements to the firmware updater focusing on reliability, maintainability and user experience.

Key Features & Enhancements

Connection & Reliability:

  • New --ip-tunnel-reconnect option for IP interfaces with non-standard L2 sequence number handling (e.g., Loxone Miniserver Gen1)
  • Automatic KNX link reconnection on exceptions with configurable --reconnect delay (milliseconds)
  • Improved exception handling with graceful shutdown on [CTRL+C]
  • Better handling of transport layer (TL4) disconnects and timeouts

Discovery & Interface Detection:

  • New --discover argument to list available KNX interfaces (IP, USB and serial-port) and their properties
  • Simple automatic KNX gateway detection on startup

Logging & Output:

  • Logging system reorganization with modular logback configuration
  • Customizable message/exception filters to reduce noise in console output
  • ANSI escape code filtering in log file
  • Prettier, more readable console output with consistent colors
  • Progress indicator with spinner animation
  • Credits and ASCII logo now only display with --version

Code Quality & Architecture:

  • Major refactoring: reorganized folder structure (moved from source/src to src/)
  • Moved to shadowJar plugin for fat JAR creation
  • New DeviceManagementFactory for reflection-based L2 handling of reconnecting
  • Functionality separated into new packages: .logging, .progress, .devicemgnt
  • Fixed many IntelliJ IDEA inspection warnings
  • Better exception handling with custom CliInvalidException for validation errors

GUI Improvements:

  • Settings now saved/loaded using JSON (supports nested structures) in settings.json
  • Fixed progress info updates when interacting with LoggingPane: JTextPane
  • Better error dialogs with UncaughtExceptionHandler

Bug Fixes:

  • diff-header size calculation d2c37e9
  • buffer not repeated if error occurred in last while run 4e7152e

Breaking Changes

  • Reorganized code base folder hierarchy (formerly in source/src, now src/)

Testing
Added test coverage for logging components, evaluators and core functionality.

Dependency Updates:

  • Replaced deprecated jansi with jline-terminal-jansi
  • Added Dependabot configuration for Updater
  • Upgraded to latest versions of dependencies:
    • Gradle 9.2.1
    • Calimero 2.6
    • Logback 1.5.21
    • jline-terminal-jansi 3.30.6
    • jackson-databind 2.20.1
    • Guava 33.5.0-jre
    • commons-cli 1.11.0
    • appdirs 1.5.0
    • java-intelhex-parser:9dec823

There is no reason to log/print the stack-trace on `CliInvalidException`
(logic errors, e.g. IP-Secure together with USB-Interface)
Instead of creating/configuring/tinkering by our self a fatJar,
we use now `com.gradleup.shadow` to create a `shadowJar`.
The old `fatJar` gradle task will be now redirected to the new `shadowJar`
task for some time.
…IDEA)

downloaded on 10.08.2024 from [Github gitignore - JetBrains.gitignore](https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore)
based on [JetBrains IDEs Support IntelliJ Platform - How to manage projects under Version Control Systems](https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems)
This commit breaks intentionally the build to fix the code base folder hierarchy
and not to loose git history. Next commits will (hopefully) fix it.
Reasons for code base reorganization:
- The Updater project itself was in subfolder `source`,
  which is redundant since we already use `src` for source files
- `main` code was in `source/src/main/java/org/selfbus/*`.
- `test` code was in `source/src/test/java/org/selfbus/*`.
New files in `.idea` are from a fresh gradle import in
IntelliJ IDEA Community Edition 2024.2
`objno` was logged instead of `objConf`
The 7th bit of the Config Octet shall always be 1 for Group Object Table - Realisation Type 1 (KNX Spec. 3.0 3/5/1 4.18.3.1.2.1).
The 7th bit of the Config Octet of The Group Object Table - Realisation Type 2 is used as Update Enable flag (KNX Spec. 3.0 3/5/1 4.18.4.1).
Also fixed gradle warning: The archives configuration has been deprecated for artifact declaration.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces substantial improvements to the firmware updater, focusing on reliability, maintainability, and user experience. The changes include:

  • Enhanced connection handling with new reconnect options
  • Improved KNX interface discovery
  • Reorganized logging system with custom filters
  • Major code refactoring with relocated source structure
  • Migration from JUnit 4 to JUnit 5
  • Updated dependencies and build configuration

Key Changes

  • Refactored communication object handling logic with improved APCI command processing
  • Added comprehensive test coverage for logging, GUI components, and utility functions
  • Migrated test framework from JUnit 4 to JUnit 5 with Hamcrest replaced by native assertions
  • Enhanced debug output with new helper functions for communication object inspection

Reviewed changes

Copilot reviewed 130 out of 158 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
test/lib-test-cases/src/knx/test_*.{h,cpp} New test files for memory and EEPROM functionality
sblib/src/eib/com_objectsBCU1.cpp Refactored processGroupTelegram logic with switch-case pattern
sblib/src/eib/com_object*.cpp Added debug output functions and formatting improvements
sblib/inc/sblib/eib/types.h Added COMCONF_UPDATE enum value
firmware_updater/updater/test/**/*.java Migrated to JUnit 5 and added new test coverage
firmware_updater/updater/test/resources/hex/*.hex Updated test resources with corrected paths
Files not reviewed (10)
  • firmware_updater/updater/.idea/.name: Language not supported
  • firmware_updater/updater/.idea/Selfbus_Updater.iml: Language not supported
  • firmware_updater/updater/.idea/artifacts/SB_updater_main_jar.xml: Language not supported
  • firmware_updater/updater/.idea/compiler.xml: Language not supported
  • firmware_updater/updater/.idea/misc.xml: Language not supported
  • firmware_updater/updater/.idea/modules.xml: Language not supported
  • firmware_updater/updater/.idea/modules/SB_updater.main.iml: Language not supported
  • firmware_updater/updater/.idea/modules/SB_updater.test.iml: Language not supported
  • firmware_updater/updater/.idea/runConfigurations/_template__of_Application.xml: Language not supported
  • firmware_updater/updater/source/.idea/artifacts/SB_updater_main_jar.xml: Language not supported
Comments suppressed due to low confidence (1)

firmware_updater/updater/src/org/selfbus/updater/bootloader/BootloaderStatistic.java:36

  • This method overrides Object.toString; it is advisable to add an Override annotation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}

private class SBTransportListener implements TransportListener
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SBTransportListener could be made static, since the enclosing instance is used only in its constructor.

Copilot uses AI. Check for mistakes.

if (cmdLine.hasOption(OPT_LONG_DUMPFLASH)) {
String[] optArgs = cmdLine.getOptionValues(OPT_LONG_DUMPFLASH);
setDumpFlashStartAddress(Long.decode(optArgs[0]));
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential uncaught 'java.lang.NumberFormatException'.

Copilot uses AI. Check for mistakes.
if (cmdLine.hasOption(OPT_LONG_DUMPFLASH)) {
String[] optArgs = cmdLine.getOptionValues(OPT_LONG_DUMPFLASH);
setDumpFlashStartAddress(Long.decode(optArgs[0]));
setDumpFlashEndAddress(Long.decode(optArgs[1]));
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential uncaught 'java.lang.NumberFormatException'.

Copilot uses AI. Check for mistakes.
int cursorMovementCode = cursorMovement.charAt(cursorMovement.length() - 1);
int number;
if (cursorMovement.length() > 1) {
number = Integer.parseInt(cursorMovement.substring(0, cursorMovement.length() - 1));
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential uncaught 'java.lang.NumberFormatException'.

Copilot uses AI. Check for mistakes.
code = code.substring(0, code.length() - 1); // strip of 'm'
}

switch (Integer.parseInt(code)) {
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential uncaught 'java.lang.NumberFormatException'.

Copilot uses AI. Check for mistakes.
}
}

public void run() {
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method overrides Thread.run; it is advisable to add an Override annotation.

Copilot uses AI. Check for mistakes.
*
* @see java.lang.Runnable#run()
*/
public void run() {
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method overrides Runnable.run; it is advisable to add an Override annotation.

Copilot uses AI. Check for mistakes.
this.linkLogger = (Logger) LoggerFactory.getLogger(SBLinkListener.class.getName() + " " + link.getName());
}

public void indication(final FrameEvent e)
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method overrides LinkListener.indication; it is advisable to add an Override annotation.

Copilot uses AI. Check for mistakes.
return new BootloaderIdentity(vMajor, vMinor, versionSBLibMajor, versionSBLibMinor, features, applicationFirstAddress);
}

public String toString() {
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method overrides Record.toString; it is advisable to add an Override annotation.

Copilot uses AI. Check for mistakes.
return " Done Speed Avg Min Max Time";
}

public String toString() {
Copy link

Copilot AI Nov 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method overrides Object.toString; it is advisable to add an Override annotation.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants