Last active
May 9, 2020 14:35
-
-
Save MZachmann/826c6894d4077d0cb4605997d1c7831b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "BlueSub.h" | |
#include "../AppInclude.h" | |
#if USE_BLUETOOTH | |
#pragma message "Using bluetooth" | |
#include <bluetooth/bluetooth.h> | |
#include <bluetooth/hci.h> | |
#include <bluetooth/uuid.h> | |
#include <bluetooth/gatt.h> | |
#include <logging/log.h> | |
LOG_MODULE_REGISTER(BlueSub, LOG_LEVEL_INF); | |
// log_strdup is required when logging transient strings | |
#define sd(x) log_strdup((x)) | |
// custom service definition for Nordic Uart Service | |
#define NUS_SVC_UUID 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, \ | |
0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x01, 0x40, 0x6E | |
// this Advertising Data set lists the services that we advertise | |
// see, for example, BT_UUID_DIS == BT_UUID_DECLARE_16(0x180a) | |
// then they just need to be instanced via BT_GATT_SERVICE_DEFINE | |
static const struct bt_data ad[] = { | |
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), | |
BT_DATA_BYTES(BT_DATA_UUID16_ALL, | |
0x09, 0x18, // HTS Service | |
0x0a, 0x18, // DIS Service | |
0x0f, 0x18), // Battery Service | |
BT_DATA_BYTES(BT_DATA_UUID128_ALL, NUS_SVC_UUID ), // nordic uart service | |
}; | |
// this is where bluetooth will assert | |
void bt_ctlr_assert_handle(char *name, int type) | |
{ | |
if(name != NULL) | |
LOG_ERR("Bt assert-> %s", sd(name)); | |
} | |
// ------------------------------------- | |
// MTU Exchange | |
// ------------------------------------- | |
// these are all static to allow async... | |
static struct bt_gatt_exchange_params _ExParams; | |
static int _MtuSize = 0; | |
// this clears the passed-in fnptr to indicate the exchange is done | |
static void ExchangeMtuFunc(struct bt_conn *conn, u8_t err, struct bt_gatt_exchange_params *params) | |
{ | |
params->func = NULL; | |
} | |
// this seems to set the mtu to 65 bytes at least on nrfConnect | |
static void DoExchangeMtu(struct bt_conn *conn) | |
{ | |
if(_MtuSize == 0) | |
{ | |
_ExParams.func = ExchangeMtuFunc; | |
if(0 == bt_gatt_exchange_mtu(conn, &_ExParams)) | |
{ | |
// the exchange is async so get_mtu would get the prior value | |
_MtuSize = 10; // bt_gatt_get_mtu(conn); | |
LOG_INF("Mtu exchange started successfully"); | |
} | |
else | |
{ | |
LOG_WRN("Mtu exchange failed to start"); | |
} | |
} | |
} | |
// ------------------------------------- | |
// Callbacks | |
// ------------------------------------- | |
// a host connects to us - callback | |
static void connected(struct bt_conn *conn, u8_t err) | |
{ | |
char addr[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | |
if (err) | |
{ | |
LOG_ERR("Failed to connect to %s (%u)\n", sd(addr), err); | |
} | |
else | |
{ | |
LOG_INF("Connected %s\n", sd(addr)); | |
// - i'm not using security for now, but if ... | |
// if (bt_conn_set_security(conn, BT_SECURITY_L2)) { | |
// LOG_ERR("Failed to set security\n"); | |
// } | |
// for some reason there is no mtu exchange so force it in the callback | |
DoExchangeMtu(conn); | |
} | |
} | |
// a host disconnects from us - callback | |
static void disconnected(struct bt_conn *conn, u8_t reason) | |
{ | |
char addr[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | |
LOG_INF("Disconnected from %s (reason 0x%02x)\n", sd(addr), reason); | |
} | |
// identity resolve callback | |
static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa, | |
const bt_addr_le_t *identity) | |
{ | |
char addr_identity[BT_ADDR_LE_STR_LEN]; | |
char addr_rpa[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity)); | |
bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa)); | |
LOG_INF("Identity resolved %s -> %s\n", sd(addr_rpa), sd(addr_identity)); | |
} | |
// security changed callback | |
static void security_changed(struct bt_conn *conn, bt_security_t level, | |
enum bt_security_err err) | |
{ | |
char addr[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | |
if (!err) { | |
LOG_WRN("Security changed: %s level %u\n", sd(addr), level); | |
} else { | |
LOG_ERR("Security failed: %s level %u err %d\n", sd(addr), level, err); | |
} | |
} | |
static struct bt_conn_cb conn_callbacks = { | |
.connected = connected, | |
.disconnected = disconnected, | |
.identity_resolved = identity_resolved, | |
.security_changed = security_changed, | |
}; | |
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) | |
{ | |
char addr[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | |
LOG_INF("Passkey for %s: %06u\n", sd(addr), passkey); | |
} | |
static void auth_cancel(struct bt_conn *conn) | |
{ | |
char addr[BT_ADDR_LE_STR_LEN]; | |
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | |
LOG_INF("Pairing cancelled: %s\n", sd(addr)); | |
} | |
static struct bt_conn_auth_cb auth_cb_display = { | |
.passkey_display = auth_passkey_display, | |
.passkey_entry = NULL, | |
.cancel = auth_cancel, | |
}; | |
// -------------------------------- | |
// higher level methods | |
// -------------------------------- | |
// the usual bt_ready bluetooth callback | |
static void bt_ready(int err) | |
{ | |
if (err) | |
{ | |
LOG_ERR("Bluetooth init failed (err %d)\n", err); | |
return; | |
} | |
LOG_INF("Bluetooth initialized\n"); | |
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); | |
if (err) | |
{ | |
LOG_ERR("Advertising failed to start (err %d)\n", err); | |
return; | |
} | |
LOG_INF("Advertising successfully started\n"); | |
} | |
int bt_start(void) | |
{ | |
int err = bt_enable(bt_ready); | |
if (! err) | |
{ | |
bt_conn_cb_register(&conn_callbacks); | |
bt_conn_auth_cb_register(&auth_cb_display); | |
} | |
else | |
{ | |
LOG_ERR("Bluetooth init failed (err %d)\n", err); | |
} | |
return err; | |
} | |
#else | |
#pragma message "Not using bluetooth" | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment