You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中获取LMP版本号?兼容C/C++实现方案

问题描述

我可以接受C/C实现方案,自行完成跨语言适配。目前已能在C中获取LMP Subversion(值为8207),但不知如何获取LMP版本(值为11)。需要通过编程方式获取该值,以此判断设备是否支持特定功能(如4.0及以上版本支持BLE)。我已花费大量时间搜索,仅能通过设备面板手动查看LMP值,未找到编程获取的相关资料。

基于@Mike Petrichenko评论与@Iłya Bursov回答的C#实现

列出支持功能的简易代码

namespace BluetoothInfoReader
{
internal class Program
{
static void Main(string[] args)
{
var features = Api.GetSupportedFeatures();

        foreach(HostFeature feature in Enum.GetValues(typeof(HostFeature)))
        {
            if (feature != HostFeature.None)
            {
                Console.WriteLine($"{feature}: {((features & feature) == feature)}");
            }
        }

        var info = Api.GetRadioInfo();
        // Any more info required can be gotten from "info"

        Console.ReadLine();
    }
}
}

配套结构体与枚举

namespace Bluetooth
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FindRadioParams
{
public FindRadioParams()
{
dwSize = (uint)Marshal.SizeOf();
}

    public uint dwSize;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DeviceInfo
{
    public uint flags;
    public ulong address;
    public uint classOfDevice;
    // 248 is the value of BTH_MAX_NAME_SIZE
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 248)]
    public string name;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct RadioInfo
{
    public ulong lmpSupportedFeatures;
    public ushort mfg;
    public ushort lmpSubversion;
    public byte lmpVersion;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct LocalRadioInfo
{
    public DeviceInfo localInfo;
    public uint flags;
    public ushort hciRevision;
    public byte hciVersion;
    public RadioInfo radioInfo;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Overlapped
{
    public ulong Internal;
    public ulong InternalHigh;
    public IntPtr Pointer;
    public IntPtr hEvent;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct HostFeatureMask
{
    public HostFeature Mask;
    public ulong Reserved1;
    public ulong Reserved2;
}

public enum HostFeature : ulong
{
    None                       = 0,
    EnhancedRetransmissionMode = (0x0000000000000001),
    StreamingMode              = (0x0000000000000002),
    LowEnergy                  = (0x0000000000000004),
    ScoHci                     = (0x0000000000000008),
    ScoHciBypass               = (0x0000000000000010)
}

public static class IoControl
{
    const int FILE_DEVICE_BLUETOOTH = 0x00000041;
    const int METHOD_BUFFERED = 0;
    const int FILE_ANY_ACCESS = 0;

    const int BTH_IOCTL_BASE = 0;

    private static uint CtlCodeCreator(ushort deviceType, ushort function, byte method, byte access)
    {
        uint result = (uint)((deviceType << 16) | (access << 14) | (function << 2) | method);

        return result;
    }

    private static uint BthCtlCodeCreator(ushort id)
    {
        return CtlCodeCreator((ushort)FILE_DEVICE_BLUETOOTH, id, (byte)METHOD_BUFFERED, (byte)FILE_ANY_ACCESS);
    }

    public static readonly uint GetLocalInfo = BthCtlCodeCreator(BTH_IOCTL_BASE + 0x00);
    public static readonly uint GetHostSupportedFeatures = BthCtlCodeCreator(BTH_IOCTL_BASE + 0x88);
}

public static class Api
{
    [DllImport("bthprops.cpl")]
    public static extern IntPtr BluetoothFindFirstRadio([In] ref FindRadioParams findRadioParams, [Out] out IntPtr hRadio);

    [DllImport("bthprops.cpl")]
    public static extern bool BluetoothFindNextRadio([In] IntPtr hFindHandle, [Out] out IntPtr hRadio);

    [DllImport("kernel32.dll")]
    public static extern bool CloseHandle(IntPtr handle);

    [DllImport("kernel32.dll")]
    public static extern bool DeviceIoControl([In] IntPtr hDevice, uint dwIoControlCode, [In] IntPtr inBuffer, uint nInBufferSize, [Out] IntPtr outBuffer, uint nOutBufferSize, [Out] out uint bytesReturned, [In, Out] ref Bluetooth.Overlapped overlapped);

    public static bool DeviceIoControl<T>([In] IntPtr hDevice, uint dwIoControlCode, [In] IntPtr inBuffer, uint nInBufferSize, [Out] out T outBuffer) where T : struct
    {
        int size = Marshal.SizeOf<T>();
        IntPtr buffer = Marshal.AllocHGlobal(size);
        Overlapped overlapped = new Overlapped();
        var result = DeviceIoControl(hDevice, dwIoControlCode, inBuffer, nInBufferSize, buffer, (uint)size, out uint bytesReturned, ref overlapped);

        if (bytesReturned != size)
        {
            // Houston we have a problem.
        }

        outBuffer = Marshal.PtrToStructure<T>(buffer);

        return result;
    }

    public static HostFeature GetSupportedFeatures()
    {
        HostFeature result = HostFeature.None;
        FindRadioParams findParams = new FindRadioParams();
        var findHandle = BluetoothFindFirstRadio(ref findParams, out IntPtr radioHandle);

        if (findHandle != IntPtr.Zero)
        {
            do
            {
                if (DeviceIoControl(radioHandle, IoControl.GetHostSupportedFeatures, IntPtr.Zero, 0, out Bluetooth.HostFeatureMask features))
                {
                    result = features.Mask;
                    break;
                }

            } while (BluetoothFindNextRadio(findHandle, out radioHandle));

            CloseHandle(radioHandle);
        }

        return result;
    }

    public static LocalRadioInfo GetRadioInfo()
    {
        LocalRadioInfo result = new LocalRadioInfo();
        FindRadioParams findParams = new FindRadioParams();
        var findHandle = BluetoothFindFirstRadio(ref findParams, out IntPtr radioHandle);

        if (findHandle != IntPtr.Zero)
        {
            do
            {
                if (DeviceIoControl(radioHandle, IoControl.GetLocalInfo, IntPtr.Zero, 0, out result))
                {
                    break;
                }

            } while (BluetoothFindNextRadio(findHandle, out radioHandle));

            CloseHandle(radioHandle);
        }

        return result;
    }
}
}

内容的提问来源于stack exchange,提问作者K.Lawrence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:29:56