WebAPI/WebTelephony/Multi-SIM
Contents
Multi-SIM Scenario
In the multisim scenario, the phone, the whole device, is using all sim cards that are all on standby. All cards are working separately and they can be connected to different networks simultaneously, like gsm, cdma, etc. Each app should be able to allow user to choose a sim card as the user currently wants. Taking telephony as example, user should be able to choose via which sim card he wants to make a call. User can choose to use a specific sim or simply use the default one. He can call friend A by sim no. 1 and to call friend B by sim no. 2. He is definitely able to receive calls from any sim. Also, among different APIs such as mobile connections and telephony, technically user can set a default sim for 3G data connection and another default sim for telephony voice calls.
In reality, hardware implementation for multi-SIM scenario varies. Some devices may have one antenna while others have multiple. Some devices may have one modem but others have multiple. If the device has one antenna only, then even in multisim scenario, user is uncapable of placing calls with both sim cards at the same time. If the hardware supports multi-antenna as well, then placing calls with both sim cards at the same time works. Neverthless, in fact, though most existing multisim-devices claim they support multi-sim-standby, they automatically disable other sim card while one is in call. If user talks on one sim card and get an incoming call on other, the second call will be redirected to voice mail or user will be unavailable. Very few, but there is, supports the full multi-sim-standby feature.
Proposal: WebTelephony API for Multi-SIM
Currently B2G supports a single SIM architecture. This proposal wants to extend it for supporting multi-SIMs and also takes single SIM scenario into account.
The improvement is quite simple that adding an optional paramter in dial() and other request functions. Also, a new attribute 'serviceId' is added into nsIDOMTelephonyCall so that API users easily know which service a call comes from.
Web API
interface nsIDOMTelephony: nsIDOMEventTarget { attribute boolean muted; attribute boolean speakerEnabled; // Calls existing in all the services. readonly attribute jsval calls; // The call that is "active", i.e. receives microphone input and tones // generated via startTone. readonly attribute jsval active; /* * Make an outgoing call * * @param number * Phone number of the remote party * @param serviceId * Id of the telephony service to be used when dialing. If not specified, * the implementation MUST use the default id. * * Possible values are 0 ~ (number of services - 1), which is simply the index of a service. * Get number of services by acquiring navigator.mozMobileConnections.length */ nsIDOMTelephonyCall dial(in DOMString number, [optional] in unsigned long serviceId); naIDOMTelephonyCall dialEmergency(in DOMString number, [optional] in unsigned long serviceId); readonly attribute nsIDOMTelephonyCallGroup conferenceGroup; void startTone(in DOMString tone, [optional] in unsigned long serviceId); void stopTone([optional] in unsigned long serviceId); attribute nsIDOMEventListener onincoming; attribute nsIDOMEventListener oncallschanged; };
interface nsIDOMTelephonyCall: nsIDOMEventTarget { // Indicate which service the call comes from. readonly attribute unsigned long serviceId; /* new attribute */ readonly attribute DOMString number; // "dialing", "alerting", "busy", "connecting", "connected", "disconnecting", // "disconnected", "incoming", "holding", "held", "resuming" readonly attribute DOMString state; readonly attribute nsIDOMDOMError error; // Functions to mediate a call. void answer(); void hangUp(); void hold(); void resume(); attribute nsIDOMEventListener onstatechange; attribute nsIDOMEventListener ondialing; attribute nsIDOMEventListener onalerting; attribute nsIDOMEventListener onbusy; attribute nsIDOMEventListener onconnecting; attribute nsIDOMEventListener onconnected; attribute nsIDOMEventListener ondisconnecting; attribute nsIDOMEventListener ondisconnected; attribute nsIDOMEventListener onincoming; attribute nsIDOMEventListener onholding; attribute nsIDOMEventListener onheld; attribute nsIDOMEventListener onresuming; };
Use Case
Outgoing Call
- Current B2G (Single SIM)
navigator.mozTelephony.dial(number)
- Multi-SIMs
navigator.mozTelephony.dial(number) // Use default service to make a call navigator.mozTelephony.dial(number, serviceId)
Incoming Call
- Current B2G (Single SIM)
tel = navigator.mozTelephony;
- Multi-SIMs
tel = navigator.mozTelephony;
Once the telephony object is obtained, the following work remains the same. We get notified when an incoming call occurs in any of services.
tel.addEventListener('incoming'); tel.onincoming = function onincoming (evt) { incoming = evt.call; }; incoming.answer();
Implementation Details of Web API
Internal API
interface nsITelephonyProvider { void registerTelephonyMsg(in nsITelephonyListener listener); void unregisterTelephonyMsg(in nsITelephonyListener listener); void enumerateCalls(in nsITelephonyListener listener); void dial(in DOMString number, in unsigned long serviceId); void dialEmergency(in DOMString number, in unsigned long serviceId); void startTone(in DOMString dtmfChar, in unsigned long serviceId); void stopTone(in unsigned long serviceId); void hangUp(in unsigned long callIndex, in unsigned long serviceId); void answerCall(in unsigned long callIndex, in unsigned long serviceId); void rejectCall(in unsigned long callIndex, in unsigned long serviceId); void holdCall(in unsigned long callIndex, in unsigned long serviceId); void resumeCall(in unsigned long callIndex, in unsigned long serviceId); attribute bool microphoneMuted; attribute bool speakerEnabled; }
interface nsITelephonyListener { void callStateChanged(in unsigned long serviceId, in unsigned long callIndex, in unsigned short callState, in AString number, in boolean isActive); boolean enumerateCallState(in unsigned long serviceId, in unsigned long callIndex, in unsigned short callState, in AString number, in boolean isActive); void notifyError(in unsigned long serviceId, in unsigned long callIndex, in Astring error); }
Proposal: Architecture
Current Architecture
This is the current architecture supporting a single SIM card.
Proposal for Multi-SIMs
With various hardware design, there might be multiple ril-daemon (rild), one rild taking care of one SIM, while it is also possible that a single rild manipulates all the SIMs. To make our architecture flexible enough, we are planning to have 'rilproxy' in charge of sending RIL parcels to the correct rild, no matter how many there are.
Here is a proposal for multi-SIMs.
RIL Implementation
We are proposing to add a new object called 'MSimRadioInterfaceLayer', which takes responsibility of creating RadioInterfaceLayer instances for every SIM, getting worker of each instance and receiving IPC messages. Once it receives the IPC messages, it dispatch the messages to the right RadioInterfaceLayer instance according to the 'subscriptionId' property. Then it is that instance to handle those messages. It is also each instacne's job to send messages to content.
In order to adding MSimRadioInterfaceLayer, we need to modify 'SystemWorkerManager.cpp' to create an instance of MSimRadioInterfaceLayer, instead of what it is doing right now, i.e. creating an instance of RadioInterfaceLayer.
Bugzilla
- Multi-SIM meta bug: bug 799023
- Multi-SIM WebTelephony API: bug 814625
- Multi-SIM RIL implementation: bug 814581 bug 814584 bug 814579 bug 826977
- Get the number of SIM slots
- Set default sim for each application
Discussion
- Q: How do we know how many phone objects should be created in 'navigator.mozTelephonyManager' ?
- A: Number of the sim slots
- Q: How to know default phone?
- A: Binded to a specified sim slot (per hardware design). We should reserve the flexibility that user has a chance to change the default phone at run-time, but note the 『default phone』 determination is another issue.
- Q: How much memory increase if we use two instances to handle 2 SIMs?
- A: According to the information from Bug 802446, the compartment of RadioInterface layer is about 3xx KBytes. But, after removing some fixed size overhead, it is expected 2xxK-increase to add an instance for each SIM. We expect it will add less than 200K for each instance after removing SMS and other stuffs out.