Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
63e61f2
fix: updated build.sh to work with docker
Apr 13, 2026
5faaa32
fix: bypass AI_ADDRCONFIG for numeric-IP gateway URLs
Apr 1, 2026
b5bc480
feat: network flap/no dns fixes
Apr 1, 2026
f38f6fa
ci: update to run connectivity tests
Apr 13, 2026
498a789
chore: linting
Apr 13, 2026
96ee593
chore: add SPDX-License-Identifier to vendored websocketpp header
Apr 13, 2026
b359a31
chore: exclude vendored websocketpp from BlackDuck scan
Apr 13, 2026
43a6ee8
fix: address Copilot review comments on PR #83
Apr 13, 2026
4e39799
Potential fix for pull request finding
brendanobra Apr 13, 2026
3a48bd0
Potential fix for pull request finding
brendanobra Apr 13, 2026
037d8be
Potential fix for pull request finding
brendanobra Apr 13, 2026
f98621c
fix: synchronize connectResult reads under mutex; add copyright heade…
Copilot Apr 13, 2026
1d659cc
fix: address second-round Copilot review comments on PR #83
Apr 13, 2026
a3094c5
chore: lint
Apr 13, 2026
212df73
fix: address third-round Copilot review comments on PR #83
Apr 13, 2026
a1f3800
chore: lint
Apr 13, 2026
82cf882
gateway: handle AlreadyConnected without false disconnect event
Apr 13, 2026
9636800
chore: append BSD-3-Clause license text for vendored WebSocket++ to L…
Apr 14, 2026
4d7c3d7
fix: address fifth-round Copilot and human review comments on PR #83
Apr 14, 2026
6852276
chore: fmt
Apr 14, 2026
65dae23
Potential fix for pull request finding
brendanobra Apr 14, 2026
17860dc
fix: address sixth-round Copilot review comments on PR #83
Apr 14, 2026
95969be
chore: fmt
Apr 14, 2026
acf6654
fix: address seventh-round Copilot review comments on PR #83
Apr 14, 2026
0dbd19a
fix: address eighth-round Copilot review comments on PR #83
Apr 14, 2026
4d41cc0
fix: add Connecting state to Transport so disconnect() aborts in-flig…
Apr 14, 2026
3d62c00
fix: address ninth-round Copilot review comments on PR #83
Apr 14, 2026
4cbe731
fix: prevent IO-thread event loss during AlreadyConnected wrapper window
Apr 14, 2026
87093da
fix: use explicit .load()/.store() on atomic connectionStatus_
Apr 14, 2026
f1ea7a9
fix: remove skipPrevForward race in connect() wrapper
Apr 14, 2026
2b122ae
feat: adding test-soc.sh to run against device over ssh tunnel for te…
Apr 15, 2026
b730dda
chore: remove file that should not be commited
Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .bdignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# BlackDuck scan exclusions
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi @brendanobra : This file will not work. There is a credit in NOTICE for the OSS code in endpoint.cpp which is now being hosted here (a significant distinction) but please append a copy of the BSD-3 license to LICENSE (using generic year and code owner) to complete the attribution.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @mhughesacn , this is my 1st one of these, appreciate the advice - will do!

# Vendored third-party source — attributed in NOTICE and LICENSE files
src/vendor/
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,39 @@ jobs:

- name: Add coverage summary to job summary
run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY

network_isolation_tests:
permissions:
contents: read
packages: read
needs: [build_docker, build_project]
runs-on: ubuntu-latest
steps:
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Checkout Code
uses: actions/checkout@v4

- name: Download build directory
uses: actions/download-artifact@v4
with:
name: build-dir
path: ${{ github.workspace }}/build

- name: Run network-isolation tests (--network none)
run: |
chmod +x ${{ github.workspace }}/build/test/utApp
docker run --rm --network none \
--user "$(id -u):$(id -g)" \
-v ${{ github.workspace }}:/workspace \
-w /workspace \
${{ needs.build_docker.outputs.image_tag }} \
bash -c " \
build/test/utApp \
--gtest_filter='TransportNumericIPUTest.*:TransportIPv6UTest.ConnectViaIPv6LoopbackIP:TransportNumericIPResolverTest.ConnectFailureViaNumericIP' \
"
Comment thread
brendanobra marked this conversation as resolved.
1 change: 1 addition & 0 deletions .version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.1.8
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,31 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

===========================================================================

BSD-3 License

Copyright <YEAR> <COPYRIGHT HOLDER>
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.

Redistribution and use in source and binary forms, with or without
Comment thread
brendanobra marked this conversation as resolved.
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
Comment thread
brendanobra marked this conversation as resolved.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
Comment thread
brendanobra marked this conversation as resolved.
48 changes: 45 additions & 3 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,39 @@

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
IMAGE="firebolt-cpp-transport-ci:local"

# Pre-scan for --docker before arg parsing so forwarded args are preserved
use_docker=false
_forward_args=()
for _arg in "$@"; do
[[ "$_arg" == "--docker" ]] && { use_docker=true; continue; }
_forward_args+=("$_arg")
done

if $use_docker; then
for _bdir in build build-dev; do
_cache="$SCRIPT_DIR/$_bdir/CMakeCache.txt"
if [[ -f "$_cache" ]]; then
_cached=$(grep '^CMAKE_HOME_DIRECTORY' "$_cache" 2>/dev/null | cut -d= -f2 || true)
# In Docker, the workspace is mounted at /workspace. Only wipe if the
# cache was configured for a different environment (e.g. a native host build).
if [[ -n "$_cached" && "$_cached" != "/workspace" ]]; then
echo "Wiping stale $_bdir (configured at $_cached, expected /workspace)..."
rm -rf "$SCRIPT_DIR/$_bdir"
fi
fi
Comment thread
brendanobra marked this conversation as resolved.
done
if ! docker image inspect "$IMAGE" &>/dev/null; then
echo "Building CI Docker image (one-time)..."
docker build -t "$IMAGE" -f "$SCRIPT_DIR/.github/Dockerfile" "$SCRIPT_DIR"
fi
exec docker run --rm --user "$(id -u):$(id -g)" \
-v "$SCRIPT_DIR:/workspace" -w /workspace \
"$IMAGE" ./build.sh "${_forward_args[@]}"
fi

bdir="build"
do_install=false
params=
Expand Down Expand Up @@ -50,12 +83,21 @@ while [[ ! -z $1 ]]; do
esac; shift
done

[[ ! -z $SYSROOT_PATH ]] || { echo "SYSROOT_PATH not set" >/dev/stderr; exit 1; }
[[ -e $SYSROOT_PATH ]] || { echo "SYSROOT_PATH not exist ($SYSROOT_PATH)" >/dev/stderr; exit 1; }
SYSROOT_PATH="${SYSROOT_PATH:-/}"
[[ -e $SYSROOT_PATH ]] || { echo "SYSROOT_PATH does not exist ($SYSROOT_PATH)" >/dev/stderr; exit 1; }

$cleanFirst && rm -rf $bdir

if [[ ! -e "$bdir" || -n "$@" ]]; then
_cache="$SCRIPT_DIR/$bdir/CMakeCache.txt"
if [[ -f "$_cache" ]]; then
_cached=$(grep '^CMAKE_HOME_DIRECTORY' "$_cache" 2>/dev/null | cut -d= -f2 || true)
if [[ -n "$_cached" && "$_cached" != "$SCRIPT_DIR" ]]; then
echo "Wiping stale $bdir (configured at $_cached, now at $SCRIPT_DIR)..."
rm -rf "$SCRIPT_DIR/$bdir"
fi
fi

if [[ ! -f "$bdir/CMakeCache.txt" || $# -gt 0 ]]; then
params+=" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
command -v ccache >/dev/null 2>&1 && params+=" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
cmake -B $bdir \
Expand Down
36 changes: 18 additions & 18 deletions cmake/version.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@ endif ()
if (NOT PROJECT_VERSION)
set(VERSION_STRING "0.1.0-unknown")

find_package(Git QUIET)

if (GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif ()

if (GIT_VERSION)
string(REGEX REPLACE "^v" "" VERSION_STRING "${GIT_VERSION}")
endif ()

if(VERSION_STRING STREQUAL "0.1.0-unknown" AND EXISTS "${CMAKE_SOURCE_DIR}/.version")
if (EXISTS "${CMAKE_SOURCE_DIR}/.version")
file(READ "${CMAKE_SOURCE_DIR}/.version" VERSION_STRING)
string(STRIP "${VERSION_STRING}" VERSION_STRING)
endif()
else ()
Comment thread
brendanobra marked this conversation as resolved.
find_package(Git QUIET)

if (GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif ()

if (GIT_VERSION)
string(REGEX REPLACE "^v" "" VERSION_STRING "${GIT_VERSION}")
endif ()
endif ()

set(PROJECT_VERSION "${VERSION_STRING}" CACHE STRING "Project version string")
set(PROJECT_VERSION "${VERSION_STRING}")
Expand Down
39 changes: 39 additions & 0 deletions include/firebolt/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,45 @@ struct Config

/** Watchdog polling cycle in milliseconds. Default: 500. */
unsigned watchdogCycle_ms = 500;

/**
* @brief Retry policy for the initial gateway connection.
*
* On embedded devices the Firebolt client may start before the gateway
* daemon is ready (poor systemd ordering) or before the loopback interface
* has an IPv4 address assigned. Setting reconnect_max_attempts > 0 causes
* connect() to retry up to that many times, waiting reconnect_delay_ms
* between each attempt, before returning an error to the caller.
*
* Each attempt is bounded by connect_attempt_timeout_ms: if the underlying
* transport (DNS + TCP + WebSocket handshake) does not complete within that
* window, the attempt is aborted and counted as a failure. connect()
* therefore blocks for at most:
* (reconnect_max_attempts + 1) * connect_attempt_timeout_ms
* + reconnect_max_attempts * reconnect_delay_ms
*
* Capped internally at 100 retries regardless of this value.
*
* Default: 0 (single attempt, no retry; connect() returns the last
* transport error, e.g. Error::NotConnected, Error::Timedout, or
* Error::General, or Error::NotConnected on per-attempt timeout).
*/
unsigned reconnect_max_attempts = 0;

/** Milliseconds to wait between reconnect attempts. Default: 1000. */
Comment thread
brendanobra marked this conversation as resolved.
unsigned reconnect_delay_ms = 1000;

/**
* @brief Per-attempt timeout for the initial connection handshake (ms).
*
* If DNS resolution + TCP connect + WebSocket handshake do not complete
* within this window, the in-flight attempt is aborted and connect()
* either retries (if reconnect_max_attempts > 0) or returns
* Error::NotConnected to the caller.
*
* Default: 10000 (10 seconds).
*/
unsigned connect_attempt_timeout_ms = 10000;
};

} // namespace Firebolt
3 changes: 3 additions & 0 deletions include/firebolt/gateway.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class IGateway
public:
virtual ~IGateway();

// NOTE: onConnectionChange is invoked once with the final result on the
// connect() calling thread. All subsequent callbacks (disconnect, watchdog
// reconnect) fire on the websocketpp IO thread. Callers must be thread-safe.
virtual Firebolt::Error connect(const Firebolt::Config& config, ConnectionChangeCallback onConnectionChange) = 0;
virtual Firebolt::Error disconnect() = 0;

Expand Down
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ target_link_libraries(${TARGET}

target_include_directories(${TARGET}
PRIVATE
# vendor/ must come before the system websocketpp headers so that
# our patched endpoint.hpp (numeric-IP resolver fix) takes priority.
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/vendor>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
PUBLIC
Expand Down
Loading
Loading