ZBLOG

bluez 被连接端示例代码

以下是使用 BlueZ(Linux Bluetooth 协议栈)作为被连接端(Server/Peripheral)的示例代码,基于 C 语言DBus API 实现。


1. 前置条件

  • 确保系统已安装 bluezdbus 开发库:
    
    sudo apt-get install libbluetooth-dev libdbus-1-dev
    
  • BlueZ 服务需正常运行:
    
    sudo systemctl start bluetooth
    

2. DBus GATT Server 示例代码

以下是一个简单的 GATT Server,提供一个可读写的特征(Characteristic):

代码 (gatt_server.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <glib.h>
#include <gio/gio.h>

// DBus BlueZ接口路径
#define ADAPTER_PATH "/org/bluez/hci0"
#define SERVICE_PATH "/org/bluez/example/service"
#define CHARACTERISTIC_PATH "/org/bluez/example/service/char1"

static GMainLoop *loop;
static GDBusConnection *conn;

// Characteristic的值(模拟数据)
static char char_value[20] = "Hello BLE";

// DBus方法调用处理:读取特征值
static gboolean handle_read_value(
    GDBusConnection *connection,
    const gchar *sender,
    const gchar *object_path,
    const gchar *interface_name,
    const gchar *method_name,
    GVariant *parameters,
    GDBusMethodInvocation *invocation,
    gpointer user_data) {

    printf("Read request received\n");
    
    // 返回当前特征值(格式:"ay"表示字节数组)
    GVariant *value = g_variant_new_fixed_array(
        G_VARIANT_TYPE_BYTE, 
        char_value, 
        strlen(char_value), 
        sizeof(char));

    g_dbus_method_invocation_return_value(invocation, g_variant_new("(ay)", value));
    
return TRUE;
}

// DBus方法调用处理:写入特征值
static gboolean handle_write_value(
    GDBusConnection *connection,
    const gchar *sender,
    const gchar *object_path,
    const gchar *interface_name,
    const gchar *method_name,
GVariant* parameters,  
GDBusMethodInvocation* invocation,  
gpointer user_data) {  

printf("Write request received\n");  

//解析写入的数据(格式:"ay"表示字节数组)  
GVariantIter* iter;  
g_variant_get(parameters,"(@ay)", &iter);  

gsize len=0;  
const guint8* data=g_variant_get_fixed_array(iter,&len,sizeof(guint8));  

memcpy(char_value,data,len);  
printf("New value: %s\n", char_value);  

g_dbus_method_invocation_return_value(invocation,NULL);  
return TRUE;  
}  

int main() {  
GError* error=NULL;  

//初始化主循环  
loop=g_main_loop_new(NULL,FALSE);  

//连接到系统总线(System Bus)  
conn=g_bus_get_sync(G_BUS_TYPE_SYSTEM,NULL,&error);  
if(error){fprintf(stderr,"Failed to connect to DBus:%s\n",error->message);exit(1);}  

//注册Service和Characteristic到BlueZ (通过DBus)   
{   
/* Service */   
GVariantBuilder service_builder;   
g_variant_builder_init(&service_builder,G_VARIANT_TYPE_ARRAY);   

g_variant_builder_add(&service_builder,"{sv}","UUID",g_variant_new_string("0000180a-0000-1000-8000-00805f9b34fb")); //自定义UUID   
g_variant_builder_add(&service_builder,"{sv}","Primary",g_variant_new_boolean(TRUE));   

/* Characteristic */   
GVariantBuilder char_builder;   
g_variant_builder_init(&char_builder,G_VARIANT_TYPE_ARRAY);   

g_variant_builder_add(&char_builder,"{sv}","UUID",g_variant_new_string("00002a57-0000-1000-8000-00805f9b34fb")); //自定义UUID   
g_variant_builder_add(&char_builder,"{sv}","Flags",g_variant_new_strv((const char*[]){"read","write"},2));   

//发布Service和Characteristic到BlueZ (简化版,实际需更多步骤)   
if(!g_dbus_connection_register_object(conn,SERVICE_PATH,g_dbus_node_info_lookup_interface(),NULL,NULL,&error)){fprintf(stderr,"Failed to register service:%s\n",error->message);exit(1);}   

if(!g_dbus_connection_register_object(conn,CHARACTERISTIC_PATH,g_dbus_node_info_lookup_interface(),handle_read_value,handle_write_value,&error)){fprintf(stderr,"Failed to register characteristic:%s\n",error->message);exit(1);} } 

printf("BLE GATT Server running...\n"); 

//运行主循环 (等待连接) 
signal(SIGINT,signal_handler);//捕获Ctrl+C退出信号 
main_loop_run(); 

cleanup(); return0;} 

void signal_handler(int sig){ if(sig==SIGINT){ printf("\nStopping server...\n"); if(main_loop_is_running())main_quit();}} 

void cleanup(){ if(main_loop_is_running())main_quit(); if(object_registered)g_dbus_unregister_all(); if(dbus_con)g_object_unref(dbus_con);}

3.关键说明

  1. UUID定义:

    • Service UUID和Characteristic UUID需符合蓝牙标准或自定义格式。
    • 示例中使用了通用UUID (180A为设备信息服务)。
  2. 权限控制:

    • Flags字段指定特征的属性(如readwritenotify)。
  3. 运行方式: “`bash #编译并运行 ./ble_gatt_server

  4. 客户端连接测试: -使用工具如 bluetoothctl, gatttool,或手机APP (例如 nRF Connect)。


###4.Python简化版 (基于PyBluez) 若需快速验证,可用Python实现简单服务端:

from bluetooth import *

server_sock=BluetoothSocket(RFCOMM)
server_sock.bind(("00:11:22:33:44:55",PORT_ANY))
server_sock.listen()

client_sock.addr=server_sock.accept()
print(f"Connected to {addr}")
data=client_sock.recv(1024)
print(f"Received:{data}")
client.close()

###5.BlueZ官方推荐方式* 生产环境建议使用官方推荐的 bluetoothd + D-Bus API ,而非直接操作Socket。

需要更详细的特性实现吗?比如通知(Notify)、多服务等?


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24003

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?