Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e3f544f authored by Aritra Sen's avatar Aritra Sen Committed by Gerrit Code Review
Browse files

Merge changes Ia2d84cbc,I7bb9462b,I5deaee65,I5c9a000b,If6dd7b3a

* changes:
  Change the BluetoothSocket#connect API to return L2CAP connection error code propagated from Native.
  Propagate the L2CAP error code from native to application via sockets.
  Capture the L2CAP error code from the GAP event data and propate it to the JV L2CAP socket callback.
  Add L2CAP conn result on error and propagate it upwards to GAP callback handler as a part of event data.
  Create new L2CAP Connection result codes for errors to replace L2CAP_CONN_OTHER_ERROR with specific errors in the GAP error callback.
parents e97208ac a23c9d40
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -440,7 +440,40 @@ public final class BluetoothSocket implements Closeable {
                mSocketOS = mSocket.getOutputStream();
            }
            int channel = readInt(mSocketIS);
            if (channel <= 0) {
            if (channel == 0) {
                int errCode = (int) mSocketIS.read();
                switch(errCode) {
                    case /*BTA_JV_L2CAP_REASON_ACL_FAILURE*/ 2:
                        throw new IOException("ACL connection failed");
                    case /*BTA_JV_L2CAP_REASON_CL_SEC_FAILURE*/ 3:
                        throw new IOException("Client security clearance failed");
                    case /*BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHENTICATION*/ 4:
                        throw new IOException("Insufficient authentication");
                    case /*BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHORIZATION*/ 5:
                        throw new IOException("Insufficient authorization");
                    case /*BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP_KEY_SIZE*/ 6:
                        throw new IOException("Insufficient encryption key size");
                    case /*BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP*/ 7:
                        throw new IOException("Insufficient encryption");
                    case /*BTA_JV_L2CAP_REASON_INVALID_SOURCE_CID*/ 8:
                        throw new IOException("Invalid source CID");
                    case /*BTA_JV_L2CAP_REASON_SOURCE_CID_ALREADY_ALLOCATED*/ 9:
                        throw new IOException("Source CID already allocated");
                    case /*BTA_JV_L2CAP_REASON_UNACCEPTABLE_PARAMETERS*/ 10:
                        throw new IOException("Unacceptable Parameters");
                    case /*BTA_JV_L2CAP_REASON_INVALID_PARAMETERS*/ 11:
                        throw new IOException("Invalid Parameters");
                    case /*BTA_JV_L2CAP_REASON_NO_RESOURCES*/ 12:
                        throw new IOException("No resources Available");
                    case /*BTA_JV_L2CAP_REASON_NO_PSM*/ 13:
                        throw new IOException("No PSM available");
                    case /*BTA_JV_L2CAP_REASON_TIMEOUT*/ 14:
                        throw new IOException("Connection Timeout");
                    default:
                        throw new IOException("bt socket connect failed for unknown reason");
                }
            }
            if (channel < 0) {
                throw new IOException("bt socket connect failed");
            }
            mPort = channel;
+22 −0
Original line number Diff line number Diff line
@@ -47,6 +47,25 @@
typedef uint8_t tBTA_JV_STATUS;
#define BTA_JV_INTERNAL_ERR (-1) /* internal error. */

/* L2CAP errors from underlying layers propagated via callbacks. */
#define BTA_JV_L2CAP_REASON_EMPTY 0
#define BTA_JV_L2CAP_REASON_UNKNOWN 1
#define BTA_JV_L2CAP_REASON_ACL_FAILURE 2
#define BTA_JV_L2CAP_REASON_CL_SEC_FAILURE 3
#define BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHENTICATION 4
#define BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHORIZATION 5
#define BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP_KEY_SIZE 6
#define BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP 7
#define BTA_JV_L2CAP_REASON_INVALID_SOURCE_CID 8
#define BTA_JV_L2CAP_REASON_SOURCE_CID_ALREADY_ALLOCATED 9
#define BTA_JV_L2CAP_REASON_UNACCEPTABLE_PARAMETERS 10
#define BTA_JV_L2CAP_REASON_INVALID_PARAMETERS 11
#define BTA_JV_L2CAP_REASON_NO_RESOURCES 12
#define BTA_JV_L2CAP_REASON_NO_PSM 13
#define BTA_JV_L2CAP_REASON_TIMEOUT 14

typedef uint8_t tBTA_JV_L2CAP_REASON;

#define BTA_JV_MAX_UUIDS SDP_MAX_UUID_FILTERS
#define BTA_JV_MAX_ATTRS SDP_MAX_ATTR_FILTERS
#define BTA_JV_MAX_SDP_REC SDP_MAX_RECORDS
@@ -208,6 +227,9 @@ typedef struct {
  tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
  uint32_t handle;       /* The connection handle */
  bool async;            /* false, if local initiates disconnect */
  /* Reason that triggered the L2CAP connection close callback.
  Used when L2CAP close callback was triggered due to a GAP error. */
  tBTA_JV_L2CAP_REASON reason;
} tBTA_JV_L2CAP_CLOSE;

/* data associated with BTA_JV_L2CAP_START_EVT */
+49 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include "stack/include/avdt_api.h"  // AVDT_PSM
#include "stack/include/bt_hdr.h"
#include "stack/include/gap_api.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/port_api.h"
#include "stack/include/sdp_api.h"
#include "types/bluetooth/uuid.h"
@@ -147,6 +148,53 @@ static void bta_jv_free_sec_id(uint8_t* p_sec_id) {
  }
}

/*******************************************************************************
 *
 * Function     bta_jv_from_gap_l2cap_err
 *
 * Description  Convert the L2CAP error result propagated from GAP to BTA JV
 *              L2CAP close reason code.
 *
 * Params      l2cap_result: The L2CAP result propagated from GAP error.
 *
 * Returns     Appropriate l2cap error reason value
 *             or BTA_JV_L2CAP_REASON_UNKNOWN if reason isn't defined yet.
 *
 ******************************************************************************/
static tBTA_JV_L2CAP_REASON bta_jv_from_gap_l2cap_err(uint16_t l2cap_result) {
  switch (l2cap_result) {
    case L2CAP_CONN_ACL_CONNECTION_FAILED:
      return BTA_JV_L2CAP_REASON_ACL_FAILURE;
    case L2CAP_CONN_CLIENT_SECURITY_CLEARANCE_FAILED:
      return BTA_JV_L2CAP_REASON_CL_SEC_FAILURE;
    case L2CAP_CONN_INSUFFICIENT_AUTHENTICATION:
      return BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHENTICATION;
    case L2CAP_CONN_INSUFFICIENT_AUTHORIZATION:
      return BTA_JV_L2CAP_REASON_INSUFFICIENT_AUTHORIZATION;
    case L2CAP_CONN_INSUFFICIENT_ENCRYP_KEY_SIZE:
      return BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP_KEY_SIZE;
    case L2CAP_CONN_INSUFFICIENT_ENCRYP:
      return BTA_JV_L2CAP_REASON_INSUFFICIENT_ENCRYP;
    case L2CAP_CONN_INVALID_SOURCE_CID:
      return BTA_JV_L2CAP_REASON_INVALID_SOURCE_CID;
    case L2CAP_CONN_SOURCE_CID_ALREADY_ALLOCATED:
      return BTA_JV_L2CAP_REASON_SOURCE_CID_ALREADY_ALLOCATED;
    case L2CAP_CONN_UNACCEPTABLE_PARAMETERS:
      return BTA_JV_L2CAP_REASON_UNACCEPTABLE_PARAMETERS;
    case L2CAP_CONN_INVALID_PARAMETERS:
      return BTA_JV_L2CAP_REASON_INVALID_PARAMETERS;
    case L2CAP_CONN_NO_RESOURCES:
      return BTA_JV_L2CAP_REASON_NO_RESOURCES;
    case L2CAP_CONN_NO_PSM:
      return BTA_JV_L2CAP_REASON_NO_PSM;
    case L2CAP_CONN_TIMEOUT:
      return BTA_JV_L2CAP_REASON_TIMEOUT;
    default:
      return BTA_JV_L2CAP_REASON_UNKNOWN;
  }
}
/******************************************************************************/

/*******************************************************************************
 *
 * Function     bta_jv_alloc_rfc_cb
@@ -884,6 +932,7 @@ static void bta_jv_l2cap_client_cback(uint16_t gap_handle, uint16_t event,
      p_cb->state = BTA_JV_ST_NONE;
      bta_jv_free_sec_id(&p_cb->sec_id);
      evt_data.l2c_close.async = true;
      evt_data.l2c_close.reason = bta_jv_from_gap_l2cap_err(data->l2cap_result);
      p_cb->p_cback(BTA_JV_L2CAP_CLOSE_EVT, &evt_data, p_cb->l2cap_socket_id);
      p_cb->p_cback = NULL;
      break;
+16 −0
Original line number Diff line number Diff line
@@ -349,6 +349,18 @@ static inline bool send_app_psm_or_chan_l(l2cap_socket* sock) {
                       sizeof(sock->channel)) == sizeof(sock->channel);
}

static bool send_app_err_code(l2cap_socket* sock, tBTA_JV_L2CAP_REASON code) {
  LOG_INFO("Sending l2cap failure reason socket_id:%u reason code:%d", sock->id,
           code);
  int err_channel = 0;
  if (sock_send_all(sock->our_fd, (const uint8_t*)&err_channel,
                    sizeof(err_channel)) != sizeof(err_channel)) {
    return false;
  }
  return sock_send_all(sock->our_fd, (const uint8_t*)&code, sizeof(code)) ==
         sizeof(code);
}

static bool send_app_connect_signal(int fd, const RawAddress* addr, int channel,
                                    int status, int send_fd, uint16_t rx_mtu,
                                    uint16_t tx_mtu) {
@@ -552,6 +564,10 @@ static void on_l2cap_close(tBTA_JV_L2CAP_CLOSE* p_close, uint32_t id) {
      sock->server ? android::bluetooth::SOCKET_ROLE_LISTEN
                   : android::bluetooth::SOCKET_ROLE_CONNECTION);

  if (!send_app_err_code(sock, p_close->reason)) {
    LOG_ERROR("Unable to send l2cap socket to application socket_id:%u",
              sock->id);
  }
  // TODO: This does not seem to be called...
  // I'm not sure if this will be called for non-server sockets?
  if (sock->server) {
+5 −1
Original line number Diff line number Diff line
@@ -691,9 +691,13 @@ static void gap_on_l2cap_error(uint16_t l2cap_cid, uint16_t result) {
  tGAP_CCB* p_ccb = gap_find_ccb_by_cid(l2cap_cid);
  if (p_ccb == nullptr) return;

  /* Propagate the l2cap result upward */
  tGAP_CB_DATA cb_data;
  cb_data.l2cap_result = result;

  /* Tell the user if there is a callback */
  if (p_ccb->p_callback)
    (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED, nullptr);
    (*p_ccb->p_callback)(p_ccb->gap_handle, GAP_EVT_CONN_CLOSED, &cb_data);

  gap_release_ccb(p_ccb);
}
Loading