Metadata-Version: 2.1
Name: brainframe-onvif-tools
Version: 0.1
Summary: This is the package including tools for BrainFrame developers to work with onvif cameras.
License: BSD License
Author: Stephen Li
Author-email: stephen@aotu.ai
Requires-Python: >=3.8,<4.0
Classifier: License :: OSI Approved :: BSD License
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Dist: PyYAML (>=6.0.2,<7.0.0)
Requires-Dist: python_i18n (>=0.3.9,<0.4.0)
Requires-Dist: requests (>=2.32.3,<3.0.0)
Description-Content-Type: text/markdown

# ONVIF Tools - Latest Updates

## Changes Made

This update implements the following improvements to the ONVIF tools:

### 1. Configuration File Rename
- **Changed:** `brainframe_config.csv` → `config.csv`
- **Reason:** `.csv` extension makes it clearer that the file is in CSV format
- **Impact:** All three scripts and documentation updated

### 2. Column Order Update
- **Changed:** Column order in the CSV header
- **Old:** `...system_datetime,osd,rtsp_url`
- **New:** `...system_datetime,rtsp_url,osd`
- **Reason:** RTSP URL logically precedes OSD text in importance
- **Impact:** All three scripts updated to write columns in the new order

### 3. Script Rename
- **Changed:** `validate_rtsp_urls.py` → `validate_onvif_cameras.py`
- **Reason:** Better reflects the script's purpose of validating ONVIF cameras
- **Impact:** Main script renamed, and import statement in `brainframe-onvif-tools.py` updated

### 4. Documentation Updates
- **Updated:** CHANGES.md to reflect all changes
- **Created:** This README.md to summarize deliverables

## Authentication Design and Workflow

This tool suite employs a robust, multi-stage authentication strategy designed to be safe, efficient, and reliable. The core philosophy is to prevent camera lockouts caused by brute-force attacks while providing flexibility for different network environments.

### Core Principles

1.  **A Single Source of Truth:** The system is built on the principle that a single camera has one primary administrative credential set. The `scan` script's job is to **discover** this credential, and the `validate` script's job is to **verify** it against other services (like RTSP).

2.  **Safety First (No Brute-Force):** The `validate` script **never** attempts to discover credentials. It only uses the single credential provided by the `scan` phase or a manual user override. This deliberate design eliminates the risk of sending multiple failed login attempts and getting locked out by camera security features.

3.  **Predictable Priority:** The scripts follow a strict and predictable order of precedence for credential sources:
    1.  **Command-Line (CLI) Override:** Highest priority. A user-provided credential is treated as an expert instruction and is used exclusively.
    2.  **JSON Inventory File:** The default source, using the credential discovered during the `scan` phase.
    3.  **Common Credentials List:** Lowest priority, used only during the `scan` phase if no override is given.

4.  **Anonymous-First:** For any camera, an anonymous login is always attempted first to correctly identify and classify cameras that do not require authentication.

### The Three-Stage Workflow

The authentication logic is distributed across the three main commands:

#### 1. `discover`
*   **Role:** Finds potential camera IPs on the network.
*   **Authentication:** None. This stage is completely anonymous and uses network broadcast protocols.

#### 2. `scan`
*   **Role:** Discovers the single, correct administrative credential for each camera.
*   **Credential Order of Attempt:**
    1.  **Anonymous (`""`/`""`):** Always tried first. If successful, the script **stops** and records the camera as anonymous.
    2.  **CLI Override (`--user`/`--password`):** If an anonymous attempt fails and a CLI override is provided, **only** that credential is used. If it fails, the script **stops** and reports the failure for that camera.
    3.  **Common Credentials List:** If the Anonymous fails and no CLI Override was given, the script tries a list of common credentials. It **stops** on the first success.
*   **Output:** The `camera_onvif_info.json` file now contains one confirmed credential set (or anonymous) for each successfully scanned camera.

#### 3. `validate`
*   **Role:** Verifies the discovered credential against RTSP and Snapshot services. It **never** discovers new credentials.
*   **Credential Source Priority:**
    1.  **CLI Override (`--user`/`--password`):** If provided, this credential is used **instead of** what's in the JSON file. If it fails, the validation fails. There is no fallback.
    2.  **JSON File (`camera_onvif_info.json`):** If no override is given, the script uses the single credential set from the JSON file. If it fails, the validation fails.
*   **Behavior:** This script will only ever make **one** authentication attempt per stream, ensuring it is safe to run repeatedly.

### Handling Edge Cases

It is rare, but possible, for a camera's RTSP or Snapshot service to use a different credential than its ONVIF administrative service. This design handles that scenario safely:

*   In an edge case where the `validate` step fails with the discovered credential, the stream is correctly marked as **invalid**.
*   This provides clear feedback to the user that the service requires a different authentication method.
*   The user can then investigate the camera's web interface and use the **CLI override** as an expert tool to provide the correct, specific credential for that service, ensuring all cameras can be configured correctly without compromising safety.

**Note on CLI Overrides:** When using an override with the `validate` command, it will update the final `config.csv` with the successful override credentials to produce a working configuration. However, it will not modify the master `camera_onvif_info.json` inventory. To permanently update the inventory with new credentials, you should update the `credentials.txt` or re-run the `scan` command with new credentials.

## Deliverables

### Updated Scripts
1. **discover_onvif_cameras.py** - Updated for `config.csv` and new column order
2. **scan_onvif_cameras.py** - Updated for `config.csv` and new column order
3. **validate_onvif_cameras.py** - Renamed from `validate_rtsp_urls.py`, updated for `config.csv` and new column order
4. **brainframe-onvif-tools.py** - Updated to import `validate_onvif_cameras` instead of `validate_rtsp_urls`

### Documentation
5. **CHANGES.md** - Updated with complete change history
6. **README.md** - This file, summarizing deliverables

## Files Changed Summary

| File | Type of Change | Description |
|------|---------------|-------------|
| discover_onvif_cameras.py | Modified | Filename and column order |
| scan_onvif_cameras.py | Modified | Filename and column order |
| validate_rtsp_urls.py → validate_onvif_cameras.py | Renamed + Modified | File rename, filename and column order |
| brainframe-onvif-tools.py | Modified | Import statement and help text |
| CHANGES.md | Modified | Updated documentation |

## New CSV Header Format

```
# ip:port,username,password,manufacturer,model,serial_number,audio_in,audio_out,auth_required,encoding,width,height,framerate,bitrate,system_datetime,rtsp_url,osd
```

Note: `rtsp_url` now appears before `osd`

## Backward Compatibility

⚠️ **Important:** These changes are NOT backward compatible with:
- Old `brainframe.config` files (different filename)
- Files using the old column order (osd before rtsp_url)

To migrate:
1. Run `discover` again to create a new `config.csv`
2. Or manually rename and reorder columns in existing files

## Usage

All scripts continue to work the same way, just with the new filenames:

```bash
# Discover cameras
python3 discover_onvif_cameras.py --auto

# Scan cameras
python3 scan_onvif_cameras.py

# Validate cameras
python3 validate_onvif_cameras.py

# Or use the unified tool
python3 brainframe-onvif-tools.py discover
python3 brainframe-onvif-tools.py scan
python3 brainframe-onvif-tools.py validate
```

## What Stayed the Same

- File structure with opening/closing tags: `<add_stream, load_settings, start_analyzing>` and `</>`
- CSV format with comma-separated values
- All command-line arguments
- All functionality and features
- RTSP URL embedding with credentials
- Video encoder information extraction
- Snapshot functionality

Only the filename, column order, and one script name changed.

