// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <array>
#include <utility>
#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <glib.h>
#include <gio/gio.h>
#include <gmodule.h>
#include <gio/gunixsocketaddress.h>
#include <libmbim-glib/libmbim-glib.h>
#include "hermes/apdu.h"
#include "hermes/euicc_manager_interface.h"
#include "hermes/hermes_common.h"
#include "hermes/modem_mbim.h"
#include "hermes/sgp_22.h"
#include "hermes/type_traits.h"

namespace {

const guint kMbimResponseTimeout = 30;
constexpr int kMbimMessageSuccess = 144;
// Application identifier for the eUICC's SIM EID
const std::array<uint8_t, 12> kMbimEidReqApdu = {
    0x81, 0xE2, 0x91, 0x00, 0x06, 0xBF, 0x3E, 0x03, 0x5C, 0x01, 0x5A, 0x00,
};

}  // namespace

namespace hermes {

/* static */
std::unique_ptr<ModemMbim> ModemMbim::Create(Logger* logger,
                                             Executor* executor) {
  VLOG(2) << __func__;
  GFile* file = NULL;
  const gchar* const path = "/dev/cdc-wdm0";
  file = g_file_new_for_path(path);
  if (file == NULL) {
    LOG(ERROR) << __func__ << " :No file exist";
    return nullptr;
  }
  return std::unique_ptr<ModemMbim>(new ModemMbim(file, logger, executor));
}

ModemMbim::ModemMbim(GFile* file, Logger* logger, Executor* executor)
    : Modem<MbimCmd>(logger, executor),
      logical_slot_(0),
      channel_(kInvalidChannel),
      pending_response_(false),
      ready_state_(MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED),
      file_(file),
      is_ready_state_valid(false),
      weak_factory_(this) {}

ModemMbim::~ModemMbim() {
  VLOG(2) << "~ModemMbim Destructor++";
  Shutdown();
}

void ModemMbim::Initialize(EuiccManagerInterface* euicc_manager,
                           ResultCallback cb) {
  LOG(INFO) << __func__;
  CHECK(current_state_ == State::kMbimUninitialized);
  retry_initialization_callback_.Reset();
  euicc_manager_ = euicc_manager;
  init_done_cb_ = std::move(cb);
  current_state_.Transition(State::kMbimInitializeStarted);
  mbim_device_new(file_, /* cancellable */ NULL,
                  (GAsyncReadyCallback)MbimCreateNewDeviceCb, this);
}

void ModemMbim::Shutdown() {
  VLOG(2) << __func__;
  CloseDevice();
  channel_ = kInvalidChannel;
  pending_response_ = false;
  ready_state_ = MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED,
  current_state_.Transition(State::kMbimUninitialized);
}

void ModemMbim::TransmitFromQueue() {
  VLOG(2) << __func__;
  if (tx_queue_.empty() || pending_response_ ||
      retry_initialization_callback_) {
    return;
  }

  auto mbim_cmd = tx_queue_[0].msg_.get();
  switch (mbim_cmd->mbim_type()) {
    case MbimCmd::MbimType::kMbimOpenLogicalChannel:
      TransmitMbimOpenLogicalChannel();
      break;
    case MbimCmd::MbimType::kMbimCloseLogicalChannel:
      TransmitMbimCloseChannel();
      break;
    case MbimCmd::MbimType::kMbimSendApdu:
      TransmitMbimSendApdu(&tx_queue_[0]);
      break;
    case MbimCmd::MbimType::kMbimSubscriberStatusReady:
      TransmitSubscriberReadyStatusQuery();
      break;
    case MbimCmd::MbimType::kMbimDeviceCaps:
      TransmitMbimLoadCurrentCapabilities();
      break;
    case MbimCmd::MbimType::kMbimSendEidApdu:
      TransmitMbimSendEidApdu();
      break;
    default:
      break;
  }
}

std::unique_ptr<MbimCmd> ModemMbim::GetTagForSendApdu() {
  return std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimSendApdu);
}

void ModemMbim::ProcessMbimResult(int err) {
  if (tx_queue_.empty()) {
    VLOG(2) << __func__ << " :Queue is Empty";
    return;
  }
  // pop before running the callback since the callback might change the state
  // of the queue.
  auto cb_ = std::move(tx_queue_[0].cb_);
  tx_queue_.pop_front();
  if (!cb_.is_null()) {
    std::move(cb_).Run(err);
  }
}

/* static */
void ModemMbim::MbimCreateNewDeviceCb(GObject* source,
                                      GAsyncResult* res,
                                      ModemMbim* modem_mbim) {
  /* Open the device */
  VLOG(2) << __func__;
  g_autoptr(GError) error = NULL;
  glib_bridge::ScopedGObject<MbimDevice> mbimdevice(
      mbim_device_new_finish(res, &error));
  modem_mbim->device_ = std::move(mbimdevice);
  if (!modem_mbim->device_.get() || error != NULL) {
    // TODO(pholla): Gate initialization until a modem dbus object appears.
    // (b/197256318)
    LOG(INFO) << __func__ << ": " << error->message
              << ". The modem may be booting ...";
    modem_mbim->RetryInitialization(std::move(modem_mbim->init_done_cb_));
    return;
  }
  mbim_device_open_full(modem_mbim->device_.get(), MBIM_DEVICE_OPEN_FLAGS_PROXY,
                        kMbimResponseTimeout, /* cancellable */ NULL,
                        (GAsyncReadyCallback)MbimDeviceOpenReadyCb, modem_mbim);
}

/* static */
void ModemMbim::MbimDeviceOpenReadyCb(MbimDevice* device,
                                      GAsyncResult* res,
                                      ModemMbim* modem_mbim) {
  VLOG(2) << __func__;
  g_autoptr(GError) error = NULL;
  if (!mbim_device_open_finish(device, res, &error)) {
    LOG(ERROR) << "Failed  due to error: " << error->message;
    modem_mbim->RetryInitialization(std::move(modem_mbim->init_done_cb_));
    return;
  }
  modem_mbim->indication_id_ = g_signal_connect(
      modem_mbim->device_.get(), MBIM_DEVICE_SIGNAL_INDICATE_STATUS,
      G_CALLBACK(ClientIndicationCb), modem_mbim);

  if (modem_mbim->current_state_ == State::kMbimStarted) {
    VLOG(2) << "Opened device. Reusing previous EID and IMEI";
    std::move(modem_mbim->init_done_cb_).Run(kModemSuccess);
    return;
  }

  LOG(INFO) << "Mbim device is ready, acquire eid and imei";
  auto get_imei = base::BindOnce(&ModemMbim::QueryCurrentMbimCapabilities,
                                 modem_mbim->weak_factory_.GetWeakPtr());

  modem_mbim->tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), modem_mbim->AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimSubscriberStatusReady),
       base::BindOnce(&ModemMbim::RunNextStepOrRetry,
                      modem_mbim->weak_factory_.GetWeakPtr(),
                      std::move(get_imei),
                      std::move(modem_mbim->init_done_cb_))});
  modem_mbim->TransmitFromQueue();
}

void ModemMbim::TransmitSubscriberReadyStatusQuery() {
  g_autoptr(MbimMessage) message = NULL;
  VLOG(2) << __func__;
  message = mbim_message_subscriber_ready_status_query_new(NULL);
  if (!message) {
    LOG(ERROR) << "Mbim message creation failed";
    ProcessMbimResult(kModemMessageProcessingError);
    return;
  }
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /*cancellable*/ NULL,
                      (GAsyncReadyCallback)SubscriberReadyStatusRspCb, this);
}

void ModemMbim::TransmitMbimLoadCurrentCapabilities() {
  g_autoptr(MbimMessage) message = NULL;
  VLOG(2) << __func__;
  message = mbim_message_device_caps_query_new(/* error */ NULL);
  if (!message) {
    LOG(ERROR) << __func__ << " :Mbim message creation failed";
    ProcessMbimResult(kModemMessageProcessingError);
    return;
  }
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /*cancellable*/ NULL,
                      (GAsyncReadyCallback)DeviceCapsQueryReady, this);
}

void ModemMbim::TransmitMbimCloseChannel() {
  g_autoptr(MbimMessage) message = NULL;
  g_autoptr(GError) error = NULL;
  VLOG(2) << __func__;
  message = mbim_message_ms_uicc_low_level_access_close_channel_set_new(
      channel_,
      /*channelGroupId*/ 1, &error);
  if (!message) {
    LOG(ERROR) << "Mbim message creation failed:" << error->message;
    ProcessMbimResult(kModemMessageProcessingError);
    return;
  }
  pending_response_ = true;
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /*cancellable*/ NULL,
                      (GAsyncReadyCallback)UiccLowLevelAccessCloseChannelSetCb,
                      this);
}

void ModemMbim::TransmitMbimOpenLogicalChannel() {
  VLOG(2) << __func__;
  guint8 appId[16];
  guint32 appIdSize = kAidIsdr.size();
  g_autoptr(GError) error = NULL;
  g_autoptr(MbimMessage) message = NULL;
  std::copy(kAidIsdr.begin(), kAidIsdr.end(), appId);
  message = mbim_message_ms_uicc_low_level_access_open_channel_set_new(
      appIdSize, appId, /* selectP2arg */ 4, /* channelGroupId */ 1, &error);
  if (!message) {
    LOG(ERROR) << __func__ << ": Mbim Message Creation Failed";
    ProcessMbimResult(kModemMessageProcessingError);
    return;
  }
  pending_response_ = true;
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /*cancellable*/ NULL,
                      (GAsyncReadyCallback)UiccLowLevelAccessOpenChannelSetCb,
                      this);
}

void ModemMbim::TransmitMbimSendEidApdu() {
  VLOG(2) << __func__;
  uint8_t eid_apduCmd[kMaxApduLen];
  guint32 kMbimEidReqApduSize = kMbimEidReqApdu.size();
  g_autoptr(MbimMessage) message = NULL;
  MbimUiccSecureMessaging secure_messaging = MBIM_UICC_SECURE_MESSAGING_NONE;
  MbimUiccClassByteType class_byte_type = MBIM_UICC_CLASS_BYTE_TYPE_EXTENDED;
  std::copy(kMbimEidReqApdu.begin(), kMbimEidReqApdu.end(), eid_apduCmd);
  message = (mbim_message_ms_uicc_low_level_access_apdu_set_new(
      channel_, secure_messaging, class_byte_type, kMbimEidReqApduSize,
      eid_apduCmd, NULL));
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /*cancellable*/ NULL,
                      (GAsyncReadyCallback)UiccLowLevelAccessApduEidParse,
                      this);
}

void ModemMbim::TransmitMbimSendApdu(TxElement* tx_element) {
  g_autoptr(MbimMessage) message = NULL;
  MbimUiccSecureMessaging secure_messaging = MBIM_UICC_SECURE_MESSAGING_NONE;
  MbimUiccClassByteType class_byte_type = MBIM_UICC_CLASS_BYTE_TYPE_EXTENDED;
  uint8_t* fragment;
  size_t apdu_len = 0;
  uint8_t apduCmd[kMaxApduLen] = {0};
  VLOG(2) << __func__;
  ApduTxInfo* apdu = static_cast<ApduTxInfo*>(tx_element->info_.get());
  size_t fragment_size = apdu->apdu_.GetNextFragment(&fragment);
  VLOG(2) << "Fragment size" << fragment_size;
  apdu_len = fragment_size;
  std::copy(fragment, fragment + fragment_size, apduCmd);
  apduCmd[apdu_len++] = 0x00;

  VLOG(2) << "APDU fragment #"
          << " bytes): " << base::HexEncode(apduCmd, apdu_len);
  VLOG(2) << "Send the apdu over channel number: " << channel_;
  pending_response_ = true;
  message = (mbim_message_ms_uicc_low_level_access_apdu_set_new(
      channel_, secure_messaging, class_byte_type, apdu_len, apduCmd, NULL));
  mbim_device_command(device_.get(), message, kMbimResponseTimeout,
                      /* cancellable */ NULL,
                      (GAsyncReadyCallback)UiccLowLevelAccessApduResponseParse,
                      this);

  return;
}

void ModemMbim::QueryCurrentMbimCapabilities(ResultCallback cb) {
  auto reacquire_channel = base::BindOnce(&ModemMbim::GetEidStepCloseChannel,
                                          weak_factory_.GetWeakPtr());
  tx_queue_.push_front(
      {std::make_unique<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimDeviceCaps),
       base::BindOnce(&ModemMbim::RunNextStepOrRetry,
                      weak_factory_.GetWeakPtr(), std::move(reacquire_channel),
                      std::move(cb))});
  TransmitFromQueue();
}

void ModemMbim::AcquireChannel(base::OnceCallback<void(int)> cb) {
  LOG(INFO) << __func__;
  tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimOpenLogicalChannel),
       std::move(cb)});
  TransmitFromQueue();
}

void ModemMbim::ReacquireChannel(const uint32_t physical_slot,
                                 ResultCallback cb) {
  LOG(INFO) << __func__ << " with physical_slot: " << physical_slot;
  auto acquire_channel =
      base::BindOnce(&ModemMbim::AcquireChannel, weak_factory_.GetWeakPtr());
  tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimCloseLogicalChannel),
       base::BindOnce(&RunNextStep, std::move(acquire_channel),
                      std::move(cb))});
  TransmitFromQueue();
}

void ModemMbim::GetEidFromSim(ResultCallback cb) {
  VLOG(2) << __func__;
  tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimSendEidApdu),
       std::move(cb)});
  TransmitFromQueue();
}

void ModemMbim::GetEidStepCloseChannel(ResultCallback cb) {
  auto open_channel = base::BindOnce(&ModemMbim::GetEidStepOpenChannel,
                                     weak_factory_.GetWeakPtr());
  tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimCloseLogicalChannel),
       base::BindOnce(&RunNextStep, std::move(open_channel), std::move(cb))});
  TransmitFromQueue();
}

void ModemMbim::GetEidStepOpenChannel(ResultCallback cb) {
  VLOG(2) << __func__;

  auto get_eid_from_sim =
      base::BindOnce(&ModemMbim::GetEidFromSim, weak_factory_.GetWeakPtr());
  tx_queue_.push_back(
      {std::unique_ptr<TxInfo>(), AllocateId(),
       std::make_unique<MbimCmd>(MbimCmd::MbimType::kMbimOpenLogicalChannel),
       base::BindOnce(&ModemMbim::RunNextStepOrRetry,
                      weak_factory_.GetWeakPtr(), std::move(get_eid_from_sim),
                      std::move(cb))});
  TransmitFromQueue();
}

/* static */
void ModemMbim::SubscriberReadyStatusRspCb(MbimDevice* device,
                                           GAsyncResult* res,
                                           ModemMbim* modem_mbim) {
  g_autoptr(MbimMessage) response = NULL;
  VLOG(2) << __func__;
  g_autoptr(GError) error = NULL;
  MbimSubscriberReadyState ready_state =
      MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED;
  g_autofree gchar* subscriber_id = NULL;
  response = mbim_device_command_finish(device, res, &error);
  if (response &&
      mbim_message_response_get_result(response, MBIM_MESSAGE_TYPE_COMMAND_DONE,
                                       &error) &&
      mbim_message_subscriber_ready_status_response_parse(
          response, &ready_state, &subscriber_id,
          /* sim_iccid */ NULL,
          /* ready_info */ NULL,
          /* telephone_numbers_count */ NULL,
          /* telephone_numbers */ NULL, &error)) {
    modem_mbim->ready_state_ = ready_state;
    LOG(INFO) << "Current Sim status: " << ready_state;
    if (ready_state == MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED) {
      VLOG(2) << "Sim not inserted";
      modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
      return;
    }
    if (ready_state == MBIM_SUBSCRIBER_READY_STATE_INITIALIZED)
      VLOG(2) << "Profile already enabled";

    modem_mbim->ProcessMbimResult(kModemSuccess);
    return;
  }
  LOG(ERROR) << __func__ << "Failed due to error: " << error->message;
  modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
}

/* static */
void ModemMbim::DeviceCapsQueryReady(MbimDevice* device,
                                     GAsyncResult* res,
                                     ModemMbim* modem_mbim) {
  g_autoptr(MbimMessage) response = NULL;
  g_autoptr(GError) error = NULL;
  g_autofree gchar* caps_device_id = NULL;
  VLOG(2) << __func__;
  response = mbim_device_command_finish(device, res, &error);
  if (!response ||
      !mbim_message_response_get_result(
          response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
      !mbim_message_device_caps_response_parse(response, NULL, /* device_type */
                                               NULL, /* cellular class  */
                                               NULL, /* voice_class  */
                                               NULL, /* sim_class  */
                                               NULL, /* data_class */
                                               NULL, /* sms_caps */
                                               NULL, /* ctrl_caps */
                                               NULL, /* max_sessions */
                                               NULL, /* custom_data_class */
                                               &caps_device_id,
                                               NULL, /* firmware_info */
                                               NULL, /* hardware_info */
                                               &error)) {
    modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
    return;
  }
  modem_mbim->imei_ = caps_device_id;
  VLOG(2) << "IMEI received from modem: " << modem_mbim->imei_;
  modem_mbim->ProcessMbimResult(kModemSuccess);
}

/* static */
void ModemMbim::UiccLowLevelAccessCloseChannelSetCb(MbimDevice* device,
                                                    GAsyncResult* res,
                                                    ModemMbim* modem_mbim) {
  g_autoptr(GError) error = NULL;
  g_autoptr(MbimMessage) response = NULL;
  guint32 status;
  LOG(INFO) << __func__;
  response = mbim_device_command_finish(device, res, &error);
  modem_mbim->pending_response_ = false;

  if (response &&
      mbim_message_response_get_result(response, MBIM_MESSAGE_TYPE_COMMAND_DONE,
                                       &error) &&
      mbim_message_ms_uicc_low_level_access_close_channel_response_parse(
          response, &status, &error)) {
    modem_mbim->channel_ = kInvalidChannel;
    modem_mbim->ProcessMbimResult(kModemSuccess);
    return;
  }
  if (g_error_matches(error, MBIM_STATUS_ERROR,
                      MBIM_STATUS_ERROR_OPERATION_NOT_ALLOWED)) {
    LOG(INFO) << "Operation not allowed from modem: " << error->message;
  } else {
    LOG(INFO) << "Channel could not be closed: " << error->message;
  }
  modem_mbim->ProcessMbimResult(kModemSuccess);
}

/* static */
void ModemMbim::UiccLowLevelAccessOpenChannelSetCb(MbimDevice* device,
                                                   GAsyncResult* res,
                                                   ModemMbim* modem_mbim) {
  g_autoptr(GError) error = NULL;
  g_autoptr(MbimMessage) response = NULL;
  guint32 status;
  guint32 chl;
  guint32 rsp_size;
  const guint8* rsp = NULL;
  LOG(INFO) << __func__;
  response = mbim_device_command_finish(device, res, &error);
  modem_mbim->pending_response_ = false;
  if (response &&
      mbim_message_response_get_result(response, MBIM_MESSAGE_TYPE_COMMAND_DONE,
                                       &error) &&
      mbim_message_ms_uicc_low_level_access_open_channel_response_parse(
          response, &status, &chl, &rsp_size, &rsp, &error)) {
    if (status != kMbimMessageSuccess) {
      LOG(INFO) << "Could not open channel: " << error->message
                << ". Inserted sim may not be an eSIM.";
      modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
      return;
    }
    VLOG(2) << "Successfully opened channel: " << chl;
    modem_mbim->channel_ = chl;
    modem_mbim->ProcessMbimResult(kModemSuccess);
    return;
  }
  if (g_error_matches(error, MBIM_STATUS_ERROR,
                      MBIM_STATUS_ERROR_OPERATION_NOT_ALLOWED)) {
    LOG(INFO) << "Modem FW may not support eSIM: " << error->message;
  } else {
    LOG(INFO) << "Could not open channel:" << error->message
              << ". Inserted sim may not be an eSIM.";
  }
  modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
}

/* static */
void ModemMbim::UiccLowLevelAccessApduEidParse(MbimDevice* device,
                                               GAsyncResult* res,
                                               ModemMbim* modem_mbim) {
  g_autoptr(GError) error = NULL;
  g_autoptr(MbimMessage) response = NULL;
  guint32 status;
  guint32 response_size = 0;
  const guint8* out_response = NULL;
  std::vector<uint8_t> kGetEidDgiTag = {0xBF, 0x3E, 0x12, 0x5A, 0x10};
  response = mbim_device_command_finish(device, res, &error);

  // b/199808449. Close the device since we no longer need it. Hermes gets stuck
  // in an infinite loop if the modem is reset by modemfwd
  modem_mbim->CloseDevice();

  if (response &&
      mbim_message_response_get_result(response, MBIM_MESSAGE_TYPE_COMMAND_DONE,
                                       &error) &&
      mbim_message_ms_uicc_low_level_access_apdu_response_parse(
          response, &status, &response_size, &out_response, &error)) {
    if (response_size < 2 || out_response[0] != kGetEidDgiTag[0] ||
        out_response[1] != kGetEidDgiTag[1]) {
      modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
      return;
    }

    VLOG(2) << "Adding to payload from APDU response (" << response_size
            << " bytes)"
            << base::HexEncode(&out_response[kGetEidDgiTag.size()],
                               response_size - kGetEidDgiTag.size());
    for (int j = kGetEidDgiTag.size(); j < response_size; j++) {
      modem_mbim->eid_ += bcd_chars[(out_response[j] >> 4) & 0xF];
      modem_mbim->eid_ += bcd_chars[out_response[j] & 0xF];
    }
    LOG(INFO) << "EID for physical slot: " << modem_mbim->logical_slot_ + 1
              << " is " << modem_mbim->eid_;
    if (modem_mbim->current_state_ == State::kMbimInitializeStarted)
      modem_mbim->current_state_.Transition(State::kMbimStarted);
    modem_mbim->euicc_manager_->OnEuiccUpdated(
        modem_mbim->logical_slot_ + 1,
        EuiccSlotInfo(modem_mbim->logical_slot_, std::move(modem_mbim->eid_)));
    modem_mbim->ProcessMbimResult(kModemSuccess);
    return;
  }
  LOG(INFO) << "Could not find eSIM";
  modem_mbim->euicc_manager_->OnEuiccRemoved(modem_mbim->logical_slot_ + 1);
  modem_mbim->ProcessMbimResult(kModemMessageProcessingError);
  return;
}

/* static */
void ModemMbim::UiccLowLevelAccessApduResponseParse(MbimDevice* device,
                                                    GAsyncResult* res,
                                                    ModemMbim* modem_mbim) {
  g_autoptr(GError) error = NULL;
  g_autoptr(MbimMessage) response = NULL;
  guint32 status;
  guint32 response_size = 0;
  const guint8* out_response;
  CHECK(modem_mbim->tx_queue_.size());
  // Ensure that the queued element is for a kSendApdu command
  TxInfo* base_info = modem_mbim->tx_queue_[0].info_.get();
  CHECK(base_info);
  static ResponseApdu payload;
  ApduTxInfo* info = static_cast<ApduTxInfo*>(base_info);
  response = mbim_device_command_finish(device, res, &error);
  modem_mbim->pending_response_ = false;
  if (response &&
      mbim_message_response_get_result(response, MBIM_MESSAGE_TYPE_COMMAND_DONE,
                                       &error) &&
      mbim_message_ms_uicc_low_level_access_apdu_response_parse(
          response, &status, &response_size, &out_response, &error)) {
    VLOG(2) << "Adding to payload from APDU response (" << response_size
            << " bytes): " << base::HexEncode(out_response, response_size);

    payload.AddData(out_response, response_size);
    if (payload.MorePayloadIncoming()) {
      // Make the next transmit operation be a request for more APDU data
      info->apdu_ = payload.CreateGetMoreCommand(/*is_extended_apdu*/ false);
      return;
    }
    if (info->apdu_.HasMoreFragments()) {
      // Send next fragment of APDU
      VLOG(2) << "Sending next APDU fragment";
      modem_mbim->TransmitFromQueue();
      return;
    }
    // In case of mbim there are no appended status bytes in the APDU received.
    // Hence no extra bytes to be removed.
    modem_mbim->responses_.push_back(payload.ReleaseOnly());
    std::move(modem_mbim->tx_queue_[0].cb_).Run(lpa::card::EuiccCard::kNoError);
    modem_mbim->tx_queue_.pop_front();
    modem_mbim->TransmitFromQueue();
  } else {
    std::move(modem_mbim->tx_queue_[0].cb_)
        .Run(lpa::card::EuiccCard::kSendApduError);
    modem_mbim->tx_queue_.pop_front();
    modem_mbim->TransmitFromQueue();
    return;
  }
}

/* static */
void ModemMbim::ClientIndicationCb(MbimDevice* device,
                                   MbimMessage* notification,
                                   ModemMbim* modem_mbim) {
  MbimService service;
  g_autoptr(GError) error = NULL;
  service = mbim_message_indicate_status_get_service(notification);

  VLOG(2) << "Received notification for service: "
          << mbim_service_get_string(service);
  VLOG(2) << "Command received from the modem: "
          << mbim_cid_get_printable(
                 service, mbim_message_indicate_status_get_cid(notification));

  switch (service) {
    case MBIM_SERVICE_BASIC_CONNECT:
      if (mbim_message_indicate_status_get_cid(notification) ==
          MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS) {
        MbimSubscriberReadyState ready_state;
        if (mbim_message_subscriber_ready_status_notification_parse(
                notification, &ready_state,
                /* subscriber_id */ NULL,
                /* sim_iccid */ NULL,
                /* ready_info */ NULL,
                /* telephone_numbers_count */ NULL,
                /* telephone_numbers */ NULL, &error)) {
          modem_mbim->ready_state_ = ready_state;
          modem_mbim->is_ready_state_valid = true;
          LOG(INFO) << "Current sim status: " << ready_state;
          if (ready_state == MBIM_SUBSCRIBER_READY_STATE_INITIALIZED) {
            VLOG(2) << "Sim has one profile enabled";
          } else if (ready_state ==
                     MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED) {
            VLOG(2) << "Sim not inserted";
          }
        }
      }
      break;
    default:
      VLOG(2) << "Indication received is not handled";
      break;
  }
  return;
}

void ModemMbim::CloseDevice() {
  if (device_ && g_signal_handler_is_connected(device_.get(), indication_id_))
    g_signal_handler_disconnect(device_.get(), indication_id_);
  device_.reset();
}

bool ModemMbim::State::Transition(ModemMbim::State::Value value) {
  bool valid_transition = true;
  switch (value) {
    case kMbimUninitialized:
      valid_transition = true;
      break;
    default:
      // Most states can only transition from the previous state.
      valid_transition = (value == value_ + 1);
  }
  if (valid_transition) {
    LOG(INFO) << "Transitioning from state " << *this << " to state "
              << State(value);
    value_ = value;
  } else {
    LOG(ERROR) << "Cannot transition from state " << *this << " to state "
               << State(value);
  }
  return valid_transition;
}

void ModemMbim::StoreAndSetActiveSlot(const uint32_t physical_slot,
                                      ResultCallback cb) {
  LOG(INFO) << __func__ << " physical_slot:" << physical_slot;
  // The modem may be reset, causing device_ to be invalid. Reopen to be
  // safe. Then acquire a channel.
  CloseDevice();

  auto reacquire_channel = base::BindOnce(
      &ModemMbim::ReacquireChannel, weak_factory_.GetWeakPtr(), physical_slot);
  init_done_cb_ =
      base::BindOnce(&RunNextStep, std::move(reacquire_channel), std::move(cb));
  mbim_device_new(file_, /* cancellable */ NULL,
                  (GAsyncReadyCallback)MbimCreateNewDeviceCb, this);
}

void ModemMbim::StartProfileOp(uint32_t physical_slot, ResultCallback cb) {
  LOG(INFO) << __func__ << " physical_slot:" << physical_slot;
  retry_count_ = 0;
  is_ready_state_valid = false;
  StoreAndSetActiveSlot(physical_slot, std::move(cb));
}

void ModemMbim::FinishProfileOp(ResultCallback cb) {
  LOG(INFO) << __func__;
  const guint MBIM_SUBSCRIBER_READY_STATE_NO_ESIM_PROFILE = 7;
  if (!is_ready_state_valid ||
      !(ready_state_ == MBIM_SUBSCRIBER_READY_STATE_NOT_INITIALIZED ||
        ready_state_ == MBIM_SUBSCRIBER_READY_STATE_INITIALIZED ||
        ready_state_ == MBIM_SUBSCRIBER_READY_STATE_NO_ESIM_PROFILE)) {
    if (retry_count_ > kMaxRetries) {
      LOG(ERROR) << "Could not finish profile operation, ready_state_="
                 << ready_state_
                 << ", is_ready_state_valid=" << is_ready_state_valid;
      std::move(cb).Run(kModemMessageProcessingError);
      return;
    }
    retry_count_++;
    executor_->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&ModemMbim::FinishProfileOp, weak_factory_.GetWeakPtr(),
                       std::move(cb)),
        kSimRefreshDelay);
    return;
  }
  retry_count_ = 0;
  AcquireChannel(std::move(cb));
}

void ModemMbim::RestoreActiveSlot(ResultCallback cb) {
  LOG(INFO) << __func__;
  std::move(cb).Run(kModemSuccess);
}

bool ModemMbim::IsSimValidAfterEnable() {
  VLOG(2) << __func__;
  return false;
  // The sim issues a proactive refresh after an enable. This
  // function should return true immediately after the refresh completes,
  // However, the LPA expects that this function does not read any
  // other state variable. Thus, we simply return false until the LPA
  // times out, and then finish the operation. This imposes a 15 sec penalty
  // on every enable and 30 sec penalty on every disable.
  // A workaround is to return true and complete the eSIM operation before the
  // refresh. FinishProfileOp can gate the dbus response until the refresh is
  // complete. However, this exposes UI issues.
}

bool ModemMbim::IsSimValidAfterDisable() {
  VLOG(2) << __func__;
  return false;
}

}  // namespace hermes
