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). Signed-off-by: Mathieu Pasquet <mathieu.pasquet@alterway.fr> Change-Id: If4c0a17af0986e58d11db57140fa9f931bdae8aa
diff --git a/android-qemu1-glue/qemu-cellular-agent-impl.c b/android-qemu1-glue/qemu-cellular-agent-impl.c index c86af98..e916fe7 100644 --- a/android-qemu1-glue/qemu-cellular-agent-impl.c +++ b/android-qemu1-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) @@ -103,6 +115,7 @@ static const QAndroidCellularAgent sQAndroidCellularAgent = { .setSignalStrength = cellular_setSignalStrength, + .setSignalStrengthProfile = cellular_setSignalStrengthProfile, .setVoiceStatus = cellular_setVoiceStatus, .setDataStatus = cellular_setDataStatus, .setStandard = cellular_setStandard};
diff --git a/android/console.c b/android/console.c index d856581..bc950549e 100644 --- a/android/console.c +++ b/android/console.c
@@ -1484,61 +1484,85 @@ static int do_gsm_signal( ControlClient client, char* args ) { - enum { SIGNAL_RSSI = 0, SIGNAL_BER, NUM_SIGNAL_PARAMS }; - char* p = args; - int top_param = -1; - int params[ NUM_SIGNAL_PARAMS ]; + enum { SIGNAL_RSSI = 0, SIGNAL_BER, NUM_SIGNAL_PARAMS }; + char* p = args; + int top_param = -1; + int params[ NUM_SIGNAL_PARAMS ]; - static int last_ber = 99; + static int last_ber = 99; - if (!p) - p = ""; + if (!p) + p = ""; - /* tokenize */ - while (*p) { - char* end; - int val = strtol( p, &end, 10 ); + /* tokenize */ + while (*p) { + char* end; + int val = strtol( p, &end, 10 ); - if (end == p) { - control_write( client, "KO: argument '%s' is not a number\n", p ); - return -1; - } + if (end == p) { + control_write( client, "KO: argument '%s' is not a number\n", p ); + return -1; + } - params[++top_param] = val; - if (top_param + 1 == NUM_SIGNAL_PARAMS) - break; + params[++top_param] = val; + if (top_param + 1 == NUM_SIGNAL_PARAMS) + break; - p = end; - while (*p && (p[0] == ' ' || p[0] == '\t')) - p += 1; - } + p = end; + while (*p && (p[0] == ' ' || p[0] == '\t')) + p += 1; + } - /* sanity check */ - if (top_param < SIGNAL_RSSI) { - control_write( client, "KO: not enough arguments: see 'help gsm signal' for details\r\n" ); - return -1; - } + /* sanity check */ + if (top_param < SIGNAL_RSSI) { + control_write( client, "KO: not enough arguments: see 'help gsm signal' for details\r\n" ); + return -1; + } - int rssi = params[SIGNAL_RSSI]; - if ((rssi < 0 || rssi > 31) && rssi != 99) { - control_write( client, "KO: invalid RSSI - must be 0..31 or 99\r\n"); - return -1; - } + int rssi = params[SIGNAL_RSSI]; + if ((rssi < 0 || rssi > 31) && rssi != 99) { + control_write( client, "KO: invalid RSSI - must be 0..31 or 99\r\n"); + return -1; + } - /* check ber is 0..7 or 99 */ - if (top_param >= SIGNAL_BER) { - int ber = params[SIGNAL_BER]; - if ((ber < 0 || ber > 7) && ber != 99) { - control_write( client, "KO: invalid BER - must be 0..7 or 99\r\n"); - return -1; - } - last_ber = ber; - } + /* check ber is 0..7 or 99 */ + if (top_param >= SIGNAL_BER) { + int ber = params[SIGNAL_BER]; + if ((ber < 0 || ber > 7) && ber != 99) { + control_write( client, "KO: invalid BER - must be 0..7 or 99\r\n"); + return -1; + } + last_ber = ber; + } - amodem_set_signal_strength( android_modem, rssi, last_ber ); + amodem_set_signal_strength( android_modem, rssi, last_ber ); - return 0; - } + return 0; +} + +static int +do_gsm_signal_profile( ControlClient client, char* args ) +{ + char* end; + char* p = args; + if (!p) + p = ""; + int val = strtol( p, &end, 10 ); + + if (end == p) { + control_write( client, "KO: argument '%s' is not a number\r\n", p ); + return -1; + } + + if (val < 0 || val > 4) { + control_write( client, "KO: invalid signal strength - must be 0..4\r\n"); + return -1; + } + + amodem_set_signal_strength_profile( android_modem, val ); + + return 0; +} #if 0 @@ -1620,6 +1644,11 @@ "ber range is 0..7 percent and 99 for unknown\r\n", NULL, do_gsm_signal, NULL }, + { "signal-profile", "set the signal strength profile", + "'gsm signal-profile <strength>' changes the reported strength on next (15s) update.\r\n" + "strength range is 0..4\r\n", + NULL, do_gsm_signal_profile, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL } };
diff --git a/android/emulation/control/cellular_agent.h b/android/emulation/control/cellular_agent.h index f631872..734a8e9 100644 --- a/android/emulation/control/cellular_agent.h +++ b/android/emulation/control/cellular_agent.h
@@ -22,11 +22,18 @@ enum CellularStandard { Cellular_Std_GSM, Cellular_Std_HSCSD, Cellular_Std_GPRS, Cellular_Std_EDGE, Cellular_Std_UMTS, Cellular_Std_HSDPA, Cellular_Std_full }; +enum CellularSignal { Cellular_Signal_None, Cellular_Signal_Poor, Cellular_Signal_Moderate, + Cellular_Signal_Good, Cellular_Signal_Great }; + typedef struct QAndroidCellularAgent { // Sets the cellular signal strength // Input: 0(none) .. 31(very strong) void (*setSignalStrength)(int zeroTo31); + // Sets the cellular signal strength + // Input: enum CellularSignal, above + void (*setSignalStrengthProfile)(enum CellularSignal); + // Sets the status of the voice connectivity // Input: enum CellularStatus, above void (*setVoiceStatus)(enum CellularStatus);
diff --git a/android/telephony/modem.c b/android/telephony/modem.c index 1690778..1602cd1 100644 --- a/android/telephony/modem.c +++ b/android/telephony/modem.c
@@ -210,6 +210,46 @@ #define A_MODEM_SELF_SIZE 3 +typedef struct _signal { + int gsm_rssi; + int gsm_ber; + int cdma_dbm; + int cdma_ecio; + int evdo_dbm; + int evdo_ecio; + int evdo_snr; + int lte_rssi; + int lte_rsrp; + int lte_rsrq; + int lte_rssnr; + int lte_cqi; + int lte_timing; +} signal_t; + +typedef enum { + NONE = 0, + POOR = 1, + MODERATE = 2, + GOOD = 3, + GREAT = 4, +} signal_strength; + +/* + * Values derived from the ranges used in the SignalStrength + * class in the frameworks/base telephony framework. + */ +static const signal_t NET_PROFILES[5] = { + /* NONE */ + {0, 7, 105, 160, 110, 160, 0, 105, 140, 3, -200, 0, 500}, + /* POOR (one bar) */ + {5, 5, 100, 150, 100, 150, 2, 100, 110, 5, 0, 2, 300}, + /* MODERATE (2 bars) */ + {12, 4, 90, 120, 80, 120, 4, 90, 100, 10, 30, 7, 200}, + /* GOOD (3 bars) */ + {20, 2, 80, 100, 70, 100, 6, 70, 90, 15, 100, 12, 100}, + /* GREAT (4 bars) */ + {30, 0, 70, 80, 60, 80, 7, 60, 80, 20, 200, 15, 50}, +}; typedef struct AModemRec_ { @@ -222,8 +262,12 @@ int cell_id; int base_port; - int rssi; - int ber; + /* Signal strength variables */ + int use_signal_profile; + signal_strength quality; + int rssi; + int ber; + /* SMS */ int wait_sms; @@ -455,7 +499,9 @@ modem->radio_state = A_RADIO_STATE_OFF; modem->wait_sms = 0; - modem->rssi= 7; // Two signal strength bars + modem->use_signal_profile = 1; + modem->quality = MODERATE; // Two signal strength bars + modem->rssi = 7; // Two signal strength bars modem->ber = 99; // Means 'unknown' modem->oper_name_index = amodem_nvram_get_int(modem, NV_OPER_NAME_INDEX, 2); @@ -920,6 +966,16 @@ { modem->rssi = rssi; modem->ber = ber; + modem->use_signal_profile = 0; +} + +void +amodem_set_signal_strength_profile( AModem modem, int quality ) +{ + if (quality >= NONE && quality <= GREAT) { + modem->quality = quality; + modem->use_signal_profile = 1; + } } static void @@ -2190,14 +2246,25 @@ android_snapshot_update_time_request = 0; } - // rssi = 0 (<-113dBm) 1 (<-111) 2-30 (<-109--53) 31 (>=-51) 99 (?!) - // ber (bit error rate) - always 99 (unknown), apparently. - // TODO: return 99 if modem->radio_state==A_RADIO_STATE_OFF, once radio_state is in snapshot. - int rssi = modem->rssi; - int ber = modem->ber; - rssi = (0 > rssi && rssi > 31) ? 99 : rssi ; - ber = (0 > ber && ber > 7 ) ? 99 : ber; - amodem_add_line( modem, "+CSQ: %i,%i,85,130,90,6,4,25,9,50,68,12\r\n", rssi, ber ); + if (modem->use_signal_profile) { + signal_t current_signal = NET_PROFILES[modem->quality]; + amodem_add_line(modem, "+CSQ: %i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i\r\n", + current_signal.gsm_rssi, current_signal.gsm_ber, + current_signal.cdma_dbm, current_signal.cdma_ecio, + current_signal.evdo_dbm, current_signal.evdo_ecio, current_signal.evdo_snr, + current_signal.lte_rssi, current_signal.lte_rsrp, current_signal.lte_rsrq, + current_signal.lte_rssnr, current_signal.lte_cqi, current_signal.lte_timing); + } + else { + // rssi = 0 (<-113dBm) 1 (<-111) 2-30 (<-109--53) 31 (>=-51) 99 (?!) + // ber (bit error rate) - always 99 (unknown), apparently. + // TODO: return 99 if modem->radio_state==A_RADIO_STATE_OFF, once radio_state is in snapshot. + int rssi = modem->rssi; + int ber = modem->ber; + rssi = (0 > rssi && rssi > 31) ? 99 : rssi; + ber = (0 > ber && ber > 7 ) ? 99 : ber; + amodem_add_line(modem, "+CSQ: %i,%i,85,130,90,6,4,25,9,50,68,12\r\n", rssi, ber); + } return amodem_end_line( modem ); }
diff --git a/android/telephony/modem.h b/android/telephony/modem.h index 5b896bf..ef41075 100644 --- a/android/telephony/modem.h +++ b/android/telephony/modem.h
@@ -50,6 +50,9 @@ /* Set the received signal strength indicator and bit error rate */ extern void amodem_set_signal_strength( AModem modem, int rssi, int ber ); +/* Set the received signal strength profile */ +extern void amodem_set_signal_strength_profile( AModem modem, int quality ); + /** SIM CARD STATUS **/ extern ASimCard amodem_get_sim( AModem modem );