diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble.c b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble.c index e0b8171cb13c..6ae1cbb54b4e 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble.c +++ b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble.c @@ -29,7 +29,7 @@ #include "ui.h" #define SEND_NOTIFY_STACK_SIZE 2048 -#define SEND_NOTIFY_PRIORITY 9 +#define SEND_NOTIFY_PRIORITY 5 #define SUBSCRIPTION_LIMIT 16 #define NOTIFICATION_QUEUE_LIMIT 10 #define MAX_BUF_SIZE 11000 @@ -234,8 +234,11 @@ void ble_register_notify_callback(notification_cb_t callback) } /* Thread responsible for transferring ble data over MQTT */ -void send_notify_data(int unused1, int unused2, int unused3) +static void send_ble_read_data(int unused1, int unused2, int unused3) { + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + ARG_UNUSED(unused3); char uuid[BT_UUID_STR_LEN]; char path[BT_MAX_PATH_LEN]; @@ -251,6 +254,9 @@ void send_notify_data(int unused1, int unused2, int unused3) if (rx_data == NULL) { continue; } + atomic_dec(&queued_notifications); + LOG_DBG("Queued: %ld", atomic_get(&queued_notifications)); + err = ble_conn_mgr_get_conn_by_addr(rx_data->addr_trunc, &connected_ptr); if (err) { LOG_ERR("Connection not found for addr %s", @@ -262,13 +268,14 @@ void send_notify_data(int unused1, int unused2, int unused3) if (rx_data->read) { handle = rx_data->read_params.single.handle; - LOG_INF("Read: Addr %s Handle %d", + LOG_INF("Dequeued gatt_read results, addr %s handle %d", rx_data->addr_trunc, handle); } else { handle = rx_data->sub_params.value_handle; - LOG_DBG("Notify Addr %s Handle %d", + LOG_DBG("Dequeued BLE notification data, addr %s handle %d", rx_data->addr_trunc, handle); } + LOG_HEXDUMP_DBG(rx_data->data, rx_data->length, "notify"); err = ble_conn_mgr_get_uuid_by_handle(handle, uuid, connected_ptr); if (err) { @@ -296,8 +303,6 @@ void send_notify_data(int unused1, int unused2, int unused3) goto cleanup; } - LOG_HEXDUMP_DBG(rx_data->data, rx_data->length, "notify"); - if (!rx_data->read && notify_callback) { err = notify_callback(rx_data->addr_trunc, uuid, rx_data->data, rx_data->length); @@ -335,9 +340,11 @@ void send_notify_data(int unused1, int unused2, int unused3) LOG_ERR("Unable to encode: %d", err); goto cleanup; } + /* LOG_DBG("UUID %s, path %s, len %u, json %s", uuid, path, rx_data->length, (char *)output.data.ptr); + */ err = g2c_send(&output.data); k_mutex_unlock(&output.lock); if (err) { @@ -346,12 +353,11 @@ void send_notify_data(int unused1, int unused2, int unused3) cleanup: k_free(rx_data); - atomic_dec(&queued_notifications); } } K_THREAD_DEFINE(ble_rec_thread, SEND_NOTIFY_STACK_SIZE, - send_notify_data, NULL, NULL, NULL, + send_ble_read_data, NULL, NULL, NULL, SEND_NOTIFY_PRIORITY, 0, 0); static void discovery_completed(struct bt_gatt_dm *disc, void *ctx) @@ -460,8 +466,6 @@ static uint8_t gatt_read_callback(struct bt_conn *conn, uint8_t err, bt_to_upper(addr_trunc, BT_ADDR_LE_STR_LEN); - LOG_INF("Read Addr %s", addr_trunc); - struct rec_data_t read_data = { .fifo_reserved = NULL, .length = length, @@ -488,6 +492,8 @@ static uint8_t gatt_read_callback(struct bt_conn *conn, uint8_t err, atomic_inc(&queued_notifications); memcpy(mem_ptr, &read_data, size); k_fifo_put(&rec_fifo, mem_ptr); + LOG_DBG("Enqueued gatt_read results %ld", + atomic_get(&queued_notifications)); } } @@ -631,10 +637,11 @@ int gatt_write_without_response(char *ble_addr, char *chrc_uuid, uint8_t *data, err = bt_gatt_write_without_response(conn, handle, data, data_len, false); + bt_conn_unref(conn); return err; } -static uint8_t on_received(struct bt_conn *conn, +static uint8_t on_notification_received(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length) { @@ -669,8 +676,7 @@ static uint8_t on_received(struct bt_conn *conn, if (atomic_get(&queued_notifications) >= NOTIFICATION_QUEUE_LIMIT) { - struct rec_data_t *rx_data = k_fifo_get(&rec_fifo, - K_NO_WAIT); + struct rec_data_t *rx_data = k_fifo_get(&rec_fifo, K_NO_WAIT); LOG_INF("Dropping oldest message"); if (rx_data != NULL) { @@ -701,6 +707,8 @@ static uint8_t on_received(struct bt_conn *conn, atomic_inc(&queued_notifications); memcpy(mem_ptr, &tx_data, size); k_fifo_put(&rec_fifo, mem_ptr); + LOG_DBG("Enqueued BLE notification data %ld", + atomic_get(&queued_notifications)); } } @@ -809,7 +817,7 @@ int ble_subscribe(char *ble_addr, char *chrc_uuid, uint8_t value_type) ble_addr, handle); } else if (curr_subs < SUBSCRIPTION_LIMIT) { if (conn != NULL) { - sub_param[next_sub_index].notify = on_received; + sub_param[next_sub_index].notify = on_notification_received; sub_param[next_sub_index].value = value_type; sub_param[next_sub_index].value_handle = handle; sub_param[next_sub_index].ccc_handle = handle + 1; @@ -1185,7 +1193,6 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) if (connection_ptr) { ble_conn_set_connected(connection_ptr, false); } - bt_conn_unref(conn); return; } @@ -1204,7 +1211,7 @@ static void connected(struct bt_conn *conn, uint8_t conn_err) } } - //ui_led_set_pattern(UI_BLE_CONNECTED, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_CONNECTED, PWM_DEV_1); */ if (!connection_ptr->connected) { LOG_INF("Connected: %s", addr); @@ -1269,7 +1276,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason) } } - //ui_led_set_pattern(UI_BLE_DISCONNECTED, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_DISCONNECTED, PWM_DEV_1); */ /* Start the timer to begin scanning again. */ k_timer_start(&auto_conn_start_timer, K_SECONDS(3), K_SECONDS(0)); diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble_conn_mgr.c b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble_conn_mgr.c index 7976a271a52c..d0cb90eb13b6 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble_conn_mgr.c +++ b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ble_conn_mgr.c @@ -90,6 +90,7 @@ static void process_connection(int i) void connection_manager(int unused1, int unused2, int unused3) { int i; + bool printed = false; ble_conn_mgr_init(); while (1) { @@ -97,10 +98,14 @@ void connection_manager(int unused1, int unused2, int unused3) for (i = 0; i < CONFIG_BT_MAX_CONN; i++) { /* Manager is busy. Do nothing. */ if (connected_ble_devices[i].discovering) { - LOG_DBG("Connection work busy."); + if (!printed) { + LOG_DBG("Connection work busy."); + printed = true; + } goto end; } } + printed = false; for (i = 0; i < CONFIG_BT_MAX_CONN; i++) { process_connection(i); diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.c b/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.c index b661d5762ea5..14810a45a53b 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.c +++ b/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.c @@ -34,8 +34,6 @@ LOG_MODULE_REGISTER(gateway, CONFIG_NRFCLOUD_BLE_GATEWAY_LOG_LEVEL); #define CLOUD_PROC_STACK_SIZE 2048 #define CLOUD_PROC_PRIORITY 5 -#define QUEUE_CHAR_READS - #define GET_PSK_ID "AT%CMNG=2,16842753,4" #define GET_PSK_ID_LEN (sizeof(GET_PSK_ID)-1) #define GET_PSK_ID_ERR "ERROR" @@ -45,7 +43,8 @@ LOG_MODULE_REGISTER(gateway, CONFIG_NRFCLOUD_BLE_GATEWAY_LOG_LEVEL); * to the fifo. There was no memory to unsubscribe from memory intensive * subscribes. */ -/* #define QUEUE_CHAR_WRITES */ +#define QUEUE_CHAR_WRITES +#define QUEUE_CHAR_READS #define VALUE_BUF_SIZE 256 static uint8_t value_buf[VALUE_BUF_SIZE]; @@ -56,14 +55,22 @@ struct cloud_data_t { void *fifo_reserved; char addr[BT_ADDR_STR_LEN]; char uuid[UUID_STR_LEN]; + uint8_t client_char_config; bool read; bool ccc; bool sub; - uint8_t client_char_config; +#if defined(QUEUE_CHAR_WRITES) + bool write; + size_t data_len; + uint8_t data[VALUE_BUF_SIZE]; +#endif }; +static atomic_t queued_cloud_data; K_FIFO_DEFINE(cloud_data_fifo); +static int gateway_handler(cJSON *json); + int gateway_shadow_delta_handler(struct nrf_cloud_obj *desired) { if (!desired || (desired->type != NRF_CLOUD_OBJ_TYPE_JSON) || (!desired->json)) { @@ -103,16 +110,24 @@ int gateway_shadow_transform_handler(struct nrf_cloud_obj *desired_conns) return desired_conns_handler(desired); } -void cloud_data_process(int unused1, int unused2, int unused3) +static void cloud_data_process(int unused1, int unused2, int unused3) { + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + ARG_UNUSED(unused3); struct k_mutex lock; int ret; k_mutex_init(&lock); while (1) { + LOG_DBG("Waiting for cloud_data_fifo"); struct cloud_data_t *cloud_data = k_fifo_get(&cloud_data_fifo, K_FOREVER); + atomic_dec(&queued_cloud_data); + LOG_DBG("Dequeued cloud_data_fifo element; still queued: %ld", + atomic_get(&queued_cloud_data)); + if (cloud_data != NULL) { k_mutex_lock(&lock, K_FOREVER); @@ -163,7 +178,7 @@ void cloud_data_process(int unused1, int unused2, int unused3) K_THREAD_DEFINE(cloud_proc_thread, CLOUD_PROC_STACK_SIZE, cloud_data_process, NULL, NULL, NULL, - CLOUD_PROC_PRIORITY, 0, 0); + K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0); static cJSON *json_object_decode(cJSON *obj, const char *str) { @@ -198,7 +213,7 @@ int gateway_data_handler(const struct nrf_cloud_data *const dev_msg) return err; } -int gateway_handler(cJSON *root_obj) +static int gateway_handler(cJSON *root_obj) { int ret = 0; cJSON *desired_obj; @@ -288,13 +303,13 @@ int gateway_handler(cJSON *root_obj) } memcpy(mem_ptr, &cloud_data, size); + atomic_inc(&queued_cloud_data); k_fifo_put(&cloud_data_fifo, mem_ptr); - LOG_INF("Queued device_characteristic_value_read addr:%s, uuid:%s", - cloud_data.addr, - cloud_data.uuid); + LOG_DBG("Queued device_characteristic_value_read addr:%s, uuid:%s; " + "queued: %ld", + cloud_data.addr, cloud_data.uuid, atomic_get(&queued_cloud_data)); #else - ret = gatt_read(ble_address->valuestring, - chrc_uuid->valuestring); + ret = gatt_read(ble_address->valuestring, chrc_uuid->valuestring, false); if (ret) { LOG_ERR("Error on gatt_read(%s, %s, 0): %d", ble_address->valuestring, @@ -339,13 +354,12 @@ int gateway_handler(cJSON *root_obj) } memcpy(mem_ptr, &cloud_data, size); + atomic_inc(&queued_cloud_data); k_fifo_put(&cloud_data_fifo, mem_ptr); - LOG_INF("Queued device_descriptor_value_read addr:%s, uuid:%s", - cloud_data.addr, - cloud_data.uuid); + LOG_DBG("Queued device_descriptor_value_read addr:%s, uuid:%s, queued: %ld", + cloud_data.addr, cloud_data.uuid, atomic_get(&queued_cloud_data)); #else - ret = gatt_read(ble_address->valuestring, - chrc_uuid->valuestring, true); + ret = gatt_read(ble_address->valuestring, chrc_uuid->valuestring, true); if (ret) { LOG_ERR("Error on gatt_read(%s, %s, 1): %d", ble_address->valuestring, @@ -364,9 +378,6 @@ int gateway_handler(cJSON *root_obj) desc_arr = json_object_decode(operation_obj, "descriptorValue"); - LOG_INF("Got device_descriptor_value_write: %s", - ble_address->valuestring); - desc_len = cJSON_GetArraySize(desc_arr); for (int i = 0; i < desc_len; i++) { cJSON *item = cJSON_GetArrayItem(desc_arr, i); @@ -374,7 +385,13 @@ int gateway_handler(cJSON *root_obj) desc_buf[i] = item->valueint; } + LOG_DBG("Got device_descriptor_value_write " + "addr: %s, uuid: %s, value: (0x%02X, 0x%02X)", + ble_address->valuestring, chrc_uuid->valuestring, + desc_buf[0], desc_buf[1]); + if ((ble_address != NULL) && (chrc_uuid != NULL)) { +#if defined(QUEUE_CHAR_WRITES) struct cloud_data_t cloud_data = { .sub = true, .read = false @@ -399,13 +416,26 @@ int gateway_handler(cJSON *root_obj) } memcpy(mem_ptr, &cloud_data, size); + atomic_inc(&queued_cloud_data); k_fifo_put(&cloud_data_fifo, mem_ptr); - LOG_INF("Queued device_descriptor_value_write addr:%s, uuid:%s, " - "ccc:%d, sub:%d, conf:%d", + LOG_DBG("Queued device_descriptor_value_write addr:%s, uuid:%s, " + "ccc:%d, sub:%d, conf:%d, queued:%ld", cloud_data.addr, cloud_data.uuid, cloud_data.ccc, cloud_data.sub, - cloud_data.client_char_config); + cloud_data.client_char_config, + atomic_get(&queued_cloud_data)); +#else + ret = gatt_write(ble_address->valuestring, + chrc_uuid->valuestring, + desc_buf, desc_len, NULL); + if (ret) { + LOG_ERR("Error on gatt_write(%s, %s): %d", + ble_address->valuestring, + chrc_uuid->valuestring, + ret); + } +#endif } } else if (compare(desired_obj->valuestring, @@ -418,10 +448,6 @@ int gateway_handler(cJSON *root_obj) "serviceUUID"); value_arr = json_object_decode(operation_obj, "characteristicValue"); - LOG_INF("Got device_characteristic_value_write addr: %s, svc uuid:%s, chrc uuid:%s", - ble_address->valuestring, - service_uuid ? service_uuid->valuestring : "n/a", - chrc_uuid ? chrc_uuid->valuestring : "n/a"); if (cJSON_IsString(value_arr)) { char *str = cJSON_GetStringValue(value_arr); @@ -438,7 +464,12 @@ int gateway_handler(cJSON *root_obj) } } - LOG_INF("device_characteristic_value_write: %s\n", value_buf); + LOG_DBG("Got device_characteristic_value_write " + "addr: %s, svc uuid:%s, chrc uuid:%s", + ble_address->valuestring, + service_uuid ? service_uuid->valuestring : "n/a", + chrc_uuid ? chrc_uuid->valuestring : "n/a"); + LOG_HEXDUMP_DBG(value_buf, value_len, "value"); if ((ble_address != NULL) && (chrc_uuid != NULL)) { #if defined(QUEUE_CHAR_WRITES) @@ -467,7 +498,11 @@ int gateway_handler(cJSON *root_obj) } memcpy(mem_ptr, &cloud_data, size); + atomic_inc(&queued_cloud_data); k_fifo_put(&cloud_data_fifo, mem_ptr); + LOG_DBG("Queued device_characteristic_value_write " + "addr:%s, uuid:%s, queued:%ld", + cloud_data.addr, cloud_data.uuid, atomic_get(&queued_cloud_data)); #else ret = gatt_write(ble_address->valuestring, chrc_uuid->valuestring, @@ -508,7 +543,7 @@ static void starting_button_handler(void) */ if (ui_button_is_active(1)) { printk("BOOT BUTTON HELD\n"); - //ui_led_set_pattern(UI_BLE_BUTTON, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_BUTTON, PWM_DEV_1); */ while (ui_button_is_active(1)) { k_sleep(K_MSEC(500)); } @@ -516,7 +551,7 @@ static void starting_button_handler(void) if (!is_boot_selected()) { printk("Boot held after reset but not long enough" " to select the nRF52840 bootloader!\n"); - //ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); */ } else { /* User wants to update the 52840 */ nrf52840_reset_to_mcuboot(); @@ -528,7 +563,7 @@ static void starting_button_handler(void) err = nrf52840_wait_boot_complete(WAIT_BOOT_TIMEOUT_MS); if (err == 0) { - //ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); */ k_sleep(K_SECONDS(1)); printk("nRF52840 update complete\n"); } else { @@ -705,7 +740,7 @@ void device_shutdown(bool reboot) #endif } - //ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); + /* ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); */ LOG_INF("Disconnect from cloud..."); err = nrf_cloud_disconnect(); diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.h b/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.h index a6f7d4ba2734..5e05da11c631 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.h +++ b/samples/cellular/nrf_cloud_ble_gateway/src/ble/gateway.h @@ -23,7 +23,6 @@ int gateway_shadow_accepted_handler(struct nrf_cloud_obj *desired); int gateway_shadow_transform_handler(struct nrf_cloud_obj *desired_conns); int gw_psk_id_get(char **id, size_t *id_len); -int gateway_handler(cJSON *json); int gateway_data_handler(const struct nrf_cloud_data *const dev_msg); #if defined(CONFIG_ENTER_52840_MCUBOOT_VIA_BUTTON) diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ui/ui.c b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ui/ui.c index 2e3ca9e2155d..445fb79edfeb 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/ble/ui/ui.c +++ b/samples/cellular/nrf_cloud_ble_gateway/src/ble/ui/ui.c @@ -32,7 +32,7 @@ static void button_press_timer_handler(struct k_timer *timer) ui_led_set_pattern(UI_LTE_DISCONNECTED, PWM_DEV_0); ui_led_set_pattern(UI_BLE_OFF, PWM_DEV_1); #else - //current_led_state = UI_LTE_DISCONNECTED; + /* current_led_state = UI_LTE_DISCONNECTED; */ #endif shutdown = true; LOG_INF("Button pressed; disconnecting!"); diff --git a/samples/cellular/nrf_cloud_ble_gateway/src/cloud_connection.c b/samples/cellular/nrf_cloud_ble_gateway/src/cloud_connection.c index 2b2c7437cb35..aa94edc5b9af 100644 --- a/samples/cellular/nrf_cloud_ble_gateway/src/cloud_connection.c +++ b/samples/cellular/nrf_cloud_ble_gateway/src/cloud_connection.c @@ -639,6 +639,7 @@ static int setup_cloud(void) err = lte_lc_psm_req(IS_ENABLED(CONFIG_LTE_PSM_REQ)); if (err) { LOG_ERR("Unable to disable PSM: %d", err); + } #endif #elif defined(CONFIG_NRF_CLOUD_COAP)