shared/att: Add debug level to bt_att_set_debug
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 8 Jan 2021 18:54:24 +0000 (10:54 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:34 +0000 (19:08 +0530)
This creates different levels of debugging which can be passed to
bt_att_set_debug as depending on the application it may not need to
print everything which can pollute the logs quite a bit.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/shared/att.c
src/shared/att.h
tools/btgatt-client.c
tools/btgatt-server.c
unit/test-gatt.c

index ace4468..d66accf 100755 (executable)
@@ -76,6 +76,7 @@ struct bt_att {
        bt_att_destroy_func_t timeout_destroy;
        void *timeout_data;
 
+       uint8_t debug_level;
        bt_att_debug_func_t debug_callback;
        bt_att_destroy_func_t debug_destroy;
 
@@ -280,6 +281,33 @@ static bool match_disconn_id(const void *a, const void *b)
        return disconn->id == id;
 }
 
+static void att_log(struct bt_att *att, uint8_t level, const char *format,
+                                                               ...)
+{
+       va_list va;
+
+       if (att->debug_level < level)
+               return;
+       va_start(va, format);
+
+       util_debug_va(att->debug_callback, att->debug_data, format, va);
+       va_end(va);
+}
+
+#define att_debug(_att, _format, _arg...) \
+       att_log(_att, BT_ATT_DEBUG, _format, ## _arg)
+
+#define att_verbose(_att, _format, _arg...) \
+       att_log(_att, BT_ATT_DEBUG_VERBOSE, _format, ## _arg)
+
+static void att_hexdump(struct bt_att *att, char dir, const void *data,
+                                                       size_t len)
+{
+       if (att->debug_level < 2)
+               return;
+
+       util_hexdump(dir, data, len, att->debug_callback, att->debug_data);
+}
 static bool encode_pdu(struct bt_att *att, struct att_send_op *op,
                                        const void *pdu, uint16_t length)
 {
@@ -315,8 +343,7 @@ static bool encode_pdu(struct bt_att *att, struct att_send_op *op,
                                sign_cnt, &((uint8_t *) op->pdu)[1 + length])))
                return true;
 
-       util_debug(att->debug_callback, att->debug_data,
-                                       "ATT unable to generate signature");
+       att_debug(att, "ATT unable to generate signature");
 
 fail:
        free(op->pdu);
@@ -444,9 +471,8 @@ static bool timeout_cb(void *user_data)
        if (!op)
                return false;
 
-       util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) Operation timed out: 0x%02x",
-                               chan, op->opcode);
+       att_debug(att, "(chan %p) Operation timed out: 0x%02x", chan,
+                                               op->opcode);
 
        if (att->timeout_callback)
                att->timeout_callback(op->id, op->opcode, att->timeout_data);
@@ -481,20 +507,19 @@ static ssize_t bt_att_chan_write(struct bt_att_chan *chan, uint8_t opcode,
        iov.iov_base = (void *) pdu;
        iov.iov_len = len;
 
-       util_debug(att->debug_callback, att->debug_data,
-                                       "(chan %p) ATT op 0x%02x",
-                                       chan, opcode);
+       att_verbose(att, "(chan %p) ATT op 0x%02x", chan, opcode);
 
        ret = io_send(chan->io, &iov, 1);
        if (ret < 0) {
-               util_debug(att->debug_callback, att->debug_data,
-                                       "(chan %p) write failed: %s",
-                                       chan, strerror(-ret));
 
+               att_debug(att, "(chan %p) write failed: %s", chan,
+                                               strerror(-ret));
                return ret;
        }
 
-       util_hexdump('<', pdu, ret, att->debug_callback, att->debug_data);
+       if (att->debug_level)
+               util_hexdump('<', pdu, ret, att->debug_callback,
+                                               att->debug_data);
 
        return ret;
 }
@@ -632,15 +657,12 @@ static bool disconnect_cb(struct io *io, void *user_data)
        len = sizeof(err);
 
        if (getsockopt(chan->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
-               util_debug(chan->att->debug_callback, chan->att->debug_data,
-                                       "(chan %p) Failed to obtain disconnect"
-                                       " error: %s", chan, strerror(errno));
+               att_debug(att, "(chan %p) Failed to obtain disconnect "
+                               "error: %s", chan, strerror(errno));
                err = 0;
        }
 
-       util_debug(chan->att->debug_callback, chan->att->debug_data,
-                                       "Channel %p disconnected: %s",
-                                       chan, strerror(err));
+       att_debug(att, "Channel %p disconnected: %s", chan, strerror(err));
 
        /* Dettach channel */
        queue_remove(att->chans, chan);
@@ -768,9 +790,7 @@ static bool handle_error_rsp(struct bt_att_chan *chan, uint8_t *pdu,
                op->timeout_id = 0;
        }
 
-       util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) Retrying operation "
-                               "%p", chan, op);
+       att_debug(att, "(chan %p) Retrying operation %p", chan, op);
 
        chan->pending_req = NULL;
 
@@ -793,9 +813,8 @@ static void handle_rsp(struct bt_att_chan *chan, uint8_t opcode, uint8_t *pdu,
         * the bearer.
         */
        if (!op) {
-               util_debug(att->debug_callback, att->debug_data,
-                                       "(chan %p) Received unexpected ATT "
-                                       "response", chan);
+               att_debug(att, "(chan %p) Received unexpected ATT response",
+                                                               chan);
                io_shutdown(chan->io);
                return;
        }
@@ -826,8 +845,7 @@ static void handle_rsp(struct bt_att_chan *chan, uint8_t opcode, uint8_t *pdu,
        goto done;
 
 fail:
-       util_debug(att->debug_callback, att->debug_data,
-                       "(chan %p) Failed to handle response PDU; opcode: "
+       att_debug(att, "(chan %p) Failed to handle response PDU; opcode: "
                        "0x%02x", chan, opcode);
 
        rsp_opcode = BT_ATT_OP_ERROR_RSP;
@@ -852,8 +870,7 @@ static void handle_conf(struct bt_att_chan *chan, uint8_t *pdu, ssize_t pdu_len)
         * invalid.
         */
        if (!op || pdu_len) {
-               util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) Received unexpected/invalid ATT "
+               att_debug(att, "(chan %p) Received unexpected/invalid ATT "
                                "confirmation", chan);
                io_shutdown(chan->io);
                return;
@@ -927,8 +944,7 @@ static bool handle_signed(struct bt_att *att, uint8_t *pdu, ssize_t pdu_len)
        return true;
 
 fail:
-       util_debug(att->debug_callback, att->debug_data,
-                       "ATT failed to verify signature: 0x%02x", opcode);
+       att_debug(att, "ATT failed to verify signature: 0x%02x", opcode);
 
        return false;
 }
@@ -1010,12 +1026,9 @@ static bool can_read_data(struct io *io, void *user_data)
        if (bytes_read < 0)
                return false;
 
-       util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) ATT received: %zd",
-                               chan, bytes_read);
+       att_verbose(att, "(chan %p) ATT received: %zd", chan, bytes_read);
 
-       util_hexdump('>', chan->buf, bytes_read,
-                               att->debug_callback, att->debug_data);
+       att_hexdump(att, '>', chan->buf, bytes_read);
 
        if (bytes_read < ATT_MIN_PDU_LEN)
                return true;
@@ -1028,14 +1041,12 @@ static bool can_read_data(struct io *io, void *user_data)
        /* Act on the received PDU based on the opcode type */
        switch (get_op_type(opcode)) {
        case ATT_OP_TYPE_RSP:
-               util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) ATT response received: 0x%02x",
+               att_verbose(att, "(chan %p) ATT response received: 0x%02x",
                                chan, opcode);
                handle_rsp(chan, opcode, pdu + 1, bytes_read - 1);
                break;
        case ATT_OP_TYPE_CONF:
-               util_debug(att->debug_callback, att->debug_data,
-                               "(chan %p) ATT confirmation received: 0x%02x",
+               att_verbose(att, "(chan %p) ATT confirmation received: 0x%02x",
                                chan, opcode);
                handle_conf(chan, pdu + 1, bytes_read - 1);
                break;
@@ -1046,8 +1057,7 @@ static bool can_read_data(struct io *io, void *user_data)
                 * promptly notify the upper layer via disconnect handlers.
                 */
                if (chan->in_req) {
-                       util_debug(att->debug_callback, att->debug_data,
-                                       "(chan %p) Received request while "
+                       att_debug(att, "(chan %p) Received request while "
                                        "another is pending: 0x%02x",
                                        chan, opcode);
                        io_shutdown(chan->io);
@@ -1067,9 +1077,8 @@ static bool can_read_data(struct io *io, void *user_data)
                /* For all other opcodes notify the upper layer of the PDU and
                 * let them act on it.
                 */
-               util_debug(att->debug_callback, att->debug_data,
-                                       "(chan %p) ATT PDU received: 0x%02x",
-                                       chan, opcode);
+               att_debug(att, "(chan %p) ATT PDU received: 0x%02x", chan,
+                                                       opcode);
                handle_notify(chan, pdu, bytes_read);
                break;
        }
@@ -1221,8 +1230,7 @@ static void bt_att_attach_chan(struct bt_att *att, struct bt_att_chan *chan)
 
        io_set_close_on_destroy(chan->io, att->close_on_unref);
 
-       util_debug(att->debug_callback, att->debug_data, "Channel %p attached",
-                                                                       chan);
+       att_debug(att, "Channel %p attached", chan);
 
        wakeup_chan_writer(chan, NULL);
 }
@@ -1338,8 +1346,9 @@ int bt_att_get_channels(struct bt_att *att)
        return queue_length(att->chans);
 }
 
-bool bt_att_set_debug(struct bt_att *att, bt_att_debug_func_t callback,
-                               void *user_data, bt_att_destroy_func_t destroy)
+bool bt_att_set_debug(struct bt_att *att, uint8_t level,
+                       bt_att_debug_func_t callback, void *user_data,
+                       bt_att_destroy_func_t destroy)
 {
        if (!att)
                return false;
@@ -1347,6 +1356,7 @@ bool bt_att_set_debug(struct bt_att *att, bt_att_debug_func_t callback,
        if (att->debug_destroy)
                att->debug_destroy(att->debug_data);
 
+       att->debug_level = level;
        att->debug_callback = callback;
        att->debug_destroy = destroy;
        att->debug_data = user_data;
index 161b84c..233f717 100755 (executable)
 #include "lib/bluetooth.h"
 #endif
 
+#define BT_ATT_DEBUG           0x00
+#define BT_ATT_DEBUG_VERBOSE   0x01
+#define BT_ATT_DEBUG_HEXDUMP   0x02
+
 struct bt_att;
 struct bt_att_chan;
 
@@ -44,8 +48,9 @@ typedef void (*bt_att_timeout_func_t)(unsigned int id, uint8_t opcode,
 typedef void (*bt_att_disconnect_func_t)(int err, void *user_data);
 typedef bool (*bt_att_counter_func_t)(uint32_t *sign_cnt, void *user_data);
 
-bool bt_att_set_debug(struct bt_att *att, bt_att_debug_func_t callback,
-                               void *user_data, bt_att_destroy_func_t destroy);
+bool bt_att_set_debug(struct bt_att *att, uint8_t level,
+                       bt_att_debug_func_t callback, void *user_data,
+                       bt_att_destroy_func_t destroy);
 
 uint16_t bt_att_get_mtu(struct bt_att *att);
 bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu);
index 4e515a0..69d6419 100755 (executable)
@@ -217,7 +217,8 @@ static struct client *client_create(int fd, uint16_t mtu)
                                                                NULL, NULL);
 
        if (verbose) {
-               bt_att_set_debug(cli->att, att_debug_cb, "att: ", NULL);
+               bt_att_set_debug(cli->att, BT_ATT_DEBUG_VERBOSE, att_debug_cb,
+                                                               "att: ", NULL);
                bt_gatt_client_set_debug(cli->gatt, gatt_debug_cb, "gatt: ",
                                                                        NULL);
        }
index 477e446..4b592a6 100755 (executable)
@@ -583,7 +583,8 @@ static struct server *server_create(int fd, uint16_t mtu, bool hr_visible)
        server->hr_visible = hr_visible;
 
        if (verbose) {
-               bt_att_set_debug(server->att, att_debug_cb, "att: ", NULL);
+               bt_att_set_debug(server->att, BT_ATT_DEBUG_VERBOSE,
+                                               att_debug_cb, "att: ", NULL);
                bt_gatt_server_set_debug(server->gatt, gatt_debug_cb,
                                                        "server: ", NULL);
        }
index 2e2c0fd..e60f4c6 100755 (executable)
@@ -783,7 +783,7 @@ static struct context *create_context(uint16_t mtu, gconstpointer data)
 
        switch (test_data->context_type) {
        case ATT:
-               bt_att_set_debug(context->att, print_debug, "bt_att:", NULL);
+               bt_att_set_debug(context->att, 1, print_debug, "bt_att:", NULL);
 
                bt_gatt_exchange_mtu(context->att, mtu, NULL, NULL, NULL);
                break;