标准的linux系统一般都不带ble的应用功能,需要客户自己自定义开发,不过一般可以采用开源的bluez架构,目前最新的已经到5.5版本了,我用的5.4版本。

Linux 系统ble功能开发

里面包含了bt的各种应用场景,可以作为bt设备,以及ble主设备和从设备功能 ,而我们项目需要将linux系统作为一个ble从设备,所以需要使用peripheral这个文件夹。

attach.c  attach.h  efivars.c  efivars.h  gap.c  gap.h  gatt.c  gatt.h  log.c  log.h  main.c

代码逻辑可以从main.c开始分析, 找到其中的gap_start函数。

void gap_start(void)
{
    mgmt = mgmt_new_default();
    if (!mgmt) {
        fprintf(stderr, "Failed to open management socket\n");
        return;
    }

    if (!mgmt_send(mgmt, MGMT_OP_READ_COMMANDS,
                MGMT_INDEX_NONE, 0, NULL,
                read_commands_complete, NULL, NULL)) {
        fprintf(stderr, "Failed to read supported commands\n");
        return;
    }
}

在这个read_commands_complete函数中找到index_added_event函数,然后进入到read_info_complete函数,在这里会初始化ble的各种配置信息,包括BD地址,以及设备初始化名称。还有其中最为关键的gatt_server_start();

void gatt_server_start(void)
{
    struct sockaddr_l2 addr;

    if (att_fd >= 0)
        return;

    att_fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_CLOEXEC,
                            BTPROTO_L2CAP);
    if (att_fd < 0) {
        fprintf(stderr, "Failed to create ATT server socket: %m\n");
        return;
    }

    memset(&addr, 0, sizeof(addr));
    addr.l2_family = AF_BLUETOOTH;
    addr.l2_cid = htobs(ATT_CID);
    memcpy(&addr.l2_bdaddr, static_addr, 6);
    addr.l2_bdaddr_type = BDADDR_LE_RANDOM;

    if (bind(att_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        fprintf(stderr, "Failed to bind ATT server socket: %m\n");
        close(att_fd);
        att_fd = -1;
        return;
    }

    if (listen(att_fd, 1) < 0) {
        fprintf(stderr, "Failed to listen on ATT server socket: %m\n");
        close(att_fd);
        att_fd = -1;
        return;
    }

    gatt_db = gatt_db_new();
    if (!gatt_db) {
        close(att_fd);
        att_fd = -1;
        return;
    }

    populate_gap_service(gatt_db);
    populate_devinfo_service(gatt_db);

    gatt_cache = gatt_db_new();

    conn_list = queue_new();
    if (!conn_list) {
        gatt_db_unref(gatt_db);
        gatt_db = NULL;
        close(att_fd);
        att_fd = -1;
        return;
    }

    mainloop_add_fd(att_fd, EPOLLIN, att_conn_callback, NULL, NULL);
}

这里会初始化gap 以及device的service服务。这些service里配置了ble从设备需要对外发送的信息。

static void populate_gap_service(struct gatt_db *db)
{
    struct gatt_db_attribute *service;
    bt_uuid_t uuid;

    bt_uuid16_create(&uuid, UUID_GAP);
    service = gatt_db_add_service(db, &uuid, true, 6);

    bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
    gatt_db_service_add_characteristic(service, &uuid,
                    BT_ATT_PERM_READ,
                    BT_GATT_CHRC_PROP_READ,
                    gap_device_name_read, NULL, NULL);

    gatt_db_service_set_active(service, true);
}

bluez-5.41  CMakeLists.txt  src
源代码通过cmake管理,下载路径://download.csdn.net/download/punmpkin/12064879

源码解压之后路径,执行cmake即可,最终生成一个ble_emulator的bin文件,在执行这个bin文件以前需要先将ble功能打开。

需要执行ble_setup.sh脚本,内容如下

# bring up bluetooth
echo 0 > /sys/class/rfkill/rfkill2/state
echo 1 > /sys/class/rfkill/rfkill2/state
brcm_patchram_plus -d --enable_hci --no2bytes --tosleep 200000 --baudrate 3000000 --patchram /lib/firmware/bcm/APM_BCM43456/bcmdhd.hcd /dev/ttymxc2 &
sleep 25
rfkill unblock bluetooth
hciconfig hci0 up
/usr/libexec/bluetooth/bluetoothd --experimental start &

执行这个bin文件,然后在手机设置界面搜索这个ble设备,并点击配对,配对完成之后打开ble 的app,就可以在app里查看信息以及发送数据了。

Linux 系统ble功能开发

Linux 系统ble功能开发

 

 

相关文章:

  • 2022-01-19
  • 2022-12-23
  • 2021-10-22
  • 2022-01-04
  • 2021-12-03
  • 2021-11-29
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-11-17
  • 2021-10-02
  • 2022-01-15
  • 2021-11-17
  • 2021-11-29
相关资源
相似解决方案