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;
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)
{
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);
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);
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;
}
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);
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;
* 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;
}
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;
* 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;
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;
}
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;
/* 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;
* 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);
/* 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;
}
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);
}
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;
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;