Artifact [5bb988b927]
Not logged in

Artifact 5bb988b9279e6b1a4d2b677a3245221c3bd19fe8:

Wiki page [ble command] by chw 2017-01-25 10:43:47.
D 2017-01-25T10:43:47.292
L ble\scommand
P 2014ffb3f79b1002b8f4a814ebbe8d8ae874a88b
U chw
W 20660
<h2>Name</h2>

<b>ble</b> - interact with Bluetooth Low Energy (BLE) devices. Requires Android 4.3 or higher.

<h2>Synopsis</h2>

<tt>package require Ble</tt><br>
<tt>ble subcommand ?options?</tt>

<h2>Description</h2>

This command is used to deal with Bluetooth Low Energy (BLE) devices. The legal <tt>subcommands</tt> (which may be abbreviated) are:

<tt>ble abort <i>handle</i></tt>

    Abort the current write transaction on the BLE connection identified by <tt><i>handle</i></tt> which was obtained earlier by a <tt>ble connect</tt> command. Returns an integer indicating success (1), failure (0), or system error (less than 0).

<tt>ble begin <i>handle</i></tt>

    Starts a write transaction on the BLE connection identified by <tt><i>handle</i></tt> which was obtained earlier by a <tt>ble connect</tt> command. Returns an integer indicating success (1), failure (0), or system error (less than 0).

<tt>ble callback <i>handle ?callback?</i></tt>

    If the <tt><i>callback</i></tt> argument is provided that argument replaces the callback function on the BLE connection identified by <tt><i>handle</i></tt> and returns the old callback function. Otherwise the current callback function is returned. In contrast to e.g. the Tk event bind mechanism, the <tt><i>callback</i></tt> argument has not all the freedom of a Tcl bind script, i.e. it must be a single command and be parseable as a list since internally the Tcl core function Tcl_EvalObjv() is used for executing the callback instead of the Tcl_Eval*() function family supporting full scripts.

<tt>ble characteristics <i>handle suuid sinstance</i></tt>

    Returns a list of characteristics of the service described by its UUID <tt><i>suuid</i></tt> and instance number <tt><i>sinstance</i></tt> on the BLE connection <tt><i>handle</i></tt>. The list is layed out as a table with the five columns characteristic UUID, characteristic instance number, permissions, properties, and write type suitable for iterating using <tt>foreach {cuuid cinstance perm prop wrtype} <nowiki>[ble characteristics ...]</nowiki> {...}</tt>.

<tt>ble close <i>handle</i></tt>

    Closes the BLE connection identified by <tt><i>handle</i></tt> which was obtained earlier by a <tt>ble connect</tt> or <tt>ble scanner</tt> command.

<tt>ble connect <i>address callback ?flag?</i></tt>

    Connects to the Bluetooth LE device with address <tt><i>address</i></tt> (expressed as six hexadecimal 8 bit numbers separated by colons, like a Ethernet MAC address), and arranges for the <tt><i>callback</i></tt> command to be invoked on events on the connection to this device. The optional <tt><i>flag</i></tt> is a boolean with default false controlling automatic connection setup (see the <a href="https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html">Android documentation</a> for more details). The callback command is called with two additional arguments, the first is a string (<tt>connection</tt>, <tt>scan</tt>, <tt>service</tt>, <tt>characteristic</tt>, <tt>descriptor</tt>, or <tt>transaction</tt>) indicating the kind of event, the second is a dictionary with event related information, see the section <b>Event Data</b> below. For restrictions of the <tt><i>callback</i></tt> argument see the description in <tt>ble callback</tt> above. The result of the <tt>ble connect</tt> command is a handle (a string identifying the BLE connection) to be used in other <tt>ble</tt> subcommands. During connection establishment an automatic discovery takes place which detects all advertised services, characteristics, and descriptors of the remote Bluetooth LE device.

<tt>ble descriptors <i>handle suuid sinstance cuuid cinstance</i></tt>

    Returns a list of descriptors of the service and characteristic described by its UUIDs <tt><i>suuid</i></tt> and <tt><i>cuuid</i></tt> and instance numbers <tt><i>sinstance</i></tt> and <tt><i>cinstance</i></tt> on the BLE connection <tt><i>handle</i></tt>. The list is layed out as a table with the two columns descriptor UUID and permissions suitable for iterating using <tt>foreach {duuid perm} <nowiki>[ble descriptors ...]</nowiki> {...}</tt>.

<tt>ble disable <i>handle suuid sinstance cuuid cinstance</i></tt>

    Turns off notifications of a characteristic of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), and <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0).

<tt>ble disconnect <i>handle</i></tt>

    Initiates a disconnect of the BLE connection <tt><i>handle</i></tt> if the current connection state is disconnected. When the operation completes the callback function of the connection is invoked.

<tt>ble dread <i>handle suuid sinstance cuuid cinstance duuid</i></tt>

    Initiates the read of a descriptor of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0), and <tt><i>duuid</i></tt> (128 bit descriptor UUID). The result is a positive integer when the descriptor read operation is in progress, 0 or negative on error. The completion of the descriptor read operation is indicated through the callback function of the connection.

<tt>ble dwrite <i>handle suuid sinstance cuuid cinstance duuid value</i></tt>

    Initiates the write of a descriptor of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0), and <tt><i>duuid</i></tt> (128 bit descriptor UUID). <tt><i>value</i></tt> is the value to be written and should be a string or byte array. The result is a positive integer when the descriptor write operation is in progress, 0 or negative on error. The completion of the descriptor write operation is indicated through the callback function of the connection.

<tt>ble enable <i>handle suuid sinstance cuuid cinstance</i></tt>

    Turns on notifications of a characteristic of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), and <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0).

<tt>ble equal <i>handle uuid1 uuid2</i></tt>

    Tests if the given UUIDs are equal. Both can be specified in abbreviated form and are expanded before comparison. Returns true, if the UUIDs are the same. Unknown abbreviated or long UUIDs with respect to the connection <tt><i>handle</i></tt> compare always to false.

<tt>ble execute <i>handle</i></tt>

    Dispatches execute (commit) of the current write transaction which was started earlier using <tt>ble begin</tt> on the BLE connection identified by <tt><i>handle</i></tt> which was obtained earlier by a <tt>ble connect</tt> command. Returns an integer indicating success (1), failure (0), or system error (less than 0). The result of the transaction is reported in the callback with event kind <tt>transaction</tt>.

<tt>ble expand <i>handle uuid</i></tt>

    Expands the given (abbreviated, short) UUID to its 128 bit (long, canonical) form and returns a 128 bit UUID string. An error is reported if an abbreviated or long UUID is unknown with respect to the connection <tt><i>handle</i></tt>.

<tt>ble getrssi <i>handle</i></tt>

    Requests remote SSI information from the BLE connection identified by <tt><i>handle</i></tt> which was obtained earlier by a <tt>ble connect</tt> command. Returns an integer indicating success (1), failure (0), or system error (less than 0). The updated remote SSI is reported in later callbacks.

<tt>ble info <i>?handle?</i></tt>

    Returns information of the BLE connection identified by <tt></i>handle</i></tt> as a dictionary made up the fields <i>handle</i> (the connection identifier), <i>address</i> (Bluetooth address), and <i>state</i> (connection state, one of <i>disconnected</i>, <i>discovery</i>, <i>scanning</i>, <i>connected</i>, or <i>idle</i>. If <tt><i>handle</i></tt> is omitted, a list of all known connection identifiers is returned.

<tt>ble pair <i>address</i></tt>

    Initiates pairing with the Bluetooth device with address <tt><i>address</i></tt> (expressed as six hexadecimal 8 bit numbers separated by colons, like a Ethernet MAC address).

<tt>ble read <i>handle suuid sinstance cuuid cinstance</i></tt>

    Initiates the read of a characteristic of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), and <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0). The result is a positive integer when the read operation is in progress, 0 or negative on error. The completion of the read operation is indicated through the callback function of the connection.

<tt>ble reconnect <i>handle</i></tt>

    Initiates a reconnect of the BLE connection <tt><i>handle</i></tt> if the current connection state is disconnected. When the operation completes the callback function of the connection is invoked with information on the new connection state.

<tt>ble scanner <i>callback</i></tt>

    Creates a BLE connection to be used for detection (scan) of BLE devices and returns a handle (a string identifying the BLE scanner) to be used to deal with this scanner and arranges for the <tt><i>callback</i></tt> command to be invoked on events on the connection. See the description of <tt>ble connect</tt> and the section <b>Event Data</b> for more details on the <tt>callback</tt> argument.

<tt>ble services <i>handle</i></tt>

    Returns a list of services of the BLE connection <tt><i>handle</i></tt>. The list is layed out as a table with the three columns service UUID, service instance number, and service type suitable for iterating using <tt>foreach {suuid sinstance type} <nowiki>[ble services ...]</nowiki> {...}</tt>.

<tt>ble shorten <i>handle uuid</i></tt>

    Shorten the given (long, canonical) UUID to its shortest (16 or 32 bit) form. An error is reported if the long UUID is unknown with respect to the connection <tt><i>handle</i></tt>. If no unique abbreviation is found, the full 128 bit UUID is returned.

<tt>ble start <i>handle</i></tt>

    Starts scanning for BLE devices. Scan status and scan results are indicated by invocations of the <tt><i>callback</i></tt> function given to the corresponding <tt>ble scanner</tt> command.

<tt>ble stop <i>handle</i></tt>

    Stops scanning for BLE devices. Scan status is indicated by invocations of the <tt><i>callback</i></tt> function given to the corresponding <tt>ble scanner</tt> command.

<tt>ble unpair <i>address</i></tt>

    Initiates release of the pairing with the Bluetooth device with address <tt><i>address</i></tt> (expressed as six hexadecimal 8 bit numbers separated by colons, like a Ethernet MAC address).

<tt>ble userdata <i>handle ?data?</i></tt>

    Associate or retrieve user data with the BLE connection <tt><i>handle</i></tt>. When <tt><i>data</i></tt> is given it replaces the former associated user data. When omitted, the current user data or an empty list is returned.  

<tt>ble write <i>handle suuid sinstance cuuid cinstance value</i></tt>

    Initiates the write of a characteristic of the BLE connection <tt><i>handle</i></tt> identified by <tt><i>suuid</i></tt> (128 bit service UUID), <tt><i>sinstance</i></tt> (service instance identifier, integer, usually 0), <tt><i>cuuid</i></tt> (128 bit characteristic UUID), and <tt><i>cinstance</i></tt> (characteristic identifier, integer, usually 0). <tt><i>value</i></tt> is the value to be written and should be a string or byte array. The result is a positive integer when the write operation is in progress, 0 or negative on error. The completion of the write operation is indicated through the callback function of the connection.  Note: not all Android implementations allow more than one active command (example, issuing a "ble read" immediately after a "ble write"). For best compatibility, you should wait for the callback that your write operation has completed before issuing the next ble write/read command.

<h2>Abbreviated UUIDs</h2>

The 128 bit UUID arguments to <tt>ble</tt> commands can be specified in abbreviated 16 or 32 bit form as long as the value is unique with respect to the UUIDs learned during the discovery phase. Examples:

<verbatim>
 TI SensorTag Base UUID:        F0000000-0451-4000-B000-000000000000

 IR Temperature Sensor Service: F000AA00-0451-4000-B000-000000000000
          abbreviated (32 bit): F000AA00
          abbreviated (16 bit):     AA00

 IR Temperature Sensor Value:   F000AA01-0451-4000-B000-000000000000
          abbreviated (32 bit): F000AA01
          abbreviated (16 bit):     AA01

 Generic descriptor for notify: 00002902-0000-1000-8000-00805F9B34FB
          abbreviated (32 bit): 00002902
          abbreviated (16 bit):     2902
</verbatim>

<h2>Event Data</h2>

The first argument to callback functions is the type of event, as described below.

<tt>connection</tt>

    Indicates change in connection state.

<tt>scan</tt>

    Indicates change in scan state or reports newly detected Bluetooth LE devices.

<tt>service</tt>

    Information about a service.

<tt>characteristic</tt>

    Information about a characteristic, used for data exchange.

<tt>descriptor</tt>

    Information about a descriptor (meta information of a characteristic).

<tt>transaction</tt>

    Indicates status of a write transaction.

The second argument to callback functions is a dictionary with keys depending on the kind of the event. The following paragraphs list the various event formats.

<tt>handle <i>h</i> state <i>s</i></tt>

    Connection state event for <tt>ble scan</tt>. <tt>state</tt> can be one of <tt>scanning</tt> or <tt>idle</tt>.

<tt>handle <i>h</i> address <i>a</i> state <i>s</i> rssi <i>r</i></tt>

    Connection state event for <tt>ble connect</tt>. <tt>state</tt> can be one of <tt>disconnected</tt>, <tt>discovery</tt>, or <tt>connected</tt>. In the discovery phase the services, characteristics, and descriptors of the remote device are gathered. The <tt>rssi</tt> field contains the last read remote SSI  (signal strength indicator) in dBm as integer number.

<tt>handle <i>h</i> state <i>s</i> address <i>a</i> name <i>n</i> type <i>t</i> rssi <i>r</i></tt>

    Scan result event. <tt>address</tt> is the Bluetooth address of the remote device, <tt>name</tt> it's advertised friendly name, <tt>type</tt> the device type as integer, <tt>rssi</tt> the receive SSI in dBm as integer.

<tt>handle <i>h</i> address <i>a</i> state <i>s</i> rssi <i>r</i> suuid <i>su</i> sinstance <i>si</i> type <i>t</i></tt>

    Service discovery event. <tt>suuid</tt> is the UUID of the service, <tt>sinstance</tt> the instance of that service as integer number. Refer to <a href="https://developer.android.com/reference/android/bluetooth/BluetoothGattService.html">BluetoothGattService</a> for details.

<tt>handle <i>h</i> address <i>a</i> state <i>s</i> rssi <i>r</i> suuid <i>su</i> sinstance <i>si</i> cuuid <i>ci</i> cinstance <i>ci</i> permissions <i>p</i> properties <i>q</i> writetype <i>w</i> access <i>a</i> value <i>v</i></tt>

    Characteristic event. <tt>cuuid</tt> is the UUID of the characteristic, <tt>cinstance</tt> the instance of that characteristic as integer number. The items <tt>permission</tt>, <tt>properties</tt>, and <tt>writetype</tt> are integer numbers, too. The <tt>access</tt> item contains a one letter code indicating the type of access ('c' for change notification, 'd' for discovery, 'r' for read, 'w' for write). The <tt>value</tt> item holds the data of the characteristic as a byte array. It's interpretation is device/characteristic depending. This event is reported during discovery and normal operation when <tt>ble read</tt> or <tt>ble write</tt> are performed locally or notifications for the characteristic are enabled using <tt>ble enable</tt>. Refer to <a href="https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html">BluetoothGattCharacteristic</a> for details.

<tt>handle <i>h</i> address <i>a</i> state <i>s</i> rssi <i>r</i> suuid <i>su</i> sinstance <i>si</i> cuuid <i>ci</i> cinstance <i>ci</i> duuid <i>di</i> permissions <i>p</i> access <i>a</i>  value <i>v</i></tt>

    Descriptor event. <tt>duuid</tt> is the UUID of the descriptor. The item <tt>permission</tt> is an integer number, too. The <tt>access</tt> item contains a one letter code indicating the type of access ('d' for discovery, 'r' for read, 'w' for write). The <tt>value</tt> item holds the data of the descriptor as a byte array. It's interpretation is device/characteristic/descriptor depending. This event is reported during discovery and normal operation when <tt>ble dread</tt> or <tt>ble dwrite</tt> are performed locally. Refer to <a href="https://developer.android.com/reference/android/bluetooth/BluetoothGattDescriptor.html">BluetoothGattDescriptor</a> for details.

<tt>handle <i>h</i> success <i>s</i></tt>

    Transaction result event. <tt>success</tt> is the transaction result and is 1 for success or 0 for failure.

<h2>Example</h2>

The following example scans for Bluetooth LE devices, connects to a <a href="http://www.ti.com/tool/cc2541dk-sensor">TI SensorTag</a> and enables notifications of the buttons of the device.

<verbatim>

    proc ble_handler {what data} {
        switch -- $what {
            scan {
                if {[dict get $data name] eq "SensorTag"} {
                    # found the TI SensorTag, connect it, stop the scanner
                    ble connect [dict get $data address] ble_handler 1
                    ble close [dict get $data handle]
                }
            }
            connection {
                if {[dict get $data state] == "disconnected"} {
                    # fall back to scanning
                    ble close [dict get $data handle]
                    ble start [ble scanner ble_handler]
                } elseif {[dict get $data state] == "connected"} {
                    # if the TI SensorTag buttons were found,
                    # it will be enabled for notifications now
                    set handle [dict get $data handle]
                    set cmd [ble userdata $handle]
                    if {$cmd ne {}} {
                        if {[{*}$cmd]} {
                            # success, clear userdata
                            ble userdata $handle {}
                        }
                    }
                }
            }
            descriptor {
                if {[string match "*2902-*" [dict get $data duuid]] &&
                    [string match "*FFE1-*" [dict get $data cuuid]]} {
                    # descriptor for TI SensorTag buttons found
                    set flag 0
                    # notification enable state, 16 bit little-endian
                    #  0x0000 = disabled, 0x0001 = enabled
                    binary scan [dict get $data value] s flag
                    if {!$flag} {
                        # later turn on notifications of button changes
                        set handle [dict get $data handle]
                        ble userdata $handle [list ble enable $handle \
                            [dict get $data suuid] [dict get $data sinstance] \
                            [dict get $data cuuid] [dict get $data cinstance]]
                    }
                }
            }
        }
        # dump data to stdout
        if {[dict exists $data value]} {
            # make hex string from byte array
            binary scan [dict get $data value] H* value
            dict set data value $value
        }
        puts "$what: $data"
    }

    ble start [ble scanner ble_handler]

</verbatim>
Z d40c4dea02318fa8dcf94e733c279b26