经典蓝牙
## 简介
经典蓝牙:模块蓝牙支持hfp和avrcp两种协议
hfp:HFP(Hands-freeProfile),让蓝牙设备可以控制电话,如接听、挂断、拒接、语音拨号等,拒接、语音拨号要视蓝牙耳机及电话是否支持。
avrcp:AVRCP定义了如何控制流媒体的特征。包括暂停、停止、启动重放、音量控制及其它类型的远程控制操作。
AVRCP定义了两个角色,即控制器和目标设备。控制器通常为远程控制设备,而目标设备为特征可以更改的设备。在AVRCP中,控制器将检测到的用户操作翻译为A/V控制信号,然后再将其传输至远程Bluetooth设备。
**可以通过模块经典蓝牙控制手机打电话,支持作为蓝牙音箱播放音频**
## API说明
以下API是模块经典蓝牙用到的接口,其余接口及具体接口参数说明和用法请到API说明章节和demo内查看并学习
| API接口 | 描述 |
| -------------------------------- | -------------------------------------- |
| btcore.open() | 打开蓝牙 |
| btcore.close() | 关闭蓝牙 |
| btcore.state() | 查询蓝牙状态(开启或者关闭) |
| btcore.setname() | 设置蓝牙名称 |
| btcore.setvisibility() | 经典蓝牙设置可见性 |
| btcore.getvisibility() | 获取蓝牙可见性 |
| btcore.sethfpvol() | 经典蓝牙设置HFP音量 |
| btcore.hfpcallanswer() | 经典蓝牙接听电话 |
| btcore.hfpcallreject() | 经典蓝牙拒接电话 |
| btcore.hfpcallhangup() | 经典蓝牙挂断电话 |
| btcore.hfpcallredial() | 经典蓝牙重拨电话 |
| btcore.hfpcalldial() | 经典蓝牙拨打电话 |
| btcore.setavrcpvol() | 经典蓝牙设置AVRCP音量 |
| btcore.getavrcpvol() | 经典蓝牙获取AVRCP音量 |
| btcore.setavrcpsongs() | 经典蓝牙设置AVRCP音乐播放的状态 |
经典蓝牙用到的蓝牙消息
| API接口 | 描述 |
| ------------------------- | -------------------------------------- |
| MSG_OPEN_CNF | 蓝牙打开成功 |
| MSG_CLOSE_CNF | 蓝牙关闭成功 |
| MSG_BT_HFP_CONNECT_IND | hfp连接成功 |
| MSG_BT_HFP_DISCONNECT_IND | hfp断开连接 |
| MSG_BT_HFP_CALLSETUP_OUTGOING | 建立呼出电话 |
| MSG_BT_HFP_CALLSETUP_INCOMING | 呼叫传入 |
| MSG_BT_HFP_RING_INDICATION | 呼叫传入铃声 |
| MSG_BT_AVRCP_CONNECT_IND | avrcp连接成功 |
| MSG_BT_AVRCP_DISCONNECT_IND | avrcp断开连接 |
> 详细的API介绍见[btcore API章节](https://doc.openluat.com/wiki/21?wiki_page_id=2244)
## 实现流程
- 注册蓝牙消息回调函数
通过rtos.on() 注册蓝牙消息回调函数
- 打开蓝牙
使用btcore.open(2)打开经典蓝牙
- 设置蓝牙名称
使用btcore.setname()蓝牙名称
- 设置蓝牙可见性
使用btcore.setvisibility()设置蓝牙可见性
- 等待被连接
- 连接成功后就可以使用hfp或avrcp控制接口实现不同的效果
hfp:设置hfp音量、拒接电话、挂断电话、重播电话、拨打电话
avrcp:设置音量、获取音量、播放、暂停、下一曲、上一曲
## 示例
以\script_LuaTask_V2.3.9\demo\bluetooth\bt.lua作为基础进行修改。
**首先使用rtos.on()注册蓝牙消息的回调处理函数。**
**初始化注册蓝牙消息回调函数**
```lua
local function init()
log.info("bt", "init")
call_state = 0
rtos.on(rtos.MSG_BLUETOOTH, function(msg)
if msg.event == btcore.MSG_OPEN_CNF then
sys.publish("BT_OPEN", msg.result) -- 蓝牙打开成功
elseif msg.event == btcore.MSG_CLOSE_CNF then
log.info("bt", "ble close") -- 蓝牙关闭成功
elseif msg.event == btcore.MSG_BT_AVRCP_CONNECT_IND then
sys.publish("BT_AVRCP_CONNECT_IND", msg.result) -- avrcp连接成功
log.info("bt", "bt avrcp connect", msg.result)
elseif msg.event == btcore.MSG_BT_AVRCP_DISCONNECT_IND then
log.info("bt", "bt avrcp disconnect") -- avrcp断开连接
elseif msg.event == btcore.MSG_BT_HFP_CONNECT_IND then
log.info("bt", "bt hfp connect", msg.result) --hfp连接成功
elseif msg.event == btcore.MSG_BT_HFP_DISCONNECT_IND then
log.info("bt", "bt hfp disconnect") --hfp断开连接
elseif msg.event == btcore.MSG_BT_HFP_CALLSETUP_OUTGOING then
log.info("bt", "bt call outgoing") --建立呼出电话
elseif msg.event == btcore.MSG_BT_HFP_CALLSETUP_INCOMING then
log.info("bt", "bt call incoming") --呼叫传入
elseif msg.event == btcore.MSG_BT_HFP_RING_INDICATION then
log.info("bt", "bt ring indication") --呼叫传入铃声
end
end)
end
```
**打开蓝牙**
```lua
local function poweron()
log.info("bt", "poweron")
btcore.open(2) --打开经典蓝牙
_, result = sys.waitUntil("BT_OPEN", 5000) --等待蓝牙打开成功
if result ~= 0 then --5秒超时没收到蓝牙打开成功的消息,则返回失败
return false
end
end
```
**设置蓝牙名称、蓝牙可见性、等待蓝牙连接**
```lua
local function setParam()
log.info("setparam")
btcore.setname("LuatOS-Air")
btcore.setvisibility(0x11)--设置蓝牙可见性 0x11表示可被发现、可被连接
log.info("bt", "bt visibility", btcore.getvisibility()) --获取蓝牙可见性
_, result = sys.waitUntil("BT_AVRCP_CONNECT_IND") --等待蓝牙连接成功
if result ~= 0 then
return false
end
end
```
**将以上代码放进task内运行**
```lua
sys.taskInit(
function()
sys.wait(5000) --此处延时是为了可以从luatools看到打印的日志
init()
poweron()
setParam()
end
)
```
将软件烧录进模块,打开手机蓝牙,就可以搜索到模块的蓝牙并连接,如下图所示:
**发现**

**手机端点击连接**

**连接成功**

接下来就可以打开音乐播放器播放音乐或控制手机来打电话
avrcp功能模块可以调用以下接口来控制音频的播放
| API接口 | 描述 |
| ------------------------- | -------------------------------------- |
| btcore.setavrcpsongs(0) | 暂停播放 |
| btcore.setavrcpsongs(1) | 开始播放 |
| btcore.setavrcpsongs(2) | 上一曲 |
| btcore.setavrcpsongs(3) | 下一曲 |
hfp功能模块可以调用以下接口来控制手机电话功能
| API接口 | 描述 |
| ------------------------- | -------------------------------------- |
| btcore.hfpcallanswer() | 经典蓝牙接听电话 |
| btcore.hfpcallreject() | 经典蓝牙拒接电话 |
| btcore.hfpcallhangup() | 经典蓝牙挂断电话 |
| btcore.hfpcallredial() | 经典蓝牙重拨电话 |
| btcore.hfpcalldial(number) | 经典蓝牙拨打电话 |
**调用经典蓝牙重播电话的接口,会拨打手机最近一次拨出去的电话**
**测试时不方便调用接口的话可以使用调试控制台**
只需要在main.lua里面将这两行代码打开,即可向模块的串口一发送接口调用

调用接口方法如下图所示,向串口1发送接口即可

[调试控制台详细用法请点我查看](https://hmi.wiki.luatos.com/doc/65042949/e6zPC3k9/onvc4862)