Hello!
I'm trying to make what initially seemed like a straightfoward program - a bluetooth-to-hid adapter.
Since Nordic's sample (BLE Central HIDS) uses the hogp and bt_scan libs, I decided to try using them as well.
However, I seem to be stuck at getting the services from the bt_conn once I've established it.
The program finds the device, and then errors out with the following message:
[00:01:08.417,694] <err> bt_gatt_dm: Discover failed, error: -128.
As far as I can tell, this is a lack of memory error code, so I tried adding memory both to the heap, as well
as touching the CONFIG_BT_ATT_TX_COUNT config.
I've attached both the prj.conf and the main.c below.
(please have in mind I'm new and this is my first serious attempt at embedded programming, so there may be other mistakes along the way)
/* --- Header --- */ #include <zephyr/kernel.h> #include <zephyr/logging/log.h> // The main lib itself includes #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/conn.h> #include <zephyr/bluetooth/uuid.h> #include <bluetooth/scan.h> #include <bluetooth/gatt_dm.h> #include <bluetooth/services/hogp.h> #define TARGET_DEVICE_NAME "Flow84@Lofree" struct bt_conn *target_conn; struct bt_hogp target_hogp; LOG_MODULE_REGISTER(ska_logging, LOG_LEVEL_INF); /* --- End Header --- */ /* --- BLE Connection Handling --- */ static void scan_filter_match(struct bt_scan_device_info *device_info, struct bt_scan_filter_match *filter_match, bool connectable); static void scan_filter_no_match(struct bt_scan_device_info *device_info, bool connectable); static void connecting_error(struct bt_scan_device_info *device_info); static void connecting(struct bt_scan_device_info *device_info, struct bt_conn *conn); BT_SCAN_CB_INIT(scan_cb, scan_filter_match, scan_filter_no_match, connecting_error, connecting); static const struct bt_le_scan_param scan_params = { .type = BT_LE_SCAN_TYPE_ACTIVE, .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, .interval = BT_GAP_SCAN_FAST_INTERVAL, .window = BT_GAP_SCAN_FAST_WINDOW, }; static const struct bt_scan_init_param init_params = { .scan_param = &scan_params, .connect_if_match = true, .conn_param = NULL, }; /* --- End BLE Connection Handling --- */ /* --- GATT Discovery Functions --- */ static void dm_completed(struct bt_gatt_dm *dm, void *context); static void dm_error(struct bt_conn *conn, int err, void *context); static void dm_service_not_found(struct bt_conn *conn, void *context); static struct bt_gatt_dm_cb dm_cbs = { .completed = dm_completed, .error_found = dm_error, .service_not_found = dm_service_not_found, }; /* --- End GATT Discovery Functions */ /* --- HOGP Handling --- */ static void hogp_ready(struct bt_hogp *hogp); static void hogp_init_error(struct bt_hogp *hogp, int error); static void hogp_pm_update(struct bt_hogp *hogp); static struct bt_hogp_init_params hogp_params = { .ready_cb = hogp_ready, .prep_error_cb = hogp_init_error, .pm_update_cb = hogp_pm_update, }; /* --- End HOGP Handling --- */ int main(void) { int err; err = bt_enable(NULL); if(err) { LOG_INF("Error initializing Bluetooth stack."); return 1; } bt_hogp_init(&target_hogp, &hogp_params); // Note: The filtering needs to be defined after the scan object has been initialized bt_scan_init(&init_params); bt_scan_cb_register(&scan_cb); bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_HIDS); bt_scan_filter_enable(BT_SCAN_UUID_FILTER, true); bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); return 0; } static void scan_filter_match(struct bt_scan_device_info *device_info, struct bt_scan_filter_match *filter_match, bool connectable) { char addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(device_info->recv_info->addr, addr_str, sizeof(addr_str)); if(filter_match->uuid.match) { LOG_INF("HID Device found at addr %s with RSSI of %d db. The device is %s", addr_str, device_info->recv_info->rssi, connectable ? "connectable." : "not connectable"); } } static void scan_filter_no_match(struct bt_scan_device_info *device_info, bool connectable) { // char addr_str[BT_ADDR_LE_STR_LEN]; // bt_addr_le_to_str(device_info->recv_info->addr, addr_str, sizeof(addr_str)); // LOG_INF("Non-HID device found at address %s with RSSI of %d db", addr_str, device_info->recv_info->rssi); } static void connecting_error(struct bt_scan_device_info *device_info) { char addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(device_info->recv_info->addr, addr_str, sizeof(addr_str)); LOG_ERR("Error connecting to target device at address %s.", addr_str); return; } // I'm doing quite a bit in the connecting function, but it's the only logical point to start most of the opetations static void connecting(struct bt_scan_device_info *device_info, struct bt_conn *conn) { int err; char addr_str[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(device_info->recv_info->addr, addr_str, sizeof(addr_str)); LOG_INF("Target device found at address %s, connecting...", addr_str); if(!conn) { LOG_ERR("Received NULL pointer for connection object, aborting."); return; } target_conn = bt_conn_ref(conn); LOG_INF("Connected! Connection information saved in the global variable. Now starting GATT discovery"); err = bt_gatt_dm_start(conn, BT_UUID_HIDS, &dm_cbs, NULL); } static void dm_completed(struct bt_gatt_dm *dm, void *context) { LOG_INF("HID Service discovery complete!"); int err = bt_hogp_handles_assign(dm, &target_hogp); if (err) { LOG_ERR("Failed to assign HOGP handles: %d", err); bt_gatt_dm_data_release(dm); return; } bt_gatt_dm_data_print(dm); // const struct bt_hogp_rep_info *rep = NULL; bt_gatt_dm_data_release(dm); } static void dm_error(struct bt_conn *conn, int err, void *context) { LOG_INF("Error when discovering HID service: %d", err); } static void dm_service_not_found(struct bt_conn *conn, void *context) { LOG_INF("HID service not found."); } static void hogp_ready(struct bt_hogp *hogp) { LOG_INF("The HOG profile has been created successfully."); } static void hogp_init_error(struct bt_hogp *hogp, int error) { LOG_INF("Error initializing the HOGP struct: %d", error); } static void hogp_pm_update(struct bt_hogp *hogp) { }