mirror of
https://github.com/dwhinham/mt32-pi.git
synced 2026-07-08 17:56:50 +00:00
WIP
This commit is contained in:
@@ -86,4 +86,6 @@ FLUIDSYNTHLIB=$(FLUIDSYNTHBUILDDIR)/src/libfluidsynth.a
|
||||
|
||||
INIHHOME=$(realpath external/inih)
|
||||
|
||||
MDNSHOME=$(realpath external/mdns)
|
||||
|
||||
-include $(CIRCLE_STDLIB_CONFIG)
|
||||
|
||||
@@ -24,6 +24,7 @@ OBJS := src/config.o \
|
||||
src/net/applemidi.o \
|
||||
src/net/ftpdaemon.o \
|
||||
src/net/ftpworker.o \
|
||||
src/net/mdnsresponder.o \
|
||||
src/net/udpmidi.o \
|
||||
src/pisound.o \
|
||||
src/power.o \
|
||||
@@ -48,6 +49,11 @@ INCLUDE += -I $(INIHHOME)
|
||||
EXTRACLEAN += $(INIHHOME)/ini.d \
|
||||
$(INIHHOME)/ini.o
|
||||
|
||||
#
|
||||
# mdns
|
||||
#
|
||||
INCLUDE += -I $(MDNSHOME)
|
||||
|
||||
include $(CIRCLEHOME)/Rules.mk
|
||||
|
||||
CFLAGS += -Werror -Wextra -Wno-unused-parameter
|
||||
|
||||
19
Makefile
19
Makefile
@@ -5,7 +5,7 @@
|
||||
include Config.mk
|
||||
|
||||
.DEFAULT_GOAL=all
|
||||
.PHONY: circle-stdlib mt32emu fluidsynth all clean veryclean
|
||||
.PHONY: circle-stdlib mdns mt32emu fluidsynth all clean veryclean
|
||||
|
||||
#
|
||||
# Functions to apply/reverse patches only if not completely applied/reversed already
|
||||
@@ -36,7 +36,7 @@ $(CIRCLE_STDLIB_CONFIG) $(CIRCLE_CONFIG)&:
|
||||
# Apply patches
|
||||
@${APPLY_PATCH} $(CIRCLEHOME) patches/circle-45-minimal-usb-drivers.patch
|
||||
@${APPLY_PATCH} $(CIRCLEHOME) patches/circle-45-cp210x-remove-partnum-check.patch
|
||||
@${APPLY_PATCH} $(CIRCLEHOME) patches/circle-44-multicast.patch
|
||||
@${APPLY_PATCH} $(CIRCLEHOME) patches/circle-45-multicast.patch
|
||||
|
||||
ifeq ($(strip $(GC_SECTIONS)),1)
|
||||
# Enable function/data sections for circle-stdlib
|
||||
@@ -64,6 +64,15 @@ $(CIRCLESTDLIBHOME)/.done: $(CIRCLE_STDLIB_CONFIG)
|
||||
@$(MAKE) -C $(CIRCLESTDLIBHOME)
|
||||
touch $@
|
||||
|
||||
#
|
||||
# Patch mdns
|
||||
#
|
||||
mdns: $(MDNSHOME)/.done
|
||||
|
||||
$(MDNSHOME)/.done:
|
||||
@${APPLY_PATCH} $(MDNSHOME) patches/mdns-1.4.2-circle.patch
|
||||
touch $@
|
||||
|
||||
#
|
||||
# Build mt32emu
|
||||
#
|
||||
@@ -127,7 +136,7 @@ $(FLUIDSYNTHBUILDDIR)/.done: $(CIRCLESTDLIBHOME)/.done
|
||||
#
|
||||
# Build kernel itself
|
||||
#
|
||||
all: circle-stdlib mt32emu fluidsynth
|
||||
all: circle-stdlib mdns mt32emu fluidsynth
|
||||
@$(MAKE) -f Kernel.mk $(KERNEL).img $(KERNEL).hex
|
||||
|
||||
#
|
||||
@@ -145,11 +154,15 @@ veryclean: clean
|
||||
@${REVERSE_PATCH} $(CIRCLEHOME) patches/circle-45-cp210x-remove-partnum-check.patch
|
||||
@${REVERSE_PATCH} $(CIRCLEHOME) patches/circle-45-minimal-usb-drivers.patch
|
||||
@${REVERSE_PATCH} $(FLUIDSYNTHHOME) patches/fluidsynth-2.3.1-circle.patch
|
||||
@${REVERSE_PATCH} $(MDNSHOME) patches/mdns-1.4.2-circle.patch
|
||||
|
||||
# Clean circle-stdlib
|
||||
@$(MAKE) -C $(CIRCLESTDLIBHOME) mrproper
|
||||
@$(RM) $(CIRCLESTDLIBHOME)/.done
|
||||
|
||||
# Clean mdns
|
||||
@$(RM) $(MDNSHOME)/.done
|
||||
|
||||
# Clean mt32emu
|
||||
@$(RM) -r $(MT32EMUBUILDDIR)
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "midiparser.h"
|
||||
#include "net/applemidi.h"
|
||||
#include "net/ftpdaemon.h"
|
||||
#include "net/mdnsresponder.h"
|
||||
#include "net/udpmidi.h"
|
||||
#include "pisound.h"
|
||||
#include "power.h"
|
||||
@@ -161,6 +162,7 @@ private:
|
||||
CBcm4343Device m_WLAN;
|
||||
CWPASupplicant m_WPASupplicant;
|
||||
bool m_bNetworkReady;
|
||||
CMDNSResponder* m_pMDNSResponder;
|
||||
CAppleMIDIParticipant* m_pAppleMIDIParticipant;
|
||||
CUDPMIDIReceiver* m_pUDPMIDIReceiver;
|
||||
CFTPDaemon* m_pFTPDaemon;
|
||||
|
||||
59
include/net/mdnsresponder.h
Normal file
59
include/net/mdnsresponder.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// mdnsresponder.h
|
||||
//
|
||||
// mt32-pi - A baremetal MIDI synthesizer for Raspberry Pi
|
||||
// Copyright (C) 2020-2022 Dale Whinham <daleyo@gmail.com>
|
||||
//
|
||||
// This file is part of mt32-pi.
|
||||
//
|
||||
// mt32-pi is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// mt32-pi is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// mt32-pi. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#ifndef _mdnsresponder_h
|
||||
#define _mdnsresponder_h
|
||||
|
||||
#include <circle/net/socket.h>
|
||||
#include <circle/sched/task.h>
|
||||
|
||||
class CMDNSResponder : protected CTask
|
||||
{
|
||||
public:
|
||||
CMDNSResponder();
|
||||
virtual ~CMDNSResponder() override;
|
||||
|
||||
bool Initialize();
|
||||
|
||||
virtual void Run() override;
|
||||
|
||||
private:
|
||||
void Probe();
|
||||
void Announce();
|
||||
void Goodbye();
|
||||
|
||||
static constexpr size_t MaxMDNSNameLength = 256;
|
||||
|
||||
// UDP socket
|
||||
CSocket* m_pSocket;
|
||||
|
||||
// Socket receive buffer
|
||||
u8 m_Buffer[FRAME_BUFFER_SIZE];
|
||||
char m_DNSName[MaxMDNSNameLength];
|
||||
|
||||
// static int MDNSServiceCallback(mdns_socket_t sock, const struct sockaddr* from, size_t addrlen, mdns_entry_type_t entry,
|
||||
// uint16_t query_id, uint16_t rtype, uint16_t rclass, uint32_t ttl, const void* data,
|
||||
// size_t size, size_t name_offset, size_t name_length, size_t record_offset,
|
||||
// size_t record_length, void* user_data);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -23,7 +23,6 @@
|
||||
#ifndef _udpmidi_h
|
||||
#define _udpmidi_h
|
||||
|
||||
#include <circle/net/ipaddress.h>
|
||||
#include <circle/net/socket.h>
|
||||
#include <circle/sched/task.h>
|
||||
|
||||
@@ -44,11 +43,11 @@ public:
|
||||
virtual void Run() override;
|
||||
|
||||
private:
|
||||
// UDP sockets
|
||||
CSocket* m_pMIDISocket;
|
||||
// UDP socket
|
||||
CSocket* m_pSocket;
|
||||
|
||||
// Socket receive buffer
|
||||
u8 m_MIDIBuffer[FRAME_BUFFER_SIZE];
|
||||
u8 m_ReceiveBuffer[FRAME_BUFFER_SIZE];
|
||||
|
||||
// Callback handler
|
||||
CUDPMIDIHandler* m_pHandler;
|
||||
|
||||
@@ -98,6 +98,11 @@ namespace Utility
|
||||
return nTicks / 1000;
|
||||
}
|
||||
|
||||
constexpr u32 IPAddressToInteger(u8 nA, u8 nB, u8 nC, u8 nD)
|
||||
{
|
||||
return nA | (nB << 8) | (nC << 16) | (nD << 24);
|
||||
}
|
||||
|
||||
// Computes the Roland checksum
|
||||
constexpr u8 RolandChecksum(const u8* pData, size_t nSize)
|
||||
{
|
||||
|
||||
553
patches/mdns-1.4.2-circle.patch
Normal file
553
patches/mdns-1.4.2-circle.patch
Normal file
@@ -0,0 +1,553 @@
|
||||
diff --git a/mdns.h b/mdns.h
|
||||
index 4b3b03d..96c76ec 100644
|
||||
--- a/mdns.h
|
||||
+++ b/mdns.h
|
||||
@@ -24,6 +24,10 @@
|
||||
#include <Winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
#define strncasecmp _strnicmp
|
||||
+#elif defined(__circle__)
|
||||
+#include <circle/net/ipaddress.h>
|
||||
+#include <circle/net/socket.h>
|
||||
+#include <circle/util.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -74,11 +78,46 @@ enum mdns_entry_type {
|
||||
|
||||
enum mdns_class { MDNS_CLASS_IN = 1, MDNS_CLASS_ANY = 255 };
|
||||
|
||||
+#ifdef __circle__
|
||||
+#define htons(VALUE) __builtin_bswap16(VALUE)
|
||||
+#define htonl(VALUE) __builtin_bswap32(VALUE)
|
||||
+#define ntohs(VALUE) __builtin_bswap16(VALUE)
|
||||
+#define ntohl(VALUE) __builtin_bswap32(VALUE)
|
||||
+
|
||||
+#define AF_INET 2
|
||||
+typedef CSocket* mdns_socket_t;
|
||||
+
|
||||
+typedef u32 in_addr_t;
|
||||
+typedef u8 sa_family_t;
|
||||
+typedef u16 in_port_t;
|
||||
+
|
||||
+struct in_addr
|
||||
+{
|
||||
+ in_addr_t s_addr;
|
||||
+};
|
||||
+
|
||||
+struct sockaddr_in
|
||||
+{
|
||||
+ sa_family_t sin_family;
|
||||
+ in_port_t sin_port;
|
||||
+ struct in_addr sin_addr;
|
||||
+};
|
||||
+
|
||||
+struct sockaddr {
|
||||
+ sa_family_t sa_family;
|
||||
+ char sa_data[14];
|
||||
+};
|
||||
+
|
||||
+typedef size_t socklen_t;
|
||||
+#else
|
||||
+typedef int mdns_socket_t;
|
||||
+#endif
|
||||
+
|
||||
typedef enum mdns_record_type mdns_record_type_t;
|
||||
typedef enum mdns_entry_type mdns_entry_type_t;
|
||||
typedef enum mdns_class mdns_class_t;
|
||||
|
||||
-typedef int (*mdns_record_callback_fn)(int sock, const struct sockaddr* from, size_t addrlen,
|
||||
+typedef int (*mdns_record_callback_fn)(mdns_socket_t sock, const struct sockaddr* from, size_t addrlen,
|
||||
mdns_entry_type_t entry, uint16_t query_id, uint16_t rtype,
|
||||
uint16_t rclass, uint32_t ttl, const void* data, size_t size,
|
||||
size_t name_offset, size_t name_length, size_t record_offset,
|
||||
@@ -136,9 +175,11 @@ struct mdns_record_a_t {
|
||||
struct sockaddr_in addr;
|
||||
};
|
||||
|
||||
+#ifndef __circle__
|
||||
struct mdns_record_aaaa_t {
|
||||
struct sockaddr_in6 addr;
|
||||
};
|
||||
+#endif
|
||||
|
||||
struct mdns_record_txt_t {
|
||||
mdns_string_t key;
|
||||
@@ -152,7 +193,9 @@ struct mdns_record_t {
|
||||
mdns_record_ptr_t ptr;
|
||||
mdns_record_srv_t srv;
|
||||
mdns_record_a_t a;
|
||||
+#ifndef __circle__
|
||||
mdns_record_aaaa_t aaaa;
|
||||
+#endif
|
||||
mdns_record_txt_t txt;
|
||||
} data;
|
||||
uint16_t rclass;
|
||||
@@ -176,12 +219,13 @@ struct mdns_query_t {
|
||||
|
||||
// mDNS/DNS-SD public API
|
||||
|
||||
+#ifndef __circle__
|
||||
//! Open and setup a IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
|
||||
//! in the appropriate socket address in saddr, otherwise pass a null pointer for INADDR_ANY. To
|
||||
//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
|
||||
//! random user level ephemeral port. To run discovery service listening for incoming discoveries
|
||||
//! and queries, you must set MDNS_PORT as port.
|
||||
-static inline int
|
||||
+static inline mdns_socket_t
|
||||
mdns_socket_open_ipv4(const struct sockaddr_in* saddr);
|
||||
|
||||
//! Setup an already opened IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
|
||||
@@ -190,14 +234,14 @@ mdns_socket_open_ipv4(const struct sockaddr_in* saddr);
|
||||
//! random user level ephemeral port. To run discovery service listening for incoming discoveries
|
||||
//! and queries, you must set MDNS_PORT as port.
|
||||
static inline int
|
||||
-mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr);
|
||||
+mdns_socket_setup_ipv4(mdns_socket_t sock, const struct sockaddr_in* saddr);
|
||||
|
||||
//! Open and setup a IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
|
||||
//! in the appropriate socket address in saddr, otherwise pass a null pointer for in6addr_any. To
|
||||
//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
|
||||
//! random user level ephemeral port. To run discovery service listening for incoming discoveries
|
||||
//! and queries, you must set MDNS_PORT as port.
|
||||
-static inline int
|
||||
+static inline mdns_socket_t
|
||||
mdns_socket_open_ipv6(const struct sockaddr_in6* saddr);
|
||||
|
||||
//! Setup an already opened IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
|
||||
@@ -206,30 +250,31 @@ mdns_socket_open_ipv6(const struct sockaddr_in6* saddr);
|
||||
//! random user level ephemeral port. To run discovery service listening for incoming discoveries
|
||||
//! and queries, you must set MDNS_PORT as port.
|
||||
static inline int
|
||||
-mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr);
|
||||
+mdns_socket_setup_ipv6(mdns_socket_t sock, const struct sockaddr_in6* saddr);
|
||||
|
||||
//! Close a socket opened with mdns_socket_open_ipv4 and mdns_socket_open_ipv6.
|
||||
static inline void
|
||||
-mdns_socket_close(int sock);
|
||||
+mdns_socket_close(mdns_socket_t sock);
|
||||
+#endif
|
||||
|
||||
//! Listen for incoming multicast DNS-SD and mDNS query requests. The socket should have been opened
|
||||
//! on port MDNS_PORT using one of the mdns open or setup socket functions. Buffer must be 32 bit
|
||||
//! aligned. Parsing is stopped when callback function returns non-zero. Returns the number of
|
||||
//! queries parsed.
|
||||
static inline size_t
|
||||
-mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_socket_listen(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data);
|
||||
|
||||
//! Send a multicast DNS-SD reqeuest on the given socket to discover available services. Returns 0
|
||||
//! on success, or <0 if error.
|
||||
static inline int
|
||||
-mdns_discovery_send(int sock);
|
||||
+mdns_discovery_send(mdns_socket_t sock);
|
||||
|
||||
//! Recieve unicast responses to a DNS-SD sent with mdns_discovery_send. Any data will be piped to
|
||||
//! the given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
|
||||
//! function returns non-zero. Returns the number of responses parsed.
|
||||
static inline size_t
|
||||
-mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_discovery_recv(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data);
|
||||
|
||||
//! Send a multicast mDNS query on the given socket for the given service name. The supplied buffer
|
||||
@@ -239,7 +284,7 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callbac
|
||||
//! ephemeral port, or a multicast response if the socket is bound to mDNS port 5353. Returns the
|
||||
//! used query ID, or <0 if error.
|
||||
static inline int
|
||||
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
|
||||
+mdns_query_send(mdns_socket_t sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
|
||||
size_t capacity, uint16_t query_id);
|
||||
|
||||
//! Send a multicast mDNS query on the given socket for the given service names. The supplied buffer
|
||||
@@ -251,7 +296,7 @@ mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t leng
|
||||
//! unicast response if the socket is bound to an ephemeral port, or a multicast response if the
|
||||
//! socket is bound to mDNS port 5353. Returns the used query ID, or <0 if error.
|
||||
static inline int
|
||||
-mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer,
|
||||
+mdns_multiquery_send(mdns_socket_t sock, const mdns_query_t* query, size_t count, void* buffer,
|
||||
size_t capacity, uint16_t query_id);
|
||||
|
||||
//! Receive unicast responses to a mDNS query sent with mdns_discovery_recv, optionally filtering
|
||||
@@ -260,7 +305,7 @@ mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* bu
|
||||
//! given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
|
||||
//! function returns non-zero. Returns the number of responses parsed.
|
||||
static inline size_t
|
||||
-mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_query_recv(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data, int query_id);
|
||||
|
||||
//! Send a variable unicast mDNS query answer to any question with variable number of records to the
|
||||
@@ -269,7 +314,7 @@ mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn
|
||||
//! Buffer must be 32 bit aligned. The record type and name should match the data from the query
|
||||
//! recieved. Returns 0 if success, or <0 if error.
|
||||
static inline int
|
||||
-mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
|
||||
+mdns_query_answer_unicast(mdns_socket_t sock, const void* address, size_t address_size, void* buffer,
|
||||
size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
|
||||
const char* name, size_t name_length, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
@@ -280,7 +325,7 @@ mdns_query_answer_unicast(int sock, const void* address, size_t address_size, vo
|
||||
//! if the answer should be sent unicast (bit set) or multicast (bit not set). Buffer must be 32 bit
|
||||
//! aligned. Returns 0 if success, or <0 if error.
|
||||
static inline int
|
||||
-mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_query_answer_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count);
|
||||
|
||||
@@ -288,14 +333,14 @@ mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record
|
||||
//! records.Buffer must be 32 bit aligned. Returns 0 if success, or <0 if error. Use this on service
|
||||
//! startup to announce your instance to the local network.
|
||||
static inline int
|
||||
-mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_announce_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count);
|
||||
|
||||
//! Send a variable multicast mDNS announcement. Use this on service end for removing the resource
|
||||
//! from the local network. The records must be identical to the according announcement.
|
||||
static inline int
|
||||
-mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_goodbye_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count);
|
||||
|
||||
@@ -316,10 +361,12 @@ static inline struct sockaddr_in*
|
||||
mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
|
||||
struct sockaddr_in* addr);
|
||||
|
||||
+#ifndef __circle__
|
||||
//! Parse an AAAA record, returns the IPv6 address in the record
|
||||
static inline struct sockaddr_in6*
|
||||
mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
|
||||
struct sockaddr_in6* addr);
|
||||
+#endif
|
||||
|
||||
//! Parse a TXT record, returns the number of key=value records parsed and stores the key-value
|
||||
//! pairs in the supplied buffer
|
||||
@@ -383,9 +430,10 @@ mdns_htonl(void* data, uint32_t val) {
|
||||
return MDNS_POINTER_OFFSET(data, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
-static inline int
|
||||
+#ifndef __circle__
|
||||
+static inline mdns_socket_t
|
||||
mdns_socket_open_ipv4(const struct sockaddr_in* saddr) {
|
||||
- int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
+ mdns_socket_t sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
if (mdns_socket_setup_ipv4(sock, saddr)) {
|
||||
@@ -396,7 +444,7 @@ mdns_socket_open_ipv4(const struct sockaddr_in* saddr) {
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr) {
|
||||
+mdns_socket_setup_ipv4(mdns_socket_t sock, const struct sockaddr_in* saddr) {
|
||||
unsigned char ttl = 1;
|
||||
unsigned char loopback = 1;
|
||||
unsigned int reuseaddr = 1;
|
||||
@@ -447,9 +495,9 @@ mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int
|
||||
+static inline mdns_socket_t
|
||||
mdns_socket_open_ipv6(const struct sockaddr_in6* saddr) {
|
||||
- int sock = (int)socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
+ mdns_socket_t sock = (int)socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
if (mdns_socket_setup_ipv6(sock, saddr)) {
|
||||
@@ -460,7 +508,7 @@ mdns_socket_open_ipv6(const struct sockaddr_in6* saddr) {
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr) {
|
||||
+mdns_socket_setup_ipv6(mdns_socket_t sock, const struct sockaddr_in6* saddr) {
|
||||
int hops = 1;
|
||||
unsigned int loopback = 1;
|
||||
unsigned int reuseaddr = 1;
|
||||
@@ -512,13 +560,14 @@ mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr) {
|
||||
}
|
||||
|
||||
static inline void
|
||||
-mdns_socket_close(int sock) {
|
||||
+mdns_socket_close(mdns_socket_t sock) {
|
||||
#ifdef _WIN32
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
}
|
||||
+#endif
|
||||
|
||||
static inline int
|
||||
mdns_is_string_ref(uint8_t val) {
|
||||
@@ -773,7 +822,7 @@ mdns_string_make(void* buffer, size_t capacity, void* data, const char* name, si
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
-mdns_records_parse(int sock, const struct sockaddr* from, size_t addrlen, const void* buffer,
|
||||
+mdns_records_parse(mdns_socket_t sock, const struct sockaddr* from, size_t addrlen, const void* buffer,
|
||||
size_t size, size_t* offset, mdns_entry_type_t type, uint16_t query_id,
|
||||
size_t records, mdns_record_callback_fn callback, void* user_data) {
|
||||
size_t parsed = 0;
|
||||
@@ -807,16 +856,30 @@ mdns_records_parse(int sock, const struct sockaddr* from, size_t addrlen, const
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_unicast_send(int sock, const void* address, size_t address_size, const void* buffer,
|
||||
+mdns_unicast_send(mdns_socket_t sock, const void* address, size_t address_size, const void* buffer,
|
||||
size_t size) {
|
||||
+#ifdef __circle__
|
||||
+ const sockaddr_in* addr = (const struct sockaddr_in*)address;
|
||||
+ CIPAddress ipaddr(addr->sin_addr.s_addr);
|
||||
+ u16 port = addr->sin_port;
|
||||
+
|
||||
+ if (sock->SendTo(buffer, size, 0, ipaddr, port) < 0)
|
||||
+ return -1;
|
||||
+#else
|
||||
if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, (const struct sockaddr*)address,
|
||||
(socklen_t)address_size) < 0)
|
||||
return -1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_multicast_send(int sock, const void* buffer, size_t size) {
|
||||
+mdns_multicast_send(mdns_socket_t sock, const void* buffer, size_t size) {
|
||||
+#ifdef __circle__
|
||||
+ CIPAddress ipaddr(htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U)));
|
||||
+ if (sock->SendTo(buffer, size, 0, ipaddr, MDNS_PORT) < 0)
|
||||
+ return -1;
|
||||
+#else
|
||||
struct sockaddr_storage addr_storage;
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in6 addr6;
|
||||
@@ -850,6 +913,7 @@ mdns_multicast_send(int sock, const void* buffer, size_t size) {
|
||||
|
||||
if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, saddr, saddrlen) < 0)
|
||||
return -1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -871,13 +935,28 @@ static const uint8_t mdns_services_query[] = {
|
||||
0x80, MDNS_CLASS_IN};
|
||||
|
||||
static inline int
|
||||
-mdns_discovery_send(int sock) {
|
||||
+mdns_discovery_send(mdns_socket_t sock) {
|
||||
return mdns_multicast_send(sock, mdns_services_query, sizeof(mdns_services_query));
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
-mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_discovery_recv(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data) {
|
||||
+#ifdef __circle__
|
||||
+ struct sockaddr_in addr;
|
||||
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
+ socklen_t addrlen = sizeof(addr);
|
||||
+
|
||||
+ CIPAddress ipaddr;
|
||||
+ u16 port;
|
||||
+ mdns_ssize_t ret = sock->ReceiveFrom(buffer, capacity, 0, &ipaddr, &port);
|
||||
+ if (ret <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ addr.sin_family = AF_INET;
|
||||
+ addr.sin_port = port;
|
||||
+ addr.sin_addr.s_addr = (u32)ipaddr;
|
||||
+#else
|
||||
struct sockaddr_in6 addr;
|
||||
struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
@@ -888,6 +967,7 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callbac
|
||||
mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
+#endif
|
||||
|
||||
size_t data_size = (size_t)ret;
|
||||
size_t records = 0;
|
||||
@@ -980,8 +1060,23 @@ mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callbac
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
-mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_socket_listen(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data) {
|
||||
+#ifdef __circle__
|
||||
+ struct sockaddr_in addr;
|
||||
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
+ socklen_t addrlen = sizeof(addr);
|
||||
+
|
||||
+ CIPAddress ipaddr;
|
||||
+ u16 port;
|
||||
+ mdns_ssize_t ret = sock->ReceiveFrom(buffer, capacity, 0, &ipaddr, &port);
|
||||
+ if (ret <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ addr.sin_family = AF_INET;
|
||||
+ addr.sin_port = port;
|
||||
+ addr.sin_addr.s_addr = (u32)ipaddr;
|
||||
+#else
|
||||
struct sockaddr_in6 addr;
|
||||
struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
@@ -992,6 +1087,7 @@ mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback
|
||||
mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
+#endif
|
||||
|
||||
size_t data_size = (size_t)ret;
|
||||
const uint16_t* data = (const uint16_t*)buffer;
|
||||
@@ -1061,7 +1157,7 @@ mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
|
||||
+mdns_query_send(mdns_socket_t sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
|
||||
size_t capacity, uint16_t query_id) {
|
||||
mdns_query_t query;
|
||||
query.type = type;
|
||||
@@ -1071,11 +1167,15 @@ mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t leng
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer, size_t capacity,
|
||||
+mdns_multiquery_send(mdns_socket_t sock, const mdns_query_t* query, size_t count, void* buffer, size_t capacity,
|
||||
uint16_t query_id) {
|
||||
if (!count || (capacity < (sizeof(struct mdns_header_t) + (6 * count))))
|
||||
return -1;
|
||||
|
||||
+#ifdef __circle__
|
||||
+ // Only multicast response supported
|
||||
+ uint16_t rclass = MDNS_CLASS_IN;
|
||||
+#else
|
||||
// Ask for a unicast response since it's a one-shot query
|
||||
uint16_t rclass = MDNS_CLASS_IN | MDNS_UNICAST_RESPONSE;
|
||||
|
||||
@@ -1090,6 +1190,7 @@ mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* bu
|
||||
(ntohs(((struct sockaddr_in6*)saddr)->sin6_port) == MDNS_PORT))
|
||||
rclass &= ~MDNS_UNICAST_RESPONSE;
|
||||
}
|
||||
+#endif
|
||||
|
||||
struct mdns_header_t* header = (struct mdns_header_t*)buffer;
|
||||
// Query ID
|
||||
@@ -1122,8 +1223,23 @@ mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* bu
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
-mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
+mdns_query_recv(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
|
||||
void* user_data, int only_query_id) {
|
||||
+#ifdef __circle__
|
||||
+ struct sockaddr_in addr;
|
||||
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
+ socklen_t addrlen = sizeof(addr);
|
||||
+
|
||||
+ CIPAddress ipaddr;
|
||||
+ u16 port;
|
||||
+ mdns_ssize_t ret = sock->ReceiveFrom(buffer, capacity, 0, &ipaddr, &port);
|
||||
+ if (ret <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ addr.sin_family = AF_INET;
|
||||
+ addr.sin_port = port;
|
||||
+ addr.sin_addr.s_addr = (u32)ipaddr;
|
||||
+#else
|
||||
struct sockaddr_in6 addr;
|
||||
struct sockaddr* saddr = (struct sockaddr*)&addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
@@ -1134,6 +1250,7 @@ mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn
|
||||
mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
+#endif
|
||||
|
||||
size_t data_size = (size_t)ret;
|
||||
const uint16_t* data = (const uint16_t*)buffer;
|
||||
@@ -1264,12 +1381,14 @@ mdns_answer_add_record(void* buffer, size_t capacity, void* data, mdns_record_t
|
||||
data = MDNS_POINTER_OFFSET(data, 4);
|
||||
break;
|
||||
|
||||
+#ifndef __circle__
|
||||
case MDNS_RECORDTYPE_AAAA:
|
||||
if (remain < 16)
|
||||
return 0;
|
||||
memcpy(data, &record.data.aaaa.addr.sin6_addr, 16); // ipv6 address
|
||||
data = MDNS_POINTER_OFFSET(data, 16);
|
||||
break;
|
||||
+#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -1360,7 +1479,7 @@ mdns_answer_get_record_count(const mdns_record_t* records, size_t record_count)
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
|
||||
+mdns_query_answer_unicast(mdns_socket_t sock, const void* address, size_t address_size, void* buffer,
|
||||
size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
|
||||
const char* name, size_t name_length, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
@@ -1424,7 +1543,7 @@ mdns_query_answer_unicast(int sock, const void* address, size_t address_size, vo
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_answer_multicast_rclass_ttl(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_answer_multicast_rclass_ttl(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count,
|
||||
uint16_t rclass, uint32_t ttl) {
|
||||
@@ -1473,7 +1592,7 @@ mdns_answer_multicast_rclass_ttl(int sock, void* buffer, size_t capacity, mdns_r
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_query_answer_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count) {
|
||||
return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
|
||||
@@ -1482,7 +1601,7 @@ mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_announce_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count) {
|
||||
return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
|
||||
@@ -1491,7 +1610,7 @@ mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t a
|
||||
}
|
||||
|
||||
static inline int
|
||||
-mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
+mdns_goodbye_multicast(mdns_socket_t sock, void* buffer, size_t capacity, mdns_record_t answer,
|
||||
const mdns_record_t* authority, size_t authority_count,
|
||||
const mdns_record_t* additional, size_t additional_count) {
|
||||
// Goodbye should have ttl of 0
|
||||
@@ -1545,6 +1664,7 @@ mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t lengt
|
||||
return addr;
|
||||
}
|
||||
|
||||
+#ifndef __circle__
|
||||
static inline struct sockaddr_in6*
|
||||
mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
|
||||
struct sockaddr_in6* addr) {
|
||||
@@ -1557,6 +1677,7 @@ mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t le
|
||||
memcpy(&addr->sin6_addr, MDNS_POINTER_OFFSET(buffer, offset), 16);
|
||||
return addr;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static inline size_t
|
||||
mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
|
||||
@@ -82,6 +82,7 @@ CMT32Pi::CMT32Pi(CI2CMaster* pI2CMaster, CSPIMaster* pSPIMaster, CInterruptSyste
|
||||
m_WLAN(WLANFirmwarePath),
|
||||
m_WPASupplicant(WLANConfigFile),
|
||||
m_bNetworkReady(false),
|
||||
m_pMDNSResponder(nullptr),
|
||||
m_pAppleMIDIParticipant(nullptr),
|
||||
m_pUDPMIDIReceiver(nullptr),
|
||||
m_pFTPDaemon(nullptr),
|
||||
@@ -901,6 +902,14 @@ void CMT32Pi::UpdateNetwork()
|
||||
else
|
||||
m_pLogger->Write(MT32PiName, LogNotice, "FTP daemon initialized");
|
||||
}
|
||||
|
||||
m_pMDNSResponder = new CMDNSResponder();
|
||||
if (!m_pMDNSResponder->Initialize())
|
||||
{
|
||||
m_pLogger->Write(MT32PiName, LogError, "Failed to init mDNS responder");
|
||||
delete m_pMDNSResponder;
|
||||
m_pMDNSResponder = nullptr;
|
||||
}
|
||||
}
|
||||
else if (m_bNetworkReady && !bNetIsRunning)
|
||||
{
|
||||
|
||||
246
src/net/mdnsresponder.cpp
Normal file
246
src/net/mdnsresponder.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// mdsnresponder.cpp
|
||||
//
|
||||
// mt32-pi - A baremetal MIDI synthesizer for Raspberry Pi
|
||||
// Copyright (C) 2020-2022 Dale Whinham <daleyo@gmail.com>
|
||||
//
|
||||
// This file is part of mt32-pi.
|
||||
//
|
||||
// mt32-pi is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later
|
||||
// version.
|
||||
//
|
||||
// mt32-pi is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
// details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// mt32-pi. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <circle/logger.h>
|
||||
#include <circle/net/in.h>
|
||||
#include <circle/net/netsubsystem.h>
|
||||
#include <circle/sched/scheduler.h>
|
||||
|
||||
#include <mdns.h>
|
||||
|
||||
#include "net/mdnsresponder.h"
|
||||
#include "utility.h"
|
||||
|
||||
constexpr u32 MDNSAddress = Utility::IPAddressToInteger(224, 0, 0, 251);
|
||||
constexpr u16 MDNSPort = 5353;
|
||||
|
||||
const char MDNSResponderName[] = "mdns";
|
||||
|
||||
struct TDNSHeader
|
||||
{
|
||||
u16 nID;
|
||||
u16 nFlags;
|
||||
#define DNS_FLAGS_QR 0x8000
|
||||
#define DNS_FLAGS_OPCODE 0x7800
|
||||
#define DNS_FLAGS_OPCODE_QUERY 0x0000
|
||||
#define DNS_FLAGS_OPCODE_IQUERY 0x0800
|
||||
#define DNS_FLAGS_OPCODE_STATUS 0x1000
|
||||
#define DNS_FLAGS_AA 0x0400
|
||||
#define DNS_FLAGS_TC 0x0200
|
||||
#define DNS_FLAGS_RD 0x0100
|
||||
#define DNS_FLAGS_RA 0x0080
|
||||
#define DNS_FLAGS_RCODE 0x000F
|
||||
#define DNS_RCODE_SUCCESS 0x0000
|
||||
#define DNS_RCODE_FORMAT_ERROR 0x0001
|
||||
#define DNS_RCODE_SERVER_FAILURE 0x0002
|
||||
#define DNS_RCODE_NAME_ERROR 0x0003
|
||||
#define DNS_RCODE_NOT_IMPLEMENTED 0x0004
|
||||
#define DNS_RCODE_REFUSED 0x0005
|
||||
u16 nQDCount;
|
||||
u16 nANCount;
|
||||
u16 nNSCount;
|
||||
u16 nARCount;
|
||||
}
|
||||
PACKED;
|
||||
|
||||
struct TDNSResourceRecordTrailerAIN
|
||||
{
|
||||
u16 nType;
|
||||
u16 nClass;
|
||||
u32 nTTL;
|
||||
u16 nRDLength;
|
||||
#define DNS_RDLENGTH_AIN 4
|
||||
unsigned char RData[DNS_RDLENGTH_AIN];
|
||||
}
|
||||
PACKED;
|
||||
|
||||
CMDNSResponder::CMDNSResponder()
|
||||
: CTask(TASK_STACK_SIZE, true),
|
||||
m_pSocket(nullptr),
|
||||
m_Buffer{0}
|
||||
{
|
||||
snprintf(m_DNSName, sizeof(m_DNSName), "_%s", "mt32-pi");
|
||||
}
|
||||
|
||||
CMDNSResponder::~CMDNSResponder()
|
||||
{
|
||||
if (m_pSocket)
|
||||
delete m_pSocket;
|
||||
}
|
||||
|
||||
bool CMDNSResponder::Initialize()
|
||||
{
|
||||
assert(m_pSocket == nullptr);
|
||||
|
||||
CLogger* const pLogger = CLogger::Get();
|
||||
CNetSubSystem* const pNet = CNetSubSystem::Get();
|
||||
|
||||
if ((m_pSocket = new CSocket(pNet, IPPROTO_UDP)) == nullptr)
|
||||
return false;
|
||||
|
||||
if (m_pSocket->Bind(MDNSPort) != 0)
|
||||
{
|
||||
pLogger->Write(MDNSResponderName, LogError, "Couldn't bind to port %d", MDNSPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_pSocket->SetOptionBroadcast(true) != 0)
|
||||
{
|
||||
pLogger->Write(MDNSResponderName, LogError, "Couldn't enable broadcast packet for socket");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We started as a suspended task; run now that initialization is successful
|
||||
Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMDNSResponder::Run()
|
||||
{
|
||||
assert(m_pSocket != nullptr);
|
||||
|
||||
//CLogger* const pLogger = CLogger::Get();
|
||||
CScheduler* const pScheduler = CScheduler::Get();
|
||||
|
||||
// CIPAddress MDNSIPAddress(MDNSAddress);//Utility::IPAddressToInteger(192, 168, 175, 30));
|
||||
|
||||
// char buf[] = "hello world";
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// m_pSocket->SendTo(buf, sizeof(buf), 0, MDNSIPAddress, MDNSPort);
|
||||
// pScheduler->Sleep(1);
|
||||
// }
|
||||
|
||||
// return;
|
||||
|
||||
|
||||
// mdns_record_t Record =
|
||||
// {
|
||||
// { "_applemidi", 10 },
|
||||
// MDNS_RECORDTYPE_PTR,
|
||||
// {
|
||||
// .ptr.name = ""
|
||||
// }
|
||||
// };
|
||||
// mdns_record_t Record;
|
||||
// Record.name = { MDNS_STRING_CONST("_applemidi._udp.local.") };
|
||||
// Record.type = MDNS_RECORDTYPE_PTR;
|
||||
// Record.data.ptr.name = { MDNS_STRING_CONST("mt32-pi._applemidi._udp.local.") };
|
||||
// Record.rclass = 0;
|
||||
// Record.ttl = 0;
|
||||
|
||||
|
||||
return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// char buf[] = "hello world";
|
||||
// CIPAddress MDNSIPAddress(MDNSAddress);
|
||||
// m_pSocket->SendTo(buf, sizeof(buf), 0, MDNSIPAddress, MDNSPort);
|
||||
// pScheduler->Sleep(1);
|
||||
|
||||
mdns_record_t Record =
|
||||
{
|
||||
.name = { MDNS_STRING_CONST("_apple-midi._udp.local.") },
|
||||
.type = MDNS_RECORDTYPE_PTR,
|
||||
.data = { .ptr = { .name = { MDNS_STRING_CONST("mt32-pi._apple-midi._udp.local.") } } },
|
||||
.rclass = 0,
|
||||
.ttl = 0
|
||||
};
|
||||
|
||||
assert(mdns_announce_multicast(m_pSocket, m_Buffer, sizeof(m_Buffer), Record, nullptr, 0, nullptr, 0) == 0);
|
||||
pScheduler->Sleep(2);
|
||||
|
||||
assert(mdns_announce_multicast(m_pSocket, m_Buffer, sizeof(m_Buffer), Record, nullptr, 0, nullptr, 0) == 0);
|
||||
pScheduler->Sleep(10);
|
||||
|
||||
assert(mdns_announce_multicast(m_pSocket, m_Buffer, sizeof(m_Buffer), Record, nullptr, 0, nullptr, 0) == 0);
|
||||
pScheduler->Sleep(20);
|
||||
|
||||
assert(mdns_goodbye_multicast(m_pSocket, m_Buffer, sizeof(m_Buffer), Record, nullptr, 0, nullptr, 0) == 0);
|
||||
pScheduler->Sleep(2);
|
||||
|
||||
// // Non-blocking call
|
||||
// const int nResult = m_pSocket->Receive(m_ReceiveBuffer, sizeof(m_ReceiveBuffer), MSG_DONTWAIT);
|
||||
// m_pSocket->ReceiveFrom()
|
||||
|
||||
// if (nResult < 0)
|
||||
// pLogger->Write(MDNSResponderName, LogError, "Socket receive error: %d", nResult);
|
||||
// else if (nResult > 0)
|
||||
// {
|
||||
// pLogger->Write(MDNSResponderName, LogDebug, "Received something of size %d", nResult);
|
||||
// }
|
||||
|
||||
// TDNSHeader* Header = reinterpret_cast<TDNSHeader*>(m_ReceiveBuffer);
|
||||
// Header->nID = htons(0);
|
||||
// Header->nFlags = htons(DNS_FLAGS_QR | DNS_FLAGS_AA);
|
||||
// Header->nQDCount = htons(0);
|
||||
// Header->nANCount = htons(1);
|
||||
// Header->nNSCount = htons(0);
|
||||
// Header->nARCount = htons(0);
|
||||
|
||||
// u8* pPtr = m_ReceiveBuffer + sizeof(TDNSHeader);
|
||||
// *pPtr++ = 0x0B;
|
||||
// *pPtr++ = '_';
|
||||
// *pPtr++ = 'a';
|
||||
// *pPtr++ = 'p';
|
||||
// *pPtr++ = 'p';
|
||||
// *pPtr++ = 'l';
|
||||
// *pPtr++ = 'e';
|
||||
// *pPtr++ = '-';
|
||||
// *pPtr++ = 'm';
|
||||
// *pPtr++ = 'i';
|
||||
// *pPtr++ = 'd';
|
||||
// *pPtr++ = 'i';
|
||||
// *pPtr++ = 0x04;
|
||||
// *pPtr++ = '_';
|
||||
// *pPtr++ = 'u';
|
||||
// *pPtr++ = 'd';
|
||||
// *pPtr++ = 'p';
|
||||
// *pPtr++ = 0x05;
|
||||
// *pPtr++ = 'l';
|
||||
// *pPtr++ = 'o';
|
||||
// *pPtr++ = 'c';
|
||||
// *pPtr++ = 'a';
|
||||
// *pPtr++ = 'l';
|
||||
// *pPtr++ = '\0';
|
||||
|
||||
// TDNSResourceRecordTrailerAIN* Record = reinterpret_cast<TDNSResourceRecordTrailerAIN*>(pPtr);
|
||||
// Record->nType = 0x0C;
|
||||
// Record->nClass = 0x01;
|
||||
// Record->nTTL = 120;
|
||||
// //Record->nRDLength
|
||||
|
||||
// const u8 nNameLength = strlen(m_DNSName);
|
||||
// *pPtr++ = nNameLength;
|
||||
// memcpy(reinterpret_cast<char*>(pPtr), m_DNSName, nNameLength);//, sizeof(m_ReceiveBuffer) - (pPtr - m_ReceiveBuffer));
|
||||
// pPtr += nNameLength;
|
||||
|
||||
// // Allow other tasks to run
|
||||
// //pScheduler->Yield();
|
||||
// pScheduler->Sleep(10);
|
||||
}
|
||||
}
|
||||
@@ -33,29 +33,29 @@ const char UDPMIDIName[] = "udpmidi";
|
||||
|
||||
CUDPMIDIReceiver::CUDPMIDIReceiver(CUDPMIDIHandler* pHandler)
|
||||
: CTask(TASK_STACK_SIZE, true),
|
||||
m_pMIDISocket(nullptr),
|
||||
m_MIDIBuffer{0},
|
||||
m_pSocket(nullptr),
|
||||
m_ReceiveBuffer{0},
|
||||
m_pHandler(pHandler)
|
||||
{
|
||||
}
|
||||
|
||||
CUDPMIDIReceiver::~CUDPMIDIReceiver()
|
||||
{
|
||||
if (m_pMIDISocket)
|
||||
delete m_pMIDISocket;
|
||||
if (m_pSocket)
|
||||
delete m_pSocket;
|
||||
}
|
||||
|
||||
bool CUDPMIDIReceiver::Initialize()
|
||||
{
|
||||
assert(m_pMIDISocket == nullptr);
|
||||
assert(m_pSocket == nullptr);
|
||||
|
||||
CLogger* const pLogger = CLogger::Get();
|
||||
CNetSubSystem* const pNet = CNetSubSystem::Get();
|
||||
|
||||
if ((m_pMIDISocket = new CSocket(pNet, IPPROTO_UDP)) == nullptr)
|
||||
if ((m_pSocket = new CSocket(pNet, IPPROTO_UDP)) == nullptr)
|
||||
return false;
|
||||
|
||||
if (m_pMIDISocket->Bind(MIDIPort) != 0)
|
||||
if (m_pSocket->Bind(MIDIPort) != 0)
|
||||
{
|
||||
pLogger->Write(UDPMIDIName, LogError, "Couldn't bind to port %d", MIDIPort);
|
||||
return false;
|
||||
@@ -70,7 +70,7 @@ bool CUDPMIDIReceiver::Initialize()
|
||||
void CUDPMIDIReceiver::Run()
|
||||
{
|
||||
assert(m_pHandler != nullptr);
|
||||
assert(m_pMIDISocket != nullptr);
|
||||
assert(m_pSocket != nullptr);
|
||||
|
||||
CLogger* const pLogger = CLogger::Get();
|
||||
CScheduler* const pScheduler = CScheduler::Get();
|
||||
@@ -78,12 +78,12 @@ void CUDPMIDIReceiver::Run()
|
||||
while (true)
|
||||
{
|
||||
// Blocking call
|
||||
const int nMIDIResult = m_pMIDISocket->Receive(m_MIDIBuffer, sizeof(m_MIDIBuffer), 0);
|
||||
const int nResult = m_pSocket->Receive(m_ReceiveBuffer, sizeof(m_ReceiveBuffer), 0);
|
||||
|
||||
if (nMIDIResult < 0)
|
||||
pLogger->Write(UDPMIDIName, LogError, "MIDI socket receive error: %d", nMIDIResult);
|
||||
else if (nMIDIResult > 0)
|
||||
m_pHandler->OnUDPMIDIDataReceived(m_MIDIBuffer, nMIDIResult);
|
||||
if (nResult < 0)
|
||||
pLogger->Write(UDPMIDIName, LogError, "Socket receive error: %d", nResult);
|
||||
else if (nResult > 0)
|
||||
m_pHandler->OnUDPMIDIDataReceived(m_ReceiveBuffer, nResult);
|
||||
|
||||
// Allow other tasks to run
|
||||
pScheduler->Yield();
|
||||
|
||||
Reference in New Issue
Block a user