DEV Community

SipanOhanyan
SipanOhanyan

Posted on

How to Communicate with Silicon Labs EFR32 NCP from C# / .NET using BGAPI

If you're working with Silicon Labs EFR32 Bluetooth or Bluetooth Mesh hardware and need to control it from a C# / .NET application, you've probably noticed there's no official C# SDK. Silicon Labs provides pyBGAPI for Python, but .NET developers have been left to figure things out on their own.

We built CsharpBgapi to fill that gap. This tutorial walks through setting up serial communication with an EFR32 NCP device from a .NET console application.

What is BGAPI?

BGAPI is Silicon Labs' binary protocol for communicating with their Bluetooth and Bluetooth Mesh Network Co-Processor (NCP) devices over a serial connection (UART). In NCP mode, the EFR32 chip handles the Bluetooth stack, and your host application sends commands and receives events via BGAPI.

The protocol is defined by XAPI files (XML API definitions) that ship with the Gecko SDK. These files describe every command, response, and event along with their parameters.

Prerequisites

  • .NET 9.0 or later (download)
  • Silicon Labs EFR32 NCP hardware (e.g., BRD4186C, BRD4187C, or any EFR32 board flashed with Bluetooth NCP firmware)
  • A USB connection to your NCP device (it will appear as a COM port on Windows or /dev/ttyACM* on Linux)

Step 1: Create a New Project

dotnet new console -n BgapiDemo
cd BgapiDemo
dotnet add package CsharpBgapi
Enter fullscreen mode Exit fullscreen mode

That's it. The NuGet package includes built-in XAPI definitions for Bluetooth and Bluetooth Mesh, so you don't need the Gecko SDK installed.

Step 2: Say Hello to Your Device

The simplest BGAPI interaction is the system hello command -- it verifies that communication is working.

using CsharpBgapi;

// Create and configure the device
var device = new BgapiDevice();
device.LoadDefaultXapis();  // Load built-in Bluetooth + Mesh protocol definitions

// Open serial connection (adjust port for your system)
device.Open("COM3");  // Windows
// device.Open("/dev/ttyACM0");  // Linux

try
{
    // Send the 'hello' command -- this is a simple ping
    var response = await device.SendCommandAsync("bt", "system", "hello");
    Console.WriteLine($"Device responded! Status: {response.Status}");
}
finally
{
    device.Close();
}
Enter fullscreen mode Exit fullscreen mode

Run it:

dotnet run
Enter fullscreen mode Exit fullscreen mode

If your device is connected and running NCP firmware, you'll see:

Device responded! Status: Ok
Enter fullscreen mode Exit fullscreen mode

Step 3: Get System Information

Let's retrieve the firmware version and Bluetooth address:

using CsharpBgapi;

var device = new BgapiDevice();
device.LoadDefaultXapis();
device.Open("COM3");

try
{
    // Get firmware version
    var version = await device.SendCommandAsync("bt", "system", "get_version");
    Console.WriteLine($"Firmware: {version["major"]}.{version["minor"]}.{version["patch"]}");
    Console.WriteLine($"Bluetooth version: {version["build"]}");

    // Get Bluetooth address
    var addrResponse = await device.SendCommandAsync("bt", "system", "get_identity_address");
    Console.WriteLine($"BT Address: {addrResponse["address"]}");
}
finally
{
    device.Close();
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Wait for Events

BGAPI is event-driven. After sending a command, you often need to wait for one or more events. CsharpBgapi provides EventSelector for this:

using CsharpBgapi;

var device = new BgapiDevice();
device.LoadDefaultXapis();
device.Open("COM3");

try
{
    // Start scanning for BLE advertisements
    await device.SendCommandAsync("bt", "scanner", "start",
        new Dictionary<string, object>
        {
            ["scanning_phy"] = 1,     // 1M PHY
            ["discover_mode"] = 2     // Discover all devices
        });

    // Wait for scan report events
    var selector = new EventSelector("bt", "scanner", "legacy_advertisement_report");
    var events = device.WaitEvents(selector, TimeSpan.FromSeconds(5), finalEventCount: 10);

    Console.WriteLine($"Found {events.Count} advertisements:");
    foreach (var evt in events)
    {
        Console.WriteLine($"  Address: {evt["address"]}, RSSI: {evt["rssi"]}");
    }

    // Stop scanning
    await device.SendCommandAsync("bt", "scanner", "stop");
}
finally
{
    device.Close();
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Retry Pattern for Reliable Communication

In Bluetooth Mesh, commands can fail due to network congestion. CsharpBgapi has a built-in retry mechanism:

var events = await device.RetryUntilAsync(
    command: () => device.SendCommandAsync("bt", "mesh", "vendor_model_send", parameters),
    eventSelector: new EventSelector("bt", "mesh", "vendor_model_receive"),
    retryParams: new RetryParams
    {
        RetryMax = 3,
        RetryInterval = TimeSpan.FromSeconds(2)
    },
    finalEventCount: 1
);
Enter fullscreen mode Exit fullscreen mode

This sends the command, waits for a matching event, and retries up to 3 times if it doesn't arrive.

Step 6: Using Dependency Injection

For production applications, CsharpBgapi integrates with .NET's dependency injection:

using CsharpBgapi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

// Register CsharpBgapi with custom options
builder.Services.AddCsharpBgapi(options =>
{
    options.ResponseTimeoutSeconds = 5.0;
    options.RetryMax = 10;
});

var host = builder.Build();
var device = host.Services.GetRequiredService<BgapiDevice>();
Enter fullscreen mode Exit fullscreen mode

Or bind from appsettings.json:

{
  "CsharpBgapi": {
    "DefaultBaudRate": 115200,
    "ResponseTimeoutSeconds": 5.0,
    "RetryMax": 10
  }
}
Enter fullscreen mode Exit fullscreen mode
builder.Services.Configure<CsharpBgapiOptions>(
    builder.Configuration.GetSection("CsharpBgapi"));
builder.Services.AddCsharpBgapi();
Enter fullscreen mode Exit fullscreen mode

Using Custom XAPI Files

The built-in XAPI files cover Bluetooth and Bluetooth Mesh from Gecko SDK v10.1.1. If you need a different version (to match your NCP firmware), load XAPI files manually:

var device = new BgapiDevice();
device.LoadXapi("/path/to/gecko_sdk/protocol/bluetooth/api/sl_bt.xapi");
device.LoadXapi("/path/to/gecko_sdk/protocol/bluetooth/api/sl_btmesh.xapi");
Enter fullscreen mode Exit fullscreen mode

How CsharpBgapi Compares to Alternatives

Library Protocol Hardware .NET Version Status
CsharpBgapi Modern BGAPI v3+ (XAPI) EFR32 series .NET 9.0+ Active
jrowberg/bglib Legacy Bluegiga BLED112/BLE112 .NET Framework Unmaintained (2021)
BgApiDriver Legacy Bluegiga BLED112/BLE112 .NET 6-9 Low activity
BGLib.NET Legacy Bluegiga BLED112/BLE112 .NET 5.0 Dead (2021)
pyBGAPI (Python) Modern BGAPI v3+ EFR32 series Python 3 Official, active

CsharpBgapi is the only C# library targeting the modern Silicon Labs BGAPI protocol. If you're using current EFR32 hardware, this is your option for .NET.

Get Started

dotnet add package CsharpBgapi
Enter fullscreen mode Exit fullscreen mode

Contributions and feedback welcome! Open an issue on GitHub if you run into any problems.


CsharpBgapi is developed by Lynxal and is not affiliated with Silicon Labs. XAPI definition files bundled with the package originate from the Silicon Labs Gecko SDK.

Top comments (0)