#arduino #mdns
#arduino #mdns
Вопрос:
Я пытаюсь реализовать легкий диктор mDNS для arduino. Он должен объявить об услуге «apple midi rtp».
Теперь хорошая часть в том, что я могу пропинговать свое имя (mymdnstest.local) большую часть времени, и иногда оно появляется в выводе «avahi-browse-a».
Всегда демон avahi-демон отображается в журнале systemd:
Received conflicting record [_apple-midi._udp.local IN PTR mymdnstest._apple-midi._udp.local ; ttl=120]. Resetting our record.".
tcpdump показывает:
22:12:00.691720 wlo1 M IP (tos 0x0, ttl 2, id 969, offset 0, flags [none], proto UDP (17), length 199) 192.168.65.215.5353 gt; 224.0.0.251.5353: [udp sum ok] 0*- [0q] 3/0/0 _apple-midi._udp.local. (Cache flush) [2m] PTR mymdnstest._apple-midi._udp.local., _apple-midi._udp.local. (Cache flush) [2m] SRV mymdnstest.local.:5004 0 0, mymdnstest.local. (Cache flush) [2m] A 192.168.65.215 (171)
Что может быть такого, что эти ошибки видны и что он ведет себя так беспорядочно?
#include lt;ESP8266WiFi.hgt; #include lt;WiFiClient.hgt; #include lt;WiFiUdp.hgt; char ssid[] = " my ssid "; char pass[] = " password for my ssid "; WiFiUDP udp; const IPAddress tgt_ip { 224, 0, 0, 251 }; constexpr int tgt_port = 5353; constexpr char name[] = "mymdnstest"; constexpr uint16_t port = 5004; void update_mdns() { static uint32_t last_msg = 0; uint32_t now = millis(); if (last_msg == 0 || now - last_msg gt;= 750) { last_msg = now; static bool state = true; digitalWrite(D0, state); // blink led state = !state; uint8_t response[256]; uint16_t ro = 0; response[ro ] = 0x00; // transaction id response[ro ] = 0x00; response[ro ] = 0x84; // standard query response, no error response[ro ] = 0x00; response[ro ] = 0x00; // 0 questions response[ro ] = 0x00; response[ro ] = 0x00; // 3 answers response[ro ] = 0x03; response[ro ] = 0x00; // 0 authority rr response[ro ] = 0x00; response[ro ] = 0x00; // 0 additional rr response[ro ] = 0x00; // PTR record constexpr char applemidi[] = "_apple-midi"; constexpr char udp_[] = "_udp"; constexpr char local[] = "local"; response[ro ] = strlen(applemidi); ro = sprintf((char *)amp;response[ro], "%s", applemidi); // name itself response[ro ] = strlen(udp_); ro = sprintf((char *)amp;response[ro], "%s", udp_); // name itself response[ro ] = strlen(local); ro = sprintf((char *)amp;response[ro], "%s", local); // name itself response[ro ] = 0x00; response[ro ] = 0x00; // PTR (12) response[ro ] = 0x0c; response[ro ] = 0x80; // cache flush amp; class: in response[ro ] = 0x01; response[ro ] = 0x00; // ttl 2 minutes response[ro ] = 0x00; response[ro ] = 0x00; response[ro ] = 0x78; uint16_t ptr_data_len = 1 strlen(name) 1 strlen(applemidi) 1 strlen(udp_) 1 strlen(local) 1; response[ro ] = ptr_data_len gt;gt; 8; response[ro ] = ptr_data_len; response[ro ] = strlen(name); ro = sprintf((char *)amp;response[ro], "%s", name); // name itself response[ro ] = strlen(applemidi); ro = sprintf((char *)amp;response[ro], "%s", applemidi); // name itself response[ro ] = strlen(udp_); ro = sprintf((char *)amp;response[ro], "%s", udp_); // name itself response[ro ] = strlen(local); ro = sprintf((char *)amp;response[ro], "%s", local); // name itself response[ro ] = 0x00; // SRV apple midi record response[ro ] = strlen(applemidi); // length of name ro = sprintf((char *)amp;response[ro], "%s", applemidi); // name itself response[ro ] = strlen(udp_); ro = sprintf((char *)amp;response[ro], "%s", udp_); // name itself response[ro ] = strlen(local); ro = sprintf((char *)amp;response[ro], "%s", local); // name itself response[ro ] = 0; // string delimiter response[ro ] = 0x00; // type 33 SRV (server selection) response[ro ] = 0x21; response[ro ] = 0x80; // class (cache flush: True, class: in) response[ro ] = 0x01; response[ro ] = 0x00; // ttl 2 minutes response[ro ] = 0x00; response[ro ] = 0x00; response[ro ] = 0x78; uint16_t srv_data_len = 2 2 2 1 strlen(name) 1 strlen(local) 1; response[ro ] = srv_data_len gt;gt; 8; // data len response[ro ] = srv_data_len; response[ro ] = 0x00; // priority response[ro ] = 0x00; response[ro ] = 0x00; // weight response[ro ] = 0x00; response[ro ] = port gt;gt; 8; // port on which the apple thing listens response[ro ] = port; response[ro ] = strlen(name); // length of name ro = sprintf((char *)amp;response[ro], "%s", name); // name itself response[ro ] = strlen(local); ro = sprintf((char *)amp;response[ro], "%s", local); // name itself response[ro ] = 0x00; // A record for the hostname to the ip-address response[ro ] = strlen(name); // length of name ro = sprintf((char *)amp;response[ro], "%s", name); // name itself response[ro ] = strlen(local); // length of "local" ro = sprintf((char *)amp;response[ro], local); response[ro ] = 0; // string delimiter response[ro ] = 0x00; // type 0001 (A) response[ro ] = 0x01; response[ro ] = 0x80; // class (cache flush: True, class: in) response[ro ] = 0x01; response[ro ] = 0x00; // ttl 2 minutes response[ro ] = 0x00; response[ro ] = 0x00; response[ro ] = 0x78; response[ro ] = 0x00; // length of address response[ro ] = 0x04; response[ro ] = WiFi.localIP()[0]; response[ro ] = WiFi.localIP()[1]; response[ro ] = WiFi.localIP()[2]; response[ro ] = WiFi.localIP()[3]; udp.beginPacketMulticast(tgt_ip, tgt_port, WiFi.localIP(), 2); udp.write(response, ro); udp.endPacket(); } } void setup() { Serial.begin(115200); Serial.println(F("Go!")); pinMode(D0, OUTPUT); WiFi.hostname(name); WiFi.begin(ssid, pass); static bool state = true; while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print(F(".")); digitalWrite(D0, state); state = !state; } digitalWrite(D0, false); Serial.println(F("")); Serial.print("IP address:t"); IPAddress myIP = WiFi.localIP(); Serial.println(myIP); udp.beginMulticast(WiFi.localIP(), tgt_ip, 5353); } void loop() { update_mdns(); }
Ответ №1:
- флаги каждого RR были неверными. только A и SRV должны иметь чистый кэш
- имя хоста отсутствовало в записи SRV
С этим все еще есть проблема: rtpmidid сигнализирует о тайм-ау при разрешении имени хоста, но это не соответствует этому вопросу.