modem-utilities: Add commands to request/install smds profiles

Add commands to request pending events from SMDS. This gathers pending
profiles meant for the device(EID). Following this, we may choose to
install a pending profile.

BUG=b:169946381
TEST=modem esim request_pending_profiles ${EUICC} ${ROOT_SMDS};modem esim install_pending_profile ${EUICC} ${ICCID}

Change-Id: Ib2487d281a63b4839e66f05345a773ca24d76c23
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2567648
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Tested-by: Pavan Holla <pholla@google.com>
Commit-Queue: Pavan Holla <pholla@google.com>
diff --git a/modem-utilities/modem b/modem-utilities/modem
index fc5187d..291bd3b 100755
--- a/modem-utilities/modem
+++ b/modem-utilities/modem
@@ -139,9 +139,13 @@
   echo "  esim set_test_mode <true/false>              Set hermes to test mode"
   echo "  esim refresh_profiles [-euicc <euicc>]       Get list of profiles " \
     "from eSIM"
+  echo "  esim request_pending_profiles [-euicc <euicc>] [smds] " \
+    "Get list of pending profiles from SMDS"
   echo "  esim status                                  Display eSIM status"
   echo "  esim install [-euicc <euicc>] <activation> [<confirmation>]" \
     "Install eSIM profile"
+  echo "  esim install [-euicc <euicc>] <iccid> [<confirmation>]" \
+    "Install an eSIM profile fetched by request_pending_profiles"
   echo "  esim uninstall [-euicc <euicc>] <iccid>      Uninstall eSIM profile"
   echo "  esim enable [-euicc <euicc>] <iccid>         Enable eSIM profile"
   echo "  esim disable [-euicc <euicc>] <iccid>        Disable eSIM profile"
diff --git a/modem-utilities/modem-common.sh b/modem-utilities/modem-common.sh
index e298bf5..2766e68 100644
--- a/modem-utilities/modem-common.sh
+++ b/modem-utilities/modem-common.sh
@@ -128,6 +128,10 @@
       poll_for_dbus_service "${HERMES}"
       esim_refresh_profiles "${euicc}" "$@"
       ;;
+    request_pending_profiles)
+      poll_for_dbus_service "${HERMES}"
+      esim_request_pending_profiles "${euicc}" "$@"
+      ;;
     status)
       poll_for_dbus_service "${HERMES}"
       esim_status "$@"
@@ -136,6 +140,10 @@
       poll_for_dbus_service "${HERMES}"
       esim_install "${euicc}" "$@"
       ;;
+    install_pending_profile)
+      poll_for_dbus_service "${HERMES}"
+      esim_install_pending_profile "${euicc}" "$@"
+      ;;
     uninstall)
       poll_for_dbus_service "${HERMES}"
       esim_uninstall "${euicc}" "$@"
@@ -150,8 +158,8 @@
       ;;
     *)
       error_exit "Expected one of "\
-        "{set_test_mode|refresh_profiles|status|install|uninstall|Enable"\
-        "|disable}"
+        "{set_test_mode|refresh_profiles|request_pending_profiles|status"\
+        "install|install_pending_profile|uninstall|enable|disable}"
       ;;
   esac
 }
@@ -172,21 +180,30 @@
   local iccid="$2"
   [ -z "${iccid}" ] && error_exit "No iccid provided."
 
-  local profiles
-  profiles=$(dbus_property "${HERMES}" "${euicc}" \
-    "${HERMES_EUICC_IFACE}" "InstalledProfiles" |
-               sed 's|^/[[:digit:]]* ||')
-  [ -z "${profiles}" ] && error_exit "${euicc} has no installed profiles."
+  local profile_type
+  for profile_type in "InstalledProfiles" "PendingProfiles"; do
+    local profiles
+    profiles="$(dbus_property "${HERMES}" "${euicc}" \
+                              "${HERMES_EUICC_IFACE}" "${profile_type}" |
+                              sed 's|^/[[:digit:]]* ||' | tr '\n' ' ')"
 
-  local profile
-  for profile in ${profiles}; do
-    local current
-    current=$(dbus_property "${HERMES}" "${profile}" \
-                            "${HERMES_PROFILE_IFACE}" Iccid)
-    if [ "${current}" = "${iccid}" ]; then
-      echo "${profile}"
-      return
+    if ! echo "${profiles}" | grep -q -E \
+      '^(/org/chromium/Hermes/profile/[0-9]+ )*$'; then
+
+      error_exit "Invalid profile objects received from hermes"
+
     fi
+
+    local profile
+    for profile in ${profiles}; do
+      local current
+      current="$(dbus_property "${HERMES}" "${profile}" \
+                               "${HERMES_PROFILE_IFACE}" Iccid)"
+      if [ "${current}" = "${iccid}" ]; then
+        echo "${profile}"
+        return
+      fi
+    done
   done
   error_exit "No matching Profile found for iccid ${iccid}."
 }
@@ -239,6 +256,16 @@
             string:"${activation_code}" string:"${confirmation_code}"
 }
 
+esim_install_pending_profile() {
+  local euicc="$1"
+  local profile
+  profile=$(esim_profile_from_iccid "$@")
+  local confirmation_code="$3"
+  dbus_call "${HERMES}" "${euicc}" \
+            "${HERMES_EUICC_IFACE}.InstallPendingProfile" \
+            objpath:"${profile}" string:"${confirmation_code}"
+}
+
 esim_uninstall() {
   local euicc="$1"
   local profile
@@ -248,6 +275,14 @@
             "${HERMES_EUICC_IFACE}.UninstallProfile" objpath:"${profile}"
 }
 
+esim_request_pending_profiles() {
+  local euicc="$1"
+  local smds="$2"
+
+  dbus_call "${HERMES}" "${euicc}" \
+            "${HERMES_EUICC_IFACE}.RequestPendingProfiles" string:"${smds}"
+}
+
 esim_enable() {
   local profile
   profile=$(esim_profile_from_iccid "$@")