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.message.discovery.OutgoingSearchRequest;
20  import org.fourthline.cling.model.message.header.MXHeader;
21  import org.fourthline.cling.model.message.header.STAllHeader;
22  import org.fourthline.cling.model.message.header.UpnpHeader;
23  import org.fourthline.cling.protocol.SendingAsync;
24  import org.fourthline.cling.transport.RouterException;
25  
26  import java.util.logging.Logger;
27  
28  /**
29   * Sending search request messages using the supplied search type.
30   * <p>
31   * Sends all search messages 5 times, waits 0 to 500
32   * milliseconds between each sending procedure.
33   * </p>
34   *
35   * @author Christian Bauer
36   */
37  public class SendingSearch extends SendingAsync {
38  
39      final private static Logger log = Logger.getLogger(SendingSearch.class.getName());
40  
41      private final UpnpHeader searchTarget;
42      private final int mxSeconds;
43  
44      /**
45       * Defaults to {@link org.fourthline.cling.model.message.header.STAllHeader} and an MX of 3 seconds.
46       */
47      public SendingSearch(UpnpService upnpService) {
48          this(upnpService, new STAllHeader());
49      }
50  
51      /**
52       * Defaults to an MX value of 3 seconds.
53       */
54      public SendingSearch(UpnpService upnpService, UpnpHeader searchTarget) {
55          this(upnpService, searchTarget, MXHeader.DEFAULT_VALUE);
56      }
57  
58      /**
59       * @param mxSeconds The time in seconds a host should wait before responding.
60       */
61      public SendingSearch(UpnpService upnpService, UpnpHeader searchTarget, int mxSeconds) {
62          super(upnpService);
63  
64          if (!UpnpHeader.Type.ST.isValidHeaderType(searchTarget.getClass())) {
65              throw new IllegalArgumentException(
66                      "Given search target instance is not a valid header class for type ST: " + searchTarget.getClass()
67              );
68          }
69          this.searchTarget = searchTarget;
70          this.mxSeconds = mxSeconds;
71      }
72  
73      public UpnpHeader getSearchTarget() {
74          return searchTarget;
75      }
76  
77      public int getMxSeconds() {
78          return mxSeconds;
79      }
80  
81      protected void execute() throws RouterException {
82  
83          log.fine("Executing search for target: " + searchTarget.getString() + " with MX seconds: " + getMxSeconds());
84  
85          OutgoingSearchRequest msg = new OutgoingSearchRequest(searchTarget, getMxSeconds());
86          prepareOutgoingSearchRequest(msg);
87  
88          for (int i = 0; i < getBulkRepeat(); i++) {
89              try {
90  
91                  getUpnpService().getRouter().send(msg);
92  
93                  // UDA 1.0 is silent about this but UDA 1.1 recommends "a few hundred milliseconds"
94                  log.finer("Sleeping " + getBulkIntervalMilliseconds() + " milliseconds");
95                  Thread.sleep(getBulkIntervalMilliseconds());
96  
97              } catch (InterruptedException ex) {
98                  // Interruption means we stop sending search messages, e.g. on shutdown of thread pool
99                  break;
100             }
101         }
102     }
103 
104     public int getBulkRepeat() {
105         return 5; // UDA 1.0 says "repeat more than once"
106     }
107 
108     public int getBulkIntervalMilliseconds() {
109         return 500; // That should be plenty on an ethernet LAN
110     }
111 
112     /**
113      * Override this to edit the outgoing message, e.g. by adding headers.
114      */
115     protected void prepareOutgoingSearchRequest(OutgoingSearchRequest message) {
116     }
117 
118 }