00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 package org.jaebi.midlet.bt;
00013 import java.util.Enumeration;
00014 import java.util.Hashtable;
00015 import javax.bluetooth.BluetoothStateException;
00016 import javax.bluetooth.DeviceClass;
00017 import javax.bluetooth.DiscoveryAgent;
00018 import javax.bluetooth.DiscoveryListener;
00019 import javax.bluetooth.LocalDevice;
00020 import javax.bluetooth.RemoteDevice;
00021 import javax.bluetooth.ServiceRecord;
00022 import javax.bluetooth.UUID;
00023 import org.jaebi.midlet.bt.btException.BtInitException;
00024 import org.jaebi.midlet.bt.btException.DiscoveryException.DiscoveryInterruptionException;
00025 import org.jaebi.midlet.bt.btException.DiscoveryException.InquiryErrorException;
00026 import org.jaebi.midlet.bt.btException.DiscoveryException.StartInquiryException;
00027 import org.jaebi.midlet.bt.btException.DiscoveryException.UnexpectedDiscoveryCodeException;
00028 import org.jaebi.midlet.bt.btException.DiscoveryException.UnexpectedInterruptionException;
00029 import org.jaebi.midlet.bt.btException.DiscoveryException.UserInterruptionException;
00030 import org.jaebi.midlet.util.Observable;
00031 import org.jaebi.midlet.util.Observer;
00032 import org.jaebi.midlet.bt.discoveryHandling.DiscoveryReport;
00033 import org.jaebi.midlet.bt.discoveryHandling.ServiceSearchError;
00034 import org.jaebi.midlet.bt.discoveryHandling.DeviceSearchError;
00035 import org.jaebi.midlet.bt.discoveryHandling.DiscoveryError;
00036
00078 public class Discoverer extends Observable implements DiscoveryListener, DiscovererState, Runnable {
00079
00080
00081
00082
00083 LocalDevice localDevice;
00084
00085
00086
00087 private DiscoveryAgent discoveryAgent;
00088
00090 private int state = READY;
00091
00095 private DiscoveryReport discoveryReport;
00096
00109 private Hashtable serviceSearches;
00110
00112 private int discType;
00113
00114 private boolean closed;
00115
00119 private UUID UUIDset[];
00120
00124 private int attrset[];
00127
00128
00129
00130
00131 public Discoverer(DiscovererObserver discovererObserver, UUID UUIDset[], int attrset[] ) throws BtInitException{
00132 closed = false;
00133 this.discoveryReport = new DiscoveryReport();
00134
00135 try{
00136
00137 localDevice = LocalDevice.getLocalDevice();
00138 discoveryAgent = localDevice.getDiscoveryAgent();
00139 }catch (BluetoothStateException e1) {
00140 throw new BtInitException("Impossibile inizializzare la periferica bluetooth");
00141 }
00142 this.addObserver((Observer)discovererObserver);
00143 this.UUIDset = UUIDset;
00144 this.attrset = attrset;
00145 }
00146
00147 public Discoverer(DiscovererObserver discovererObservers[], UUID UUIDset[], int attrset[])throws BtInitException{
00148 closed = false;
00149 this.discoveryReport = new DiscoveryReport();
00150
00151 try{
00152
00153 localDevice = LocalDevice.getLocalDevice();
00154 discoveryAgent = localDevice.getDiscoveryAgent();
00155 }catch (BluetoothStateException e1) {
00156 throw new BtInitException("Impossibile inizializzare la periferica bluetooth");
00157 }
00158
00159 for (int i =0; i<discovererObservers.length; i++){
00160 this.addObserver((Observer)discovererObservers[i]);
00161 }
00162 this.UUIDset = UUIDset;
00163 this.attrset = attrset;
00164 }
00165
00166
00167 public boolean isClosed(){
00168 return this.closed;
00169 }
00170
00171
00172 public int getState(){
00173 return this.state;
00174 }
00175
00176
00177 private void setState(int state){
00178 this.state = state;
00179 setChanged();
00180 }
00181
00182
00189 private synchronized void searchDevices() throws StartInquiryException, DiscoveryInterruptionException, InquiryErrorException, UnexpectedDiscoveryCodeException{
00190
00191 try {
00192 discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
00193 } catch (BluetoothStateException e) {
00194 setState(DISCOVERY_ERROR);
00195 throw new StartInquiryException("Impossibile iniziare l'inquiry; impossibile iniziare la ricerca di device");
00196 }
00197
00198 try {
00199
00200 wait();
00201 } catch (InterruptedException e) {
00202 setState(DISCOVERY_ERROR);
00203 throw new UnexpectedInterruptionException("Ricerca device terminata a causa di un'interruzione inaspettata");
00204 }
00205
00206
00207 if (isClosed()) {
00208 setState(DISCOVERY_ERROR);
00209 throw new DiscoveryInterruptionException("Discovery interrotto");
00210 }
00211
00212
00213
00214
00215
00216 switch (discType) {
00217 case INQUIRY_ERROR:
00218 setState(DISCOVERY_ERROR);
00219 throw new InquiryErrorException("errore durante la ricerca di device");
00220 case INQUIRY_TERMINATED:
00221
00222
00223
00224
00225
00226 setState(DISCOVERY_ERROR);
00227 throw new UserInterruptionException("Ricerca delle device interrotta");
00228
00229 case INQUIRY_COMPLETED:
00230
00231 break;
00232 default:
00233 setState(DISCOVERY_ERROR);
00234
00235 destroy();
00236 throw new UnexpectedDiscoveryCodeException("Errore di sistema: discovery code sconosciuto");
00237 }
00238 }
00239
00240
00252 private synchronized void searchServices() throws DiscoveryInterruptionException{
00253 serviceSearches = new Hashtable();
00254 Enumeration devices = discoveryReport.getDevices();
00255 DiscoveryError discoveryError = null;
00256
00257
00258 System.out.println("sono il client e sto cercando questi UUID");
00259 for (int i=0; i<UUIDset.length; i++)
00260 System.out.println(UUIDset[i]);
00261 System.out.println("sono il client e sto cercando questi attr");
00262 for (int i=0; i<attrset.length; i++)
00263 System.out.println(attrset[i]);
00264
00265
00271 while (devices.hasMoreElements()) {
00272 RemoteDevice rd = (RemoteDevice) devices.nextElement();
00273
00274 System.out.println("sono il client ed ho indirizzo " + localDevice.getBluetoothAddress() );
00275 System.out.println("sono il client ed ho trovato un server con indirizzo " + rd.getBluetoothAddress() );
00276
00277 try {
00278 int id = discoveryAgent.searchServices(null, UUIDset,rd, this);
00279 serviceSearches.put(new Integer(id), rd );
00280 } catch (BluetoothStateException e) {
00287 String errorMsg = "Impossibile ricercare i servizi offerti dalla device ";
00288
00289 discoveryError = new ServiceSearchError(ServiceSearchError.CANT_START_SEARCH, errorMsg, rd);
00290 setState(NEW_SERVICE_SEARCH_ERROR);
00291 notifyObservers(discoveryError);
00292 setState(SERVICE_SEARCH);
00293 notifyObservers();
00294 }
00295
00296 try {
00297
00298
00299
00300
00301 wait();
00302 } catch (InterruptedException e) {
00303 setState(DISCOVERY_ERROR);
00304 throw new UnexpectedInterruptionException("Ricerca servizi terminata a causa di un'interruzione inaspettata");
00305 }
00306
00307
00308 if (isClosed()) {
00309 setState(DISCOVERY_ERROR);
00310 throw new DiscoveryInterruptionException("Discovery interrotto");
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 }
00320 }
00321
00322
00323 public void run(){
00324 discoveryReport.clear();
00325 DiscoveryError discoveryError = null;
00326
00327
00328
00329
00330
00331
00332
00333 setState(DEVICE_SEARCH);
00334 notifyObservers();
00335
00336
00337 try{
00338 searchDevices();
00339 }
00340
00341 catch(StartInquiryException e){
00342 discoveryError = new DeviceSearchError(DeviceSearchError.CANT_START_INQUIRY, e.getMessage());
00343 }
00344
00345 catch (DiscoveryInterruptionException e1){
00346
00347
00348
00349
00350
00351 String errorMsg = e1.getMessage();
00352 Exception ex;
00353
00354 try{
00355
00356
00357
00358
00359
00360 ex =(UserInterruptionException)e1;
00361 discoveryError = new DeviceSearchError(DeviceSearchError.INQUIRY_TERMINATED, errorMsg);
00362 } catch (ClassCastException ex1){
00363
00364 try{
00365
00366
00367
00368
00369
00370 ex = (UnexpectedInterruptionException)e1;
00371 discoveryError = new DiscoveryError(DeviceSearchError.UNEXPECTED_DISCOVERY_INTERRUPTION, errorMsg);
00372 } catch (ClassCastException ex2){
00373
00374
00375
00376
00377
00378 discoveryError = new DiscoveryError(DeviceSearchError.DISCOVERY_INTERRUPTION, errorMsg);
00379 }
00380
00381 }
00382
00383 }
00384
00385 catch (InquiryErrorException e2){
00386 discoveryError = new DeviceSearchError(DeviceSearchError.INQUIRY_ERROR, e2.getMessage());
00387 }
00388
00389 catch(UnexpectedDiscoveryCodeException e3){
00390 discoveryError = new DiscoveryError(DeviceSearchError.UNKNOWN_DISCOVERY_CODE, e3.getMessage());
00391 }
00392
00393 notifyObservers(discoveryError);
00394
00398 if( (discoveryError != null) || (discoveryReport.deviceCount()==0) ){
00399 setState(READY);
00400 notifyObservers();
00401 return;
00402 }
00403
00404
00405
00406
00407
00408 setState(SERVICE_SEARCH);
00409
00410
00411
00412
00413
00414 notifyObservers();
00415
00416 try{
00417 searchServices();
00418 }
00419
00420 catch (DiscoveryInterruptionException e) {
00421 Exception ex;
00422 String errorMsg = e.getMessage();
00423 try{
00424 ex = (UnexpectedInterruptionException)e;
00425 discoveryError = new DiscoveryError(DiscoveryError.UNEXPECTED_DISCOVERY_INTERRUPTION, errorMsg);
00426 } catch (ClassCastException e1){
00427 discoveryError = new DiscoveryError(DiscoveryError.DISCOVERY_INTERRUPTION, errorMsg);
00428 }
00429 }
00430
00431 notifyObservers(discoveryError);
00432
00433 setState(READY);
00434 notifyObservers();
00435
00436 }
00437
00438
00442 public void scanDevicesServices(){
00443 closed = false;
00444 new Thread(this).start();
00445 }
00446
00447
00452 public void deviceDiscovered(RemoteDevice btDevice,
00453 DeviceClass cod){
00454
00455 discoveryReport.addDevice(btDevice);
00456
00457
00458 System.out.println("device trovata: " + btDevice.getBluetoothAddress());
00459 }
00460
00461
00465 public void inquiryCompleted(int discType){
00466
00467
00468
00469
00470
00471 this.discType = discType;
00472
00473
00474
00475
00476
00477 synchronized (this) {
00478 notify();
00479 }
00480 }
00481
00482
00487 public void servicesDiscovered(int transID,ServiceRecord[] servRecord){
00488
00489 System.out.println("servizio scoperto");
00490
00491 for (int i = 0; i < servRecord.length; i++) {
00492 discoveryReport.addService(servRecord[i]);
00493
00494 }
00495 }
00496
00497
00498
00500 public void cancelSearch() {
00501 synchronized (this) {
00502 if (state == DEVICE_SEARCH) {
00503 discoveryAgent.cancelInquiry(this);
00504 } else if (state == SERVICE_SEARCH) {
00505 Enumeration en = serviceSearches.keys();
00506 while (en.hasMoreElements()){
00507 int id = ((Integer)en.nextElement()).intValue();
00508 discoveryAgent.cancelServiceSearch(id);
00509 }
00510 }
00511 }
00512 }
00513
00514
00515
00516 public void cancelServiceSearch(int id){
00517 discoveryAgent.cancelServiceSearch(id);
00518 }
00519
00520
00521
00522 public void cancelAllPendigServiceSearch(){
00523 Enumeration en = serviceSearches.keys();
00524
00525 while (en.hasMoreElements()){
00526 int id = ((Integer)en.nextElement()).intValue();
00527 discoveryAgent.cancelServiceSearch(id);
00528 }
00529 }
00530
00536 public void serviceSearchCompleted(int transID, int respCode){
00537 boolean error = false;
00538 String errorMsg;
00539
00540
00541
00542
00543
00544 Integer id = new Integer(transID);
00545 RemoteDevice rd = (RemoteDevice) serviceSearches.get(id);
00546
00547
00548 if (rd != null){
00549 System.out.println("è finita la ricerca di servizi per la device con indirizzo " + rd.getBluetoothAddress());
00550 System.out.println("ci sono " + discoveryReport.getServices(rd).size()+" servizi associati a questa device");
00551 } else
00552 System.out.println("trans id inatteso");
00553
00554 DiscoveryError discoveryError = null;
00555
00556
00557 if (!serviceSearches.containsKey(id)) {
00558
00559
00560
00561
00562
00563 error = true;
00564 errorMsg = "Id ricerca non previsto";
00565 setState(NEW_SERVICE_SEARCH_ERROR);
00566 discoveryError = new ServiceSearchError(ServiceSearchError.UNEXPECTED_TRANS_ID, errorMsg, rd);
00567
00568
00569 }
00570
00571
00572 this.serviceSearches.remove(id);
00573
00574
00575
00576
00577
00578
00579 if (!error){
00580 switch (respCode){
00581
00582 case SERVICE_SEARCH_ERROR:
00583 setState(NEW_SERVICE_SEARCH_ERROR);
00584 errorMsg = "Errore durante la ricerca di servizi";
00585 discoveryError = new ServiceSearchError(ServiceSearchError.SEARCH_ERROR, errorMsg, rd);
00586 break;
00587
00588 case SERVICE_SEARCH_TERMINATED:
00589
00590
00591
00592
00593 setState(NEW_SERVICE_SEARCH_ERROR);
00594 errorMsg = "Ricerca dei servizi interrotta";
00595 discoveryError = new ServiceSearchError(ServiceSearchError.SEARCH_TERMINATED, errorMsg, rd);
00596 break;
00597
00598 case SERVICE_SEARCH_COMPLETED:
00599 setState(this.NEW_SERVICE_SEARCH_COMPLETE);
00600
00601
00602
00603
00604
00605
00606 notifyObservers(rd);
00607 break;
00608
00609 case SERVICE_SEARCH_NO_RECORDS:
00610 setState(NEW_SERVICE_SEARCH_ERROR);
00611 errorMsg = "Per questa device non è stato trovato alcun record di servizio compatibile con quelli richiesti";
00612 discoveryError = new ServiceSearchError(ServiceSearchError.SEARCH_TERMINATED, errorMsg, rd);
00613 break;
00614
00615 case SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
00616 setState(NEW_SERVICE_SEARCH_ERROR);
00617 errorMsg = "Per questa device non è possibile continuare la ricerca di servizi perchè la device risulta non raggiungibile";
00618 discoveryError = new ServiceSearchError(ServiceSearchError.SEARCH_TERMINATED, errorMsg, rd);
00619 break;
00620
00621 default:
00622 setState(NEW_SERVICE_SEARCH_ERROR);
00623 errorMsg = "Response code sconosciuto";
00624 discoveryError = new ServiceSearchError(ServiceSearchError.UNKNOWN_DISCOVERY_CODE, errorMsg, rd);
00625 break;
00626 }
00627 }
00628
00629
00637 notifyObservers(discoveryError);
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 if (serviceSearches.size() > 0) {
00652 setState(this.SERVICE_SEARCH);
00653 notifyObservers();
00654 return;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663 synchronized (this) {
00664
00665 notify();
00666 }
00667 }
00668
00669
00670 public DiscoveryReport getDiscoveryReport(){
00671 return discoveryReport;
00672 }
00673
00674
00678 public void destroy(){
00679
00680
00681
00682 notify();
00683 cancelSearch();
00684 closed = true;
00685
00686 }
00687
00688 }