audio: Add ril_interface to talk to radio
authorChristopher N. Hesse <raymanfx@gmail.com>
Fri, 10 Feb 2017 20:20:30 +0000 (21:20 +0100)
committerChristopher N. Hesse <raymanfx@gmail.com>
Fri, 10 Feb 2017 20:30:35 +0000 (20:30 +0000)
This is based on previous work for tuna, i9300,
i9500 and many other devices.

Change-Id: Ie94f12ee7940ffae84aec5e409a2a831b34d616f

audio/Android.mk
audio/ril_interface.c [new file with mode: 0644]
audio/ril_interface.h [new file with mode: 0644]

index c858d789dfad0d7ff5f57d3b1b87fc02adef798f..8b3061311913189e28cce621e4d6cac6f87d019b 100644 (file)
@@ -22,7 +22,8 @@ LOCAL_ARM_MODE := arm
 
 LOCAL_SRC_FILES := \
        audio_hw.c \
-       compress_offload.c
+       compress_offload.c \
+       ril_interface.c
 
 # TODO: remove resampler if possible when AudioFlinger supports downsampling from 48 to 8
 LOCAL_SHARED_LIBRARIES := \
@@ -32,13 +33,15 @@ LOCAL_SHARED_LIBRARIES := \
        libtinyalsa \
        libtinycompress \
        libaudioroute \
-       libdl
+       libdl \
+       libsecril-client
 
 
 LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/include \
        external/tinyalsa/include \
        external/tinycompress/include \
+       hardware/samsung/ril/libsecril-client \
        $(call include-path-for, audio-utils) \
        $(call include-path-for, audio-route) \
        $(call include-path-for, audio-effects)
diff --git a/audio/ril_interface.c b/audio/ril_interface.c
new file mode 100644 (file)
index 0000000..179e120
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * 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;
+}
diff --git a/audio/ril_interface.h b/audio/ril_interface.h
new file mode 100644 (file)
index 0000000..d68c6b4
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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