// Provider communication — mDNS discovery, device registration, screen fetch. #include "provider.hpp" #include #include #include "esp_log.h" #include "mdns.h" #include "sdkconfig.h" #include "http_client.hpp" #include "network.hpp" static const char *TAG = "Provider"; // ── mDNS Provider Discovery ──────────────────────────────────────────────── // Resolve the Provider's IP via mDNS. Returns true and fills `out_ip` on // success. Falls back to CONFIG_CALENDINK_PROVIDER_FALLBACK_IP if set. static bool resolve_provider_ip(char *out_ip, size_t out_ip_len) { ESP_LOGI(TAG, "Resolving Provider via mDNS: %s.local", CONFIG_CALENDINK_PROVIDER_MDNS_HOSTNAME); esp_err_t err = mdns_init(); if (err != ESP_OK) { ESP_LOGE(TAG, "mDNS init failed: %s", esp_err_to_name(err)); goto fallback; } { esp_ip4_addr_t addr = {}; err = mdns_query_a(CONFIG_CALENDINK_PROVIDER_MDNS_HOSTNAME, 5000, &addr); if (err == ESP_OK) { snprintf(out_ip, out_ip_len, IPSTR, IP2STR(&addr)); ESP_LOGI(TAG, "Provider resolved: %s", out_ip); return true; } ESP_LOGW(TAG, "mDNS resolution failed: %s", esp_err_to_name(err)); } fallback: if (strlen(CONFIG_CALENDINK_PROVIDER_FALLBACK_IP) > 0) { strlcpy(out_ip, CONFIG_CALENDINK_PROVIDER_FALLBACK_IP, out_ip_len); ESP_LOGW(TAG, "Using fallback IP: %s", out_ip); return true; } ESP_LOGE(TAG, "No fallback IP configured. Cannot reach Provider."); return false; } // ── Provider Communication Test ───────────────────────────────────────────── void test_provider_communication(void) { // 1. Resolve Provider IP char provider_ip[16] = {}; if (!resolve_provider_ip(provider_ip, sizeof(provider_ip))) { return; } uint16_t provider_port = CONFIG_CALENDINK_PROVIDER_PORT; // 2. Get our own MAC address uint8_t mac_bytes[6] = {}; esp_err_t err = get_mac_address(mac_bytes); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to get WiFi MAC: %s", esp_err_to_name(err)); return; } char mac_str[18] = {}; snprintf(mac_str, sizeof(mac_str), "%02X:%02X:%02X:%02X:%02X:%02X", mac_bytes[0], mac_bytes[1], mac_bytes[2], mac_bytes[3], mac_bytes[4], mac_bytes[5]); ESP_LOGI(TAG, "Client MAC: %s", mac_str); // 3. Register with Provider: POST /api/devices/register { char *url = http_build_url(provider_ip, provider_port, "/api/devices/register"); if (url == nullptr) { return; } char json_body[64] = {}; snprintf(json_body, sizeof(json_body), "{\"mac\":\"%s\"}", mac_str); http_text_response_t resp = {}; err = http_post_json(url, json_body, &resp); if (err == ESP_OK) { ESP_LOGI(TAG, "Register response (%d): %s", resp.status_code, resp.body ? resp.body : "(empty)"); } else { ESP_LOGE(TAG, "Register request failed: %s", esp_err_to_name(err)); } free(resp.body); free(url); } // 4. Fetch screen image: GET /api/devices/screen.png?mac=XX:XX:XX:XX:XX:XX { char path[80] = {}; snprintf(path, sizeof(path), "/api/devices/screen.png?mac=%s", mac_str); char *url = http_build_url(provider_ip, provider_port, path); if (url == nullptr) { return; } http_binary_response_t resp = {}; err = http_get_binary(url, &resp); if (err == ESP_OK) { ESP_LOGI(TAG, "Screen image response (%d): %zu bytes", resp.status_code, resp.data_len); } else { ESP_LOGE(TAG, "Screen image request failed: %s", esp_err_to_name(err)); } free(resp.data); free(url); } }