Hallo Forum,
ich versuche einen Bluetooth Client mit der Bluecove Bibliothek zum Laufen zu bekommen, um darüber später ein HID-Gerät und ein Dateiaustausch zu ermöglichen. Unten angehängt ist meine Testklasse. Um das Verhalten von Bluetooth besser nachvollziehen zu können, sind dort bewusst noch blocking- Thread.sleep enthalten. Das Multithreading kommt später.
Mein Problem ist, dass ich mit "searchServices()" bei Test's mit unterschiedlichen Bluetooth Geräten keinen einzigen Service finde. Es ist gut möglich, dass ich das Bluetooth-Konzept aus den ganzen Informationen im Internet missinterpretiert habe. Mein grundsätzliches Verständnis des späteren Ablaufes (der GUI-Teil ist in dem Code unten nicht enthalten und ist durch Konstanten ersetzt) ist aktuell:
Geräte in der nähe suchen
Geräte in der nähe anzeigen
-> User wählt Gerät für Verbindung
Gewähltes Gerät nach dem von mir benötigten Service fragen
-> wenn Service nicht verfügbar -> User-Meldung: Gerät ungeeignet
-> wenn Service verfügbar -> Server/Service URL aus dem gefundenen Services holen und Verbindung öffnen
Nur finde ich für die von mir versuchten Service-Ids "0011", "1124" oder "1106" keine Services. Eines meiner Testgeräte ist auch ein Win-PC der mindestens den HID Service unterstützen müsste. Aber selbst das konnte ich bisher nicht verifizieren, da ich bisher keine Möglichkeit gefunden habe ein bestimmtes Gerät einfach nach "allen verfügbaren" Services zu fragen. In der API sehe ich nur Service-such-Befehle um nach bestimmten/bekannten Services zu fragen.
Entweder missverstehe ich die Befehle oder die Channel/SDP Id's. Hat jemand einen Tipp?
[CODE lang="java" title="Bluecove Testklasse"]import java.io.IOException;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
public class BtHidDataHandler implements DiscoveryListener {
private final BtHidDataHandler btHandler;
private Logger log;
//private final UUID hidServiceId = new UUID("1124", true);
private final UUID hidServiceId = new UUID("0011", true);
private final UUID ftpServiceId = new UUID("1106", true);
private final UUID[] serviceIdTable = new UUID[]{hidServiceId};
//private final UUID[] serviceIdTable = new UUID[]{hidServiceId, ftpServiceId};
private final Queue<RemoteDevice> foundRemoteDevices = new ConcurrentLinkedQueue<RemoteDevice>();
private final Queue<ServiceRecord> foundRemoteServices = new ConcurrentLinkedQueue<ServiceRecord>();
public void startDeviceAccessTest(){
try{
// ja, is der stöpsel denn auch an?
if (LocalDevice.isPowerOn()){
// lokaler zugriff
LocalDevice ld = LocalDevice.getLocalDevice();
String sLocalName = ld.getFriendlyName();
log.log(Level.INFO, "mein Gerät heißt: {0}", sLocalName);
// bekannte partner finden
DiscoveryAgent agent = ld.getDiscoveryAgent();
RemoteDevice[] knownPairingPartners = agent.retrieveDevices(DiscoveryAgent.PREKNOWN);
if (knownPairingPartners != null) {
log.log(Level.INFO, "Meine Freunde heißen: ");
for(RemoteDevice rd : knownPairingPartners){
log.log(Level.INFO, "{0} : {1}", new Object[]{rd.getFriendlyName(false), rd.getBluetoothAddress()});
}
}
// starte device suche
foundRemoteDevices.clear();
agent.startInquiry(DiscoveryAgent.GIAC, btHandler);
log.log(Level.INFO, "Gerätesuche gestartet");
try {Thread.sleep(15000);} catch (InterruptedException ex) {}
log.log(Level.INFO, "Gerätesuche warten beendet");
// finde meinen partner
RemoteDevice myRD = null;
log.log(Level.INFO, "Geräte gefunden: ");
while(!foundRemoteDevices.isEmpty()){
RemoteDevice device = foundRemoteDevices.poll();
log.log(Level.INFO, "{0} : {1}", new Object[]{device.getFriendlyName(false), device.getBluetoothAddress()});
if (device.getFriendlyName(false).equals("Galaxy M30s")){
myRD = device;
}
}
// partner steht zur verfügung
if (myRD != null){
// starte service suche
foundRemoteServices.clear();
agent.searchServices(null, serviceIdTable, myRD, this);
log.log(Level.INFO, "Servicesuche gestartet");
try {Thread.sleep(15000);} catch (InterruptedException ex) {}
log.log(Level.INFO, "Servicesuche warten beendet");
// wurde überhaupt ein service gefunden?
if (!foundRemoteServices.isEmpty()) {
// ermittle aus dem ersten gefundenen service die server url
log.log(Level.INFO, "Services gefunden: ");
String url = null;
while(!foundRemoteServices.isEmpty()){
ServiceRecord record = foundRemoteServices.poll();
log.log(Level.INFO, "url: {0}", record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
if (url == null) {
url = record.getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT, false);
}
}
// url gefunden
if (url != null) {
log.log(Level.INFO, "versuche connection: {0}", url);
StreamConnection connection = (StreamConnection)Connector.open(url);
log.log(Level.INFO, "Connection geöffnet");
// die verbindung testen
if (myRD.isAuthorized(connection) && myRD.isEncrypted()){
// melde erfolg
log.log(Level.INFO, "yippie!");
} else {
// melde grütze
log.log(Level.INFO, "kacka!");
}
connection.close();
}
} else {
log.log(Level.INFO, "keine Services gefunden");
}
// keine ahnung ob dieser zugriff zur Hid report konfiguration benötigt wird?!
//ServiceRecord rc = ld.getRecord(connNotifier);
//rc.
//ld.updateRecord(rc);
}
}
} catch(IOException | NullPointerException ex){
log.log(Level.INFO, "Huston we have a problem: {0}", ex.toString());
}
}
public BtHidDataHandler(Logger log){
btHandler = this;
btHandler.log = log;
}
// Discovery
@Override
public void deviceDiscovered(RemoteDevice rd, DeviceClass dc) {
foundRemoteDevices.add(rd);
}
@Override
public void servicesDiscovered(int i, ServiceRecord[] srs) {
foundRemoteServices.addAll(Arrays.asList(srs));
}
@Override
public void serviceSearchCompleted(int i, int i1) {
log.log(Level.INFO, "Servicesuche thread beendet");
}
@Override
public void inquiryCompleted(int i) {
log.log(Level.INFO, "Gerätesuche thread beendet");
}
}[/CODE]
ich versuche einen Bluetooth Client mit der Bluecove Bibliothek zum Laufen zu bekommen, um darüber später ein HID-Gerät und ein Dateiaustausch zu ermöglichen. Unten angehängt ist meine Testklasse. Um das Verhalten von Bluetooth besser nachvollziehen zu können, sind dort bewusst noch blocking- Thread.sleep enthalten. Das Multithreading kommt später.
Mein Problem ist, dass ich mit "searchServices()" bei Test's mit unterschiedlichen Bluetooth Geräten keinen einzigen Service finde. Es ist gut möglich, dass ich das Bluetooth-Konzept aus den ganzen Informationen im Internet missinterpretiert habe. Mein grundsätzliches Verständnis des späteren Ablaufes (der GUI-Teil ist in dem Code unten nicht enthalten und ist durch Konstanten ersetzt) ist aktuell:
Geräte in der nähe suchen
Geräte in der nähe anzeigen
-> User wählt Gerät für Verbindung
Gewähltes Gerät nach dem von mir benötigten Service fragen
-> wenn Service nicht verfügbar -> User-Meldung: Gerät ungeeignet
-> wenn Service verfügbar -> Server/Service URL aus dem gefundenen Services holen und Verbindung öffnen
Nur finde ich für die von mir versuchten Service-Ids "0011", "1124" oder "1106" keine Services. Eines meiner Testgeräte ist auch ein Win-PC der mindestens den HID Service unterstützen müsste. Aber selbst das konnte ich bisher nicht verifizieren, da ich bisher keine Möglichkeit gefunden habe ein bestimmtes Gerät einfach nach "allen verfügbaren" Services zu fragen. In der API sehe ich nur Service-such-Befehle um nach bestimmten/bekannten Services zu fragen.
Entweder missverstehe ich die Befehle oder die Channel/SDP Id's. Hat jemand einen Tipp?
[CODE lang="java" title="Bluecove Testklasse"]import java.io.IOException;
import java.util.Arrays;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
public class BtHidDataHandler implements DiscoveryListener {
private final BtHidDataHandler btHandler;
private Logger log;
//private final UUID hidServiceId = new UUID("1124", true);
private final UUID hidServiceId = new UUID("0011", true);
private final UUID ftpServiceId = new UUID("1106", true);
private final UUID[] serviceIdTable = new UUID[]{hidServiceId};
//private final UUID[] serviceIdTable = new UUID[]{hidServiceId, ftpServiceId};
private final Queue<RemoteDevice> foundRemoteDevices = new ConcurrentLinkedQueue<RemoteDevice>();
private final Queue<ServiceRecord> foundRemoteServices = new ConcurrentLinkedQueue<ServiceRecord>();
public void startDeviceAccessTest(){
try{
// ja, is der stöpsel denn auch an?
if (LocalDevice.isPowerOn()){
// lokaler zugriff
LocalDevice ld = LocalDevice.getLocalDevice();
String sLocalName = ld.getFriendlyName();
log.log(Level.INFO, "mein Gerät heißt: {0}", sLocalName);
// bekannte partner finden
DiscoveryAgent agent = ld.getDiscoveryAgent();
RemoteDevice[] knownPairingPartners = agent.retrieveDevices(DiscoveryAgent.PREKNOWN);
if (knownPairingPartners != null) {
log.log(Level.INFO, "Meine Freunde heißen: ");
for(RemoteDevice rd : knownPairingPartners){
log.log(Level.INFO, "{0} : {1}", new Object[]{rd.getFriendlyName(false), rd.getBluetoothAddress()});
}
}
// starte device suche
foundRemoteDevices.clear();
agent.startInquiry(DiscoveryAgent.GIAC, btHandler);
log.log(Level.INFO, "Gerätesuche gestartet");
try {Thread.sleep(15000);} catch (InterruptedException ex) {}
log.log(Level.INFO, "Gerätesuche warten beendet");
// finde meinen partner
RemoteDevice myRD = null;
log.log(Level.INFO, "Geräte gefunden: ");
while(!foundRemoteDevices.isEmpty()){
RemoteDevice device = foundRemoteDevices.poll();
log.log(Level.INFO, "{0} : {1}", new Object[]{device.getFriendlyName(false), device.getBluetoothAddress()});
if (device.getFriendlyName(false).equals("Galaxy M30s")){
myRD = device;
}
}
// partner steht zur verfügung
if (myRD != null){
// starte service suche
foundRemoteServices.clear();
agent.searchServices(null, serviceIdTable, myRD, this);
log.log(Level.INFO, "Servicesuche gestartet");
try {Thread.sleep(15000);} catch (InterruptedException ex) {}
log.log(Level.INFO, "Servicesuche warten beendet");
// wurde überhaupt ein service gefunden?
if (!foundRemoteServices.isEmpty()) {
// ermittle aus dem ersten gefundenen service die server url
log.log(Level.INFO, "Services gefunden: ");
String url = null;
while(!foundRemoteServices.isEmpty()){
ServiceRecord record = foundRemoteServices.poll();
log.log(Level.INFO, "url: {0}", record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
if (url == null) {
url = record.getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT, false);
}
}
// url gefunden
if (url != null) {
log.log(Level.INFO, "versuche connection: {0}", url);
StreamConnection connection = (StreamConnection)Connector.open(url);
log.log(Level.INFO, "Connection geöffnet");
// die verbindung testen
if (myRD.isAuthorized(connection) && myRD.isEncrypted()){
// melde erfolg
log.log(Level.INFO, "yippie!");
} else {
// melde grütze
log.log(Level.INFO, "kacka!");
}
connection.close();
}
} else {
log.log(Level.INFO, "keine Services gefunden");
}
// keine ahnung ob dieser zugriff zur Hid report konfiguration benötigt wird?!
//ServiceRecord rc = ld.getRecord(connNotifier);
//rc.
//ld.updateRecord(rc);
}
}
} catch(IOException | NullPointerException ex){
log.log(Level.INFO, "Huston we have a problem: {0}", ex.toString());
}
}
public BtHidDataHandler(Logger log){
btHandler = this;
btHandler.log = log;
}
// Discovery
@Override
public void deviceDiscovered(RemoteDevice rd, DeviceClass dc) {
foundRemoteDevices.add(rd);
}
@Override
public void servicesDiscovered(int i, ServiceRecord[] srs) {
foundRemoteServices.addAll(Arrays.asList(srs));
}
@Override
public void serviceSearchCompleted(int i, int i1) {
log.log(Level.INFO, "Servicesuche thread beendet");
}
@Override
public void inquiryCompleted(int i) {
log.log(Level.INFO, "Gerätesuche thread beendet");
}
}[/CODE]