1212import xyz .gianlu .librespot .common .proto .Authentication ;
1313import xyz .gianlu .librespot .crypto .DiffieHellman ;
1414import xyz .gianlu .librespot .mercury .MercuryClient ;
15+ import xyz .gianlu .zeroconf .Service ;
16+ import xyz .gianlu .zeroconf .Zeroconf ;
1517
1618import javax .crypto .Cipher ;
1719import javax .crypto .Mac ;
1820import javax .crypto .spec .IvParameterSpec ;
1921import javax .crypto .spec .SecretKeySpec ;
20- import javax .jmdns .JmDNS ;
21- import javax .jmdns .ServiceInfo ;
2222import java .io .Closeable ;
2323import java .io .DataInputStream ;
2424import java .io .IOException ;
@@ -82,9 +82,9 @@ public class ZeroconfServer implements Closeable {
8282 private final HttpRunner runner ;
8383 private final Session .Inner inner ;
8484 private final DiffieHellman keys ;
85- private final JmDNS [] instances ;
8685 private final List <SessionListener > sessionListeners ;
8786 private volatile Session session ;
87+ private final Zeroconf zeroconf ;
8888
8989 private ZeroconfServer (Session .Inner inner , Configuration conf ) throws IOException {
9090 this .inner = inner ;
@@ -97,48 +97,46 @@ private ZeroconfServer(Session.Inner inner, Configuration conf) throws IOExcepti
9797
9898 new Thread (this .runner = new HttpRunner (port ), "zeroconf-http-server" ).start ();
9999
100- InetAddress [] bound ;
100+ Runtime .getRuntime ().addShutdownHook (new Thread (() -> {
101+ try {
102+ close ();
103+ } catch (IOException ignored ) {
104+ }
105+ }));
106+
107+ List <NetworkInterface > nics ;
101108 if (conf .zeroconfListenAll ()) {
102- bound = getAllInterfacesAddresses ();
109+ nics = getAllInterfaces ();
103110 } else {
104111 String [] interfaces = conf .zeroconfInterfaces ();
105112 if (interfaces == null || interfaces .length == 0 ) {
106- bound = new InetAddress []{ InetAddress . getLoopbackAddress ()} ;
113+ nics = getAllInterfaces () ;
107114 } else {
108- List <InetAddress > list = new ArrayList <>();
109- for (String str : interfaces ) addAddressForInterfaceName (list , str );
110- bound = list .toArray (new InetAddress [0 ]);
115+ nics = new ArrayList <>();
116+ for (String str : interfaces ) {
117+ NetworkInterface nif = NetworkInterface .getByName (str );
118+ if (nif == null ) {
119+ LOGGER .warn (String .format ("Interface %s doesn't exists." , str ));
120+ continue ;
121+ }
122+
123+ checkInterface (nics , nif , true );
124+ }
111125 }
112126 }
113127
114- LOGGER .debug ("Registering service on " + Arrays .toString (bound ));
128+ zeroconf = new Zeroconf ();
129+ zeroconf .addSendListener (packet -> System .out .println ("SEND: " + packet ));
130+ zeroconf .addReceiveListener (packet -> System .out .println ("RECV: " + packet ));
131+ zeroconf .addNetworkInterfaces (nics );
115132
116133 Map <String , String > txt = new HashMap <>();
117134 txt .put ("CPath" , "/" );
118135 txt .put ("VERSION" , "1.0" );
136+ Service service = new Service (inner .deviceName , "spotify-connect" , port );
137+ service .setText (txt );
119138
120- boolean atLeastOne = false ;
121- instances = new JmDNS [bound .length ];
122- for (int i = 0 ; i < instances .length ; i ++) {
123- try {
124- instances [i ] = JmDNS .create (bound [i ], bound [i ].getHostName ());
125- ServiceInfo serviceInfo = ServiceInfo .create ("_spotify-connect._tcp.local." , "librespot-java-" + i , port , 0 , 0 , txt );
126- instances [i ].registerService (serviceInfo );
127- atLeastOne = true ;
128- } catch (SocketException ex ) {
129- LOGGER .warn ("Failed creating socket for " + bound [i ], ex );
130- }
131- }
132-
133- if (atLeastOne ) LOGGER .info ("SpotifyConnect service registered successfully!" );
134- else throw new IllegalStateException ("Could not register the service anywhere!" );
135-
136- Runtime .getRuntime ().addShutdownHook (new Thread (() -> {
137- try {
138- close ();
139- } catch (IOException ignored ) {
140- }
141- }));
139+ zeroconf .announce (service );
142140 }
143141
144142 @ NotNull
@@ -147,16 +145,6 @@ public static ZeroconfServer create(@NotNull AbsConfiguration conf) throws IOExc
147145 return new ZeroconfServer (Session .Inner .from (conf ), conf );
148146 }
149147
150- private static void addAddressForInterfaceName (List <InetAddress > list , @ NotNull String name ) throws SocketException {
151- NetworkInterface nif = NetworkInterface .getByName (name );
152- if (nif == null ) {
153- LOGGER .warn (String .format ("Interface %s doesn't exists." , name ));
154- return ;
155- }
156-
157- addAddressOfInterface (list , nif , false );
158- }
159-
160148 private static boolean isVirtual (@ NotNull NetworkInterface nif ) throws SocketException {
161149 byte [] mac = nif .getHardwareAddress ();
162150 if (mac == null ) return true ;
@@ -174,7 +162,7 @@ private static boolean isVirtual(@NotNull NetworkInterface nif) throws SocketExc
174162 return false ;
175163 }
176164
177- private static void addAddressOfInterface (List <InetAddress > list , @ NotNull NetworkInterface nif , boolean checkVirtual ) throws SocketException {
165+ private static void checkInterface (List <NetworkInterface > list , @ NotNull NetworkInterface nif , boolean checkVirtual ) throws SocketException {
178166 if (nif .isLoopback ()) return ;
179167
180168 if (isVirtual (nif )) {
@@ -184,18 +172,15 @@ private static void addAddressOfInterface(List<InetAddress> list, @NotNull Netwo
184172 LOGGER .warn (String .format ("Interface %s is suspected to be virtual, mac: %s" , nif .getName (), Utils .bytesToHex (nif .getHardwareAddress ())));
185173 }
186174
187- LOGGER .trace (String .format ("Adding addresses of %s {displayName: %s, mac: %s}" , nif .getName (), nif .getDisplayName (), Utils .bytesToHex (nif .getHardwareAddress ())));
188- Enumeration <InetAddress > ias = nif .getInetAddresses ();
189- while (ias .hasMoreElements ())
190- list .add (ias .nextElement ());
175+ list .add (nif );
191176 }
192177
193178 @ NotNull
194- private static InetAddress [] getAllInterfacesAddresses () throws SocketException {
195- List <InetAddress > list = new ArrayList <>();
179+ private static List < NetworkInterface > getAllInterfaces () throws SocketException {
180+ List <NetworkInterface > list = new ArrayList <>();
196181 Enumeration <NetworkInterface > is = NetworkInterface .getNetworkInterfaces ();
197- while (is .hasMoreElements ()) addAddressOfInterface (list , is .nextElement (), true );
198- return list . toArray ( new InetAddress [ 0 ]) ;
182+ while (is .hasMoreElements ()) checkInterface (list , is .nextElement (), true );
183+ return list ;
199184 }
200185
201186 @ NotNull
@@ -208,11 +193,7 @@ private static Map<String, String> parsePath(@NotNull String path) {
208193
209194 @ Override
210195 public void close () throws IOException {
211- for (JmDNS instance : instances ) {
212- if (instance != null ) instance .unregisterAllServices ();
213- }
214-
215- LOGGER .trace ("SpotifyConnect service unregistered successfully." );
196+ zeroconf .close ();
216197 runner .close ();
217198 }
218199
0 commit comments