【问题标题】:Bluetooth Low Energy on Linux: Implement a GATT-ClientLinux 上的低功耗蓝牙:实现 GATT 客户端
【发布时间】:2018-01-29 13:52:52
【问题描述】:

我是低功耗蓝牙的新手,我正在尝试在 Linux 上构建自己的 C 程序,以连接低功耗蓝牙设备并与之交互。为此,我使用的是 Linux 蓝牙协议栈 Bluez。

阅读此博客 (https://www.jaredwolff.com/blog/get-started-with-bluetooth-low-energy/) 后,我可以通过命令行与我的设备进行连接和通信。但现在我坚持用我的代码来做这件事。我查看了 Gatttool 源文件,但我很难理解..

我尝试使用 gatt_connect(const char *src, const char *dst, const char *dst_type, const char *sec_l​​evel, int psm, int mtu, BtIOConnect connect_cb, GError **gerr),但我认为我传递给函数的参数有问题。

char dst[] = "XX:XX:XX:XX:XX:XX"; //device address
char dst_type = BDADDR_LE_RANDOM;
char sec_level = BT_IO_SEC_LOW;
GError *gerr;
BtIOConnect connect_cb; //Compiler says it´s uninitialized, but I don´t in what way I have how to initialize it 
GIOhannel *chan;

chan = gatt_connect(NULL, dst, &dst_type, &sec_level, 0, 0, connect_cb, &gerr); 

函数崩溃。我认为 connect_cb 函数指针有问题。但是在查看 Gattool 源代码后,我不知道如何修复它。

【问题讨论】:

  • 你试过使用调试器吗?
  • 是的。当使用给定参数调用 bt_io_connect 时,它会在 gatt_connect() 内部崩溃。但是调试器不能更深入地了解它。它说分段错误。

标签: c linux bluetooth-lowenergy gatt


【解决方案1】:

gatt_connect 的定义是:

GIOChannel *gatt_connect(const char *src, const char *dst,
            const char *dst_type, const char *sec_level,
            int psm, int mtu, BtIOConnect connect_cb,
            GError **gerr);

connect_cb 是连接时调用的回调函数 (typedef void (*BtIOConnect)(GIOChannel *io, GError *err, gpointer user_data);)。因为你有垃圾回调可能这就是它崩溃的原因!

以下是我正在使用的回调函数:

static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
    VVBOX_BLE_DEV_t *pdev = (VVBOX_BLE_DEV_t *)user_data;
    uint16_t mtu;
    uint16_t cid;

    if (err) {
        if (reply_to_listner) {
            mq_send_probe_ble_rsp(listener_id, 0, 5, "");
            reply_to_listner = 0;
        }
        printf("%s failed %s",__FUNCTION__, err->message);
        return;
    }

    bt_io_get(io, &err, BT_IO_OPT_IMTU, &mtu,
                BT_IO_OPT_CID, &cid, BT_IO_OPT_INVALID);

    if (err) {
        printf("%s Can't detect MTU, using default: %s", __FUNCTION__, err->message);
        g_error_free(err);
        mtu = ATT_DEFAULT_LE_MTU;
    }

    if (cid == ATT_CID)
        mtu = ATT_DEFAULT_LE_MTU;

    pdev->attrib = g_attrib_new(pdev->iochannel, mtu, false);
    printf("Connection successful\n");

    gatt_discover_primary(pdev->attrib, NULL, primary_all_cb, user_data);
    return;
}

【讨论】:

  • 好的,谢谢!有道理。我必须实现回调函数吗?您在哪里找到 gatt_connect 的定义?当我查看 gatttool.h 文件时,我只能看到 8 个参数。没有user_data..
  • 啊..我的错误是我在我的代码中修改了一点;),是的,需要 8 个!
  • 好的,我实现了回调函数并将其传递给 gatt_connect。现在看起来好多了,但仍然崩溃..我之前必须注册回调函数吗?
  • 没有 gatt_connect() 本身注册它。现在什么时候崩溃了?
  • 此时,内部gatt_connect:陈= bt_io_connect(connect_cb,NULL,NULL,&tmp_err,BT_IO_OPT_SOURCE_BDADDR,&SBA,BT_IO_OPT_SOURCE_TYPE,BDADDR_LE_PUBLIC,BT_IO_OPT_DEST_BDADDR,&DBA,BT_IO_OPT_DEST_TYPE,dest_type,BT_IO_OPT_CID,ATT_CID,BT_IO_OPT_SEC_LEVEL,仲, BT_IO_OPT_INVALID);
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 2015-03-11
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多