How to get my Bluetooth UUID's and Advertising Data

I’m working towards getting information over Bluetooth LE from my Smartshunt and BMV-712’s

The most relevant info I have found so far is this Victron Bluetooth advertising protocol post on 19 Feb 2023, and especially the excellent details provided by Jake Baldwin in 19 May 2023 further down the same page.

I have 2 questions:

  1. I can find my Encryption Keys, but how do I find the Service UUID and the Characteristic UUIDs for my devices?

  2. Is the advertising data transmitted continually and automatically, and how often (e.g. 1/5secs or 1/sec or 10/sec) ?

TIA

Hi Chris,
what do you mean with Service UUID - model no?
The data is pushed every few seconds…
Best Sascha

Hi Saschakopp,

Since my post above I have discovered a couple of BLE scanning apps on android (BLE Scanner & nRF Connect) that are very helpful, or should I say too helpful, as now have many UUID’s to choose from, but I’ve yet to figure out which is which.

If I open the Scanner tab in nRF Connect and select my Smartshunt I can see the advertised data, as shown in the screenshot attached. I’m pretty sure this is the advertised data. It consists of 22 bytes with the first 5 bytes stable and starting with 0x10, and the remaining 17 bytes updating every few seconds (as you said :slightly_smiling_face:). They would have to be the encrypted data evolving with time.

But I can’t seem to find the specific UUID I need so I can access this data from the app I am developing (using MIT App Inventor, a great tool BTW)

Is there a Victon reference explaining how to find the UUIDs for advertised data ?

I think in this data you don’t get the uuid…

You don’t need a UUID in order to receive the BLE advertisement data.

The UUIDs are service IDs but the data you are looking for is not part of a service.

The device state is broadcast in the Manufacturer Data section of the Bluetooth Low Energy Advertisement packet, under the Victron manufacturer ID of 737.

It’s literally those bytes starting 0x10 in the screenshot above!

Yes that’s right. Since posting here I’ve succeeded in reading the advertised data using a custom program on a microprocessor with BLE, without needing a UUID or bluetooth connection (just pairing). Right now I’m wrestling with decrypting the encypted portion and it’s proving tricky. I will be posting here soon, seeking help from Victron staff …
And yes the Victron manufacturer ID is indeed 737 = HEX 02E1
You can see it in the nRF screenshot above as <0x02E1>

For anyone who interested, I’ve attached examples showing how to break the advertised data into its parts.
RAW fiddle (c).txt (2.7 KB)

Hi Chris,

In case you’re interested, I already have this working. You might like to look at my code to see how I do it:

This file is probably the most interesting for you:

Cheers
Felix

Hi Felix,

It’s great to hear someone’s actually got this working. I’ve hit a brick wall and would like to ask you for a huge favour … please.

If you could load the following encrypted data (cipher) into your application, and decrypt it using my initialisation vector and encryption key. The data is from my MPPT 100/30 Solar Charger:

cipher = 0x66,0xC7,0x15,0x10,0x21,0x11,0x4B,0x58,0xB8,0x62,0x42,0xF1 (12 bytes HEX)

iv = 0x43,0x05

my key = 0x33,0x9a,0x28,0x9d,0x08,0x61,0xe8,0x34,0x16,0xe5,0x8d,0xb7,0x58,0x33,0xdc,0x0a (16 bytes)

To progess my issue I need:

  1. the resulting unencrypted 12 bytes of clear data
  2. and ideally what values your app reports for the state of the charger.

As a guide, this was the state of my Solar Charger when I recorded the above cipher:

Device State = Float
Charger Error = none
Batt Voltage = 27.00 V (approx)
Batt Current = 2.3 A (approx)
Yield today = 1.06 kWh (approx)
PV Power = 65 W (approx)
Load current = 0 A

I’m expecting your app to report values very close to the above

many thanks in advance

best regards
Chris Jennings

PS: Some additional background info, FYI only …

I had a look at your Rust code (thanks). I’ve never used Rust so I can only get a few clues.

I’m developing in C++ for Arduino compatible hardware and I’ve also built an encyption/decyrption routine based on the “Extra Manufacturer Data” document, “Solar Charger” section on Page 3 and other info I found on the old Victron fourm.

When I generate a (fictitious) data string according to the bit-field spec, then encrypt, then decrypt, I get the original data back, as expected. So it “appears” to be working … however … when I use it to decrypt real data I don’t get the expected results.

Basically I’m not sure if:

  • my program isn’t decrypting the data correctly
  • my program isn’t disassembling the data correctly
  • the Victron “Extra Manufacturer Data” document has an error, or is incomplete.
  • something else I haven’t thought of !

Your data decrypts and parses correctly.

I had to reconstruct what your full manufacturer data packet should look like and I got this:

0x100000000143053366C7151021114B58B86242F1

Decrypting that with your key and IV I got the decrypted payload:

05008c0a21006a005c00ffffc1fc25c4

And parsing that I got:

SolarCharger(SolarChargerState { mode: Float, error_state: NoError, battery_voltage_v: 27.0, battery_current_a: 3.3, yield_today_kwh: 1.06, pv_power_w: 92.0, load_current_a: 51.1 })

If you’re going wrong at decryption please the file I linked above.

If you’re going wrong at parsing please see:

victron_ble/src/bit_reader.rs at main · felixwatts/victron_ble · GitHub and victron_ble/src/model/solar_charger_state.rs at main · felixwatts/victron_ble · GitHub

Hope this helps!

Felix,

Many thanks for your helpful response. It’s now apparent I had two issues:
(1) some flaws in parsing and
(2) a suspect decryption algorithm

The former was resolved by some easy little-endian swaps. Now I can parse your decrypted output and match your results

But for the latter: I’m using the wolfSSL libraries (https://www.wolfssl.com/) in the Arduino IDE, and my algorithm doesn’t give same results as yours.

I tried a little-endian swap on the iv, but it made no difference.

I now suspect this algoritm doesn’t match the one used by Victron, so I may have to ditch wolfSSL and find (or write) another algorithm.

I had a look at your records.rs file on github. Is your code calling a third party algorithm, or an algorithm you have written (or borrowed) to do the AES Counter mode decryption?

TIA

PS: if you’re interested see attached the output when I run my program that:

  • uses your ‘decyrpted output’ as the input
  • encyrpts → cipher
  • decrypts → output
  • dissects and reports

AES_CTR_enc_dec.t_output.txt (1.2 KB)

And you can see that works fine over the cycle, but it produces and uses a different cipher to yours.

But when I use the 16 byte cipher I provided in my last post (per the last 16 bytes of your ''full manufacturer data packet"), and decrypt, I get rubbish out :frowning:

Hold the boat … I just found the solution to my decyption woes: the iv has to be 16 bytes!

As soon as I added zeros padding the iv out to 16 bytes, the decyption worked. success is sweet :slightly_smiling_face:

I literally just came here to suggest that! It caught me out too.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.