Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions cli/commands/communication/ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import click

from ...core.group_usage import LagerGroup
from ...core.net_helpers import resolve_box, post_box_command
from ...core.net_helpers import resolve_box, resolve_box_locked, post_box_command


@click.group(name='ble', cls=LagerGroup)
Expand Down Expand Up @@ -107,7 +107,7 @@ def scan(ctx, box, timeout, name_contains, name_exact, verbose):
click.secho(f"Error: Timeout must be between {MIN_TIMEOUT} and {MAX_TIMEOUT} seconds, got {timeout}", fg='red', err=True)
ctx.exit(1)

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'ble')

click.secho(f"Scanning for BLE devices for {timeout} seconds...", fg='green')
result = _post_ble(
Expand Down Expand Up @@ -149,7 +149,7 @@ def scan(ctx, box, timeout, name_contains, name_exact, verbose):
def _info_or_connect(ctx, box, address, connect_style: bool):
"""Shared body for the info and connect commands (same box action)."""
_validate_ble_address(ctx, address)
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'ble')

verb = "Connecting to" if connect_style else "Getting info for"
click.secho(f"{verb} BLE device: {address}", fg='green')
Expand Down Expand Up @@ -214,7 +214,7 @@ def disconnect(ctx, box, address):
Disconnect from a BLE device
"""
_validate_ble_address(ctx, address)
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'ble')

click.secho(f"Disconnecting from BLE device: {address}", fg='green')
result = _post_ble(ctx, box_ip, 'disconnect', http_timeout=45.0, address=address)
Expand Down
14 changes: 7 additions & 7 deletions cli/commands/communication/blufi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import click

from ...core.group_usage import LagerGroup
from ...core.net_helpers import resolve_box, post_box_command
from ...core.net_helpers import resolve_box_locked, post_box_command


@click.group(name='blufi', cls=LagerGroup)
Expand Down Expand Up @@ -43,7 +43,7 @@ def _print_json(value: dict) -> None:
@click.option('--name-contains', required=False, help='Filter devices to those whose name contains this string')
def scan(ctx, box, timeout, name_contains):
"""Scan for BluFi-capable BLE devices"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

click.secho(f"Scanning for BluFi devices for {timeout} seconds...", fg='green')
result = _post_blufi(
Expand Down Expand Up @@ -79,7 +79,7 @@ def scan(ctx, box, timeout, name_contains):
@click.argument('device_name', required=True)
def connect(ctx, box, timeout, device_name):
"""Connect to a BluFi device and retrieve version and status"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

click.secho(f"Connecting to BluFi device: {device_name}", fg='green')
result = _post_blufi(
Expand Down Expand Up @@ -108,7 +108,7 @@ def connect(ctx, box, timeout, device_name):
@click.argument('device_name', required=True)
def provision(ctx, box, timeout, ssid, password, device_name):
"""Provision WiFi credentials to a BluFi device"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

click.secho(f"Provisioning '{ssid}' to BluFi device: {device_name}", fg='green')
# Provisioning blocks box-side through connect + security negotiation +
Expand All @@ -135,7 +135,7 @@ def provision(ctx, box, timeout, ssid, password, device_name):
@click.argument('device_name', required=True)
def wifi_scan(ctx, box, timeout, scan_timeout, device_name):
"""Scan for WiFi networks via a BluFi device"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

click.secho(f"Requesting WiFi scan via {device_name} (timeout={scan_timeout}s)...", fg='green')
result = _post_blufi(
Expand Down Expand Up @@ -169,7 +169,7 @@ def wifi_scan(ctx, box, timeout, scan_timeout, device_name):
@click.argument('device_name', required=True)
def status(ctx, box, timeout, device_name):
"""Get WiFi connection status from a BluFi device"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

result = _post_blufi(
ctx, box_ip, 'status',
Expand All @@ -193,7 +193,7 @@ def status(ctx, box, timeout, device_name):
@click.argument('device_name', required=True)
def version(ctx, box, timeout, device_name):
"""Get firmware version from a BluFi device"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'blufi')

result = _post_blufi(
ctx, box_ip, 'version',
Expand Down
6 changes: 3 additions & 3 deletions cli/commands/communication/i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from texttable import Texttable

from ...core.net_group import NetGroupHelpMixin
from ...core.net_helpers import resolve_box, fetch_nets, post_net_command
from ...core.net_helpers import resolve_box, resolve_box_locked, fetch_nets, post_net_command
from ...context import get_default_net
from ...errors import net_not_specified_error

Expand Down Expand Up @@ -56,12 +56,12 @@ def parse_args(self, ctx, args):

def _resolve_box_with_name(ctx, box):
"""
Resolve box parameter to IP address.
Resolve box parameter to IP address and acquire an ephemeral lock.
Returns tuple of (ip_address, box_name).
"""
from ...box_storage import get_box_name_by_ip

resolved_ip = resolve_box(ctx, box)
resolved_ip = resolve_box_locked(ctx, box, 'i2c')

if box and not box.replace('.', '').isdigit():
resolved_name = box
Expand Down
28 changes: 14 additions & 14 deletions cli/commands/communication/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import click

from ...core.group_usage import LagerGroup
from ...core.net_helpers import resolve_box, post_net_command, NET_HTTP_PORT
from ...core.net_helpers import resolve_box, resolve_box_locked, post_net_command, NET_HTTP_PORT

ROUTER_ROLE = "router"

Expand Down Expand Up @@ -64,7 +64,7 @@ def add_net(ctx, name, address, username, password, instrument, use_ssl, box):
"""
import requests

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')

net_data = {
"name": name,
Expand Down Expand Up @@ -117,7 +117,7 @@ def connect(ctx, netname, box):

lager router connect router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "connect", "netname": netname})


Expand All @@ -133,7 +133,7 @@ def interfaces(ctx, netname, box):

lager router interfaces router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "interfaces", "netname": netname})


Expand All @@ -149,7 +149,7 @@ def wireless_interfaces(ctx, netname, box):

lager router wireless-interfaces router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "wireless_interfaces", "netname": netname})


Expand All @@ -165,7 +165,7 @@ def wireless_clients(ctx, netname, box):

lager router wireless-clients router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "wireless_clients", "netname": netname})


Expand All @@ -181,7 +181,7 @@ def dhcp_leases(ctx, netname, box):

lager router dhcp-leases router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "dhcp_leases", "netname": netname})


Expand All @@ -197,7 +197,7 @@ def system_info(ctx, netname, box):

lager router system-info router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "system_info", "netname": netname})


Expand All @@ -218,7 +218,7 @@ def reboot(ctx, netname, yes, box):
click.secho("Aborted.", fg="yellow")
return

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "reboot", "netname": netname})


Expand All @@ -235,7 +235,7 @@ def enable_interface(ctx, netname, interface, box):

lager router enable-interface router1 wlan1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "enable_interface", "netname": netname,
"interface": interface})

Expand All @@ -253,7 +253,7 @@ def disable_interface(ctx, netname, interface, box):

lager router disable-interface router1 wlan1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "disable_interface", "netname": netname,
"interface": interface})

Expand All @@ -272,7 +272,7 @@ def block_internet(ctx, netname, box):

lager router block-internet router1 --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "block_internet", "netname": netname})


Expand Down Expand Up @@ -300,7 +300,7 @@ def reset(ctx, netname, ssid, password, yes, box):
click.secho("Aborted.", fg="yellow")
return

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {
"action": "reset_to_defaults",
"netname": netname,
Expand All @@ -325,5 +325,5 @@ def run_cmd(ctx, netname, path, box):

lager router run router1 /ip/address --box mybox
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'router')
_run_router(ctx, box_ip, {"action": "run", "netname": netname, "path": path})
6 changes: 3 additions & 3 deletions cli/commands/communication/spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from texttable import Texttable

from ...core.net_group import NetGroupHelpMixin
from ...core.net_helpers import resolve_box, fetch_nets, post_net_command
from ...core.net_helpers import resolve_box, resolve_box_locked, fetch_nets, post_net_command
from ...context import get_default_net
from ...errors import net_not_specified_error

Expand Down Expand Up @@ -62,12 +62,12 @@ def parse_args(self, ctx, args):

def _resolve_box_with_name(ctx, box):
"""
Resolve box parameter to IP address.
Resolve box parameter to IP address and acquire an ephemeral lock.
Returns tuple of (ip_address, box_name) where box_name is used for username lookup.
"""
from ...box_storage import get_box_name_by_ip

resolved_ip = resolve_box(ctx, box)
resolved_ip = resolve_box_locked(ctx, box, 'spi')

if box and not box.replace('.', '').isdigit():
resolved_name = box
Expand Down
6 changes: 3 additions & 3 deletions cli/commands/communication/uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# Import consolidated helpers from cli.core.net_helpers
from ...core.net_group import NetCommand, HiddenArgument
from ...core.net_helpers import resolve_box
from ...core.net_helpers import resolve_box, resolve_box_locked
from ...context import get_default_net
from ...errors import net_not_specified_error

Expand All @@ -40,8 +40,8 @@ def _resolve_box_with_name(ctx, box):
"""
from ...box_storage import get_box_name_by_ip

# Use the shared resolve_box helper
resolved_ip = resolve_box(ctx, box)
# Use the shared resolve_box_locked helper (auto-acquires ephemeral lock)
resolved_ip = resolve_box_locked(ctx, box, 'uart')

# Try to find box name for username lookup
# If box was provided and is not an IP, it's the box name
Expand Down
3 changes: 2 additions & 1 deletion cli/commands/communication/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ...core.net_helpers import (
require_netname,
resolve_box,
resolve_box_locked,
list_nets_by_role,
display_nets_table,
validate_net_exists,
Expand Down Expand Up @@ -129,7 +130,7 @@ def usb(ctx, netname, box):
def _run_usb_action(ctx, box, action: str) -> None:
"""Shared body for the enable/disable/toggle subcommands."""
netname = require_netname(ctx, "usb")
resolved_box = resolve_box(ctx, box)
resolved_box = resolve_box_locked(ctx, box, 'usb')

# Validate net exists before invoking remote command
if _validate_usb_net(ctx, resolved_box, netname) is None:
Expand Down
10 changes: 5 additions & 5 deletions cli/commands/communication/wifi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# Import consolidated helpers from cli.core.net_helpers
from ...core.group_usage import LagerGroup
from ...core.net_helpers import resolve_box, post_box_command
from ...core.net_helpers import resolve_box, resolve_box_locked, post_box_command

# WiFi constraints
MAX_SSID_LENGTH = 32 # IEEE 802.11 maximum SSID length
Expand Down Expand Up @@ -117,7 +117,7 @@ def status(ctx, box):
"""
Get the current WiFi Status of the box
"""
box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'wifi')

result = _post_wifi(ctx, box_ip, 'status')
interfaces = (result.get('value') or {}).get('interfaces', [])
Expand Down Expand Up @@ -145,7 +145,7 @@ def access_points(ctx, box, interface='wlan0'):
# Validate interface name
_validate_interface(ctx, interface)

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'wifi')

click.secho(f"Scanning for WiFi networks on {interface}...", fg='green')
result = _post_wifi(ctx, box_ip, 'scan', interface=interface)
Expand Down Expand Up @@ -173,7 +173,7 @@ def connect(ctx, box, ssid, interface, password=''):
_validate_password(ctx, password)
_validate_interface(ctx, interface)

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'wifi')

click.secho(f"Connecting to WiFi network: {ssid}", fg='green')
result = _post_wifi(ctx, box_ip, 'connect',
Expand All @@ -200,7 +200,7 @@ def delete_connection(ctx, box, yes, ssid):
click.echo("Aborting")
return

box_ip = resolve_box(ctx, box)
box_ip = resolve_box_locked(ctx, box, 'wifi')

click.secho(f"Deleting WiFi connection: {ssid}", fg='green')
result = _post_wifi(ctx, box_ip, 'delete', ssid=ssid, connection_name=ssid)
Expand Down
14 changes: 10 additions & 4 deletions cli/commands/development/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ...core.net_group import NetGroup
from ...core.net_helpers import (
resolve_box,
resolve_box_locked,
list_nets_by_role,
validate_net_exists,
post_net_command,
Expand Down Expand Up @@ -88,11 +89,16 @@ def _validate_arm_net(ctx, box, netname) -> bool:


def _resolve_box_for_command(ctx, target_box):
"""Resolve box from command-level --box option or group-level stored box."""
"""Resolve box from command-level --box option or group-level stored box.
Acquires an ephemeral lock for hardware interaction.
"""
if target_box:
return resolve_box(ctx, target_box)
return resolve_box_locked(ctx, target_box, 'arm')
# Fall back to box stored by the group command
return getattr(ctx.obj, "resolved_box", None) or get_default_box(ctx)
stored = getattr(ctx.obj, "resolved_box", None)
if stored:
return stored
return resolve_box_locked(ctx, None, 'arm')


@click.group(
Expand Down Expand Up @@ -125,7 +131,7 @@ class _Obj: pass
# Only resolve box if box is provided at group level
# Otherwise, let subcommands resolve it
if box:
resolved = resolve_box(ctx, box)
resolved = resolve_box_locked(ctx, box, 'arm')
setattr(ctx.obj, "resolved_box", resolved)
else:
# Don't set box - let subcommands handle it
Expand Down
Loading
Loading