99#include <zephyr/bluetooth/hci.h>
1010#include <zephyr/net/net_if.h>
1111#include <zephyr/net/dhcpv4.h>
12+ #include <zephyr/drivers/gpio.h>
1213
1314#include <golioth/client.h>
1415#include <golioth/gateway.h>
1516#include <samples/common/sample_credentials.h>
1617
1718#include <pouch/transport/gatt/common/types.h>
1819
20+ #include <pouch_gateway/bt/bond.h>
1921#include <pouch_gateway/bt/connect.h>
2022#include <pouch_gateway/bt/scan.h>
2123#include <pouch_gateway/cert.h>
@@ -29,6 +31,31 @@ LOG_MODULE_REGISTER(main);
2931
3032struct golioth_client * client ;
3133
34+ static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR (DT_ALIAS (sw0 ), gpios , {});
35+ static struct gpio_callback button_cb_data ;
36+ static struct bt_conn * default_conn ;
37+
38+ static const k_timeout_t bonding_timeout = K_SECONDS (30 );
39+ static const bt_security_t bt_security =
40+ IS_ENABLED (CONFIG_POUCH_GATEWAY_GATT_SCAN_FILTER_BONDED ) ? BT_SECURITY_L4 : BT_SECURITY_L2 ;
41+
42+ static void button_pressed (const struct device * dev , struct gpio_callback * cb , uint32_t pins )
43+ {
44+ if (default_conn )
45+ {
46+ LOG_INF ("Confirming passkey" );
47+ bt_conn_auth_passkey_confirm (default_conn );
48+ }
49+ else if (pouch_gateway_bonding_is_enabled ())
50+ {
51+ LOG_WRN ("Bonding already enabled" );
52+ }
53+ else
54+ {
55+ pouch_gateway_bonding_enable (bonding_timeout );
56+ }
57+ }
58+
3259#ifdef CONFIG_POUCH_GATEWAY_CLOUD
3360
3461static K_SEM_DEFINE (connected , 0 , 1 ) ;
@@ -159,8 +186,9 @@ static void bt_connected(struct bt_conn *conn, uint8_t err)
159186 }
160187
161188 LOG_INF ("Connected: %s" , addr );
189+ default_conn = conn ;
162190
163- err = bt_conn_set_security (conn , BT_SECURITY_L2 );
191+ err = bt_conn_set_security (conn , bt_security );
164192 if (err )
165193 {
166194 LOG_ERR ("Failed to set security (%d)." , err );
@@ -174,6 +202,8 @@ static void bt_disconnected(struct bt_conn *conn, uint8_t reason)
174202{
175203 char addr [BT_ADDR_LE_STR_LEN ];
176204
205+ default_conn = NULL ;
206+
177207 bt_addr_le_to_str (bt_conn_get_dst (conn ), addr , sizeof (addr ));
178208 LOG_INF ("Disconnected: %s, reason 0x%02x %s" , addr , reason , bt_hci_err_to_str (reason ));
179209
@@ -222,8 +252,43 @@ static void auth_cancel(struct bt_conn *conn)
222252 LOG_INF ("Pairing cancelled: %s" , addr );
223253}
224254
255+ static void auth_passkey_confirm (struct bt_conn * conn , unsigned int passkey )
256+ {
257+ char addr [BT_ADDR_LE_STR_LEN ];
258+ char passkey_str [7 ];
259+
260+ bt_addr_le_to_str (bt_conn_get_dst (conn ), addr , sizeof (addr ));
261+
262+ snprintk (passkey_str , 7 , "%06u" , passkey );
263+
264+ LOG_INF ("Confirm passkey for %s: %s" , addr , passkey_str );
265+
266+ if (IS_ENABLED (CONFIG_SAMPLE_POUCH_GATEWAY_BT_AUTO_CONFIRM ))
267+ {
268+ LOG_INF ("Confirming passkey" );
269+ bt_conn_auth_passkey_confirm (conn );
270+ }
271+ }
272+
273+ static void auth_passkey_display (struct bt_conn * conn , unsigned int passkey )
274+ {
275+ char addr [BT_ADDR_LE_STR_LEN ];
276+ char passkey_str [7 ];
277+
278+ bt_addr_le_to_str (bt_conn_get_dst (conn ), addr , sizeof (addr ));
279+
280+ snprintk (passkey_str , 7 , "%06u" , passkey );
281+
282+ LOG_INF ("Passkey for %s: %s" , addr , passkey_str );
283+ }
284+
225285static struct bt_conn_auth_cb auth_cb = {
226286 .cancel = auth_cancel ,
287+
288+ .passkey_confirm =
289+ IS_ENABLED (CONFIG_POUCH_GATEWAY_GATT_SCAN_FILTER_BONDED ) ? auth_passkey_confirm : NULL ,
290+ .passkey_display =
291+ IS_ENABLED (CONFIG_POUCH_GATEWAY_GATT_SCAN_FILTER_BONDED ) ? auth_passkey_display : NULL ,
227292};
228293
229294static void pairing_complete (struct bt_conn * conn , bool bonded )
@@ -252,16 +317,42 @@ void pouch_gateway_bt_finished(struct bt_conn *conn)
252317
253318int main (void )
254319{
320+ int err ;
321+
255322 LOG_INF ("Gateway Version: " STRINGIFY (GIT_DESCRIBE ));
256323 LOG_INF ("Pouch BLE Transport Protocol Version: %d" , POUCH_GATT_VERSION );
257324
325+ if (DT_HAS_ALIAS (sw0 ))
326+ {
327+ LOG_INF ("Set up button at %s pin %d" , button .port -> name , button .pin );
328+
329+ err = gpio_pin_configure_dt (& button , GPIO_INPUT );
330+ if (err < 0 )
331+ {
332+ LOG_ERR ("Could not initialize Button" );
333+ }
334+
335+ err = gpio_pin_interrupt_configure_dt (& button , GPIO_INT_EDGE_TO_ACTIVE );
336+ if (err )
337+ {
338+ LOG_ERR ("Error %d: failed to configure interrupt on %s pin %d" ,
339+ err ,
340+ button .port -> name ,
341+ button .pin );
342+ return 0 ;
343+ }
344+
345+ gpio_init_callback (& button_cb_data , button_pressed , BIT (button .pin ));
346+ gpio_add_callback (button .port , & button_cb_data );
347+ }
348+
258349 connect_to_cloud ();
259350
260351 pouch_gateway_cert_module_on_connected (client );
261352 pouch_gateway_uplink_module_init (client );
262353 pouch_gateway_downlink_module_init (client );
263354
264- int err = bt_enable (NULL );
355+ err = bt_enable (NULL );
265356 if (err )
266357 {
267358 LOG_ERR ("Bluetooth init failed (err %d)" , err );
@@ -276,6 +367,11 @@ int main(void)
276367
277368 LOG_INF ("Bluetooth initialized" );
278369
370+ if (IS_ENABLED (CONFIG_SAMPLE_POUCH_GATEWAY_BT_AUTO_BOND ))
371+ {
372+ pouch_gateway_bonding_enable (K_FOREVER );
373+ }
374+
279375 pouch_gateway_scan_start ();
280376
281377#ifdef CONFIG_POUCH_GATEWAY_CLOUD
0 commit comments