Metadata-Version: 2.4
Name: bt-pan
Version: 0.1.0
Summary: Bluetooth PAN gateway and client management for Linux
Author-email: Chris Watkins <chris@watkinslabs.com>
License: MIT
Project-URL: Homepage, https://github.com/chris17453/bt-nap
Project-URL: Repository, https://github.com/chris17453/bt-nap
Project-URL: Issues, https://github.com/chris17453/bt-nap/issues
Keywords: bluetooth,pan,nap,tethering,bluez
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Networking
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: dbus-python>=1.2
Requires-Dist: PyGObject>=3.40
Provides-Extra: dev
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Provides-Extra: build
Requires-Dist: build; extra == "build"
Requires-Dist: twine; extra == "build"
Dynamic: license-file

# bt-pan

Bluetooth PAN gateway and client management for Linux. One tool, one install,
both ends. Server runs a NAP gateway that bridges Bluetooth clients to the
internet; client connects automatically on boot.

## Install

```bash
sudo dnf install python3-dbus python3-gobject python3-pip
sudo pip install /path/to/bt-pan
# or, from a clone:
sudo pip install .
```

The `dbus-python` and `PyGObject` packages have C dependencies; on
Fedora/RHEL the `dnf` install above is the path of least resistance. Pip
will then pick up the already-installed system bindings.

## Bring up a gateway (server)

```bash
sudo btpan install server
# defaults: bridge=pan0, cidr=192.168.44.1/24, upstream=auto-detect,
#           dns=1.1.1.1,8.8.8.8, dhcp range .10-.100
```

Customize:

```bash
sudo btpan install server --cidr 10.66.0.1/24 --upstream eth0 --alias my-bt-gw
```

Note the printed adapter MAC — you'll need it on the client.

## Bring up a client

If you know the server MAC:

```bash
sudo btpan install client AA:BB:CC:DD:EE:FF
```

If you don't, scan + pick interactively (with explicit confirmation):

```bash
sudo btpan install client --pair
```

## Day-to-day

```bash
btpan status                 # auto-detects role, prints checks; exit code reflects health
btpan status --json          # machine-readable
btpan stats --watch          # live bandwidth + lease + device view
btpan devices                # paired devices known to BlueZ
btpan scan --nap-only        # find NAP-capable gateways nearby
btpan tail                   # journalctl -fu for all bt-pan units
btpan logs --since 1h        # recent journal output
btpan doctor                 # deeper diagnostics + suggested fixes
sudo btpan reload            # restart all bt-pan services
sudo btpan pair MAC          # pair (and trust) a device
sudo btpan unpair MAC        # remove pairing
sudo btpan disconnect        # one-shot disconnect (service stays enabled)
sudo btpan uninstall         # remove all bt-pan units + config
```

## What it actually does

**Server install** writes:

- `/etc/sysctl.d/99-bt-pan.conf` — IPv4 forwarding
- `/etc/NetworkManager/conf.d/99-bt-pan.conf` — keep `pan0` and `bnep*` out of NM
- `/etc/nftables/bt-pan.nft` — masquerade `pan0` subnet through the upstream iface
- `/etc/modules-load.d/bt-pan-bnep.conf` — pin the kernel `bnep` module
- `/etc/systemd/system/bt-pan-{bridge,nft,dnsmasq,server}.service`

…and registers the BlueZ NAP profile + a `NoInputNoOutput` pairing agent so
clients can pair without operator input.

**Client install** writes:

- `/etc/modules-load.d/bt-pan-bnep.conf`
- An `nmcli` connection profile `bt-pan` for DHCP on `bnep0`
- `/etc/systemd/system/bt-pan-client.service`

## File layout

```
bt-pan/
├── pyproject.toml
├── README.md
├── legacy/             # original bash scripts, kept for reference
└── src/btpan/
    ├── cli.py          # click CLI, all subcommands
    ├── daemon.py       # `serve` and `connect` long-running entry points
    ├── bluez.py        # BlueZ D-Bus wrappers + pairing Agent
    ├── pair.py         # scan + interactive pair flow
    ├── system.py       # bridge, sysctl, NM, nftables, dnsmasq glue
    ├── services.py     # systemd unit templates
    ├── install.py      # install/uninstall orchestration
    ├── status.py       # health checks
    ├── stats.py        # bandwidth + leases + paired-device telemetry
    ├── config.py       # defaults and well-known paths
    └── util.py         # process runner, color, root check
```

## Caveats

- **Bandwidth**: BR/EDR PAN tops out at ~1–2 Mbps real-world. Fine for SSH,
  APIs, IRC. Painful for large package updates or video.
- **Range**: ~10 m, attenuated through walls.
- **Pairing**: defaults to `Just Works` (NoInputNoOutput). The first pairing
  is the trust ceremony — do it in a known-clean RF environment, or pass
  `--alias` to `btpan pair` to defend against MAC-name spoofing.
- **firewalld**: the install assumes firewalld is off. If you turn it on later,
  it will flush the `inet bt-pan` nftables table; re-run `btpan install server`
  to reapply, or seed firewalld zones first.
- **Distro support**: tested on Fedora/RHEL 10. Debian/Ubuntu would need the
  `dnf install` block in `install.py` swapped for `apt-get install`.
# bt-nap
