3d05768f00
- aes67_sdp_sap: aes67_sdp_build() builds the AES67 SDP (RFC 4566 + RFC 7273) with the same lines and order as the web UI preview; GET /stream.sdp serves it as application/sdp. - aes67_ptp: public aes67_ptp_gm_id(), aes67_ptp_locked(), aes67_ptp_now_ns(). Clock IDs are now uppercase (RFC 7273 style), also in status.ptp, which the UI copies into ts-refclk. - aes67_net: aes67_net_netif() returns the AES67 interface. - Verified on board: /stream.sdp byte-identical to the UI's sdp() for the same config/status; mono, L16, ptime 0.333, ttl 8, clk_offset 4294967295 and session_ver all follow the config. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.0 KiB
C
68 lines
2.0 KiB
C
#include "aes67_ptp.h"
|
|
|
|
#include "aes67_cfg.h"
|
|
#include "aes67_web.h"
|
|
#include "ptp_clock.h"
|
|
#include "ptp_hw.h"
|
|
|
|
// Core defaults: Riedel SIC intervals, role auto with fallback priorities (docs/aes67-core-base.md).
|
|
static const char PTP_DEFAULTS[] =
|
|
"{\"mode\":\"multicast\",\"role\":\"auto\",\"domain\":0,\"priority1\":250,\"priority2\":250,"
|
|
"\"log_sync\":0,\"log_announce\":1,\"announce_timeout\":3,\"log_delay_req\":0,"
|
|
"\"dscp\":46,\"hw_ts\":true}";
|
|
|
|
static bool ptp_validate(const cJSON *g, char *err, size_t n)
|
|
{
|
|
static const char *const modes[] = { "multicast", "hybrid", NULL };
|
|
static const char *const roles[] = { "slave", "auto", "master", NULL };
|
|
return cfg_check_enum(g, "mode", modes, err, n) &&
|
|
cfg_check_enum(g, "role", roles, err, n) &&
|
|
cfg_check_int(g, "domain", 0, 127, err, n) &&
|
|
cfg_check_int(g, "priority1", 0, 255, err, n) &&
|
|
cfg_check_int(g, "priority2", 0, 255, err, n) &&
|
|
cfg_check_int(g, "log_sync", -4, 1, err, n) &&
|
|
cfg_check_int(g, "log_announce", 0, 4, err, n) &&
|
|
cfg_check_int(g, "announce_timeout", 2, 10, err, n) &&
|
|
cfg_check_int(g, "log_delay_req", -4, 1, err, n) &&
|
|
cfg_check_int(g, "dscp", 0, 63, err, n);
|
|
}
|
|
|
|
esp_err_t aes67_ptp_init(void)
|
|
{
|
|
return cfg_register("ptp", PTP_DEFAULTS, ptp_validate, NULL);
|
|
}
|
|
|
|
esp_err_t aes67_ptp_start(esp_eth_handle_t eth)
|
|
{
|
|
esp_netif_t *netif = esp_netif_get_handle_from_ifkey("ETH_DEF");
|
|
esp_err_t err = ptp_hw_init(eth, netif);
|
|
if (err != ESP_OK) {
|
|
return err;
|
|
}
|
|
err = ptp_clock_start(netif);
|
|
if (err == ESP_OK) {
|
|
err = status_register(ptp_clock_status);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
bool aes67_ptp_gm_id(char out[24])
|
|
{
|
|
return ptp_clock_gm_id(out);
|
|
}
|
|
|
|
bool aes67_ptp_locked(void)
|
|
{
|
|
return ptp_clock_locked();
|
|
}
|
|
|
|
esp_err_t aes67_ptp_now_ns(int64_t *ns)
|
|
{
|
|
eth_mac_time_t t;
|
|
esp_err_t err = ptp_hw_get_time(&t);
|
|
if (err == ESP_OK) {
|
|
*ns = (int64_t)t.seconds * 1000000000LL + t.nanoseconds;
|
|
}
|
|
return err;
|
|
}
|