# UCM6301 HTTPS API Probe

## Scope

`tools/ucm_https_api_probe.php` is a DEV-only, read-only client for Grandstream's newer IPPBX HTTPS API. The global HTTPS API interface must be enabled on the UCM, and the configured API user must have the required API permissions.

The probe sends JSON `POST` requests to `<base_url>/api`. It does not use the legacy `/recapi` interface, HTTP Digest authentication, browser GUI endpoints, or audio-download operations.

## Authentication and query flow

The implemented sequence is:

1. Request `challenge` using the configured API username and version `1.0`.
2. Calculate the login token as `MD5(challenge + password)`, using direct string concatenation.
3. Request `login` and retain the returned session cookie internally.
4. Request `cdrapi` with that cookie, `format=json`, the requested time range, offset zero, and a bounded record limit.
5. Traverse the returned CDR trees and request `getRecordInfosByCall` for every node containing recording metadata.

Every authenticated request passes the cookie inside the documented JSON request object. The probe stops on a non-zero or missing API status.

## CDR and recording correlation

Each `cdr_root` item is treated as a CDR tree. The probe dynamically examines `main_cdr` and every key matching `sub_cdr_N`; it does not assume a fixed sub-CDR number.

For each node with a non-empty `recordfiles` value, the probe internally retains its `AcctId`, `uniqueid`, `session`, `cdr`, timestamps, caller, destination, disposition, service, and normalized recording paths. It then calls `getRecordInfosByCall` using the `AcctId` from that same recording-bearing node. A wrapper CDR value, another node's `AcctId`, `uniqueid`, or `session` is not substituted for the ID.

Recording values may contain multiple entries separated by `@` or comma. Empty trailing delimiters, including a trailing `@`, are removed during normalization. Directory paths are preserved internally for exact comparison, but are masked in output. Both API results must normalize to the same ordered entries or the probe exits with an error.

Only relative `.wav` metadata paths are accepted. Paths containing `..`, null bytes, backslashes, or a leading slash are rejected. The probe does not request or download audio.

## Ignored local configuration

Configuration is read only from `tools/ucm_https_api_probe.secret.php`, which is covered by the repository's `*.secret.php` ignore rule:

```php
<?php

return [
    'base_url' => 'https://ucm6301-dev.example.invalid:8089',
    'username' => 'replace-with-api-user',
    'password' => 'replace-with-api-password',
    'verify_tls' => true,
    'ca_bundle' => '/absolute/path/to/dev-ucm-ca.pem',
];
```

`verify_tls=false` is permitted only as an explicit, temporary DEV setting and produces a warning. Normal use should verify TLS, using a trusted CA bundle when necessary.

## Usage

Both timestamps are required and intentionally omit a timezone suffix:

```bash
php tools/ucm_https_api_probe.php \
  --start="2026-07-20T00:00:00" \
  --end="2026-07-20T23:59:59" \
  --limit=10
```

The limit defaults to 10 and must be between 1 and 100.

## Output and safety controls

Output is limited to API step status, CDR and recording-node counts, caller and callee values masked to their final three digits, masked recording patterns, extensions, directory presence, and recording-metadata match status.

The probe never prints passwords, challenge values, login tokens, cookies, authorization data, complete telephone numbers, complete recording filenames, or device identifiers. Redirects and HTML responses are rejected, `application/json` is required, and each response is limited to 1 MiB.

## Validation

```bash
php -l tools/ucm_https_api_probe.php
git diff --check
git status --short
```
