static bool can_write_data(struct io *io, void *user_data) { struct bt_att *att = user_data; struct att_send_op *op; struct timeout_data *timeout; ssize_t bytes_written; op = pick_next_send_op(att); if (!op) return false; bytes_written = write(att->fd, op->pdu, op->len); if (bytes_written < 0) { util_debug(att->debug_callback, att->debug_data, "write failed: %s", strerror(errno)); if (op->callback) op->callback(BT_ATT_OP_ERROR_RSP, NULL, 0, op->user_data); destroy_att_send_op(op); return true; } util_debug(att->debug_callback, att->debug_data, "ATT op 0x%02x", op->opcode); util_hexdump('<', op->pdu, bytes_written, att->debug_callback, att->debug_data); /* Based on the operation type, set either the pending request or the * pending indication. If it came from the write queue, then there is * no need to keep it around. */ switch (op->type) { case ATT_OP_TYPE_REQ: att->pending_req = op; break; case ATT_OP_TYPE_IND: att->pending_ind = op; break; default: destroy_att_send_op(op); return true; } timeout = new0(struct timeout_data, 1); if (!timeout) return true; timeout->att = att; timeout->id = op->id; op->timeout_id = timeout_add(ATT_TIMEOUT_INTERVAL, timeout_cb, timeout, free); /* Return true as there may be more operations ready to write. */ return true; }
static bool can_write_data(struct io *io, void *user_data) { struct bt_att *att = user_data; struct att_send_op *op; struct timeout_data *timeout; ssize_t ret; struct iovec iov; op = pick_next_send_op(att); if (!op) return false; iov.iov_base = op->pdu; iov.iov_len = op->len; ret = io_send(io, &iov, 1); if (ret < 0) { util_debug(att->debug_callback, att->debug_data, "write failed: %s", strerror(-ret)); if (op->callback) op->callback(BT_ATT_OP_ERROR_RSP, NULL, 0, op->user_data); destroy_att_send_op(op); return true; } util_debug(att->debug_callback, att->debug_data, "ATT op 0x%02x", op->opcode); util_hexdump('<', op->pdu, ret, att->debug_callback, att->debug_data); /* Based on the operation type, set either the pending request or the * pending indication. If it came from the write queue, then there is * no need to keep it around. */ switch (op->type) { case ATT_OP_TYPE_REQ: att->pending_req = op; break; case ATT_OP_TYPE_IND: att->pending_ind = op; break; case ATT_OP_TYPE_RSP: /* Set in_req to false to indicate that no request is pending */ att->in_req = false; /* Fall through to the next case */ case ATT_OP_TYPE_CMD: case ATT_OP_TYPE_NOT: case ATT_OP_TYPE_CONF: case ATT_OP_TYPE_UNKNOWN: default: destroy_att_send_op(op); return true; } timeout = new0(struct timeout_data, 1); if (!timeout) return true; timeout->att = att; timeout->id = op->id; op->timeout_id = timeout_add(ATT_TIMEOUT_INTERVAL, timeout_cb, timeout, free); /* Return true as there may be more operations ready to write. */ return true; }