Files
Bjorn/bjorn_bluetooth.sh
Fabien POLLY eb20b168a6 Add RLUtils class for managing RL/AI dashboard endpoints
- Implemented methods for fetching AI stats, training history, and recent experiences.
- Added functionality to set operation mode (MANUAL, AUTO, AI) with appropriate handling.
- Included helper methods for querying the database and sending JSON responses.
- Integrated model metadata extraction for visualization purposes.
2026-02-18 22:36:10 +01:00

518 lines
18 KiB
Bash

#!/bin/bash
# bjorn_bluetooth_manager.sh
# Script to configure Bluetooth PAN for BJORN
# Usage: ./bjorn_bluetooth_manager.sh -f
# ./bjorn_bluetooth_manager.sh -u
# ./bjorn_bluetooth_manager.sh -l
# ./bjorn_bluetooth_manager.sh -h
# Author: Infinition
# Version: 1.1
# Description: This script configures and manages Bluetooth PAN for BJORN
# ============================================================
# Colors for Output
# ============================================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# ============================================================
# Logging Configuration
# ============================================================
LOG_DIR="/var/log/bjorn_install"
LOG_FILE="$LOG_DIR/bjorn_bluetooth_manager_$(date +%Y%m%d_%H%M%S).log"
# Ensure log directory exists
mkdir -p "$LOG_DIR"
# ============================================================
# Logging Function
# ============================================================
log() {
local level=$1
shift
local message="[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*"
echo -e "$message" | tee -a "$LOG_FILE"
case $level in
"ERROR") echo -e "${RED}$message${NC}" ;;
"SUCCESS") echo -e "${GREEN}$message${NC}" ;;
"WARNING") echo -e "${YELLOW}$message${NC}" ;;
"INFO") echo -e "${BLUE}$message${NC}" ;;
"CYAN") echo -e "${CYAN}$message${NC}" ;;
*) echo -e "$message" ;;
esac
}
# ============================================================
# Error Handling
# ============================================================
handle_error() {
local error_message=$1
log "ERROR" "$error_message"
exit 1
}
# ============================================================
# Function to Check Command Success
# ============================================================
check_success() {
if [ $? -eq 0 ]; then
log "SUCCESS" "$1"
return 0
else
handle_error "$1"
return $?
fi
}
# ============================================================
# Function to Show Usage
# ============================================================
show_usage() {
echo -e "${GREEN}Usage: $0 [OPTIONS]${NC}"
echo -e "Options:"
echo -e " ${BLUE}-f${NC} Install Bluetooth PAN"
echo -e " ${BLUE}-u${NC} Uninstall Bluetooth PAN"
echo -e " ${BLUE}-l${NC} List Bluetooth PAN Information"
echo -e " ${BLUE}-h${NC} Show this help message"
echo -e ""
echo -e "Example:"
echo -e " $0 -f Install Bluetooth PAN"
echo -e " $0 -u Uninstall Bluetooth PAN"
echo -e " $0 -l List Bluetooth PAN Information"
echo -e " $0 -h Show help"
echo -e ""
echo -e "${YELLOW}===== Bluetooth PAN Configuration Procedure =====${NC}"
echo -e "To configure the Bluetooth PAN driver and set the IP address, subnet mask, and gateway for the PAN network interface card, follow the steps below:"
echo -e ""
echo -e "1. **Configure IP Address on the Server (Pi):**"
echo -e " - The default IP address is set in the script as follows:"
echo -e " - IP: 172.20.2.1"
echo -e " - Subnet Mask: 255.255.255.0"
echo -e ""
echo -e "2. **Configure IP Address on the Host Computer:**"
echo -e " - On your host computer (Windows, Linux, etc.), configure the RNDIS network interface to use an IP address in the same subnet. For example:"
echo -e " - IP: 172.20.2.2"
echo -e " - Subnet Mask: 255.255.255.0"
echo -e " - Gateway: 172.20.2.1"
echo -e " - DNS Servers: 8.8.8.8, 8.8.4.4"
echo -e ""
echo -e "3. **Restart the Service:**"
echo -e " - After installing the Bluetooth PAN, restart the service to apply the changes:"
echo -e " ```bash"
echo -e " sudo systemctl restart auto_bt_connect.service"
echo -e " ```"
echo -e ""
echo -e "4. **Verify the Connection:**"
echo -e " - Ensure that the PAN network interface is active on both devices."
echo -e " - Test connectivity by pinging the IP address of the other device."
echo -e " - From the Pi: \`ping 172.20.2.2\`"
echo -e " - From the host computer: \`ping 172.20.2.1\`"
echo -e ""
echo -e "===== End of Procedure =====${NC}"
exit 1
}
# ============================================================
# Function to Install Bluetooth PAN
# ============================================================
install_bluetooth_pan() {
log "INFO" "Starting Bluetooth PAN installation..."
# Ensure the script is run as root
if [ "$(id -u)" -ne 0 ]; then
log "ERROR" "This script must be run as root. Please use 'sudo'."
exit 1
fi
# Create settings directory
SETTINGS_DIR="/home/bjorn/.settings_bjorn"
if [ ! -d "$SETTINGS_DIR" ]; then
mkdir -p "$SETTINGS_DIR"
check_success "Created settings directory at $SETTINGS_DIR"
else
log "INFO" "Settings directory $SETTINGS_DIR already exists. Skipping creation."
fi
# Create bt.json if it doesn't exist
BT_CONFIG="$SETTINGS_DIR/bt.json"
if [ ! -f "$BT_CONFIG" ]; then
log "INFO" "Creating Bluetooth configuration file at $BT_CONFIG"
cat << 'EOF' > "$BT_CONFIG"
{
"device_mac": "AA:BB:CC:DD:EE:FF" # Replace with your device's MAC address
}
EOF
check_success "Created Bluetooth configuration file at $BT_CONFIG"
log "WARNING" "Please edit $BT_CONFIG to include your Bluetooth device's MAC address."
else
log "INFO" "Bluetooth configuration file $BT_CONFIG already exists. Skipping creation."
fi
# Create auto_bt_connect.py
BT_PY_SCRIPT="/usr/local/bin/auto_bt_connect.py"
if [ ! -f "$BT_PY_SCRIPT" ]; then
log "INFO" "Creating Bluetooth auto-connect Python script at $BT_PY_SCRIPT"
cat << 'EOF' > "$BT_PY_SCRIPT"
#!/usr/bin/env python3
import json
import subprocess
import time
import logging
import os
LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
logging.basicConfig(filename="/var/log/auto_bt_connect.log", level=logging.INFO, format=LOG_FORMAT)
logger = logging.getLogger("auto_bt_connect")
CONFIG_PATH = "/home/bjorn/.settings_bjorn/bt.json"
CHECK_INTERVAL = 30 # Interval in seconds between each check
def ensure_bluetooth_service():
try:
res = subprocess.run(["systemctl", "is-active", "bluetooth"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if "active" not in res.stdout:
logger.info("Bluetooth service not active. Starting and enabling it...")
start_res = subprocess.run(["systemctl", "start", "bluetooth"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if start_res.returncode != 0:
logger.error(f"Failed to start bluetooth service: {start_res.stderr}")
return False
enable_res = subprocess.run(["systemctl", "enable", "bluetooth"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if enable_res.returncode != 0:
logger.error(f"Failed to enable bluetooth service: {enable_res.stderr}")
# Not fatal, but log it.
else:
logger.info("Bluetooth service enabled successfully.")
else:
logger.info("Bluetooth service is already active.")
return True
except Exception as e:
logger.error(f"Error ensuring bluetooth service: {e}")
return False
def is_already_connected():
# Check if bnep0 interface is up with an IP
ip_res = subprocess.run(["ip", "addr", "show", "bnep0"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if ip_res.returncode == 0 and "inet " in ip_res.stdout:
# bnep0 interface exists and has an IPv4 address
logger.info("bnep0 is already up and has an IP. No action needed.")
return True
return False
def run_in_background(cmd):
# Run a command in background, return the process
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return process
def establish_connection(device_mac):
# Attempt to run bt-network
logger.info(f"Attempting to connect PAN with device {device_mac}...")
bt_process = run_in_background(["bt-network", "-c", device_mac, "nap"])
# Wait a bit for PAN to set up
time.sleep(3)
# Check if bt-network exited prematurely
if bt_process.poll() is not None:
# Process ended
if bt_process.returncode != 0:
stderr_output = bt_process.stderr.read() if bt_process.stderr else ""
logger.error(f"bt-network failed: {stderr_output}")
return False
else:
logger.warning("bt-network ended immediately. PAN may not be established.")
return False
else:
logger.info("bt-network running in background...")
# Now run dhclient for IPv4
dh_res = subprocess.run(["dhclient", "-4", "bnep0"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if dh_res.returncode != 0:
logger.error(f"dhclient failed: {dh_res.stderr}")
return False
logger.info("Successfully obtained IP on bnep0. PAN connection established.")
return True
def load_config():
if not os.path.exists(CONFIG_PATH):
logger.error(f"Config file {CONFIG_PATH} not found.")
return None
try:
with open(CONFIG_PATH, "r") as f:
config = json.load(f)
device_mac = config.get("device_mac")
if not device_mac:
logger.error("No device_mac found in config.")
return None
return device_mac
except Exception as e:
logger.error(f"Error loading config: {e}")
return None
def main():
device_mac = load_config()
if not device_mac:
return
while True:
try:
if not ensure_bluetooth_service():
logger.error("Bluetooth service setup failed.")
elif is_already_connected():
# Already connected and has IP, do nothing
pass
else:
# Attempt to establish connection
success = establish_connection(device_mac)
if not success:
logger.warning("Failed to establish PAN connection.")
except Exception as e:
logger.error(f"Unexpected error in main loop: {e}")
# Wait before the next check
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
EOF
check_success "Created Bluetooth auto-connect Python script at $BT_PY_SCRIPT"
else
log "INFO" "Bluetooth auto-connect Python script $BT_PY_SCRIPT already exists. Skipping creation."
fi
# Make the Python script executable
chmod +x "$BT_PY_SCRIPT"
check_success "Made Python script executable at $BT_PY_SCRIPT"
# Create the systemd service
BT_SERVICE="/etc/systemd/system/auto_bt_connect.service"
if [ ! -f "$BT_SERVICE" ]; then
log "INFO" "Creating systemd service at $BT_SERVICE"
cat << 'EOF' > "$BT_SERVICE"
[Unit]
Description=Auto Bluetooth PAN Connect
After=network.target bluetooth.service
Wants=bluetooth.service
[Service]
Type=simple
ExecStart=/usr/local/bin/auto_bt_connect.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
check_success "Created systemd service at $BT_SERVICE"
else
log "INFO" "Systemd service $BT_SERVICE already exists. Skipping creation."
fi
# Reload systemd daemon
systemctl daemon-reload
check_success "Reloaded systemd daemon"
# Enable and start the service
systemctl enable auto_bt_connect.service
check_success "Enabled auto_bt_connect.service"
systemctl start auto_bt_connect.service
check_success "Started auto_bt_connect.service"
echo -e "${GREEN}Bluetooth PAN installation completed successfully. A reboot is required for changes to take effect.${NC}"
}
# ============================================================
# Function to Uninstall Bluetooth PAN
# ============================================================
uninstall_bluetooth_pan() {
log "INFO" "Starting Bluetooth PAN uninstallation..."
# Ensure the script is run as root
if [ "$(id -u)" -ne 0 ]; then
log "ERROR" "This script must be run as root. Please use 'sudo'."
exit 1
fi
BT_SERVICE="/etc/systemd/system/auto_bt_connect.service"
BT_PY_SCRIPT="/usr/local/bin/auto_bt_connect.py"
SETTINGS_DIR="/home/bjorn/.settings_bjorn"
BT_CONFIG="$SETTINGS_DIR/bt.json"
# Stop and disable the service
if systemctl is-active --quiet auto_bt_connect.service; then
systemctl stop auto_bt_connect.service
check_success "Stopped auto_bt_connect.service"
else
log "INFO" "auto_bt_connect.service is not running."
fi
if systemctl is-enabled --quiet auto_bt_connect.service; then
systemctl disable auto_bt_connect.service
check_success "Disabled auto_bt_connect.service"
else
log "INFO" "auto_bt_connect.service is not enabled."
fi
# Remove the systemd service file
if [ -f "$BT_SERVICE" ]; then
rm "$BT_SERVICE"
check_success "Removed $BT_SERVICE"
else
log "INFO" "$BT_SERVICE does not exist. Skipping removal."
fi
# Remove the Python script
if [ -f "$BT_PY_SCRIPT" ]; then
rm "$BT_PY_SCRIPT"
check_success "Removed $BT_PY_SCRIPT"
else
log "INFO" "$BT_PY_SCRIPT does not exist. Skipping removal."
fi
# Remove Bluetooth configuration directory and file
if [ -d "$SETTINGS_DIR" ]; then
rm -rf "$SETTINGS_DIR"
check_success "Removed settings directory at $SETTINGS_DIR"
else
log "INFO" "Settings directory $SETTINGS_DIR does not exist. Skipping removal."
fi
# Reload systemd daemon
systemctl daemon-reload
check_success "Reloaded systemd daemon"
log "SUCCESS" "Bluetooth PAN uninstallation completed successfully."
}
# ============================================================
# Function to List Bluetooth PAN Information
# ============================================================
list_bluetooth_pan_info() {
echo -e "${CYAN}===== Bluetooth PAN Information =====${NC}"
BT_SERVICE="/etc/systemd/system/auto_bt_connect.service"
BT_PY_SCRIPT="/usr/local/bin/auto_bt_connect.py"
BT_CONFIG="/home/bjorn/.settings_bjorn/bt.json"
# Check status of auto_bt_connect.service
echo -e "\n${YELLOW}Service Status:${NC}"
if systemctl list-units --type=service | grep -q auto_bt_connect.service; then
systemctl status auto_bt_connect.service --no-pager
else
echo -e "${RED}auto_bt_connect.service is not installed.${NC}"
fi
# Check if Bluetooth auto-connect Python script exists
echo -e "\n${YELLOW}Bluetooth Auto-Connect Script:${NC}"
if [ -f "$BT_PY_SCRIPT" ]; then
echo -e "${GREEN}$BT_PY_SCRIPT exists.${NC}"
else
echo -e "${RED}$BT_PY_SCRIPT does not exist.${NC}"
fi
# Check Bluetooth configuration file
echo -e "\n${YELLOW}Bluetooth Configuration File:${NC}"
if [ -f "$BT_CONFIG" ]; then
echo -e "${GREEN}$BT_CONFIG exists.${NC}"
echo -e "${CYAN}Contents:${NC}"
cat "$BT_CONFIG"
else
echo -e "${RED}$BT_CONFIG does not exist.${NC}"
fi
echo -e "\n===== End of Information ====="
}
# ============================================================
# Function to Display the Main Menu
# ============================================================
display_main_menu() {
while true; do
clear
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Bluetooth PAN Manager Menu ║${NC}"
echo -e "${BLUE}╠════════════════════════════════════════╣${NC}"
echo -e "${BLUE}${NC} 1. Install Bluetooth PAN ${BLUE}${NC}"
echo -e "${BLUE}${NC} 2. Uninstall Bluetooth PAN ${BLUE}${NC}"
echo -e "${BLUE}${NC} 3. List Bluetooth PAN Information ${BLUE}${NC}"
echo -e "${BLUE}${NC} 4. Show Help ${BLUE}${NC}"
echo -e "${BLUE}${NC} 5. Exit ${BLUE}${NC}"
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
echo -e "Note: Ensure you run this script as root."
echo -e "${YELLOW}Usage: $0 [OPTIONS] (use -h for help)${NC}"
echo -n -e "${GREEN}Please choose an option (1-5): ${NC}"
read choice
case $choice in
1)
install_bluetooth_pan
echo ""
read -p "Press Enter to return to the menu..."
;;
2)
uninstall_bluetooth_pan
echo ""
read -p "Press Enter to return to the menu..."
;;
3)
list_bluetooth_pan_info
echo ""
read -p "Press Enter to return to the menu..."
;;
4)
show_usage
;;
5)
log "INFO" "Exiting Bluetooth PAN Manager. Goodbye!"
exit 0
;;
*)
log "ERROR" "Invalid option. Please choose between 1-5."
sleep 2
;;
esac
done
}
# ============================================================
# Process Command Line Arguments
# ============================================================
while getopts ":fulh" opt; do
case $opt in
f)
install_bluetooth_pan
exit 0
;;
u)
uninstall_bluetooth_pan
exit 0
;;
l)
list_bluetooth_pan_info
exit 0
;;
h)
show_usage
;;
\?)
echo -e "${RED}Invalid option: -$OPTARG${NC}" >&2
show_usage
;;
esac
done
# ============================================================
# Main Execution
# ============================================================
# If no arguments are provided, display the menu
if [ $OPTIND -eq 1 ]; then
display_main_menu
fi