From c2a69f502944444c9b17f3c00c413091dbcc5c75 Mon Sep 17 00:00:00 2001 From: Kim Uk Date: Tue, 19 Jul 2011 12:57:26 -0700 Subject: audio: check for ril presence before calling into it This prevents a seg fault if no ril is present. Change-Id: I5f9443e31bdcab07df21d9f12ed2dd92807300f8 --- audio/audio_hw.c | 13 +++--- audio/ril_interface.c | 111 ++++++++++++++++++++++++++++++++++---------------- audio/ril_interface.h | 25 ++++++------ 3 files changed, 93 insertions(+), 56 deletions(-) (limited to 'audio') diff --git a/audio/audio_hw.c b/audio/audio_hw.c index 3da3cee..02b8d33 100644 --- a/audio/audio_hw.c +++ b/audio/audio_hw.c @@ -267,8 +267,7 @@ struct tuna_audio_device { int in_call; /* RIL */ - void *ril_handle; - void *ril_client; + struct ril_handle ril; }; struct tuna_stream_out { @@ -355,8 +354,8 @@ static int start_call(struct tuna_audio_device *adev) } } - ril_set_call_clock_sync(adev->ril_client, SOUND_CLOCK_START); - ril_set_call_audio_path(adev->ril_client, SOUND_AUDIO_PATH_HANDSET); + ril_set_call_clock_sync(&adev->ril, SOUND_CLOCK_START); + ril_set_call_audio_path(&adev->ril, SOUND_AUDIO_PATH_HANDSET); pcm_start(adev->pcm_modem_dl); pcm_start(adev->pcm_modem_ul); @@ -888,7 +887,7 @@ static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) /* convert the float volume to something suitable for the RIL */ if (adev->in_call) { int int_volume = (int)(volume * 5); - ril_set_call_volume(adev->ril_client, SOUND_TYPE_VOICE, int_volume); + ril_set_call_volume(&adev->ril, SOUND_TYPE_VOICE, int_volume); } return 0; @@ -1032,7 +1031,7 @@ static int adev_close(hw_device_t *device) struct tuna_audio_device *adev = (struct tuna_audio_device *)device; /* RIL */ - ril_close(adev->ril_handle, adev->ril_client); + ril_close(&adev->ril); mixer_close(adev->mixer); free(device); @@ -1127,7 +1126,7 @@ static int adev_open(const hw_module_t* module, const char* name, adev->pcm_modem_ul = NULL; /* RIL */ - ril_open(&adev->ril_handle, &adev->ril_client); + ril_open(&adev->ril); *device = &adev->device.common; diff --git a/audio/ril_interface.c b/audio/ril_interface.c index b20d42b..6bc0127 100644 --- a/audio/ril_interface.c +++ b/audio/ril_interface.c @@ -14,73 +14,112 @@ * limitations under the License. */ +#define LOG_TAG "audio_hw_primary" +/*#define LOG_NDEBUG 0*/ + #include #include #include "ril_interface.h" -int ril_open(void **ril_handle, void **ril_client) +/* Function pointers */ +void *(*_ril_open_client)(void); +int (*_ril_close_client)(void *); +int (*_ril_connect)(void *); +int (*_ril_is_connected)(void *); +int (*_ril_disconnect)(void *); +int (*_ril_set_call_volume)(void *, enum ril_sound_type, int); +int (*_ril_set_call_audio_path)(void *, enum ril_audio_path); +int (*_ril_set_call_clock_sync)(void *, enum ril_clock_state); + +static int ril_connect_if_required(struct ril_handle *ril) +{ + if (_ril_is_connected(ril->client)) + return 0; + + if (_ril_connect(ril->client) != RIL_CLIENT_ERR_SUCCESS) { + LOGE("ril_connect() failed"); + return -1; + } + return 0; +} + +int ril_open(struct ril_handle *ril) { - void *handle; - void *client; + if (!ril) + return -1; - handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW); + ril->handle = dlopen(RIL_CLIENT_LIBPATH, RTLD_NOW); - if (!handle) { + if (!ril->handle) { LOGE("Cannot open '%s'", RIL_CLIENT_LIBPATH); return -1; } - ril_open_client = dlsym(handle, "OpenClient_RILD"); - ril_close_client = dlsym(handle, "CloseClient_RILD"); - ril_connect = dlsym(handle, "Connect_RILD"); - ril_is_connected = dlsym(handle, "isConnected_RILD"); - ril_disconnect = dlsym(handle, "Disconnect_RILD"); - ril_set_call_volume = dlsym(handle, "SetCallVolume"); - ril_set_call_audio_path = dlsym(handle, "SetCallAudioPath"); - ril_set_call_clock_sync = dlsym(handle, "SetCallClockSync"); - - if (!ril_open_client || !ril_close_client || !ril_connect || - !ril_is_connected || !ril_disconnect || !ril_set_call_volume || - !ril_set_call_audio_path || !ril_set_call_clock_sync) { + _ril_open_client = dlsym(ril->handle, "OpenClient_RILD"); + _ril_close_client = dlsym(ril->handle, "CloseClient_RILD"); + _ril_connect = dlsym(ril->handle, "Connect_RILD"); + _ril_is_connected = dlsym(ril->handle, "isConnected_RILD"); + _ril_disconnect = dlsym(ril->handle, "Disconnect_RILD"); + _ril_set_call_volume = dlsym(ril->handle, "SetCallVolume"); + _ril_set_call_audio_path = dlsym(ril->handle, "SetCallAudioPath"); + _ril_set_call_clock_sync = dlsym(ril->handle, "SetCallClockSync"); + + if (!_ril_open_client || !_ril_close_client || !_ril_connect || + !_ril_is_connected || !_ril_disconnect || !_ril_set_call_volume || + !_ril_set_call_audio_path || !_ril_set_call_clock_sync) { LOGE("Cannot get symbols from '%s'", RIL_CLIENT_LIBPATH); - dlclose(handle); + dlclose(ril->handle); return -1; } - client = ril_open_client(); - if (!client) { + ril->client = _ril_open_client(); + if (!ril->client) { LOGE("ril_open_client() failed"); - dlclose(handle); + dlclose(ril->handle); return -1; } - if (ril_connect(client) != RIL_CLIENT_ERR_SUCCESS || - !ril_is_connected(client)) { - LOGE("ril_connect() failed"); - ril_close_client(client); - dlclose(handle); - return -1; - } - - *ril_handle = handle; - *ril_client = client; return 0; } -int ril_close(void *ril_handle, void *ril_client) +int ril_close(struct ril_handle *ril) { - if (!ril_handle) + if (!ril || !ril->handle || !ril->client) return -1; - if ((ril_disconnect(ril_client) != RIL_CLIENT_ERR_SUCCESS) || - (ril_close_client(ril_client) != RIL_CLIENT_ERR_SUCCESS)) { + if ((_ril_disconnect(ril->client) != RIL_CLIENT_ERR_SUCCESS) || + (_ril_close_client(ril->client) != RIL_CLIENT_ERR_SUCCESS)) { LOGE("ril_disconnect() or ril_close_client() failed"); return -1; } - dlclose(ril_handle); + dlclose(ril->handle); return 0; } +int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type, + int volume) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_volume(ril->client, sound_type, volume); +} + +int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_audio_path(ril->client, path); +} + +int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state) +{ + if (ril_connect_if_required(ril)) + return 0; + + return _ril_set_call_clock_sync(ril->client, state); +} diff --git a/audio/ril_interface.h b/audio/ril_interface.h index 95da631..c47484d 100644 --- a/audio/ril_interface.h +++ b/audio/ril_interface.h @@ -28,6 +28,12 @@ #define RIL_CLIENT_ERR_RESOURCE 6 // Resource not available #define RIL_CLIENT_ERR_UNKNOWN 7 +struct ril_handle +{ + void *handle; + void *client; +}; + enum ril_sound_type { SOUND_TYPE_VOICE, SOUND_TYPE_SPEAKER, @@ -49,19 +55,12 @@ enum ril_clock_state { SOUND_CLOCK_START }; -/* Function pointers */ -void *(*ril_open_client)(void); -int (*ril_close_client)(void *); -int (*ril_connect)(void *); -int (*ril_is_connected)(void *); -int (*ril_disconnect)(void *); -int (*ril_set_call_volume)(void *, enum ril_sound_type, int); -int (*ril_set_call_audio_path)(void *, enum ril_audio_path); -int (*ril_set_call_clock_sync)(void *, enum ril_clock_state); - /* Function prototypes */ -int ril_open(void **ril_handle, void **ril_client); -int ril_close(void *ril_handle, void *ril_client); - +int ril_open(struct ril_handle *ril); +int ril_close(struct ril_handle *ril); +int ril_set_call_volume(struct ril_handle *ril, enum ril_sound_type sound_type, + int volume); +int ril_set_call_audio_path(struct ril_handle *ril, enum ril_audio_path path); +int ril_set_call_clock_sync(struct ril_handle *ril, enum ril_clock_state state); #endif -- cgit v1.1