HomeKit 如何找到附近的设备?

How does HomeKit find nearby devices?

首先,如果这不是 post 这个问题的最合适论坛,我深表歉意。我查看了 AskDifferent,这似乎不够技术,我查看了 Super User,它似乎太技术化了。所以我在这里问它,因为它也与编程有关。

描述

我正在使用 Arduino IDE 在 ESP8266 (-01) 上设置 HAP(HomeKit 附件协议)服务器。我已经成功地在其上设置了一个 mDNS 服务器,以便使用 ESP8266mDNS 库进行发现。但是,我遇到了一个小问题:

启动 mDNS 服务器并添加 _hap._tcp 服务后,设备最初不会显示在 Home 应用程序中。只有在我从终端使用 $ dns-sd -B _hap._tcp "probe" _hap._tcp 服务后,ESP8266 才会出现在 Home 应用程序中。

这 "probing" 似乎在网络上做了一些最初不是由 mDNS 服务器完成但 HomeKit 要求被发现的事情。

我已经用“_http._tcp”等其他服务测试过这个,并在我的 iPhone 上使用名为 Radar 的应用程序来搜索 Bonjour 服务。它找到任何其他服务但没有找到(直到我 "probe" 它)。

使用 WireShark 显示,在单击(已发现的)设备之前,Home 应用程序不会发送任何 mDNS 请求。这让我认为最初的发现(显示要点击的设备)不是由 mDNS 完成的,而是由其他一些方法完成的。也许是网络上的某种注册表,然后在我使用 dns-sd 进行探测后填写。

使用 Radar 应用程序,我可以在网络上看到我 select 除了 hap 之外的任何服务的 mDNS 数据包。这很奇怪,好像 iPhone 阻止了对 hap 服务的 mDNS 请求。

我已经花了 3 天时间试图让它工作,但我真的不知道从这里该去哪里。我想知道我缺少什么才能让 Home 应用程序立即发现 ESP8266,而无需使用 dsn-sd 来 "activate"。如果你想重现这个问题,我已经把我的代码的简化版本放在下面,它仍然有同样的问题。安装适当的板后,您可以使用 Arduino IDE 将其上传到 ESP8266。

安装后,尝试查看设备是否出现在 HomeKit 中。如果没有,请在同一网络上使用 Mac 并在终端中输入 $ dns-sd -B _hap._tcp。虽然这是 运行,但请返回“家庭”应用,您应该可以在那里看到该设备。

代码

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>


const char* ssid = "WiFi"; //Change to your SSID
const char* password = "xxxxx"; //Change to your password

ESP8266WebServer server(80);

void handleNotFound(){
  server.send(404, "text/plain", "Not Found!");
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.hostname("ESP8266");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  if (MDNS.begin("ESP8266")) {
    Serial.println("MDNS Started.");
  }
  server.onNotFound(handleNotFound);

  server.begin();

  MDNS.addService("hap", "tcp", 80);
  MDNS.addServiceTxt("hap", "tcp", "md", "ESP8266");
  MDNS.addServiceTxt("hap", "tcp", "pv", "1.0");
  MDNS.addServiceTxt("hap", "tcp", "id", "A0:20:A6:15:46:44");
  MDNS.addServiceTxt("hap", "tcp", "c#", "3");
  MDNS.addServiceTxt("hap", "tcp", "s#", "1");
  MDNS.addServiceTxt("hap", "tcp", "ff", "0");
  MDNS.addServiceTxt("hap", "tcp", "ci", "5");
  MDNS.addServiceTxt("hap", "tcp", "sf", "1");
}

void loop() {
  server.handleClient();
}

我做了更多测试并在 Mac 上安装了 Homebridge,并使用 WireShark 监控它的 mDNS 数据包。服务器启动时,它会发出几个“ANY”查询和几个响应。它在这里所做的正如 section 8 of RFC 6762 namely, "Probing and Announcing on Startup". It seems that the ESP8266mDNS library is currently not doing this so I have reopened my issue on GitHub 中描述的那样来实现它。 我会自己尝试,但我敦促任何有足够知识的人做出贡献! 该库目前正在根据通过 Apple 一致性测试的 idf 实现进行重写。完成后应该会解决此问题。

查看您的配置值,我发现 "ff" 设置为 0;这意味着您没有请求为此设备配对。配对请求会触发您的设备被发现。