Add a "gsm signal-profile" command

The previous "gsm signal" command was only letting the user set the RSSI
and BER. This new "signal-profile" commands uses a set of five profiles
corresponding to the signal strength bars displayed on the phone (from 0
to 4, matching one of None, Poor, Moderate, Good, Great).

Change-Id: I9e8b151d10e435b5eddee7e83c9eb381bc805fa0
Signed-off-by: Mathieu Pasquet <mathieu.pasquet@alterway.fr>
diff --git a/android-commands.h b/android-commands.h
index 910d238..e612bb0 100644
--- a/android-commands.h
+++ b/android-commands.h
@@ -351,11 +351,20 @@
         .args_type = "arg:S?",
         .params = "",
         .help = "sets the rssi and ber"
-            "signal <rssi> [<ber>]' changes the reported strength and error rate on next (15s) update.\n"
-    "rssi range is 0..31 and 99 for unknown\n"
-    "ber range is 0..7 percent and 99 for unknown\n",
+                "signal <rssi> [<ber>]' changes the reported strength and error rate on next (15s) update.\n"
+                "rssi range is 0..31 and 99 for unknown\n"
+                "ber range is 0..7 percent and 99 for unknown\n",
         .mhandler.cmd = android_console_gsm_signal,
     },
+    {
+        .name = "signal-profile",
+        .args_type = "arg:S?",
+        .params = "",
+        .help = "sets the signal strength profile"
+            "signal-profile <strength>' changes the reported strength on next (15s) update.\n"
+            "strength range is 0..4\n",
+        .mhandler.cmd = android_console_gsm_signal_profile,
+    },
     { NULL, NULL, },
 };
 
diff --git a/android-console.c b/android-console.c
index 2805f00..8f0dbc4 100644
--- a/android-console.c
+++ b/android-console.c
@@ -1387,7 +1387,8 @@
     CMD_GSM_DATA = 7,
     CMD_GSM_VOICE = 8,
     CMD_GSM_STATUS = 9,
-    CMD_GSM_SIGNAL = 10
+    CMD_GSM_SIGNAL = 10,
+    CMD_GSM_SIGNAL_PROFILE = 11
 };
 
 static const char* gsm_help[] = {
@@ -1409,7 +1410,8 @@
         "   gsm data               modify data connection state\n"
         "   gsm voice              modify voice connection state\n"
         "   gsm status             display GSM state\n"
-        "   gsm signal             sets the rssi and ber\n",
+        "   gsm signal             sets the rssi and ber\n"
+        "   gsm signal-profile     sets the signal strength\n",
         /* CMD_GSM_LIST */
         "list current phone calls\n"
         "'gsm list' lists all inbound and outbound calls and their state\n",
@@ -1449,6 +1451,11 @@
         "rate on next (15s) update.\n"
         "rssi range is 0..31 and 99 for unknown\n"
         "ber range is 0..7 percent and 99 for unknown\n",
+        /* CMD_GSM_SIGNAL_PROFILE */
+        "sets the signal strength\n"
+        "'gsm signal-profile <strength>' changes the reported signal strength "
+        "on next (15s) update.\n"
+        "strength range is 0..4\n",
 };
 
 void android_console_gsm(Monitor* mon, const QDict* qdict) {
@@ -1477,7 +1484,9 @@
             cmd = CMD_GSM_VOICE;
         } else if (strstr(helptext, "status")) {
             cmd = CMD_GSM_STATUS;
-        } else if (strstr(helptext, "signal")) {
+        } else if (strstr(helptext, "signal-profile")) {
+            cmd = CMD_GSM_SIGNAL_PROFILE;
+        } else if (strstr(helptext, "signal")) { // Must be after "signal-profile"
             cmd = CMD_GSM_SIGNAL;
         }
     }
@@ -1859,6 +1868,29 @@
     monitor_printf(mon, "OK\n");
 }
 
+void android_console_gsm_signal_profile(Monitor* mon, const QDict* qdict) {
+    char* args = (char*)qdict_get_try_str(qdict, "arg");
+    char* end;
+    char*   p = args;
+    if (!p)
+        p = "";
+    int  val = strtol( p, &end, 10 );
+
+    if (end == p || (end != NULL && *end != '\0')) {
+        monitor_printf( mon, "KO: argument '%s' is not a number\n", p );
+        return;
+    }
+
+    if (val < 0 || val > 4) {
+        monitor_printf(mon, "KO: invalid signal strength - must be 0..4\n");
+        return;
+    }
+
+    amodem_set_signal_strength_profile( android_modem, val );
+
+    monitor_printf(mon, "OK\n");
+}
+
 enum { CMD_GEO = 0, CMD_GEO_NMEA = 1, CMD_GEO_FIX = 2 };
 
 static const char* geo_help[] = {
diff --git a/android-console.h b/android-console.h
index efb275d..2cc39b9 100644
--- a/android-console.h
+++ b/android-console.h
@@ -87,6 +87,7 @@
 void android_console_gsm_voice(Monitor *mon, const QDict *qdict);
 void android_console_gsm_status(Monitor *mon, const QDict *qdict);
 void android_console_gsm_signal(Monitor *mon, const QDict *qdict);
+void android_console_gsm_signal_profile(Monitor *mon, const QDict *qdict);
 void android_console_gsm(Monitor *mon, const QDict *qdict);
 
 void android_console_rotate_screen(Monitor *mon, const QDict *qdict);
diff --git a/android-qemu2-glue/qemu-cellular-agent-impl.c b/android-qemu2-glue/qemu-cellular-agent-impl.c
index 7e50dd9..7197f3f 100644
--- a/android-qemu2-glue/qemu-cellular-agent-impl.c
+++ b/android-qemu2-glue/qemu-cellular-agent-impl.c
@@ -30,6 +30,18 @@
     }
 }
 
+static void cellular_setSignalStrengthProfile(int zeroTo4)
+{
+    // (See do_gsm_signal_profile() in android-qemu1-glue/console.c)
+
+    if (android_modem) {
+        if (zeroTo4 < 0) zeroTo4 = 0;
+        if (zeroTo4 > 4) zeroTo4 = 4;
+
+        amodem_set_signal_strength_profile(android_modem, zeroTo4);
+    }
+}
+
 static void cellular_setVoiceStatus(enum CellularStatus voiceStatus)
 {
     // (See do_gsm_voice() in android-qemu1-glue/console.c)
@@ -106,6 +118,7 @@
 
 static const QAndroidCellularAgent sQAndroidCellularAgent = {
     .setSignalStrength = cellular_setSignalStrength,
+    .setSignalStrengthProfile = cellular_setSignalStrengthProfile,
     .setVoiceStatus = cellular_setVoiceStatus,
     .setDataStatus = cellular_setDataStatus,
     .setStandard = cellular_setStandard};