/** @file
 *  @brief Bluetooth Object Transfer Client Sample
 *
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <stddef.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/services/ots.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/printk.h>
#include <zephyr/types.h>
#include <zephyr/kernel.h>

#define OBJ_MAX_SIZE			      1024
/* Hardcoded here since definition is in internal header */
#define BT_GATT_OTS_OLCP_RES_OPERATION_FAILED 0x04
#define BT_GATT_OTS_OLCP_RES_OUT_OF_BONDS     0x05

static struct bt_ots_client otc;
static struct bt_ots_client_cb otc_cb;
static struct bt_gatt_discover_params discover_params;
static struct bt_gatt_subscribe_params *oacp_sub_params;
static struct bt_gatt_subscribe_params *olcp_sub_params;
static unsigned char obj_data_buf[OBJ_MAX_SIZE];
static uint32_t last_checksum;

static bool first_selected;
static void on_obj_selected(struct bt_ots_client *ots_inst, struct bt_conn *conn, int err);

static void on_obj_metadata_read(struct bt_ots_client *ots_inst, struct bt_conn *conn, int err,
				 uint8_t metadata_read);

static int on_obj_data_read(struct bt_ots_client *ots_inst, struct bt_conn *conn, uint32_t offset,
			    uint32_t len, uint8_t *data_p, bool is_complete);

static void start_scan(void);
static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
static struct bt_conn *default_conn;
static atomic_t discovery_state;

enum OTS_SERVICE_DISCOVERY_STATE_BIT {
	DISC_OTS_FEATURE,
	DISC_OTS_NAME,
	DISC_OTS_TYPE,
	DISC_OTS_SIZE,
	DISC_OTS_ID,
	DISC_OTS_PROPERTIES,
	DISC_OTS_ACTION_CP,
	DISC_OTS_LIST_CP,
};

static void print_hex_number(const uint8_t *num, size_t len)
{
	printk("0x");
	for (size_t i = 0; i < len; i++) {
		printk("%02x ", num[i]);
	}

	printk("\n");
}

/*
 * Get buttons configuration from the devicetree sw0~sw3 alias. This is mandatory.
 */
#define SW0_NODE DT_ALIAS(sw0)
#define SW1_NODE DT_ALIAS(sw1)
#define SW2_NODE DT_ALIAS(sw2)
#define SW3_NODE DT_ALIAS(sw3)
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay) || !DT_NODE_HAS_STATUS(SW1_NODE, okay) ||                  \
	!DT_NODE_HAS_STATUS(SW2_NODE, okay) || !DT_NODE_HAS_STATUS(SW3_NODE, okay)
#error "Unsupported board: This sample need 4 buttons to run"
#endif

static const struct gpio_dt_spec button0 = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET_OR(SW1_NODE, gpios, {0});
static const struct gpio_dt_spec button2 = GPIO_DT_SPEC_GET_OR(SW2_NODE, gpios, {0});
static const struct gpio_dt_spec button3 = GPIO_DT_SPEC_GET_OR(SW3_NODE, gpios, {0});
#define BTN_COUNT 4

static const struct gpio_dt_spec btns[BTN_COUNT] = {button0, button1, button2, button3};
static struct gpio_callback button_cb_data;
struct otc_btn_work_info {
	struct k_work_delayable work;
	uint32_t pins;
} otc_btn_work;

struct otc_checksum_work_info {
	struct k_work_delayable work;
	off_t offset;
	size_t len;
} otc_checksum_work;

static void otc_btn_work_fn(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct otc_btn_work_info *btn_work = CONTAINER_OF(dwork, struct otc_btn_work_info, work);
	int err;
	size_t size_to_write;

	if (btn_work->pins == BIT(button0.pin)) {
		if (!first_selected) {
			err = bt_ots_client_select_id(&otc, default_conn, BT_OTS_OBJ_ID_MIN);
			first_selected = true;
		} else {
			printk("select next\n");
			err = bt_ots_client_select_next(&otc, default_conn);
		}

		if (err != 0) {
			printk("Failed to select object (err %d)\n", err);
		}

		printk("Selecting object succeeded\n");
	} else if (btn_work->pins == BIT(button1.pin)) {
		printk("read OTS object meta\n");
		err = bt_ots_client_read_object_metadata(&otc, default_conn,
							 BT_OTS_METADATA_REQ_ALL);
		if (err != 0) {
			printk("Failed to read object metadata (err %d)\n", err);
		}

	} else if (btn_work->pins == BIT(button2.pin)) {
		if (BT_OTS_OBJ_GET_PROP_WRITE(otc.cur_object.props)) {
			size_to_write = MIN(OBJ_MAX_SIZE, otc.cur_object.size.alloc);
			(void)memset(obj_data_buf, 0, size_to_write);
			printk("Going to write OTS object len %d\n", size_to_write);
			for (uint32_t idx = 0; idx < size_to_write; idx++) {
				obj_data_buf[idx] = UINT8_MAX - (idx % UINT8_MAX);
			}

			last_checksum = bt_ots_client_calc_checksum(obj_data_buf, size_to_write);
			printk("Data sent checksum 0x%08x\n", last_checksum);
			err = bt_ots_client_write_object_data(&otc, default_conn, obj_data_buf,
							      size_to_write, 0,
							      BT_OTS_OACP_WRITE_OP_MODE_NONE);
			if (err != 0) {
				printk("Failed to write object (err %d)\n", err);
			}
		} else {
			printk("This OBJ does not support WRITE OP\n");
		}

	} else if (btn_work->pins == BIT(button3.pin)) {
		if (BT_OTS_OBJ_GET_PROP_READ(otc.cur_object.props)) {
			printk("read OTS object\n");
			err = bt_ots_client_read_object_data(&otc, default_conn);
			if (err != 0) {
				printk("Failed to read object %d\n", err);
			}
		} else {
			printk("This OBJ does not support READ OP\n");
		}
	}
}

static void otc_checksum_work_fn(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct otc_checksum_work_info *checksum_work =
		CONTAINER_OF(dwork, struct otc_checksum_work_info, work);
	int err;

	err = bt_ots_client_get_object_checksum(&otc, default_conn, checksum_work->offset,
						checksum_work->len);
	if (err != 0) {
		printk("bt_ots_client_get_object_checksum failed (%d)\n", err);
	}
}

static void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
	otc_btn_work.pins = pins;
	k_work_schedule(&otc_btn_work.work, K_MSEC(100));
}

static void configure_button_irq(const struct gpio_dt_spec btn)
{
	int ret;

	if (!device_is_ready(btn.port)) {
		printk("Error: button device %s is not ready\n", btn.port->name);
		return;
	}

	ret = gpio_pin_configure_dt(&btn, GPIO_INPUT);
	if (ret != 0) {
		printk("Error %d: failed to configure %s pin %d\n", ret, btn.port->name, btn.pin);
		return;
	}

	ret = gpio_pin_interrupt_configure_dt(&btn, GPIO_INT_EDGE_TO_ACTIVE);

	if (ret != 0) {
		printk("Error %d: failed to configure interrupt on %s pin %d\n", ret,
		       btn.port->name, btn.pin);
		return;
	}

	button_cb_data.pin_mask |= BIT(btn.pin);
	gpio_add_callback(btn.port, &button_cb_data);

	printk("Set up button at %s pin %d\n", btn.port->name, btn.pin);
}

static void configure_buttons(void)
{
	gpio_init_callback(&button_cb_data, button_pressed, 0);

	for (int idx = 0; idx < BTN_COUNT; idx++) {
		configure_button_irq(btns[idx]);
	}
}

static bool eir_found(struct bt_data *data, void *user_data)
{
	bt_addr_le_t *addr = user_data;
	int i;

	switch (data->type) {
	case BT_DATA_UUID16_SOME:
	case BT_DATA_UUID16_ALL:
		if (data->data_len % sizeof(uint16_t) != 0U) {
			printk("AD malformed\n");
			return true;
		}

		for (i = 0; i < data->data_len; i += sizeof(uint16_t)) {
			struct bt_le_conn_param *param;
			struct bt_uuid *uuid;
			uint16_t u16;
			int err;

			(void)memcpy(&u16, &data->data[i], sizeof(u16));
			uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(u16));
			if (bt_uuid_cmp(uuid, BT_UUID_OTS) != 0) {
				continue;
			}

			err = bt_le_scan_stop();
			if (err != 0) {
				printk("Stop LE scan failed (err %d)\n", err);
				continue;
			}

			param = BT_LE_CONN_PARAM_DEFAULT;
			err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &default_conn);
			if (err != 0) {
				printk("Create conn failed (err %d)\n", err);
				start_scan();
			}

			return false;
		}
	}
	return true;
}

static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
			 struct net_buf_simple *ad)
{
	char dev[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(addr, dev, sizeof(dev));

	/* We're only interested in connectable events and scan response
	 * because service UUID is in sd of sample peripheral_ots.
	 */
	if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND ||
	    type == BT_GAP_ADV_TYPE_SCAN_RSP) {
		bt_data_parse(ad, eir_found, (void *)addr);
	}
}

static void start_scan(void)
{
	int err;

	/* Use active scanning and disable duplicate filtering to handle any
	 * devices that might update their advertising data at runtime.
	 */
	struct bt_le_scan_param scan_param = {
		.type = BT_LE_SCAN_TYPE_ACTIVE,
		.options = BT_LE_SCAN_OPT_NONE,
		.interval = BT_GAP_SCAN_FAST_INTERVAL,
		.window = BT_GAP_SCAN_FAST_WINDOW,
	};

	err = bt_le_scan_start(&scan_param, device_found);
	if (err != 0) {
		printk("Scanning OTS TAG failed to start (err %d)\n", err);
		return;
	}

	printk("Scanning successfully started\n");
}

static int subscribe_func(void)
{
	int ret;

	printk("Subscribe OACP and OLCP Indication\n");
	oacp_sub_params = &otc.oacp_sub_params;
	oacp_sub_params->disc_params = &otc.oacp_sub_disc_params;
	if (oacp_sub_params) {
		/* With ccc_handle == 0 it will use auto discovery */
		oacp_sub_params->ccc_handle = 0;
		oacp_sub_params->end_handle = otc.end_handle;
		oacp_sub_params->value = BT_GATT_CCC_INDICATE;
		oacp_sub_params->value_handle = otc.oacp_handle;
		oacp_sub_params->notify = bt_ots_client_indicate_handler;
		ret = bt_gatt_subscribe(default_conn, oacp_sub_params);

		if (ret != 0) {
			printk("Subscribe OACP failed %d\n", ret);
			return ret;
		}
	}

	olcp_sub_params = &otc.olcp_sub_params;
	olcp_sub_params->disc_params = &otc.olcp_sub_disc_params;
	if (olcp_sub_params) {
		/* With ccc_handle == 0 it will use auto discovery */
		olcp_sub_params->ccc_handle = 0;
		olcp_sub_params->end_handle = otc.end_handle;
		olcp_sub_params->value = BT_GATT_CCC_INDICATE;
		olcp_sub_params->value_handle = otc.olcp_handle;
		olcp_sub_params->notify = bt_ots_client_indicate_handler;
		ret = bt_gatt_subscribe(default_conn, olcp_sub_params);

		if (ret != 0) {
			printk("Subscribe OLCP failed %d\n", ret);
			return ret;
		}
	}

	return ret;
}

static bool is_discovery_complete(void)
{
	return (atomic_test_bit(&discovery_state, DISC_OTS_FEATURE) &&
		atomic_test_bit(&discovery_state, DISC_OTS_NAME) &&
		atomic_test_bit(&discovery_state, DISC_OTS_TYPE) &&
		atomic_test_bit(&discovery_state, DISC_OTS_SIZE) &&
		atomic_test_bit(&discovery_state, DISC_OTS_ID) &&
		atomic_test_bit(&discovery_state, DISC_OTS_PROPERTIES) &&
		atomic_test_bit(&discovery_state, DISC_OTS_ACTION_CP) &&
		atomic_test_bit(&discovery_state, DISC_OTS_LIST_CP));
}

static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			     struct bt_gatt_discover_params *params)
{
	int err;

	if (!attr) {
		printk("Discover complete\n");
		(void)memset(params, 0, sizeof(*params));
		return BT_GATT_ITER_STOP;
	}

	if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS) == 0) {
		(void)memcpy(&uuid, BT_UUID_OTS_FEATURE, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
		err = bt_gatt_discover(conn, &discover_params);

		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_FEATURE) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_FEATURE);
		otc.feature_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_NAME, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_NAME) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_NAME);
		otc.obj_name_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_TYPE, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_TYPE) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_TYPE);
		otc.obj_type_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_SIZE, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_SIZE) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_SIZE);
		otc.obj_size_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_ID, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_ID) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_ID);
		otc.obj_id_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_PROPERTIES, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}

	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_PROPERTIES) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_PROPERTIES);
		otc.obj_properties_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_ACTION_CP, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}
	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_ACTION_CP) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_ACTION_CP);
		otc.oacp_handle = bt_gatt_attr_value_handle(attr);
		(void)memcpy(&uuid, BT_UUID_OTS_LIST_CP, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.start_handle = attr->handle + 1;
		discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;

		err = bt_gatt_discover(conn, &discover_params);
		if (err != 0) {
			printk("Discover failed (err %d)\n", err);
		}
	} else if (bt_uuid_cmp(discover_params.uuid, BT_UUID_OTS_LIST_CP) == 0) {
		atomic_set_bit(&discovery_state, DISC_OTS_LIST_CP);
		otc.olcp_handle = bt_gatt_attr_value_handle(attr);
	} else {
		return BT_GATT_ITER_STOP;
	}

	if (is_discovery_complete()) {
		printk("Discovery complete for OTS Client\n");
		err = subscribe_func();

		if (err != 0) {
			return BT_GATT_ITER_STOP;
		}

		/* Read feature of OTS server*/
		err = bt_ots_client_read_feature(&otc, default_conn);
		if (err != 0) {
			printk("bt_ots_client_read_feature failed (err %d)", err);
		}
	}

	return BT_GATT_ITER_STOP;
}

static void connected(struct bt_conn *conn, uint8_t err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
	first_selected = false;
	if (err != 0) {
		printk("Failed to connect to %s (%u)\n", addr, err);

		bt_conn_unref(default_conn);
		default_conn = NULL;
		start_scan();
		return;
	}

	if (conn != default_conn) {
		return;
	}

	printk("Connected: %s\n", addr);

	if (conn == default_conn) {
		(void)memcpy(&uuid, BT_UUID_OTS, sizeof(uuid));
		discover_params.uuid = &uuid.uuid;
		discover_params.func = discover_func;
		discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
		discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
		discover_params.type = BT_GATT_DISCOVER_PRIMARY;

		err = bt_gatt_discover(default_conn, &discover_params);
		if (err != 0) {
			printk("Discover failed(err %d)\n", err);
			return;
		}
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (conn != default_conn) {
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);

	bt_conn_unref(default_conn);
	default_conn = NULL;
	discovery_state = ATOMIC_INIT(0);
	start_scan();
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
};

static void on_obj_selected(struct bt_ots_client *ots_inst, struct bt_conn *conn, int err)
{
	printk("Current object selected cb OLCP result (%d)\n", err);

	if (err == BT_GATT_OTS_OLCP_RES_OPERATION_FAILED) {
		printk("BT_GATT_OTS_OLCP_RES_OPERATION_FAILED %d\n", err);
		first_selected = false;
	} else if (err == BT_GATT_OTS_OLCP_RES_OUT_OF_BONDS) {
		printk("BT_GATT_OTS_OLCP_RES_OUT_OF_BONDS %d. Select first valid instead\n", err);
		(void)bt_ots_client_select_id(&otc, default_conn, BT_OTS_OBJ_ID_MIN);
	}

	(void)memset(obj_data_buf, 0, OBJ_MAX_SIZE);
}

static int on_obj_data_read(struct bt_ots_client *ots_inst, struct bt_conn *conn, uint32_t offset,
			    uint32_t len, uint8_t *data_p, bool is_complete)
{
	printk("Received OTS Object content, %i bytes at offset %i\n", len, offset);

	print_hex_number(data_p, len);

	if ((offset + len) > OBJ_MAX_SIZE) {
		printk("Can not fit whole object, drop the rest of data\n");
	} else {
		(void)memcpy((obj_data_buf + offset), data_p, MIN((OBJ_MAX_SIZE - offset), len));
	}

	if (is_complete) {
		printk("Object total received %d\n", len + offset);
		print_hex_number(obj_data_buf, len + offset);
		(void)memset(obj_data_buf, 0, OBJ_MAX_SIZE);
		otc_checksum_work.offset = 0;
		otc_checksum_work.len = otc.cur_object.size.cur;
		k_work_schedule(&otc_checksum_work.work, K_NO_WAIT);
		return BT_OTS_STOP;
	}

	return BT_OTS_CONTINUE;
}

static void on_obj_metadata_read(struct bt_ots_client *ots_inst, struct bt_conn *conn, int err,
				 uint8_t metadata_read)
{
	printk("Object's meta data:\n");
	printk("\tCurrent size\t:%u", ots_inst->cur_object.size.cur);
	printk("\tAlloc size\t:%u\n", ots_inst->cur_object.size.alloc);

	if (ots_inst->cur_object.size.cur > OBJ_MAX_SIZE) {
		printk("Object larger than allocated buffer\n");
	}

	bt_ots_metadata_display(&ots_inst->cur_object, 1);
}
static void on_obj_data_written(struct bt_ots_client *ots_inst, struct bt_conn *conn, size_t len)
{
	int err;

	printk("Object been written %d\n", len);
	/* Update object size after write done*/
	err = bt_ots_client_read_object_metadata(&otc, default_conn,
						 BT_OTS_METADATA_REQ_ALL);
	if (err != 0) {
		printk("Failed to read object metadata (err %d)\n", err);
	}
}

void on_obj_checksum_calculated(struct bt_ots_client *ots_inst,
				struct bt_conn *conn, int err, uint32_t checksum)
{
	printk("Object Calculate checksum OACP result (%d)\nChecksum 0x%08x last sent 0x%08x %s\n",
	       err, checksum, last_checksum, (checksum == last_checksum) ? "match" : "not match");
}

static void bt_otc_init(void)
{
	otc_cb.obj_data_read = on_obj_data_read;
	otc_cb.obj_selected = on_obj_selected;
	otc_cb.obj_metadata_read = on_obj_metadata_read;
	otc_cb.obj_data_written = on_obj_data_written;
	otc_cb.obj_checksum_calculated = on_obj_checksum_calculated;
	otc.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
	otc.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
	printk("Current object selected callback: %p\n", otc_cb.obj_selected);
	printk("Content callback: %p\n", otc_cb.obj_data_read);
	printk("Metadata callback: %p\n", otc_cb.obj_metadata_read);
	otc.cb = &otc_cb;
	bt_ots_client_register(&otc);
}

int main(void)
{
	int err;

	first_selected = false;
	discovery_state = ATOMIC_INIT(0);
	k_work_init_delayable(&otc_btn_work.work, otc_btn_work_fn);
	k_work_init_delayable(&otc_checksum_work.work, otc_checksum_work_fn);

	configure_buttons();
	err = bt_enable(NULL);

	if (err != 0) {
		printk("Bluetooth init failed (err %d)\n", err);
		return 0;
	}

	bt_otc_init();
	printk("Bluetooth OTS client sample running\n");

	start_scan();
	return 0;
}
