Forum: PC-Programmierung Android BLE Schreiben von Characteristic schlägt fehl


von kk (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit meinem nrf51822(Adafruit UART BLE Friend 
Board). Ich habe über meinem Mikrocontroller(XMC4500) das Modul 
konfiguriert, und hab meine Costum Services und Characteristics 
hinzugefügt. Diese kann ich auch mit meiner NRF Connect App sehen. Ich 
kann mit einem Android 4.4.4 Device, die Characteristics zugreifen und 
darauf schreiben(mit der NRF APP). Versuche ich nun diese 
Characteristics mit Android 9.0 zu beschreiben, dann scheitert die App, 
und es kommt laut log zu einem Gatt Error 133 (mit auch ohne Bonding).

Der Log:

V  19:19:30.820  Writing request to characteristic 
00000002-0000-1000-8000-00805f9b34fb
D  19:19:30.820 
gatt.writeCharacteristic(00000002-0000-1000-8000-00805f9b34fb, 
value=0x23702E33)
E  19:20:00.825  Error 133 (0x85): GATT ERROR

Daher habe ich meine eigene App geschrieben, für Android 9.0. Jedoch 
tritt bei mir der selbe Fehler auf, wie in der NRF Connect App. Ich 
sende die Daten folgender Maßen:
1
void sendMessage(byte[] message,  String uuid_se, String uuid_ch) {
2
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
3
            Log.e(TAG, "BluetoothAdapter not initialized");
4
            return;
5
        }
6
        mCustomService_w = mBluetoothGatt.getService(UUID.fromString(uuid_se));
7
        if(mCustomService_w == null){
8
            Log.e(TAG, "Custom BLE Service not found");
9
            return;
10
        }
11
        mWriteCharacteristic = mCustomService_w.getCharacteristic(UUID.fromString(uuid_ch));
12
        mWriteCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
13
14
        synchronized (this) {
15
            if (isSending) {
16
                messageQueue.add(message);
17
                return;
18
            }
19
            isSending = true;
20
        }
21
        mWriteCharacteristic.setValue(message);
22
        final int charaProp = mWriteCharacteristic.getProperties();
23
        if((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
24
            boolean status = mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
25
            if (status == false) {
26
                Log.e(TAG, "Failed to write characteristic");
27
            } else {
28
                byte[] bytes = mWriteCharacteristic.getValue();
29
                StringBuilder sb = new StringBuilder();
30
                for (byte b : bytes) {
31
                    sb.append(String.format("%02X ", b));
32
                }
33
                Log.w(TAG, "Write message: hal: " + mWriteCharacteristic.getStringValue(0) + " Mess_len: " + mWriteCharacteristic.getValue().length + " BYTES " + sb.toString());
34
                Log.e(TAG, "Message sent");
35
            }
36
        }
37
    }
38
39
    protected void sendDataWithCRC(byte[] data, String uuid_se, String uuid_ch) {
40
41
        // Calculate checksum
42
        byte checksum = 0;
43
        for (byte aData : data) {
44
            checksum += aData;
45
        }
46
        checksum = (byte) (~checksum);       // Invert
47
48
        // Add crc to data
49
        byte dataCrc[] = new byte[data.length + 1];
50
        System.arraycopy(data, 0, dataCrc, 0, data.length);
51
        dataCrc[data.length] = checksum;
52
53
        // Send it
54
        Log.d(TAG, "Send to UART: ");
55
        sendMessage(dataCrc, uuid_se, uuid_ch);
56
    }
57
//CALLBACK wird nach der Übertragung aufgerufen, jedoch schreibt dieser //einen Status 133(GATT ERROR) hinaus.

Ich versuche es schon seit 3 Tagen, aber leider scheitere ich daran. 
Kennt jemand das Problem?

Noch die die gesendeten AT Commands:
1
error_identifier(atcommand_send("AT+GATTADDSERVICE=UUID128=00-11-00-11-44-55-66-77-88-99-AA-BB-CC-DD-EE-FF", &se_brightness_id));
2
  error_identifier(atcommand_send("AT+GATTADDCHAR=UUID=0x0002,PROPERTIES=0x08,MIN_LEN=1,MAX_LEN=15,VALUE=#p.100", &ch_brightness_write_id))

LG
Vielen Dank im Voraus!

von Jim M. (turboj)


Lesenswert?

Die App nNRF Connect funktioniert hier auf meinen Android 9.0 Geräten.

Braucht zwingend die "Standort" Berechtigung - das brauchen alle BT LE 
Apps, die nach BT Geräten scannen.

> BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT

Probiere mal: BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE

Bei "default" muss AFAIK das BT Gerät korrekt antworten. Kann man in der 
nRF Connect app über "Write Value->Advanced->(x)Command" einstellen.

Wie sieht die Characteristic Definition aus? Sagt die App "WRITE" oder 
"WRITE NO RESPONSE"?

von Joachim (Gast)


Lesenswert?

Ist zwar mit hoher Wahrscheinlichkeit nicht die Ursache des hier 
vorliegenden Problems, aber die UUIDs Deiner Characteristics und 
Services sollten nicht wie hier "00000002-0000-1000-8000-00805f9b34fb" 
sein.
Denn BLE UUIDs, die auf das Muster 
"xxxxxxxx-0000-1000-8000-00805F9B34FB" passen, sind für offizielle, 
standardisierte Services und Characteristics reserviert.

Für nicht standardisierte Services und Characteristics, die Du Dir 
selbst ausgedacht hast, solltest Du als UUID daher keine 16- oder 
32-Bit-Integer-Zahl nehmen, sondern eine vollständige, 128 Bit lange, 
(pseudo)zufällig generierte UUID, z.B. von hier:
https://www.uuidgenerator.net/

von kk (Gast)


Lesenswert?

> Braucht zwingend die "Standort" Berechtigung - das brauchen alle BT LE
> Apps, die nach BT Geräten scannen.

Vielen Dank für die Antwort. Die Rechte für den Standort und die 
Permission im Code habe ich abgefragt. Das Scannen und listen der 
Services der Geräte funktioniert. Auch in Mainfest.xml hinzugefügt
1
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
2
            if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
3
            }else {
4
                Toast.makeText(this, R.string.no_permisson_gps, Toast.LENGTH_SHORT).show();
5
                if (!this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
6
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_FINE_LOCATION);
7
                }
8
            }
9
        }

> Probiere mal: BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE

BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE, hab ich probiert, 
selber Fehler. Wobei ich diesen hier nicht verstehe, weil das Programm 
nicht auf ein Acknowledge wartet.

> Bei "default" muss AFAIK das BT Gerät korrekt antworten. Kann man in der
> nRF Connect app über "Write Value->Advanced->(x)Command" einstellen.

Habe ich gemacht. Selber Fehler. Hier noch der Log. Ich war mir aber 
nicht sicher, was ich senden soll, wenn ich ein Command sende.

V 20:47:34.679 Changing write type for 
00000002-0000-1000-8000-00805f9b34fb to WRITE COMMAND
D 20:47:34.679 characteristic.setWriteType(WRITE COMMAND)
V 20:47:34.691 Writing command to characteristic 
00000002-0000-1000-8000-00805f9b34fb
D 20:47:34.691 
gatt.writeCharacteristic(00000002-0000-1000-8000-00805f9b34fb, 
value=0x23702E30)
D 20:48:04.695 [Server callback] Connection state changed with status: 0 
and new state: DISCONNECTED (0)
I 20:48:04.695 [Server] Device disconnected
E 20:48:04.709 Error 133 (0x85): GATT ERROR
D 20:48:04.743 [Callback] Connection state changed with status: 22 and 
new state: DISCONNECTED (0)
D 20:48:04.743 [Broadcast] Action received: 
android.bluetooth.device.action.ACL_DISCONNECTED
E 20:48:04.744 Error 22 (0x16): GATT CONN TERMINATE LOCAL HOST
I 20:48:04.744 Disconnected

> Wie sieht die Characteristic Definition aus? Sagt die App "WRITE" oder
> "WRITE NO RESPONSE"?

Die App sagt WRITE. Den Versuch mit 
BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE und 
BluetoothGattCharacteristic.WRITE_DEFAULT habe ich mit "WRITE" und 
"WRITE NO RESPONSE" characteristicen probiert.

von kk (Gast)


Lesenswert?

Joachim schrieb:
> Ist zwar mit hoher Wahrscheinlichkeit nicht die Ursache des hier
> vorliegenden Problems, aber die UUIDs Deiner Characteristics und
> Services sollten nicht wie hier "00000002-0000-1000-8000-00805f9b34fb"
> sein.
> Denn BLE UUIDs, die auf das Muster
> "xxxxxxxx-0000-1000-8000-00805F9B34FB" passen, sind für offizielle,
> standardisierte Services und Characteristics reserviert.
>
> Für nicht standardisierte Services und Characteristics, die Du Dir
> selbst ausgedacht hast, solltest Du als UUID daher keine 16- oder
> 32-Bit-Integer-Zahl nehmen, sondern eine vollständige, 128 Bit lange,
> (pseudo)zufällig generierte UUID, z.B. von hier:

Ich dachte dies gilt nur für die UUID von Services? Ein Moment, ich 
ändere die UUID.

von Joachim (Gast)


Lesenswert?

kk schrieb:
> Ich dachte dies gilt nur für die UUID von Services?

Laut
https://en.wikipedia.org/wiki/Bluetooth_Low_Energy#Identifiers
gilt das für alle "Attribute", wobei "Attribute" der gemeinsame 
Überbegriff für Services, Characteristics und Descriptors ist.

> Ein Moment, ich ändere die UUID.

Mach das. Aber ich halte es wie gesagt doch für eher unwahrscheinlich, 
dass das hier das Problem ist.

von kk (Gast)


Lesenswert?

Joachim schrieb:
> kk schrieb:
>> Ich dachte dies gilt nur für die UUID von Services?
>
> Laut
> https://en.wikipedia.org/wiki/Bluetooth_Low_Energy#Identifiers
> gilt das für alle "Attribute", wobei "Attribute" der gemeinsame
> Überbegriff für Services, Characteristics und Descriptors ist.
>
>> Ein Moment, ich ändere die UUID.
>
> Mach das. Aber ich halte es wie gesagt doch für eher unwahrscheinlich,
> dass das hier das Problem ist.

Ja leider hattest du Recht, keine Veränderung. Ich glaube ich habe 
vergessen, zu erwähnen, dass das Lesen der Characteristics funktioniert. 
Ich kann z.B die ADC Spannung lesen

von kk (Gast)


Lesenswert?

Ich habe etwas anderes ausprobiert. Ich habe den Interrupt, welcher die 
Informationen, vom NRF51822 holt mal ausgeschalten, weil ich gedacht 
habe, dass ev. das Polling (ich weiß man hätte es schöner lösen können), 
dass Problem ist. Jedoch tritt der selbe Fehler wieder auf. Status 133

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.