summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGilbok Lee <gilbok.lee@samsung.com>2016-10-20 19:44:41 +0900
committerGilbok Lee <gilbok.lee@samsung.com>2016-11-03 19:25:54 +0900
commit4dd8d5309b074cab27a5dac23dd92cbc1d47803b (patch)
tree63d0e5232a97a964a613331b3f6ca82f28b991ed /src
parent6779ede5625e9c3003c06d8b8399a7cc9bcf1ed7 (diff)
downloadlibmm-radio-4dd8d5309b074cab27a5dac23dd92cbc1d47803b.tar.gz
libmm-radio-4dd8d5309b074cab27a5dac23dd92cbc1d47803b.tar.bz2
libmm-radio-4dd8d5309b074cab27a5dac23dd92cbc1d47803b.zip
First version of libmm-radio using radio-hal
[Version] 0.2.7 [Profile] Mobile [Issue Type] Refactoring Change-Id: I332bae2294a30988afb5a8c65864336277b1d5c9
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Makefile.am49
-rw-r--r--src/include/mm_radio.h6
-rw-r--r--[-rwxr-xr-x]src/include/mm_radio_priv.h17
-rw-r--r--src/include/mm_radio_priv_hal.h216
-rw-r--r--[-rwxr-xr-x]src/include/mm_radio_sound_focus.h (renamed from src/include/mm_radio_audio_focus.h)24
-rw-r--r--src/include/mm_radio_utils.h24
-rw-r--r--src/include/radio_hal_interface.h56
-rw-r--r--src/include/tizen-radio.h264
-rw-r--r--[-rwxr-xr-x]src/mm_radio.c15
-rwxr-xr-xsrc/mm_radio_audio_focus.c181
-rw-r--r--src/mm_radio_priv_emulator.c187
-rw-r--r--[-rwxr-xr-x]src/mm_radio_priv_hal.c (renamed from src/mm_radio_priv.c)1050
-rw-r--r--src/mm_radio_sound_focus.c355
-rw-r--r--src/radio_hal_interface.c353
14 files changed, 1946 insertions, 851 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fae2c44..1b67d95 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,26 +3,43 @@ lib_LTLIBRARIES = libmmfradio.la
includelibmmfradiodir = $(includedir)/mmf
includelibmmfradio_HEADERS = include/mm_radio.h
-libmmfradio_la_SOURCES = mm_radio.c \
- mm_radio_audio_focus.c
-if ENABLE_EMULATOR
-libmmfradio_la_SOURCES += mm_radio_priv_emulator.c
-else
-libmmfradio_la_SOURCES += mm_radio_priv.c
-endif
+libmmfradio_la_SOURCES = mm_radio.c
libmmfradio_la_CFLAGS = -I. -I./include \
$(GTHREAD_CFLAGS) \
$(MMCOMMON_CFLAGS) \
- $(MMSESSION_CFLAGS) \
- $(MMSOUND_CFLAGS) \
- $(GST_CFLAGS) \
- $(GSTAPP_CFLAGS) \
-DMMF_LOG_OWNER=0x200000 -DMMF_DEBUG_PREFIX=\"MM-RADIO\"
libmmfradio_la_LIBADD = $(GTHREAD_LIBS) \
- $(MMCOMMON_LIBS) \
- $(MMSESSION_LIBS) \
- $(MMSOUND_LIBS) \
- $(GST_LIBS) \
- $(GSTAPP_LIBS) \ No newline at end of file
+ $(MMCOMMON_LIBS)
+
+if ENABLE_EMULATOR
+libmmfradio_la_SOURCES += mm_radio_priv_emulator.c
+
+libmmfradio_la_CFLAGS += $(GST_CFLAGS) \
+ $(GSTAPP_CFLAGS)
+
+libmmfradio_la_LIBADD += $(GST_LIBS) \
+ $(GSTAPP_LIBS)
+else
+libmmfradio_la_SOURCES += mm_radio_priv_hal.c \
+ radio_hal_interface.c
+endif
+
+if ENABLE_SOUND_FOCUS
+libmmfradio_la_SOURCES += mm_radio_sound_focus.c
+
+libmmfradio_la_CFLAGS += $(MMSESSION_CFLAGS) \
+ $(MMSOUND_CFLAGS) \
+ -DTIZEN_FEATURE_SOUND_FOCUS
+
+libmmfradio_la_LIBADD += $(MMSESSION_LIBS) \
+ $(MMSOUND_LIBS)
+endif
+
+if ENABLE_SOUND_VSTREAM
+libmmfradio_la_CFLAGS += $(SOUNDMGR_CFLAGS) \
+ -DTIZEN_FEATURE_SOUND_VSTREAM
+
+libmmfradio_la_LIBADD += $(SOUNDMGR_LIBS)
+endif
diff --git a/src/include/mm_radio.h b/src/include/mm_radio.h
index 9106199..493280e 100644
--- a/src/include/mm_radio.h
+++ b/src/include/mm_radio.h
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio.h
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/include/mm_radio_priv.h b/src/include/mm_radio_priv.h
index b6569bb..ca8dfe5 100755..100644
--- a/src/include/mm_radio_priv.h
+++ b/src/include/mm_radio_priv.h
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio_priv.h
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +16,7 @@
* limitations under the License.
*
*/
-
+
#ifndef __MM_Radio_INTERNAL_H__
#define __MM_Radio_INTERNAL_H__
@@ -35,7 +33,10 @@
#include <mm_types.h>
#include <mm_message.h>
-#include "mm_radio_audio_focus.h"
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+#include "mm_radio_sound_focus.h"
+#endif
+
#include "mm_radio.h"
#include "mm_radio_utils.h"
#include <linux/videodev2.h>
@@ -184,7 +185,9 @@ typedef struct {
int prev_seek_freq;
MMRadioSeekDirectionType seek_direction;
- MMRadioAudioFocus sm;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ mm_radio_sound_focus sound_focus;
+#endif
int freq;
#ifdef USE_GST_PIPELINE
diff --git a/src/include/mm_radio_priv_hal.h b/src/include/mm_radio_priv_hal.h
new file mode 100644
index 0000000..e214df1
--- /dev/null
+++ b/src/include/mm_radio_priv_hal.h
@@ -0,0 +1,216 @@
+/*
+ * mm_radio_priv_hal.h
+ *
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __MM_Radio_INTERNAL_H__
+#define __MM_Radio_INTERNAL_H__
+
+/*===========================================================================================
+ INCLUDE FILES
+========================================================================================== */
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <mm_types.h>
+#include <mm_message.h>
+
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+#include "mm_radio_sound_focus.h"
+#endif
+
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+#include <media/sound_manager.h>
+#include <media/sound_manager_internal.h>
+#endif
+
+#include "mm_radio.h"
+#include "mm_radio_utils.h"
+#include "radio_hal_interface.h"
+#include <linux/videodev2.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*===========================================================================================
+ GLOBAL DEFINITIONS AND DECLARATIONS FOR MODULE
+========================================================================================== */
+
+/*---------------------------------------------------------------------------
+ GLOBAL #defines:
+---------------------------------------------------------------------------*/
+#define SAMPLEDELAY 15000
+
+/* si470x dependent define */
+#define SYSCONFIG1 4 /* System Configuration 1 */
+#define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable */
+#define SYSCONFIG1_RDS_OFFSET 12 /* bits 12..12: RDS Enable Offset */
+
+#define SYSCONFIG2 5 /* System Configuration 2 */
+#define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
+#define SYSCONFIG2_SEEKTH_OFFSET 8 /* bits 15..08: RSSI Seek Threshold Offset */
+
+#define SYSCONFIG3 6 /* System Configuration 3 */
+#define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
+#define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
+#define SYSCONFIG3_SKSNR_OFFSET 4 /* bits 07..04: Seek SNR Threshold Offset */
+#define SYSCONFIG3_SKCNT_OFFSET 0 /* bits 03..00: Seek FM Impulse Detection Threshold Offset */
+
+#define DEFAULT_CHIP_MODEL "radio-si470x"
+
+/*---------------------------------------------------------------------------
+ GLOBAL CONSTANT DEFINITIONS:
+---------------------------------------------------------------------------*/
+typedef enum {
+ MMRADIO_COMMAND_CREATE = 0,
+ MMRADIO_COMMAND_DESTROY,
+ MMRADIO_COMMAND_REALIZE,
+ MMRADIO_COMMAND_UNREALIZE,
+ MMRADIO_COMMAND_START,
+ MMRADIO_COMMAND_STOP,
+ MMRADIO_COMMAND_START_SCAN,
+ MMRADIO_COMMAND_STOP_SCAN,
+ MMRADIO_COMMAND_SET_FREQ,
+ MMRADIO_COMMAND_GET_FREQ,
+ MMRADIO_COMMAND_VOLUME,
+ MMRADIO_COMMAND_MUTE,
+ MMRADIO_COMMAND_UNMUTE,
+ MMRADIO_COMMAND_SEEK,
+ MMRADIO_COMMAND_SET_REGION,
+ MMRADIO_COMMAND_GET_REGION,
+ MMRADIO_COMMAND_NUM
+} MMRadioCommand;
+
+/* max and mix frequency types, KHz */
+typedef enum {
+ MM_RADIO_FREQ_NONE = 0,
+ /* min band types */
+ MM_RADIO_FREQ_MIN_76100_KHZ = 76100,
+ MM_RADIO_FREQ_MIN_87500_KHZ = 87500,
+ MM_RADIO_FREQ_MIN_88100_KHZ = 88100,
+ /* max band types */
+ MM_RADIO_FREQ_MAX_89900_KHZ = 89900,
+ MM_RADIO_FREQ_MAX_108000_KHZ = 108000,
+} MMRadioFreqTypes;
+
+/* de-emphasis types */
+typedef enum {
+ MM_RADIO_DEEMPHASIS_NONE = 0,
+ MM_RADIO_DEEMPHASIS_50_US,
+ MM_RADIO_DEEMPHASIS_75_US,
+} MMRadioDeemphasis;
+
+/* radio region settings */
+typedef struct {
+ MMRadioRegionType country;
+ MMRadioDeemphasis deemphasis; // unit : us
+ MMRadioFreqTypes band_min; // <- freq. range, unit : KHz
+ MMRadioFreqTypes band_max; // ->
+ int channel_spacing; // TBD
+} MMRadioRegion_t;
+
+/*---------------------------------------------------------------------------
+ GLOBAL DATA TYPE DEFINITIONS:
+---------------------------------------------------------------------------*/
+
+typedef struct {
+ /* radio state */
+ int current_state;
+ int old_state;
+ int pending_state;
+
+ int cmd;
+
+ /* command lock */
+ pthread_mutex_t cmd_lock;
+
+ /* radio attributes */
+ MMHandleType *attrs;
+
+ /* message callback */
+ MMMessageCallback msg_cb;
+ void *msg_cb_param;
+
+ /* scan */
+ pthread_t scan_thread;
+ bool stop_scan;
+
+ /* seek */
+ pthread_t seek_thread;
+ pthread_mutex_t seek_cancel_mutex;
+ bool stop_seek;
+ bool is_seeking;
+ int prev_seek_freq;
+ int is_muted;
+ int is_ready;
+
+ int seek_unmute;
+ bool seek_cancel;
+
+ MMRadioSeekDirectionType seek_direction;
+
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ mm_radio_sound_focus sound_focus;
+#endif
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ sound_stream_info_h stream_info;
+ virtual_sound_stream_h vstream;
+#endif
+
+ int freq;
+
+ /* region settings */
+ MMRadioRegion_t region_setting;
+
+ mm_radio_hal_interface *hal_inf;
+
+} mm_radio_t;
+
+/*===========================================================================================
+ GLOBAL FUNCTION PROTOTYPES
+========================================================================================== */
+int _mmradio_create_radio(mm_radio_t *radio);
+int _mmradio_destroy(mm_radio_t *radio);
+int _mmradio_realize(mm_radio_t *radio);
+int _mmradio_unrealize(mm_radio_t *radio);
+int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param);
+int _mmradio_get_state(mm_radio_t *radio, int *pState);
+int _mmradio_set_frequency(mm_radio_t *radio, int freq);
+int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq);
+int _mmradio_mute(mm_radio_t *radio);
+int _mmradio_unmute(mm_radio_t *radio);
+int _mmradio_start(mm_radio_t *radio);
+int _mmradio_stop(mm_radio_t *radio);
+int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction);
+int _mmradio_start_scan(mm_radio_t *radio);
+int _mmradio_stop_scan(mm_radio_t *radio);
+int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value);
+int _mmradio_apply_region(mm_radio_t*radio, MMRadioRegionType region, bool update);
+int _mmradio_get_region_type(mm_radio_t*radio, MMRadioRegionType *type);
+int _mmradio_get_region_frequency_range(mm_radio_t *radio, unsigned int *min_freq, unsigned int *max_freq);
+int _mmradio_get_channel_spacing(mm_radio_t* radio, unsigned int *ch_spacing);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_Radio_INTERNAL_H__ */
diff --git a/src/include/mm_radio_audio_focus.h b/src/include/mm_radio_sound_focus.h
index e14d371..ce8ec8e 100755..100644
--- a/src/include/mm_radio_audio_focus.h
+++ b/src/include/mm_radio_sound_focus.h
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio_sound_focus.h
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,18 +34,22 @@ enum {
MMRADIO_FOCUS_CB_SKIP_POSTMSG
};
typedef struct {
+ int focus_id;
+ int watch_id;
+ unsigned int subscribe_id;
+ unsigned int device_subs_id;
int handle;
int pid;
int by_focus_cb;
int event_src;
int snd_session_flags;
+ int session_type;
mm_sound_focus_type_e cur_focus_type;
-} MMRadioAudioFocus;
-
-int mmradio_audio_focus_register(MMRadioAudioFocus* sm, mm_sound_focus_changed_cb callback, void* param);
-int mmradio_audio_focus_deregister(MMRadioAudioFocus* sm);
-int mmradio_acquire_audio_focus(MMRadioAudioFocus* sm);
-int mmradio_release_audio_focus(MMRadioAudioFocus* sm);
-void mmradio_get_audio_focus_reason(mm_sound_focus_state_e focus_state, const char *reason_for_change, enum MMMessageInterruptedCode *event_source, int *postMsg);
+} mm_radio_sound_focus;
+int mmradio_sound_focus_register(mm_radio_sound_focus *sound_focus, mm_sound_focus_changed_cb focus_cb, mm_sound_focus_changed_watch_cb watch_cb, void *param);
+int mmradio_sound_focus_deregister(mm_radio_sound_focus *sound_focus);
+int mmradio_acquire_sound_focus(mm_radio_sound_focus *sound_focus);
+int mmradio_release_sound_focus(mm_radio_sound_focus *sound_focus);
+void mmradio_get_sound_focus_reason(mm_sound_focus_state_e focus_state, const char *reason_for_change, enum MMMessageInterruptedCode *event_source, int *postMsg);
#endif /* MM_RADIO_AUDIO_FOCUS_H_ */
diff --git a/src/include/mm_radio_utils.h b/src/include/mm_radio_utils.h
index 8187adb..d498b59 100644
--- a/src/include/mm_radio_utils.h
+++ b/src/include/mm_radio_utils.h
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio_utils.h
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +23,7 @@
#include <assert.h>
#include <mm_types.h>
#include <mm_error.h>
+#include <mm_debug.h>
#include <mm_message.h>
/* radio log */
@@ -32,7 +31,7 @@
#define MMRADIO_LOG_FLEAVE debug_fleave
#define MMRADIO_LOG_DEBUG debug_log
#define MMRADIO_LOG_ERROR debug_error
-#define MMRADIO_LOG_WARNING debug_warning
+#define MMRADIO_LOG_WARNING debug_warning
#define MMRADIO_LOG_CRITICAL debug_critical
#define MMRADIO_SLOG_DEBUG debug_log /* secure_debug_log */
@@ -41,6 +40,13 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
#define MMRADIO_MAX_INT (2147483647)
#define MMRADIO_FREEIF(x) \
@@ -55,6 +61,14 @@ if ( ! x_radio ) \
return MM_ERROR_RADIO_NOT_INITIALIZED; \
}
+#define MMRADIO_CHECK_ARG( x_radio ) \
+if ( ! x_radio ) \
+{ \
+ debug_error("argument is NULL\n"); \
+ return MM_ERROR_COMMON_INVALID_ARGUMENT; \
+}
+
+
#define MMRADIO_CHECK_INSTANCE_RETURN_VOID( x_radio ) \
if ( ! x_radio ) \
{ \
diff --git a/src/include/radio_hal_interface.h b/src/include/radio_hal_interface.h
new file mode 100644
index 0000000..68bfb14
--- /dev/null
+++ b/src/include/radio_hal_interface.h
@@ -0,0 +1,56 @@
+/*
+ * radio_hal_interface.h
+ *
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tizen-radio.h"
+
+typedef enum _seek_direction_type {
+ SEEK_DIRECTION_UP, /**< Seek upward */
+ SEEK_DIRECTION_DOWN /**< Seek downward */
+} seek_direction_type_t;
+
+typedef struct _mmradio_hal_interface {
+ void *dl_handle;
+ void *rh_handle;
+ radio_interface_t intf;
+} mm_radio_hal_interface;
+
+int radio_hal_interface_init(mm_radio_hal_interface **handle);
+int radio_hal_interface_deinit(mm_radio_hal_interface *handle);
+int radio_hal_open(mm_radio_hal_interface *radio_handle);
+int radio_hal_prepare(mm_radio_hal_interface *radio_handle);
+int radio_hal_unprepare(mm_radio_hal_interface *radio_handle);
+int radio_hal_close(mm_radio_hal_interface *radio_handle);
+int radio_hal_start(mm_radio_hal_interface *radio_handle);
+int radio_hal_stop(mm_radio_hal_interface *radio_handle);
+int radio_hal_seek(mm_radio_hal_interface *radio_handle, seek_direction_type_t direction);
+int radio_hal_get_frequency(mm_radio_hal_interface *radio_handle, uint32_t *frequency);
+int radio_hal_set_frequency(mm_radio_hal_interface *radio_handle, uint32_t frequency);
+int radio_hal_get_signal_strength(mm_radio_hal_interface *radio_handle, uint32_t *strength);
+int radio_hal_mute(mm_radio_hal_interface *radio_handle);
+int radio_hal_unmute(mm_radio_hal_interface *radio_handle);
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/include/tizen-radio.h b/src/include/tizen-radio.h
new file mode 100644
index 0000000..8f6ce17
--- /dev/null
+++ b/src/include/tizen-radio.h
@@ -0,0 +1,264 @@
+/*
+ * tizen-radio.h
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_RADIO_HAL_H__
+#define __TIZEN_RADIO_HAL_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file tizen-radio.h
+ * @brief This file contains the Tizen radio HAL API, related structures and enumerations.
+ * @since_tizen 3.0
+ */
+
+/**
+ * @addtogroup TIZEN_RADIO_HAL_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for the radio error.
+ * @since_tizen 3.0
+ */
+typedef enum radio_error {
+ RADIO_ERROR_NONE,
+ RADIO_ERROR_INVALID_PARAMETER,
+ RADIO_ERROR_INVALID_STATE,
+ RADIO_ERROR_INVALID_OPERATION,
+ RADIO_ERROR_PERMISSION_DENIED,
+ RADIO_ERROR_NOT_SUPPORTED,
+ RADIO_ERROR_OUT_OF_MEMORY,
+ RADIO_ERROR_DEVICE_NOT_PREPARED,
+ RADIO_ERROR_DEVICE_NOT_OPENED,
+ RADIO_ERROR_DEVICE_NOT_FOUND,
+ RADIO_ERROR_DEVICE_NOT_SUPPORTED,
+ RADIO_ERROR_NO_ANTENNA,
+ RADIO_ERROR_INTERNAL,
+ RADIO_ERROR_UNKNOWN
+} radio_error_t;
+
+/**
+ * @brief Enumeration for the radio seek direction.
+ * @since_tizen 3.0
+ */
+typedef enum radio_seek_direction_type {
+ RADIO_SEEK_DIRECTION_UP, /**< Seek upward */
+ RADIO_SEEK_DIRECTION_DOWN /**< Seek downward */
+} radio_seek_direction_type_t;
+
+typedef struct radio_interface {
+ /* create & destroy */
+ radio_error_t (*init)(void **radio_hanle);
+ radio_error_t (*deinit)(void *radio_handle);
+ radio_error_t (*prepare)(void *radio_handle);
+ radio_error_t (*unprepare)(void *radio_handle);
+ radio_error_t (*open)(void *radio_handle);
+ radio_error_t (*close)(void *radio_handle);
+ radio_error_t (*start)(void *radio_handle);
+ radio_error_t (*stop)(void *radio_handle);
+ radio_error_t (*seek)(void *radio_handle, radio_seek_direction_type_t direction);
+ radio_error_t (*get_frequency)(void *radio_handle, uint32_t *frequency);
+ radio_error_t (*set_frequency)(void *radio_handle, uint32_t frequency);
+ radio_error_t (*mute)(void *radio_handle);
+ radio_error_t (*unmute)(void *radio_handle);
+ radio_error_t (*get_signal_strength)(void *radio_handle, uint32_t *strength);
+} radio_interface_t;
+
+/**
+ * @brief Initializes new handle of radio HAL.
+ * @since_tizen 3.0
+ * @param[out] radio_handle A newly returned handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_OUT_OF_MEMORY Out of memory
+ * @see radio_deinit()
+ */
+radio_error_t radio_init(void **radio_handle);
+
+/**
+ * @brief Deinitializes handle of camera HAL.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see radio_init()
+ */
+radio_error_t radio_deinit(void *radio_handle);
+
+/**
+ * @brief Prepare the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_DEVICE_NOT_OPENED The radio device is not opened
+ * @see radio_unprepare()
+ */
+radio_error_t radio_prepare(void *radio_handle);
+
+/**
+ * @brief Unprepare the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see radio_prepare()
+ */
+radio_error_t radio_unprepare(void *radio_handle);
+
+/**
+ * @brief Opens the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_DEVICE_NOT_FOUND Failed to find radio device
+ * @retval #RADIO_ERROR_DEVICE_NOT_OPENED The radio device is not opened
+ * @retval #RADIO_ERROR_PERMISSION_DENIED The access to the resources can not be granted.
+ * @retval #RADIO_ERROR_DEVICE_NOT_PREPARED Not prepared the radio device
+ * @see radio_close()
+ */
+radio_error_t radio_open(void *radio_handle);
+
+/**
+ * @brief Closes the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see radio_open()
+ */
+radio_error_t radio_close(void *radio_handle);
+
+/**
+ * @brief Starts the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see radio_stop()
+ */
+radio_error_t radio_start(void *radio_handle);
+
+/**
+ * @brief Stops the device of radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see radio_start()
+ */
+radio_error_t radio_stop(void *radio_handle);
+
+/**
+ * @brief Seeks (up or down) the effective frequency of the radio.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @param[in] direction The seek direction type (up or down)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_DEVICE_NOT_OPENED The radio device is not opened
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_seek(void *radio_handle, radio_seek_direction_type_t direction);
+
+/**
+ * @brief Gets the radio frequency.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @param[out] frequency The current frequency (khz)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_DEVICE_NOT_OPENED The radio device is not opened
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_get_frequency(void *radio_handle, uint32_t *frequency);
+
+/**
+ * @brief Sets the radio frequency.
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @param[in] frequency The frequency to set (khz)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_DEVICE_NOT_OPENED The radio device is not opened
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_set_frequency(void *radio_handle, uint32_t frequency);
+
+/**
+ * @brief Sets the radio's mute
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_mute(void *radio_handle);
+
+/**
+ * @brief Unsets the radio's mute
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_unmute(void *radio_handle);
+
+/**
+ * @brief Gets the current signal strength of the radio
+ * @since_tizen 3.0
+ * @param[in] radio_handle The handle to the radio HAL
+ * @param[out] strength The current signal strength (dBm)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #RADIO_ERROR_NONE Successful
+ * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation
+ */
+radio_error_t radio_get_signal_strength(void *radio_handle, uint32_t *strength);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_RADIO_HAL_H__ */
+
diff --git a/src/mm_radio.c b/src/mm_radio.c
index 2847ee6..5f8b495 100755..100644
--- a/src/mm_radio.c
+++ b/src/mm_radio.c
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio.c
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,11 +24,16 @@
========================================================================================== */
#include <string.h>
+#include <glib.h>
+#include <mm_types.h>
+#include <mm_message.h>
#include "mm_radio.h"
+#ifdef TIZEN_FEATURE_RADIO_HAL
+#include "mm_radio_priv_hal.h"
+#else
#include "mm_radio_priv.h"
+#endif
#include "mm_radio_utils.h"
-#include <mm_types.h>
-#include <mm_message.h>
#include "mm_debug.h"
/*===========================================================================================
diff --git a/src/mm_radio_audio_focus.c b/src/mm_radio_audio_focus.c
deleted file mode 100755
index 6e20751..0000000
--- a/src/mm_radio_audio_focus.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * libmm-radio
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
- *
- * 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.
- *
- */
-
-#include <assert.h>
-#include <mm_debug.h>
-#include "mm_radio_audio_focus.h"
-#include "mm_radio_utils.h"
-#include "mm_sound_focus.h"
-#include "unistd.h"
-
-int mmradio_audio_focus_register(MMRadioAudioFocus *sm, mm_sound_focus_changed_cb callback, void *param)
-{
- /* read mm-session information */
- int session_type = MM_SESSION_TYPE_MEDIA;
- int session_flags = 0;
- int errorcode = MM_ERROR_NONE;
- int pid = getpid();
- int handle;
-
- MMRADIO_LOG_FENTER();
-
- if (!sm) {
- MMRADIO_LOG_ERROR("invalid session handle\n");
- return MM_ERROR_RADIO_NOT_INITIALIZED;
- }
- sm->cur_focus_type = FOCUS_NONE;
-
- /* read session information */
- errorcode = _mm_session_util_read_information(pid, &session_type, &session_flags);
- if (errorcode == MM_ERROR_NONE) {
- debug_warning("Read Session Information success. session_type : %d flags: %d \n", session_type, session_flags);
- sm->snd_session_flags = session_flags;
- session_type = MM_SESSION_TYPE_MEDIA;
- } else {
- debug_warning("Read Session Information failed. skip sound focus register function. errorcode %x \n", errorcode);
- }
-
- /* check if it's MEDIA type */
- if (session_type != MM_SESSION_TYPE_MEDIA) {
- MMRADIO_LOG_DEBUG("session type is not MEDIA (%d)\n", session_type);
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- /* check if it's running on the media_server */
- sm->pid = pid;
-
- MMRADIO_LOG_DEBUG("sound register focus pid[%d]", pid);
-
- mm_sound_focus_get_id(&handle);
- sm->handle = handle;
-
- if (mm_sound_register_focus_for_session(handle, pid, "radio", callback, param) != MM_ERROR_NONE) {
- MMRADIO_LOG_DEBUG("mm_sound_register_focus_for_session is failed\n");
- return MM_ERROR_POLICY_BLOCKED;
- }
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int mmradio_audio_focus_deregister(MMRadioAudioFocus *sm)
-{
- MMRADIO_LOG_FENTER();
-
- if (!sm) {
- MMRADIO_LOG_ERROR("invalid session handle\n");
- return MM_ERROR_RADIO_NOT_INITIALIZED;
- }
-
- if (MM_ERROR_NONE != mm_sound_unregister_focus(sm->handle))
- MMRADIO_LOG_ERROR("mm_sound_unregister_focus failed\n");
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-int mmradio_acquire_audio_focus(MMRadioAudioFocus *sm)
-{
- int ret = MM_ERROR_NONE;
- mm_sound_focus_type_e focus_type = FOCUS_NONE;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_LOG_ERROR("mmradio_acquire_audio_focus sm->cur_focus_type : %d\n", sm->cur_focus_type);
-
- focus_type = FOCUS_FOR_BOTH & ~(sm->cur_focus_type);
- if (focus_type != FOCUS_NONE) {
- ret = mm_sound_acquire_focus(sm->handle, focus_type, NULL);
- if (ret != MM_ERROR_NONE) {
- MMRADIO_LOG_ERROR("mm_sound_acquire_focus is failed\n");
- return MM_ERROR_POLICY_BLOCKED;
- }
- sm->cur_focus_type = FOCUS_FOR_BOTH;
- }
-
- MMRADIO_LOG_FLEAVE();
- return ret;
-}
-
-int mmradio_release_audio_focus(MMRadioAudioFocus *sm)
-{
- int ret = MM_ERROR_NONE;
- MMRADIO_LOG_FENTER();
-
- MMRADIO_LOG_ERROR("mmradio_release_audio_focus sm->cur_focus_type : %d\n", sm->cur_focus_type);
- if (sm->cur_focus_type != FOCUS_NONE) {
- ret = mm_sound_release_focus(sm->handle, sm->cur_focus_type, NULL);
- if (ret != MM_ERROR_NONE) {
- MMRADIO_LOG_ERROR("mm_sound_release_focus is failed\n");
- return MM_ERROR_POLICY_BLOCKED;
- }
- sm->cur_focus_type = FOCUS_NONE;
- }
-
- MMRADIO_LOG_FLEAVE();
- return ret;
-}
-
-#define AUDIO_FOCUS_REASON_MAX 128
-
-void mmradio_get_audio_focus_reason(mm_sound_focus_state_e focus_state, const char *reason_for_change, enum MMMessageInterruptedCode *event_source, int *postMsg)
-{
- MMRADIO_LOG_FENTER();
- MMRADIO_LOG_ERROR("mmradio_get_audio_focus_reason focus_state : %d reason_for_change :%s\n", focus_state, reason_for_change);
-
- if (0 == strncmp(reason_for_change, "call-voice", AUDIO_FOCUS_REASON_MAX)
- || (0 == strncmp(reason_for_change, "voip", AUDIO_FOCUS_REASON_MAX))
- || (0 == strncmp(reason_for_change, "ringtone-voip", AUDIO_FOCUS_REASON_MAX))
- || (0 == strncmp(reason_for_change, "ringtone-call", AUDIO_FOCUS_REASON_MAX))
- ) {
- if (focus_state == FOCUS_IS_RELEASED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_START;
- else if (focus_state == FOCUS_IS_ACQUIRED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_END;
- *postMsg = true;
- } else if (0 == strncmp(reason_for_change, "alarm", AUDIO_FOCUS_REASON_MAX)) {
- if (focus_state == FOCUS_IS_RELEASED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_START;
- else if (focus_state == FOCUS_IS_ACQUIRED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_END;
- *postMsg = true;
- } else if (0 == strncmp(reason_for_change, "notification", AUDIO_FOCUS_REASON_MAX)) {
- if (focus_state == FOCUS_IS_RELEASED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START;
- else if (focus_state == FOCUS_IS_ACQUIRED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END;
- *postMsg = true;
- } else if (0 == strncmp(reason_for_change, "emergency", AUDIO_FOCUS_REASON_MAX)) {
- if (focus_state == FOCUS_IS_RELEASED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START;
- else if (focus_state == FOCUS_IS_ACQUIRED)
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END;
- *postMsg = false;
- } else if (0 == strncmp(reason_for_change, "media", AUDIO_FOCUS_REASON_MAX)) {
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
- *postMsg = false;
- } else {
- *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
- *postMsg = false;
- }
- MMRADIO_LOG_FLEAVE();
-}
diff --git a/src/mm_radio_priv_emulator.c b/src/mm_radio_priv_emulator.c
index d468ef3..e601266 100644
--- a/src/mm_radio_priv_emulator.c
+++ b/src/mm_radio_priv_emulator.c
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio_priv_emulator.c
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,9 +37,11 @@
#include <mm_message.h>
#include <time.h>
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
#include <mm_sound.h>
#include <mm_sound_focus.h>
#include <mm_sound_device.h>
+#endif
#include "mm_radio_priv.h"
@@ -136,11 +136,14 @@ static bool __is_tunable_frequency(mm_radio_t * radio, int freq);
static int __mmradio_set_deemphasis(mm_radio_t * radio);
static int __mmradio_set_band_range(mm_radio_t * radio);
static int __mmradio_get_wave_num(mm_radio_t * radio);
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
- mm_sound_focus_state_e focus_state, const char *reason_for_change,int option,
+ mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
const char *additional_info, void *user_data);
-static void __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data);
-
+static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
+ mm_sound_focus_state_e focus_state, const char *reason_for_change,
+ const char *additional_info, void *user_data);
+#endif
/*===========================================================================
FUNCTION DEFINITIONS
========================================================================== */
@@ -234,22 +237,19 @@ int _mmradio_create_radio(mm_radio_t * radio)
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
- /* add device conneted callback */
- ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
- (mm_sound_device_connected_cb)__mmradio_device_connected_cb,
- (void *)radio, &radio->subs_id);
- if (ret) {
- MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
- return MM_ERROR_RADIO_INTERNAL;
- }
-
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
/* register to audio focus */
- ret = mmradio_audio_focus_register(&radio->sm, __mmradio_sound_focus_cb, (void *)radio);
+ ret = mmradio_sound_focus_register(&radio->sound_focus,
+ (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb,
+ (mm_sound_focus_changed_watch_cb)__mmradio_sound_focus_watch_cb,
+ (void *)radio);
+
if (ret) {
/* NOTE : we are dealing it as an error since we cannot expect it's behavior */
MMRADIO_LOG_ERROR("mmradio_audio_focus_register is failed\n");
return MM_ERROR_RADIO_INTERNAL;
}
+#endif
MMRADIO_LOG_FLEAVE();
@@ -305,17 +305,6 @@ int _mmradio_realize(mm_radio_t * radio)
MMRADIO_LOG_FLEAVE();
return MM_ERROR_NONE;
-
-/* error:
- if (radio->radio_fd >= 0) {
- close(radio->radio_fd);
- radio->radio_fd = -1;
- }
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_RADIO_INTERNAL;
-*/
}
int _mmradio_unrealize(mm_radio_t * radio)
@@ -335,11 +324,15 @@ int _mmradio_unrealize(mm_radio_t * radio)
radio->radio_fd = -1;
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
- ret = mmradio_release_audio_focus(&radio->sm);
+
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ ret = mmradio_release_sound_focus(&radio->sound_focus);
if (ret) {
- MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed\n");
+ MMRADIO_LOG_ERROR("mmradio_release_sound_focus is failed\n");
return ret;
}
+#endif
+
#ifdef USE_GST_PIPELINE
ret = _mmradio_destroy_pipeline(radio);
if (ret) {
@@ -355,24 +348,21 @@ int _mmradio_unrealize(mm_radio_t * radio)
int _mmradio_destroy(mm_radio_t * radio)
{
- int ret = 0;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
- ret = mmradio_audio_focus_deregister(&radio->sm);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to deregister audio focus\n");
- return MM_ERROR_RADIO_INTERNAL;
- }
+ _mmradio_unrealize(radio);
- ret = mm_sound_remove_device_connected_callback(radio->subs_id);
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ int ret = 0;
+ ret = mmradio_sound_focus_deregister(&radio->sound_focus);
if (ret) {
- MMRADIO_LOG_ERROR("mm_sound_remove_device_connected_callback error %d\n", ret);
+ MMRADIO_LOG_ERROR("failed to deregister sound focus\n");
return MM_ERROR_RADIO_INTERNAL;
}
- _mmradio_unrealize(radio);
+#endif
MMRADIO_LOG_FLEAVE();
@@ -585,11 +575,15 @@ int _mmradio_start(mm_radio_t * radio)
MMRADIO_SLOG_DEBUG("now tune to frequency : %d\n", radio->freq);
- ret = mmradio_acquire_audio_focus(&radio->sm);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to set audio focus\n");
- return ret;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ if (radio->sound_focus.handle > 0) {
+ ret = mmradio_acquire_sound_focus(&radio->sound_focus);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("failed to set sound focus");
+ return ret;
+ }
}
+#endif
/* set stored frequency */
_mmradio_set_frequency(radio, radio->freq);
@@ -624,6 +618,16 @@ int _mmradio_stop(mm_radio_t * radio)
/* if( _mmradio_mute(radio) != MM_ERROR_NONE) */
/* return MM_ERROR_RADIO_NOT_INITIALIZED; */
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ if (radio->sound_focus.handle > 0) {
+ ret = mmradio_release_sound_focus(&radio->sound_focus);
+ if (ret) {
+ MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed\n");
+ return ret;
+ }
+ }
+#endif
+
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
#ifdef USE_GST_PIPELINE
@@ -1238,8 +1242,9 @@ static bool __mmradio_set_state(mm_radio_t * radio, int new_state)
msg.state.previous = radio->old_state;
msg.state.current = radio->current_state;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
/* post message to application */
- switch (radio->sm.by_focus_cb) {
+ switch (radio->sound_focus.by_focus_cb) {
case MMRADIO_FOCUS_CB_NONE:
{
msg_type = MM_MESSAGE_STATE_CHANGED;
@@ -1251,7 +1256,7 @@ static bool __mmradio_set_state(mm_radio_t * radio, int new_state)
{
msg_type = MM_MESSAGE_STATE_INTERRUPTED;
msg.union_type = MM_MSG_UNION_CODE;
- msg.code = radio->sm.event_src;
+ msg.code = radio->sound_focus.event_src;
MMRADIO_POST_MSG(radio, msg_type, &msg);
}
break;
@@ -1260,7 +1265,10 @@ static bool __mmradio_set_state(mm_radio_t * radio, int new_state)
default:
break;
}
-
+#else
+ msg_type = MM_MESSAGE_STATE_CHANGED;
+ MMRADIO_POST_MSG(radio, msg_type, &msg);
+#endif
MMRADIO_LOG_FLEAVE();
return true;
@@ -1276,11 +1284,12 @@ static int __mmradio_get_state(mm_radio_t * radio)
return radio->current_state;
}
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
const char *additional_info, void *user_data)
{
- mm_radio_t *radio = (mm_radio_t *) user_data;
+ mm_radio_t *radio = (mm_radio_t *)user_data;
enum MMMessageInterruptedCode event_source;
int result = MM_ERROR_NONE;
int postMsg = false;
@@ -1288,19 +1297,19 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
- radio->sm.event_src = event_source;
+ mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
+ radio->sound_focus.event_src = event_source;
switch (focus_state) {
case FOCUS_IS_RELEASED:{
- radio->sm.cur_focus_type &= ~focus_type;
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
+ radio->sound_focus.cur_focus_type &= ~focus_type;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
result = _mmradio_stop(radio);
if (result)
MMRADIO_LOG_ERROR("failed to stop radio\n");
- MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sm.cur_focus_type);
+ MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
break;
@@ -1309,14 +1318,14 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
msg.union_type = MM_MSG_UNION_CODE;
msg.code = event_source;
- radio->sm.cur_focus_type |= focus_type;
+ radio->sound_focus.cur_focus_type |= focus_type;
- if ((postMsg) && (FOCUS_FOR_BOTH == radio->sm.cur_focus_type))
+ if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
- MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sm.cur_focus_type);
+ MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
break;
@@ -1328,40 +1337,58 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
MMRADIO_LOG_FLEAVE();
}
-static void __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data)
+static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
+ mm_sound_focus_state_e focus_state, const char *reason_for_change,
+ const char *additional_info, void *user_data)
{
- mm_radio_t *radio = (mm_radio_t *) user_data;
+ mm_radio_t *radio = (mm_radio_t *)user_data;
+ enum MMMessageInterruptedCode event_source;
int result = MM_ERROR_NONE;
- mm_sound_device_type_e type;
+ int postMsg = false;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- if (mm_sound_get_device_type(device, &type) != MM_ERROR_NONE) {
- debug_error("getting device type failed");
- } else {
- switch (type) {
- case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
- case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
- case MM_SOUND_DEVICE_TYPE_HDMI:
- case MM_SOUND_DEVICE_TYPE_MIRRORING:
- case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
- if (!is_connected) {
- MMRADIO_LOG_ERROR("sound device unplugged");
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
- radio->sm.event_src = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG;
-
- result = _mmradio_stop(radio);
- if (result != MM_ERROR_NONE)
- MMRADIO_LOG_ERROR("failed to stop radio\n");
- }
- break;
- default:
- break;
+ mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
+ radio->sound_focus.event_src = event_source;
+
+ switch (focus_state) {
+ case FOCUS_IS_ACQUIRED: {
+ radio->sound_focus.cur_focus_type &= ~focus_type;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
+
+ result = _mmradio_stop(radio);
+ if (result)
+ MMRADIO_LOG_ERROR("failed to stop radio\n");
+
+ MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
+ break;
+
+ case FOCUS_IS_RELEASED: {
+ MMMessageParamType msg = { 0, };
+ msg.union_type = MM_MSG_UNION_CODE;
+ msg.code = event_source;
+
+ radio->sound_focus.cur_focus_type |= focus_type;
+
+ if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
+ MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
+
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
+
+ MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
+ }
+ break;
+
+ default:
+ MMRADIO_LOG_DEBUG("Unknown focus_state\n");
+ break;
}
+
MMRADIO_LOG_FLEAVE();
}
+#endif
int _mmradio_get_region_type(mm_radio_t * radio, MMRadioRegionType * type)
{
diff --git a/src/mm_radio_priv.c b/src/mm_radio_priv_hal.c
index 4ba943c..6ac3757 100755..100644
--- a/src/mm_radio_priv.c
+++ b/src/mm_radio_priv_hal.c
@@ -1,9 +1,7 @@
/*
- * libmm-radio
+ * mm_radio_priv_hal.c
*
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,11 +36,7 @@
#include <mm_debug.h>
#include <mm_message.h>
-#include <mm_sound.h>
-#include <mm_sound_focus.h>
-#include <mm_sound_device.h>
-
-#include "mm_radio_priv.h"
+#include "mm_radio_priv_hal.h"
/*===========================================================================================
LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
@@ -123,28 +117,20 @@ static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype
static int __mmradio_check_state(mm_radio_t *radio, MMRadioCommand command);
static int __mmradio_get_state(mm_radio_t *radio);
static bool __mmradio_set_state(mm_radio_t *radio, int new_state);
+void _mmradio_seek_cancel(mm_radio_t *radio);
static void __mmradio_seek_thread(mm_radio_t *radio);
static void __mmradio_scan_thread(mm_radio_t *radio);
static bool __is_tunable_frequency(mm_radio_t *radio, int freq);
-static int __mmradio_set_deemphasis(mm_radio_t *radio);
-static int __mmradio_set_band_range(mm_radio_t *radio);
+
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
const char *additional_info, void *user_data);
-static void __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data);
-
-/*===========================================================================
- FUNCTION DEFINITIONS
-========================================================================== */
-/* --------------------------------------------------------------------------
- * Name : _mmradio_apply_region()
- * Desc : update radio region information and set values to device
- * Param :
- * [in] radio : radio handle
- * [in] region : region type
- * [in] update : update region values or not
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
+static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
+ mm_sound_focus_state_e focus_state, const char *reason_for_change,
+ const char *additional_info, void *user_data);
+#endif
+
int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool update)
{
int ret = MM_ERROR_NONE;
@@ -177,26 +163,10 @@ int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool upda
}
}
- /* chech device is opened or not. if it's not ready, skip to apply region to device now */
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_DEBUG("not opened device. just updating region info. \n");
- return MM_ERROR_NONE;
- }
-
MMRADIO_LOG_DEBUG("setting region - country: %d, de-emphasis: %d, band range: %d ~ %d KHz\n",
radio->region_setting.country, radio->region_setting.deemphasis,
radio->region_setting.band_min, radio->region_setting.band_max);
- /* set de-emphsasis to device */
- ret = __mmradio_set_deemphasis(radio);
-
- MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set de-emphasis");
-
- /* set band range to device */
- ret = __mmradio_set_band_range(radio);
-
- MMRADIO_CHECK_RETURN_IF_FAIL(ret, "set band range");
-
MMRADIO_LOG_FLEAVE();
return ret;
@@ -204,7 +174,7 @@ int _mmradio_apply_region(mm_radio_t *radio, MMRadioRegionType region, bool upda
int _mmradio_create_radio(mm_radio_t *radio)
{
- int ret = 0;
+ int ret = MM_ERROR_NONE;
MMRADIO_LOG_FENTER();
@@ -212,10 +182,11 @@ int _mmradio_create_radio(mm_radio_t *radio)
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_CREATE);
/* set default value */
- radio->radio_fd = -1;
radio->freq = DEFAULT_FREQ;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ memset(&radio->sound_focus, 0, sizeof(mm_radio_sound_focus));
+#endif
memset(&radio->region_setting, 0, sizeof(MMRadioRegion_t));
- radio->subs_id = 0;
/* create command lock */
ret = pthread_mutex_init(&radio->cmd_lock, NULL);
@@ -226,22 +197,24 @@ int _mmradio_create_radio(mm_radio_t *radio)
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
- /* add device conneted callback */
- ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_STATE_ACTIVATED_FLAG,
- (mm_sound_device_connected_cb)__mmradio_device_connected_cb,
- (void *)radio, &radio->subs_id);
- if (ret) {
- MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
- return MM_ERROR_RADIO_INTERNAL;
- }
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ ret = mmradio_sound_focus_register(&radio->sound_focus,
+ (mm_sound_focus_changed_cb)__mmradio_sound_focus_cb,
+ (mm_sound_focus_changed_watch_cb)__mmradio_sound_focus_watch_cb,
+ (void *)radio);
- /* register to audio focus */
- ret = mmradio_audio_focus_register(&radio->sm, __mmradio_sound_focus_cb, (void *)radio);
if (ret) {
/* NOTE : we are dealing it as an error since we cannot expect it's behavior */
MMRADIO_LOG_ERROR("mmradio_audio_focus_register is failed\n");
return MM_ERROR_RADIO_INTERNAL;
}
+#endif
+
+ ret = radio_hal_interface_init(&(radio->hal_inf));
+ if (ret) {
+ MMRADIO_LOG_ERROR("mmradio hal interface init failed\n");
+ return ret;
+ }
MMRADIO_LOG_FLEAVE();
@@ -251,101 +224,49 @@ int _mmradio_create_radio(mm_radio_t *radio)
int _mmradio_realize(mm_radio_t *radio)
{
int ret = MM_ERROR_NONE;
- char str_error[READ_MAX_BUFFER_SIZE];
+ bool update = false;
+ MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_REALIZE);
- /* open radio device */
- if (radio->radio_fd == -1) {
- MMRadioRegionType region = MM_RADIO_REGION_GROUP_NONE;
- bool update = false;
-
- /* open device */
- radio->radio_fd = open(DEFAULT_DEVICE, O_RDONLY);
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_ERROR("failed to open radio device[%s] because of %s(%d)\n",
- DEFAULT_DEVICE, strerror_r(errno, str_error, sizeof(str_error)), errno);
-
- /* check error */
- switch (errno) {
- case ENOENT:
- return MM_ERROR_RADIO_DEVICE_NOT_FOUND;
- case EACCES:
- return MM_ERROR_RADIO_PERMISSION_DENIED;
- default:
- return MM_ERROR_RADIO_DEVICE_NOT_OPENED;
- }
- }
- MMRADIO_LOG_DEBUG("radio device fd : %d\n", radio->radio_fd);
-
- /* query radio device capabilities. */
- if (ioctl(radio->radio_fd, VIDIOC_QUERYCAP, &(radio->vc)) < 0) {
- MMRADIO_LOG_ERROR("VIDIOC_QUERYCAP failed!\n");
- goto error;
- }
-
- if (!(radio->vc.capabilities & V4L2_CAP_TUNER)) {
- MMRADIO_LOG_ERROR("this system can't support fm-radio!\n");
- goto error;
- }
-
- /* set tuner audio mode */
- ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt));
-
- if (!((radio->vt).capability & V4L2_TUNER_CAP_STEREO)) {
- MMRADIO_LOG_ERROR("this system can support mono!\n");
- (radio->vt).audmode = V4L2_TUNER_MODE_MONO;
- } else {
- (radio->vt).audmode = V4L2_TUNER_MODE_STEREO;
- }
-
- /* set tuner index. Must be 0. */
- (radio->vt).index = TUNER_INDEX;
- ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt));
-
- /* check region country type if it's updated or not */
- if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
- /* not initialized yet. set it with default region */
- region = RADIO_DEFAULT_REGION;
- update = true;
- } else {
- /* already initialized by application */
- region = radio->region_setting.country;
- }
-
- ret = _mmradio_apply_region(radio, region, update);
+ ret = pthread_mutex_init(&radio->seek_cancel_mutex, NULL);
+ if (ret < 0) {
+ MMRADIO_LOG_DEBUG("Mutex creation failed %d", ret);
+ }
- MMRADIO_CHECK_RETURN_IF_FAIL(ret, "update region info");
+ if (radio->region_setting.country == MM_RADIO_REGION_GROUP_NONE) {
+ /* not initialized yet. set it with default region */
+ region = RADIO_DEFAULT_REGION;
+ update = true;
+ } else {
+ /* already initialized by application */
+ region = radio->region_setting.country;
}
- /* ready but nosound */
- if (_mmradio_mute(radio) != MM_ERROR_NONE)
- goto error;
+ ret = _mmradio_apply_region(radio, region, update);
- MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
-#ifdef USE_GST_PIPELINE
- ret = _mmradio_realize_pipeline(radio);
- if (ret) {
- debug_error("_mmradio_realize_pipeline is failed\n");
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_RADIO, NULL, radio, &radio->stream_info);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("sound_manager_create_stream_information_internal error");
+ MMRADIO_LOG_FLEAVE();
return ret;
}
-#endif
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-
-error:
- if (radio->radio_fd >= 0) {
- close(radio->radio_fd);
- radio->radio_fd = -1;
+ ret = sound_manager_create_virtual_stream(radio->stream_info, &radio->vstream);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("sound_manager_create_virtual_stream error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
}
+#endif
+ MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
MMRADIO_LOG_FLEAVE();
- return MM_ERROR_RADIO_INTERNAL;
+ return MM_ERROR_NONE;
}
int _mmradio_unrealize(mm_radio_t *radio)
@@ -357,29 +278,31 @@ int _mmradio_unrealize(mm_radio_t *radio)
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNREALIZE);
- if (_mmradio_mute(radio) != MM_ERROR_NONE)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
-
- /* close radio device here !!!! */
- if (radio->radio_fd >= 0) {
- close(radio->radio_fd);
- radio->radio_fd = -1;
+ ret = radio_hal_unmute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_unmute error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
}
- MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
+ /*Finish if there are scans*/
+ _mmradio_stop_scan(radio);
- ret = mmradio_release_audio_focus(&radio->sm);
- if (ret) {
- MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed\n");
- return ret;
- }
-#ifdef USE_GST_PIPELINE
- ret = _mmradio_destroy_pipeline(radio);
- if (ret) {
- debug_error("_mmradio_destroy_pipeline is failed\n");
- return ret;
- }
+ /*Stop radio if started*/
+ _mmradio_stop(radio);
+
+ /* close radio device here !!!! */
+ radio_hal_close(radio->hal_inf);
+ radio_hal_unprepare(radio->hal_inf);
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ sound_manager_destroy_virtual_stream(radio->vstream);
+ sound_manager_destroy_stream_information(radio->stream_info);
#endif
+ pthread_mutex_destroy(&radio->seek_cancel_mutex);
+
+ MMRADIO_SET_STATE(radio, MM_RADIO_STATE_NULL);
MMRADIO_LOG_FLEAVE();
@@ -388,25 +311,26 @@ int _mmradio_unrealize(mm_radio_t *radio)
int _mmradio_destroy(mm_radio_t *radio)
{
- int ret = 0;
+ int ret = MM_ERROR_NONE;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_DESTROY);
- ret = mmradio_audio_focus_deregister(&radio->sm);
+ _mmradio_unrealize(radio);
+
+ ret = radio_hal_interface_deinit(radio->hal_inf);
if (ret) {
- MMRADIO_LOG_ERROR("failed to deregister audio focus\n");
- return MM_ERROR_RADIO_INTERNAL;
+ MMRADIO_LOG_ERROR("mmradio hal interface deinit failed\n");
+ return ret;
}
-
- ret = mm_sound_remove_device_connected_callback(radio->subs_id);
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ ret = mmradio_sound_focus_deregister(&radio->sound_focus);
if (ret) {
- MMRADIO_LOG_ERROR("mm_sound_remove_device_connected_callback error %d\n", ret);
+ MMRADIO_LOG_ERROR("failed to deregister sound focus\n");
return MM_ERROR_RADIO_INTERNAL;
}
- _mmradio_unrealize(radio);
-
+#endif
MMRADIO_LOG_FLEAVE();
return MM_ERROR_NONE;
@@ -415,6 +339,8 @@ int _mmradio_destroy(mm_radio_t *radio)
/* unit should be KHz */
int _mmradio_set_frequency(mm_radio_t *radio, int freq)
{
+ int ret = MM_ERROR_NONE;
+
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
@@ -424,33 +350,23 @@ int _mmradio_set_frequency(mm_radio_t *radio, int freq)
radio->freq = freq;
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_DEBUG("radio device is not opened yet\n");
- return MM_ERROR_NONE;
- }
-
- /* check frequency range */
- if (freq < radio->region_setting.band_min || freq > radio->region_setting.band_max) {
- MMRADIO_LOG_ERROR("out of frequency range\n", freq);
- return MM_ERROR_INVALID_ARGUMENT;
+ ret = radio_hal_set_frequency(radio->hal_inf, freq);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
}
- /* set it */
- (radio->vf).tuner = 0;
- (radio->vf).frequency = RADIO_FREQ_FORMAT_SET(freq);
-
- if (ioctl(radio->radio_fd, VIDIOC_S_FREQUENCY, &(radio->vf)) < 0)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
-
MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
+ return ret;
}
int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
{
- int freq = 0;
+ int ret = MM_ERROR_NONE;
+ uint32_t freq = 0;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
@@ -458,146 +374,68 @@ int _mmradio_get_frequency(mm_radio_t *radio, int *pFreq)
return_val_if_fail(pFreq, MM_ERROR_INVALID_ARGUMENT);
- /* just return stored frequency if radio device is not ready */
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_DEBUG("freq : %d\n", radio->freq);
- *pFreq = radio->freq;
- return MM_ERROR_NONE;
- }
-
- if (ioctl(radio->radio_fd, VIDIOC_G_FREQUENCY, &(radio->vf)) < 0) {
- MMRADIO_LOG_ERROR("failed to do VIDIOC_G_FREQUENCY\n");
- return MM_ERROR_RADIO_INTERNAL;
+ ret = radio_hal_get_frequency(radio->hal_inf, &freq);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_get_frequency error");
+ *pFreq = 0;
+ return ret;
}
- freq = RADIO_FREQ_FORMAT_GET((radio->vf).frequency);
-
/* update freq in handle */
radio->freq = freq;
- *pFreq = radio->freq;
+ *pFreq = (int)radio->freq;
MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
+ return ret;
}
int _mmradio_mute(mm_radio_t *radio)
{
+ int ret = MM_ERROR_NONE;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_MUTE);
- if (radio->radio_fd < 0)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
-
- (radio->vctrl).id = V4L2_CID_AUDIO_MUTE;
- /* mute */
- (radio->vctrl).value = 1;
-
- if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ ret = radio_hal_mute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_mute error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
+ }
+ radio->is_muted = TRUE;
MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-
+ return ret;
}
int _mmradio_unmute(mm_radio_t *radio)
{
+ int ret = MM_ERROR_NONE;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_UNMUTE);
- MMRADIO_CHECK_DEVICE_STATE(radio);
- (radio->vctrl).id = V4L2_CID_AUDIO_MUTE;
- /* unmute */
- (radio->vctrl).value = 0;
-
- if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
-}
-
-/* --------------------------------------------------------------------------
- * Name : __mmradio_set_deemphasis
- * Desc : apply de-emphasis value to device
- * Param :
- * [in] radio : radio handle
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
-int __mmradio_set_deemphasis(mm_radio_t *radio)
-{
- int value = 0;
-
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- /* get de-emphasis */
- switch (radio->region_setting.deemphasis) {
- case MM_RADIO_DEEMPHASIS_50_US:
- /* V4L2_DEEMPHASIS_50_uS; */
- value = 1;
- break;
-
- case MM_RADIO_DEEMPHASIS_75_US:
- /* V4L2_DEEMPHASIS_75_uS; */
- value = 2;
- break;
-
- default:
- MMRADIO_LOG_ERROR("not availabe de-emphasis value\n");
- return MM_ERROR_COMMON_INVALID_ARGUMENT;
+ ret = radio_hal_unmute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_unmute error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
}
- /* set it to device */
- /* V4L2_CID_TUNE_DEEMPHASIS; */
- (radio->vctrl).id = (0x009d0000 | 0x900) + 1;
- (radio->vctrl).value = value;
-
- if (ioctl(radio->radio_fd, VIDIOC_S_CTRL, &(radio->vctrl)) < 0) {
- MMRADIO_LOG_ERROR("failed to set de-emphasis\n");
- return MM_ERROR_RADIO_INTERNAL;
- }
+ radio->is_muted = FALSE;
MMRADIO_LOG_FLEAVE();
- return MM_ERROR_NONE;
-}
-
-/* --------------------------------------------------------------------------
- * Name : __mmradio_set_band_range
- * Desc : apply max and min frequency to device
- * Param :
- * [in] radio : radio handle
- * Return : zero on success, or negative value with error code
- *---------------------------------------------------------------------------*/
-int __mmradio_set_band_range(mm_radio_t *radio)
-{
- MMRADIO_LOG_FENTER();
-
- MMRADIO_CHECK_INSTANCE(radio);
-
- /* get min and max freq. */
- (radio->vt).rangelow = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_min);
- (radio->vt).rangehigh = RADIO_FREQ_FORMAT_SET(radio->region_setting.band_max);
-
- /* set it to device */
- if (ioctl(radio->radio_fd, VIDIOC_S_TUNER, &(radio->vt)) < 0) {
- MMRADIO_LOG_ERROR("failed to set band range\n");
- return MM_ERROR_RADIO_INTERNAL;
- }
-
- MMRADIO_LOG_FLEAVE();
-
- return MM_ERROR_NONE;
+ return ret;
}
int _mmradio_set_message_callback(mm_radio_t *radio, MMMessageCallback callback, void *user_param)
@@ -645,30 +483,72 @@ int _mmradio_start(mm_radio_t *radio)
MMRADIO_LOG_DEBUG("now tune to frequency : %d\n", radio->freq);
- ret = mmradio_acquire_audio_focus(&radio->sm);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to set audio focus\n");
- return ret;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ if (radio->sound_focus.handle > 0) {
+ ret = mmradio_acquire_sound_focus(&radio->sound_focus);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("failed to set sound focus");
+ return ret;
+ }
}
+#endif
- /* set stored frequency */
- _mmradio_set_frequency(radio, radio->freq);
+ if (!radio->is_ready) {
+ ret = radio_hal_prepare(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
+ goto error;
+ }
- /* unmute */
- if (_mmradio_unmute(radio) != MM_ERROR_NONE)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ ret = radio_hal_open(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_open is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_init error");
+ goto error;
+ }
+ radio->is_ready = TRUE;
+ } else {
+ MMRADIO_LOG_DEBUG("radio prepared and opened");
+ }
- MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
-#ifdef USE_GST_PIPELINE
- ret = _mmradio_start_pipeline(radio);
+ ret = radio_hal_start(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_start is not supported");
+ } else if (ret) {
+ MMRADIO_LOG_ERROR("failed to radio_hal_start\n");
+ goto error;
+ }
+
+ /* set stored frequency */
+ ret = radio_hal_set_frequency(radio->hal_inf, radio->freq);
if (ret) {
- debug_error("_mmradio_start_pipeline is failed\n");
- return ret;
+ MMRADIO_LOG_ERROR("failed to radio_hal_set_frequency\n");
+ goto error;
+ }
+
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ ret = sound_manager_start_virtual_stream(radio->vstream);
+ if (ret) {
+ MMRADIO_LOG_ERROR("failed to sound_manager_start_virtual_stream\n");
+ goto error;
}
#endif
+ MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
+
MMRADIO_LOG_FLEAVE();
+ return MM_ERROR_NONE;
+
+error:
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ sound_manager_stop_virtual_stream(radio->vstream);
+#endif
+ radio_hal_close(radio->hal_inf);
+ radio_hal_unprepare(radio->hal_inf);
return ret;
}
@@ -681,147 +561,90 @@ int _mmradio_stop(mm_radio_t *radio)
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_STOP);
- if (_mmradio_mute(radio) != MM_ERROR_NONE)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
-
- MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
-
-#ifdef USE_GST_PIPELINE
- ret = _mmradio_stop_pipeline(radio);
- if (ret) {
- debug_error("_mmradio_stop_pipeline is failed\n");
- return ret;
- }
+ radio->seek_unmute = FALSE;
+ /*cancel if any seek*/
+ _mmradio_seek_cancel(radio);
+#ifdef TIZEN_FEATURE_SOUND_VSTREAM
+ ret = sound_manager_stop_virtual_stream(radio->vstream);
#endif
-
- MMRADIO_LOG_FLEAVE();
-
- return ret;
-}
-
-#ifdef USE_GST_PIPELINE
-int _mmradio_realize_pipeline(mm_radio_t *radio)
-{
- int ret = MM_ERROR_NONE;
-
- gst_init(NULL, NULL);
- radio->pGstreamer_s = g_new0(mm_radio_gstreamer_s, 1);
-
- radio->pGstreamer_s->pipeline = gst_pipeline_new("fmradio");
-
- radio->pGstreamer_s->audiosrc = gst_element_factory_make("pulsesrc", "fm audio src");
- radio->pGstreamer_s->queue2 = gst_element_factory_make("queue2", "queue2");
- radio->pGstreamer_s->audiosink = gst_element_factory_make("pulsesink", "audio sink");
-
- /* g_object_set(radio->pGstreamer_s->audiosrc, "latency", 2, NULL); */
- g_object_set(radio->pGstreamer_s->audiosink, "sync", false, NULL);
-
- if (!radio->pGstreamer_s->pipeline || !radio->pGstreamer_s->audiosrc ||
- !radio->pGstreamer_s->queue2 || !radio->pGstreamer_s->audiosink) {
- debug_error("[%s][%05d] One element could not be created. Exiting.\n", __func__, __LINE__);
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ ret = radio_hal_mute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret) {
+ MMRADIO_LOG_ERROR("failed to radio_hal_mute\n");
+ return ret;
}
- gst_bin_add_many(GST_BIN(radio->pGstreamer_s->pipeline),
- radio->pGstreamer_s->audiosrc, radio->pGstreamer_s->queue2,
- radio->pGstreamer_s->audiosink, NULL);
- if (!gst_element_link_many(radio->pGstreamer_s->audiosrc,
- radio->pGstreamer_s->queue2, radio->pGstreamer_s->audiosink, NULL)) {
- debug_error("[%s][%05d] Fail to link b/w appsrc and ffmpeg in rotate\n", __func__, __LINE__);
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ ret = radio_hal_stop(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret) {
+ MMRADIO_LOG_ERROR("failed to radio_hal_stop\n");
+ return ret;
}
- return ret;
-}
-int _mmradio_start_pipeline(mm_radio_t *radio)
-{
- int ret = MM_ERROR_NONE;
- GstStateChangeReturn ret_state;
- debug_log("\n");
-
- if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
- debug_error("Fail to change pipeline state");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
+ /* close radio device here !!!! */
+ ret = radio_hal_close(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_close is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_close_device error");
+ return ret;
}
-
- ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
- if (ret_state == GST_STATE_CHANGE_FAILURE) {
- debug_error("GST_STATE_CHANGE_FAILURE");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
- } else {
- debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
+ ret = radio_hal_unprepare(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_close_device error");
+ return ret;
}
- return ret;
-}
-int _mmradio_stop_pipeline(mm_radio_t *radio)
-{
- int ret = MM_ERROR_NONE;
- GstStateChangeReturn ret_state;
-
- debug_log("\n");
- if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
- debug_error("Fail to change pipeline state");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
- }
+ radio->is_ready = FALSE;
- ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
- if (ret_state == GST_STATE_CHANGE_FAILURE) {
- debug_error("GST_STATE_CHANGE_FAILURE");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
- } else {
- debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
+ if (radio->sound_focus.handle > 0) {
+ ret = mmradio_release_sound_focus(&radio->sound_focus);
+ if (ret) {
+ MMRADIO_LOG_ERROR("mmradio_release_audio_focus is failed\n");
+ return ret;
+ }
}
- return ret;
-}
+#endif
+ MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
-int _mmradio_destroy_pipeline(mm_radio_t *radio)
-{
- int ret = 0;
- GstStateChangeReturn ret_state;
- debug_log("\n");
-
- if (gst_element_set_state(radio->pGstreamer_s->pipeline, GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE) {
- debug_error("Fail to change pipeline state");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
- }
+ MMRADIO_LOG_FLEAVE();
- ret_state = gst_element_get_state(radio->pGstreamer_s->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
- if (ret_state == GST_STATE_CHANGE_FAILURE) {
- debug_error("GST_STATE_CHANGE_FAILURE");
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return MM_ERROR_RADIO_INVALID_STATE;
- } else {
- debug_log("[%s][%05d] GST_STATE_NULL ret_state = %d (GST_STATE_CHANGE_SUCCESS)\n", __func__, __LINE__, ret_state);
- }
- gst_object_unref(radio->pGstreamer_s->pipeline);
- g_free(radio->pGstreamer_s);
- return ret;
+ return MM_ERROR_NONE;
}
-#endif
int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
{
+ int ret = MM_ERROR_NONE;
+
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
MMRADIO_CHECK_STATE_RETURN_IF_FAIL(radio, MMRADIO_COMMAND_SEEK);
- int ret = 0;
+ if (radio->is_seeking) {
+ MMRADIO_LOG_ERROR("[RADIO_ERROR_INVALID_OPERATION]radio is seeking, can't serve another request try again");
+ return MM_ERROR_RADIO_INTERNAL;
+ }
- if (_mmradio_mute(radio) != MM_ERROR_NONE)
- return MM_ERROR_RADIO_NOT_INITIALIZED;
+ radio->seek_unmute = FALSE;
+ radio->is_seeking = TRUE;
+ radio->seek_cancel = FALSE;
+
+ if (!radio->is_muted) {
+ ret = radio_hal_mute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
+ } else if (ret) {
+ MMRADIO_LOG_ERROR("failed to radio_hal_mute\n");
+ return ret;
+ }
+ radio->seek_unmute = TRUE;
+ }
MMRADIO_LOG_DEBUG("trying to seek. direction[0:UP/1:DOWN) %d\n", direction);
radio->seek_direction = direction;
@@ -830,6 +653,18 @@ int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
if (ret) {
MMRADIO_LOG_DEBUG("failed create thread\n");
+ radio->is_seeking = FALSE;
+ radio->seek_cancel = TRUE;
+ if (radio->seek_unmute) {
+ ret = radio_hal_mute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
+ } else if (ret) {
+ MMRADIO_LOG_ERROR("failed to radio_hal_mute\n");
+ radio->seek_unmute = FALSE;
+ return ret;
+ }
+ }
return MM_ERROR_RADIO_INTERNAL;
}
@@ -838,8 +673,41 @@ int _mmradio_seek(mm_radio_t *radio, MMRadioSeekDirectionType direction)
return MM_ERROR_NONE;
}
+void _mmradio_seek_cancel(mm_radio_t *radio)
+{
+ int ret = MM_ERROR_NONE;
+ char str_error[READ_MAX_BUFFER_SIZE];
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
+
+ /*cancel any outstanding seek request*/
+ radio->seek_cancel = TRUE;
+ if (radio->seek_thread) {
+ ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
+ MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
+ if (ret == EBUSY) { /* it was already locked by other */
+ MMRADIO_LOG_DEBUG("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
+ } else if (ret == 0) {
+ MMRADIO_LOG_DEBUG("trylock is successful. unlock now");
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+ } else {
+ MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
+ }
+ MMRADIO_LOG_DEBUG("pthread_join seek_thread");
+ pthread_join(radio->seek_thread, NULL);
+ MMRADIO_LOG_DEBUG("done");
+ radio->is_seeking = FALSE;
+ radio->seek_thread = 0;
+ }
+ MMRADIO_LOG_FLEAVE();
+}
+
+
int _mmradio_start_scan(mm_radio_t *radio)
{
+ int ret = MM_ERROR_NONE;
+
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
@@ -849,6 +717,28 @@ int _mmradio_start_scan(mm_radio_t *radio)
radio->stop_scan = false;
+ if (!radio->is_ready) {
+ ret = radio_hal_prepare(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_prepare is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_prepare_device error");
+ return ret;
+ }
+
+ ret = radio_hal_open(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_open is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_init error");
+ MMRADIO_LOG_FLEAVE();
+ return ret;
+ }
+ radio->is_ready = TRUE;
+ } else {
+ MMRADIO_LOG_DEBUG("radio prepared and opened");
+ }
+
scan_tr_id = pthread_create(&radio->scan_thread, NULL, (void *)__mmradio_scan_thread, (void *)radio);
if (scan_tr_id != 0) {
@@ -865,6 +755,8 @@ int _mmradio_start_scan(mm_radio_t *radio)
int _mmradio_stop_scan(mm_radio_t *radio)
{
+ int ret = 0;
+ char str_error[READ_MAX_BUFFER_SIZE];
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
@@ -873,6 +765,18 @@ int _mmradio_stop_scan(mm_radio_t *radio)
radio->stop_scan = true;
if (radio->scan_thread > 0) {
+ /* make sure all the search is stopped else we'll wait till search finish which is not ideal*/
+ ret = pthread_mutex_trylock(&radio->seek_cancel_mutex);
+ MMRADIO_LOG_DEBUG("try lock ret: %s (%d)", strerror_r(ret, str_error, sizeof(str_error)), ret);
+ if (ret == EBUSY) { /* it was already locked by other */
+ MMRADIO_LOG_DEBUG("send SEEK ABORT with FMRX_PROPERTY_SEARCH_ABORT");
+ } else if (ret == 0) {
+ MMRADIO_LOG_DEBUG("trylock is successful. unlock now");
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+ } else {
+ MMRADIO_LOG_ERROR("trylock is failed but Not EBUSY. ret: %d", ret);
+ }
+ MMRADIO_LOG_DEBUG("pthread_join scan_thread");
pthread_cancel(radio->scan_thread);
pthread_join(radio->scan_thread, NULL);
radio->scan_thread = 0;
@@ -888,76 +792,81 @@ int _mmradio_stop_scan(mm_radio_t *radio)
int _mm_radio_get_signal_strength(mm_radio_t *radio, int *value)
{
+ int ret = MM_ERROR_NONE;
+ uint32_t strength = 0;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE(radio);
return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
/* just return stored frequency if radio device is not ready */
- if (radio->radio_fd < 0) {
- MMRADIO_LOG_DEBUG("Device not ready so sending 0\n");
+ ret = radio_hal_get_signal_strength(radio->hal_inf, &strength);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ debug_error("radio_hal_get_signal_strength error\n");
*value = 0;
- return MM_ERROR_NONE;
- }
- if (ioctl(radio->radio_fd, VIDIOC_G_TUNER, &(radio->vt)) < 0) {
- debug_error("ioctl VIDIOC_G_TUNER error\n");
- return MM_ERROR_RADIO_INTERNAL;
+ MMRADIO_LOG_FLEAVE();
+ return ret;
}
- *value = radio->vt.signal;
+ *value = (int)strength;
MMRADIO_LOG_FLEAVE();
return MM_ERROR_NONE;
}
void __mmradio_scan_thread(mm_radio_t *radio)
{
- int ret = 0;
+ int ret = MM_ERROR_NONE;
int prev_freq = 0;
- char str_error[READ_MAX_BUFFER_SIZE];
-
- struct v4l2_hw_freq_seek vs = { 0, };
- vs.tuner = TUNER_INDEX;
- vs.type = V4L2_TUNER_RADIO;
- vs.wrap_around = 0; /* around:1 not around:0 */
- vs.seek_upward = 1; /* up : 1 ------- down : 0 */
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- if (_mmradio_mute(radio) != MM_ERROR_NONE)
+
+ ret = radio_hal_mute(radio->hal_inf);
+
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_mute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_mute error");
goto FINISHED;
+ }
+ ret = radio_hal_set_frequency(radio->hal_inf, radio->region_setting.band_min);
- if (_mmradio_set_frequency(radio, radio->region_setting.band_min) != MM_ERROR_NONE)
+ if (ret != MM_ERROR_NONE)
goto FINISHED;
MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_START, NULL);
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_SCANNING);
while (!radio->stop_scan) {
- int freq = 0;
+ uint32_t freq = 0;
MMMessageParamType param = { 0, };
MMRADIO_LOG_DEBUG("scanning....\n");
- ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs);
- if (ret == -1) {
- if (errno == EAGAIN) {
- MMRADIO_LOG_ERROR("scanning timeout\n");
- continue;
- } else if (errno == EINVAL) {
- MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong.");
- break;
- } else {
- MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno);
- break;
- }
+ pthread_mutex_lock(&radio->seek_cancel_mutex);
+
+ if (radio->stop_scan) {
+ MMRADIO_LOG_DEBUG("scan was canceled");
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+ goto FINISHED;
}
- /* now we can get new frequency from radio device */
+ ret = radio_hal_seek(radio->hal_inf, MM_RADIO_SEEK_UP);
+
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio scanning error");
+ break;
+ }
+ /* now we can get new frequency from radio device */
if (radio->stop_scan)
break;
- ret = _mmradio_get_frequency(radio, &freq);
- if (ret) {
+ ret = radio_hal_get_frequency(radio->hal_inf, &freq);
+ if (ret != MM_ERROR_NONE) {
MMRADIO_LOG_ERROR("failed to get current frequency\n");
} else {
if (freq < prev_freq) {
@@ -968,7 +877,7 @@ void __mmradio_scan_thread(mm_radio_t *radio)
if (freq == prev_freq)
continue;
- prev_freq = param.radio_scan.frequency = freq;
+ prev_freq = param.radio_scan.frequency = (int)freq;
MMRADIO_LOG_DEBUG("scanning : new frequency : [%d]\n", param.radio_scan.frequency);
/* drop if max freq is scanned */
@@ -985,16 +894,50 @@ void __mmradio_scan_thread(mm_radio_t *radio)
MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SCAN_INFO, &param);
}
}
- FINISHED:
- radio->scan_thread = 0;
-
+FINISHED:
if (radio->old_state == MM_RADIO_STATE_READY) {
- MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
+ MMRADIO_LOG_DEBUG("old state is ready");
} else if (radio->old_state == MM_RADIO_STATE_PLAYING) {
MMRADIO_LOG_DEBUG("old state is playing");
- ret = _mmradio_unmute(radio);
- ret = _mmradio_set_frequency(radio->hal_inf, prev_freq);
+ ret = radio_hal_unmute(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_unmute is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_unmute error");
+ goto FINISHED_ERR;
+ }
+ ret = radio_hal_set_frequency(radio->hal_inf, prev_freq);
+ if (ret == MM_ERROR_NOT_SUPPORT_API) {
+ MMRADIO_LOG_WARNING("radio_hal_set_frequency is not supported");
+ } else if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal_set_frequency error");
+ goto FINISHED_ERR;
+ }
+ }
+
+FINISHED_ERR:
+
+ radio->scan_thread = 0;
+
+ if (radio->old_state == MM_RADIO_STATE_PLAYING) {
MMRADIO_SET_STATE(radio, MM_RADIO_STATE_PLAYING);
+ } else {
+ /* close radio device here !!!! */
+ ret = radio_hal_close(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API)
+ MMRADIO_LOG_WARNING("radio_hal_close is not supported");
+ else if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("radio_hal_close_device error");
+
+ ret = radio_hal_unprepare(radio->hal_inf);
+ if (ret == MM_ERROR_NOT_SUPPORT_API)
+ MMRADIO_LOG_WARNING("radio_hal_unprepare is not supported");
+ else if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("radio_hal_close_device error");
+
+ radio->is_ready = FALSE;
+
+ MMRADIO_SET_STATE(radio, MM_RADIO_STATE_READY);
}
if (!radio->stop_scan)
@@ -1013,7 +956,8 @@ bool __is_tunable_frequency(mm_radio_t *radio, int freq)
MMRADIO_CHECK_INSTANCE(radio);
- if (freq == radio->region_setting.band_max || freq == radio->region_setting.band_min)
+ if (freq >= radio->region_setting.band_max
+ || freq <= radio->region_setting.band_min)
return false;
MMRADIO_LOG_FLEAVE();
@@ -1023,53 +967,38 @@ bool __is_tunable_frequency(mm_radio_t *radio, int freq)
void __mmradio_seek_thread(mm_radio_t *radio)
{
- int ret = 0;
- int freq = 0;
- char str_error[READ_MAX_BUFFER_SIZE];
- bool seek_stop = false;
+ int ret = MM_ERROR_NONE;
+ uint32_t freq = 0;
MMMessageParamType param = {0, };
- struct v4l2_hw_freq_seek vs = {0, };
-
- vs.tuner = TUNER_INDEX;
- vs.type = V4L2_TUNER_RADIO;
- vs.wrap_around = DEFAULT_WRAP_AROUND;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- /* check direction */
- switch (radio->seek_direction) {
- case MM_RADIO_SEEK_UP:
- vs.seek_upward = 1;
- break;
- default:
- vs.seek_upward = 0;
- break;
- }
-
MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_START, NULL);
MMRADIO_LOG_DEBUG("seeking....\n");
- while (!seek_stop) {
- ret = ioctl(radio->radio_fd, VIDIOC_S_HW_FREQ_SEEK, &vs);
+ if (!radio->seek_cancel) {
- if (ret == -1) {
- if (errno == EAGAIN) {
- /* FIXIT : we need retrying code here */
- MMRADIO_LOG_ERROR("scanning timeout\n");
- goto SEEK_FAILED;
- } else if (errno == EINVAL) {
- MMRADIO_LOG_ERROR("The tuner index is out of bounds or the value in the type field is wrong.");
- goto SEEK_FAILED;
- } else {
- MMRADIO_LOG_ERROR("Error: %s, %d\n", strerror_r(errno, str_error, sizeof(str_error)), errno);
- goto SEEK_FAILED;
- }
+ MMRADIO_LOG_DEBUG("try to seek ");
+ pthread_mutex_lock(&radio->seek_cancel_mutex);
+ MMRADIO_LOG_DEBUG("seek start\n");
+
+ if (radio->seek_cancel) {
+ MMRADIO_LOG_DEBUG("seek was canceled so we return failure to application");
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+ goto SEEK_FAILED;
+ }
+
+ ret = radio_hal_seek(radio->hal_inf, radio->seek_direction);
+ pthread_mutex_unlock(&radio->seek_cancel_mutex);
+ if (ret) {
+ MMRADIO_LOG_ERROR("radio_hal_seek failed\n");
+ goto SEEK_FAILED;
}
/* now we can get new frequency from radio device */
- ret = _mmradio_get_frequency(radio, &freq);
+ ret = radio_hal_get_frequency(radio->hal_inf, &freq);
if (ret) {
MMRADIO_LOG_ERROR("failed to get current frequency\n");
goto SEEK_FAILED;
@@ -1080,36 +1009,39 @@ void __mmradio_seek_thread(mm_radio_t *radio)
/* if same freq is found, ignore it and search next one. */
if (freq == radio->prev_seek_freq) {
MMRADIO_LOG_DEBUG("It's same with previous found one. So, trying next one. \n");
- continue;
+ goto SEEK_FAILED;
}
/* check if it's limit freq or not */
if (__is_tunable_frequency(radio, freq)) {
/* now tune to new frequency */
- ret = _mmradio_set_frequency(radio, freq);
+ ret = radio_hal_set_frequency(radio->hal_inf, freq);
if (ret) {
MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
goto SEEK_FAILED;
}
}
- /* now turn on radio
- * In the case of limit freq, tuner should be unmuted.
- * Otherwise, sound can't output even though application set new frequency.
- */
- ret = _mmradio_unmute(radio);
- if (ret) {
- MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
- goto SEEK_FAILED;
+ if (radio->seek_unmute) {
+ /* now turn on radio
+ * In the case of limit freq, tuner should be unmuted.
+ * Otherwise, sound can't output even though application set new frequency.
+ */
+ ret = radio_hal_unmute(radio->hal_inf);
+ if (ret) {
+ MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
+ goto SEEK_FAILED;
+ }
+ radio->seek_unmute = FALSE;
}
- param.radio_scan.frequency = radio->prev_seek_freq = freq;
+ param.radio_scan.frequency = radio->prev_seek_freq = (int)freq;
MMRADIO_LOG_DEBUG("seeking : new frequency : [%d]\n", param.radio_scan.frequency);
MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, &param);
- seek_stop = true;
}
radio->seek_thread = 0;
+ radio->is_seeking = FALSE;
MMRADIO_LOG_FLEAVE();
@@ -1117,9 +1049,21 @@ void __mmradio_seek_thread(mm_radio_t *radio)
return;
SEEK_FAILED:
+
+ if (radio->seek_unmute) {
+ /* now turn on radio
+ * In the case of limit freq, tuner should be unmuted.
+ * Otherwise, sound can't output even though application set new frequency.
+ */
+ ret = radio_hal_unmute(radio->hal_inf);
+ if (ret)
+ MMRADIO_LOG_ERROR("failed to tune to new frequency\n");
+ radio->seek_unmute = FALSE;
+ }
/* freq -1 means it's failed to seek */
param.radio_scan.frequency = -1;
MMRADIO_POST_MSG(radio, MM_MESSAGE_RADIO_SEEK_FINISH, &param);
+ radio->is_seeking = FALSE;
pthread_exit(NULL);
return;
}
@@ -1135,7 +1079,7 @@ static bool __mmradio_post_message(mm_radio_t *radio, enum MMMessageType msgtype
return false;
}
- MMRADIO_LOG_DEBUG("address of msg_cb : %d\n", radio->msg_cb);
+ MMRADIO_LOG_DEBUG("address of msg_cb : %p\n", radio->msg_cb);
radio->msg_cb(msgtype, param, radio->msg_cb_param);
@@ -1301,8 +1245,9 @@ static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
msg.state.previous = radio->old_state;
msg.state.current = radio->current_state;
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
/* post message to application */
- switch (radio->sm.by_focus_cb) {
+ switch (radio->sound_focus.by_focus_cb) {
case MMRADIO_FOCUS_CB_NONE:
{
msg_type = MM_MESSAGE_STATE_CHANGED;
@@ -1314,7 +1259,7 @@ static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
{
msg_type = MM_MESSAGE_STATE_INTERRUPTED;
msg.union_type = MM_MSG_UNION_CODE;
- msg.code = radio->sm.event_src;
+ msg.code = radio->sound_focus.event_src;
MMRADIO_POST_MSG(radio, msg_type, &msg);
}
break;
@@ -1323,6 +1268,10 @@ static bool __mmradio_set_state(mm_radio_t *radio, int new_state)
default:
break;
}
+#else
+ msg_type = MM_MESSAGE_STATE_CHANGED;
+ MMRADIO_POST_MSG(radio, msg_type, &msg);
+#endif
MMRADIO_LOG_FLEAVE();
@@ -1339,6 +1288,7 @@ static int __mmradio_get_state(mm_radio_t *radio)
return radio->current_state;
}
+#ifdef TIZEN_FEATURE_SOUND_FOCUS
static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
mm_sound_focus_state_e focus_state, const char *reason_for_change, int option,
const char *additional_info, void *user_data)
@@ -1351,19 +1301,19 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- mmradio_get_audio_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
- radio->sm.event_src = event_source;
+ mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
+ radio->sound_focus.event_src = event_source;
switch (focus_state) {
case FOCUS_IS_RELEASED:{
- radio->sm.cur_focus_type &= ~focus_type;
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
+ radio->sound_focus.cur_focus_type &= ~focus_type;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
result = _mmradio_stop(radio);
if (result)
MMRADIO_LOG_ERROR("failed to stop radio\n");
- MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sm.cur_focus_type);
+ MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
break;
@@ -1372,14 +1322,14 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
msg.union_type = MM_MSG_UNION_CODE;
msg.code = event_source;
- radio->sm.cur_focus_type |= focus_type;
+ radio->sound_focus.cur_focus_type |= focus_type;
- if ((postMsg) && (FOCUS_FOR_BOTH == radio->sm.cur_focus_type))
+ if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
- MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sm.cur_focus_type);
+ MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
break;
@@ -1391,40 +1341,58 @@ static void __mmradio_sound_focus_cb(int id, mm_sound_focus_type_e focus_type,
MMRADIO_LOG_FLEAVE();
}
-static void __mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data)
+static void __mmradio_sound_focus_watch_cb(int id, mm_sound_focus_type_e focus_type,
+ mm_sound_focus_state_e focus_state, const char *reason_for_change,
+ const char *additional_info, void *user_data)
{
mm_radio_t *radio = (mm_radio_t *)user_data;
+ enum MMMessageInterruptedCode event_source;
int result = MM_ERROR_NONE;
- mm_sound_device_type_e type;
+ int postMsg = false;
MMRADIO_LOG_FENTER();
MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
- if (mm_sound_get_device_type(device, &type) != MM_ERROR_NONE) {
- debug_error("getting device type failed");
- } else {
- switch (type) {
- case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
- case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
- case MM_SOUND_DEVICE_TYPE_HDMI:
- case MM_SOUND_DEVICE_TYPE_MIRRORING:
- case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
- if (!is_connected) {
- MMRADIO_LOG_ERROR("sound device unplugged");
- radio->sm.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
- radio->sm.event_src = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG;
-
- result = _mmradio_stop(radio);
- if (result != MM_ERROR_NONE)
- MMRADIO_LOG_ERROR("failed to stop radio\n");
- }
- break;
- default:
- break;
+ mmradio_get_sound_focus_reason(focus_state, reason_for_change, &event_source, &postMsg);
+ radio->sound_focus.event_src = event_source;
+
+ switch (focus_state) {
+ case FOCUS_IS_ACQUIRED: {
+ radio->sound_focus.cur_focus_type &= ~focus_type;
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
+
+ result = _mmradio_stop(radio);
+ if (result)
+ MMRADIO_LOG_ERROR("failed to stop radio\n");
+
+ MMRADIO_LOG_DEBUG("FOCUS_IS_RELEASED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
}
+ break;
+
+ case FOCUS_IS_RELEASED: {
+ MMMessageParamType msg = { 0, };
+ msg.union_type = MM_MSG_UNION_CODE;
+ msg.code = event_source;
+
+ radio->sound_focus.cur_focus_type |= focus_type;
+
+ if ((postMsg) && (FOCUS_FOR_BOTH == radio->sound_focus.cur_focus_type))
+ MMRADIO_POST_MSG(radio, MM_MESSAGE_READY_TO_RESUME, &msg);
+
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_NONE;
+
+ MMRADIO_LOG_DEBUG("FOCUS_IS_ACQUIRED cur_focus_type : %d\n", radio->sound_focus.cur_focus_type);
+ }
+ break;
+
+ default:
+ MMRADIO_LOG_DEBUG("Unknown focus_state\n");
+ break;
}
+
MMRADIO_LOG_FLEAVE();
}
+#endif
int _mmradio_get_region_type(mm_radio_t *radio, MMRadioRegionType *type)
{
diff --git a/src/mm_radio_sound_focus.c b/src/mm_radio_sound_focus.c
new file mode 100644
index 0000000..19c72bc
--- /dev/null
+++ b/src/mm_radio_sound_focus.c
@@ -0,0 +1,355 @@
+/*
+ * mm_radio_sound_focus.c
+ *
+ * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <assert.h>
+#include <unistd.h>
+#include <mm_debug.h>
+#include <mm_sound.h>
+#include <mm_sound_focus.h>
+#include <mm_sound_device.h>
+#include "mm_radio_utils.h"
+#include "mm_radio_priv_hal.h"
+#include "mm_radio_sound_focus.h"
+
+static void _mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data)
+{
+ mm_radio_t *radio = (mm_radio_t *)user_data;
+ int result = MM_ERROR_NONE;
+ mm_sound_device_type_e type;
+
+ MMRADIO_LOG_FENTER();
+ MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
+
+ if (mm_sound_get_device_type(device, &type) != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("getting device type failed");
+ } else {
+ switch (type) {
+ case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
+ case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
+ case MM_SOUND_DEVICE_TYPE_HDMI:
+ case MM_SOUND_DEVICE_TYPE_MIRRORING:
+ case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
+ if (!is_connected) {
+ MMRADIO_LOG_ERROR("sound device unplugged");
+ radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
+ radio->sound_focus.event_src = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG;
+
+ result = _mmradio_stop(radio);
+ if (result != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to stop radio\n");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ MMRADIO_LOG_FLEAVE();
+}
+
+void _mmradio_sound_signal_callback(mm_sound_signal_name_t signal, int value, void *user_data)
+{
+ mm_radio_sound_focus *sound_focus = (mm_radio_sound_focus *)user_data;
+ int ret = MM_ERROR_NONE;
+
+ MMRADIO_LOG_DEBUG("sound signal callback %d / %d", signal, value);
+
+ if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS) {
+ if (value == 1) {
+ /* unregister watch callback */
+ if (sound_focus->watch_id > 0) {
+ MMRADIO_LOG_DEBUG("unset the focus watch cb %d", sound_focus->watch_id);
+
+ ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
+ sound_focus->watch_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_unset_focus_watch_callback()");
+ }
+ /* unregister focus callback */
+ if (sound_focus->focus_id > 0) {
+ ret = mm_sound_unregister_focus(sound_focus->focus_id);
+ sound_focus->focus_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_unregister_focus() %d", sound_focus->focus_id);
+ }
+ /* unregister device connected callback */
+ if (sound_focus->device_subs_id > 0) {
+ MMRADIO_LOG_DEBUG("unset the device connected cb %d", sound_focus->device_subs_id);
+ ret = mm_sound_remove_device_connected_callback(sound_focus->device_subs_id);
+ sound_focus->device_subs_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_remove_device_connected_callback()");
+ }
+ }
+ }
+}
+
+int mmradio_sound_focus_register(mm_radio_sound_focus *sound_focus,
+ mm_sound_focus_changed_cb focus_cb, mm_sound_focus_changed_watch_cb watch_cb, void *param)
+{
+ /* read mm-session information */
+ int session_type = MM_SESSION_TYPE_MEDIA;
+ int session_flags = 0;
+ int ret = MM_ERROR_NONE;
+ int pid = getpid();
+ int handle = 0;
+
+ MMRADIO_LOG_FENTER();
+
+ if (!sound_focus) {
+ MMRADIO_LOG_ERROR("invalid session handle\n");
+ return MM_ERROR_RADIO_NOT_INITIALIZED;
+ }
+ sound_focus->cur_focus_type = FOCUS_NONE;
+
+ /* read session information */
+ ret = _mm_session_util_read_information(pid, &session_type, &session_flags);
+ MMRADIO_LOG_DEBUG("Read Session type ret:0x%X", ret);
+ if (ret == MM_ERROR_INVALID_HANDLE) {
+ MMRADIO_LOG_WARNING("subscribe_id=%d\n", sound_focus->subscribe_id);
+ if (sound_focus->subscribe_id == 0) {
+ ret = mm_sound_subscribe_signal_for_daemon(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, pid, &sound_focus->subscribe_id,
+ (mm_sound_signal_callback)_mmradio_sound_signal_callback, (void*)sound_focus);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_subscribe_signal is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+
+ MMRADIO_LOG_DEBUG("register focus watch callback for the value is 0, sub_cb id %d\n", sound_focus->subscribe_id);
+ /* register watch callback */
+ ret = mm_sound_set_focus_watch_callback_for_session(pid,
+ FOCUS_FOR_BOTH, watch_cb, (void *)param, &sound_focus->watch_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_set_focus_watch_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("(%p) set focus watch callback = %d", param, sound_focus->watch_id);
+
+ /* register device connected callback */
+ ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
+ (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void *)param, &sound_focus->device_subs_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_ERROR("register device connected callback for the value is 0, sub_cb id %d\n", sound_focus->device_subs_id);
+ }
+ ret = MM_ERROR_NONE;
+ } else if (ret == MM_ERROR_NONE) {
+ MMRADIO_LOG_WARNING("Read Session Information success. session_type : %d flags: %d \n", session_type, session_flags);
+ sound_focus->session_type = session_type;
+ sound_focus->snd_session_flags = session_flags;
+ if (sound_focus->session_type == MM_SESSION_TYPE_MEDIA) {
+ if (sound_focus->snd_session_flags & MM_SESSION_OPTION_PAUSE_OTHERS) {
+ /* register focus session */
+ sound_focus->pid = pid;
+ MMRADIO_LOG_DEBUG("sound register focus pid[%d]", pid);
+ ret = mm_sound_focus_get_id(&handle);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("Failed to get sound focus id");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ sound_focus->handle = handle;
+
+ ret = mm_sound_register_focus_for_session(handle, pid, "radio", focus_cb, param);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_DEBUG("mm_sound_register_focus_for_session is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("(%p) register focus for session %d", param, pid);
+ /* register device_connected_cb */
+ ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
+ (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void *)param, &sound_focus->device_subs_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("(%p) add device connected callback = %d", param, sound_focus->device_subs_id);
+
+ } else if (sound_focus->snd_session_flags & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
+ /* register device_connected_cb */
+ ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
+ (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void*)param, &sound_focus->device_subs_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("add device connected callback = %d", sound_focus->device_subs_id);
+ MMRADIO_LOG_WARNING("settion flags isn't OPTION_PAUSE_OTHERS and UNINTERRUPTIBLE. skip it..");
+ } else {
+ /* register watch callback */
+ ret = mm_sound_set_focus_watch_callback_for_session(pid,
+ FOCUS_FOR_BOTH, watch_cb, (void*)param, &sound_focus->watch_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_set_focus_watch_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("set focus watch callback = %d", sound_focus->watch_id);
+
+ /* register device connected callback */
+ ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
+ (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void*)param, &sound_focus->device_subs_id);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ MMRADIO_LOG_DEBUG("(%p) add device connected callback = %d", param, sound_focus->device_subs_id);
+ }
+ } else if (sound_focus->session_type == MM_SESSION_TYPE_REPLACED_BY_STREAM) {
+ /* didn't register device connected cb */
+ MMRADIO_LOG_WARNING("this process is using stream info. skip it..");
+ } else {
+ MMRADIO_LOG_WARNING("seesion type is not MEDIA (%d)", sound_focus->session_type);
+ return MM_ERROR_RADIO_INTERNAL;
+ }
+ ret = MM_ERROR_NONE;
+ } else {
+ MMRADIO_LOG_WARNING("Read Session Information failed. skip sound focus register function. errorcode %x \n", ret);
+ }
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+int mmradio_sound_focus_deregister(mm_radio_sound_focus *sound_focus)
+{
+
+ int ret = MM_ERROR_NONE;
+
+ MMRADIO_LOG_FENTER();
+
+ if (!sound_focus) {
+ MMRADIO_LOG_ERROR("invalid session handle\n");
+ return MM_ERROR_RADIO_NOT_INITIALIZED;
+ }
+
+ if (sound_focus->watch_id > 0) {
+ MMRADIO_LOG_DEBUG("unset the focus watch cb %d", sound_focus->watch_id);
+
+ ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
+ sound_focus->watch_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_unset_focus_watch_callback() ret = %d", ret);
+ }
+ /* unregister focus callback */
+ if (sound_focus->focus_id > 0) {
+ ret = mm_sound_unregister_focus(sound_focus->focus_id);
+ sound_focus->focus_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_unregister_focus() ret = %d", ret);
+ }
+ /* unregister device connected callback */
+ if (sound_focus->device_subs_id > 0) {
+ MMRADIO_LOG_DEBUG("unset the device connected cb %d", sound_focus->device_subs_id);
+ ret = mm_sound_remove_device_connected_callback(sound_focus->device_subs_id);
+ sound_focus->device_subs_id = 0;
+ if (ret != MM_ERROR_NONE)
+ MMRADIO_LOG_ERROR("failed to mm_sound_remove_device_connected_callback() ret = %d", ret);
+ }
+
+ MMRADIO_LOG_FLEAVE();
+
+ return MM_ERROR_NONE;
+}
+
+int mmradio_acquire_sound_focus(mm_radio_sound_focus *sound_focus)
+{
+ int ret = MM_ERROR_NONE;
+ mm_sound_focus_type_e focus_type = FOCUS_NONE;
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_LOG_ERROR("mmradio_acquire_sound_focus sound_focus->cur_focus_type : %d\n", sound_focus->cur_focus_type);
+
+ focus_type = FOCUS_FOR_BOTH & ~(sound_focus->cur_focus_type);
+ if (focus_type != FOCUS_NONE) {
+ ret = mm_sound_acquire_focus(sound_focus->handle, focus_type, NULL);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_acquire_focus is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ sound_focus->cur_focus_type = FOCUS_FOR_BOTH;
+ }
+
+ MMRADIO_LOG_FLEAVE();
+ return ret;
+}
+
+int mmradio_release_sound_focus(mm_radio_sound_focus *sound_focus)
+{
+ int ret = MM_ERROR_NONE;
+ MMRADIO_LOG_FENTER();
+
+ MMRADIO_LOG_ERROR("mmradio_release_sound_focus sound_focus->cur_focus_type : %d\n", sound_focus->cur_focus_type);
+ if (sound_focus->cur_focus_type != FOCUS_NONE) {
+ ret = mm_sound_release_focus(sound_focus->handle, sound_focus->cur_focus_type, NULL);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("mm_sound_release_focus is failed\n");
+ return MM_ERROR_POLICY_BLOCKED;
+ }
+ sound_focus->cur_focus_type = FOCUS_NONE;
+ }
+
+ MMRADIO_LOG_FLEAVE();
+ return ret;
+}
+
+#define AUDIO_FOCUS_REASON_MAX 128
+
+void mmradio_get_sound_focus_reason(mm_sound_focus_state_e focus_state, const char *reason_for_change, enum MMMessageInterruptedCode *event_source, int *postMsg)
+{
+ MMRADIO_LOG_FENTER();
+ MMRADIO_LOG_ERROR("mmradio_get_sound_focus_reason focus_state : %d reason_for_change :%s\n", focus_state, reason_for_change);
+
+ if (0 == strncmp(reason_for_change, "call-voice", AUDIO_FOCUS_REASON_MAX)
+ || (0 == strncmp(reason_for_change, "voip", AUDIO_FOCUS_REASON_MAX))
+ || (0 == strncmp(reason_for_change, "ringtone-voip", AUDIO_FOCUS_REASON_MAX))
+ || (0 == strncmp(reason_for_change, "ringtone-call", AUDIO_FOCUS_REASON_MAX))
+ ) {
+ if (focus_state == FOCUS_IS_RELEASED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_START;
+ else if (focus_state == FOCUS_IS_ACQUIRED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_END;
+ *postMsg = true;
+ } else if (0 == strncmp(reason_for_change, "alarm", AUDIO_FOCUS_REASON_MAX)) {
+ if (focus_state == FOCUS_IS_RELEASED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_START;
+ else if (focus_state == FOCUS_IS_ACQUIRED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_END;
+ *postMsg = true;
+ } else if (0 == strncmp(reason_for_change, "notification", AUDIO_FOCUS_REASON_MAX)) {
+ if (focus_state == FOCUS_IS_RELEASED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START;
+ else if (focus_state == FOCUS_IS_ACQUIRED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END;
+ *postMsg = true;
+ } else if (0 == strncmp(reason_for_change, "emergency", AUDIO_FOCUS_REASON_MAX)) {
+ if (focus_state == FOCUS_IS_RELEASED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START;
+ else if (focus_state == FOCUS_IS_ACQUIRED)
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END;
+ *postMsg = false;
+ } else if (0 == strncmp(reason_for_change, "media", AUDIO_FOCUS_REASON_MAX)) {
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
+ *postMsg = false;
+ } else {
+ *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
+ *postMsg = false;
+ }
+ MMRADIO_LOG_FLEAVE();
+}
diff --git a/src/radio_hal_interface.c b/src/radio_hal_interface.c
new file mode 100644
index 0000000..499cd57
--- /dev/null
+++ b/src/radio_hal_interface.c
@@ -0,0 +1,353 @@
+/*
+ * radio_hal_interface.c
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <dlfcn.h>
+#include "mm_radio_utils.h"
+#include "radio_hal_interface.h"
+
+#define LIB_TIZEN_RADIO "libtizen-radio.so"
+
+static int __convert_error_code(int code, char *func_name)
+{
+ int ret = RADIO_ERROR_NONE;
+ char *msg = "RADIO_ERROR_NONE";
+ MMRADIO_LOG_DEBUG("[%s] Enter code :%x", func_name, code);
+
+ switch (code) {
+
+ case RADIO_ERROR_NONE :
+ ret = MM_ERROR_NONE;
+ msg = "MM_ERROR_NONE";
+ break;
+ case RADIO_ERROR_INVALID_PARAMETER :
+ ret = MM_ERROR_COMMON_INVALID_ARGUMENT;
+ msg = "MM_ERROR_COMMON_INVALID_ARGUMENT";
+ break;
+ case RADIO_ERROR_INVALID_STATE :
+ ret = MM_ERROR_RADIO_INVALID_STATE;
+ msg = "MM_ERROR_RADIO_INVALID_STATE";
+ break;
+ case RADIO_ERROR_OUT_OF_MEMORY :
+ ret = MM_ERROR_RADIO_NO_FREE_SPACE;
+ msg = "MM_ERROR_RADIO_NO_FREE_SPACE";
+ break;
+ case RADIO_ERROR_PERMISSION_DENIED :
+ case RADIO_ERROR_DEVICE_NOT_PREPARED :
+ ret = MM_ERROR_RADIO_PERMISSION_DENIED;
+ msg = "MM_ERROR_RADIO_PERMISSION_DENIED";
+ break;
+ case RADIO_ERROR_DEVICE_NOT_OPENED :
+ ret = MM_ERROR_RADIO_DEVICE_NOT_OPENED;
+ msg = "MM_ERROR_RADIO_DEVICE_NOT_OPENED";
+ break;
+ case RADIO_ERROR_NOT_SUPPORTED :
+ case RADIO_ERROR_DEVICE_NOT_SUPPORTED :
+ case RADIO_ERROR_DEVICE_NOT_FOUND :
+ ret = MM_ERROR_RADIO_DEVICE_NOT_FOUND;
+ msg = "MM_ERROR_RADIO_DEVICE_NOT_FOUND";
+ break;
+ case RADIO_ERROR_NO_ANTENNA:
+ ret = MM_ERROR_RADIO_NO_ANTENNA;
+ msg = "MM_ERROR_RADIO_NO_ANTENNA";
+ break;
+ case RADIO_ERROR_UNKNOWN :
+ case RADIO_ERROR_INTERNAL :
+ default:
+ ret = MM_ERROR_RADIO_INTERNAL;
+ msg = "MM_ERROR_RADIO_INTERNAL";
+ break;
+ }
+ MMRADIO_LOG_ERROR("[%s] %s(0x%08x) : core fw error(0x%x)", func_name, msg, ret, code);
+ return ret;
+}
+
+int radio_hal_interface_init(mm_radio_hal_interface **handle)
+{
+ mm_radio_hal_interface *h = NULL;
+ int ret = MM_ERROR_NONE;
+ h = (mm_radio_hal_interface *)malloc(sizeof(mm_radio_hal_interface));
+
+ if(!h) {
+ MMRADIO_LOG_ERROR("cannot allocate memory for radio_hal interface");
+ return MM_ERROR_RADIO_NO_FREE_SPACE;
+ }
+
+ h->dl_handle = dlopen(LIB_TIZEN_RADIO, RTLD_NOW);
+
+ if(h->dl_handle) {
+ h->intf.init = dlsym(h->dl_handle, "radio_init");
+ h->intf.deinit = dlsym(h->dl_handle, "radio_deinit");
+ h->intf.prepare = dlsym(h->dl_handle, "radio_prepare");
+ h->intf.unprepare = dlsym(h->dl_handle, "radio_unprepare");
+ h->intf.open = dlsym(h->dl_handle, "radio_open");
+ h->intf.close = dlsym(h->dl_handle, "radio_close");
+ h->intf.start = dlsym(h->dl_handle, "radio_start");
+ h->intf.stop = dlsym(h->dl_handle, "radio_stop");
+ h->intf.seek = dlsym(h->dl_handle, "radio_seek");
+ h->intf.get_frequency = dlsym(h->dl_handle, "radio_get_frequency");
+ h->intf.set_frequency = dlsym(h->dl_handle, "radio_set_frequency");
+ h->intf.mute = dlsym(h->dl_handle, "radio_mute");
+ h->intf.unmute = dlsym(h->dl_handle, "radio_unmute");
+ h->intf.get_signal_strength = dlsym(h->dl_handle, "radio_get_signal_strength");
+
+ if (h->intf.init == NULL || h->intf.deinit == NULL) {
+ MMRADIO_LOG_ERROR("could not get mandatory funtion");
+ goto FAIL;
+ }
+
+ if (h->intf.init) {
+ ret = h->intf.init(&h->rh_handle);
+ if (ret != MM_ERROR_NONE) {
+ MMRADIO_LOG_ERROR("radio_hal init failed %d", ret);
+ goto FAIL;
+ }
+ }
+ } else {
+ MMRADIO_LOG_ERROR("open radio hal_interface failed : %s", dlerror());
+ return MM_ERROR_RADIO_INTERNAL;
+ }
+
+ *handle = h;
+
+ MMRADIO_LOG_ERROR("open radio_hal interface");
+
+ return MM_ERROR_NONE;
+FAIL:
+ if (h) {
+ if (h->dl_handle)
+ dlclose(h->dl_handle);
+ free(h);
+ }
+
+ return ret;
+}
+
+int radio_hal_interface_deinit(mm_radio_hal_interface *handle)
+{
+ int ret = MM_ERROR_NONE;
+ MMRADIO_CHECK_ARG(handle);
+
+ if (handle->dl_handle) {
+ ret = handle->intf.deinit(handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+
+ handle->rh_handle = NULL;
+
+ dlclose(handle->dl_handle);
+ handle->dl_handle = NULL;
+ }
+
+ free(handle);
+ handle = NULL;
+
+ return ret;
+}
+
+int radio_hal_open(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.open) {
+ ret = radio_handle->intf.open(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal open is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_prepare(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.prepare) {
+ ret = radio_handle->intf.prepare(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal prepare is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_unprepare(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.prepare) {
+ ret = radio_handle->intf.unprepare(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal prepare is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+
+int radio_hal_close(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.close) {
+ ret = radio_handle->intf.close(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal close is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_start(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.start) {
+ ret = radio_handle->intf.start(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal start is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_stop(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.stop) {
+ ret = radio_handle->intf.stop(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal stop is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+
+int radio_hal_seek(mm_radio_hal_interface *radio_handle, seek_direction_type_t direction)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.seek) {
+ ret = radio_handle->intf.seek(radio_handle->rh_handle, (radio_seek_direction_type_t)direction);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal seek is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_get_frequency(mm_radio_hal_interface *radio_handle, uint32_t *frequency)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.get_frequency) {
+ ret = radio_handle->intf.get_frequency(radio_handle->rh_handle, frequency);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal get_frequency is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_set_frequency(mm_radio_hal_interface *radio_handle, uint32_t frequency)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.set_frequency) {
+ ret = radio_handle->intf.set_frequency(radio_handle->rh_handle, frequency);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal get_frequency is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_get_signal_strength(mm_radio_hal_interface *radio_handle, uint32_t *strength)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.get_signal_strength) {
+ ret = radio_handle->intf.get_signal_strength(radio_handle->rh_handle, strength);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal get_signal_strength is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_mute(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.mute) {
+ ret = radio_handle->intf.mute(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal mute is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+}
+
+int radio_hal_unmute(mm_radio_hal_interface *radio_handle)
+{
+ radio_error_t ret = RADIO_ERROR_NONE;
+ MMRADIO_CHECK_ARG(radio_handle);
+ if (radio_handle->intf.unmute) {
+ ret = radio_handle->intf.unmute(radio_handle->rh_handle);
+ if (ret != RADIO_ERROR_NONE)
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ MMRADIO_LOG_WARNING("radio_hal unmute is NULL");
+ return MM_ERROR_NOT_SUPPORT_API;
+ }
+ return MM_ERROR_NONE;
+
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+