View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling.protocol.async;
17  
18  import org.fourthline.cling.UpnpService;
19  import org.fourthline.cling.model.ValidationError;
20  import org.fourthline.cling.model.ValidationException;
21  import org.fourthline.cling.model.message.IncomingDatagramMessage;
22  import org.fourthline.cling.model.message.UpnpResponse;
23  import org.fourthline.cling.model.message.discovery.IncomingSearchResponse;
24  import org.fourthline.cling.model.meta.RemoteDevice;
25  import org.fourthline.cling.model.meta.RemoteDeviceIdentity;
26  import org.fourthline.cling.model.types.UDN;
27  import org.fourthline.cling.protocol.ReceivingAsync;
28  import org.fourthline.cling.protocol.RetrieveRemoteDescriptors;
29  import org.fourthline.cling.transport.RouterException;
30  
31  import java.util.logging.Logger;
32  
33  /**
34   * Handles reception of search response messages.
35   * <p>
36   * This protocol implementation is basically the same as
37   * the {@link org.fourthline.cling.protocol.async.ReceivingNotification} protocol for
38   * an <em>ALIVE</em> message.
39   * </p>
40   *
41   * @author Christian Bauer
42   */
43  public class ReceivingSearchResponse extends ReceivingAsync<IncomingSearchResponse> {
44  
45      final private static Logger log = Logger.getLogger(ReceivingSearchResponse.class.getName());
46  
47      public ReceivingSearchResponse(UpnpService upnpService, IncomingDatagramMessage<UpnpResponse> inputMessage) {
48          super(upnpService, new IncomingSearchResponse(inputMessage));
49      }
50  
51      protected void execute() throws RouterException {
52  
53          if (!getInputMessage().isSearchResponseMessage()) {
54              log.fine("Ignoring invalid search response message: " + getInputMessage());
55              return;
56          }
57  
58          UDN udn = getInputMessage().getRootDeviceUDN();
59          if (udn == null) {
60              log.fine("Ignoring search response message without UDN: " + getInputMessage());
61              return;
62          }
63  
64          RemoteDeviceIdentity rdIdentity = new RemoteDeviceIdentity(getInputMessage());
65          log.fine("Received device search response: " + rdIdentity);
66  
67          if (getUpnpService().getRegistry().update(rdIdentity)) {
68              log.fine("Remote device was already known: " + udn);
69              return;
70          }
71  
72          RemoteDevice rd;
73          try {
74              rd = new RemoteDevice(rdIdentity);
75          } catch (ValidationException ex) {
76              log.warning("Validation errors of device during discovery: " + rdIdentity);
77              for (ValidationError validationError : ex.getErrors()) {
78                  log.warning(validationError.toString());
79              }
80              return;
81          }
82  
83          if (rdIdentity.getDescriptorURL() == null) {
84              log.finer("Ignoring message without location URL header: " + getInputMessage());
85              return;
86          }
87  
88          if (rdIdentity.getMaxAgeSeconds() == null) {
89              log.finer("Ignoring message without max-age header: " + getInputMessage());
90              return;
91          }
92  
93          // Unfortunately, we always have to retrieve the descriptor because at this point we
94          // have no idea if it's a root or embedded device
95          getUpnpService().getConfiguration().getAsyncProtocolExecutor().execute(
96                  new RetrieveRemoteDescriptors(getUpnpService(), rd)
97          );
98  
99      }
100 
101 }