UPDATE AND SOLUTION
After getting the Nordic nRF52840 Dongle working to sniff BLE packets, I was able to capture and decipher enough ATT packets from the manufacturer's app to the LED controller to learn what I needed to. I was also able to write a Windows console app to send commands. Here are some takeaways in case someone sees this in the future:
- The nRF dongle can be fiddly. The instructions from Nordic for getting it running and capturing to Wireshark are good, but there would be times where it just quit (didn't appear in the list of Wireshark options). Restarting usually fixed this - I think maybe there were problems with assigned COM ports.
- Make sure the target (GATT server) is not connected to anything else, even the nRF Connect app before you try to capture packets.
- It turns out that, yes, the controller does just write out "012345678" on the writable characteristic whether you send a successful command or not.
- FWIW, here are some example commands for this particular brand of LED strips (GUPUP):
- The final two bytes of all commands are CRC, specifically CRC-16 (MODBUS, big endian, normal). I found this out by using this site. If you are revere engineering a different set of commands that have CRC bytes, you can input the command and check this site's outputs against captured packets.
- Turn on: A0110401b121
- Turn off: A011040070e1
- Change color: A01506RRGGBBnnnn where RR, GG, and BB are hex values for the color and nnnn are the two CRC bytes
- Change brightness: A01304xxnnnn where xx is 0 to 100 in hex
- etc.
- This video walks through how to create a C# console app for Win 10 that talks to the a BLE device. Be warned, .NET and Visual Studio change so often that it doesn't take long for certain parts of code tutorials to go stale. In my case (in March 2024), I was unable to add Windows.Devices as done in the video. There are a few fixes for this out there that are already also stale, but what worked for me was to change the target .NET version (the TargetFramework field in the .csproj XML file) from 'net8.0' to 'net6.0-windows10.0.19041.0'. I have no idea how proper or sustainable this is - it was just the first thing I tried that worked.
Good luck, fellow reverse engineers!
![[nRF image]](https://i.sstatic.net/x2Ryx.png)
![[LightBlue image]](https://i.sstatic.net/HHBoj.png)