Reverse Engineering a BLE meat smoker
Tags: bluetooth
Published: 2021-02-09 19:41:19

There are not many things more satisfying than a brisket smoked low-and-slow for 20 or more hours. All that work, though, can turn to heartbreak when the fire goes out, or the smoker gets too hot and the brisket becomes a brick. So lately I’ve been using an electric smoker made by Masterbuilt ([link here](https://www.masterbuilt.com/products/40-inch-bluetooth-digital-electric-smoker), I’m not associated with Masterbuilt).

Some will say that hitting a button at 8pm to set the temperature to 225°, adding some wood chips, and going to bed is not real smoking. That I should stay up all night stoking the fire and adding logs to it. To those, I say:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vd1qohe9qmurqrjpp98q.jpg)

Yes, you pretty much have to give up in getting a smoke ring on it. So if you’re going for a competition where aesthetics matter, by all means stay up all night with a wood-fired pit. But that right there has a crunchy bark, melt in your mouth flat, and a point that tastes like caramel. It’s not Franklin’s, but I didn’t have to stay up all night tending to the fire or in line in Austin.

One cool about this smoker is that it has Bluetooth as well as a built-in meat probe. Now, what’s the point of this? 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vgusdgx0gov7ewr0szlt.png)

Well, the smartphone App from Masterbuilt allows you to change the temperature of the smoker, and monitor the temperature of both the smoker and the meat. Changing the temperature with the App is cool, but how often do you really need to do that? The more useful part is being able to monitor the probe temperature (i.e. the temperature of the MEAT!). It also allows you to set an alarm for when it reaches a certain temperature, say 203°. 

That is actually really cool. You can set the smoker outside, and monitor the temperature while in the living room watching TV. However, there are a couple of limitations that made me want to do more with it.

First, the App only works as long as your phone is within Bluetooth range of the smoker. Did you run out of beer and have to make a run to the store? Can’t monitor the temperature while you’re away, and you’ll need to remember to re-connect when you get back.

Second, I wanted to automatically record the temperatures over time to be able to get some analytics and possibly improve the smoking process. Not just the total smoke time, but things such as how long it spent in “The Stall”, how much of a difference wrapping in butcher paper, aluminum, or no-wrap made, etc.

This calls for connecting the smoker to an Internet of Things (IoT) Gateway, and publishing the data to the Cloud. That solves both of the use cases above, so let’s get to it. The Masterbuilt smoker uses Bluetooth Low Energy (BLE), but the Bluetooth SIG doesn’t define a profile or service for a meat smoker ([https://www.bluetooth.com/specifications/gatt/](https://www.bluetooth.com/specifications/gatt/)). Clearly this is an oversight! Can’t think of anything more important to standardize on. So Masterbuilt had to go the custom Service route.

Time to do some reverse engineering. Tools that help:

* App for discovering BLE services and characteristics, as well as sending values for testing. I like using [Lightblue](https://play.google.com/store/apps/details?id=com.punchthrough.lightblueexplorer) and/or [nRF Connect](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp)
* An [nRF Sniffer](https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Sniffer-for-Bluetooth-LE) and [Wireshark](https://www.wireshark.org/) to do deep inspection of all the packets.

Let’s use Lightblue to see what Services and Characteristics are available. The App shows a service with the UUID 426f7567-6854-6563-2d57-65694c69fff0, and four Characteristics:

Characteristic 1: 426f7567-6854-6563-2d57-65694c69fff1 Read/Write
Characteristic 2: 426f7567-6854-6563-2d57-65694c69fff2 Read
Characteristic 3: 426f7567-6854-6563-2d57-65694c69fff3 
Read/Write
Characteristic 4: 426f7567-6854-6563-2d57-65694c69fff4 Notify

Well, the names are not very descriptive, so I’m not sure what they all do, let’s grab the sniffer and Wireshark to look at the packets as we use the official App to control and monitor the smoker.

The first thing it does after connecting is read from Characteristics 1 and 2, and then turning on the notification on Characteristic 4:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1kz4f4a1zq02khgmazq2.png)

Characteristic 4 now sends a notification every second. With the smoker turned off, the value is always 0xb2000000:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uvb4jntztii90tf9k8cj.png)

I use the App to set the temperature to 225 for one hour, and here’s the packet that goes across. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s2g2d9u1rz2woa3923mf.png)

This tells us that Characteristic 3 is for control. Let’s try a few more changes, and see what the value being sent is. 

Set to 225 degrees for 60 minutes: A1 07 05 3C 00 E1 00
Set to 250 degrees for 60 minutes: A1 07 05 3C 00 FA 00
Set to 250 degrees for 120 minutes: A1 07 05 78 00 FA 00
Turn off: A1 01 00

Byte 0 is always 0xA1. Bytes 1 and 2 are 0x0507 when on, and 0x0001 when off. Bytes 3 and 4 are the time to set (0x0078 for 120 minutes, 0x003C for 60 minutes), and the last two bytes are the temperature (225 is 0x00E1, 250 is 0x00FA).

Now that I can control it, let’s see what the notification value comes out as:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zvwjt1v9twwks0twr7ix.png)

Remember that when it was off, we got B2 00 00 00. Now we get 15 bytes instead of 4. I observed as these changed when the temperature of the smoker and the meat probe changed, and here’s the mapping:

Byte 0 is always 0xB2. 
Byte 1 seems to always be 0x1F
Byte 2 is some sort of status. 0x01 when on but no set temp. 0x05 when heating up.
Bytes 4 and 5 are current smoker temperature (0x0026, or 38)
Bytes 6 and 7 are probe temperature (0x0024, or 36)
Bytes 8 and 9 are minutes remaining (0x0078, 120 minutes)
Bytes 11 and 12 are set time in minutes (0x0078, 120 minutes)
Bytes 13 and 14 are set temperature (0x00FA, or 250)
I’m not sure what byte 3 (0x00) or byte 10 (0x12) are. Maybe something to explore later.

In conclusion, we now have:
* BLE characteristic that can be used to control the temperature and time for the smoker, as well as what the bytes to be written should be.
* BLE characteristic to subscribe to notifications, to receive the current status of the smoker, including the temperature of the meat.

With these two pieces of information, we can now integrate them into the IoT gateway of choice to publish the data to the cloud and be able to access it remotely. Here's an example using a [Particle Boron](https://github.com/particle-iot/ble-gateway-library/tree/main/examples/masterbuilt-smoker).