/*
 * Copyright (C) 2018 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.4;

import @1.0::RadioResponseInfo;
import @1.3::IRadioResponse;
import @1.4::CardStatus;
import @1.4::CarrierRestrictionsWithPriority;
import @1.4::CellInfo;
import @1.4::DataRegStateResult;
import @1.4::RadioAccessFamily;
import @1.4::SetupDataCallResult;
import @1.4::SignalStrength;
import @1.4::SimLockMultiSimPolicy;

/**
 * Interface declaring response functions to solicited radio requests.
 */
interface IRadioResponse extends @1.3::IRadioResponse {
    /**
     * @param info Response info struct containing response type, serial no. and error
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE (radio resetting)
     *   RadioError:DIAL_MODIFIED_TO_USSD
     *   RadioError:DIAL_MODIFIED_TO_SS
     *   RadioError:DIAL_MODIFIED_TO_DIAL
     *   RadioError:INVALID_ARGUMENTS
     *   RadioError:NO_RESOURCES
     *   RadioError:INTERNAL_ERR
     *   RadioError:FDN_CHECK_FAILURE
     *   RadioError:MODEM_ERR
     *   RadioError:NO_SUBSCRIPTION
     *   RadioError:NO_NETWORK_FOUND
     *   RadioError:INVALID_CALL_ID
     *   RadioError:DEVICE_IN_USE
     *   RadioError:ABORTED
     *   RadioError:INVALID_MODEM_STATE
     */
    oneway emergencyDialResponse(RadioResponseInfo info);

    /**
     * @param info Response info struct containing response type, serial no. and error
     *
     * Same API as @1.1::IRadioResponse.startNetworkScanResponse, except disallowing error codes
     * OPERATION_NOT_ALLOWED and REQUEST_NOT_SUPPORTED.
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:DEVICE_IN_USE
     *   RadioError:INTERNAL_ERR
     *   RadioError:MODEM_ERR
     *   RadioError:INVALID_ARGUMENTS
     */
    oneway startNetworkScanResponse_1_4(RadioResponseInfo info);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param cellInfo List of current cell information known to radio
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     */
    oneway getCellInfoListResponse_1_4(RadioResponseInfo info, vec<CellInfo> cellInfo);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param dataRegResponse Current Data registration response as defined by DataRegStateResult in
     *        types.hal
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     *   RadioError:NOT_PROVISIONED
     */
    oneway getDataRegistrationStateResponse_1_4(RadioResponseInfo info,
            DataRegStateResult dataRegResponse);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param cardStatus ICC card status as defined by CardStatus in types.hal
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     *   RadioError:NO_RESOURCES
     *   RadioError:REQUEST_NOT_SUPPORTED
     */
    oneway getIccCardStatusResponse_1_4(RadioResponseInfo info, CardStatus cardStatus);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily.
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     *   RadioError:INVALID_ARGUMENTS
     *   RadioError:MODEM_ERR
     *   RadioError:REQUEST_NOT_SUPPORTED
     *   RadioError:NO_RESOURCES
     */
    oneway getPreferredNetworkTypeBitmapResponse(RadioResponseInfo info,
            bitfield<RadioAccessFamily> networkTypeBitmap);

    /**
     * Callback of IRadio.setPreferredNetworkTypeBitmap(int, bitfield<RadioAccessFamily>)
     *
     * @param info Response info struct containing response type, serial no. and error
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:OPERATION_NOT_ALLOWED
     *   RadioError:MODE_NOT_SUPPORTED
     *   RadioError:INTERNAL_ERR
     *   RadioError:INVALID_ARGUMENTS
     *   RadioError:MODEM_ERR
     *   RadioError:REQUEST_NOT_SUPPORTED
     *   RadioError:NO_RESOURCES
     */
    oneway setPreferredNetworkTypeBitmapResponse(RadioResponseInfo info);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param dcResponse List of DataCallResult as defined in types.hal
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     *   RadioError:NO_RESOURCES
     *   RadioError:REQUEST_NOT_SUPPORTED
     *   RadioError:SIM_ABSENT
     */
    oneway getDataCallListResponse_1_4(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);

    /**
     * @param info Response info struct containing response type, serial no. and error
     * @param dcResponse SetupDataCallResult defined in types.hal
     *
     * Valid errors returned:
     *   RadioError:NONE must be returned on both success and failure of setup with the
     *              DataCallResponse.status containing the actual status
     *              For all other errors the DataCallResponse is ignored.
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW
     *   RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
     *   RadioError:REQUEST_NOT_SUPPORTED
     *   RadioError:INVALID_ARGUMENTS
     *   RadioError:INTERNAL_ERR
     *   RadioError:NO_RESOURCES
     *   RadioError:SIM_ABSENT
     */
    oneway setupDataCallResponse_1_4(RadioResponseInfo info, SetupDataCallResult dcResponse);

    /**
     * @param info Response info struct containing response type, serial no. and error
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INVALID_ARGUMENTS
     *   RadioError:REQUEST_NOT_SUPPORTED
     */
    oneway setAllowedCarriersResponse_1_4(RadioResponseInfo info);

    /**
     * Expected modem behavior:
     *  Return list of allowed carriers, and if all carriers are allowed.
     *
     * @param info Response info struct containing response type, serial no. and error
     * @param carriers Carrier restriction information.
     * @param multiSimPolicy Policy used for devices with multiple SIM cards.
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:REQUEST_NOT_SUPPORTED
     */
    oneway getAllowedCarriersResponse_1_4(RadioResponseInfo info,
            CarrierRestrictionsWithPriority carriers, SimLockMultiSimPolicy multiSimPolicy);

    /**
     * @param signalStrength Current signal strength
     *
     * Valid errors returned:
     *   RadioError:NONE
     *   RadioError:RADIO_NOT_AVAILABLE
     *   RadioError:INTERNAL_ERR
     */
    oneway getSignalStrengthResponse_1_4(RadioResponseInfo info, SignalStrength signalStrength);
};
