Skip to content

Commit 6626aeb

Browse files
authored
Merge pull request #54 from digidotcom/xbee_cellular_x16_features
Release new typehints and samples for XBee (3) Cellular x16 firmware
2 parents 17e6b47 + 5ad43b0 commit 6626aeb

File tree

5 files changed

+459
-7
lines changed

5 files changed

+459
-7
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
Bluetooth Pairing Sample Application
2+
============================================================
3+
4+
This example demonstrates performing pairing to secure the BLE
5+
connection to another BLE device.
6+
7+
Requirements
8+
------------
9+
10+
To run this example you need:
11+
12+
* One XBee3 radio module with MicroPython support.
13+
* One carrier board for the radio module (XBIB-U-DEV or XBIB-C board).
14+
* A peripheral BLE device to connect to which supports pairing.
15+
16+
Setup
17+
-----
18+
19+
Make sure the hardware is set up correctly:
20+
21+
1. Plug the XBee3 radio module into the XBee adapter and connect it to your
22+
computer's USB port.
23+
2. Find the BLE MAC address of the peripheral BLE device. It will be
24+
used later in the example. The peripheral must support pairing with
25+
MITM support. If it does not, edit the `ble.config` like to remove
26+
that flag. If the flag is removed Just Works pairing may occur with
27+
no callbacks.
28+
29+
Run
30+
---
31+
32+
Before launching the application, update the `REMOTE_ADDRESS` and `address_type`
33+
variables in `main.py` to match your BLE peripheral device.
34+
35+
Compile and launch the MicroPython application. It prints information to the
36+
console.
37+
38+
After connecting to the peripheral device, it will delay for a short
39+
period of time and then one of the `io_callback` methods will be
40+
called. The specific callback will depend on the capabilities of the
41+
BLE peripheral being paired against.
42+
43+
Example session when connecting to a device with a keyboard and display.
44+
45+
Loading /flash/main.mpy...
46+
Running bytecode...
47+
Connecting
48+
Connected
49+
Wait for a bit before securing
50+
Securing
51+
Sleep forever
52+
The passkey is 520308
53+
Is this correct (y/n): y
54+
Secured
55+
56+
Supported platforms
57+
-------------------
58+
59+
* Digi XBee3 Cellular LTE-M/NB-IoT - minimum firmware version: 11416
60+
* Digi XBee3 Cellular LTE Cat 1 - minimum firmware version: x16
61+
62+
License
63+
-------
64+
65+
Copyright (c) 2020, Digi International Inc.
66+
67+
Permission is hereby granted, free of charge, to any person obtaining a copy
68+
of this software and associated documentation files (the "Software"), to deal
69+
in the Software without restriction, including without limitation the rights
70+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
71+
copies of the Software, and to permit persons to whom the Software is
72+
furnished to do so, subject to the following conditions:
73+
74+
The above copyright notice and this permission notice shall be included in all
75+
copies or substantial portions of the Software.
76+
77+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
78+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
79+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
80+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
81+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
82+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
83+
SOFTWARE.

samples/bluetooth/pairing/main.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Copyright (c) 2020, Digi International Inc.
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
# Change these two variables to your device's address and address type.
22+
# The address and address type can be discovered using ble.gap_scan().
23+
24+
import binascii
25+
import time
26+
27+
from digi import ble
28+
29+
REMOTE_ADDRESS = "f2:bc:3c:06:01:0a"
30+
address_type = ble.ADDR_TYPE_PUBLIC
31+
32+
# Put address into bytes (without colons)
33+
address = binascii.unhexlify(REMOTE_ADDRESS.replace(':', ''))
34+
35+
36+
# Present the passkey to the user
37+
def display_cb(passkey):
38+
print("The passkey is {}".format(passkey))
39+
40+
41+
# Solicit the passkey from the user.
42+
# NOTE: `ble.passkey_enter()` does not need to be called from the
43+
# callback, this is done for simplicity here, but blocking the
44+
# callback for user activity in a real application may not be
45+
# desirable.
46+
def request_cb():
47+
print("The passkey is being requested")
48+
passkey = input("Passkey: ")
49+
passkey = int(passkey)
50+
ble.passkey_enter(passkey)
51+
52+
53+
# Ask the user to confirm the passkey
54+
# NOTE: As above `passkey_confirm` need not be called from the
55+
# callback.
56+
def confirm_cb(passkey):
57+
print("The passkey is {}".format(passkey))
58+
yn = input("Is this correct (y/n): ")
59+
yn = yn.strip().lower()
60+
ble.passkey_confirm(yn[0] == 'y')
61+
62+
63+
# Called when the `secure` operation completes
64+
def secure_cb(code):
65+
if code == 0:
66+
print("Secured")
67+
else:
68+
print("Pairing failed with error 0x{:x}".format(code))
69+
70+
71+
def main():
72+
# io_callbacks must be called before `ble.config` to enable
73+
# Require MITM.
74+
ble.io_callbacks(display_cb=display_cb,
75+
request_cb=request_cb,
76+
confirm_cb=confirm_cb)
77+
ble.config(security=ble.PAIRING_REQUIRE_MITM)
78+
# Comment the line above, and uncomment the line below to use
79+
# bonding. Once bonded the pairing activity will no longer be
80+
# necessary on each connection as long as the keys are retained by
81+
# the devices.
82+
# ble.config(security=ble.PAIRING_REQUIRE_MITM | ble.PAIRING_REQUIRE_BONDING)
83+
84+
85+
print("Connecting")
86+
conn = ble.gap_connect(address_type, address)
87+
print("Connected")
88+
89+
# The delay is not necessary, just here to easily observe the
90+
# secured vs unsecured state.
91+
print("Wait for a bit before securing")
92+
time.sleep(5)
93+
94+
print("Securing")
95+
conn.secure(secure_cb)
96+
97+
print("Sleep forever")
98+
while True:
99+
time.sleep(1)
100+
101+
102+
if __name__ == "__main__":
103+
main()
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
XBee-to-XBee Bluetooth Connection Sample Application
2+
======================================
3+
4+
This example demonstrates XBee to XBee communication by creating an
5+
authenticated and encrypted connection to the API service of a remote
6+
XBee 3 device.
7+
8+
When run the example will connect to the specified XBee address with
9+
the provided password and periodically query the time and temperature
10+
of the remote XBee.
11+
12+
Requirements
13+
------------
14+
15+
To run this example you need:
16+
17+
* Two XBee3 radio modules with MicroPython support.
18+
* One will act as the MicroPython host, the other the target for
19+
the API Service client.
20+
* Two carrier boards for the radio module (XBIB-U-DEV or XBIB-C board).
21+
22+
Setup
23+
-----
24+
25+
Make sure the hardware is set up correctly:
26+
27+
1. Plug the XBee3 radio modules into the XBee adapters and connect to
28+
your computer's USB port.
29+
2. On the XBee3 that will act as the API Service server
30+
1. Enable Bluetooth
31+
2. Configure a password and take note of the Bluetooth address and
32+
password for customization of the MicroPython application.
33+
34+
Run
35+
---
36+
37+
The example must be configured prior to execution by providing the
38+
Bluetooth address and the password for the server XBee3. The example
39+
code should be modified to provide these values in the ADDRESS and
40+
PASSWORD variables at the top of the file.
41+
42+
When run the script reports when it performs a query and provides
43+
interpreted response data for the time and temperature when it is
44+
received.
45+
46+
Required libraries
47+
--------------------
48+
49+
N/A
50+
51+
Supported platforms
52+
-------------------
53+
54+
* Digi XBee3 Cellular LTE-M/NB-IoT - minimum firmware version: 11416
55+
* Digi XBee3 Cellular LTE Cat 1 - minimum firmware version: x16
56+
57+
License
58+
-------
59+
60+
Copyright (c) 2020, Digi International, Inc.
61+
62+
Permission is hereby granted, free of charge, to any person obtaining a copy
63+
of this software and associated documentation files (the "Software"), to deal
64+
in the Software without restriction, including without limitation the rights
65+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66+
copies of the Software, and to permit persons to whom the Software is
67+
furnished to do so, subject to the following conditions:
68+
69+
The above copyright notice and this permission notice shall be included in all
70+
copies or substantial portions of the Software.
71+
72+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
75+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
76+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
77+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78+
SOFTWARE.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright (c) 2020, Digi International Inc.
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in
11+
# all copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
import time
21+
import struct
22+
from binascii import unhexlify
23+
24+
from digi import ble
25+
ble.active(True)
26+
27+
# Replace these with the BL and password values for your XBee
28+
ADDRESS = "90FD9F7B764B"
29+
PASSWORD = "password"
30+
31+
DT_request = unhexlify("7E000508014454015D")
32+
TP_request = unhexlify("7E00040801545052")
33+
34+
35+
def process_at_cmd_response(payload):
36+
frame_id, at_cmd, status = struct.unpack(">B2sB", payload[:4])
37+
value = payload[4:]
38+
if at_cmd == b"DT":
39+
print("Peer responded with time: {}".format(value))
40+
elif at_cmd == b"TP":
41+
(temp,) = struct.unpack(">H", value)
42+
print("Peer responded with temperature: {}".format(temp))
43+
44+
45+
def process_frame(frame):
46+
delim, len, cmd = struct.unpack(">BHB", frame[:4]) # Throw away initial delimiter
47+
payload = frame[4:-1] # Throw away CRC, checked by receive logic
48+
49+
if cmd == 0x88:
50+
process_at_cmd_response(payload)
51+
52+
53+
def main():
54+
conn = ble.gap_connect(ble.ADDR_TYPE_PUBLIC, unhexlify(ADDRESS))
55+
xbeeconn = ble.xbee_connect(conn, process_frame, PASSWORD, timeout=10)
56+
57+
while True:
58+
print("Querying DT & TP")
59+
xbeeconn.send(DT_request)
60+
xbeeconn.send(TP_request)
61+
time.sleep(5)
62+
63+
64+
main()

0 commit comments

Comments
 (0)