summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'audio/hw/ril_interface.c')
-rw-r--r--audio/hw/ril_interface.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/audio/hw/ril_interface.c b/audio/hw/ril_interface.c
new file mode 100644
index 0000000..1df5932
--- /dev/null
+++ b/audio/hw/ril_interface.c
@@ -0,0 +1,224 @@
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_primary"
18/*#define LOG_NDEBUG 0*/
19/*#define LOG_NDEBUG_FUNCTION*/
20#ifndef LOG_NDEBUG_FUNCTION
21#define LOGFUNC(...) ((void)0)
22#else
23#define LOGFUNC(...) (ALOGV(__VA_ARGS__))
24#endif
25
26#include <dlfcn.h>
27#include <stdlib.h>
28
29#include <utils/Log.h>
30#include <cutils/properties.h>
31
32#include "ril_interface.h"
33
34#define VOLUME_STEPS_DEFAULT "5"
35#define VOLUME_STEPS_PROPERTY "ro.config.vc_call_vol_steps"
36
37/* Function pointers */
38void *(*_ril_open_client)(int, char **);
39int (*_ril_close_client)(void *);
40int (*_ril_connect)(void *);
41int (*_ril_is_connected)(void *);
42int (*_ril_disconnect)(void *);
43int (*_ril_set_call_volume)(void *, enum ril_sound_type, int);
44int (*_ril_set_call_audio_path)(void *, enum ril_audio_path);
45int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state);
46int (*_ril_register_unsolicited_handler)(void *, int, void *);
47
48/* Audio WB AMR callback */
49void (*_audio_set_wb_amr_callback)(void *, int);
50void *callback_data = NULL;
51
52void ril_register_set_wb_amr_callback(void *function, void *data)
53{
54 _audio_set_wb_amr_callback = function;
55 callback_data = data;
56}
57
58/* This is the callback function that the RIL uses to
59set the wideband AMR state */
60static int ril_set_wb_amr_callback(void *ril_client,
61 const void *data,
62 size_t datalen)
63{
64 int enable = ((int *)data)[0];
65
66 if (!callback_data || !_audio_set_wb_amr_callback)
67 return -1;
68
69 _audio_set_wb_amr_callback(callback_data, enable);
70
71 return 0;
72}
73
74static int make_argv(char * args, char ** argv)
75{
76 int count = 0;
77 char *tok;
78 char *s = args;
79
80 while ((tok = strtok(s, " \0"))) {
81 argv[count] = tok;
82 s = NULL;
83 count++;
84 }
85 return count;
86}
87
88static int ril_connect_if_required(struct ril_handle *ril)
89{
90 LOGFUNC("%s(%p)", __FUNCTION__, ril);
91
92 if (_ril_is_connected(ril->client))
93 return 0;
94
95 if (_ril_connect(ril->client) != RIL_CLIENT_ERR_SUCCESS) {
96 ALOGE("ril_connect() failed");
97 return -1;
98 }
99 return 0;
100}
101
102int ril_open(struct ril_handle *ril)
103{
104 char property[PROPERTY_VALUE_MAX];
105 char **ril_client_argv;
106 int ril_client_argc;
107 static char *new_argv[RIL_CLIENT_MAX_LIB_ARGS];
108
109 LOGFUNC("%s(%p)", __FUNCTION__, ril);
110
111 if (!ril)
112 return -1;
113
114 if (!property_get(RIL_CLIENT_PATH_PROPERTY, property, NULL)) {
115 ALOGE("Cannot find '%s' property", RIL_CLIENT_PATH_PROPERTY);
116 goto none;
117 }
118
119 ril->handle = dlopen(property, RTLD_NOW);
120
121 if (!ril->handle) {
122 ALOGE("Cannot open '%s'", property);
123 goto none;
124 }
125
126 _ril_open_client = dlsym(ril->handle, "OpenClient_RILD");
127 _ril_close_client = dlsym(ril->handle, "CloseClient_RILD");
128 _ril_connect = dlsym(ril->handle, "Connect_RILD");
129 _ril_is_connected = dlsym(ril->handle, "isConnected_RILD");
130 _ril_disconnect = dlsym(ril->handle, "Disconnect_RILD");
131 _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume");
132 _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath");
133 _ril_set_call_clock_sync = dlsym(ril->handle, "SetCallClockSync");
134 _ril_register_unsolicited_handler = dlsym(ril->handle,
135 "RegisterUnsolicitedHandler");
136
137 if (!_ril_open_client || !_ril_close_client || !_ril_connect ||
138 !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume ||
139 !_ril_set_call_audio_path || !_ril_set_call_clock_sync ||
140 !_ril_register_unsolicited_handler) {
141 ALOGE("Cannot get symbols from '%s'", property);
142 dlclose(ril->handle);
143 goto none;
144 }
145
146 ril_client_argv = new_argv;
147 property_get(RIL_CLIENT_ARGS_PROPERTY, property, "");
148 ril_client_argc = make_argv(property, ril_client_argv);
149
150 ril->client = _ril_open_client(ril_client_argc, ril_client_argv);
151 if (!ril->client) {
152 ALOGE("ril_open_client() failed");
153 dlclose(ril->handle);
154 goto none;
155 }
156
157 /* register the wideband AMR callback */
158 _ril_register_unsolicited_handler(ril->client, RIL_UNSOL_WB_AMR_STATE,
159 ril_set_wb_amr_callback);
160
161 property_get(VOLUME_STEPS_PROPERTY, property, VOLUME_STEPS_DEFAULT);
162 ril->volume_steps_max = atoi(property);
163 /* this catches the case where VOLUME_STEPS_PROPERTY does not contain
164 an integer */
165 if (ril->volume_steps_max == 0)
166 ril->volume_steps_max = atoi(VOLUME_STEPS_DEFAULT);
167
168 return 0;
169
170none:
171 while(1) {
172 ALOGE("ril_open failed");
173 sleep(10);
174 }
175}
176
177int ril_close(struct ril_handle *ril)
178{
179 LOGFUNC("%s(%p)", __FUNCTION__, ril);
180
181 if (!ril || !ril->handle || !ril->client)
182 return -1;
183
184 if ((_ril_disconnect(ril->client) != RIL_CLIENT_ERR_SUCCESS) ||
185 (_ril_close_client(ril->client) != RIL_CLIENT_ERR_SUCCESS)) {
186 ALOGE("ril_disconnect() or ril_close_client() failed");
187 return -1;
188 }
189
190 dlclose(ril->handle);
191 return 0;
192}
193
194int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type,
195 float volume)
196{
197 LOGFUNC("%s(%p, %d, %f)", __FUNCTION__, ril, sound_type, volume);
198
199 if (ril_connect_if_required(ril))
200 return 0;
201
202 return _ril_set_call_volume(ril->client, sound_type,
203 (int)(volume * ril->volume_steps_max));
204}
205
206int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path)
207{
208 LOGFUNC("%s(%p, %d)", __FUNCTION__, ril, path);
209
210 if (ril_connect_if_required(ril))
211 return 0;
212
213 return _ril_set_call_audio_path(ril->client, path);
214}
215
216int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state)
217{
218 LOGFUNC("%s(%p, %d)", __FUNCTION__, ril, state);
219
220 if (ril_connect_if_required(ril))
221 return 0;
222
223 return _ril_set_call_clock_sync(ril->client, state);
224}