diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/editor.xml b/.idea/editor.xml
new file mode 100644
index 0000000..963c96f
--- /dev/null
+++ b/.idea/editor.xml
@@ -0,0 +1,344 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libblepp.iml b/.idea/libblepp.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/libblepp.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..0b76fe5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..273fa9d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b371a29..2cd3fd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,9 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif()
option(WITH_EXAMPLES "Build examples" OFF)
+option(WITH_BLUEZ_SUPPORT "Build with BlueZ transport support (HCI/L2CAP)" ON)
+option(WITH_NIMBLE_SUPPORT "Build with Nimble transport support (/dev/atbm_ioctl)" OFF)
+option(WITH_SERVER_SUPPORT "Build with BLE GATT server support" OFF)
include(GNUInstallDirs)
@@ -33,7 +36,9 @@ set(HEADERS
blepp/xtoa.h
blepp/att.h
blepp/blestatemachine.h
- blepp/att_pdu.h)
+ blepp/att_pdu.h
+ blepp/blepp_config.h
+ blepp/bleclienttransport.h)
set(SRC
src/att_pdu.cc
@@ -45,42 +50,202 @@ set(SRC
src/pretty_printers.cc
src/att.cc
src/lescan.cc
+ src/bleclienttransport.cc
${HEADERS})
+# BlueZ transport support (client + optional server)
+if(WITH_BLUEZ_SUPPORT)
+ list(APPEND HEADERS
+ blepp/bluez_client_transport.h)
+
+ list(APPEND SRC
+ src/bluez_client_transport.cc)
+endif()
+
+# Nimble transport support (client + optional server)
+if(WITH_NIMBLE_SUPPORT)
+ list(APPEND HEADERS
+ blepp/nimble_client_transport.h)
+
+ list(APPEND SRC
+ src/nimble_client_transport.cc)
+endif()
+
+# Server support headers and sources
+if(WITH_SERVER_SUPPORT)
+ list(APPEND HEADERS
+ blepp/bletransport.h
+ blepp/bleattributedb.h
+ blepp/gatt_services.h
+ blepp/blegattserver.h)
+
+ list(APPEND SRC
+ src/bleattributedb.cc
+ src/blegattserver.cc)
+
+ # BlueZ server transport (only if BlueZ support enabled)
+ if(WITH_BLUEZ_SUPPORT)
+ list(APPEND HEADERS
+ blepp/bluez_transport.h)
+
+ list(APPEND SRC
+ src/bluez_transport.cc)
+ endif()
+
+ # Nimble server transport (only if Nimble support enabled)
+ if(WITH_NIMBLE_SUPPORT)
+ list(APPEND HEADERS
+ blepp/nimble_transport.h)
+
+ list(APPEND SRC
+ src/nimble_transport.cc)
+ endif()
+endif()
+
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
-find_package(Bluez REQUIRED)
+# Validate: require at least one transport
+if(NOT WITH_BLUEZ_SUPPORT AND NOT WITH_NIMBLE_SUPPORT)
+ message(FATAL_ERROR "At least one of WITH_BLUEZ_SUPPORT or WITH_NIMBLE_SUPPORT must be enabled")
+endif()
+
+# Find BlueZ if enabled
+if(WITH_BLUEZ_SUPPORT)
+ find_package(Bluez REQUIRED)
+ include_directories(${BLUEZ_INCLUDE_DIRS})
+ message(STATUS "BlueZ transport: ENABLED")
+else()
+ message(STATUS "BlueZ transport: DISABLED")
+endif()
+
+include_directories(${PROJECT_SOURCE_DIR})
+
+# Add preprocessor definitions based on options
+if(WITH_BLUEZ_SUPPORT)
+ add_definitions(-DBLEPP_BLUEZ_SUPPORT)
+endif()
+
+if(WITH_NIMBLE_SUPPORT)
+ add_definitions(-DBLEPP_NIMBLE_SUPPORT)
+
+ # Find Nimble BLE stack (required for Nimble transport)
+ set(NIMBLE_ROOT_DEFAULT "${CMAKE_SOURCE_DIR}/../atbm-wifi/ble_host/nimble_v42")
+
+ if(DEFINED ENV{NIMBLE_ROOT})
+ set(NIMBLE_ROOT $ENV{NIMBLE_ROOT})
+ elseif(DEFINED NIMBLE_ROOT)
+ # Use the NIMBLE_ROOT passed via -DNIMBLE_ROOT=...
+ else()
+ set(NIMBLE_ROOT ${NIMBLE_ROOT_DEFAULT})
+ endif()
+
+ if(NOT EXISTS "${NIMBLE_ROOT}")
+ message(FATAL_ERROR "NIMBLE_ROOT not found at ${NIMBLE_ROOT}. "
+ "Please set NIMBLE_ROOT environment variable or pass -DNIMBLE_ROOT=/path/to/nimble_v42")
+ endif()
+
+ message(STATUS "Nimble transport: ENABLED (using Nimble from ${NIMBLE_ROOT})")
+
+ # Add Nimble include directories
+ include_directories(
+ ${NIMBLE_ROOT}/include
+ ${NIMBLE_ROOT}/nimble/include
+ ${NIMBLE_ROOT}/nimble/host/include
+ ${NIMBLE_ROOT}/nimble/host/services/gap/include
+ ${NIMBLE_ROOT}/nimble/host/services/gatt/include
+ ${NIMBLE_ROOT}/nimble/host/util/include
+ ${NIMBLE_ROOT}/porting/nimble/include
+ ${NIMBLE_ROOT}/ext/tinycrypt/include
+ )
+
+ # Find Nimble libraries (dynamic linking)
+ # Look for libnimble.so or libnimble.a in NIMBLE_ROOT/lib
+ find_library(NIMBLE_LIBRARY
+ NAMES nimble
+ HINTS ${NIMBLE_ROOT}/lib ${NIMBLE_ROOT}/build
+ NO_DEFAULT_PATH
+ )
+
+ if(NOT NIMBLE_LIBRARY)
+ message(FATAL_ERROR "Nimble library not found. Please build Nimble as a shared library first.\n"
+ "Expected location: ${NIMBLE_ROOT}/lib/libnimble.so or ${NIMBLE_ROOT}/build/libnimble.so\n"
+ "See README for instructions on building Nimble.")
+ endif()
+
+ message(STATUS "Found Nimble library: ${NIMBLE_LIBRARY}")
+ set(NIMBLE_LIBRARIES ${NIMBLE_LIBRARY})
+else()
+ message(STATUS "Nimble transport: DISABLED")
+endif()
+
+if(WITH_SERVER_SUPPORT)
+ add_definitions(-DBLEPP_SERVER_SUPPORT)
+ message(STATUS "Server support: ENABLED")
+else()
+ message(STATUS "Server support: DISABLED")
+endif()
-include_directories(${PROJECT_SOURCE_DIR} ${BLUEZ_INCLUDE_DIRS})
add_library(${PROJECT_NAME} SHARED ${SRC})
-target_link_libraries(${PROJECT_NAME} ${BLUEZ_LIBRARIES})
-set_target_properties(${PROJECT_NAME} PROPERTIES
+# Link BlueZ libraries if enabled
+if(WITH_BLUEZ_SUPPORT)
+ target_link_libraries(${PROJECT_NAME} ${BLUEZ_LIBRARIES})
+endif()
+
+# Link Nimble libraries if enabled
+if(WITH_NIMBLE_SUPPORT)
+ target_link_libraries(${PROJECT_NAME} ${NIMBLE_LIBRARIES})
+endif()
+
+# Add pthread for server support (needed for std::thread and semaphores)
+if(WITH_SERVER_SUPPORT)
+ find_package(Threads REQUIRED)
+ target_link_libraries(${PROJECT_NAME} Threads::Threads)
+endif()
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 11
CMAKE_CXX_STANDARD_REQUIRED YES
SOVERSION 5)
#----------------------- EXAMPLES --------------------------------
if(WITH_EXAMPLES)
- set(EXAMPLES
- examples/lescan.cc
- examples/blelogger.cc
- examples/bluetooth.cc
- examples/lescan_simple.cc
- examples/temperature.cc)
-
- foreach (example_src ${EXAMPLES})
- get_filename_component(example_name ${example_src} NAME_WE)
+ # Transport-agnostic examples (work with any transport)
+ set(CORE_EXAMPLES
+ examples/lescan_transport.cc)
+ foreach (example_src ${CORE_EXAMPLES})
+ get_filename_component(example_name ${example_src} NAME_WE)
add_executable(${example_name} ${example_src})
- target_link_libraries(${example_name} ${BLUEZ_LIBRARIES} ${PROJECT_NAME})
-
- set_target_properties(${example_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY examples)
+ target_link_libraries(${example_name} ${PROJECT_NAME})
set_target_properties(${example_name} PROPERTIES
CXX_STANDARD 11
CMAKE_CXX_STANDARD_REQUIRED YES
RUNTIME_OUTPUT_DIRECTORY examples)
endforeach()
+
+ # BlueZ-specific examples (only build when BlueZ support is enabled)
+ # These use BLEGATTStateMachine::connect_blocking or HCIScanner
+ if(WITH_BLUEZ_SUPPORT)
+ set(BLUEZ_EXAMPLES
+ examples/lescan.cc
+ examples/blelogger.cc
+ examples/bluetooth.cc
+ examples/lescan_simple.cc
+ examples/temperature.cc
+ examples/read_device_name.cc
+ examples/write.cc)
+
+ foreach (example_src ${BLUEZ_EXAMPLES})
+ get_filename_component(example_name ${example_src} NAME_WE)
+ add_executable(${example_name} ${example_src})
+ target_link_libraries(${example_name} ${BLUEZ_LIBRARIES} ${PROJECT_NAME})
+ set_target_properties(${example_name} PROPERTIES
+ CXX_STANDARD 11
+ CMAKE_CXX_STANDARD_REQUIRED YES
+ RUNTIME_OUTPUT_DIRECTORY examples)
+ endforeach()
+ endif()
endif()
#----------------------- PKG CONFIGURATION --------------------------------
diff --git a/Makefile.in b/Makefile.in
index 7ad89ab..365e7e0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -9,6 +9,13 @@ srcdir = @srcdir@
libdir=@libdir@
LOADLIBES = @LIBS@
+# Transport support flags from configure
+BLEPP_BLUEZ_SUPPORT = @BLEPP_BLUEZ_SUPPORT@
+BLEPP_NIMBLE_SUPPORT = @BLEPP_NIMBLE_SUPPORT@
+BLEPP_SERVER_SUPPORT = @BLEPP_SERVER_SUPPORT@
+NIMBLE_ROOT = @NIMBLE_ROOT@
+NIMBLE_LIBDIR = @NIMBLE_LIBDIR@
+
vpath %.cc $(srcdir)
ifneq "$(DESTDIR)" ""
@@ -16,7 +23,7 @@ DESTDIR+=/
endif
CXX=@CXX@
-LD=@CXX@
+LD=@LD@
CXXFLAGS=@CXXFLAGS@ -I$(srcdir)
LDFLAGS=@LDFLAGS@
@@ -29,9 +36,71 @@ soname1=libble++.so.0
soname2=libble++.so.0.5
set_soname=-Wl,-soname,libble++.so.0
-LIBOBJS=src/att.o src/uuid.o src/bledevice.o src/att_pdu.o src/pretty_printers.o src/blestatemachine.o src/float.o src/logging.o src/lescan.o
+# Core library objects (always compiled)
+# lescan.o contains parse_advertisement_packet() which is transport-agnostic
+LIBOBJS=src/att.o src/uuid.o src/bledevice.o src/att_pdu.o src/pretty_printers.o src/blestatemachine.o src/float.o src/logging.o src/lescan.o src/bleclienttransport.o
+
+# Validate: require at least one transport (configure already checks this, but keep for manual builds)
+ifeq ($(strip $(BLEPP_BLUEZ_SUPPORT)),)
+ifeq ($(strip $(BLEPP_NIMBLE_SUPPORT)),)
+$(error At least one of BLEPP_BLUEZ_SUPPORT or BLEPP_NIMBLE_SUPPORT must be defined)
+endif
+endif
+
+# BlueZ transport support (client + optional server)
+ifneq ($(strip $(BLEPP_BLUEZ_SUPPORT)),)
+LIBOBJS+=src/bluez_client_transport.o
+CXXFLAGS+=-DBLEPP_BLUEZ_SUPPORT
+endif
+
+# Nimble transport support (client + optional server)
+ifneq ($(strip $(BLEPP_NIMBLE_SUPPORT)),)
+LIBOBJS+=src/nimble_client_transport.o
+CXXFLAGS+=-DBLEPP_NIMBLE_SUPPORT
+CXXFLAGS+=-DCONFIG_LINUX_BLE_STACK_APP=1
+
+# Add Nimble include directories (NIMBLE_ROOT set by configure)
+ifneq ($(strip $(NIMBLE_ROOT)),)
+CXXFLAGS+=-I$(NIMBLE_ROOT)/nimble/include \
+ -I$(NIMBLE_ROOT)/nimble/host/include \
+ -I$(NIMBLE_ROOT)/nimble/host/services/gap/include \
+ -I$(NIMBLE_ROOT)/nimble/host/services/gatt/include \
+ -I$(NIMBLE_ROOT)/nimble/host/util/include \
+ -I$(NIMBLE_ROOT)/porting/nimble/include \
+ -I$(NIMBLE_ROOT)/ext/tinycrypt/include
+endif
+
+# Link Nimble library (NIMBLE_LIBDIR set by configure)
+ifneq ($(strip $(NIMBLE_LIBDIR)),)
+LDFLAGS+=-L$(NIMBLE_LIBDIR) -Wl,-rpath,$(NIMBLE_LIBDIR)
+LOADLIBES+=-lnimble
+endif
+endif
+
+# Server support objects
+ifneq ($(strip $(BLEPP_SERVER_SUPPORT)),)
+LIBOBJS+=src/bleattributedb.o src/blegattserver.o
+CXXFLAGS+=-DBLEPP_SERVER_SUPPORT
+
+# BlueZ server transport (only if BlueZ support enabled)
+ifneq ($(strip $(BLEPP_BLUEZ_SUPPORT)),)
+LIBOBJS+=src/bluez_transport.o
+endif
+
+# Nimble server transport (only if Nimble support enabled)
+ifneq ($(strip $(BLEPP_NIMBLE_SUPPORT)),)
+LIBOBJS+=src/nimble_transport.o
+endif
-PROGS=examples/lescan examples/blelogger examples/bluetooth examples/lescan_simple examples/temperature examples/read_device_name examples/write
+endif
+
+# Core examples that work with any transport
+PROGS=examples/lescan_transport
+
+# BlueZ-specific examples (use BLEGATTStateMachine::connect_blocking)
+ifneq ($(strip $(BLEPP_BLUEZ_SUPPORT)),)
+PROGS+=examples/lescan_simple examples/blelogger examples/bluetooth examples/temperature examples/read_device_name examples/write
+endif
.PHONY: all clean testclean install lib progs test doc install-so install-a install-hdr install-pkgconfig
@@ -97,8 +166,17 @@ docs:
#Every .cc file in the tests directory is a test
-TESTS=$(notdir $(basename $(wildcard $(srcdir)/tests/*.cc)))
+# Transport-agnostic tests (work with any transport)
+CORE_TESTS=test_transport test_scan
+# BlueZ-specific tests (use HCIScanner hardware interface)
+BLUEZ_TESTS=
+
+# Combine tests based on what's enabled
+TESTS=$(CORE_TESTS)
+ifneq ($(strip $(BLEPP_BLUEZ_SUPPORT)),)
+TESTS+=$(BLUEZ_TESTS)
+endif
#Get the intermediate file names from the list of tests.
TEST_RESULT=$(TESTS:%=tests/%.result)
@@ -110,11 +188,11 @@ TEST_RESULT=$(TESTS:%=tests/%.result)
test:tests/results
-#We don't want this file hanging around on failure since we
+#We don't want this file hanging around on failure since we
#want the build depend on it. If we leave it behing then typing make
#twice in a row will suceed, since make will find the file and not try
#to rebuild it.
-.DELETE_ON_ERROR: tests/results
+.DELETE_ON_ERROR: tests/results
tests/results:$(TEST_RESULT)
cat $(TEST_RESULT) > tests/results
diff --git a/NIMBLE_BUILD.md b/NIMBLE_BUILD.md
new file mode 100644
index 0000000..a2a2f86
--- /dev/null
+++ b/NIMBLE_BUILD.md
@@ -0,0 +1,184 @@
+# Building Nimble BLE Stack for libblepp
+
+This document explains how to build the Apache Nimble BLE stack as a shared library for use with libblepp's Nimble transport.
+
+## Overview
+
+libblepp's Nimble transport requires the Apache Nimble BLE stack to be built as a shared library. This avoids bloating libblepp with statically linked Nimble code (which can add ~5MB to the library size).
+
+## Prerequisites
+
+- GCC or Clang compiler
+- Make
+- The Nimble source code (from ATBM project or Apache Nimble repository)
+
+## Build Instructions
+
+### Option 1: Build from ATBM Project
+
+If you're using the ATBM Nimble sources:
+
+```bash
+cd /path/to/atbm-wifi/ble_host/nimble_v42
+
+# Create build directory
+mkdir -p build
+cd build
+
+# Create a simple Makefile for building libnimble.so
+cat > Makefile << 'EOF'
+CC = gcc
+AR = ar
+CFLAGS = -fPIC -O2 -g -Wall
+
+# Source directories
+NIMBLE_ROOT = ..
+HOST_SRC = $(NIMBLE_ROOT)/nimble/host/src
+SERVICES_GAP = $(NIMBLE_ROOT)/nimble/host/services/gap/src
+SERVICES_GATT = $(NIMBLE_ROOT)/nimble/host/services/gatt/src
+UTIL_SRC = $(NIMBLE_ROOT)/nimble/host/util/src
+PORT_SRC = $(NIMBLE_ROOT)/porting/nimble/src
+CORE_SRC = $(NIMBLE_ROOT)/nimble/src
+CRYPTO_SRC = $(NIMBLE_ROOT)/ext/tinycrypt/src
+
+# Include directories
+INCLUDES = -I$(NIMBLE_ROOT)/nimble/include \
+ -I$(NIMBLE_ROOT)/nimble/host/include \
+ -I$(NIMBLE_ROOT)/nimble/host/services/gap/include \
+ -I$(NIMBLE_ROOT)/nimble/host/services/gatt/include \
+ -I$(NIMBLE_ROOT)/nimble/host/util/include \
+ -I$(NIMBLE_ROOT)/porting/nimble/include \
+ -I$(NIMBLE_ROOT)/ext/tinycrypt/include
+
+# Collect all source files
+SRCS = $(wildcard $(HOST_SRC)/*.c) \
+ $(wildcard $(SERVICES_GAP)/*.c) \
+ $(wildcard $(SERVICES_GATT)/*.c) \
+ $(wildcard $(UTIL_SRC)/*.c) \
+ $(wildcard $(CORE_SRC)/*.c) \
+ $(wildcard $(CRYPTO_SRC)/*.c) \
+ $(PORT_SRC)/endian.c \
+ $(PORT_SRC)/mem.c \
+ $(PORT_SRC)/nimble_port.c \
+ $(PORT_SRC)/os_mbuf.c \
+ $(PORT_SRC)/os_mempool.c \
+ $(PORT_SRC)/os_msys_init.c
+
+OBJS = $(SRCS:.c=.o)
+
+.PHONY: all clean
+
+all: libnimble.so
+
+%.o: %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+
+libnimble.so: $(OBJS)
+ $(CC) -shared -o $@ $^
+ @echo "Built libnimble.so successfully"
+
+clean:
+ rm -f $(OBJS) libnimble.so
+EOF
+
+# Build the library
+make
+
+# Verify it was built
+ls -lh libnimble.so
+```
+
+### Option 2: Build from Apache Nimble Repository
+
+If you're using the official Apache Nimble repository:
+
+```bash
+git clone https://github.com/apache/mynewt-nimble.git
+cd mynewt-nimble
+
+# Follow Apache Nimble's build instructions for your platform
+# Typically involves using newt or cmake with specific configuration
+```
+
+## Installation
+
+After building, you have two options:
+
+### Option A: Use from build directory
+
+Set the `NIMBLE_ROOT` environment variable or CMake/Make variable to point to your Nimble directory:
+
+```bash
+# For CMake
+cmake -DWITH_NIMBLE_SUPPORT=ON -DNIMBLE_ROOT=/path/to/atbm-wifi/ble_host/nimble_v42 ..
+
+# For Make
+make BLEPP_NIMBLE_SUPPORT=1 NIMBLE_ROOT=/path/to/atbm-wifi/ble_host/nimble_v42
+```
+
+### Option B: Install system-wide
+
+```bash
+# Copy library
+sudo cp build/libnimble.so /usr/local/lib/
+
+# Copy headers
+sudo mkdir -p /usr/local/include/nimble
+sudo cp -r nimble/include/* /usr/local/include/nimble/
+sudo cp -r nimble/host/include/* /usr/local/include/nimble/
+# ... copy other necessary headers
+
+# Update library cache
+sudo ldconfig
+```
+
+## Verification
+
+To verify the Nimble library is properly built and linkable:
+
+```bash
+# Check library dependencies
+ldd build/libnimble.so
+
+# Check exported symbols
+nm -D build/libnimble.so | grep ble_gap
+
+# Check size (should be much smaller than 5MB)
+ls -lh build/libnimble.so
+```
+
+Expected size: ~500KB - 1MB (depending on optimization and debug symbols)
+
+## Troubleshooting
+
+### Library not found error
+
+If you get an error like:
+```
+Nimble library not found. Please build Nimble as a shared library first.
+```
+
+Make sure:
+1. The library was built successfully: `ls $NIMBLE_ROOT/build/libnimble.so`
+2. The `NIMBLE_ROOT` path is correct
+3. The library is in either `lib/` or `build/` subdirectory of `NIMBLE_ROOT`
+
+### Runtime linking errors
+
+If you get runtime errors about missing libraries:
+
+```bash
+# Check where the library is being found
+ldd /path/to/libble++.so | grep nimble
+
+# Add to library path if needed
+export LD_LIBRARY_PATH=/path/to/nimble/build:$LD_LIBRARY_PATH
+```
+
+Or use the rpath option (already included in libblepp's Makefile).
+
+## Notes
+
+- The Nimble library must be built with `-fPIC` (Position Independent Code) for shared library support
+- Thread support may be required depending on your Nimble port
+- Some Nimble ports may require additional dependencies (e.g., FreeRTOS, Zephyr OS layers)
diff --git a/README.md b/README.md
index 612a5b8..a4cb582 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,332 @@
-# libble++
+# libble++ - Modern C++ Bluetooth Low Energy Library
-Implementation of Bluetooth Low Energy functions in modern C++, without
-the BlueZ DBUS API.
+A modern C++ implementation of Bluetooth Low Energy (BLE) functionality with support for both client (central) and server (peripheral) modes, without requiring the BlueZ D-Bus API.
-### Includes
-* Scanning for bluetooth packets
-* Implementation of the GATT profile and ATT protocol
-* Lots of comments, complete with references to the specific part of
- the Bluetooth 4.0 standard.
-* Example programs
+## Features
-### Design
-Clean, modern C++ with callbacks. Feed it with lambdas (or whatever you like)
-to perform an event happens. Access provided to the raw socket FD, so
-you can use select(), poll() or blocking IO.
+### Core Functionality
+- **BLE Central/Client Mode**
+ - Scan for BLE devices
+ - Connect to peripherals
+ - Service discovery (GATT)
+ - Read/write characteristics
+ - Subscribe to notifications/indications
+ - Full ATT protocol implementation
-### The example programs
-* lescan_simple: Simplest possible program for scanning for devices. Only 2 non boilerplate lines.
-* lescan: A "proper" scanning program that cleans up properly. It's got the same 2 lines of BLE related code and a bit of pretty standard unix for dealing with non blocking I/O and signals.
-* temperature: A program for logging temperature values from a device providing a standard temperature characteristic. Very short to indicate the usave, but not much error checking.
+- **BLE Peripheral/Server Mode** *(optional)*
+ - Create custom GATT services
+ - Advertise services
+ - Accept incoming connections
+ - Handle read/write requests
+ - Send notifications/indications
+ - Attribute database management
+### Transport Layer Abstraction
+libblepp supports multiple transport layers for maximum hardware compatibility:
-### Building the library
-There are currently autoconf (./configure) and CMake options. It's not
-a complex library to build, so either option should work fine.
-Autoconf:
+- **BlueZ Transport** (Linux standard)
+ - Uses HCI sockets for scanning
+ - Uses L2CAP sockets for connections
+ - Works with any BlueZ-compatible adapter
+
+- **ATBM/NimBLE Transport** (hardware-specific)
+ - Direct ioctl interface (`/dev/atbm_ioctl`)
+ - Optimized for Altobeam WiFi+BLE combo chips
+ - Signal-based asynchronous event handling
+ - Full HCI packet wrapping/unwrapping
+
+### Design Philosophy
+- Clean, modern C++11/14 with callbacks
+- Extensively commented with references to Bluetooth 4.0+ specifications
+- Direct socket access for `select()`, `poll()`, or blocking I/O
+- No dependency on BlueZ D-Bus API
+- Thread-safe transport implementations
+
+## Quick Start
+
+### Installation
+
+#### Using CMake (Recommended)
+```bash
+mkdir build && cd build
+cmake ..
+make
+sudo make install
```
-./configure
+
+#### Using Autoconf
+```bash
+./configure
make
-```
-CMake:
+sudo make install
```
-mkdir build && cd build
+
+### Basic Scanning Example
+```cpp
+#include
+#include
+
+int main() {
+ BLEPP::log_level = BLEPP::LogLevels::Info;
+
+ // Create transport (auto-selects available transport)
+ BLEPP::BLEClientTransport* transport = BLEPP::create_client_transport();
+ if (!transport) {
+ return 1;
+ }
+
+ // Create scanner
+ BLEPP::BLEScanner scanner(transport);
+ scanner.start();
+
+ while (1) {
+ std::vector ads = scanner.get_advertisements();
+ // Process advertisements...
+ }
+
+ delete transport;
+}
+```
+
+### Basic Server Example
+```cpp
+#include
+
+int main() {
+ BLEPP::BLEGATTServer server;
+
+ // Add a service with a characteristic
+ auto service = server.add_service(0x180F); // Battery Service
+ auto characteristic = service->add_characteristic(
+ 0x2A19, // Battery Level
+ BLEPP::ReadOnly
+ );
+
+ characteristic->set_read_callback([](auto conn) {
+ return std::vector{85}; // 85% battery
+ });
+
+ server.start_advertising("MyDevice");
+ server.run(); // Event loop
+}
+```
+
+## Build Options
+
+### CMake Build Options
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `WITH_SERVER_SUPPORT` | `OFF` | Enable BLE peripheral/server mode |
+| `WITH_BLUEZ_SUPPORT` | `ON` | Enable BlueZ HCI/L2CAP transport |
+| `WITH_NIMBLE_SUPPORT` | `OFF` | Enable ATBM/NimBLE ioctl transport |
+| `WITH_EXAMPLES` | `OFF` | Build example programs |
+
+### Build Configuration Examples
+
+**Client-only (BlueZ):**
+```bash
cmake ..
-make install
+make
```
-CMake with examples:
-Examples will be in ```build/examples```
+
+**Client + Server (BlueZ):**
+```bash
+cmake -DWITH_SERVER_SUPPORT=ON ..
+make
+```
+
+**Client + Server + ATBM:**
+```bash
+cmake -DWITH_SERVER_SUPPORT=ON -DWITH_NIMBLE_SUPPORT=ON ..
+make
```
+
+**Everything with examples:**
+```bash
+cmake -DWITH_SERVER_SUPPORT=ON -DWITH_NIMBLE_SUPPORT=ON -DWITH_EXAMPLES=ON ..
+make
+```
+
+### Makefile Build Options
+
+```bash
+# Client-only
+make
+
+# Client + Server
+make BLEPP_SERVER_SUPPORT=1
+
+# Client + Server + ATBM
+make BLEPP_SERVER_SUPPORT=1 BLEPP_NIMBLE_SUPPORT=1 BLEPP_BLUEZ_SUPPORT=1
+```
+
+See [BUILD_OPTIONS.md](docs/BUILD_OPTIONS.md) for complete build configuration reference.
+
+## Example Programs
+
+Located in the `examples/` directory:
+
+**Client/Central Examples:**
+- **lescan_simple** - Minimal BLE scanning example using transport abstraction
+- **lescan** - Full-featured scanner with BlueZ HCI (signal handling, duplicate filtering)
+- **lescan_transport** - Scanner using transport abstraction layer
+- **temperature** - Read and log temperature characteristic with notifications
+- **read_device_name** - Simple example reading device name characteristic
+- **write** - Write to a characteristic (demonstrates write operations)
+- **bluetooth** - Comprehensive example with notifications, plotting, and non-blocking I/O
+- **blelogger** - Data logging from custom BLE device
+
+**Server/Peripheral Examples:**
+- **gatt_server** - Complete GATT server with Battery Service, Device Info, and custom services *(requires server support)*
+
+Build examples with CMake:
+```bash
mkdir build && cd build
cmake -DWITH_EXAMPLES=ON ..
-make install
-```
\ No newline at end of file
+make
+```
+
+Build with server support:
+```bash
+cmake -DWITH_SERVER_SUPPORT=ON -DWITH_EXAMPLES=ON ..
+make
+```
+
+Examples will be in `build/examples/`.
+
+Run examples (most require root for BLE access):
+```bash
+# Scan for devices
+sudo ./examples/lescan
+
+# Connect and read device name
+sudo ./examples/read_device_name AA:BB:CC:DD:EE:FF
+
+# Run GATT server
+sudo ./examples/gatt_server "My BLE Device"
+```
+
+## Documentation
+
+- [BUILD_OPTIONS.md](docs/BUILD_OPTIONS.md) - Complete build configuration reference
+- [CMAKE_BUILD_GUIDE.md](docs/CMAKE_BUILD_GUIDE.md) - CMake build system guide
+- [CLIENT_TRANSPORT_ABSTRACTION.md](docs/CLIENT_TRANSPORT_ABSTRACTION.md) - Transport layer architecture
+- [ATBM_IOCTL_API.md](docs/ATBM_IOCTL_API.md) - ATBM transport API reference
+
+## Requirements
+
+### Common Requirements
+- C++11 or later compiler
+- Linux kernel 3.4+ (for BLE support)
+
+### BlueZ Transport (default)
+- BlueZ 5.0 or later
+- libbluetooth-dev (development headers)
+- Root privileges or `CAP_NET_ADMIN` + `CAP_NET_RAW` capabilities
+
+Install on Debian/Ubuntu:
+```bash
+sudo apt-get install libbluetooth-dev
+```
+
+### ATBM Transport (optional)
+- Altobeam WiFi+BLE driver loaded
+- `/dev/atbm_ioctl` device accessible
+- Appropriate device permissions
+- Apache NimBLE 4.2+ (bundled with driver)
+
+## Architecture
+
+### Transport Abstraction
+```
+┌─────────────────────────────────────┐
+│ Application Code │
+└──────────────┬──────────────────────┘
+ │
+ ┌──────────┴──────────┐
+ │ │
+┌───▼─────┐ ┌────────▼────────┐
+│ Scanner │ │ GATT Client │
+└───┬─────┘ └────────┬────────┘
+ │ │
+ └──────────┬──────────┘
+ │
+ ┌──────────▼─────────────┐
+ │ BLEClientTransport │ ◄─ Abstract Interface
+ │ (Pure Virtual) │
+ └──────────┬─────────────┘
+ │
+ ┌────────┴────────┐
+ │ │
+┌─────▼──────┐ ┌─────▼──────┐
+│ BlueZ │ │ ATBM │
+│ Transport │ │ Transport │
+└─────┬──────┘ └─────┬──────┘
+ │ │
+┌─────▼──────┐ ┌─────▼──────┐
+│ HCI/L2CAP │ │ /dev/atbm │
+│ Sockets │ │ ioctl │
+└────────────┘ └────────────┘
+```
+
+## Using libblepp in Your Project
+
+### CMake
+```cmake
+find_library(BLEPP_LIB ble++ REQUIRED)
+find_path(BLEPP_INCLUDE blepp REQUIRED)
+
+add_executable(my_app main.cpp)
+target_include_directories(my_app PRIVATE ${BLEPP_INCLUDE})
+target_link_libraries(my_app ${BLEPP_LIB} bluetooth pthread)
+```
+
+### pkg-config
+```bash
+g++ main.cpp $(pkg-config --cflags --libs libblepp) -o my_app
+```
+
+### Direct Linking
+```bash
+g++ main.cpp -lble++ -lbluetooth -lpthread -o my_app
+```
+
+## License
+
+[License information - please verify in source]
+
+## Contributing
+
+Contributions are welcome! Please ensure:
+- Code follows existing style conventions
+- Changes include relevant documentation updates
+- Build succeeds with all configuration options
+- Examples compile and run correctly
+
+## References
+
+- Bluetooth Core Specification 4.0+
+- BlueZ 5.x documentation
+- Apache NimBLE documentation
+- Linux kernel Bluetooth subsystem
+
+## Version History
+
+See git history for detailed changelog. Recent major updates include:
+- ATBM/NimBLE transport support with ioctl interface
+- Transport abstraction layer for multiple hardware backends
+- Complete GATT server implementation
+- CMake build system alongside autoconf
+- Comprehensive documentation suite
+
+## Support & Issues
+
+For bugs, feature requests, or questions:
+1. Check existing documentation in `docs/`
+2. Search closed issues
+3. Open a new issue with details about your environment
+
+## Credits
+
+Originally designed for BlueZ-based systems, now extended to support multiple transport layers for broader hardware compatibility.
diff --git a/blepp/advertising.h b/blepp/advertising.h
new file mode 100644
index 0000000..9d95761
--- /dev/null
+++ b/blepp/advertising.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * blepp - Implementation of the Generic ATTribute Protocol
+ *
+ * Copyright (C) 2024
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __INC_BLEPP_ADVERTISING_H
+#define __INC_BLEPP_ADVERTISING_H
+
+#include
+#include
+#include
+
+namespace BLEPP
+{
+
+/// Parse a BLE HCI advertisement packet into structured AdvertisingResponse
+/// This is transport-agnostic and can be used by both BlueZ and ATBM implementations
+/// @param packet Raw HCI event packet data
+/// @return Vector of parsed advertising responses (may contain multiple advertisements)
+std::vector parse_advertisement_packet(const std::vector& packet);
+
+} // namespace BLEPP
+
+#endif // __INC_BLEPP_ADVERTISING_H
diff --git a/blepp/att.h b/blepp/att.h
index e86d4ac..6374141 100644
--- a/blepp/att.h
+++ b/blepp/att.h
@@ -44,7 +44,55 @@
*
*/
+#ifndef __INC_BLEPP_ATT_H
+#define __INC_BLEPP_ATT_H
+
#include
+#include
+#include
+
+// Byte order macros for Bluetooth (little-endian)
+// Only define if not already provided by bluetooth.h
+#ifndef htobs
+#ifdef __APPLE__
+#include
+#define htobs(x) OSSwapHostToLittleInt16(x)
+#define btohs(x) OSSwapLittleToHostInt16(x)
+#define htobl(x) OSSwapHostToLittleInt32(x)
+#define btohl(x) OSSwapLittleToHostInt32(x)
+#else
+#include
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobs(x) (x)
+#define btohs(x) (x)
+#define htobl(x) (x)
+#define btohl(x) (x)
+#else
+#include
+#define htobs(x) bswap_16(x)
+#define btohs(x) bswap_16(x)
+#define htobl(x) bswap_32(x)
+#define btohl(x) bswap_32(x)
+#endif
+#endif
+#endif // htobs
+
+// Unaligned access macros (replace BlueZ bt_get_unaligned/bt_put_unaligned)
+#define bt_get_unaligned(ptr) \
+__extension__ ({ \
+ struct __attribute__((packed)) { \
+ __typeof__(*(ptr)) __v; \
+ } *__p = (__typeof__(__p)) (ptr); \
+ __p->__v; \
+})
+
+#define bt_put_unaligned(val, ptr) \
+do { \
+ struct __attribute__((packed)) { \
+ __typeof__(*(ptr)) __v; \
+ } *__p = (__typeof__(__p)) (ptr); \
+ __p->__v = (val); \
+} while(0)
namespace BLEPP
{
@@ -321,3 +369,5 @@ namespace BLEPP
uint16_t enc_exec_write_req(uint8_t flags, uint8_t *pdu, size_t len);
uint16_t dec_exec_write_resp(const uint8_t *pdu, size_t len);
}
+
+#endif // __INC_BLEPP_ATT_H
diff --git a/blepp/bleattributedb.h b/blepp/bleattributedb.h
new file mode 100644
index 0000000..382c1e4
--- /dev/null
+++ b/blepp/bleattributedb.h
@@ -0,0 +1,287 @@
+/*
+ *
+ * blepp - Implementation of the Generic ATTribute Protocol
+ *
+ * Copyright (C) 2024
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __INC_BLEPP_ATTRIBUTEDB_H
+#define __INC_BLEPP_ATTRIBUTEDB_H
+
+#include
+
+#ifdef BLEPP_SERVER_SUPPORT
+
+#include
+#include
+#include
+#include
+#include