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

Commit f97faa3f authored by Jack He's avatar Jack He
Browse files

HCI: Simplify btu_hcif_hdl_command_status()

* Move 2nd layer switch statements into top layer
* Check if p_cmd is nullptr at the beginning of the function so
  that each case does not need to check it individually. p_cmd
  is never null.
* Skip parameter total length at beginning of the function

Test: make, unit test, use Bluetooth for music and calls
Change-Id: I23cf983a1ade44bcea0b1009860efdfaf3b8bca8
parent e7e2406e
Loading
Loading
Loading
Loading
+95 −121
Original line number Diff line number Diff line
@@ -1021,89 +1021,89 @@ static void btu_hcif_command_complete_evt(BT_HDR* response, void* context) {
static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
                                        uint8_t* p_cmd,
                                        void* p_vsc_status_cback) {
  CHECK_NE(p_cmd, nullptr) << "Null command for opcode 0x" << loghex(opcode);
  p_cmd++;  // Skip parameter total length

  RawAddress bd_addr;
  uint16_t handle;
  tBTM_ESCO_DATA esco_data;

  switch (opcode) {
    case HCI_EXIT_SNIFF_MODE:
    case HCI_EXIT_PARK_MODE:
      if (status != HCI_SUCCESS) {
        /* Allow SCO initiation to continue if waiting for change mode event */
        if (p_cmd != NULL) {
          p_cmd++; /* bypass length field */
          STREAM_TO_UINT16(handle, p_cmd);
          btm_sco_chk_pend_unpark(status, handle);
        }
      }
      FALLTHROUGH_INTENDED; /* FALLTHROUGH */

    case HCI_HOLD_MODE:
    case HCI_SNIFF_MODE:
    case HCI_PARK_MODE:
      btm_pm_proc_cmd_status(status);
      break;

    default:
      /* If command failed to start, we may need to tell BTM */
      if (status != HCI_SUCCESS) {
  switch (opcode) {
    // Link Control Commands
    case HCI_INQUIRY:
            /* Tell inquiry processing that we are done */
      if (status != HCI_SUCCESS) {
        // Tell inquiry processing that we are done
        btm_process_inq_complete(status, BTM_BR_INQUIRY_MASK);
      }
      break;

          case HCI_RMT_NAME_REQUEST:
            /* Tell inquiry processing that we are done */
            btm_process_remote_name(NULL, NULL, 0, status);

            btm_sec_rmt_name_request_complete(NULL, NULL, status);
            break;

    case HCI_QOS_SETUP:
            /* Tell qos setup that we are done */
            btm_qos_setup_complete(status, 0, NULL);
      if (status != HCI_SUCCESS) {
        // Tell qos setup that we are done
        btm_qos_setup_complete(status, 0, nullptr);
      }
      break;

    case HCI_SWITCH_ROLE:
            /* Tell BTM that the command failed */
            /* read bd addr out of stored command */
            if (p_cmd != NULL) {
              p_cmd++;
      if (status != HCI_SUCCESS) {
        // Tell BTM that the command failed
        STREAM_TO_BDADDR(bd_addr, p_cmd);
        btm_acl_role_changed(status, &bd_addr, BTM_ROLE_UNDEFINED);
            } else
              btm_acl_role_changed(status, NULL, BTM_ROLE_UNDEFINED);
        l2c_link_role_changed(nullptr, BTM_ROLE_UNDEFINED,
                              HCI_ERR_COMMAND_DISALLOWED);
      }
      break;

    case HCI_CREATE_CONNECTION:
            /* read bd addr out of stored command */
            if (p_cmd != NULL) {
              p_cmd++;
      if (status != HCI_SUCCESS) {
        STREAM_TO_BDADDR(bd_addr, p_cmd);
        btm_sec_connected(bd_addr, HCI_INVALID_HANDLE, status, 0);
        l2c_link_hci_conn_comp(status, HCI_INVALID_HANDLE, bd_addr);
      }
      break;

    case HCI_AUTHENTICATION_REQUESTED:
      if (status != HCI_SUCCESS) {
        // Device refused to start authentication
        // This is treated as an authentication failure
        btm_sec_auth_complete(BTM_INVALID_HCI_HANDLE, status);
      }
      break;
    case HCI_SET_CONN_ENCRYPTION:
      if (status != HCI_SUCCESS) {
        // Device refused to start encryption
        // This is treated as an encryption failure
        btm_sec_encrypt_change(BTM_INVALID_HCI_HANDLE, status, false);
      }
      break;
    case HCI_RMT_NAME_REQUEST:
      if (status != HCI_SUCCESS) {
        // Tell inquiry processing that we are done
        btm_process_remote_name(nullptr, nullptr, 0, status);
        btm_sec_rmt_name_request_complete(nullptr, nullptr, status);
      }
      break;
    case HCI_READ_RMT_EXT_FEATURES:
            if (p_cmd != NULL) {
              p_cmd++; /* skip command length */
      if (status != HCI_SUCCESS) {
        STREAM_TO_UINT16(handle, p_cmd);
            } else
              handle = HCI_INVALID_HANDLE;

        btm_read_remote_ext_features_failed(status, handle);
      }
      break;

          case HCI_AUTHENTICATION_REQUESTED:
            /* Device refused to start authentication.  That should be treated
             * as authentication failure. */
            btm_sec_auth_complete(BTM_INVALID_HCI_HANDLE, status);
    case HCI_SETUP_ESCO_CONNECTION:
    case HCI_ENH_SETUP_ESCO_CONNECTION:
      if (status != HCI_SUCCESS) {
        STREAM_TO_UINT16(handle, p_cmd);
        // Determine if initial connection failed or is a change of setup
        if (btm_is_sco_active(handle)) {
          btm_esco_proc_conn_chg(status, handle, 0, 0, 0, 0);
        } else {
          btm_sco_connected(status, nullptr, handle, nullptr);
        }
      }
      break;

    // BLE Commands
    case HCI_BLE_CREATE_LL_CONN:
    case HCI_LE_EXTENDED_CREATE_CONNECTION:
      if (status != HCI_SUCCESS) {
        btm_ble_create_ll_conn_complete(status);
      }
      break;
    case HCI_BLE_START_ENC:
      // Race condition: disconnection happened right before we send
      // "LE Encrypt", controller responds with no connection, we should
@@ -1113,49 +1113,23 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status,
      }
      break;

          case HCI_SET_CONN_ENCRYPTION:
            /* Device refused to start encryption.  That should be treated as
             * encryption failure. */
            btm_sec_encrypt_change(BTM_INVALID_HCI_HANDLE, status, false);
            break;

          case HCI_BLE_CREATE_LL_CONN:
          case HCI_LE_EXTENDED_CREATE_CONNECTION:
            btm_ble_create_ll_conn_complete(status);
            break;

          case HCI_SETUP_ESCO_CONNECTION:
          case HCI_ENH_SETUP_ESCO_CONNECTION:
            /* read handle out of stored command */
            if (p_cmd != NULL) {
              p_cmd++;
    // Link Policy Commands
    case HCI_EXIT_SNIFF_MODE:
    case HCI_EXIT_PARK_MODE:
      if (status != HCI_SUCCESS) {
        // Allow SCO initiation to continue if waiting for change mode event
        STREAM_TO_UINT16(handle, p_cmd);

              /* Determine if initial connection failed or is a change
               * of setup */
              if (btm_is_sco_active(handle))
                btm_esco_proc_conn_chg(status, handle, 0, 0, 0, 0);
              else
                btm_sco_connected(status, NULL, handle, &esco_data);
        btm_sco_chk_pend_unpark(status, handle);
      }
      FALLTHROUGH_INTENDED; /* FALLTHROUGH */
    case HCI_HOLD_MODE:
    case HCI_SNIFF_MODE:
    case HCI_PARK_MODE:
      btm_pm_proc_cmd_status(status);
      break;

          /* This is commented out until an upper layer cares about returning
          event
          #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE)
                      case HCI_ENHANCED_FLUSH:
                          break;
          #endif
          */
    default:
            if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC)
              btm_vsc_complete(&status, opcode, 1,
                               (tBTM_VSC_CMPL_CB*)p_vsc_status_cback);
            break;
        }

      } else {
        if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC)
      if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC) {
        btm_vsc_complete(&status, opcode, 1,
                         (tBTM_VSC_CMPL_CB*)p_vsc_status_cback);
      }