Let's just be done with contact validation.

This commit is contained in:
Jack Kingsman
2026-01-14 15:44:07 -08:00
parent e09d1672f1
commit b97dab1fd6

View File

@@ -34,82 +34,8 @@ router = APIRouter(prefix="/contacts", tags=["contacts"])
REPEATER_OP_DELAY_SECONDS = 5.0
async def ensure_repeater_on_radio(mc, contact: Contact) -> None:
"""Ensure a repeater contact is on the radio with flood mode.
This syncs contacts, removes any existing entry (to clear stale state),
and re-adds with flood mode. Does NOT perform login.
Args:
mc: MeshCore instance
contact: The repeater contact
Raises:
HTTPException: If contact cannot be added or removed
"""
# Sync contacts from radio to ensure our cache is up-to-date
# Use get_contacts() directly to force a fresh read (ensure_contacts may skip if cache exists)
logger.info("Syncing contacts from radio before repeater operation")
await mc.commands.get_contacts()
# Remove contact if it exists (clears any stale state on radio)
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if radio_contact:
logger.info("Removing existing contact %s from radio", contact.public_key[:12])
remove_result = await mc.commands.remove_contact(radio_contact)
# Error code 2 = NOT_FOUND, which is fine - contact already gone
if remove_result.type == EventType.ERROR:
error_code = remove_result.payload.get("error_code") if isinstance(remove_result.payload, dict) else None
if error_code != 2:
raise HTTPException(
status_code=500,
detail=f"Failed to remove contact from radio: {remove_result.payload}"
)
logger.info("Contact %s not found on radio (already removed)", contact.public_key[:12])
await mc.commands.get_contacts()
# Verify removal succeeded (skip if we got NOT_FOUND)
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if radio_contact:
raise HTTPException(
status_code=500,
detail="Failed to remove contact from radio - contact still present after removal"
)
# Add contact fresh with flood mode
logger.info("Adding repeater %s to radio with flood mode", contact.public_key[:12])
contact_data = {
"public_key": contact.public_key,
"adv_name": contact.name or "",
"type": contact.type,
"flags": contact.flags,
"out_path": "",
"out_path_len": -1, # Flood mode
"adv_lat": contact.lat or 0.0,
"adv_lon": contact.lon or 0.0,
"last_advert": contact.last_advert or 0,
}
add_result = await mc.commands.add_contact(contact_data)
if add_result.type == EventType.ERROR:
raise HTTPException(
status_code=500,
detail=f"Failed to add contact to radio: {add_result.payload}"
)
# Refresh and verify
await mc.commands.get_contacts()
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if not radio_contact:
raise HTTPException(
status_code=500,
detail="Failed to add contact to radio - contact not found after add"
)
async def prepare_repeater_connection(mc, contact: Contact, password: str) -> None:
"""Prepare connection to a repeater by adding to radio and logging in.
This ensures the contact is on the radio and performs a fresh login.
"""Prepare connection to a repeater by logging in.
Args:
mc: MeshCore instance
@@ -117,10 +43,8 @@ async def prepare_repeater_connection(mc, contact: Contact, password: str) -> No
password: Password for login (empty string for no password)
Raises:
HTTPException: If contact cannot be added or login fails
HTTPException: If login fails
"""
await ensure_repeater_on_radio(mc, contact)
# Send login with password
logger.info("Sending login to repeater %s", contact.public_key[:12])
login_result = await mc.commands.send_login(contact.public_key, password)
@@ -441,9 +365,6 @@ async def send_repeater_command(public_key: str, request: CommandRequest) -> Com
# Pause message polling to prevent it from stealing our response
async with pause_polling():
# Ensure the repeater contact is on the radio (fixes error_code 2 / ERR_CODE_NOT_FOUND)
await ensure_repeater_on_radio(mc, contact)
# Send the command
logger.info("Sending command to repeater %s: %s", contact.public_key[:12], request.command)