搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
小丑西瓜9
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
《java入门基础》读书笔记_写一篇传智播客2014年在清华大学出版社出版的《java基础入门》的读书笔记
2
【Windows】SecureCRT v9.2.3永久使用教程亲测可用_sshd 9.2 secrtcrt
3
软件测试c语言代码_经验分享丨软件测试面试经历之幽默篇
4
LORA开发板采集温湿度数据,连接PC上位机显示和液晶屏显示_lora模块上位机
5
数据结构循环队列C++实现_定义循环队列类,设计循环队列类中的数据成员和成员函数,成员函数实现对循环
6
如何运用git从github上下载别人的项目_下载github项目
7
git 安装到使用 (git获取远程仓库代码、上传代码)+ git常见使用命令100条_git 代码仓库
8
安装ms sql server2000提示安装失败详见sqlstp.log日志
9
2022年新一代kaldi团队技术输出盘点_zipformer
10
才知道java竟然没有运算符重载_java map有重载运算符吗
当前位置:
article
> 正文
基于BlueZ的C语言蓝牙编程_c语言实现ble蓝牙通信
作者:小丑西瓜9 | 2024-04-25 06:30:31
赞
踩
c语言实现ble蓝牙通信
基于BlueZ的C语言蓝牙编程
原文出处:
[url=http://people.csail.mit.edu/albert/bluez-intro/c401.html][color=#0000ff]http://people.csail.mit.edu/albert/bluez-intro/c401.html[/color][/url]
第四章 基于BlueZ的C语言蓝牙编程
有很多理由促使我们选用C替代其他高级语言来例如Python来开发蓝牙应用程序。Python环境可能并不适合于嵌入式系统。因为嵌入式系统对程序的大 小,运行速度,和占用的存储空间有严格的限制,这些都使得像Python之类的解释性语言无法在嵌入式系统上应用。程序员需要对本地的蓝牙适配器进行更好 的控制,或者需要建立一套动态链接库以便于其他应用程序的链接以取代单一的应用程序。就像上述描述的这些,BlueZ是一款强大的蓝牙通信协议栈,它扩展 的API使得用户方便操纵大量的蓝牙资源。但是BlueZ没有官方的描述文档,甚至非官方的文档也寥寥无几。初学者在BlueZ的官方邮件列表上请求相关 的文档,通常的得到的回复是被告知请通过仔细阅读源代码来了解API的功能。阅读BlueZ的源代码对于初学者来说是一项相当费时的
[url=javascript:;][u][b][color=#0000ff]工作[/color][/b][/u][/url]
,在短期内取得的进展是相当有限的,很可能成为很多蓝牙编程初学者的拦路虎。
本章简要叙述了基于BlueZ的C语言蓝牙编程的方法。本章为C程序员进一步阐述了第二章中涉及的知识点。
4.1 选择一个通信的对象
Example 4-1是一个查找周边蓝牙设备的简单应用程序。程序首先获取系统的蓝牙设备号,扫描周边的蓝牙设备,然后查找每一个被搜索到的蓝牙设备的名称。后边有对数据结构和函数的详细描述。
Example 4-1. simplescan.c
#include stdio.h>
#include stdlib.h>
#include unistd.h>
#include sys/socket.h>
#include bluetooth/bluetooth.h>
#include bluetooth/hci.h>
#include bluetooth/hci_lib.h>
int main(int argc, char **argv)
{
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id 0 || sock 0) {
perror("opening socket");
exit(1);
}
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
if( num_rsp 0 ) perror("hci_inquiry");
for (i = 0; i num_rsp; i++) {
ba2str(&(ii+i)->bdaddr, addr);
memset(name, 0, sizeof(name));
if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
name, 0) 0)
strcpy(name, "[unknown]");
printf("%s %s/n", addr, name);
}
free( ii );
close( sock );
return 0;
}
4.1.1 编译
编译需要使用gcc链接libbluetooth这个库。
gcc -o simplescan simplescan.c -lbluetooth
4.1.2. 解释
typedef struct {
uint8_t b[6];
} __attribute__((packed)) bdaddr_t;
蓝牙设备的地址采用结构体bdaddr_t来描述,BlueZ中队蓝牙地址的存储和操纵都使用bdaddr_t结构体,BlueZ提供两个函数来进行字符串到蓝牙地址的转换。
int str2ba( const char *str, bdaddr_t *ba );
int ba2str( const bdaddr_t *ba, char *str );
str2ba把形如XX:XX:XX:XX:XX:XX(XX标识48位蓝牙地址的16进制的一个字节)的字符串转化6字节的bdaddr_t结构, ba2str完成相反的功能。
本地蓝牙适配器被分配一个从0开始的识别号码。程序在分配系统资源时必须指定使用那一个蓝牙适配器,通常的话系统只有一个蓝牙适配器,把参数NULL传给hci_get_route可以获得第一个有效的蓝牙适配器识别号。
int hci_get_route( bdaddr_t *bdaddr );
int hci_open_dev( int dev_id );
[note]将适配器的设备号指定为0是不恰当的,因为它并不总代表第一个可用的蓝牙适配器。例如系统有两个蓝牙适配器,第一个被disable掉了,那么第一个有效的设备号就是2。
如果存在多个蓝牙适配器,选择"01:23:45:67:89:AB"作为蓝牙适配器的地址, 将指示这个地址的指针char *representation传给hci_devid函数,用这个函数替代hci_get_route。
很多蓝牙操作都需要打开一个套接口, hci_open_dev函数可以打开特定资源号的一个套接口,确切的说hci_open_dev打开的套接字建立了一条和本地蓝牙适配器控制器的连接, 而不是和远端蓝牙设备的连接。使用这个套接口发送命令到蓝牙控制器可以实现底层的蓝牙操作,这部分在4.5中有详细的讨论。
选择好本地蓝牙适配器并进行系统资源分配后,程序就可以开始扫描周边的蓝牙设备了,在这个例程中,hci_inquiry函数完成对蓝牙设备的搜寻,并将返回的设备信息数据记录在变量ii中。遇到错误时,它将返回-1并设置errno变量。
int hci_inquiry(int dev_id, int len, int max_rsp, const uint8_t *lap, inquiry_info **ii, long flags);
hci_inquiry 的参数需要使用设备资源号而非套接口,所以我们使用hci_get_route函数的返回值dev_id传递给它。查询时间最长持续1.28 * len秒。max_rsp个设别返回的信息都被存储在变量ii中,这个变量必须有足够的空间来存储max_rsp返回的结果。我们推荐max_rsp取值 255来完成标准10.24秒的查询工作。
如果标志位flag设置为IREQ_CACHE_FLUSH,那么在进行查询操作时会把先前一次查询记录的cache刷新,否则flag设置为0的话,即便先前查询的设备已经不处于有效范围内,先前查询的记录也将被返回。
inquiry_info结构体定义如下
typedef struct {
bdaddr_t bdaddr;
uint8_t pscan_rep_mode;
uint8_t pscan_period_mode;
uint8_t pscan_mode;
uint8_t dev_class[3];
uint16_t clock_offset;
} __attribute__ ((packed)) inquiry_info;
在大多数场合,我们仅用到成员bdaddr,它标识了设备的蓝牙地址。有些场合我们也会用到成员dev_class, 它标识了被检测到的蓝牙设备的一些信息(例如,识别这个设备是打印设备,电话,个人电脑等),详细地对应关系可以参见蓝牙设备分配号[3]。其余的成员在 用于底层通信,一般情况并不常用。感兴趣的读者可以阅读蓝牙内核规范[4]获取更多的信息。一旦周围的蓝牙设备和其蓝牙地址被检测到,程序可以将此设备的 名称提供给用户,hci_read_remote_name函数可以完成这个功能。
int hci_read_remote_name(int sock, const bdaddr_t *ba, int len,
char *name, int timeout)
hci_read_remote_name函数在规定的超时时间内使用套接口通过蓝牙地址ba去获取蓝牙设备的名称,成功返回0,并将获取的蓝牙设备名称存入name中;失败时返回-1并设置相应的errno。
Notes
[1]
[url=http://www.bluez.org/lists.html][color=#0000ff]http://www.bluez.org/lists.html[/color][/url]
[2] for the curious, it makes a call to socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI), followed by a call to bind with the specified resource number.
[3]
[url=https://www.bluetooth.org/foundry/assignnumb/document/baseband][color=#0000ff]https://www.bluetooth.org/foundry/assignnumb/document/baseband[/color][/url]
[4]
[url=http://www.bluetooth.org/spec][color=#0000ff]http://www.bluetooth.org/spec[/color][/url]
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/小丑西瓜9/article/detail/483745
推荐阅读
article
科技巨头投向生成式AI,解读
人工智能
在
安防
领域
的
应用
_ai
技术
在
安防
行业
的
应用
...
随着云计算和边缘计算
的
融合,
安防
系统可以实现更快、更高效
的
服务。数字孪生
技术
作为实时模拟现实世界场景
的
虚拟模型,也为
安防
...
赞
踩
article
Vivado
用
ILA
抓波形保存为
CSV
文件
_
ila
导出
csv
数据
...
将
ILA
观察到的波形
数据
捕获为
CSV
文件
,抓10次,把
文件
合并,把源
文件
删除。运行方法:
Vivado
的 Tcl cons...
赞
踩
article
【
Git
教程】(六)
分支
合并
——
合并
过程
,
各类
合并
冲突
及
解决
思路 ~_
合并
分支
...
合并
:所谓
合并
就是对相关提交图中的
分支
执行
合并
操作。
合并
提交:执行merge命令的结果就是产生一次
合并
提交。3路
合并
:G...
赞
踩
article
【
ChatGPT4
】 NLP(
自然语言
处理
)第六课
基于
统计
和
基于
深度学习的依存
句法分析
方法_
基于
统...
例如:“我(主语)的(助词)朋友(名词),小明(同位词),来(动词)了(助词)。例如:“(主语)[(连词)做(动词)好事...
赞
踩
article
RabbitMQ
和SpringBoot整合之填坑
com
.
rabbitmq
.
client
.Shutd...
1.自己手动到
RabbitMQ
里面创建相关的交换机,队列,绑定关系。追踪问题根源是,队列,交换机,绑定这些都不存在,所以...
赞
踩
article
jmeter
压测
学习12-
设置
持续
压测
时间
(
调度
器的使用)_
jmeter
调度
器
设置
持续
30
0
秒
结果3...
前言使用
jmeter
做
压测
的时候,希望对一个接口
持续
压测
10 分钟或者半小时,可以使用
调度
器
设置
持续
压测
时间
。
设置
样...
赞
踩
article
08.
mongo
db
数据
的增删改查_
use
db
08
数据
库
...
查看所有
数据
库
列表show
db
s创建一个
数据
库
use
test
use
命令用于创建或者切换一个
数据
库
。如果没有这个
数据
库
...
赞
踩
article
【
NumPy
】一文详细介绍
np
.
zeros
_
like
...
np
.
zeros
_
like
【
NumPy
】一文详细介绍
np
.z...
赞
踩
article
7
寸
显示器
树莓
派
4b_
树莓
派
7
寸
触摸屏
安装指南...
最近为我的
树莓
派
( Raspberry Pi )购置了一台官方的
7
英寸
触摸屏
,现在把使用过程整理了一下,向需要的朋友展示...
赞
踩
article
linux
常用命令
git
面试
,
Linux
常用命令
总结,大厂
面试
必备...
Linux
是很多人走进计算机行业的敲门砖,同时也是
面试
官最喜欢问的知识点。但
Linux
中的命令较多,且单个命令的参...
赞
踩
article
Linux
网络
性能评估工具
iperf
、
CHARIOT
测试
网络
吞吐量_
ixchariot
linux
...
在完成
iperf
安装后,执行“
iperf
3 –h”即可显示
iperf
的详细用法。
iperf
的命令行选项共分为三类,分别是...
赞
踩
article
Android
跨
进程
通信...
Android
中常用的跨
进程
通信方法有以下几种:Intent、Binder、AIDL、Messenger、Content...
赞
踩
article
FusionCompute
安装
和配置
步骤
_
fusioncomputer
安装
详细
步骤
...
FusionCopute
安装
配置
步骤
_
fusioncomputer
安装
详细
步骤
fusioncomputer
安装
详细
步骤
...
赞
踩
article
nlp 分词 构建词表_
python
中_
for
_
in
vocab
_
dic
.
items
() if...
MAX_VOCAB_SIZE = 10000UNK, PAD = '
', '
'def build_v...
赞
踩
article
(五)
Python
中第三方常用库(
webbrower
、
pyautogui
、
smtplib
、
xlwt
、...
使用
Python
的
smtplib
库,可以连接到SMTP服务器,并发送邮件。
xlrd
是一个用于读取Excel文件的Pyth...
赞
踩
article
华为
云
向前推进
的
底气
何在?...
“未来,各行各业
的
数字化转型将把人类带入智能社会,创新将是这场变革
的
驱动力,
云
上会出现越来越多
的
综合创新,
云
也需要综合实...
赞
踩
article
rust
设置国内
镜像
_
rust
镜像
...
rust
国内
镜像
_
rust
镜像
rust
镜像
rust
up、c...
赞
踩
article
Flink
随笔(二)
SqlClient
的配置和使用_
flink
sql
-
client
...
Flink
SQL Client
Flink
’s Table & SQL API makes it possible to...
赞
踩
article
纯
C++
自动识别
设备串口...
【代码】纯
C++
自动识别
设备串口。纯
C++
自动识别
设备串口 /...
赞
踩
article
AIX
系统
网络
性能
分析(转)...
AIX
系统
网络
性能
分析(转)[@more@]【导读】出现
性能
问题的时候,您的
系统
可能一点过失也没有,而真正的故障原因却是...
赞
踩
相关标签
科技
人工智能
音视频
视频联网
算法
fpga开发
git
大数据
分布式
自动化
java
开发语言
自然语言处理
python
java-rabbitmq
rabbitmq
spring boot
node.js
机器学习
新手入门
学习
7寸显示器 树莓派4b
linux常用命令git面试
网络