README.rst
1.. _bluetooth-ipsp-sample:
2
3Bluetooth: IPSP Sample
4######################
5
6Overview
7********
8Application demonstrating the IPSP (Internet Protocol Support Profile) Node
9role. IPSP is the Bluetooth profile that underneath utilizes 6LoWPAN, i.e. gives
10you IPv6 connectivity over BLE.
11
12Building and Running
13********************
14
15This sample can be found under :zephyr_file:`samples/bluetooth/ipsp` in the
16Zephyr tree.
17Sample can be built and executed for the nRF52840 DK NRF52840 as follows:
18
19.. zephyr-app-commands::
20 :zephyr-app: samples/bluetooth/ipsp
21 :board: nrf52840dk_nrf52840
22 :goals: build flash
23 :compact:
24
25To build a debug version, with logging and shell support, use the config file
26:file:`prj_dbg.conf`:
27
28.. zephyr-app-commands::
29 :zephyr-app: samples/bluetooth/ipsp
30 :board: nrf52840dk_nrf52840
31 :conf: prj_dbg.conf
32 :goals: build flash
33 :compact:
34
35Building and Running for Linux kernels released before 4.12
36===========================================================
37.. note::
38
39 For hosts using kernels released before 4.12,
40 option :kconfig:`CONFIG_NET_L2_BT_ZEP1656`
41 must be selected. For more information, see `Zephyr issue #3111
42 <https://github.com/zephyrproject-rtos/zephyr/issues/3111>`_
43
44.. zephyr-app-commands::
45 :zephyr-app: samples/bluetooth/ipsp
46 :board: nrf52840dk_nrf52840
47 :conf: "prj_zep1656.conf"
48 :goals: build flash
49 :compact:
50
51Testing with a Linux host
52=========================
53
54Make sure the Linux kernel has been built with Bluetooth 6LoWPAN module
55(CONFIG_BT_6LOWPAN=y) then proceed to enable it with with the following commands
56(as root):
57
58.. code-block:: console
59
60 # modprobe bluetooth_6lowpan
61 # echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
62
63If you connected your board to a UART console, you will see an output similar to
64(may vary slightly by application and Zephyr versions):
65
66.. code-block:: console
67
68 [bt] [WRN] set_static_addr: Using temporary static random address
69 [bt] [INF] show_dev_info: Identity: cb:af:14:57:d8:6e (random)
70 [bt] [INF] show_dev_info: HCI: version 5.0 (0x09) revision 0x0000, manufacturer 0xffff
71 [bt] [INF] show_dev_info: LMP: version 5.0 (0x09) subver 0xffff
72 [bt] [WRN] bt_pub_key_gen: ECC HCI commands not available
73 [ipsp] [INF] init_app: Run IPSP sample
74 [ipsp] [INF] listen: Starting to wait
75
76The output above shows the BLE address assigned to your board for the
77current session; the address will be different on subsequent sessions.
78
79Alternatively, you may scan for your board on the host. The modern way to do
80that is using ``bluetoothctl`` utility (included in the recent versions of
81BlueZ package) and its ``scan on`` command:
82
83.. code-block:: console
84
85 $ bluetoothctl
86 [NEW] Controller A3:24:97:EB:D6:23 ubuntu-0 [default]
87 [NEW] Device D7:5C:D6:18:14:87 Zephyr
88 [NEW] Device E1:E7:F9:56:EC:06 Zephyr
89 [NEW] Device C8:12:C5:08:86:E1 Zephyr
90 [bluetooth]# scan on
91 Discovery started
92 [NEW] Device DC:98:FB:22:CA:3A Zephyr
93
94When started, ``bluetoothctl`` shows all BLE (and likely, BT/EDR) devices it
95knows about. As discussed above, the IPSP uses static random addresses, so
96entries for previously connected devices, as shown above, can accumulate and
97become stale. You need to be extra careful to find an entry for the active
98address. The best approach may be to reset your board after issuing
99``scan on`` command. This way it will reinitialize with the BLE address
100which will be discovered after the command.
101
102As an alternative to ``bluetoothctl``, you can use the legacy ``hcitool``
103utility which talks directly to hardware and always shows fresh scan results:
104
105.. code-block:: console
106
107 $ sudo hcitool lescan
108 LE Scan ...
109 CB:AF:14:57:D8:6E (unknown)
110 CB:AF:14:57:D8:6E Test IPSP node
111
112After you have found the board's BLE address, connect to the board (as root):
113
114.. code-block:: console
115
116 # echo "connect <bdaddr> <type>" > /sys/kernel/debug/bluetooth/6lowpan_control
117
118Where ``<bdaddr>`` is the BLE address and ``<type>`` is BLE address type:
1191 for public address and 2 for random address. As you can see from
120the IPSP sample output above, it uses a static random address. So, with the
121sample output above, the command will be:
122
123.. code-block:: console
124
125 # echo "connect CB:AF:14:57:D8:6E 2" > /sys/kernel/debug/bluetooth/6lowpan_control
126
127Once connected a dedicated interface will be created, usually bt0. You can verify this
128with the following command:
129
130.. code-block:: console
131
132 # ifconfig
133 bt0 Link encap:UNSPEC HWaddr F8-2F-A8-FF-FE-EB-6D-8C-00-00-00-00-00-00-00-00
134 inet6 addr: fe80::fa2f:a8ff:feeb:6d8c/64 Scope:Link
135 UP POINTOPOINT RUNNING MULTICAST MTU:1280 Metric:1
136 RX packets:2 errors:0 dropped:3 overruns:0 frame:0
137 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
138 collisions:0 txqueuelen:1000
139 RX bytes:92 (92.0 B) TX bytes:233 (233.0 B)
140
141As can be seen from the output, only a link-local IPv6 address was assigned
142to the interface.
143
144At this point, you can test IPv6 connectivity (and discover your board's IPv6
145address) by pinging "All local-link nodes" IPv6 address:
146
147.. code-block:: console
148
149 # ping6 -I bt0 ff02::1
150 PING ff02::1(ff02::1) from fe80::fa54:a8ff:feeb:218f bt0: 56 data bytes
151 64 bytes from fe80::fa54:a8ff:feeb:218f: icmp_seq=1 ttl=64 time=0.088 ms
152 64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=1 ttl=64 time=285 ms (DUP!)
153
154For each ping packet, both your host and the BLE board send a reply. You
155can see the board's reply marked as ``(DUP!)``. You can ping the board
156directly with:
157
158.. code-block:: console
159
160 # ping6 fe80::c9af:14ff:fe57:d86e%bt0
161 PING fe80::c9af:14ff:fe57:d86e%bt0(fe80::c9af:14ff:fe57:d86e) 56 data bytes
162 64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=1 ttl=64 time=177 ms
163 64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=2 ttl=64 time=53.0 ms
164
165Note that the command uses a "scoped IPv6 address", where the scope is
166defined by the networking interface, with ``%bt0`` appended in this case.
167A specification like that is an alternative to passing ``-I bt0`` to
168``ping6`` (and works with other networking tools like ``telnet``, ``nc``,
169``curl``, etc.)
170
171While we can use a link-local address, it's not very convenient, as it must be
172scoped and will change on each run. Instead, the IPSP sample is configured with
173``2001:db8::1`` static address and we'll configure the host's interface to
174access that address by configuring ``bt0`` with the complementary address
175``2001:db8::2``:
176
177.. code-block:: console
178
179 # ip address add 2001:db8::2/64 dev bt0
180
181Now we can ping the board's static address with:
182
183.. code-block:: console
184
185 # ping6 2001:db8::1
186 PING 2001:db8::1(2001:db8::1) 56 data bytes
187 64 bytes from 2001:db8::1: icmp_seq=1 ttl=64 time=282 ms
188
189The IPSP sample includes builtin echo server for UDP and TCP on a port 4242,
190which we can test with:
191
192.. code-block:: console
193
194 $ telnet 2001:db8::1 4242
195 Trying 2001:db8::1...
196 Connected to 2001:db8::1.
197 Escape character is '^]'.
198 test
199 test
200 test2
201 test2
202 ^]
203 telnet> quit
204 Connection closed.
205
206In the output above, first ``test`` line was typed, next was echoed back by
207the board. Likewise for ``test2``. To quit telnet tool, type Ctrl+], then
208"quit" at the prompt.
209
210As an alternative to using well-known networking tools above, and also to
211test both TCP and UDP echo, you can use Zephyr's helper tool in the GitHub
212``zephyrproject-rtos/net-tools`` repository:
213
214.. code-block:: console
215
216 $ echo-client -i bt0 <ip>
217