通过 qca4531 实现蓝牙 mesh 网关开发指南

网关概述

该网关产品是基于高通 qca4531 以及 csr8811 芯片上开发的蓝牙 mesh 网关产品。高通 qca4531 运行 Openwrt 系统,通过 3 线 PTA 与 csr8811 通信。用户可以通过以下三种方式控制蓝牙 mesh 中的设备。

  • 蓝牙通道

    顾名思义,用户可以直接用手机蓝牙功能直接对设备进行控制,不需要通过其他网络。

  • 网关通道

    通过局域网来控制蓝牙 mesh 网络中的设备。

  • 云服务通道

    通过云平台网络来控制蓝牙 mesh 网络中的设备,该场景适合于用户外出等场景。目前该云平台是使用 csr 的测试云平台,网络不太稳定,以后可以通过实现自有的 north bound 代码实现自由云平台切换。

    高通提供相应的 app 代码以及 demo 供用户开发以及测试。

开发工具

开发过程中,有时我们会需要使用些工具帮助我们加快开发,定位问题。开发该网关产品我们需要:

  • USB TTL 线

    系统打印信息以及系统日志查看等。

  • android 或 ios app

    通过 app 可以实现控制蓝牙 mesh 网中的蓝牙设备。

  • 支持蓝牙 mesh bridge 的设备

    加入蓝牙 mesh 网络的设备。

开发环境搭建

网关关联到网络

由于目前该平台许多方面还没完善,会有些 bugs 存在,所以有些是我们必须要操作是需要手动进行的。
网关开机时,我们通过网关串口看到些信息打印,由于系统开机后,许多工作要做,比如启动些 south bound 以及 north bound 的任务,我们通过命令看到 csrservicesd 以及 csrMeshGw 任务已经运行,我们才可以进行下面的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
root@OpenWrt:/# ps
PID USER VSZ STAT COMMAND
1 root 1324 S /sbin/procd
2 root 0 SW [kthreadd]
3 root 0 SW [ksoftirqd/0]
4 root 0 SW [kworker/0:0]
5 root 0 SW< [kworker/0:0H]
6 root 0 SW [kworker/u2:0]
7 root 0 SW< [khelper]
60 root 0 SW< [writeback]
62 root 0 SW< [bioset]
64 root 0 SW< [kblockd]
98 root 0 SW [kswapd0]
145 root 0 SW [fsnotify_mark]
151 root 0 SW< [crypto]
173 root 0 SW [spi0]
265 root 0 SW< [deferwq]
273 root 0 SW [ubi_bgt0d]
289 root 0 SW [kworker/0:2]
320 root 0 SW [khubd]
336 root 0 SW [kworker/u2:2]
349 root 0 SWN [jffs2_gcd_mtd9]
418 root 884 S /sbin/ubusd
419 root 1368 S /bin/ash --login
763 root 0 SW< [ipv6_addrconf]
834 root 0 SW< [krfcommd]
863 root 0 SW< [cfg80211]
954 root 1288 S /sbin/logd -S 16
984 root 1480 S /sbin/netifd
998 root 1156 S /usr/sbin/odhcpd
1033 root 1100 S /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p
1076 root 1504 S /usr/sbin/uhttpd -f -h /www -r OpenWrt -x /cgi-bin -
1085 root 1492 S /usr/sbin/dbus-daemon --system
1098 root 3224 S /usr/bin/bluetoothd
1220 root 1368 S udhcpc -p /var/run/udhcpc-eth0.pid -s /lib/netifd/dh
1284 nobody 10088 S /usr/bin/alljoyn-daemon --config-file=/etc/alljoyn/a
1304 root 2296 S /usr/sbin/hostapd -P /var/run/wifi-phy0.pid -B /var/
1313 root 804 S odhcp6c -s /lib/netifd/dhcpv6.script -P0 eth0
1323 root 21068 S /usr/bin/csrservicesd
1381 root 800 S /sbin/rngd -r /dev/urandom -W 4000 -t 30
1399 root 1364 S /usr/sbin/ntpd -n -p 0.openwrt.pool.ntp.org -p 1.ope
1443 root 0 SW< [kworker/u3:0]
1444 root 0 SW< [hci0]
1445 root 0 SW< [hci0]
1449 root 0 SW< [kworker/u3:2]
1467 nobody 932 S /usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k
1587 root 8528 S /usr/sbin/mcproxy -f /etc/mcproxy.conf
1609 nobody 1224 S /usr/sbin/mdnsd -debug
1623 root 7832 S /bin/csrMeshGw
1684 root 1356 R ps
root@OpenWrt:/#

如果 csrMeshGw 任务没有起来,我们需要手动启动。

1
2
root@OpenWrt:/# /etc/init.d/meshGwSbStart start
root@OpenWrt:/#

下面我们开始启动一个蓝牙 mesh 网络。

高通给我们提供了三个任务程序。

1
2
root@OpenWrt:/# csrMe
csrMeshGw csrMeshGwRefApp csrMeshGwTestApp

其中 csrMeshRefApp 是实现了自动启动一个蓝牙 mesh 网络,产生 uuid ,关联网关到 mesh 网络等工作,但是有许多问题,没有完善,所以我们使用另外一个工具 csrMeshGwTestApp 。

开始蓝牙 mesh 网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*********************************/
Gateway Application :: Core Menu
1 - Start Mesh
2 - Stop Mesh
3 - Reset Mesh
4 - Get Network ID list
5 - Associate Gateway to Network
6 - Remove Network
7 - Get Local Device UUID
8 - Get Local Device ID
9 - Set Remote Device ID
10 - Set Network Key ID
11 - Set Network Key : Pass Phrase (pp1)
12 - Set Pass Phrase
13 - Find Mesh ID
14 - Find Network ID
15 - Register Sniffer
16 - UnRegister Sniffer
17 - Set Transmit State
18 - Get Transmit State
19 - Get Diagnostic Data Request
20 - Reset Diagnostic Data
21 - Go to Main Menu
22 - Exit
/*********************************/
Enter Operation ID : 1
<< Mesh Start
>> Waiting for Response
>> Received 7 bytes
>> CSRMESH_START_EVENT Received Status : SUCCESS
/*********************************/
Gateway Application :: Core Menu
1 - Start Mesh
2 - Stop Mesh
3 - Reset Mesh
4 - Get Network ID list
5 - Associate Gateway to Network
6 - Remove Network
7 - Get Local Device UUID
8 - Get Local Device ID
9 - Set Remote Device ID
10 - Set Network Key ID
11 - Set Network Key : Pass Phrase (pp1)
12 - Set Pass Phrase
13 - Find Mesh ID
14 - Find Network ID
15 - Register Sniffer
16 - UnRegister Sniffer
17 - Set Transmit State
18 - Get Transmit State
19 - Get Diagnostic Data Request
20 - Reset Diagnostic Data
21 - Go to Main Menu
22 - Exit
/*********************************/
Enter Operation ID : Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 0b
Jul 13 02:29:17 csrMeshGw[1623]: CsrMeshReadAndProcessData: Data Rx over Socket is
Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 0c
Jul 13 02:29:17 csrMeshGw[1623]: CsrMeshReadAndProcessData: Data Rx over Socket is
Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 0d
Jul 13 02:29:17 csrMeshGw[1623]: CsrMeshReadAndProcessData: Data Rx over Socket is
Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 0e
Jul 13 02:29:17 csrMeshGw[1623]: CsrMeshReadAndProcessData: Data Rx over Socket is
Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 13
Jul 13 02:29:17 csrMeshGw[1623]: CsrMeshReadAndProcessData: Data Rx over Socket is
Jul 13 02:29:17 csrMeshGw[1623]: 0a 00 14

产生 uuid 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
7
<< Get Local Device UUID
>> Waiting for Response
>> Received 23 bytes
>> CSRMESH_GET_DEVICE_UUID_EVENT Received Status : SUCCESS
UUID 793851c3-b66d-9d98-d469-224b2ce34053
/*********************************/
Gateway Application :: Core Menu
1 - Start Mesh
2 - Stop Mesh
3 - Reset Mesh
4 - Get Network ID list
5 - Associate Gateway to Network
6 - Remove Network
7 - Get Local Device UUID
8 - Get Local Device ID
9 - Set Remote Device ID
10 - Set Network Key ID
11 - Set Network Key : Pass Phrase (pp1)
12 - Set Pass Phrase
13 - Find Mesh ID
14 - Find Network ID
15 - Register Sniffer
16 - UnRegister Sniffer
17 - Set Transmit State
18 - Get Transmit State
19 - Get Diagnostic Data Request
20 - Reset Diagnostic Data
21 - Go to Main Menu
22 - Exit

关联网关到网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Enter Operation ID : 5
<< Associate Gateway (MeshGw) to Network
>> Waiting for Response
>> Received 7 bytes
>> CSRMESH_ASSOC_TO_A_NETWORK_EVENT Received Status : INPROGRESS
>> Waiting for Response
>> Response Not received
>> Waiting for Response
>> Received 7 bytes
>> CSRMESH_ASSOC_STARTED_EVENT Received Status : SUCCESS
>> Associate Gateway to Network Started !!
>> Waiting for Response
Jul 13 03:09:14 syslog[1303]: mcm: send_ack_message(out)
Jul 13 03:09:16 syslog[1303]: mcm: send_ack_message(out)
>> Response Not received
>> Waiting for Response
Jul 13 03:09:20 syslog[1303]: mcm: send_ack_message(out)
Jul 13 03:09:22 syslog[1303]: mcm: send_ack_message(out)
>> Response Not received
>> Waiting for Response
Jul 13 03:09:32 syslog[1303]: mcm: send_ack_message(out)
>> Received 8 bytes
>> CSRMESH_ASSOC_COMPLETE_EVENT Received Status : SUCCESS
NW_ID : 0x0
>> Associate Gateway to Network Completed !!

手机 app 需要打开蓝牙,打开检测设备列表,当检测到有网关设备时,点击关联设备,等关联成功后,从上面的 log 可以看出网络关联已经完成。退出该程序。

加入蓝牙设备

首先需要让设备置于关联网络状态,通过手机 app 点击关联设备,关联成功后,设备会在设备列表中。此时可以通过蓝牙控制设备了。

通道选择

在手机 app 中,通过 setting 来手动选择通道,比如现在选择网关通道方式,会提示 connect to the cloud ,然后点击 Yes 即可。选择网关的时候,选中列表中的 CSRmeshGW 后,点击 Associate device,等待完成。

troubleshooting

  • 怎么知道网关连网信息

    通过 log 方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
root@OpenWrt:/# logread -f
Wed Jul 13 03:41:21 2016 user.debug syslog[1687]: cws: client connected to csrmesh-test.csrlbs.com:443
Wed Jul 13 03:41:40 2016 user.info syslog[1687]: ccm: CSR_LWS_CALLBACK_CLIENT_ESTABLISHED
Wed Jul 13 03:41:40 2016 user.info syslog[1687]: ccm: send_auth_msg gw_uuid:db784445-78ef-287d-ac17-e0abcb82903d
Wed Jul 13 03:41:40 2016 user.debug syslog[1687]: cws: write[in]
Wed Jul 13 03:41:40 2016 user.debug syslog[1687]: cws: write[out] rc - 49
Wed Jul 13 03:41:52 2016 user.debug syslog[1687]: ccm: Sending heart beat message
Wed Jul 13 03:41:52 2016 user.debug syslog[1687]: ccm: packed buffer to write len:12
Wed Jul 13 03:41:52 2016 user.debug syslog[1687]: cws: write[in]
Wed Jul 13 03:41:52 2016 user.debug syslog[1687]: cws: write[out] rc - 12
Wed Jul 13 03:41:52 2016 user.debug syslog[1687]: ccm: packed buffer written:(len:12, sent_len:12)
Wed Jul 13 03:41:53 2016 user.debug syslog[1687]: ccm: CSR_WS_CALLBACK_CLIENT_RECEIVE
Wed Jul 13 03:41:53 2016 user.info syslog[1687]: ccm: message received from cloud size:9
Wed Jul 13 03:41:53 2016 user.info syslog[1687]: ccm: message from cloud, ts=155e253b90d, req-id:[], msg_case:4
Wed Jul 13 03:41:53 2016 user.info syslog[1687]: ccm: Ack received from cloud, req-id:[], status=0, error_msg:[(null)]
Wed Jul 13 03:42:51 2016 user.info syslog[1687]: ccm: ws session closed, status=4
Wed Jul 13 03:42:51 2016 user.info syslog[1687]: ccm: ws session closed, status=29
Wed Jul 13 03:42:53 2016 user.debug syslog[1687]: ccm: Sending heart beat message
Wed Jul 13 03:42:53 2016 user.err syslog[1687]: ccm: Sending heart beat message failed, res=1
Wed Jul 13 03:43:00 2016 user.info syslog[1687]: ccm: CSR_LWS_CALLBACK_CLIENT_ESTABLISHED
Wed Jul 13 03:43:00 2016 user.info syslog[1687]: ccm: send_auth_msg gw_uuid:db784445-78ef-287d-ac17-e0abcb82903d
Wed Jul 13 03:43:00 2016 user.debug syslog[1687]: cws: write[in]
Wed Jul 13 03:43:00 2016 user.debug syslog[1687]: cws: write[out] rc - 49
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: ccm: Sending heart beat message
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: ccm: packed buffer to write len:12
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: cws: write[in]
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: cws: write[out] rc - 12
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: ccm: packed buffer written:(len:12, sent_len:12)
Wed Jul 13 03:43:54 2016 user.debug syslog[1687]: ccm: CSR_WS_CALLBACK_CLIENT_RECEIVE
Wed Jul 13 03:43:54 2016 user.info syslog[1687]: ccm: message received from cloud size:9
Wed Jul 13 03:43:54 2016 user.info syslog[1687]: ccm: message from cloud, ts=155e25595b9, req-id:[], msg_case:4
Wed Jul 13 03:43:54 2016 user.info syslog[1687]: ccm: Ack received from cloud, req-id:[], status=0, error_msg:[(null)]
  • 手机 app 切换通道不成功

    如果 app 提示蓝牙方面的问题时,重新打开蓝牙。如果 app 提示找不到网关时,检查下手机是否和网关处于同一网络内。

技术资源

android app source v2.0.1

android app

gatewaySB source and documents

gatewayNB source and documents