2015年5月5日 星期二

Intel IoT Solution: Edison BLE 無線控制 USB 玩具砲台 DEMO (Linux - 2, BlueZ)

接著上一章, 接下來講 Intel Edison BLE 的使用, 也就是下圖右邊的部分, 如何在 Intel Edison 建立一個 GATT Server, 讓手機無線的控制砲台


















首先要安裝最新版的 blueZ, 安裝指令如下 (假如你裝完 ubilinux 內建就有了):

root@ubilinux:/home/edison# apt-get install blueZ


首先測試我們可以用 hcitool command 去做一些 scan/connect 等動作 (可以用 hcitool --help 看說明)

root@ubilinux:/home/edison# hcitool --help
hcitool - HCI Tool ver 5.28
Usage:
        hcitool [options] <command> [command parameters]
Options:
        --help  Display help
        -i dev  HCI device
Commands:
        dev     Display local devices
        inq     Inquire remote devices
        scan    Scan for remote devices
        name    Get name from remote device
        info    Get information from remote device
        spinq   Start periodic inquiry
        epinq   Exit periodic inquiry
        cmd     Submit arbitrary HCI commands
        con     Display active connections
        cc      Create connection to remote device
        dc      Disconnect from remote device
        sr      Switch master/slave role
        cpt     Change connection packet type
        rssi    Display connection RSSI
        lq      Display link quality
        tpl     Display transmit power level
        afh     Display AFH channel map
        lp      Set/display link policy settings
        lst     Set/display link supervision timeout
        auth    Request authentication
        enc     Set connection encryption
        key     Change connection link key
        clkoff  Read clock offset
        clock   Read local or remote clock
        lescan  Start LE scan
        leinfo  Get LE remote information
        lewladd Add device to LE White List
        lewlrm  Remove device from LE White List
        lewlsz  Read size of LE White List
        lewlclr Clear LE White List
        lerladd Add device to LE Resolving List
        lerlrm  Remove device from LE Resolving List
        lerlclr Clear LE Resolving List
        lerlsz  Read size of LE Resolving List
        lerlon  Enable LE Address Resolution
        lerloff Disable LE Address Resolution
        lecc    Create a LE Connection
        ledc    Disconnect a LE Connection
        lecup   LE Connection Update


下面就是做一個簡單的 DEMO, 我去連接我的 ADATA 燈泡, 可以看到他的資訊, 他是 CSR 的 BLE chip, 加上他功能有 mesh, 所以其實就可以知道他的 mesh 方案是使用 CSRmesh 這個方法, 然後可以做 connect/disconnect 等動作, 其他如 resolving address & white list 相關的就不多說

root@ubilinux:/home/edison# hcitool leinfo 70:7C:18:00:05:BF
Requesting information ...
        Handle: 64 (0x0040)
        LMP Version: 4.1 (0x7) LMP Subversion: 0x458
        Manufacturer: Cambridge Silicon Radio (10)
        Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00

root@ubilinux:/home/edison# hcitool lescan
LE Scan ...
70:7C:18:00:05:BF ADATA Aura

root@ubilinux:/home/edison# hcitool lecc 70:7C:18:00:05:BF
Connection handle 64

root@ubilinux:/home/edison# hcitool ledc 64


另外我們可以用 bluetoothctl 進入 HCI 控制介面, 得到一些其他的訊息:

root@ubilinux:/home/edison# bluetoothctl
[NEW] Controller 43:34:1B:00:1F:AC BlueZ 5.28 [default]

[bluetooth]# help
Available commands:
  list                       List available controllers
  show [ctrl]                Controller information
  select <ctrl>              Select default controller
  devices                    List available devices
  paired-devices             List paired devices
  power <on/off>             Set controller power
  pairable <on/off>          Set controller pairable mode
  discoverable <on/off>      Set controller discoverable mode
  agent <on/off/capability>  Enable/disable agent with given capability
  default-agent              Set agent as the default one
  scan <on/off>              Scan for devices
  info <dev>                 Device information
  pair <dev>                 Pair with device
  trust <dev>                Trust device
  untrust <dev>              Untrust device
  block <dev>                Block device
  unblock <dev>              Unblock device
  remove <dev>               Remove device
  connect <dev>              Connect device
  disconnect <dev>           Disconnect device
  version                    Display version
  quit                       Quit program

[bluetooth]# scan on
Discovery started
[CHG] Controller 43:34:1B:00:1F:AC Discovering: yes
[NEW] Device 70:7C:18:00:05:BF ADATA Aura
[bluetooth]# scan off
[CHG] Device 70:7C:18:00:05:BF RSSI is nil
Discovery stopped
[CHG] Controller 43:34:1B:00:1F:AC Discovering: no

[bluetooth]# info 70:7C:18:00:05:BF
Device 70:7C:18:00:05:BF
        Name: ADATA Aura
        Alias: ADATA Aura
        Appearance: 0x0340
        Paired: no
        Trusted: no
        Blocked: no
        Connected: yes
        LegacyPairing: no
        UUID: Vendor specific           (00001016-d102-11e1-9b23-00025b00a5a5)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Unknown                   (00007877-0000-1000-8000-00805f9b34fb)
        UUID: Unknown                   (0000fef1-0000-1000-8000-00805f9b34fb)

[bluetooth]# connect 70:7C:18:00:05:BF
Attempting to connect to 70:7C:18:00:05:BF
[CHG] Device 70:7C:18:00:05:BF Connected: yes
Connection successful
[CHG] Device 70:7C:18:00:05:BF UUIDs:
        00001016-d102-11e1-9b23-00025b00a5a5
        00001800-0000-1000-8000-00805f9b34fb
        00001801-0000-1000-8000-00805f9b34fb
        00007877-0000-1000-8000-00805f9b34fb
        0000fef1-0000-1000-8000-00805f9b34fb
[CHG] Device 70:7C:18:00:05:BF Appearance: 0x0340
[bluetooth]# disconnect 70:7C:18:00:05:BF
Attempting to disconnect from 70:7C:18:00:05:BF
Successful disconnected
[CHG] Device 70:7C:18:00:05:BF Connected: no


假如要讓 Intel Edison 可以被 Discover 並被 peer device 做 pair 的話可以這樣做

[bluetooth]# discoverable on
Changing discoverable on succeeded
[CHG] Controller 43:34:1B:00:1F:AC Discoverable: yes
[bluetooth]# discoverable off
Changing discoverable off succeeded
[CHG] Controller 43:34:1B:00:1F:AC Discoverable: no




























接下來假如希望 Edison 做 broadcast 的話, 可以利用 hcitool 輸入 hci command 來做到, 下面是一個範例:

root@ubilinux:/home/edison# hcitool -i hci0 cmd 0x08 0x0008 48 45 4c 4c 4f 57 4f 52 4c 44
< HCI Command: ogf 0x08, ocf 0x0008, plen 10
  48 45 4C 4C 4F 57 4F 52 4C 44
> HCI Event: 0x0e plen 4
  01 08 20 12
root@ubilinux:/home/edison# hciconfig hci0 leadv 0



























但假如要自己建立自己的 GATT Server, 讓 Edison 當作 BLE Peripheral 的話, 就建議自己寫 code, 網路上看到一個滿方便的方式是利用 node.js module 叫做 bleno 的方式

bleno - A node.js module for implementing BLE (Bluetooth low energy) peripherals 是另一個可以用來做 BLE peripheral 的工具, 是利用 node.js 方式寫 code 來達到

安裝步驟:
apt-get install bluetooth bluez-utils libbluetooth-dev npm
npm install bleno noble

測試範例:






























http://joost.damad.be/2013/08/experiments-with-bluetooth-low-energy.html

============

2015/5/14 updated

補充一個 gatttool 工具, 可以用 command line 做 service discovery & read/write characteristics, 不過我用 ublinux 內建的 gatttool 做 connect 都會出現 connect fail (112), 網路找了一點資訊後, 總之就是要用自己 Build 的 BlueZ, 我剛好有所以就用這個就可以了

cp /root/bluez-5.28/attrib/gatttool /usr/bin/gatttool

下面就是我去跟 BLE 燈泡連接並且讀寫 Characteristics 的範例, 首先先去 scan, 找到我的 BLE 燈泡 Address

| ~ @ ubilinux (edison)
| => sudo hcitool lescan
LE Scan ...
F4:F9:51:BD:BE:03 (unknown)
54:4A:16:20:9D:F1 Yeelight Blue II
54:4A:16:20:9D:F1 Yeelight Blue II
68:D9:3C:93:E5:22 (unknown)


利用 gatttool 進入 interactive mode, 並連線

| ~ @ ubilinux (edison)
| => sudo gatttool -b 54:4A:16:20:9D:F1 -I
sudo: unable to resolve host ubilinux
[54:4A:16:20:9D:F1][LE]> connect
Attempting to connect to 54:4A:16:20:9D:F1
Connection successful


看一下 help 在這 mode 下有哪些指令可以用

[54:4A:16:20:9D:F1][LE]> help
help                                           Show this help
exit                                           Exit interactive mode
quit                                           Exit interactive mode
connect         [address [address type]]       Connect to a remote device
disconnect                                     Disconnect from a remote device
primary         [UUID]                         Primary Service Discovery
included        [start hnd [end hnd]]          Find Included Services
characteristics [start hnd [end hnd [UUID]]]   Characteristics Discovery
char-desc       [start hnd] [end hnd]          Characteristics Descriptor Discovery
char-read-hnd   <handle>                       Characteristics Value/Descriptor Read by handle
char-read-uuid  <UUID> [start hnd] [end hnd]   Characteristics Value/Descriptor Read by UUID
char-write-req  <handle> <new value>           Characteristic Value Write (Write Request)
char-write-cmd  <handle> <new value>           Characteristic Value Write (No response)
sec-level       [low | medium | high]          Set security level. Default: low
mtu             <value>                        Exchange MTU for GATT/ATT


列出 Primary Services 看看

[54:4A:16:20:9D:F1][LE]> primary
attr handle: 0x0001, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000f uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0010, end grp handle: 0x0045 uuid: 0000fff0-0000-1000-8000-00805f9b34fb
attr handle: 0x0046, end grp handle: 0xffff uuid: f000ffc0-0451-4000-b000-000000000000


列出 Characteristics 看看, 這邊都會有 handle, 滿方便的

[54:4A:16:20:9D:F1][LE]> characteristics
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
handle: 0x0008, char properties: 0x0a, char value handle: 0x0009, uuid: 00002a03-0000-1000-8000-00805f9b34fb
handle: 0x000a, char properties: 0x02, char value handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x000d, char properties: 0x20, char value handle: 0x000e, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x0011, char properties: 0x0a, char value handle: 0x0012, uuid: 0000fff1-0000-1000-8000-00805f9b34fb
handle: 0x0014, char properties: 0x0a, char value handle: 0x0015, uuid: 0000fff2-0000-1000-8000-00805f9b34fb
handle: 0x0017, char properties: 0x0a, char value handle: 0x0018, uuid: 0000fff3-0000-1000-8000-00805f9b34fb
handle: 0x001a, char properties: 0x10, char value handle: 0x001b, uuid: 0000fff4-0000-1000-8000-00805f9b34fb
handle: 0x001e, char properties: 0x0a, char value handle: 0x001f, uuid: 0000fff5-0000-1000-8000-00805f9b34fb
handle: 0x0021, char properties: 0x10, char value handle: 0x0022, uuid: 0000fff6-0000-1000-8000-00805f9b34fb
handle: 0x0025, char properties: 0x0a, char value handle: 0x0026, uuid: 0000fff7-0000-1000-8000-00805f9b34fb
handle: 0x0028, char properties: 0x0a, char value handle: 0x0029, uuid: 0000fff8-0000-1000-8000-00805f9b34fb
handle: 0x002b, char properties: 0x10, char value handle: 0x002c, uuid: 0000fff9-0000-1000-8000-00805f9b34fb
handle: 0x002f, char properties: 0x0a, char value handle: 0x0030, uuid: 0000fffa-0000-1000-8000-00805f9b34fb
handle: 0x0032, char properties: 0x10, char value handle: 0x0033, uuid: 0000fffb-0000-1000-8000-00805f9b34fb
handle: 0x0036, char properties: 0x0a, char value handle: 0x0037, uuid: 0000fffc-0000-1000-8000-00805f9b34fb
handle: 0x0039, char properties: 0x0a, char value handle: 0x003a, uuid: 0000fffd-0000-1000-8000-00805f9b34fb
handle: 0x003c, char properties: 0x0a, char value handle: 0x003d, uuid: 0000fffe-0000-1000-8000-00805f9b34fb
handle: 0x003f, char properties: 0x0a, char value handle: 0x0040, uuid: 0000ffe1-0000-1000-8000-00805f9b34fb
handle: 0x0042, char properties: 0x10, char value handle: 0x0043, uuid: 0000ffe2-0000-1000-8000-00805f9b34fb
handle: 0x0047, char properties: 0x1c, char value handle: 0x0048, uuid: f000ffc1-0451-4000-b000-000000000000
handle: 0x004b, char properties: 0x1c, char value handle: 0x004c, uuid: f000ffc2-0451-4000-b000-000000000000


列出 Descriptors 看看

[54:4A:16:20:9D:F1][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002a03-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 0000fff1-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0015, uuid: 0000fff2-0000-1000-8000-00805f9b34fb
handle: 0x0016, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0017, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0018, uuid: 0000fff3-0000-1000-8000-00805f9b34fb
handle: 0x0019, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x001a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001b, uuid: 0000fff4-0000-1000-8000-00805f9b34fb
handle: 0x001c, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001d, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x001e, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001f, uuid: 0000fff5-0000-1000-8000-00805f9b34fb
...



再來讀一下 Description Descriptor 看看

[54:4A:16:20:9D:F1][LE]> char-read-hnd 1d
Characteristic value/descriptor: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 20 34


因為他只能印出 hex string, 所以要轉 text 要用工具, 我直接用 hex2text 網頁轉, 轉出來結果為 "characteristic 4"

接下來做一下 Write 看看, UUID 0000fff1-0000-1000-8000-00805f9b34fb 是控制開關燈的 characteristic, handle 0x0012, 但由於是輸入 text 方是開關燈, 但這 tool 只吃 hex string, 所以一樣用上面的網頁轉一下, 就可以做開關燈如下


[54:4A:16:20:9D:F1][LE]> char-write-req 12 2c2c2c3130302c2c2c2c2c2c2c2c2c2c2c2c
Characteristic value was written successfully
[54:4A:16:20:9D:F1][LE]> char-write-req 12 2c2c2c302c2c2c2c2c2c2c2c2c2c2c2c2c2c
Characteristic value was written successfully


大概用法就是這樣

Note: 他可以看 handle, 所以 Sniffer 前用這招看 handle 非常的好用, 推薦這個 Tool

------------------------------------------------------
Copyright by Jackal Chen @ 2015
jackalchen737@gmail.com

相關系列文章:

1 則留言:

  1. 不好意思想請問一下為什麼我用char-read-hnd 12 Characteristic value/descriptor: 00 值一直是00
    為什麼讀不到我寫入到藍芽裡的值呢?

    回覆刪除