[BUG] [FP6] Network MMI Command Failure for Call Forwarding due to Modem/RIL Firmware Issues
Bug Report: Network MMI Command Failure for Call Forwarding due to Modem/RIL Firmware Issues
Device Information:
-
Device Model: Fairphone 6
-
OS Version: e/OS v3.4-a15-20260114569178-official-FP6
-
Carrier: Tello
-
SIM Type: eSIM
( ALSO WITH * Carrier: TMobile * SIM Type: physical SIM )
Summary:
Network MMI commands for call forwarding (e.g., **61*<number>#) consistently fail on the FP6.
A generic "Call forwarding connection problem or invalid MMI code." error is returend.
The failure appears to be rooted in the FP6 modem firmware and the e/OS(Lineage?)-specific RIL (Radio Interface Layer) implementation. Leads to failed network state reporting & inability to process standard telephony service requests.
Expected Behavior: Network MMI commands should be processed successfully by the network. Phone should display confirmation msg indicating the call forwarding settings have been updated. Call forwarding should be set, verifiable at phone and carrier.
Impact: Unable to set/manage call forwarding settings using standard MMI codes.
Conclusion: MMI cmd failure is a direct consequence of low-level firmware and RIL implementation bugs on the FP6. These prevent modem from: (1) correctly processing standard telephony requests (2) accurately reporting network state information to Android OS The MMI command failure is a direct consequence of deep-seated firmware and RIL implementation bugs on the device. These issues prevent the modem from:
- Correctly processing standard telephony requests.
- Accurately reporting network state information to the Android operating system.
A f/w update from Fairphone appears required to resolve these device-side issues.
Steps to Reproduce:
(1) set config configure device
WiFi: OFF
and SIM as:
WiFi Scanning: OFF
WiFi Calling: OFF
Preferred Network: 4G
4G Calling / VoLTE: ON
Carrier Video Calling: ON
Allow 2G: OFF
(2) confirn config check @ MMI code
-> *#*#4636#*#*
Phone Number: 1XXXXXXXXXX {CARRIER:, UICC:1XXXXXXXXXX, IMS: +1XXXXXXXXXX}
Data Network Type: LTE
Data Raw Registration State: HOME
Override Network Type: LTE_CA
Voice Service: In Service
Voice Network Type: LTE
Voice Raw Registration State: HOME
Preferred Network Type: LTE/WCDMA
-> IMS Status:
IMS Registration: Registered
Voice over LTE: Available
Voice over WiFi: Unavailable
Video Calling: Unavailable
UT Interface: Unavailable
$ adb shell "\
getprop ro.build.version.release; \
getprop ro.build.version.sdk; \
getprop ro.build.id; \
getprop ro.build.fingerprint; \
getprop ro.build.version.security_patch; \
getprop ro.product.manufacturer; \
getprop ro.product.model \
"
15
35
BP1A.250505.005
Fairphone/FP6/FP6:15/FP6.QREL.15.162.0/VS1V:user/release-keys
2026-01-01
Fairphone
Fairphone 6
$ adb shell getprop | grep -Ei "e.os|lineage|build.version.incremental"
[ro.bootimage.build.version.incremental]: [1768386585]
[ro.build.flavor]: [lineage_FP6-user]
[ro.build.version.base_os]: []
[ro.build.version.incremental]: [1768386585]
[ro.lineage.build.version]: [3.4]
[ro.lineage.device]: [FP6]
[ro.lineage.display.version]: [3.4-a15-20260114569178-official-FP6]
[ro.lineage.releasetype]: [official]
[ro.lineage.version]: [3.4-a15-20260114569178-official-FP6]
[ro.odm.build.version.incremental]: [1768386585]
[ro.product.bootimage.name]: [lineage_FP6]
[ro.product.build.version.incremental]: [1768386585]
[ro.product.name]: [lineage_FP6]
[ro.product.odm.name]: [lineage_FP6]
[ro.product.product.name]: [lineage_FP6]
[ro.product.system.name]: [lineage_FP6]
[ro.product.system_dlkm.name]: [lineage_FP6]
[ro.product.system_ext.name]: [lineage_FP6]
[ro.product.vendor.name]: [lineage_FP6]
[ro.product.vendor_dlkm.name]: [lineage_FP6]
[ro.system.build.version.incremental]: [1768386585]
[ro.system_dlkm.build.version.incremental]: [1768386585]
[ro.system_ext.build.version.incremental]: [1768386585]
[ro.vendor.build.version.incremental]: [1768386585]
[ro.vendor_dlkm.build.version.incremental]: [1768386585]
(3) Open Phone app. Dial an MMI code for call forwarding,
**61*1ZZZZZZZZZZ#
(4) Observe MMI fail error:
"Call forwarding connection problem or invalid MMI code."
the device's response.
Log Detail
with config as above,
from exec of **61*1ZZZZZZZZZZ# to appearance of error,
output:
adb logcat -b all -s GsmCdmaPhone GsmMmiCode RILJ RILC Telephony MMIDialogActivity Telecom CallManager QtiOemHookAidl QcrilMsgTunnelIfaceManager | grep -E -i -C 5 "GsmMmiCode|SET_CALL_FORWARD|MODEM_ERR|Telecom.*DIALED_MMI|MMIDialogActivity.*onMMIComplete|Unsupported unsolicited response code 1028" | grep -Ev "DisplayBase::CommitThread|commit_sys_config_file"
01-26 10:34:12.972 3271 3440 D RILJ : [UNSL]< UNSOL_RESPONSE_NETWORK_STATE_CHANGED [PHONE1]
01-26 10:34:12.976 3271 3271 D RILJ : [4323]> OPERATOR [PHONE1]
01-26 10:34:12.978 3271 3271 D RILJ : [4324]> QUERY_NETWORK_SELECTION_MODE [PHONE1]
01-26 10:34:12.979 3271 3440 D RILJ : Unsol response received; Sending ack to ril.cpp [PHONE1]
--
01-26 10:34:16.065 3271 3315 D RILJ : Unsol response received; Sending ack to ril.cpp [PHONE1]
01-26 10:34:16.065 3271 3315 D RILJ : [UNSL]< UNSOL_LCE_INFO_RECV [{mType=0, mDownlinkCapacityKbps=-1, mUplinkCapacityKbps=75}, {mType=1, mDownlinkCapacityKbps=0, mUplinkCapacityKbps=0}] [PHONE1]
01-26 10:34:16.066 3271 3271 D GsmCdmaPhone: [1] updateLinkCapacityEstimate: lce list=[{mType=0, mDownlinkCapacityKbps=-1, mUplinkCapacityKbps=75}, {mType=1, mDownlinkCapacityKbps=0, mUplinkCapacityKbps=0}]
01-26 10:34:18.335 3254 3289 D QtiOemHookAidl: oemHookRawIndication length=21
01-26 10:34:18.336 3254 3254 D QcrilMsgTunnelIfaceManager: handleMessage what = 0
01-26 10:34:18.336 1758 2300 E RILC : Unsupported unsolicited response code 1028
01-26 10:34:18.351 3271 3315 D RILJ : Unsol response received; Sending ack to ril.cpp [PHONE1]
01-26 10:34:18.351 3271 3315 D RILJ : [UNSL]< UNSOL_RESPONSE_NETWORK_STATE_CHANGED [PHONE1]
01-26 10:34:18.355 3271 3271 D RILJ : [4331]> OPERATOR [PHONE1]
01-26 10:34:18.357 3271 3622 D RILJ : [4332]> DATA_REGISTRATION_STATE [PHONE1]
01-26 10:34:18.357 3271 3622 D RILJ : getDataRegistrationState: overrideHalVersion=null [PHONE1]
--
01-26 10:34:40.122 3271 3271 I Telephony: placeOutgoingConnection isEmergency=false
01-26 10:34:40.123 3271 3271 I GsmCdmaPhone: [1] dial; isEmergency=false (based on all phones)
01-26 10:34:40.126 3271 3271 I GsmCdmaPhone: [1] useImsForCall=true, useOnlyDialedSimEccList=false, isEmergency=false, useImsForEmergency=false, useImsForUt=false, isUt=true, isSuppServiceCode=true, isPotentialUssdCode=false, isWpsCall=false, allowWpsOverIms=true, imsPhone=Handler (com.android.internal.telephony.imsphone.ImsPhone) {59f97e1}, imsPhone.isVoiceOverCellularImsEnabled()=true, imsPhone.isVowifiEnabled()=false, imsPhone.isVideoEnabled()=false, imsPhone.getServiceState().getState()=0
01-26 10:34:40.129 3271 3271 D GsmCdmaPhone: [1] Trying (non-IMS) CS call
01-26 10:34:40.129 3271 3271 I Telephony: GsmConnection: registerForCallEvents; phone=Handler (com.android.internal.telephony.GsmCdmaPhone) {fae3c4}
01-26 10:34:40.129 3271 3271 D GsmCdmaPhone: [1] dialInternal: dialing w/ mmi 'GsmMmiCode {State=PENDING action=** sc=61 sia=[****] poundString=[****]}'...
01-26 10:34:40.129 3271 3271 D GsmMmiCode: processCode: is CF
01-26 10:34:40.129 3271 3271 D GsmMmiCode: processCode: is CF setCallForward
01-26 10:34:40.131 3271 3271 D RILJ : [4338]> SET_CALL_FORWARD action = 3 cfReason = 2 serviceClass = 0 timeSeconds = 0 [PHONE1]
01-26 10:34:40.131 3271 3271 D Telephony: placeOutgoingConnection, phone.dial returned null
01-26 10:34:40.131 3271 3271 D Telephony: dialed MMI code
01-26 10:34:40.131 3271 3271 D Telephony: subId: 5
01-26 10:34:40.139 3271 3271 V Telephony: onStateChanged, state: DISCONNECTED
01-26 10:34:40.139 3271 3271 V Telephony: close
01-26 10:34:40.148 2222 4418 I Telecom : PhoneAccountRegistrar: getSimCallManager: SimCallManager for subId 5 queried, returning: null: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.148 2222 4418 I Telecom : Call: handleCreateConnectionFailure; callid=TC@48, disconnectCause=DisconnectCause [ Code: (OTHER) Label: () Description: () Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.148 2222 4418 I Telecom : ConnectionServiceWrapper: Call count decrement 0, com.android.phone/com.android.services.telephony.TelephonyConnectionService: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.148 2222 4418 I Telecom : ConnectionServiceWrapper: Service unbound ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, from unbind.: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.149 3271 3271 D GsmCdmaPhone: [1] Event BarringInfoChanged Received
01-26 10:34:40.150 2222 4418 I Telecom : CallsManager: handleConnectionServiceDeath: service [ConnectionServiceWrapper componentName=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}] died: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.151 2222 3344 I Telecom : ConnectionServiceFocusManager: updateConnectionServiceFocus connSvr = null: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->CSFM.oCSD(cap/cast)@E-E-M7w
01-26 10:34:40.151 2222 3344 I Telecom : ConnectionServiceFocusManager: updateConnectionServiceFocus connSvr = null: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->CSFM.oCSD(cap/cast)@E-E-M7w
01-26 10:34:40.151 2222 3344 I Telecom : ConnectionServiceFocusManager: updateCurrentFocusCall: mCurrentFocus is null: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->CSFM.oCSD(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : CallsManager: markCallAsDisconnected: call=[Call id=TC@48, state=CONNECTING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false; disconnectCause=DisconnectCause [ Code: (OTHER) Label: () Description: () Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : CallAnomalyWatchdog: onCreateConnectionFailed: call=[Call id=TC@48, state=CONNECTING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : CallsManager: setCallState CONNECTING -> DISCONNECTED, call: [Call id=TC@48, state=CONNECTING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : Event: RecordEntry TC@48: SET_DISCONNECTED, disconnected set explicitly> DisconnectCause [ Code: (OTHER) Label: () Description: () Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : CallsManager: onFailedOutgoingCall for call [Call id=TC@48, state=DISCONNECTED, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
01-26 10:34:40.152 2222 4418 I Telecom : CallsManager: markCallAsRemoved; callid=TC@48, immediate.: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
^C
$
LogAnalysis
(1) MMI cmd init
GsmCdmaPhone service correctly identifies the dialed string as a call forwarding MMI code and initiates processing.
01-26 10:34:40.129 D GsmCdmaPhone: [1] dialInternal: dialing w/ mmi 'GsmMmiCode {State=PENDING action=** sc=61 sia=[****] poundString=[****]}'...
01-26 10:34:40.129 D GsmMmiCode: processCode: is CF setCallForward
(2) RIL cmd send
Android telephony framework sends SET_CALL_FORWARD req to RIL for modem processing
01-26 10:34:40.131 D RILJ : [4338]> SET_CALL_FORWARD action = 3 cfReason = 2 serviceClass = 0 timeSeconds = 0 [PHONE1]
(3) Connection FAIL (Telecom Layer)
Telecom service ( call mgmt & MMI cmds) reports immediate connection failure for MMI cmd
01-26 10:34:40.148 I Telecom : Call: handleCreateConnectionFailure; callid=TC@48, disconnectCause=DisconnectCause [ Code: (OTHER) Label: () Description: () Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]
(4) Modem Err: after long delay (~ 15-60 secs), RIL receives generic error code from modem in response to SET_CALL_FORWARD req
01-26 10:34:40.152 I Telecom : CallsManager: markCallAsDisconnected: call=[Call id=TC@48, state=CONNECTING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false; disconnectCause=DisconnectCause [ Code: (OTHER) Label: () Description: () Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]
(5) MMI State --> FAILED:
GsmMmiCode obj transitions to FAILED state; MMI dialog is dismissed
01-26 10:34:40.152 I Telecom : CallsManager: setCallState CONNECTING -> DISCONNECTED, call: [Call id=TC@48, state=CONNECTING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 5, UserHandle{0}, handle=tel:*****************, vidst=A, childs(0), has_parent(false), cap=[], prop=[]], voip=false: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC(cap/cast)@E-E-M7w
Root Cause Analysis The problem appears to be device-side -- that there's a functional flaw in modem fw and the e/OS(Lineage)-specific RIL
(1) Immediate Telecom Layer Disconnect: Telecom` service immediately reports connection FAIL for the MMI cmd
disconnectCause=DisconnectCause [ Code: (OTHER) ... Reason: (Connection is null, DIALED_MMI) Tone: (27) TelephonyCause: 39/-1 ImsReasonInfo: null]
the MMI cmd fails high in the Android telephony stack. possibly(?) due to inability to establish the underlying connection with the network for suplementary svcs, preventing RIL req from being fully processed or responded to by the modem
(2) *Unsupported Unsolicited RIL Responses (code 1028):
error
E RILC: Unsupported unsolicited response code 1028
reappears/recurs.
looks like modem sends proprietary(?) msgs that the FP6's RIL is not programmed to handle
if so, that's a comm mismatch between modem f/w and the RIL.
maybe a factor in the Telecom layer's failure to establish stable connect for the MMI cmds
(3) NOTE: Prior Invalid PhysicalChannelConfig
This specific error is not present in the log above, since this run is an LTE-only test config.
BUT,
in a prior run, with 5G preferred config the FP6 modem fell back to GSM (2G) due to network instability.
modem f/w incorrectly reported the GSM Cell ID (e.g., cid: 2571) in a field intended for LTE/5G Physical Cell IDs (PCI, valid range 0-1007), leading to an IllegalArgumentException reported by the framework and a corrupt phone internal network state.
switching to current LTE-only config avoids/mitigates the issue ... but suggests deeper data mapping bug between modem & RIL firmware.
Affected Components/Libraries:
(1) Modem Firmware
running on the FP6's baseband processor
it's directly responsible for the MODEM_ERR 40 and the incorrect reporting of cell IDs.
(2)
e/OS Radio Interface Layer (RIL) / Hardware Abstraction Layer (HAL)
likely Qualcomm RIL -- given QtiOemHookAidl and QcrilMsgTunnelIfaceManager logs.
it translates between the Android & modem.
responsible for incorrectly passing GSM Cell IDs as LTE/5G PCIs and for not handling proprietary unsolicited responses from the modem
(3)
com.android.phone application/service
correctly inits the MMI cmd, the receives/processes error responses from lower RIL/modem layers which leading to the observed FAIL
Yes, /com.android.services.telephony is a framework component that is directly involved in surfacing this bug. It is part of the broader com.android.phone