--- /dev/null
+/*
+ * Copyright (C) 2013 The CyanogenMod Project
+ * Copyright (C) 2017 Andreas Schneider <asn@cryptomilk.org>
+ *
+ * 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.
+ */
+
+#define LOG_TAG "audio_hw_ril"
+/*#define LOG_NDEBUG 0*/
+
+#include <errno.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <utils/Log.h>
+#include <cutils/properties.h>
+
+#include "ril_interface.h"
+
+#define VOLUME_STEPS_DEFAULT "5"
+#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
+
+/* Audio WB AMR callback */
+/*
+ * TODO:
+ * struct audio_device {
+ * HRilClient client;
+ * void *data
+ * }
+ * static struct audio_device _audio_devices[64];
+ *
+ * When registering a call back we should store it in the array and when
+ * the callback is triggered find the data pointer based on the client
+ * passed in.
+ */
+static ril_wb_amr_callback _wb_amr_callback;
+static void *_wb_amr_data = NULL;
+
+/* This is the callback function that the RIL uses to
+set the wideband AMR state */
+static int ril_internal_wb_amr_callback(HRilClient client __unused,
+ const void *data,
+ size_t datalen)
+{
+ int enable = 0;
+
+ if (_wb_amr_data == NULL || _wb_amr_callback == NULL) {
+ return -1;
+ }
+
+ if (datalen != 1) {
+ return -1;
+ }
+
+ if (*((int *)data) != 0) {
+ enable = 1;
+ }
+
+ _wb_amr_callback(_wb_amr_data, enable);
+
+ return 0;
+}
+
+static int ril_connect_if_required(struct ril_handle *ril)
+{
+ int ok;
+ int rc;
+
+ if (ril->client == NULL) {
+ ALOGE("ril->client is NULL");
+ return -1;
+ }
+
+ ok = isConnected_RILD(ril->client);
+ if (ok) {
+ return 0;
+ }
+
+ rc = Connect_RILD(ril->client);
+ if (rc != RIL_CLIENT_ERR_SUCCESS) {
+ ALOGE("Connect_RILD() failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ril_open(struct ril_handle *ril)
+{
+ char property[PROPERTY_VALUE_MAX];
+
+ if (ril == NULL) {
+ return -1;
+ }
+
+ ril->client = OpenClient_RILD();
+ if (ril->client == NULL) {
+ ALOGE("OpenClient_RILD() failed");
+ return -1;
+ }
+
+ property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
+ ril->volume_steps_max = atoi(property);
+
+ /*
+ * This catches the case where VOLUME_STEPS_PROPERTY does not contain
+ * an integer
+ */
+ if (ril->volume_steps_max == 0) {
+ ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
+ }
+
+ return 0;
+}
+
+int ril_close(struct ril_handle *ril)
+{
+ int rc;
+
+ if (ril == NULL || ril->client == NULL) {
+ return -1;
+ }
+
+ rc = Disconnect_RILD(ril->client);
+ if (rc != RIL_CLIENT_ERR_SUCCESS) {
+ ALOGE("Disconnect_RILD failed");
+ return -1;
+ }
+
+ rc = CloseClient_RILD(ril->client);
+ if (rc != RIL_CLIENT_ERR_SUCCESS) {
+ ALOGE("CloseClient_RILD() failed");
+ return -1;
+ }
+ ril->client = NULL;
+
+ return 0;
+}
+
+int ril_set_wb_amr_callback(struct ril_handle *ril,
+ ril_wb_amr_callback fn,
+ void *data)
+{
+ int rc;
+
+ if (fn == NULL || data == NULL) {
+ return -1;
+ }
+
+ _wb_amr_callback = fn;
+ _wb_amr_data = data;
+
+ ALOGV("%s: RegisterUnsolicitedHandler(%d, %p)",
+ __func__,
+ RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
+ ril_set_wb_amr_callback);
+
+ /* register the wideband AMR callback */
+ rc = RegisterUnsolicitedHandler(ril->client,
+ RIL_UNSOL_SNDMGR_WB_AMR_REPORT,
+ (RilOnUnsolicited)ril_internal_wb_amr_callback);
+ if (rc != RIL_CLIENT_ERR_SUCCESS) {
+ ALOGE("%s: Failed to register WB_AMR callback", __func__);
+ ril_close(ril);
+ return -1;
+ }
+
+ return 0;
+}
+
+int ril_set_call_volume(struct ril_handle *ril,
+ enum _SoundType sound_type,
+ float volume)
+{
+ int rc;
+
+ rc = ril_connect_if_required(ril);
+ if (rc != 0) {
+ return 0;
+ }
+
+ rc = SetCallVolume(ril->client,
+ sound_type,
+ (int)(volume * ril->volume_steps_max));
+
+ return rc;
+}
+
+int ril_set_call_audio_path(struct ril_handle *ril, enum _AudioPath path)
+{
+ int rc;
+
+ rc = ril_connect_if_required(ril);
+ if (rc != 0) {
+ return 0;
+ }
+
+ rc = SetCallAudioPath(ril->client, path);
+
+ return rc;
+}
+
+int ril_set_call_clock_sync(struct ril_handle *ril,
+ enum _SoundClockCondition condition)
+{
+ int rc;
+
+ rc = ril_connect_if_required(ril);
+ if (rc != 0) {
+ return 0;
+ }
+
+ rc = SetCallClockSync(ril->client, condition);
+
+ return rc;
+}
+
+int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition)
+{
+ int rc;
+
+ rc = ril_connect_if_required(ril);
+ if (rc != 0) {
+ return 0;
+ }
+
+ rc = SetMute(ril->client, condition);
+
+ return rc;
+}
+
+int ril_set_two_mic_control(struct ril_handle *ril,
+ enum __TwoMicSolDevice device,
+ enum __TwoMicSolReport report)
+{
+ int rc;
+
+ rc = ril_connect_if_required(ril);
+ if (rc != 0) {
+ return 0;
+ }
+
+ rc = SetTwoMicControl(ril->client, device, report);
+
+ return rc;
+}
--- /dev/null
+/*
+ * Copyright (C) 2013 The CyanogenMod 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.
+ */
+
+#ifndef RIL_INTERFACE_H
+#define RIL_INTERFACE_H
+
+#include <telephony/ril.h>
+#include <secril-client.h>
+
+typedef void (*ril_wb_amr_callback)(void *data, int enable);
+
+struct ril_handle
+{
+ void *client;
+ int volume_steps_max;
+};
+
+
+/* Function prototypes */
+int ril_open(struct ril_handle *ril);
+
+int ril_close(struct ril_handle *ril);
+
+int ril_set_call_volume(struct ril_handle *ril,
+ enum _SoundType sound_type,
+ float volume);
+
+int ril_set_call_audio_path(struct ril_handle *ril,
+ enum _AudioPath path);
+
+int ril_set_call_clock_sync(struct ril_handle *ril,
+ enum _SoundClockCondition condition);
+
+int ril_set_mute(struct ril_handle *ril, enum _MuteCondition condition);
+
+int ril_set_two_mic_control(struct ril_handle *ril,
+ enum __TwoMicSolDevice device,
+ enum __TwoMicSolReport report);
+
+int ril_set_wb_amr_callback(struct ril_handle *ril,
+ ril_wb_amr_callback fn,
+ void *data);
+
+#endif