blz_ble_shim

Runs AndroWish Bluetooth-LE Tcl apps unaltered on Linux/BlueZ, with a hardware-free DE1/Skale simulator for testing.

blz_ble_shim on GitHub →

What it is

blz_ble_shim runs AndroWish / Android Bluetooth-LE Tcl code unaltered on Linux/BlueZ. It installs an AndroWish-compatible ble command implemented on top of undroidwish's built-in blz (BlueZ) command. Programs written against AndroWish's ble API — for example the Decent Espresso de1app — run on desktop/embedded Linux with no code changes, save one line:

package require blz_ble_shim

It ships with a simulator (blz_sim) backed by virtual DE1 + Skale devices, for developing and testing AndroWish BLE apps on any platform, including macOS, with no Bluetooth hardware.

AndroWish (Android) provides a ble command. undroidwish on Linux instead provides blz, a different BlueZ-backed command. The two use the same concepts but different verbs and event shapes, so AndroWish BLE apps do not run as-is on Linux. This package presents the AndroWish ble surface and translates every call and event to and from blz.

your AndroWish app ──ble …──▶ blz_ble_shim ──blz …──▶ BlueZ (bluetoothd)
        (unchanged)          (this package)          (undroidwish on Linux)

How it works

blz emits only three callbacks (scan, connection, notification) and its read / write are synchronous with no event. AndroWish apps, however, sequence on events blz never sends — the write-with-response ACK (characteristic access=w), the read-completion (access=r), the per-service discovery stream (characteristic state=discovery), and the notification-enable acknowledgement (descriptor access=w). The shim synthesizes those events, delivered asynchronously (via after 0) so ordering matches Android. It also:

The install is guarded: it registers the global ble command only if no real ble already exists and blz is present. It also does package provide ble 1.0, so an app's own package require ble is satisfied. Everywhere else it stays inert: it does not override a real ble (Android, or macOS CoreBluetooth) and does not crash when blz is absent.

Status

undroidwish's downloadable prebuilt binaries do not bundle blz; it lives in the AndroWish source tree and must be compiled in (see below).

Building & using

Pick either install form — both make package require blz_ble_shim work.

A. Installer

./install.sh            # -> /usr/local/lib  (tclsh/wish/undroidwish; may need sudo)
./install.sh --user     # -> ~/Library/Tcl   (no sudo)
./install.sh /my/libdir # -> a directory of your choice

B. By hand — copy pkgIndex.tcl, blz_ble_shim.tcl, and blz_sim.tcl into a blz_ble_shim/ directory on Tcl's auto_path, or point TCLLIBPATH at wherever you put them. Cloning the repo and putting the clone on auto_path also works — the repo root is a valid package directory.

C. Single-file Tcl Module — copy blz_ble_shim.tcl renamed blz_ble_shim-1.0.tm to a directory on tcl::tm::path.

Then, in your app:

package require blz_ble_shim

Override the BlueZ adapter with the environment variable BLZ_ADAPTER=hciN (default hci0).

Building the real blz (Linux). undroidwish's prebuilt binaries do not bundle blz; it must be compiled from the AndroWish source tree. docs/BUILDING_BLZ.md has a step-by-step recipe. The gotchas:

The hardware-free simulator

The companion blz_sim package is a simulated blz (matching the real command contract) backed by virtual DE1 and Skale peripherals. They advertise, complete discovery, ACK writes, react to writes (a RequestedState write drives a StateInfo notification), and stream weight notifications in the real 18-byte Atomax format. This allows development and testing on any platform, including macOS, where the real blz cannot run (it needs Linux sd-bus + BlueZ).

package require blz_sim          ;# simulated blz + virtual devices
package require blz_ble_shim     ;# `ble` on top of the simulator

Run the bundled examples:

tclsh examples/scan.tcl --sim               # list the virtual devices
wish8.6 examples/run_bledemo_sim.tcl        # full GUI BLE debugger, no radio

examples/bledemo.tcl is a LightBlue-style BLE debugger (scan → connect → browse services → read / subscribe / write). It is an unmodified AndroWish app, run as-is on the shim.

Limitations. blz (BlueZ) exposes a smaller surface than Android's GATT layer, so a few AndroWish features are approximated or unavailable — none of which affect typical central-role apps (DE1, scales, sensors):

Repository

Source, installer, tests, examples, and the blz build recipe: github.com/johnbuckman/blz_ble_shim. Tcl/Tk (BSD-style) license.