/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.radio@1.0;

import IRadioResponse;
import IRadioIndication;

/**
 * This interface is used by telephony & telecom to talk to cellular radio.
 * All the functions have minimum one parameter:
 * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
 * duration of a method call. If clients provide colliding serials (including passing the same
 * serial to different methods), multiple responses (one for each method call) must still be served.
 */
interface IRadio {
    /**
     * Set response functions for radio requests & radio indications.
     *
     * @param radioResponse Object containing response functions
     * @param radioIndication Object containing radio indications
     */
    setResponseFunctions(IRadioResponse radioResponse,
            IRadioIndication radioIndication);

    /**
     * Requests status of the ICC card
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getIccCardStatusResponse()
     *
     */
    oneway getIccCardStatus(int32_t serial);

    /**
     * Supplies ICC PIN. Only called if CardStatus has AppState.PIN state
     *
     * @param serial Serial number of request.
     * @param pin PIN value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.supplyIccPinForAppResponse()
     *
     */
    oneway supplyIccPinForApp(int32_t serial, string pin, string aid);

    /**
     * Supplies ICC PUK and new PIN.
     *
     * @param serial Serial number of request.
     * @param puk PUK value
     * @param pin New PIN value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.supplyIccPukForAppResponse()
     *
     */
    oneway supplyIccPukForApp(int32_t serial, string puk, string pin, string aid);

    /**
     * Supplies ICC PIN2. Only called following operation where SIM_PIN2 was
     * returned as a a failure from a previous operation.
     *
     * @param serial Serial number of request.
     * @param pin2 PIN2 value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.supplyIccPin2ForAppResponse()
     *
     */
    oneway supplyIccPin2ForApp(int32_t serial, string pin2, string aid);

    /**
     * Supplies ICC PUK2 and new PIN2.
     *
     * @param serial Serial number of request.
     * @param puk2 PUK2 value
     * @param pin2 New PIN2 value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.supplyIccPuk2ForAppResponse()
     *
     */
    oneway supplyIccPuk2ForApp(int32_t serial, string puk2, string pin2,
            string aid);

    /**
     * Supplies old ICC PIN and new PIN.
     *
     * @param serial Serial number of request.
     * @param oldPin Old pin value
     * @param newPin New pin value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.changeIccPinForAppResponse()
     *
     */
    oneway changeIccPinForApp(int32_t serial, string oldPin, string newPin,
            string aid);

    /**
     * Supplies old ICC PIN2 and new PIN2.
     *
     * @param serial Serial number of request.
     * @param oldPin2 Old pin2 value
     * @param newPin2 New pin2 value
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.changeIccPin2ForAppResponse()
     *
     */
    oneway changeIccPin2ForApp(int32_t serial, string oldPin2, string newPin2,
            string aid);

    /**
     * Requests that network personalization be deactivated
     *
     * @param serial Serial number of request.
     * @param netPin Network depersonlization code
     *
     * Response function is IRadioResponse.supplyNetworkDepersonalizationResponse()
     *
     */
    oneway supplyNetworkDepersonalization(int32_t serial, string netPin);

    /**
     * Requests current call list
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getCurrentCallsResponse()
     *
     */
    oneway getCurrentCalls(int32_t serial);

    /**
     * Initiate voice call.
     * This method is never used for supplementary service codes
     *
     * @param serial Serial number of request.
     * @param dialInfo Dial struct
     *
     * Response function is IRadioResponse.dialResponse()
     *
     */
    oneway dial(int32_t serial, Dial dialInfo);

    /**
     * Get the SIM IMSI
     * Only valid when radio state is "RADIO_STATE_ON"
     *
     * @param serial Serial number of request.
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *
     * Response function is IRadioResponse.getImsiForAppResponse()
     *
     */
    oneway getImsiForApp(int32_t serial, string aid);

    /**
     * Hang up a specific line (like AT+CHLD=1x)
     * After this HANGUP request returns, Radio must show the connection is NOT
     * active anymore in next requestGetCurrentCalls query.
     *
     * @param serial Serial number of request.
     * @param gsmIndex Connection index (value of 'x' in CHLD above)
     *
     * Response function is IRadioResponse.hangupResponse()
     *
     */
    oneway hangup(int32_t serial, int32_t gsmIndex);

    /**
     * Hang up waiting or held (like AT+CHLD=0)
     * After this HANGUP request returns, Radio must show the connection is NOT
     * active anymore in next getCurrentCalls() query.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.hangupWaitingOrBackgroundResponse()
     *
     */
    oneway hangupWaitingOrBackground(int32_t serial);

    /**
     * Hang up waiting or held (like AT+CHLD=1)
     * After this HANGUP request returns, Radio must show the connection is NOT
     * active anymore in next getCurrentCalls query.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.hangupForegroundResumeBackgroundResponse()
     *
     */
    oneway hangupForegroundResumeBackground(int32_t serial);

    /**
     * Switch waiting or holding call and active call (like AT+CHLD=2)
     * State transitions must be as follows:
     *
     * Call transitions must happen as shown below.
     *
     *   BEFORE                               AFTER
     * Call 1   Call 2                 Call 1       Call 2
     * ACTIVE   HOLDING                HOLDING     ACTIVE
     * ACTIVE   WAITING                HOLDING     ACTIVE
     * HOLDING  WAITING                HOLDING     ACTIVE
     * ACTIVE   IDLE                   HOLDING     IDLE
     * IDLE     IDLE                   IDLE        IDLE
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.switchWaitingOrHoldingAndActiveResponse()
     *
     */
    oneway switchWaitingOrHoldingAndActive(int32_t serial);

    /**
     * Conference holding and active (like AT+CHLD=3)
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.conferenceResponse()
     *
     */
    oneway conference(int32_t serial);

    /**
     * Send UDUB (user determined user busy) to ringing or
     * waiting call answer)
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.rejectCallResponse()
     *
     */
    oneway rejectCall(int32_t serial);

    /**
     * Requests the failure cause code for the most recently terminated call.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getLastCallFailCauseResponse()
     *
     */
    oneway getLastCallFailCause(int32_t serial);

    /**
     * Requests current signal strength and associated information.
     * Must succeed if radio is on.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getSignalStrengthResponse()
     */
    oneway getSignalStrength(int32_t serial);

    /**
     * Request current voice registration state
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getVoiceRegistrationStateResponse()
     */
    oneway getVoiceRegistrationState(int32_t serial);

    /**
     * Request current data registration state
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getDataRegistrationStateResponse()
     */
    oneway getDataRegistrationState(int32_t serial);

    /**
     * Request current operator ONS or EONS
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getOperatorResponse()
     */
    oneway getOperator(int32_t serial);

    /**
     * Toggle radio on and off (for "airplane" mode)
     * If the radio is turned off/on the radio modem subsystem
     * is expected return to an initialized state. For instance,
     * any voice and data calls must be terminated and all associated
     * lists emptied.
     *
     * @param serial Serial number of request.
     * @param on To turn on radio -> on = true, to turn off radio -> on = false.
     *
     * Response function is IRadioResponse.setRadioPowerResponse()
     */
    oneway setRadioPower(int32_t serial, bool on);

    /**
     * Send a DTMF tone
     *
     * If the implementation is currently playing a tone requested via
     * startDtmf(), that tone must be cancelled and the new tone
     * must be played instead
     *
     * @param serial Serial number of request.
     * @param s string with single char having one of 12 values: 0-9, *, #
     *
     * Response function is IRadioResponse.sendDtmfResponse()
     */
    oneway sendDtmf(int32_t serial, string s);

    /**
     * Send an SMS message
     *
     * @param serial Serial number of request.
     * @param message GsmSmsMessage as defined in types.hal
     *
     * Response function is IRadioResponse.sendSmsResponse()
     *
     * Based on the return error, caller decides to resend if sending sms
     * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
     * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500)
     */
    oneway sendSms(int32_t serial, GsmSmsMessage message);

    /**
     * Send an SMS message. Identical to sendSms,
     * except that more messages are expected to be sent soon. If possible,
     * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
     *
     * @param serial Serial number of request.
     * @param message GsmSmsMessage as defined in types.hal
     *
     * Response function is IRadioResponse.sendSMSExpectMoreResponse()
     *
     * Based on the return error, caller decides to resend if sending sms
     * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
     * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500)
     */
    oneway sendSMSExpectMore(int32_t serial, GsmSmsMessage message);

    /**
     * Setup a packet data connection. If DataCallResponse.status
     * return DataCallFailCause:NONE it is added to the list of data calls and a
     * unsolDataCallListChanged() is sent. The call remains in the
     * list until deactivateDataCall() is issued or the
     * radio is powered off/on. This list is returned by getDataCallList()
     * and dataCallListChanged().
     *
     * The Radio is expected to:
     *  - Create one data call context.
     *  - Create and configure a dedicated interface for the context
     *  - The interface must be point to point.
     *  - The interface is configured with one or more addresses and
     *    is capable of sending and receiving packets. The prefix length
     *    of the addresses must be /32 for IPv4 and /128 for IPv6.
     *  - Must NOT change the linux routing table.
     *  - Support up to getDataRegistrationState response[5]
     *    number of simultaneous data call contexts.
     *
     * @param serial Serial number of request.
     * @param radioTechnology Radio technology to use.
     * @param dataProfileInfo data profile info.
     * @param modemCognitive Indicating this profile was sent to the modem through setDataProfile
     *                       earlier.
     * @param roamingAllowed Indicating data roaming is allowed or not by the user.
     * @param isRoaming Indicating the device is roaming or not. The 'protocol' parameter in the old
     *                  RIL API must be filled accordingly based on the roaming condition.
     *                  Note this is for backward compatibility with the old radio modem. The modem
     *                  must not use this param for any other reason.
     *
     * Response function is IRadioResponse.setupDataCallResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setupDataCall_1_2() instead.
     */
    oneway setupDataCall(int32_t serial, RadioTechnology radioTechnology,
            DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
            bool isRoaming);

    /**
     * Request ICC I/O operation.
     * This is similar to the TS 27.007 "restricted SIM" operation
     * where it assumes all of the EF selection must be done by the
     * callee
     *
     * Arguments and responses that are unused for certain
     * values of "command" must be ignored or set to empty string
     *
     * @param serial Serial number of request.
     * @param iccIo IccIo
     *
     * Please note that IccIo has a "PIN2" field which may be empty string,
     * or may specify a PIN2 for operations that require a PIN2 (eg
     * updating FDN records)
     *
     * Response function is IRadioResponse.iccIOForAppResponse()
     */
    oneway iccIOForApp(int32_t serial, IccIo iccIo);

    /**
     * Send a USSD message.
     *
     * If a USSD session already exists, the message must be sent in the
     * context of that session. Otherwise, a new session must be created.
     *
     * The network reply must be reported via unsolOnUssd
     *
     * Only one USSD session must exist at a time, and the session is assumed
     * to exist until:
     * a) The android system invokes cancelUssd()
     * b) The implementation sends a unsolOnUssd() with a type code
     * of "0" (USSD-Notify/no further action) or "2" (session terminated)
     *
     * @param serial Serial number of request.
     * @param ussd string containing the USSD request in UTF-8 format
     *
     * Response function is IRadioResponse.sendUssdResponse()
     *
     * See also requestCancelUssd, unsolOnUssd
     */
    oneway sendUssd(int32_t serial, string ussd);

    /**
     * Cancel the current USSD session if one exists.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.cancelPendingUssdResponse()
     */
    oneway cancelPendingUssd(int32_t serial);

    /**
     * Gets current CLIR status
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getClirResponse()
     */
    oneway getClir(int32_t serial);

    /**
     * Set current CLIR status
     *
     * @param serial Serial number of request.
     * @param status "n" parameter from TS 27.007 7.7
     *
     * Response function is IRadioResponse.setClirResponse()
     */
    oneway setClir(int32_t serial, int32_t status);

    /**
     * Request call forward status.
     *
     * @param serial Serial number of request.
     * @param callInfo CallForwardInfo
     *
     * Response function is IRadioResponse.getCallForwardStatusResponse()
     */
    oneway getCallForwardStatus(int32_t serial,
            CallForwardInfo callInfo);

    /**
     * Configure call forward rule
     *
     * @param serial Serial number of request.
     * @param callInfo CallForwardInfo
     *
     * Response function is IRadioResponse.setCallForwardResponse()
     */
    oneway setCallForward(int32_t serial, CallForwardInfo callInfo);

    /**
     * Query current call waiting state
     *
     * @param serial Serial number of request.
     * @param serviceClass Service class is the TS 27.007 service class to query
     *
     * Response function is IRadioResponse.getCallWaitingResponse()
     */
    oneway getCallWaiting(int32_t serial, int32_t serviceClass);

    /**
     * Configure current call waiting state
     *
     * @param serial Serial number of request.
     * @param enable is false for "disabled" and true for "enabled"
     * @param serviceClass is the TS 27.007 service class bit vector of services to modify
     *
     * Response function is IRadioResponse.setCallWaitingResponse()
     */
    oneway setCallWaiting(int32_t serial, bool enable,
            int32_t serviceClass);

    /**
     * Acknowledge successful or failed receipt of SMS previously indicated
     * via unsolResponseNewSms
     *
     * @param serial Serial number of request.
     * @param success is true on successful receipt
     *        (basically, AT+CNMA=1 from TS 27.005 is 0 on failed receipt
     *        (basically, AT+CNMA=2 from TS 27.005)
     * @param cause: if success is false, this contains the failure cause as defined
     *        in TS 23.040, 9.2.3.22.
     *
     * Response function is IRadioResponse.acknowledgeLastIncomingGsmSmsResponse()
     */
    oneway acknowledgeLastIncomingGsmSms(int32_t serial, bool success,
            SmsAcknowledgeFailCause cause);

    /**
     * Answer incoming call
     * Must not be called for WAITING calls.
     * switchWaitingOrHoldingAndActive() must be used in this case
     * instead
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.acceptCallResponse()
     */
    oneway acceptCall(int32_t serial);

    /**
     * Deactivate packet data connection and remove from the
     * data call list if RadioError:NONE is returned. Any other return
     * values must also try to remove the call from the list. An
     * unsolDataCallListChanged must be
     * issued because of an deactivateDataCall.
     *
     * @param serial Serial number of request.
     * @param cid Indicates CID
     * @param reasonRadioShutDown Indicates Disconnect Reason
     *        false => No specific reason specified
     *        true => Radio shutdown requested
     *
     * Response function is IRadioResponse.deactivateDataCallResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.deactivateDataCall_1_2() instead.
     */
    oneway deactivateDataCall(int32_t serial, int32_t cid,
            bool reasonRadioShutDown);

    /**
     * Query the status of a facility lock state
     *
     * @param serial Serial number of request.
     * @param facility is the facility string code from TS 27.007 7.4
     *        (eg "AO" for BAOC, "SC" for SIM lock)
     * @param password is the password, or "" if not required
     * @param serviceClass is the TS 27.007 service class bit vector of services to query
     * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *        This is only applicable in the case of Fixed Dialing Numbers (FDN) requests.
     *
     * Response function is IRadioResponse.getFacilityLockForAppResponse()
     */
    oneway getFacilityLockForApp(int32_t serial, string facility,
            string password, int32_t serviceClass, string appId);

    /**
     * Enable/disable one facility lock
     *
     * @param serial Serial number of request.
     * @param facility is the facility string code from TS 27.007 7.4 (eg "AO" for BAOC)
     * @param lockState false for "unlock" and true for "lock"
     * @param password is the password
     * @param serviceClass is string representation of decimal TS 27.007
     *        service class bit vector. Eg, the string
     *        "1" means "set this facility for voice services"
     * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value.
     *        This is only applicable in the case of Fixed Dialing Numbers (FDN) requests.
     *
     * Response function is IRadioResponse.setFacilityLockForAppResponse()
     */
    oneway setFacilityLockForApp(int32_t serial, string facility, bool lockState,
            string password, int32_t serviceClass, string appId);

    /**
     * Change call barring facility password
     *
     * @param serial Serial number of request.
     * @param facility facility string code from TS 27.007 7.4 (eg "AO" for BAOC)
     * @param oldPassword old password
     * @param newPassword new password
     *
     * Response function is IRadioResponse.setBarringPasswordResponse()
     */
    oneway setBarringPassword(int32_t serial, string facility,
            string oldPassword, string newPassword);

    /**
     * Query current network selection mode
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getNetworkSelectionModeResponse()
     */
    oneway getNetworkSelectionMode(int32_t serial);

    /**
     * Specify that the network must be selected automatically.
     * This request must not respond until the new operator is selected and registered.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.setNetworkSelectionModeAutomaticResponse()
     */
    oneway setNetworkSelectionModeAutomatic(int32_t serial);

    /**
     * Manually select a specified network.
     * This request must not respond until the new operator is selected and registered.
     *
     * @param serial Serial number of request.
     * @param operatorNumeric string specifying MCCMNC of network to select (eg "310170")
     *
     * Response function is IRadioResponse.setNetworkSelectionModeManualResponse()
     */
    oneway setNetworkSelectionModeManual(int32_t serial, string operatorNumeric);

    /**
     * Scans for available networks
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getAvailableNetworksResponse()
     */
    oneway getAvailableNetworks(int32_t serial);

    /**
     * Start playing a DTMF tone. Continue playing DTMF tone until
     * stopDtmf is received.
     * If a startDtmf() is received while a tone is currently playing,
     * it must cancel the previous tone and play the new one.
     *
     * @param serial Serial number of request.
     * @param s string having a single character with one of 12 values: 0-9,*,#
     *
     * Response function is IRadioResponse.startDtmfResponse()
     */
    oneway startDtmf(int32_t serial, string s);

    /**
     * Stop playing a currently playing DTMF tone.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.stopDtmfResponse()
     */
    oneway stopDtmf(int32_t serial);

    /**
     * Return string value indicating baseband version, eg response from AT+CGMR
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getBasebandVersionResponse()
     */
    oneway getBasebandVersion(int32_t serial);

    /**
     * Separate a party from a multiparty call placing the multiparty call
     * (less the specified party) on hold and leaving the specified party
     * as the only other member of the current (active) call
     *
     * Like AT+CHLD=2x
     *
     * See TS 22.084 1.3.8.2 (iii)
     * TS 22.030 6.5.5 "Entering "2X followed by send"
     * TS 27.007 "AT+CHLD=2x"
     *
     * @param serial Serial number of request.
     * @param gsmIndex contains Connection index (value of 'x' in CHLD above)
     *
     * Response function is IRadioResponse.separateConnectionResponse()
     */
    oneway separateConnection(int32_t serial, int32_t gsmIndex);

    /**
     * Turn on or off uplink (microphone) mute.
     * Must only be sent while voice call is active.
     * Must always be reset to "disable mute" when a new voice call is initiated
     *
     * @param serial Serial number of request.
     * @param enable true for "enable mute" and false for "disable mute"
     *
     * Response function is IRadioResponse.setMuteResponse()
     */
    oneway setMute(int32_t serial, bool enable);

    /**
     * Queries the current state of the uplink mute setting
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getMuteResponse()
     */
    oneway getMute(int32_t serial);

    /**
     * Queries the status of the CLIP supplementary service
     * (for MMI code "*#30#")
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getClipResponse()
     */
    oneway getClip(int32_t serial);

    /**
     * Returns the data call list. An entry is added when a
     * setupDataCall() is issued and removed on a
     * deactivateDataCall(). The list is emptied when
     * setRadioPower() off/on is issued.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getDataCallListResponse()
     */
    oneway getDataCallList(int32_t serial);

    /**
     * Enables/disables supplementary service related notifications from the network.
     * Notifications are reported via unsolSuppSvcNotification().
     *
     * @param serial Serial number of request.
     * @param enable true = notifications enabled, false = notifications disabled.
     *
     * Response function is IRadioResponse.setSuppServiceNotificationsResponse()
     */
    oneway setSuppServiceNotifications(int32_t serial, bool enable);

    /**
     * Stores a SMS message to SIM memory.
     *
     * @param serial Serial number of request.
     * @param smsWriteArgs SmsWriteArgs defined in types.hal
     *
     * Response function is IRadioResponse.writeSmsToSimResponse()
     */
    oneway writeSmsToSim(int32_t serial, SmsWriteArgs smsWriteArgs);

    /**
     * Deletes a SMS message from SIM memory.
     *
     * @param serial Serial number of request.
     * @param index Record index of the message to delete.
     *
     * Response function is IRadioResponse.deleteSmsOnSimResponse()
     */
    oneway deleteSmsOnSim(int32_t serial, int32_t index);

    /**
     * Assign a specified band for RF configuration.
     *
     * @param serial Serial number of request.
     * @param mode RadioBandMode defined in types.hal
     *
     * Response function is IRadioResponse.setBandModeResponse()
     */
    oneway setBandMode(int32_t serial, RadioBandMode mode);

    /**
     * Get the list of band modes supported by RF.
     *
     * @param serial Serial number of request.
     *
     * Response function is IRadioResponse.getAvailableBandModesResponse()
     */
    oneway getAvailableBandModes(int32_t serial);

    /**
     * Requests to send a SAT/USAT envelope command to SIM.
     * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111
     *
     * @param serial Serial number of request.
     * @param command SAT/USAT command in hexadecimal format string starting with command tag
     *
     * Response function is IRadioResponse.sendEnvelopeResponse()
     */
    oneway sendEnvelope(int32_t serial, string command);

    /**
     * Requests to send a terminal response to SIM for a received proactive command
     *
     * @param serial Serial number of request.
     * @param commandResponse SAT/USAT response in hexadecimal format string starting with
     *        first byte of response data
     *
     * Response function is IRadioResponse.sendTerminalResponseResponseToSim()
     */
    oneway sendTerminalResponseToSim(int32_t serial, string commandResponse);

    /**
     * When STK application gets stkCallSetup(), the call actually has
     * been initialized by mobile device already. (We could see the call has been in the 'call
     * list') So, STK application needs to accept/reject the call according to user
     * operations.
     *
     * @param serial Serial number of request.
     * @param accept true = accept the call setup, false = reject the call setup
     *
     * Response callback is IRadioResponse.handleStkCallSetupRequestFromSimResponse()
     */
    oneway handleStkCallSetupRequestFromSim(int32_t serial,
            bool accept);

    /**
     * Connects the two calls and disconnects the subscriber from both calls.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.explicitCallTransferResponse()
     */
    oneway explicitCallTransfer(int32_t serial);

    /**
     * Requests to set the preferred network type for searching and registering
     * (CS/PS domain, RAT, and operation mode)
     *
     * @param serial Serial number of request.
     * @param nwType PreferredNetworkType defined in types.hal
     *
     * Response callback is IRadioResponse.setPreferredNetworkTypeResponse()
     */
    oneway setPreferredNetworkType(int32_t serial,
            PreferredNetworkType nwType);

    /**
     * Query the preferred network type (CS/PS domain, RAT, and operation mode)
     * for searching and registering
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getPreferredNetworkTypeResponse()
     */
    oneway getPreferredNetworkType(int32_t serial);

    /**
     * Request neighboring cell id in GSM network
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getNeighboringCidsResponse()
     */
    oneway getNeighboringCids(int32_t serial);

    /**
     * Enables/disables network state change notifications due to changes in
     * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA).
     * Basically +CREG=2 vs. +CREG=1 (TS 27.007).
     * Note:  The Radio implementation must default to "updates enabled"
     * when the screen is on and "updates disabled" when the screen is off.
     *
     * @param serial Serial number of request.
     * @param enable true = updates enabled (+CREG=2), false = updates disabled (+CREG=1)
     *
     * Response callback is IRadioResponse.setLocationUpdatesResponse()
     */
    oneway setLocationUpdates(int32_t serial, bool enable);

    /**
     * Request to set the location where the CDMA subscription shall
     * be retrieved
     *
     * @param serial Serial number of request.
     * @param cdmaSub CdmaSubscriptionSource
     *
     * Response callback is IRadioResponse.setCdmaSubscriptionSourceResponse()
     */
    oneway setCdmaSubscriptionSource(int32_t serial,
            CdmaSubscriptionSource cdmaSub);

    /**
     * Request to set the roaming preferences in CDMA
     *
     * @param serial Serial number of request.
     * @param type CdmaRoamingType defined in types.hal
     *
     * Response callback is IRadioResponse.setCdmaRoamingPreferenceResponse()
     */
    oneway setCdmaRoamingPreference(int32_t serial,
            CdmaRoamingType type);

    /**
     * Request the actual setting of the roaming preferences in CDMA in the modem
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getCdmaRoamingPreferenceResponse()
     */
    oneway getCdmaRoamingPreference(int32_t serial);

    /**
     * Request to set the TTY mode
     *
     * @param serial Serial number of request.
     * @param mode TtyMode
     *
     * Response callback is IRadioResponse.setTTYModeResponse()
     */
    oneway setTTYMode(int32_t serial, TtyMode mode);

    /**
     * Request the setting of TTY mode
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getTTYModeResponse()
     */
    oneway getTTYMode(int32_t serial);

    /**
     * Request to set the preferred voice privacy mode used in voice scrambling.
     *
     * @param serial Serial number of request.
     * @param enable false for Standard Privacy Mode (Public Long Code Mask)
     *        true for Enhanced Privacy Mode (Private Long Code Mask)
     *
     * Response callback is IRadioResponse.setPreferredVoicePrivacyResponse()
     */
    oneway setPreferredVoicePrivacy(int32_t serial, bool enable);

    /**
     * Request the setting of preferred voice privacy mode.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getPreferredVoicePrivacyResponse()
     */
    oneway getPreferredVoicePrivacy(int32_t serial);

    /**
     * Send FLASH command
     *
     * @param serial Serial number of request.
     * @param featureCode String associated with Flash command
     *
     * Response callback is IRadioResponse.sendCDMAFeatureCodeResponse()
     */
    oneway sendCDMAFeatureCode(int32_t serial, string featureCode);

    /**
     * Send DTMF string
     *
     * @param serial Serial number of request.
     * @param dtmf DTMF string
     * @param on DTMF ON length in milliseconds, or 0 to use default
     * @param off is the DTMF OFF length in milliseconds, or 0 to use default
     *
     * Response callback is IRadioResponse.sendBurstDtmfResponse()
     */
    oneway sendBurstDtmf(int32_t serial, string dtmf, int32_t on, int32_t off);

    /**
     * Send a CDMA SMS message
     *
     * @param serial Serial number of request.
     * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal
     *
     * Response callback is IRadioResponse.sendCdmaSmsResponse()
     */
    oneway sendCdmaSms(int32_t serial, CdmaSmsMessage sms);

    /**
     * Acknowledge the success or failure in the receipt of SMS
     * previously indicated via responseCdmaNewSms()
     *
     * @param serial Serial number of request.
     * @param smsAck Cdma Sms ack to be sent described by CdmaSmsAck in types.hal
     *
     * Response callback is IRadioResponse.acknowledgeLastIncomingCdmaSmsResponse()
     */
    oneway acknowledgeLastIncomingCdmaSms(int32_t serial, CdmaSmsAck smsAck);

    /**
     * Request the setting of GSM/WCDMA Cell Broadcast SMS config.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getGsmBroadcastConfigResponse()
     */
    oneway getGsmBroadcastConfig(int32_t serial);

    /**
     * Set GSM/WCDMA Cell Broadcast SMS config
     *
     * @param serial Serial number of request.
     * @param configInfo Setting of GSM/WCDMA Cell broadcast config
     *
     * Response callback is IRadioResponse.setGsmBroadcastConfigResponse()
     */
    oneway setGsmBroadcastConfig(int32_t serial, vec<GsmBroadcastSmsConfigInfo> configInfo);

    /**
     * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS
     *
     * @param serial Serial number of request.
     * @param activate indicates to activate or turn off the reception of GSM/WCDMA
     *        Cell Broadcast SMS. true = activate, false = turn off
     *
     * Response callback is IRadioResponse.setGsmBroadcastActivationResponse()
     */
    oneway setGsmBroadcastActivation(int32_t serial, bool activate);

    /**
     * Request the setting of CDMA Broadcast SMS config
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getCdmaBroadcastConfigResponse()
     */
    oneway getCdmaBroadcastConfig(int32_t serial);

    /**
     * Set CDMA Broadcast SMS config
     *
     * @param serial Serial number of request.
     * @param configInfo CDMA Broadcast SMS config to be set.
     *
     * Response callback is IRadioResponse.setCdmaBroadcastConfigResponse()
     */
    oneway setCdmaBroadcastConfig(int32_t serial, vec<CdmaBroadcastSmsConfigInfo> configInfo);

    /**
     * Enable or disable the reception of CDMA Cell Broadcast SMS
     *
     * @param serial Serial number of request.
     * @param activate indicates to activate or turn off the reception of CDMA
     *        Cell Broadcast SMS. true = activate, false = turn off
     *
     * Response callback is IRadioResponse.setCdmaBroadcastActivationResponse()
     */
    oneway setCdmaBroadcastActivation(int32_t serial, bool activate);

    /**
     * Request the device MDN / H_SID / H_NID.
     * The request is only allowed when CDMA subscription is available. When CDMA
     * subscription is changed, application layer must re-issue the request to
     * update the subscription information.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getCDMASubscriptionResponse()
     */
    oneway getCDMASubscription(int32_t serial);

    /**
     * Stores a CDMA SMS message to RUIM memory.
     *
     * @param serial Serial number of request.
     * @param cdmaSms CDMA message as defined by CdmaSmsWriteArgs in types.hal
     *
     * Response callback is IRadioResponse.writeSmsToRuimResponse()
     */
    oneway writeSmsToRuim(int32_t serial, CdmaSmsWriteArgs cdmaSms);

    /**
     * Deletes a CDMA SMS message from RUIM memory.
     *
     * @param serial Serial number of request.
     * @param index record index of the message to delete
     *
     * Response callback is IRadioResponse.deleteSmsOnRuimResponse()
     */
    oneway deleteSmsOnRuim(int32_t serial, int32_t index);

    /**
     * Request the device ESN / MEID / IMEI / IMEISV.
     * The request is always allowed and contains GSM and CDMA device identity.
     * When CDMA subscription is changed the ESN/MEID changes. The application
     * layer must re-issue the request to update the device identity in this case.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getDeviceIdentityResponse()
     */
    oneway getDeviceIdentity(int32_t serial);

    /**
     * Request the radio's system selection module to exit emergency
     * callback mode. Radio must not respond with SUCCESS until the modem has
     * completely exited from Emergency Callback Mode.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.exitEmergencyCallbackModeResponse()
     */
    oneway exitEmergencyCallbackMode(int32_t serial);

    /**
     * Get the default Short Message Service Center address on the device.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getSmscAddressResponse()
     */
    oneway getSmscAddress(int32_t serial);

    /**
     * Set the default Short Message Service Center address on the device.
     *
     * @param serial Serial number of request.
     * @param smsc Short Message Service Center address to set
     *
     * Response callback is IRadioResponse.setSmscAddressResponse()
     */
    oneway setSmscAddress(int32_t serial, string smsc);

    /**
     * Indicates whether there is storage available for new SMS messages.
     *
     * @param serial Serial number of request.
     * @param available true if memory is available for storing new messages,
     *        false if memory capacity is exceeded
     *
     * Response callback is IRadioResponse.reportSmsMemoryStatusResponse()
     */
    oneway reportSmsMemoryStatus(int32_t serial, bool available);

    /**
     * Indicates that the StkService is running and is
     * ready to receive unsolicited stkXXXXX commands.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.reportStkServiceIsRunningResponse()
     */
    oneway reportStkServiceIsRunning(int32_t serial);

    /**
     * Request to query the location where the CDMA subscription shall be retrieved.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getCdmaSubscriptionSourceResponse()
     */
    oneway getCdmaSubscriptionSource(int32_t serial);

    /**
     * Request the ISIM application on the UICC to perform AKA
     * challenge/response algorithm for IMS authentication
     *
     * @param serial Serial number of request.
     * @param challenge challenge string in Base64 format
     *
     * Response callback is IRadioResponse.requestIsimAuthenticationResponse()
     */
    oneway requestIsimAuthentication(int32_t serial, string challenge);

    /**
     * Acknowledge successful or failed receipt of SMS previously indicated
     * via unsol responseNewSms(), including acknowledgement TPDU to send
     * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU.
     *
     * @param serial Serial number of request.
     * @param success true on successful receipt (send RP-ACK)
     *        false on failed receipt (send RP-ERROR)
     * @param ackPdu acknowledgement TPDU in hexadecimal format
     *
     * Response callback is IRadioResponse.acknowledgeIncomingGsmSmsWithPduResponse()
     */
    oneway acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success, string ackPdu);

    /**
     * Requests to send a SAT/USAT envelope command to SIM.
     * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111.
     *
     * This request has one difference from sendEnvelope():
     * the SW1 and SW2 status bytes from the UICC response are returned along with
     * the response data, using the same structure as iccIOForApp().
     *
     * The implementation must perform normal processing of a '91XX'
     * response in SW1/SW2 to retrieve the pending proactive command and send it
     * as an unsolicited response, as sendEnvelope() does.
     *
     * @param serial Serial number of request.
     * @param contents SAT/USAT command in hexadecimal format starting with command tag
     *
     * Response callback is IRadioResponse.sendEnvelopeWithStatusResponse()
     */
    oneway sendEnvelopeWithStatus(int32_t serial, string contents);

    /**
     * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only
     * when radio state is not RADIO_STATE_UNAVAILABLE
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getVoiceRadioTechnologyResponse()
     */
    oneway getVoiceRadioTechnology(int32_t serial);

    /**
     * Request all of the current cell information known to the radio. The radio
     * must return list of all current cells, including the neighboring cells. If for a particular
     * cell information isn't known then the appropriate unknown value will be returned.
     * This does not cause or change the rate of unsolicited cellInfoList().
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getCellInfoListResponse()
     */
    oneway getCellInfoList(int32_t serial);

    /**
     * Sets the minimum time between when unsolicited cellInfoList() must be invoked.
     * A value of 0, means invoke cellInfoList() when any of the reported
     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
     * a unsolicited cellInfoList().
     *
     * @param serial Serial number of request.
     * @param rate minimum time in milliseconds to indicate time between unsolicited cellInfoList()
     *
     * Response callback is IRadioResponse.setCellInfoListRateResponse()
     */
    oneway setCellInfoListRate(int32_t serial, int32_t rate);

    /**
     * Set an apn to initial attach network
     *
     * @param serial Serial number of request.
     * @param dataProfileInfo data profile containing APN settings
     * @param modemCognitive indicating the data profile was sent to the modem through
     *                       setDataProfile earlier.
     * @param isRoaming Indicating the device is roaming or not. The 'protocol' parameter in the old
     *                  RIL_InitialAttachApn must be filled accordingly based on the roaming
     *                  condition. Note this is for backward compatibility with the old radio modem.
     *                  The modem must not use this param for any other reason.
     *
     * Response callback is IRadioResponse.setInitialAttachApnResponse()
     */
    oneway setInitialAttachApn(int32_t serial, DataProfileInfo dataProfileInfo,
            bool modemCognitive, bool isRoaming);

    /**
     * Request current IMS registration state
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getImsRegistrationStateResponse()
     */
    oneway getImsRegistrationState(int32_t serial);

    /**
     * Send a SMS message over IMS.
     * Based on the return error, caller decides to resend if sending sms
     * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry.
     * In case of retry, data is encoded based on Voice Technology available.
     *
     * @param serial Serial number of request.
     * @param message ImsSmsMessage as defined in types.hal to be sent
     *
     * Response callback is IRadioResponse.sendImsSmsResponse()
     */
    oneway sendImsSms(int32_t serial, ImsSmsMessage message);

    /**
     * Request APDU exchange on the basic channel. This command reflects TS 27.007
     * "generic SIM access" operation (+CSIM). The modem must ensure proper function
     * of GSM/CDMA, and filter commands appropriately. It must filter
     * channel management and SELECT by DF name commands.
     * "sessionid" field must be ignored.
     *
     * @param serial Serial number of request.
     * @param message SimApdu as defined in types.hal to be sent
     *
     * Response callback is IRadioResponse.iccTransmitApduBasicChannelResponse()
     */
    oneway iccTransmitApduBasicChannel(int32_t serial, SimApdu message);

    /**
     * Open a new logical channel and select the given application. This command
     * reflects TS 27.007 "open logical channel" operation (+CCHO).
     *
     * @param serial Serial number of request.
     * @param aid AID value, See ETSI 102.221 and 101.220.
     * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to P2Constant:NO_P2
     *
     * Response callback is IRadioResponse.iccOpenLogicalChannelResponse()
     */
    oneway iccOpenLogicalChannel(int32_t serial, string aid, int32_t p2);

    /**
     * Close a previously opened logical channel. This command reflects TS 27.007
     * "close logical channel" operation (+CCHC).
     *
     * @param serial Serial number of request.
     * @param channelId session id of the logical channel (+CCHC).
     *
     * Response callback is IRadioResponse.iccCloseLogicalChannelResponse()
     */
    oneway iccCloseLogicalChannel(int32_t serial, int32_t channelId);

    /**
     * Exchange APDUs with a UICC over a previously opened logical channel. This
     * command reflects TS 27.007 "generic logical channel access" operation
     * (+CGLA). The modem must filter channel management and SELECT by DF name
     * commands.
     *
     * @param serial Serial number of request.
     * @param message SimApdu as defined in types.hal to be sent
     *
     * Response callback is IRadioResponse.iccTransmitApduLogicalChannelResponse()
     */
    oneway iccTransmitApduLogicalChannel(int32_t serial, SimApdu message);

    /**
     * Read one of the radio NV items.
     * This is used for device configuration by some CDMA operators.
     *
     * @param serial Serial number of request.
     * @param itemId NvItem is radio NV item as defined in types.hal
     *
     * Response callback is IRadioResponse.nvReadItemResponse()
     */
    oneway nvReadItem(int32_t serial, NvItem itemId);

    /**
     * Write one of the radio NV items.
     * This is used for device configuration by some CDMA operators.
     *
     * @param serial Serial number of request.
     * @param item NvWriteItem as defined in types.hal
     *
     * Response callback is IRadioResponse.nvWriteItemResponse()
     */
    oneway nvWriteItem(int32_t serial, NvWriteItem item);

    /**
     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
     * This is used for device configuration by some CDMA operators.
     *
     * @param serial Serial number of request.
     * @param prl PRL as a byte array
     *
     * Response callback is IRadioResponse.nvWriteCdmaPrlResponse()
     */
    oneway nvWriteCdmaPrl(int32_t serial, vec<uint8_t> prl);

    /**
     * Reset the radio NV configuration to the factory state.
     * This is used for device configuration by some CDMA operators.
     *
     * @param serial Serial number of request.
     * @param resetType ResetNvType as defined in types.hal
     *
     * Response callback is IRadioResponse.nvResetConfigResponse()
     */
    oneway nvResetConfig(int32_t serial, ResetNvType resetType);

    /**
     * Selection/de-selection of a subscription from a SIM card
     *
     * @param serial Serial number of request.
     * @param uiccSub SelectUiccSub as defined in types.hal
     *
     * Response callback is IRadioResponse.setUiccSubscriptionResponse()
     */
    oneway setUiccSubscription(int32_t serial, SelectUiccSub uiccSub);

    /**
     * Tells the modem whether data calls are allowed or not
     *
     * @param serial Serial number of request.
     * @param allow true to allow data calls, false to disallow data calls
     *
     * Response callback is IRadioResponse.setDataAllowedResponse()
     */
    oneway setDataAllowed(int32_t serial, bool allow);

    /**
     * Request all of the current hardware (modem and sim) associated with Radio.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getHardwareConfigResponse()
     */
    oneway getHardwareConfig(int32_t serial);

    /**
     * Returns the response of SIM Authentication through Radio challenge request.
     *
     * @param serial Serial number of request.
     * @param authContext P2 value of authentication command, see P2 parameter in
     *        3GPP TS 31.102 7.1.2
     * @param authData the challenge string in Base64 format, see 3GPP TS 31.102 7.1.2
     * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value
     *
     * Response callback is IRadioResponse.requestIccSimAuthenticationResponse()
     */
    oneway requestIccSimAuthentication(int32_t serial, int32_t authContext, string authData,
            string aid);

    /**
     * Set data profile in modem.
     * Modem must erase existed profiles from framework, and apply new profiles
     *
     * @param serial Serial number of request.
     * @param profiles Array of DataProfiles to set.
     * @param isRoaming Indicating the device is roaming or not. The 'protocol' parameter in the old
     *                  RIL API RIL_DataProfileInfo must be filled accordingly based on the
     *                  roaming condition. Note this is for backward compatibility with the old
     *                  radio modem. The modem must not use this param for any other reason.
     *
     * Response callback is IRadioResponse.setDataProfileResponse()
     */
    oneway setDataProfile(int32_t serial, vec<DataProfileInfo> profiles, bool isRoaming);

    /**
     * Device is shutting down. All further commands are ignored
     * and RADIO_NOT_AVAILABLE must be returned.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.requestShutdownResponse()
     */
    oneway requestShutdown(int32_t serial);

    /**
     * Used to get phone radio capability.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getRadioCapabilityResponse()
     */
    oneway getRadioCapability(int32_t serial);

    /**
     * Used to set the phones radio capability. Be VERY careful
     * using this request as it may cause some vendor modems to reset. Because
     * of the possible modem reset any radio commands after this one may not be
     * processed.
     *
     * @param serial Serial number of request.
     * @param rc RadioCapability structure to be set
     *
     * Response callback is IRadioResponse.setRadioCapabilityResponse()
     */
    oneway setRadioCapability(int32_t serial, RadioCapability rc);

    /**
     * Start Link Capacity Estimate (LCE) service if supported by the radio.
     *
     * @param serial Serial number of request.
     * @param reportInterval desired reporting interval (ms).
     * @param pullMode LCE service mode. true: PULL; false: PUSH.
     *
     * Response callback is IRadioResponse.startLceServiceResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
     */
    oneway startLceService(int32_t serial, int32_t reportInterval, bool pullMode);

    /**
     * Stop Link Capacity Estimate (LCE) service, the STOP operation must be
     * idempotent for the radio modem.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.stopLceServiceResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
     */
    oneway stopLceService(int32_t serial);

    /**
     * Pull LCE service for capacity information.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.pullLceDataResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
     */
    oneway pullLceData(int32_t serial);

    /**
     * Get modem activity information for power consumption estimation.
     * Request clear-on-read statistics information that is used for
     * estimating the per-millisecond power consumption of the cellular
     * modem.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getModemActivityInfoResponse()
     */
    oneway getModemActivityInfo(int32_t serial);

    /**
     * Set carrier restrictions. Expected modem behavior:
     *  If never receives this command
     *  - Must allow all carriers
     *  Receives this command with allAllowed true
     *  - Must allow all carriers. If a previously allowed SIM is present, modem must not reload
     *    the SIM. If a previously disallowed SIM is present, reload the SIM and notify Android.
     *  Receives this command with a list of carriers & allAllowed = false
     *  - Only allow specified carriers, persist across power cycles and FDR. If a present SIM
     *    is in the allowed list, modem must not reload the SIM. If a present SIM is *not* in
     *    the allowed list, modem must detach from the registered network and only keep emergency
     *    service, and notify Android SIM refresh reset with new SIM state being
     *    CardState:RESTRICTED. Emergency service must be enabled.
     *
     * @param serial Serial number of request.
     * @param allAllowed true only when all carriers are allowed. Ignore "carriers" struct.
     *        If false, consider "carriers" struct
     * @param carriers CarrierRestrictions consisting allowed and excluded carriers as defined
     *        in types.hal
     *
     * Response callback is IRadioResponse.setAllowedCarriersResponse()
     */
    oneway setAllowedCarriers(int32_t serial, bool allAllowed, CarrierRestrictions carriers);

    /**
     * Get carrier restrictions.
     *
     * @param serial Serial number of request.
     *
     * Response callback is IRadioResponse.getAllowedCarriersResponse()
     */
    oneway getAllowedCarriers(int32_t serial);

    /**
     * Send the updated device state.
     * This is providing the device state information for the modem to perform power saving
     * strategies.
     *
     * @param serial Serial number of request.
     * @param deviceStateType The updated device state type.
     * @param state The updated state. See the definition of state at DeviceStateType.
     *
     * Response callback is IRadioResponse.sendDeviceStateResponse()
     */
    oneway sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state);

    /**
     * Set the indication filter.
     * This is used to prevent unnecessary application processor wake up for power saving purposes
     * by suppressing the indications in certain scenarios.
     *
     * @param serial Serial number of request.
     * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
     *        indications are enabled. See IndicationFilter for the definition of each bit.
     *
     * Response callback is IRadioResponse.setIndicationFilterResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
     *
     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setIndicationFilter_1_2() instead.
     */
    oneway setIndicationFilter(int32_t serial, bitfield<IndicationFilter> indicationFilter);

    /**
     * Set SIM card power state.
     * Request is equivalent to inserting or removing the card.
     *
     * The radio modem must generate IRadioIndication.simStatusChanged() as if the SIM had been
     * inserted or removed.
     *
     * @param serial Serial number of request
     * @param powerUp True if powering up the sim card
     *
     * Response callback is IRadioResponse.setSimCardPowerResponse() which may return
     * RadioError:REQUEST_NOT_SUPPORTED if @1.1::IRadio or higher is supported.
     *
     * DEPRECATED in @1.1 or higher, use @1.1::IRadio.setSimCardPower_1_1() instead.
     */
    oneway setSimCardPower(int32_t serial, bool powerUp);

    /**
     * When response type received from a radio indication or radio response is
     * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively,
     * acknowledge the receipt of those messages by sending responseAcknowledgement().
     *
     */
    oneway responseAcknowledgement();
};
