如何利用Trace机制实现LLCP预览功能

描述

在蓝牙协议栈开发过程中,有时需要预先知道 LLCP。本文将介绍如何利用 Trace 机制实现 LLCP 预览功能。

实现原理

打开 Trace PLATFORM_TRACE_ID_LLCP 类型,Controller 会在接收到 LLCP 时通过 Trace 回调函数导出数据。 我们可以在回调函数里截获 PLATFORM_TRACE_ID_LLCP,并预览数据。这个的“预览”包含两层含义:

Controller 尚未处理该 PDU(Controller 将于 Trace 回调完成后处理 PDU);

只可读取 PDU 内容,不可修改。

让我们详细介绍实现方法。

1.Trace数据结构

PLATFORM_TRACE_ID_LLCP Trace 类型使用的头信息结构如下:

 

#pragma pack (push, 1)
typedef struct
{
    uint32_t A;
    uint32_t B;
    uint8_t  id;
    uint8_t  tag;
} header_t;
#pragma pack (pop)

 

这个结构使用 #pragma pack (push, 1) 指令确保内存对齐。

2.Trace回调处理

假设cb_trace_read_llcp函数为 Trace 回调函数,在函数开头添加代码截获接收到的 LLCP:

 

static uint32_t cb_trace_read_llcp(const platform_evt_trace_t *Trace, void *ctx)
{
    if (Trace->len1 == sizeof(header_t))
    {
        const header_t *p = (const header_t *)Trace->data1;
        if ((p->id == PLATFORM_TRACE_ID_LLCP) && (p->tag & 1))
        {
            const uint8_t *p8 = (const uint8_t *)Trace->data2;
            llcp_preview(p->tag >> 1, p8[0], p8 + 1, Trace->len2 - 1);
        }
    }
    // ...
    return 0;
}
3.PUD预览显示

 

llcp_preview 函数负责预览 LLCP。下面的参考代码打印了关于 LLCP 的完整信息:

连接句柄(handle)

操作码(op_code)

控制数据

 

static void llcp_preview(hci_con_handle_t handle, uint8_t op_code, const uint8_t *ctr_data, int ctr_data_len)
{
    platform_printf("LLCP[%d] OP %02x: ", handle, op_code);
    printf_hexdump(ctr_data, ctr_data_len);
    platform_printf("
");
}
    

 

特殊用法

目前 SDK 未提供设置公司 ID 的接口,暂时可以通过直接修改 LLCP_VERSION_IND 内容的方法修改公司 ID(修改这个值不影响 Controller 的行为和流程。) 在下面的代码里,公司 ID 被修改为 0xABCD,小版本号被修改为 0x1234。

 

#pragma pack (push, 1)
typedef struct
{
    uint8_t  version;
    uint16_t company_id;
    uint16_t subversion;
} llcp_version_ind_t;
#pragma pack (pop)
static uint32_t cb_trace_read_llcp(const platform_evt_trace_t *trace, void *ctx)
{
    if (trace->len1 == sizeof(header_t))
    {
        const header_t *p = (const header_t *)trace->data1;
        // 判断是否为发送方向的 LLCP
        if ((p->id == PLATFORM_TRACE_ID_LLCP) && (0 == (p->tag & 1)))
        {
            const uint8_t *p8 = (const uint8_t *)trace->data2;
            const uint16_t con_handle = p->tag >> 1;
            const uint8_t  op_code    = p8[0];
            const int ctrl_data_len   = trace->len2 - 1;
            uint8_t * ctrl_data       = (uint8_t *)p8 + 1;
            // 判断是否为 LLCP_VERSION_IND
            if ((op_code == 0x0c) && (ctrl_data_len == sizeof(llcp_version_ind_t)))
            {
                llcp_version_ind_t *ver_ind = (llcp_version_ind_t *)(ctrl_data);
                ver_ind->company_id = 0xABCD;
                ver_ind->subversion = 0x1234;
            }
        }
    }
    // ...
    return 0;
}
   

 

总结

利用 Trace 机制实现的 PDU 预览功能,能帮助开发者实时监控 LLCP 通信,实现必要功能。

温馨提示:不要忘记设置 PLATFORM_CFG_TRACE_MASK,其中要包含 PLATFORM_TRACE_ID_LLCP。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分