Hi, On Tue, Jun 23, 2015 at 3:53 PM, Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> wrote: > From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> > > This adds auto retry logic to requests when a security error happen, > it will first attempt to elevate the security to match the requirement > and then retry sending the request once again. > --- > src/shared/att.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 54 insertions(+), 4 deletions(-) > > diff --git a/src/shared/att.c b/src/shared/att.c > index f9a5817..e8be4cc 100644 > --- a/src/shared/att.c > +++ b/src/shared/att.c > @@ -576,6 +576,55 @@ static bool disconnect_cb(struct io *io, void *user_data) > return false; > } > > +static bool change_security(struct bt_att *att, uint8_t ecode) > +{ > + int security; > + > + security = bt_att_get_security(att); > + if (ecode == BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION && > + security < BT_ATT_SECURITY_MEDIUM) > + security = BT_ATT_SECURITY_MEDIUM; > + else if (ecode == BT_ATT_ERROR_AUTHENTICATION && > + security < BT_ATT_SECURITY_HIGH) > + security = BT_ATT_SECURITY_HIGH; > + else > + return false; > + > + return bt_att_set_security(att, security); > +} > + > +static bool handle_error_rsp(struct bt_att *att, uint8_t *pdu, > + ssize_t pdu_len, uint8_t *opcode) > +{ > + const struct bt_att_pdu_error_rsp *rsp; > + struct att_send_op *op = att->pending_req; > + > + if (pdu_len != sizeof(*rsp)) { > + *opcode = 0; > + return false; > + } > + > + rsp = (void *) pdu; > + > + *opcode = rsp->opcode; > + > + /* Only try to change security on L2CAP */ > + if (!att->io_on_l2cap) > + return false; > + > + /* Attempt to change security */ > + if (!change_security(att, rsp->ecode)) > + return false; > + > + util_debug(att->debug_callback, att->debug_data, > + "Retrying operation %p", op); > + > + att->pending_req = NULL; > + > + /* Push operation back to request queue */ > + return queue_push_head(att->req_queue, op); > +} > + > static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu, > ssize_t pdu_len) > { > @@ -601,10 +650,11 @@ static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu, > * the request is malformed, end the current request with failure. > */ > if (opcode == BT_ATT_OP_ERROR_RSP) { > - if (pdu_len != 4) > - goto fail; > - > - req_opcode = pdu[0]; > + /* Return if error response cause a retry */ > + if (handle_error_rsp(att, pdu, pdu_len, &req_opcode)) { > + wakeup_writer(att); > + return; > + } > } else if (!(req_opcode = get_req_opcode(opcode))) > goto fail; > > -- > 2.1.0 Applied. -- Luiz Augusto von Dentz -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html