• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Bluetooth pin generation

Hi guys,
I have got a BBQ thermometer which runs through an app and measures temperature to a certain point when it gives an alarm. Unfortunately the app is a bit short on functionality so I wanted to pair the thermomenter with my phone.
I cannot do this since I do not know the bluetooth pin. It seems that the pin is transmitted automatically by the app to the thermometer.

I had a look at the code and I think I found the place where the pin is generated, but it is not in clear text.
Could you have a look at it and help me in finding out the bluetooth pin?

I think the pin is generated in this section pasted below but I have also attached the java file to the post:

The translation of those Chinese characters close to the top of the code actually means "pairing key" which I think is quite a hot clue...
Also I think the actuall pin is generated in line I made bold.

Thanks a lot in advance

Merc

Code:
 public void onCharacteristicChanged(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) {
            int i = 0;
            String str = bluetoothGattCharacteristic.getUuid() + ":";
            String str2 = str;
            for (byte toHexString : bluetoothGattCharacteristic.getValue()) {
                str2 = str2 + Integer.toHexString(toHexString) + ", ";
            }
            byte[] value;
            short a;
            if (bluetoothGattCharacteristic.getUuid().equals(this.f1272a.f1294C.getUuid())) {
                value = bluetoothGattCharacteristic.getValue();
                if (value[0] == (byte) 32) {
                    Log.i("value[0]", "0x20   配对密钥");
                    this.f1272a.f1309R = C0463d.m1682a(value, 1);
                    this.f1272a.aa.putInt("MIYAO", this.f1272a.f1309R).apply();
                    this.f1272a.f1315X.add(new C04732(this));
                    if (this.f1272a.f1315X.size() == 1) {
                        this.f1272a.m1772i();
                    }
                } else if (value[0] == (byte) 33) {
                    Log.i("TAG", "0x21");
                    if (value[1] == (byte) 0) {
                        this.f1272a.sendBroadcast(new Intent("com.example.bbqtemperature.SERVICE_PAIR_MIYAO"));
                        Log.e("value[1]", "0x00");
                        if (!this.f1272a.f1343z.equals(this.f1272a.f1306O.m1695c())) {
                            this.f1272a.f1306O.m1690a(this.f1272a.f1343z);
                        }
                        this.f1272a.m1742a("com.example.bbqtemperature.SERVICE_YANZHENG");
                        this.f1272a.aa.putInt("MIYAO", C0463d.m1682a(new byte[]{(byte) -72, (byte) 34, (byte) 0, (byte) 0}, 0));
                        this.f1272a.aa.commit();
                        this.f1272a.m1789r();
                        this.f1272a.f1320c.m1660b(0);
                        this.f1272a.f1306O.m1696c(true);
                        this.f1272a.f1306O.m1691a(false);
                        Log.e(this.f1272a.f1318a, "connect success!");
                        this.f1272a.ae.sendEmptyMessageDelayed(20, 1500);
                        this.f1272a.f1305N = true;
                    } else if (value[1] == (byte) 1) {
                        Log.i(this.f1272a.f1318a, "connect fail");
                    } else {
                        Log.i(this.f1272a.f1318a, "what's this");
                        this.f1272a.m1742a("com.example.bbqtemperature.SERVICE_CONNECT_FAILED");
                    }
                } else if (value[0] == (byte) 35) {
                    this.f1272a.f1339v = value[1];
                    this.f1272a.f1340w = value[2];
                    if (this.f1272a.f1339v > 3 || (this.f1272a.f1339v == 3 && this.f1272a.f1340w >= 2)) {
                        this.f1272a.f1338u = 0;
                    } else {
                        this.f1272a.f1338u = 1;
                    }
                    if (this.f1272a.f1339v >= 3 && "easybbq".equals("newbbqtest")) {
                        this.f1272a.f1338u = -20;
                    }
                    this.f1272a.aa.putInt("mainVersions", value[1]);
                    this.f1272a.aa.putInt("secondVersions", value[2]);
                    this.f1272a.aa.commit();
                } else if (value[0] == (byte) 36) {
                    a = MyBbqBleService.m1730a(value, 1);
                    short a2 = MyBbqBleService.m1730a(value, 3);
                    Log.i(this.f1272a.f1318a, "onCharacteristicChanged: fullBattery: " + a2);
                    if (a2 == (short) 0) {
                        a2 = (short) 6550;
                    }
                    this.f1272a.aa.putInt("FULL_DIAN", a2).commit();
                    Intent intent = new Intent("com.example.bbqtemperature.SERVICE_DIANYA");
                    intent.putExtra("INTENT_DIANYA", a);
                    intent.putExtra("INTENT_FULL_DIANYA", a2);
                    this.f1272a.sendBroadcast(intent);
                } else if (value[0] != (byte) -1 && value[0] == (byte) 4 && value[1] == (byte) -1) {
                    this.f1272a.f1320c.m1657a();
                }
            } else if (bluetoothGattCharacteristic.getUuid().equals(this.f1272a.f1296E.getUuid())) {
                value = bluetoothGattCharacteristic.getValue();
                if (this.f1272a.f1298G) {
                    this.f1272a.aa.putInt("PROBE_COUNT", value.length / 2);
                    this.f1272a.aa.commit();
                    this.f1272a.f1298G = false;
                    this.f1272a.sendBroadcast(new Intent("INTENT_GET_TEMP"));
                }
                while (i < value.length) {
                    a = (short) ((int) Math.round(((double) MyBbqBleService.m1730a(value, i)) / 10.0d));
                    Log.i(this.f1272a.f1318a, "onCharacteristicChanged: t: " + a);
                    if (a < this.f1272a.f1338u || a > this.f1272a.f1337t) {
                        this.f1272a.m1742a(this.f1272a.f1334q[i / 2]);
                    } else {
                        this.f1272a.m1743a(this.f1272a.f1333p[i / 2], a);
                        this.f1272a.f1321d.m1666a((i / 2) + 1, a);
                    }
                    i += 2;
                }
            }
        }
 

Attachments

Last edited by a moderator:
I think this is the crucial line to get the PIN

Code:
this.f1272a.f1309R = C0463d.m1682a(value, 1);

which refers to class named C0463d, and the import statement is

Code:
import com.example.bbqtemperature.p033e.C0463d;

Do you have the code for that class? p033e is a renamed package, so you will have to hunt that down.
 
Hi LV426,
thanks for your reply.

Here is what I found based on your comment:

Code:
package com.example.bbqtemperature.p033e;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.PowerManager;
import com.example.bbqtemperature.p029a.C0358a;
import com.example.bbqtemperature.service.BbqThermometer;
import java.util.List;

/* renamed from: com.example.bbqtemperature.e.d */
public class C0463d {
    /* renamed from: a */
    private static BbqThermometer f1243a = BbqThermometer.m1687i();
    /* renamed from: b */
    private static C0358a f1244b = new C0358a(f1243a);

    /* renamed from: a */
    public static float m1681a(float f) {
        return (float) (32.0d + (((double) f) * 1.8d));
    }

    /* renamed from: a */
    public static int m1682a(byte[] bArr, int i) {
        int i2 = 0;
        int i3 = 0;
        while (i2 < 4) {
            i3 += (bArr[i2 + i] & 255) << ((3 - i2) * 8);
            i2++;
        }
        return i3;
    }

    /* renamed from: a */
    public static boolean m1683a(Context context) {
        List<RunningAppProcessInfo> runningAppProcesses = ((ActivityManager) BbqThermometer.m1687i().getSystemService("activity")).getRunningAppProcesses();
        String packageName = context.getPackageName();
        for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
            if (runningAppProcessInfo.processName.equals(packageName)) {
                return runningAppProcessInfo.importance != 100;
            }
        }
        return false;
    }

    /* renamed from: b */
    public static float m1684b(float f) {
        return (float) ((((double) f) - 32.0d) / 1.8d);
    }

    /* renamed from: b */
    public static boolean m1685b(Context context) {
        return ((KeyguardManager) context.getSystemService("keyguard")).inKeyguardRestrictedInputMode();
    }

    /* renamed from: c */
    public static void m1686c(Context context) {
        ((PowerManager) context.getSystemService("power")).newWakeLock(268435482, "Gank").acquire();
    }
}
 
Last edited by a moderator:
Ok so here's the algorithm to generate the PIN

Code:
    public static int m1682a(byte[] bArr, int i) {
        int i2 = 0;
        int i3 = 0;
        while (i2 < 4) {
            i3 += (bArr[i2 + i] & 255) << ((3 - i2) * 8);
            i2++;
        }
        return i3;
    }

So provided we know all the input values, namely 'bArr' and 'i'. And we already know that i=1, the PIN can be deduced.
 
Hi LV426,
does that mean the pin is calculated each time and differes every time?
The 'bArr' value can be found all over the place.

If that helps I could also upload the zipped remaining code.

Regards,
Merc
 
Code:
        public void onCharacteristicChanged(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic bluetoothGattCharacteristic) {
            int i = 0;
            String str = bluetoothGattCharacteristic.getUuid() + ":";
            String str2 = str;
            for (byte toHexString : bluetoothGattCharacteristic.getValue()) {
                str2 = str2 + Integer.toHexString(toHexString) + ", ";
            }
            byte[] value;
            short a;
            if (bluetoothGattCharacteristic.getUuid().equals(this.f1272a.f1294C.getUuid())) {
                value = bluetoothGattCharacteristic.getValue();      <------------------------------------------------------- input value
                if (value[0] == (byte) 32) {
                    Log.i("value[0]", "0x20   配对密钥");
                    this.f1272a.f1309R = C0463d.m1682a(value, 1);  <----------------------------------------------------- passed in to PIN generator method
                    this.f1272a.aa.putInt("MIYAO", this.f1272a.f1309R).apply();
                    this.f1272a.f1315X.add(new C04732(this));
                    if (this.f1272a.f1315X.size() == 1) {
                        this.f1272a.m1772i();
                    }

The PIN might indeed by dynamic. There's nothing I can see within the code that is a hardcoded value. PIN appears to be calculated, based on some input value.
The input value is obtained from object bluetoothGattCharacteristic. This is a parameter to the onCharacteristicChanged method. What's the value? Don't know, and the only way you'd know for sure is to dynamically debug the app.
 
Hi again,
thanks...I thought so.
So I have uploaded the complete code now. If you can be bothered to have a look that would be great but I can understand if you can't.

So thanks for all the comments up to this point!

Cheers,
Merc
 

Attachments

Back
Top Bottom