View Javadoc
1   package fr.ifremer.tutti.ichtyometer;
2   
3   /*
4    * #%L
5    * Tutti :: Ichtyometer API
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  
30  import javax.bluetooth.BluetoothStateException;
31  import javax.bluetooth.DataElement;
32  import javax.bluetooth.DeviceClass;
33  import javax.bluetooth.DiscoveryListener;
34  import javax.bluetooth.LocalDevice;
35  import javax.bluetooth.RemoteDevice;
36  import javax.bluetooth.ServiceRecord;
37  import javax.bluetooth.UUID;
38  import java.util.ArrayList;
39  import java.util.List;
40  
41  /**
42   * Created on 4/4/15.
43   *
44   * @author Tony Chemit - chemit@codelutin.com
45   * @since 3.14.4
46   */
47  public class ServiceRecordsFinder {
48  
49      /** Logger. */
50      private static final Log log = LogFactory.getLog(ServiceRecordsFinder.class);
51  
52      private final int maximumNumberOfTryToConnect;
53  
54      private final Object lock;
55  
56      private final List<ServiceRecord> serviceRecords;
57  
58      public ServiceRecordsFinder(int maximumNumberOfTryToConnect, Object lock) {
59          this.maximumNumberOfTryToConnect = maximumNumberOfTryToConnect;
60          this.lock = lock;
61          this.serviceRecords = new ArrayList<>();
62      }
63  
64      public List<ServiceRecord> findServices(LocalDevice localDevice, RemoteDevice device, int serviceIndex) throws InterruptedException, BluetoothStateException {
65  
66          ServicesDiscoveryListener listener = new ServicesDiscoveryListener();
67          int tryRound = 0;
68  
69          while (tryRound < maximumNumberOfTryToConnect && serviceRecords.isEmpty()) {
70              synchronized (lock) {
71  
72                  int[] attrIDs = new int[]{
73                          0x0100 // Service name
74                  };
75  
76  
77                  if (log.isInfoEnabled()) {
78                      log.info("Trying to get services (try " + tryRound + ")");
79                  }
80                  localDevice.getDiscoveryAgent().searchServices(attrIDs,
81                                                                 new UUID[]{new UUID(serviceIndex)},
82                                                                 device,
83                                                                 listener);
84  
85                  lock.wait();
86              }
87  
88              tryRound++;
89          }
90  
91          return serviceRecords;
92  
93      }
94  
95      protected class ServicesDiscoveryListener implements DiscoveryListener {
96  
97          @Override
98          public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
99          }
100 
101         @Override
102         public void inquiryCompleted(int discType) {
103         }
104 
105         @Override
106         public void serviceSearchCompleted(int transID, int respCode) {
107             if (log.isDebugEnabled()) {
108                 log.debug("Service search completed!");
109             }
110             synchronized (lock) {
111                 lock.notifyAll();
112             }
113         }
114 
115         @Override
116         public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
117             for (ServiceRecord aServRecord : servRecord) {
118                 String url = aServRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
119                 if (url == null) {
120                     continue;
121                 }
122                 serviceRecords.add(aServRecord);
123                 String serviceName = getServiceName(aServRecord);
124                 if (log.isDebugEnabled()) {
125                     log.debug("service found " + url + (serviceName == null ? "" : ", name: " + serviceName));
126                 }
127             }
128         }
129     }
130 
131     protected String getServiceName(ServiceRecord serviceRecord) {
132 
133         DataElement serviceName = serviceRecord.getAttributeValue(0x0100);
134         String result;
135 
136         if (serviceName == null) {
137             result = null;
138         } else {
139             result = String.valueOf(serviceName.getValue());
140         }
141         return result;
142 
143     }
144 }