I’m trying to build my own .Net Matter controller.
The first step in being a controller is being able to pair with devices. This is called Commissioning.
Commissioning
Commissioning involves finding a device and then establishing a secure relationship with it, so the commissioner becomes its controller. From my experience with the chip-tool, commissioning has many steps and involves certificates and stuff.
The first step, however, is finding the device.
There are a few different ways this can be done, but the most common is using Bluetooth. Matter devices can advertise themselves over Bluetooth, so I decided to start there.
Bluetooth Scanning
The advertisement payloads they send includes a ServiceUUID of 0xFFF6. If you detect an advertisement payload with that ServiceUUID, you know it’s Matter. This seemed like the most basic place to start: try and get my ESP32-C6 showing up in a console.
Accessing Bluetooth on Windows and .Net is an absolute mess. It took me a lot of exploration with different libraries, but eventually I found how to use the WinRT library.
First, change the TargetFramework
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
This enables the WinRT APIs
using Windows.Devices.Enumeration;
To make sure my ESP32-C6 Matter switch was advertising, I checked on my iPhone.

For whatever reason, it wasn’t showing up in my console application.

I knew the advertising packets were being generated, so I decided to just look a little closer.
In Table 52 of the Matter Specification document (1.4), it gives a break-down of what the advertising payload should contain.

I decided to start looking directly at the advertising payloads.
DataSections have a length, a type and the actual data. From Table 52, we have two sections. We want to concentrate on the 2nd. That’s byte 3 onwards. It’s worth noting that the length field also includes the type byte.
I added some code to break down the DataSections of the payload.
foreach (var section in args.Advertisement.DataSections)
{
var data = new byte[section.Data.Length];
using (var reader = DataReader.FromBuffer(section.Data))
{
reader.ReadBytes(data);
}
Console.WriteLine(string.Format("{0}|0x{1:X}|0x{2:X}",
section.Data.Length,
section.DataType,
BitConverter.ToString(data)));
}
Sure enough, the FFF6 bytes appeared. (0xF6-FF). I now had all the 10 bytes laid out in the Matter Specification.

I knew my ESP32 would have the standard discriminator value of 3840. I set about trying to parse that out of the payload. If I ensure it’s there, my code to *find* Matter devices would be working well enough to move on.
I then applied this check to see that it’s a Matter device. We are using bytes 0 and 1 here, which represent bytes 5 and 6:
if (section.DataType == 0x16 && data[0] == 0xF6 && data[1] == 0xFF)
If this is true, we want to pull out the discriminator
var disriminator = BitConverter.ToUInt16(data, 3);
In the case above the value is 3840, which is expected!
Summary
I made good progress here. I’ve figured out how to get Bluetooth working on Windows and how to find Matter devices.
With the ability to find the device via Bluetooth, the next step is actually performing the commissioning flow.
You can find the code up on https://github.com/tomasmcguinness/dotnet-matter




Leave a comment